Re: [PATCH 2/2] qom: Assert that objects being destroyed have no parent

2020-12-15 Thread Marc-André Lureau
Hi

On Wed, Dec 16, 2020 at 2:41 AM Eduardo Habkost  wrote:

> QOM reference counting bugs are often hard to detect, but there's
> one kind of bug that's easier: if we are freeing an object but is
> still attached to a parent, it means the reference count is wrong
> (because the parent always hold a reference to their children).
>
> Add an assertion to make sure we detect those cases.
>
> Signed-off-by: Eduardo Habkost 
>

On the principle, I fully agree. But the risk is high to introduce
regression if objects are manipulated in strange ways.

I remember I wanted object_unref() to automatically remove itself from the
parent when the last ref is dropped. I think there were similar concerns.

Maybe with --enable-qom-debug ? (removing the -cast)

---
>  qom/object.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/qom/object.c b/qom/object.c
> index f2ae6e6b2a..5cfed6d7c6 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -685,6 +685,7 @@ static void object_finalize(void *data)
>  object_deinit(obj, ti);
>
>  g_assert(obj->ref == 0);
> +g_assert(obj->parent == NULL);
>  if (obj->free) {
>  obj->free(obj);
>  }
> --
> 2.28.0
>
>


Re: [PATCH v2 05/11] qapi/introspect.py: add preliminary type hint annotations

2020-12-15 Thread Markus Armbruster
John Snow  writes:

> On 11/13/20 11:48 AM, Markus Armbruster wrote:
>> John Snow  writes:
>> 
>>> The typing of _make_tree and friends is a bit involved, but it can be
>>> done with some stubbed out types and a bit of elbow grease. The
>>> forthcoming patches attempt to make some simplifications, but having the
>>> type hints in advance may aid in review of subsequent patches.
>>>
>>>
>>> Some notes on the abstract types used at this point, and what they
>>> represent:
>>>
>>> - TreeValue represents any object in the type tree. _make_tree is an
>>>optional call -- not every node in the final type tree will have been
>>>passed to _make_tree, so this type encompasses not only what is passed
>>>to _make_tree (dicts, strings) or returned from it (dicts, strings, a
>>>2-tuple), but any recursive value for any of the dicts passed to
>>>_make_tree -- which includes lists, strings, integers, null constants,
>>>and so on.
>>>
>>> - _DObject is a type alias I use to mean "A JSON-style object,
>>>represented as a Python dict." There is no "JSON" type in Python, they
>>>are converted natively to recursively nested dicts and lists, with
>>>leaf values of str, int, float, None, True/False and so on. This type
>>>structure is not possible to accurately portray in mypy yet, so a
>>>placeholder is used.
>>>
>>>In this case, _DObject is being used to refer to SchemaInfo-like
>>>structures as defined in qapi/introspect.json, OR any sub-object
>>>values they may reference. We don't have strong typing available for
>>>those, so a generic alternative is used.
>>>
>>> - Extra refers explicitly to the dict containing "extra" information
>>>about a node in the tree. mypy does not offer per-key typing for dicts
>>>in Python 3.6, so this is the best we can do here.
>>>
>>> - Annotated refers to (one of) the return types of _make_tree:
>>>It represents a 2-tuple of (TreeValue, Extra).
>>>
>>>
>>> Signed-off-by: Eduardo Habkost 
>>> Signed-off-by: John Snow 
>>> ---
>>>   scripts/qapi/introspect.py | 157 -
>>>   scripts/qapi/mypy.ini  |   5 --
>>>   scripts/qapi/schema.py |   2 +-
>>>   3 files changed, 121 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
>>> index 63f721ebfb6..803288a64e7 100644
>>> --- a/scripts/qapi/introspect.py
>>> +++ b/scripts/qapi/introspect.py
>>> @@ -10,7 +10,16 @@
>>>   See the COPYING file in the top-level directory.
>>>   """
>>>   
>>> -from typing import Optional, Sequence, cast
>>> +from typing import (
>>> +Any,
>>> +Dict,
>>> +List,
>>> +Optional,
>>> +Sequence,
>>> +Tuple,
>>> +Union,
>>> +cast,
>>> +)
>>>   
>>>   from .common import (
>>>   c_name,
>>> @@ -20,13 +29,56 @@
>>>   )
>>>   from .gen import QAPISchemaMonolithicCVisitor
>>>   from .schema import (
>>> +QAPISchema,
>>>   QAPISchemaArrayType,
>>>   QAPISchemaBuiltinType,
>>> +QAPISchemaEntity,
>>> +QAPISchemaEnumMember,
>>> +QAPISchemaFeature,
>>> +QAPISchemaObjectType,
>>> +QAPISchemaObjectTypeMember,
>>>   QAPISchemaType,
>>> +QAPISchemaVariant,
>>> +QAPISchemaVariants,
>>>   )
>>> +from .source import QAPISourceInfo
>>>   
>>>   
>>> -def _make_tree(obj, ifcond, features, extra=None):
>>> +# This module constructs a tree-like data structure that is used to
>> 
>> "Tree-like" suggests it's not a tree, it just looks like one if you
>> squint.  Drop "-like"?
>> 
>
> Sure. I think I am grammatically predisposed to assume "binary tree" or 
> at least some kind of monomorphic tree when I see "tree", hence the 
> hedging and weasel-words.
>
> No problem just to drop it.
>
>>> +# generate the introspection information for QEMU. It behaves similarly
>>> +# to a JSON value.
>>> +#
>>> +# A complexity over JSON is that our values may or may not be annotated.
>> 
>> It's the obvious abstract syntax tree for JSON, hacked up^W^Wextended to
>> support certain annotations.
>> 
>
> Yes.
>
>> Let me add a bit of context and history.
>> 
>> The module's job is generating qapi-introspect.[ch] for a QAPISchema.
>> 
>> The purpose of qapi-introspect.[ch] is providing the information
>> query-qmp-schema needs, i.e. (a suitable C representation of) a JSON
>> value conforming to [SchemaInfo].  Details of this C representation are
>> not interesting right now.
>> 
>> We first go from QAPISchema to a suitable Python representation of
>> [SchemaInfo], then from there to the C source code, neatly separating
>> concerns.
>> 
>> Stupidest solution Python representation that could possibly work: the
>> obvious abstract syntax tree for JSON (that's also how Python's json
>> module works).
>> 
>> Parts corresponding to QAPISchema parts guarded by 'if' conditionals
>> need to be guarded by #if conditionals.
>> 
>> We want to prefix parts corresponding to certain QAPISchema parts with a
>> comment.
>> 
>> These two requ

Re: [PATCH 1/2] test-char: Destroy chardev correctly at char_file_test_internal()

2020-12-15 Thread Marc-André Lureau
On Wed, Dec 16, 2020 at 2:41 AM Eduardo Habkost  wrote:

> commit 1e419ee68fa5 ("chardev: generate an internal id when none
> given") changed the reference ownership semantics of
> qemu_chardev_new(NULL, ...): now all chardevs created using
> qemu_chardev_new() are added to the /chardevs QOM container, and
> the caller does not own a reference to the newly created object.
>
> However, the code at char_file_test_internal() had not been
> updated and was calling object_unref() on a chardev object it
> didn't own.  This makes the chardev be destroyed, but leaves a
> dangling pointer in the /chardev container children list, and
> seems to be the cause of the following char_serial_test() crash:
>
>   Unexpected error in object_property_try_add() at ../qom/object.c:1220: \
>   attempt to add duplicate property 'serial-id' to object (type
> 'container')
>   ERROR test-char - too few tests run (expected 38, got 9)
>
> Update the code to use object_unparent() at the end of
> char_file_test_internal(), to make sure the chardev will be
> correctly removed from the QOM tree.
>
> Fixes: 1e419ee68fa5 ("chardev: generate an internal id when none given")
> Signed-off-by: Eduardo Habkost 
>

nice catch
Reviewed-by: Marc-André Lureau 

---
>  tests/test-char.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/test-char.c b/tests/test-char.c
> index 953e0d1c1f..06102977b6 100644
> --- a/tests/test-char.c
> +++ b/tests/test-char.c
> @@ -1298,7 +1298,7 @@ static void char_file_test_internal(Chardev
> *ext_chr, const char *filepath)
>  g_assert(strncmp(contents, "hello!", 6) == 0);
>
>  if (!ext_chr) {
> -object_unref(OBJECT(chr));
> +object_unparent(OBJECT(chr));
>  g_unlink(out);
>  }
>  g_free(contents);
> --
> 2.28.0
>
>


Re: [PATCH v5 0/2] MTE support for KVM guest

2020-12-15 Thread Haibo Xu
On Mon, 7 Dec 2020 at 22:48, Steven Price  wrote:
>
> On 04/12/2020 08:25, Haibo Xu wrote:
> > On Fri, 20 Nov 2020 at 17:51, Steven Price  wrote:
> >>
> >> On 19/11/2020 19:11, Marc Zyngier wrote:
> >>> On 2020-11-19 18:42, Andrew Jones wrote:
>  On Thu, Nov 19, 2020 at 03:45:40PM +, Peter Maydell wrote:
> > On Thu, 19 Nov 2020 at 15:39, Steven Price  wrote:
> >> This series adds support for Arm's Memory Tagging Extension (MTE) to
> >> KVM, allowing KVM guests to make use of it. This builds on the
> > existing
> >> user space support already in v5.10-rc1, see [1] for an overview.
> >
> >> The change to require the VMM to map all guest memory PROT_MTE is
> >> significant as it means that the VMM has to deal with the MTE tags
> > even
> >> if it doesn't care about them (e.g. for virtual devices or if the VMM
> >> doesn't support migration). Also unfortunately because the VMM can
> >> change the memory layout at any time the check for PROT_MTE/VM_MTE has
> >> to be done very late (at the point of faulting pages into stage 2).
> >
> > I'm a bit dubious about requring the VMM to map the guest memory
> > PROT_MTE unless somebody's done at least a sketch of the design
> > for how this would work on the QEMU side. Currently QEMU just
> > assumes the guest memory is guest memory and it can access it
> > without special precautions...
> >
> 
>  There are two statements being made here:
> 
>  1) Requiring the use of PROT_MTE when mapping guest memory may not fit
>  QEMU well.
> 
>  2) New KVM features should be accompanied with supporting QEMU code in
>  order to prove that the APIs make sense.
> 
>  I strongly agree with (2). While kvmtool supports some quick testing, it
>  doesn't support migration. We must test all new features with a migration
>  supporting VMM.
> 
>  I'm not sure about (1). I don't feel like it should be a major problem,
>  but (2).
> >>
> >> (1) seems to be contentious whichever way we go. Either PROT_MTE isn't
> >> required in which case it's easy to accidentally screw up migration, or
> >> it is required in which case it's difficult to handle normal guest
> >> memory from the VMM. I get the impression that probably I should go back
> >> to the previous approach - sorry for the distraction with this change.
> >>
> >> (2) isn't something I'm trying to skip, but I'm limited in what I can do
> >> myself so would appreciate help here. Haibo is looking into this.
> >>
> >
> > Hi Steven,
> >
> > Sorry for the later reply!
> >
> > I have finished the POC for the MTE migration support with the assumption
> > that all the memory is mapped with PROT_MTE. But I got stuck in the test
> > with a FVP setup. Previously, I successfully compiled a test case to verify
> > the basic function of MTE in a guest. But these days, the re-compiled test
> > can't be executed by the guest(very weird). The short plan to verify
> > the migration
> > is to set the MTE tags on one page in the guest, and try to dump the 
> > migrated
> > memory contents.
>
> Hi Haibo,
>
> Sounds like you are making good progress - thanks for the update. Have
> you thought about how the PROT_MTE mappings might work if QEMU itself
> were to use MTE? My worry is that we end up with MTE in a guest
> preventing QEMU from using MTE itself (because of the PROT_MTE
> mappings). I'm hoping QEMU can wrap its use of guest memory in a
> sequence which disables tag checking (something similar will be needed
> for the "protected VM" use case anyway), but this isn't something I've
> looked into.
>
> > I will update the status later next week!
>
> Great, I look forward to hearing how it goes.

Hi Steve,

I have finished verifying the POC on a FVP setup, and the MTE test case can
be migrated from one VM to another successfully. Since the test case is very
simple which just maps one page with MTE enabled and does some memory
access, so I can't say it's OK for other cases.

BTW, I noticed that you have sent out patch set v6 which mentions that mapping
all the guest memory with PROT_MTE was not feasible. So what's the plan for the
next step? Will new KVM APIs which can facilitate the tag store and recover be
available?

Regards,
Haibo

>
> Thanks,
>
> Steve



Re: [PATCH 2/2] accel: kvm: Add aligment check for kvm_log_clear_one_slot

2020-12-15 Thread Andrew Jones
On Tue, Dec 15, 2020 at 12:55:50PM +0100, Andrew Jones wrote:
> On Tue, Dec 15, 2020 at 03:19:48PM +0800, Keqian Zhu wrote:
> > The parameters start and size are transfered from QEMU memory
> > emulation layer. It can promise that they are TARGET_PAGE_SIZE
> > aligned. However, KVM needs they are qemu_real_page_size aligned.
> > 
> > Though no caller breaks this aligned requirement currently, we'd
> > better add an explicit check to avoid future breaking.
> > 
> > Signed-off-by: Keqian Zhu 
> > ---
> >  accel/kvm/kvm-all.c | 5 +
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> > index c5e06288eb..3d0e3aa872 100644
> > --- a/accel/kvm/kvm-all.c
> > +++ b/accel/kvm/kvm-all.c
> > @@ -701,6 +701,11 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int 
> > as_id, uint64_t start,
> >  unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size;
> >  int ret;
> >  
> > +/* Make sure start and size are psize aligned */
> > +if (!QEMU_IS_ALIGNED(start, psize) || !QEMU_IS_ALIGNED(size, psize)) {
> > +return -EINVAL;
> > +}
> > +
> >  /*
> >   * We need to extend either the start or the size or both to
> >   * satisfy the KVM interface requirement.  Firstly, do the start
> > -- 
> > 2.23.0
> > 
> >
> 
> It's not clear to me that this function has any restrictions on start
> and size. If it does, then please document those restrictions in the
> function's header and assert rather than return.
>

Also, I see this patch is on its way in

https://patchwork.ozlabs.org/project/qemu-devel/patch/20201215175445.1272776-27-pbonz...@redhat.com/

Thanks,
drew 




Re: [PATCH v2 09/11] qapi/introspect.py: create a typed 'Annotated' data strutcure

2020-12-15 Thread Markus Armbruster
John Snow  writes:

> On 11/16/20 5:12 AM, Markus Armbruster wrote:
>> John Snow  writes:
>> 
>>> This replaces _make_tree with Annotated(). By creating it as a generic
>>> container, we can more accurately describe the exact nature of this
>>> particular value. i.e., each Annotated object is actually an
>>> Annotated, describing its contained value.
>>>
>>> This adds stricter typing to Annotated nodes and extra annotated
>>> information.
>> 
>> Inhowfar?
>> 
>
> The Generic[T] trick lets us express the type of the annotated node 
> itself, which is more specific than Tuple[_something, ...etc...] and 
> this type can be preserved when we peel the annotations off.
>
> It's not super crucial, but like you say, the big benefit is the field 
> names and strict types for the special-purpose structure.

I'd lead with a brief description of the data structure you're
replacing, how we got there, and why it's ugly.  You can steal from my
review of PATCH 5.  Then explain its replacement, briefly.  And only
then talk about types.

By the time you get to types, I'm nodding along "yes, please", and will
be predisposed to accept your typing arguments at face value.

If you start with typing arguments, they have to negotiate the "yes,
please" bar all by themselves.  Harder, because Python typing stuff you
have to explain for dummies.

>>>   It also replaces a check of "isinstance tuple" with the
>>> much more explicit "isinstance Annotated" which is guaranteed not to
>>> break if a tuple is accidentally introduced into the type tree. (Perhaps
>>> as a result of a bad conversion from a list.)
>> 
>> Sure this is worth writing home about?  Such accidents seem quite
>> unlikely.
>> 
>
> We all have our phobias. I find "isinstance(x, 
> extremely_common_stdlib_type)" to be extremely fragile and likely to 
> frustrate.

You're applying programming-in-the-large reasoning to a
programming-in-the-small case.

Say you're writing a piece of code you expect to be used in contexts you
prudently refuse to predict.  The code deals with a bunch of basic
Python types.  Reserving another basic Python type for internal use may
well be unwise then, because it can make your code break confusingly
when this other type appears in input.  Which it shouldn't, but making
your reusable code harder to misuse, and misuses easier to diagnose are
laudable goals.

This is not such a piece of code.  All the users it will ever have are
in the same file of 200-something LOC.

Your commit message makes the case for your patch.  Sometimes, dropping
weak arguments strengthens a case.  I believe dropping the "It also
replaces" argument would strengthen your case.

> Maybe what's unlikely is anyone editing this code ever again. You've 
> mentioned wanting to look into changing how the schema information is 
> stored in QEMU before, so a lot of this might not matter for too much 
> longer, who knows.

Yes, I expect generating the SchemaInfoList directly would beat
generating QLitObject, then converting QLitObject -> QObject ->
SchemaInfoList.  Whether it's worth the effort is unclear.

>> For me, the commit's benefit is making the structure of the annotated
>> tree node more explicit (your first paragraph, I guess).  It's a bit of
>> a pattern in developing Python code: we start with a Tuple because it's
>> terse and easy, then things get more complex, terse becomes too terse,
>> and we're replacing the Tuple with a class.
>> 
>
> Yep.
>
>>> Signed-off-by: John Snow 




Re: [PATCH] hw/arm/virt: Remove virt machine state 'smp_cpus'

2020-12-15 Thread Andrew Jones
On Tue, Dec 15, 2020 at 06:20:48PM +, David Edmondson wrote:
> On Tuesday, 2020-12-15 at 18:48:15 +01, Andrew Jones wrote:
> 
> > virt machine's 'smp_cpus' and machine->smp.cpus must always have the
> > same value. And, anywhere we have virt machine state we have machine
> > state. So let's remove the redundancy. Also, to make it easier to see
> > that machine->smp is the true source for "smp_cpus" and "max_cpus",
> > avoid passing them in function parameters, preferring instead to get
> > them from the state.
> >
> > No functional change intended.
> >
> > Signed-off-by: Andrew Jones 
> 
> Minor question below...
> 
> Reviewed-by: David Edmondson 

Thanks

> >  static void fdt_add_cpu_nodes(const VirtMachineState *vms)
> >  {
> > -int cpu;
> > -int addr_cells = 1;
> >  const MachineState *ms = MACHINE(vms);
> > +int smp_cpus = ms->smp.cpus, cpu;
> 
> Is it house-style to have initialised and un-initialised local variables
> declared on the same line?
>

checkpatch.pl doesn't complain and a grep of qemu shows hundreds of other
examples. That said, I only see one other example in hw/arm/virt.c, so if
we'd rather avoid it, I'll repost.

Thanks,
drew




[PATCH] x86/cpu: Add AVX512_FP16 cpu feature

2020-12-15 Thread Cathy Zhang
AVX512 Half-precision floating point (FP16) has better performance
compared to FP32 if the presicion or magnitude requirements are met.
It's defined as CPUID.(EAX=7,ECX=0):EDX[bit 23].

Refer to
https://software.intel.com/content/www/us/en/develop/download/\
intel-architecture-instruction-set-extensions-programming-reference.html

Signed-off-by: Cathy Zhang 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ca997a68cd..c4d623b8b9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -979,7 +979,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "avx512-vp2intersect", NULL, "md-clear", NULL,
 NULL, NULL, "serialize", NULL,
 "tsx-ldtrk", NULL, NULL /* pconfig */, NULL,
-NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, "avx512-fp16",
 NULL, NULL, "spec-ctrl", "stibp",
 NULL, "arch-capabilities", "core-capability", "ssbd",
 },
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c4a49c06a8..6fd675c654 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -784,6 +784,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_SERIALIZE (1U << 14)
 /* TSX Suspend Load Address Tracking instruction */
 #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16)
+/* AVX512_FP16 instruction */
+#define CPUID_7_0_EDX_AVX512_FP16   (1U << 23)
 /* Speculation Control */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26)
 /* Single Thread Indirect Branch Predictors */
-- 
2.17.1




Re: [PATCH v2 07/11] qapi/introspect.py: Unify return type of _make_tree()

2020-12-15 Thread Markus Armbruster
John Snow  writes:

> On 11/16/20 4:46 AM, Markus Armbruster wrote:
>> John Snow  writes:
>> 
>>> Returning two different types conditionally can be complicated to
>>> type. Let's always return a tuple for consistency. Prohibit the use of
>>> annotations with dict-values in this circumstance. It can be implemented
>>> later if and when the need for it arises.
>>>
>>> Signed-off-by: John Snow 
>>> ---
>>>   scripts/qapi/introspect.py | 21 -
>>>   1 file changed, 12 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
>>> index 16282f2634b..ef469b6c06e 100644
>>> --- a/scripts/qapi/introspect.py
>>> +++ b/scripts/qapi/introspect.py
>>> @@ -77,14 +77,12 @@
>>>   
>>>   def _make_tree(obj: Union[_DObject, str], ifcond: List[str],
>>>  extra: Optional[Annotations] = None
>>> -   ) -> TreeValue:
>>> +   ) -> Annotated:
>>>   if extra is None:
>>>   extra = {}
>>>   if ifcond:
>>>   extra['if'] = ifcond
>>> -if extra:
>>> -return (obj, extra)
>>> -return obj
>>> +return (obj, extra)
>> 
>> Less efficient, but that's okay.
>> 
>
> I have bad news about Python :)

Well played, sir!

>>>   
>>>   
>>>   def _tree_to_qlit(obj: TreeValue,
>>> @@ -98,12 +96,16 @@ def indent(level: int) -> str:
>>>   ifobj, extra = obj
>>>   ifcond = cast(Optional[Sequence[str]], extra.get('if'))
>>>   comment = extra.get('comment')
>>> +
>>> +msg = "Comments and Conditionals not implemented for dict values"
>>> +assert not (suppress_first_indent and (ifcond or comment)), msg
>> 
>> What exactly does this assertion guard?
>> 
>
> Something that Eduardo noticed in his review. It's ugly, and I explained 
> it poorly.
>
> We don't support annotations on dict *values*, basically. When this 
> function is called with suppress_first_indent, we know that we are being 
> called to process a dict *value* and not a dict *key*.
>
> What do you do with comments or conditionals on just one half of a key: 
> value pair?
>
> Well, break.

Your @msg is a bit misleading then: it suggests comments and
conditionals are not implemented for dict values, but could be.  Not
true for conditionals.

Minimally invasive patch correction: drop @msg.

But the actual impossibility to guard against is even simpler, I
believe:

  if isinstance(obj, tuple):
  assert not suppress_first_indent

But^2, I figure this can be made truly impossible: factor out the part
of _tree_to_qlit() that deals with non-tuple @obj into its own function
(the conditional at its end), then use that for the dict values.

>>> +
>>>   ret = ''
>>>   if comment:
>>>   ret += indent(level) + '/* %s */\n' % comment
>>>   if ifcond:
>>>   ret += gen_if(ifcond)
>>> -ret += _tree_to_qlit(ifobj, level)
>>> +ret += _tree_to_qlit(ifobj, level, suppress_first_indent)
>> 
>> Why do you need to pass on @suppress_first_indent now?
>> 
>
> We either never should or we always should have. This is just in the 
> case that "suppress first indent" is used on an annotated node. Which, 
> err, for the annotations we actually support right now (comment, ifcond) 
> -- we will reject in this case.
>
> But it felt precarious...

I suspect the factoring I suggested above will make this less
precarious, too.

>>>   if ifcond:
>>>   ret += '\n' + gen_endif(ifcond)
>>>   return ret
>>> @@ -152,7 +154,7 @@ def __init__(self, prefix: str, unmask: bool):
>>>   ' * QAPI/QMP schema introspection', __doc__)
>>>   self._unmask = unmask
>>>   self._schema: Optional[QAPISchema] = None
>>> -self._trees: List[TreeValue] = []
>>> +self._trees: List[Annotated] = []
>>>   self._used_types: List[QAPISchemaType] = []
>>>   self._name_map: Dict[str, str] = {}
>>>   self._genc.add(mcgen('''
>>> @@ -219,7 +221,8 @@ def _use_type(self, typ: QAPISchemaType) -> str:
>>>   
>>>   @classmethod
>>>   def _gen_features(cls,
>>> -  features: List[QAPISchemaFeature]) -> 
>>> List[TreeValue]:
>>> +  features: List[QAPISchemaFeature]
>>> +  ) -> List[Annotated]:
>>>   return [_make_tree(f.name, f.ifcond) for f in features]
>>>   
>>>   def _gen_tree(self, name: str, mtype: str, obj: _DObject,
>>> @@ -239,7 +242,7 @@ def _gen_tree(self, name: str, mtype: str, obj: 
>>> _DObject,
>>>   self._trees.append(_make_tree(obj, ifcond, extra))
>>>   
>>>   def _gen_member(self,
>>> -member: QAPISchemaObjectTypeMember) -> TreeValue:
>>> +member: QAPISchemaObjectTypeMember) -> Annotated:
>>>   obj: _DObject = {
>>>   'name': member.name,
>>>   'type': self._use_type(member.type)
>>> @@ -255,7 +258,7 @@ def _gen_variants(self, tag_n

Are user static builds really dynamically linked ?

2020-12-15 Thread Tj (Elloe Linux)
user --static builds are apparently resulting in dynamically linked
executables (to the glibc library, not other shared objects )

Concise summary:

$ file ../qemu-aarch64_v*

../qemu-aarch64_v4.2.1: ELF 64-bit LSB executable, x86-64, version 1
(GNU/Linux), statically linked,
BuildID[sha1]=70f5e10ac0eb9b63d7758850e2f18d0a047d4b79, for GNU/Linux
3.2.0, with debug_info, not stripped

../qemu-aarch64_v5.2:   ELF 64-bit LSB shared object, x86-64, version 1
(GNU/Linux), dynamically linked,
BuildID[sha1]=91fda2fa08f46d1bb6d19b6f72a4819a7c20fd7e, for GNU/Linux
3.2.0, stripped

$ ldd  ../qemu-aarch64_v*

../qemu-aarch64_v4.2.1:
not a dynamic executable
../qemu-aarch64_v5.2:
statically linked


Between v4.2.1 and HEAD and (trying to) perform git-bisect builds using:

$ ../../qemu/configure --disable-system --enable-linux-user --static
--target-list=aarch64-linux-user

All builds from v5.x onwards report:

$ file qemu-aarch64
qemu-aarch64: ELF 64-bit LSB shared object, x86-64, version 1
(GNU/Linux), dynamically linked,
BuildID[sha1]=546ba11f0de940f7f3cbfaffae3c2bb54b683386, for GNU/Linux
3.2.0, with debug_info, not stripped

Whereas builds of v4.2.1 report:

$ file ./aarch64-linux-user/qemu-aarch64
./aarch64-linux-user/qemu-aarch64: ELF 64-bit LSB executable, x86-64,
version 1 (GNU/Linux), statically linked,
BuildID[sha1]=70f5e10ac0eb9b63d7758850e2f18d0a047d4b79, for GNU/Linux
3.2.0, with debug_info, not stripped

... the same as the v4.2.0 built by Debian/Ubuntu:

$ file /usr/bin/qemu-aarch64-static
/usr/bin/qemu-aarch64-static: ELF 64-bit LSB executable, x86-64, version
1 (GNU/Linux), statically linked,
BuildID[sha1]=abad039a2cfc5bc87215554230a572b085fbc37a, for GNU/Linux
3.2.0, with debug_info, not stripped



This could be a problem because when the executable is dynamically
linked to glibc the same glibc version needs to be installed in the
chroot and that isn't always possible.

I'm unsure whether this is a cosmetic issue of file/ldd reporting or is
a regression.

Hit this whilst in the process of trying to isolate commits that fixed
another issue where using qemu-aarch64 on x86_64 Debian/Ubuntu host with
a foreign architecture chroot that results in "handle_cpu_signal
received signal outside vCPU context" when doing "chroot
debian-buster-aarch64 aptitude full-upgrade".



Re: [PATCH REPOST] spapr: Allow memory unplug to always succeed

2020-12-15 Thread David Gibson
On Mon, Dec 14, 2020 at 11:05:50AM +0100, Greg Kurz wrote:
65;6201;1c> It is currently impossible to hot-unplug a memory device between
> machine reset and CAS.
> 
> (qemu) device_del dimm1
> Error: Memory hot unplug not supported for this guest
> 
> This limitation was introduced in order to provide an explicit
> error path for older guests that didn't support hot-plug event
> sources (and thus memory hot-unplug).
> 
> The linux kernel has been supporting these since 4.11. All recent
> enough guests are thus capable of handling the removal of a memory
> device at all time, including during early boot.
> 
> Lift the limitation for the latest machine type. This means that
> trying to unplug memory from a guest that doesn't support it will
> likely just do nothing and the memory will only get removed at
> next reboot. Such older guests can still get the existing behavior
> by using an older machine type.
> 
> Signed-off-by: Greg Kurz 
> ---
> This patch was initially posted before the compat machine types
> for 6.0 got merged upstream. During the same period, David was
> also transitioning from github to gitlab, and the patch didn't
> applied cleanly. Now it does. Just reposting it unchanged for
> convenience.

Applied to ppc-for-6.0, thanks.

> ---
>  hw/ppc/spapr.c |6 +-
>  hw/ppc/spapr_events.c  |3 ++-
>  include/hw/ppc/spapr.h |1 +
>  3 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index dee48a0043bb..481c800a5a33 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -4051,7 +4051,8 @@ static void 
> spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
>  SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
>  
>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> -if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
> +if (!smc->pre_6_0_memory_unplug ||
> +spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
>  spapr_memory_unplug_request(hotplug_dev, dev, errp);
>  } else {
>  /* NOTE: this means there is a window after guest reset, prior to
> @@ -4537,8 +4538,11 @@ DEFINE_SPAPR_MACHINE(6_0, "6.0", true);
>   */
>  static void spapr_machine_5_2_class_options(MachineClass *mc)
>  {
> +SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
> +
>  spapr_machine_6_0_class_options(mc);
>  compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
> +smc->pre_6_0_memory_unplug = true;
>  }
>  
>  DEFINE_SPAPR_MACHINE(5_2, "5.2", false);
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index 3f37b49fd8ad..6aedd988b3d0 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -658,7 +658,8 @@ static void spapr_hotplug_req_event(uint8_t hp_id, 
> uint8_t hp_action,
>  /* we should not be using count_indexed value unless the guest
>   * supports dedicated hotplug event source
>   */
> -g_assert(spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT));
> +g_assert(!SPAPR_MACHINE_GET_CLASS(spapr)->pre_6_0_memory_unplug ||
> + spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT));
>  hp->drc_id.count_indexed.count =
>  cpu_to_be32(drc_id->count_indexed.count);
>  hp->drc_id.count_indexed.index =
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index e0f10f252c08..06a5b4259f20 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -139,6 +139,7 @@ struct SpaprMachineClass {
>  hwaddr rma_limit;  /* clamp the RMA to this size */
>  bool pre_5_1_assoc_refpoints;
>  bool pre_5_2_numa_associativity;
> +bool pre_6_0_memory_unplug;
>  
>  bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
>uint64_t *buid, hwaddr *pio, 
> 
> 

-- 
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] spapr: Fix DR properties of the root node

2020-12-15 Thread David Gibson
On Mon, Dec 14, 2020 at 12:19:55PM +0100, Greg Kurz wrote:
> Section 13.5.2 of LoPAPR mandates various DR related indentifiers
> for all hot-pluggable entities to be exposed in the "ibm,drc-indexes",
> "ibm,drc-power-domains", "ibm,drc-names" and "ibm,drc-types" properties
> of their parent node. These properties are created with spapr_dt_drc().
> 
> PHBs and LMBs are both children of the machine. Their DR identifiers
> are thus supposed to be exposed in the afore mentioned properties of
> the root node.
> 
> When PHB hot-plug support was added, an extra call to spapr_dt_drc()
> was introduced: this overwrites the existing properties, previously
> populated with the LMB identifiers, and they end up containing only
> PHB identifiers. This went unseen so far because linux doesn't care,
> but this is still not conformant with LoPAPR.
> 
> Fortunately spapr_dt_drc() is able to handle multiple DR entity types
> at the same time. Use that to handle DR indentifiers for PHBs and LMBs
> with a single call to spapr_dt_drc(). While here also account for PMEM
> DR identifiers, which were forgotten when NVDIMM hot-plug support was
> added. Also add an assert to prevent further misuse of spapr_dt_drc().
> 
> With -m 1G,maxmem=2G,slots=8 passed on the QEMU command line we get:
> 
> Without this patch:
> 
> /proc/device-tree/ibm,drc-indexes
>001f 2001 2002 2003
>2000 2005 2006 2007
>2004 2009 2008 2010
>2011 2012 2013 2014
>2015 2016 2017 2018
>2019 200a 200b 200c
>200d 200e 200f 201a
>201b 201c 201d 201e
> 
> These are the DRC indexes for the 31 possible PHBs.
> 
> With this patch:
> 
> /proc/device-tree/ibm,drc-indexes
>002b 9000 9001 9002
>9003 9004 9005 9006
>9007 2001 2002 2003
>2000 2005 2006 2007
>2004 2009 2008 2010
>2011 2012 2013 2014
>2015 2016 2017 2018
>2019 200a 200b 200c
>200d 200e 200f 201a
>201b 201c 201d 201e
>8004 8005 8006 8007
> 
> And now we also have the 4 ((2G - 1G) / 256M) LMBs and the
> 8 (slots) PMEMs.
> 
> Fixes: 3998ccd09298 ("spapr: populate PHB DRC entries for root DT node")
> Signed-off-by: Greg Kurz 

Oops, good catch.  Applied to ppc-for-6.0.

> ---
>  hw/ppc/spapr.c |   21 -
>  hw/ppc/spapr_drc.c |6 ++
>  2 files changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 16d42ba7a937..b2f9896c8bed 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1119,6 +1119,7 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool 
> reset, size_t space)
>  MachineState *machine = MACHINE(spapr);
>  MachineClass *mc = MACHINE_GET_CLASS(machine);
>  SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
> +uint32_t root_drc_type_mask = 0;
>  int ret;
>  void *fdt;
>  SpaprPhbState *phb;
> @@ -1193,8 +1194,18 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool 
> reset, size_t space)
>  
>  spapr_dt_cpus(fdt, spapr);
>  
> +/* ibm,drc-indexes and friends */
>  if (smc->dr_lmb_enabled) {
> -_FDT(spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
> +root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_LMB;
> +}
> +if (smc->dr_phb_enabled) {
> +root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PHB;
> +}
> +if (mc->nvdimm_supported) {
> +root_drc_type_mask |= SPAPR_DR_CONNECTOR_TYPE_PMEM;
> +}
> +if (root_drc_type_mask) {
> +_FDT(spapr_dt_drc(fdt, 0, NULL, root_drc_type_mask));
>  }
>  
>  if (mc->has_hotpluggable_cpus) {
> @@ -1232,14 +1243,6 @@ void *spapr_build_fdt(SpaprMachineState *spapr, bool 
> reset, size_t space)
>  }
>  }
>  
> -if (smc->dr_phb_enabled) {
> -ret = spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
> -if (ret < 0) {
> -error_report("Couldn't set up PHB DR device tree properties");
> -exit(1);
> -}
> -}
> -
>  /* NVDIMM devices */
>  if (mc->nvdimm_supported) {
>  spapr_dt_persistent_memory(spapr, fdt);
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index f991cf89a08a..fc7e321fcdf6 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -832,6 +832,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, 
> uint32_t drc_type_mask)
>  GString *drc_names, *drc_types;
>  int ret;
>  
> +/*
> + * This should really be only called once per node since it overwrites
> +   

[PATCH v15 13/13] block: apply COR-filter to block-stream jobs

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

This patch completes the series with the COR-filter applied to
block-stream operations.

Adding the filter makes it possible in future implement discarding
copied regions in backing files during the block-stream job, to reduce
the disk overuse (we need control on permissions).

Also, the filter now is smart enough to do copy-on-read with specified
base, so we have benefit on guest reads even when doing block-stream of
the part of the backing chain.

Several iotests are slightly modified due to filter insertion.

Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/stream.c | 105 ++---
 tests/qemu-iotests/030 |   8 +--
 tests/qemu-iotests/141.out |   2 +-
 tests/qemu-iotests/245 |  20 ---
 4 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 626dfa2b22..1fa742b0db 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -17,8 +17,10 @@
 #include "block/blockjob_int.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qdict.h"
 #include "qemu/ratelimit.h"
 #include "sysemu/block-backend.h"
+#include "block/copy-on-read.h"
 
 enum {
 /*
@@ -33,11 +35,11 @@ typedef struct StreamBlockJob {
 BlockJob common;
 BlockDriverState *base_overlay; /* COW overlay (stream from this) */
 BlockDriverState *above_base;   /* Node directly above the base */
+BlockDriverState *cor_filter_bs;
 BlockDriverState *target_bs;
 BlockdevOnError on_error;
 char *backing_file_str;
 bool bs_read_only;
-bool chain_frozen;
 } StreamBlockJob;
 
 static int coroutine_fn stream_populate(BlockBackend *blk,
@@ -45,17 +47,7 @@ static int coroutine_fn stream_populate(BlockBackend *blk,
 {
 assert(bytes < SIZE_MAX);
 
-return blk_co_preadv(blk, offset, bytes, NULL,
- BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH);
-}
-
-static void stream_abort(Job *job)
-{
-StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
-
-if (s->chain_frozen) {
-bdrv_unfreeze_backing_chain(s->target_bs, s->above_base);
-}
+return blk_co_preadv(blk, offset, bytes, NULL, BDRV_REQ_PREFETCH);
 }
 
 static int stream_prepare(Job *job)
@@ -67,8 +59,9 @@ static int stream_prepare(Job *job)
 Error *local_err = NULL;
 int ret = 0;
 
-bdrv_unfreeze_backing_chain(s->target_bs, s->above_base);
-s->chain_frozen = false;
+/* We should drop filter at this point, as filter hold the backing chain */
+bdrv_cor_filter_drop(s->cor_filter_bs);
+s->cor_filter_bs = NULL;
 
 if (bdrv_cow_child(unfiltered_bs)) {
 const char *base_id = NULL, *base_fmt = NULL;
@@ -94,6 +87,11 @@ static void stream_clean(Job *job)
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockJob *bjob = &s->common;
 
+if (s->cor_filter_bs) {
+bdrv_cor_filter_drop(s->cor_filter_bs);
+s->cor_filter_bs = NULL;
+}
+
 /* Reopen the image back in read-only mode if necessary */
 if (s->bs_read_only) {
 /* Give up write permissions before making it read-only */
@@ -109,7 +107,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockBackend *blk = s->common.blk;
 BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
-bool enable_cor = !bdrv_cow_child(s->base_overlay);
 int64_t len;
 int64_t offset = 0;
 uint64_t delay_ns = 0;
@@ -127,15 +124,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 }
 job_progress_set_remaining(&s->common.job, len);
 
-/* Turn on copy-on-read for the whole block device so that guest read
- * requests help us make progress.  Only do this when copying the entire
- * backing chain since the copy-on-read operation does not take base into
- * account.
- */
-if (enable_cor) {
-bdrv_enable_copy_on_read(s->target_bs);
-}
-
 for ( ; offset < len; offset += n) {
 bool copy;
 int ret;
@@ -194,10 +182,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 }
 }
 
-if (enable_cor) {
-bdrv_disable_copy_on_read(s->target_bs);
-}
-
 /* Do not remove the backing file if an error was there but ignored. */
 return error;
 }
@@ -209,7 +193,6 @@ static const BlockJobDriver stream_job_driver = {
 .free  = block_job_free,
 .run   = stream_run,
 .prepare   = stream_prepare,
-.abort = stream_abort,
 .clean = stream_clean,
 .user_resume   = block_job_user_resume,
 },
@@ -228,7 +211,9 @@ void stream_start(const char *job_id, BlockDriverState *bs,
 bool bs_read_only;
 int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
 BlockDriverState *base_overlay;
+BlockDriverState *cor_fil

[PATCH v15 07/13] block: include supported_read_flags into BDS structure

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Add the new member supported_read_flags to the BlockDriverState
structure. It will control the flags set for copy-on-read operations.
Make the block generic layer evaluate supported read flags before they
go to a block driver.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
 [vsementsov: use assert instead of abort]
Reviewed-by: Max Reitz 
---
 include/block/block_int.h |  4 
 block/io.c| 10 --
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index 6f778e2517..1f56443440 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -881,6 +881,10 @@ struct BlockDriverState {
 /* I/O Limits */
 BlockLimits bl;
 
+/*
+ * Flags honored during pread
+ */
+unsigned int supported_read_flags;
 /* Flags honored during pwrite (so far: BDRV_REQ_FUA,
  * BDRV_REQ_WRITE_UNCHANGED).
  * If a driver does not support BDRV_REQ_WRITE_UNCHANGED, those
diff --git a/block/io.c b/block/io.c
index 24205f5168..851fe53604 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1431,6 +1431,9 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild 
*child,
 if (flags & BDRV_REQ_COPY_ON_READ) {
 int64_t pnum;
 
+/* The flag BDRV_REQ_COPY_ON_READ has reached its addressee */
+flags &= ~BDRV_REQ_COPY_ON_READ;
+
 ret = bdrv_is_allocated(bs, offset, bytes, &pnum);
 if (ret < 0) {
 goto out;
@@ -1452,9 +1455,11 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild 
*child,
 goto out;
 }
 
+assert(!(flags & ~bs->supported_read_flags));
+
 max_bytes = ROUND_UP(MAX(0, total_bytes - offset), align);
 if (bytes <= max_bytes && bytes <= max_transfer) {
-ret = bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, 0);
+ret = bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, flags);
 goto out;
 }
 
@@ -1467,7 +1472,8 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild 
*child,
 
 ret = bdrv_driver_preadv(bs, offset + bytes - bytes_remaining,
  num, qiov,
- qiov_offset + bytes - bytes_remaining, 0);
+ qiov_offset + bytes - bytes_remaining,
+ flags);
 max_bytes -= num;
 } else {
 num = bytes_remaining;
-- 
2.25.4




Re: [PATCH] block: report errno when flock fcntl fails

2020-12-15 Thread Vladimir Sementsov-Ogievskiy

15.12.2020 22:01, David Edmondson wrote:

When a call to fcntl(2) for the purpose of manipulating file locks
fails, report the error returned by fcntl.

Signed-off-by: David Edmondson


Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



[PATCH v15 12/13] block/stream: add s->target_bs

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
Add a direct link to target bs for convenience and to simplify
following commit which will insert COR filter above target bs.

This is a part of original commit written by Andrey.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 block/stream.c | 23 ++-
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 045d6bc76b..626dfa2b22 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -33,6 +33,7 @@ typedef struct StreamBlockJob {
 BlockJob common;
 BlockDriverState *base_overlay; /* COW overlay (stream from this) */
 BlockDriverState *above_base;   /* Node directly above the base */
+BlockDriverState *target_bs;
 BlockdevOnError on_error;
 char *backing_file_str;
 bool bs_read_only;
@@ -53,23 +54,20 @@ static void stream_abort(Job *job)
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 
 if (s->chain_frozen) {
-BlockJob *bjob = &s->common;
-bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->above_base);
+bdrv_unfreeze_backing_chain(s->target_bs, s->above_base);
 }
 }
 
 static int stream_prepare(Job *job)
 {
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
-BlockJob *bjob = &s->common;
-BlockDriverState *bs = blk_bs(bjob->blk);
-BlockDriverState *unfiltered_bs = bdrv_skip_filters(bs);
+BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
 BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base);
 BlockDriverState *unfiltered_base = bdrv_skip_filters(base);
 Error *local_err = NULL;
 int ret = 0;
 
-bdrv_unfreeze_backing_chain(bs, s->above_base);
+bdrv_unfreeze_backing_chain(s->target_bs, s->above_base);
 s->chain_frozen = false;
 
 if (bdrv_cow_child(unfiltered_bs)) {
@@ -95,13 +93,12 @@ static void stream_clean(Job *job)
 {
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockJob *bjob = &s->common;
-BlockDriverState *bs = blk_bs(bjob->blk);
 
 /* Reopen the image back in read-only mode if necessary */
 if (s->bs_read_only) {
 /* Give up write permissions before making it read-only */
 blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
-bdrv_reopen_set_read_only(bs, true, NULL);
+bdrv_reopen_set_read_only(s->target_bs, true, NULL);
 }
 
 g_free(s->backing_file_str);
@@ -111,8 +108,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 {
 StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
 BlockBackend *blk = s->common.blk;
-BlockDriverState *bs = blk_bs(blk);
-BlockDriverState *unfiltered_bs = bdrv_skip_filters(bs);
+BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
 bool enable_cor = !bdrv_cow_child(s->base_overlay);
 int64_t len;
 int64_t offset = 0;
@@ -125,7 +121,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 return 0;
 }
 
-len = bdrv_getlength(bs);
+len = bdrv_getlength(s->target_bs);
 if (len < 0) {
 return len;
 }
@@ -137,7 +133,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
  * account.
  */
 if (enable_cor) {
-bdrv_enable_copy_on_read(bs);
+bdrv_enable_copy_on_read(s->target_bs);
 }
 
 for ( ; offset < len; offset += n) {
@@ -199,7 +195,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
 }
 
 if (enable_cor) {
-bdrv_disable_copy_on_read(bs);
+bdrv_disable_copy_on_read(s->target_bs);
 }
 
 /* Do not remove the backing file if an error was there but ignored. */
@@ -314,6 +310,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
 s->base_overlay = base_overlay;
 s->above_base = above_base;
 s->backing_file_str = g_strdup(backing_file_str);
+s->target_bs = bs;
 s->bs_read_only = bs_read_only;
 s->chain_frozen = true;
 
-- 
2.25.4




[PATCH v15 08/13] copy-on-read: skip non-guest reads if no copy needed

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

If the flag BDRV_REQ_PREFETCH was set, skip idling read/write
operations in COR-driver. It can be taken into account for the
COR-algorithms optimization. That check is being made during the
block stream job by the moment.

Add the BDRV_REQ_PREFETCH flag to the supported_read_flags of the
COR-filter.

block: Modify the comment for the flag BDRV_REQ_PREFETCH as we are
going to use it alone and pass it to the COR-filter driver for further
processing.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 include/block/block.h |  8 +---
 block/copy-on-read.c  | 14 ++
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index 8ea794959b..f652f31406 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -81,9 +81,11 @@ typedef enum {
 BDRV_REQ_NO_FALLBACK= 0x100,
 
 /*
- * BDRV_REQ_PREFETCH may be used only together with BDRV_REQ_COPY_ON_READ
- * on read request and means that caller doesn't really need data to be
- * written to qiov parameter which may be NULL.
+ * BDRV_REQ_PREFETCH makes sense only in the context of copy-on-read
+ * (i.e., together with the BDRV_REQ_COPY_ON_READ flag or when a COR
+ * filter is involved), in which case it signals that the COR operation
+ * need not read the data into memory (qiov) but only ensure they are
+ * copied to the top layer (i.e., that COR operation is done).
  */
 BDRV_REQ_PREFETCH  = 0x200,
 /* Mask of valid flags */
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index 71560984f6..9cad9e1b8c 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -50,6 +50,8 @@ static int cor_open(BlockDriverState *bs, QDict *options, int 
flags,
 return -EINVAL;
 }
 
+bs->supported_read_flags = BDRV_REQ_PREFETCH;
+
 bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
 (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
 
@@ -172,10 +174,14 @@ static int coroutine_fn 
cor_co_preadv_part(BlockDriverState *bs,
 }
 }
 
-ret = bdrv_co_preadv_part(bs->file, offset, n, qiov, qiov_offset,
-  local_flags);
-if (ret < 0) {
-return ret;
+/* Skip if neither read nor write are needed */
+if ((local_flags & (BDRV_REQ_PREFETCH | BDRV_REQ_COPY_ON_READ)) !=
+BDRV_REQ_PREFETCH) {
+ret = bdrv_co_preadv_part(bs->file, offset, n, qiov, qiov_offset,
+  local_flags);
+if (ret < 0) {
+return ret;
+}
 }
 
 offset += n;
-- 
2.25.4




[PATCH v15 03/13] copy-on-read: add filter drop function

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Provide API for the COR-filter removal. Also, drop the filter child
permissions for an inactive state when the filter node is being
removed.
To insert the filter, the block generic layer function
bdrv_insert_node() can be used.
The new function bdrv_cor_filter_drop() may be considered as an
intermediate solution before the QEMU permission update system has
overhauled. Then we are able to implement the API function
bdrv_remove_node() on the block generic layer.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 block/copy-on-read.h | 32 +
 block/copy-on-read.c | 56 
 2 files changed, 88 insertions(+)
 create mode 100644 block/copy-on-read.h

diff --git a/block/copy-on-read.h b/block/copy-on-read.h
new file mode 100644
index 00..7bf405dccd
--- /dev/null
+++ b/block/copy-on-read.h
@@ -0,0 +1,32 @@
+/*
+ * Copy-on-read filter block driver
+ *
+ * The filter driver performs Copy-On-Read (COR) operations
+ *
+ * Copyright (c) 2018-2020 Virtuozzo International GmbH.
+ *
+ * Author:
+ *   Andrey Shinkevich 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef BLOCK_COPY_ON_READ
+#define BLOCK_COPY_ON_READ
+
+#include "block/block_int.h"
+
+void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs);
+
+#endif /* BLOCK_COPY_ON_READ */
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index cb03e0f2d3..618c4c4f43 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -23,11 +23,20 @@
 #include "qemu/osdep.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
+#include "qapi/error.h"
+#include "block/copy-on-read.h"
+
+
+typedef struct BDRVStateCOR {
+bool active;
+} BDRVStateCOR;
 
 
 static int cor_open(BlockDriverState *bs, QDict *options, int flags,
 Error **errp)
 {
+BDRVStateCOR *state = bs->opaque;
+
 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
false, errp);
@@ -42,6 +51,13 @@ static int cor_open(BlockDriverState *bs, QDict *options, 
int flags,
 ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
 bs->file->bs->supported_zero_flags);
 
+state->active = true;
+
+/*
+ * We don't need to call bdrv_child_refresh_perms() now as the permissions
+ * will be updated later when the filter node gets its parent.
+ */
+
 return 0;
 }
 
@@ -57,6 +73,17 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild 
*c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
 {
+BDRVStateCOR *s = bs->opaque;
+
+if (!s->active) {
+/*
+ * While the filter is being removed
+ */
+*nperm = 0;
+*nshared = BLK_PERM_ALL;
+return;
+}
+
 *nperm = perm & PERM_PASSTHROUGH;
 *nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
 
@@ -135,6 +162,7 @@ static void cor_lock_medium(BlockDriverState *bs, bool 
locked)
 
 static BlockDriver bdrv_copy_on_read = {
 .format_name= "copy-on-read",
+.instance_size  = sizeof(BDRVStateCOR),
 
 .bdrv_open  = cor_open,
 .bdrv_child_perm= cor_child_perm,
@@ -154,6 +182,34 @@ static BlockDriver bdrv_copy_on_read = {
 .is_filter  = true,
 };
 
+
+void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs)
+{
+BdrvChild *child;
+BlockDriverState *bs;
+BDRVStateCOR *s = cor_filter_bs->opaque;
+
+child = bdrv_filter_child(cor_filter_bs);
+if (!child) {
+return;
+}
+bs = child->bs;
+
+/* Retain the BDS until we complete the graph change. */
+bdrv_ref(bs);
+/* Hold a guest back from writing while permissions are being reset. */
+bdrv_drained_begin(bs);
+/* Drop permissions before the graph change. */
+s->active = false;
+bdrv_child_refresh_perms(cor_filter_bs, child, &error_abort);
+bdrv_replace_node(cor_filter_bs, bs, &error_abort);
+
+bdrv_drained_end(bs);
+bdrv_unref(bs);
+bdrv_unref(cor_filter_bs);
+}
+
+
 static void bdrv_copy_on_read_init(void)
 {
 bdrv_regis

[PATCH v15 11/13] iotests: 30: prepare to COR filter insertion by stream job

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
test_stream_parallel run parallel stream jobs, intersecting so that top
of one is base of another. It's OK now, but it would be a problem if
insert the filter, as one job will want to use another job's filter as
above_base node.

Correct thing to do is move to new interface: "bottom" argument instead
of base. This guarantees that jobs don't intersect by their actions.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 tests/qemu-iotests/030 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index dcb4b5d6a6..bd8cf9cff7 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -245,7 +245,9 @@ class TestParallelOps(iotests.QMPTestCase):
 node_name = 'node%d' % i
 job_id = 'stream-%s' % node_name
 pending_jobs.append(job_id)
-result = self.vm.qmp('block-stream', device=node_name, 
job_id=job_id, base=self.imgs[i-2], speed=1024)
+result = self.vm.qmp('block-stream', device=node_name,
+ job_id=job_id, bottom=f'node{i-1}',
+ speed=1024)
 self.assert_qmp(result, 'return', {})
 
 for job in pending_jobs:
-- 
2.25.4




[PATCH v15 06/13] iotests: add #310 to test bottom node in COR driver

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

The test case #310 is similar to #216 by Max Reitz. The difference is
that the test #310 involves a bottom node to the COR filter driver.

Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
  [vsementsov: detach backing to test reads from top, limit to qcow2]
---
 tests/qemu-iotests/310 | 116 +
 tests/qemu-iotests/310.out |  15 +
 tests/qemu-iotests/group   |   1 +
 3 files changed, 132 insertions(+)
 create mode 100755 tests/qemu-iotests/310
 create mode 100644 tests/qemu-iotests/310.out

diff --git a/tests/qemu-iotests/310 b/tests/qemu-iotests/310
new file mode 100755
index 00..a35e8e14f5
--- /dev/null
+++ b/tests/qemu-iotests/310
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+#
+# Copy-on-read tests using a COR filter with a bottom node
+#
+# Copyright (C) 2018 Red Hat, Inc.
+# Copyright (c) 2020 Virtuozzo International GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import iotests
+from iotests import log, qemu_img, qemu_io_silent
+
+# Need backing file support
+iotests.script_initialize(supported_fmts=['qcow2'],
+  supported_platforms=['linux'])
+
+log('')
+log('=== Copy-on-read across nodes ===')
+log('')
+
+# This test is similar to the 216 one by Max Reitz 
+# The difference is that this test case involves a bottom node to the
+# COR filter driver.
+
+with iotests.FilePath('base.img') as base_img_path, \
+ iotests.FilePath('mid.img') as mid_img_path, \
+ iotests.FilePath('top.img') as top_img_path, \
+ iotests.VM() as vm:
+
+log('--- Setting up images ---')
+log('')
+
+assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0
+assert qemu_io_silent(base_img_path, '-c', 'write -P 1 0M 1M') == 0
+assert qemu_io_silent(base_img_path, '-c', 'write -P 1 3M 1M') == 0
+assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path,
+'-F', iotests.imgfmt, mid_img_path) == 0
+assert qemu_io_silent(mid_img_path,  '-c', 'write -P 3 2M 1M') == 0
+assert qemu_io_silent(mid_img_path,  '-c', 'write -P 3 4M 1M') == 0
+assert qemu_img('create', '-f', iotests.imgfmt, '-b', mid_img_path,
+'-F', iotests.imgfmt, top_img_path) == 0
+assert qemu_io_silent(top_img_path,  '-c', 'write -P 2 1M 1M') == 0
+
+#  0 1 2 3 4
+# top2
+# mid  3   3
+# base 1 1
+
+log('Done')
+
+log('')
+log('--- Doing COR ---')
+log('')
+
+vm.launch()
+
+log(vm.qmp('blockdev-add',
+   node_name='node0',
+   driver='copy-on-read',
+   bottom='node2',
+   file={
+   'driver': iotests.imgfmt,
+   'file': {
+   'driver': 'file',
+   'filename': top_img_path
+   },
+   'backing': {
+   'node-name': 'node2',
+   'driver': iotests.imgfmt,
+   'file': {
+   'driver': 'file',
+   'filename': mid_img_path
+   },
+   'backing': {
+   'driver': iotests.imgfmt,
+   'file': {
+   'driver': 'file',
+   'filename': base_img_path
+   }
+   },
+   }
+   }))
+
+# Trigger COR
+log(vm.qmp('human-monitor-command',
+   command_line='qemu-io node0 "read 0 5M"'))
+
+vm.shutdown()
+
+log('')
+log('--- Checking COR result ---')
+log('')
+
+# Detach backing to check that we can read the data from the top level now
+assert qemu_img('rebase', '-u', '-b', '', '-f', iotests.imgfmt,
+top_img_path,) == 0
+
+assert qemu_io_silent(top_img_path,  '-c', 'read -P 0 0 1M') == 0
+assert qemu_io_silent(top_img_path,  '-c', 'read -P 2 1M 1M') == 0
+assert qemu_io_silent(top_img_path,  '-c', 'read -P 3 2M 1M') == 0
+assert qemu_io_silent(top_img_path,  '-c', 'read -P 0 3M 1M') == 0
+assert qemu_io_silent(top_img_path,  '-c', 'read -P 3 4M 1M') == 0
+
+log('Done')
diff --git a/tests/qemu-iotests/310.out b/tests/qemu-iotests/310.out
new file mode 100644
index 00

[PATCH v15 01/13] copy-on-read: support preadv/pwritev_part functions

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Add support for the recently introduced functions
bdrv_co_preadv_part()
and
bdrv_co_pwritev_part()
to the COR-filter driver.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/copy-on-read.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index 2816e61afe..cb03e0f2d3 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -74,21 +74,25 @@ static int64_t cor_getlength(BlockDriverState *bs)
 }
 
 
-static int coroutine_fn cor_co_preadv(BlockDriverState *bs,
-  uint64_t offset, uint64_t bytes,
-  QEMUIOVector *qiov, int flags)
+static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
+   uint64_t offset, uint64_t bytes,
+   QEMUIOVector *qiov,
+   size_t qiov_offset,
+   int flags)
 {
-return bdrv_co_preadv(bs->file, offset, bytes, qiov,
-  flags | BDRV_REQ_COPY_ON_READ);
+return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
+   flags | BDRV_REQ_COPY_ON_READ);
 }
 
 
-static int coroutine_fn cor_co_pwritev(BlockDriverState *bs,
-   uint64_t offset, uint64_t bytes,
-   QEMUIOVector *qiov, int flags)
+static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
+uint64_t offset,
+uint64_t bytes,
+QEMUIOVector *qiov,
+size_t qiov_offset, int flags)
 {
-
-return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
+flags);
 }
 
 
@@ -137,8 +141,8 @@ static BlockDriver bdrv_copy_on_read = {
 
 .bdrv_getlength = cor_getlength,
 
-.bdrv_co_preadv = cor_co_preadv,
-.bdrv_co_pwritev= cor_co_pwritev,
+.bdrv_co_preadv_part= cor_co_preadv_part,
+.bdrv_co_pwritev_part   = cor_co_pwritev_part,
 .bdrv_co_pwrite_zeroes  = cor_co_pwrite_zeroes,
 .bdrv_co_pdiscard   = cor_co_pdiscard,
 .bdrv_co_pwritev_compressed = cor_co_pwritev_compressed,
-- 
2.25.4




[PATCH v15 09/13] stream: rework backing-file changing

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Stream in stream_prepare calls bdrv_change_backing_file() to change
backing-file in the metadata of bs.

It may use either backing-file parameter given by user or just take
filename of base on job start.

Backing file format is determined by base on job finish.

There are some problems with this design, we solve only two by this
patch:

1. Consider scenario with backing-file unset. Current concept of stream
supports changing of the base during the job (we don't freeze link to
the base). So, we should not save base filename at job start,

  - let's determine name of the base on job finish.

2. Using direct base to determine filename and format is not very good:
base node may be a filter, so its filename may be JSON, and format_name
is not good for storing into qcow2 metadata as backing file format.

  - let's use unfiltered_base

Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
  [vsementsov: change commit subject, change logic in stream_prepare]
---
 block/stream.c | 9 +
 blockdev.c | 8 +---
 2 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 6e281c71ac..6a525a5edf 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -65,6 +65,7 @@ static int stream_prepare(Job *job)
 BlockDriverState *bs = blk_bs(bjob->blk);
 BlockDriverState *unfiltered_bs = bdrv_skip_filters(bs);
 BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base);
+BlockDriverState *unfiltered_base = bdrv_skip_filters(base);
 Error *local_err = NULL;
 int ret = 0;
 
@@ -73,10 +74,10 @@ static int stream_prepare(Job *job)
 
 if (bdrv_cow_child(unfiltered_bs)) {
 const char *base_id = NULL, *base_fmt = NULL;
-if (base) {
-base_id = s->backing_file_str;
-if (base->drv) {
-base_fmt = base->drv->format_name;
+if (unfiltered_base) {
+base_id = s->backing_file_str ?: unfiltered_base->filename;
+if (unfiltered_base->drv) {
+base_fmt = unfiltered_base->drv->format_name;
 }
 }
 bdrv_set_backing_hd(unfiltered_bs, base, &local_err);
diff --git a/blockdev.c b/blockdev.c
index c290cb1dca..b58f36fc31 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2510,7 +2510,6 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 BlockDriverState *base_bs = NULL;
 AioContext *aio_context;
 Error *local_err = NULL;
-const char *base_name = NULL;
 int job_flags = JOB_DEFAULT;
 
 if (!has_on_error) {
@@ -2538,7 +2537,6 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 goto out;
 }
 assert(bdrv_get_aio_context(base_bs) == aio_context);
-base_name = base;
 }
 
 if (has_base_node) {
@@ -2553,7 +2551,6 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 }
 assert(bdrv_get_aio_context(base_bs) == aio_context);
 bdrv_refresh_filename(base_bs);
-base_name = base_bs->filename;
 }
 
 /* Check for op blockers in the whole chain between bs and base */
@@ -2573,9 +2570,6 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 goto out;
 }
 
-/* backing_file string overrides base bs filename */
-base_name = has_backing_file ? backing_file : base_name;
-
 if (has_auto_finalize && !auto_finalize) {
 job_flags |= JOB_MANUAL_FINALIZE;
 }
@@ -2583,7 +2577,7 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 job_flags |= JOB_MANUAL_DISMISS;
 }
 
-stream_start(has_job_id ? job_id : NULL, bs, base_bs, base_name,
+stream_start(has_job_id ? job_id : NULL, bs, base_bs, backing_file,
  job_flags, has_speed ? speed : 0, on_error,
  filter_node_name, &local_err);
 if (local_err) {
-- 
2.25.4




[PATCH v15 05/13] qapi: copy-on-read filter: add 'bottom' option

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Add an option to limit copy-on-read operations to specified sub-chain
of backing-chain, to make copy-on-read filter useful for block-stream
job.

Suggested-by: Max Reitz 
Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
  [vsementsov: change subject, modified to freeze the chain,
   do some fixes]
---
 qapi/block-core.json | 20 -
 block/copy-on-read.c | 98 +++-
 2 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6050cf3c39..b8094a5ec7 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3942,6 +3942,24 @@
   'data': { 'throttle-group': 'str',
 'file' : 'BlockdevRef'
  } }
+
+##
+# @BlockdevOptionsCor:
+#
+# Driver specific block device options for the copy-on-read driver.
+#
+# @bottom: The name of a non-filter node (allocation-bearing layer) that
+#  limits the COR operations in the backing chain (inclusive), so
+#  that no data below this node will be copied by this filter.
+#  If option is absent, the limit is not applied, so that data
+#  from all backing layers may be copied.
+#
+# Since: 6.0
+##
+{ 'struct': 'BlockdevOptionsCor',
+  'base': 'BlockdevOptionsGenericFormat',
+  'data': { '*bottom': 'str' } }
+
 ##
 # @BlockdevOptions:
 #
@@ -3994,7 +4012,7 @@
   'bochs':  'BlockdevOptionsGenericFormat',
   'cloop':  'BlockdevOptionsGenericFormat',
   'compress':   'BlockdevOptionsGenericFormat',
-  'copy-on-read':'BlockdevOptionsGenericFormat',
+  'copy-on-read':'BlockdevOptionsCor',
   'dmg':'BlockdevOptionsGenericFormat',
   'file':   'BlockdevOptionsFile',
   'ftp':'BlockdevOptionsCurlFtp',
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index 618c4c4f43..71560984f6 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -24,18 +24,24 @@
 #include "block/block_int.h"
 #include "qemu/module.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
 #include "block/copy-on-read.h"
 
 
 typedef struct BDRVStateCOR {
 bool active;
+BlockDriverState *bottom_bs;
+bool chain_frozen;
 } BDRVStateCOR;
 
 
 static int cor_open(BlockDriverState *bs, QDict *options, int flags,
 Error **errp)
 {
+BlockDriverState *bottom_bs = NULL;
 BDRVStateCOR *state = bs->opaque;
+/* Find a bottom node name, if any */
+const char *bottom_node = qdict_get_try_str(options, "bottom");
 
 bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
@@ -51,7 +57,38 @@ static int cor_open(BlockDriverState *bs, QDict *options, 
int flags,
 ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
 bs->file->bs->supported_zero_flags);
 
+if (bottom_node) {
+bottom_bs = bdrv_find_node(bottom_node);
+if (!bottom_bs) {
+error_setg(errp, "Bottom node '%s' not found", bottom_node);
+qdict_del(options, "bottom");
+return -EINVAL;
+}
+qdict_del(options, "bottom");
+
+if (!bottom_bs->drv) {
+error_setg(errp, "Bottom node '%s' not opened", bottom_node);
+return -EINVAL;
+}
+
+if (bottom_bs->drv->is_filter) {
+error_setg(errp, "Bottom node '%s' is a filter", bottom_node);
+return -EINVAL;
+}
+
+if (bdrv_freeze_backing_chain(bs, bottom_bs, errp) < 0) {
+return -EINVAL;
+}
+state->chain_frozen = true;
+
+/*
+ * We do freeze the chain, so it shouldn't be removed. Still, storing a
+ * pointer worth bdrv_ref().
+ */
+bdrv_ref(bottom_bs);
+}
 state->active = true;
+state->bottom_bs = bottom_bs;
 
 /*
  * We don't need to call bdrv_child_refresh_perms() now as the permissions
@@ -107,8 +144,46 @@ static int coroutine_fn 
cor_co_preadv_part(BlockDriverState *bs,
size_t qiov_offset,
int flags)
 {
-return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
-   flags | BDRV_REQ_COPY_ON_READ);
+int64_t n;
+int local_flags;
+int ret;
+BDRVStateCOR *state = bs->opaque;
+
+if (!state->bottom_bs) {
+return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
+   flags | BDRV_REQ_COPY_ON_READ);
+}
+
+while (bytes) {
+local_flags = flags;
+
+/* In case of failure, try to copy-on-read anyway */
+ret = bdrv_is_allocated(bs->file->bs, offset, bytes, &n);
+if (ret <= 0) {
+ret = 
bdrv_is_allocated_above(bdrv_backing_chain_next(bs->file->bs),
+  

[PATCH v15 10/13] qapi: block-stream: add "bottom" argument

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
The code already don't freeze base node and we try to make it prepared
for the situation when base node is changed during the operation. In
other words, block-stream doesn't own base node.

Let's introduce a new interface which should replace the current one,
which will in better relations with the code. Specifying bottom node
instead of base, and requiring it to be non-filter gives us the
following benefits:

 - drop difference between above_base and base_overlay, which will be
   renamed to just bottom, when old interface dropped

 - clean way to work with parallel streams/commits on the same backing
   chain, which otherwise become a problem when we introduce a filter
   for stream job

 - cleaner interface. Nobody will surprised the fact that base node may
   disappear during block-stream, when there is no word about "base" in
   the interface.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 qapi/block-core.json   | 12 ---
 include/block/block_int.h  |  1 +
 block/monitor/block-hmp-cmds.c |  3 +-
 block/stream.c | 50 +++-
 blockdev.c | 59 --
 5 files changed, 94 insertions(+), 31 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index b8094a5ec7..cb0066fd5c 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2517,10 +2517,14 @@
 # @device: the device or node name of the top image
 #
 # @base: the common backing file name.
-#It cannot be set if @base-node is also set.
+#It cannot be set if @base-node or @bottom is also set.
 #
 # @base-node: the node name of the backing file.
-# It cannot be set if @base is also set. (Since 2.8)
+# It cannot be set if @base or @bottom is also set. (Since 2.8)
+#
+# @bottom: the last node in the chain that should be streamed into
+#  top. It cannot be set if @base or @base-node is also set.
+#  It cannot be filter node. (Since 6.0)
 #
 # @backing-file: The backing file string to write into the top
 #image. This filename is not validated.
@@ -2576,8 +2580,8 @@
 ##
 { 'command': 'block-stream',
   'data': { '*job-id': 'str', 'device': 'str', '*base': 'str',
-'*base-node': 'str', '*backing-file': 'str', '*speed': 'int',
-'*on-error': 'BlockdevOnError',
+'*base-node': 'str', '*backing-file': 'str', '*bottom': 'str',
+'*speed': 'int', '*on-error': 'BlockdevOnError',
 '*filter-node-name': 'str',
 '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 1f56443440..4b8aa61fb4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1160,6 +1160,7 @@ int is_windows_drive(const char *filename);
  */
 void stream_start(const char *job_id, BlockDriverState *bs,
   BlockDriverState *base, const char *backing_file_str,
+  BlockDriverState *bottom,
   int creation_flags, int64_t speed,
   BlockdevOnError on_error,
   const char *filter_node_name,
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index e8a58f326e..afd75ab628 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -507,7 +507,8 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
 
 qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
- false, NULL, qdict_haskey(qdict, "speed"), speed, true,
+ false, NULL, false, NULL,
+ qdict_haskey(qdict, "speed"), speed, true,
  BLOCKDEV_ON_ERROR_REPORT, false, NULL, false, false, 
false,
  false, &error);
 
diff --git a/block/stream.c b/block/stream.c
index 6a525a5edf..045d6bc76b 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -221,6 +221,7 @@ static const BlockJobDriver stream_job_driver = {
 
 void stream_start(const char *job_id, BlockDriverState *bs,
   BlockDriverState *base, const char *backing_file_str,
+  BlockDriverState *bottom,
   int creation_flags, int64_t speed,
   BlockdevOnError on_error,
   const char *filter_node_name,
@@ -230,25 +231,42 @@ void stream_start(const char *job_id, BlockDriverState 
*bs,
 BlockDriverState *iter;
 bool bs_read_only;
 int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
-BlockDriverState *base_overlay = bdrv_find_overlay(bs, base);
+BlockDriverState *base_overlay;
 BlockDriverState *above_base;
 
-if (!base_overlay) {
-error_setg(errp, "'%s' is not in the backing chain of '%s'",
-   base->node_name, bs->node_name);
-return;
-}
+assert(!(base && bottom));
+assert(!(backing_file_s

[PATCH v15 02/13] block: add API function to insert a node

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Provide API for insertion a node to backing chain.

Suggested-by: Max Reitz 
Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 include/block/block.h |  2 ++
 block.c   | 25 +
 2 files changed, 27 insertions(+)

diff --git a/include/block/block.h b/include/block/block.h
index 5b81e33e94..8ea794959b 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -360,6 +360,8 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState 
*bs_top,
  Error **errp);
 void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
Error **errp);
+BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
+   int flags, Error **errp);
 
 int bdrv_parse_aio(const char *mode, int *flags);
 int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
diff --git a/block.c b/block.c
index 8f177504d4..8ed9c5eaf9 100644
--- a/block.c
+++ b/block.c
@@ -4704,6 +4704,31 @@ static void bdrv_delete(BlockDriverState *bs)
 g_free(bs);
 }
 
+BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
+   int flags, Error **errp)
+{
+BlockDriverState *new_node_bs;
+Error *local_err = NULL;
+
+new_node_bs = bdrv_open(NULL, NULL, node_options, flags, errp);
+if (new_node_bs == NULL) {
+error_prepend(errp, "Could not create node: ");
+return NULL;
+}
+
+bdrv_drained_begin(bs);
+bdrv_replace_node(bs, new_node_bs, &local_err);
+bdrv_drained_end(bs);
+
+if (local_err) {
+bdrv_unref(new_node_bs);
+error_propagate(errp, local_err);
+return NULL;
+}
+
+return new_node_bs;
+}
+
 /*
  * Run consistency checks on an image
  *
-- 
2.25.4




[PATCH v15 00/13] Apply COR-filter to the block-stream permanently

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
Hi all!

Here is a new version of cor-filter in block-stream series. Main change
is freezing the chain in cor-filter itself.

v15:
02: s/ =  / = /
add Max's r-b
03: add Max's r-b
04: since: 6.0
indent comment
add Max's r-b
05: changed commit msg
wording
document the default
since: 6.0
use bdrv_find_node(), fix errp overwriting
freeze the chain
check bottom is not filter
ref bottom_bs
06: limit to qcow2 to not care
use qemu-img rebase -u -b ''
07: use assert instead of abort
add Max's r-b
08: add Max's r-b
09: changed commit msg (was "stream: skip filters when writing backing file 
name to QCOW2 header")
keep mostly same logic for the case when backing-file is specified, don't 
do bdrv_find_backing_image()
10: don't restrict backing-file for now
11: add Max's r-b
12: add Max's r-b
13: chain is now frozen in filter, so the logic changed around add/remove 
fitlter

Andrey Shinkevich (10):
  copy-on-read: support preadv/pwritev_part functions
  block: add API function to insert a node
  copy-on-read: add filter drop function
  qapi: add filter-node-name to block-stream
  qapi: copy-on-read filter: add 'bottom' option
  iotests: add #310 to test bottom node in COR driver
  block: include supported_read_flags into BDS structure
  copy-on-read: skip non-guest reads if no copy needed
  stream: rework backing-file changing
  block: apply COR-filter to block-stream jobs

Vladimir Sementsov-Ogievskiy (3):
  qapi: block-stream: add "bottom" argument
  iotests: 30: prepare to COR filter insertion by stream job
  block/stream: add s->target_bs

 qapi/block-core.json   |  38 ++-
 block/copy-on-read.h   |  32 ++
 include/block/block.h  |  10 +-
 include/block/block_int.h  |  12 ++-
 block.c|  25 +
 block/copy-on-read.c   | 184 +---
 block/io.c |  10 +-
 block/monitor/block-hmp-cmds.c |   7 +-
 block/stream.c | 185 -
 blockdev.c |  69 +---
 tests/qemu-iotests/030 |  12 ++-
 tests/qemu-iotests/141.out |   2 +-
 tests/qemu-iotests/245 |  20 ++--
 tests/qemu-iotests/310 | 116 +
 tests/qemu-iotests/310.out |  15 +++
 tests/qemu-iotests/group   |   1 +
 16 files changed, 608 insertions(+), 130 deletions(-)
 create mode 100644 block/copy-on-read.h
 create mode 100755 tests/qemu-iotests/310
 create mode 100644 tests/qemu-iotests/310.out

-- 
2.25.4




[PATCH v15 04/13] qapi: add filter-node-name to block-stream

2020-12-15 Thread Vladimir Sementsov-Ogievskiy
From: Andrey Shinkevich 

Provide the possibility to pass the 'filter-node-name' parameter to the
block-stream job as it is done for the commit block job.

Signed-off-by: Andrey Shinkevich 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
  [vsementsov: comment indentation, s/Since: 5.2/Since: 6.0/]
Reviewed-by: Max Reitz 
---
 qapi/block-core.json   | 6 ++
 include/block/block_int.h  | 7 ++-
 block/monitor/block-hmp-cmds.c | 4 ++--
 block/stream.c | 4 +++-
 blockdev.c | 4 +++-
 5 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 04c5196e59..6050cf3c39 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2543,6 +2543,11 @@
 #'stop' and 'enospc' can only be used if the block device
 #supports io-status (see BlockInfo).  Since 1.3.
 #
+# @filter-node-name: the node name that should be assigned to the
+#filter driver that the stream job inserts into the graph
+#above @device. If this option is not given, a node name is
+#autogenerated. (Since: 6.0)
+#
 # @auto-finalize: When false, this job will wait in a PENDING state after it 
has
 # finished its work, waiting for @block-job-finalize before
 # making any block graph changes.
@@ -2573,6 +2578,7 @@
   'data': { '*job-id': 'str', 'device': 'str', '*base': 'str',
 '*base-node': 'str', '*backing-file': 'str', '*speed': 'int',
 '*on-error': 'BlockdevOnError',
+'*filter-node-name': 'str',
 '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
 
 ##
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 1eeafc118c..6f778e2517 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1142,6 +1142,9 @@ int is_windows_drive(const char *filename);
  *  See @BlockJobCreateFlags
  * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
  * @on_error: The action to take upon error.
+ * @filter_node_name: The node name that should be assigned to the filter
+ *driver that the commit job inserts into the graph above
+ *@bs. NULL means that a node name should be autogenerated.
  * @errp: Error object.
  *
  * Start a streaming operation on @bs.  Clusters that are unallocated
@@ -1154,7 +1157,9 @@ int is_windows_drive(const char *filename);
 void stream_start(const char *job_id, BlockDriverState *bs,
   BlockDriverState *base, const char *backing_file_str,
   int creation_flags, int64_t speed,
-  BlockdevOnError on_error, Error **errp);
+  BlockdevOnError on_error,
+  const char *filter_node_name,
+  Error **errp);
 
 /**
  * commit_start:
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index d15a2be827..e8a58f326e 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -508,8 +508,8 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
 
 qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
  false, NULL, qdict_haskey(qdict, "speed"), speed, true,
- BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
- &error);
+ BLOCKDEV_ON_ERROR_REPORT, false, NULL, false, false, 
false,
+ false, &error);
 
 hmp_handle_error(mon, error);
 }
diff --git a/block/stream.c b/block/stream.c
index 236384f2f7..6e281c71ac 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -221,7 +221,9 @@ static const BlockJobDriver stream_job_driver = {
 void stream_start(const char *job_id, BlockDriverState *bs,
   BlockDriverState *base, const char *backing_file_str,
   int creation_flags, int64_t speed,
-  BlockdevOnError on_error, Error **errp)
+  BlockdevOnError on_error,
+  const char *filter_node_name,
+  Error **errp)
 {
 StreamBlockJob *s;
 BlockDriverState *iter;
diff --git a/blockdev.c b/blockdev.c
index 412354b4b6..c290cb1dca 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2501,6 +2501,7 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
   bool has_backing_file, const char *backing_file,
   bool has_speed, int64_t speed,
   bool has_on_error, BlockdevOnError on_error,
+  bool has_filter_node_name, const char *filter_node_name,
   bool has_auto_finalize, bool auto_finalize,
   bool has_auto_dismiss, bool auto_dismiss,
   Error **errp)
@@ -2583,7 +2584,8 @@ void qmp_block_stream(bool has_job_id, const char 
*job_id, const char *device,
 }
 
 stream_start(has_jo

Re: [PATCH v5 3/4] hmp: Use QMP query-netdev in hmp_info_network

2020-12-15 Thread Jason Wang



- Original Message -
> Jason Wang  writes:
> 
> [...]
> > One more stupid question, instead of generating the string via hard
> > codes, is there any method (dict?) to iterate all the key/values
> > automatically?
> 
> QAPI visitors.
> 
> The lazy way: use the QObject output visitor to convert the QAPI type
> (here: NetdevInfo) to QObject, then qobject_to_json() to convert to
> JSON text.
> 
> If you don't want JSON, replace qobject_to_json().  Perhaps you can
> create something that's generally useful for HMP, not just "info
> network".  I'd pick keyval_parse() syntax.
> 
> The detour through QObject creates and destroys a rather fat temporary
> data structure.  Tolerable when the amount of data is small.  An output
> visitor that directly creates the string is more efficient.  Takes a bit
> more code, though.  I intend to post one for JSON, to reduce QMP's
> malloc gluttony.
> 

Thanks a lot for the answer.

Alexey, let's try what Markus suggested here.




Re: [PATCH v2 04/12] i386: Register feature bit properties as class properties

2020-12-15 Thread Markus Armbruster
Eduardo Habkost  writes:

> On Tue, Dec 15, 2020 at 03:11:06PM +0100, Markus Armbruster wrote:
>> Eduardo Habkost  writes:
>> 
>> > Class properties make QOM introspection simpler and easier, as
>> > they don't require an object to be instantiated.
>> >
>> > Signed-off-by: Eduardo Habkost 
>> 
>> This is significantly more than just "simpler and easier".
>> 
>> The other day, I played with the QMP core to reduce its appetite for
>> malloc.  I came up with patches that should approximately halve it, and
>> felt quite pleased with myself.  I looked for a simple test to
>> demonstrate the effect.  Something with plenty of output.  Hmm, why not
>> query-cpu-definitions, it produces about 32KiB.  Instrument, instrument,
>> run, ... wht?!?
>> 
>> My patches save some 7000 allocations (670 KiB total), roughly matching
>> my expectations.
>> 
>> Turns out this is a drop in the bucket: query-cpu-definitions still
>> takes some 180,000 allocations (almost 12 MiB total).  They're hiding
>> behind this line in qmp_query_cpu_definitions():
>> 
>> g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
>> 
>> The line takes more than a quarter second for me.
>> 
>> Hogging the main loop for a quarter second is not good.
>
> Wow!
>
>> 
>> Eduardo's patch reduces run time to 0.02 seconds (40,000 allocations, 9
>> MiB total).  It's a smaller pig now.
>
> Thanks for investigating this!  I'll amend the commit message with:
>
>   Also, the hundreds of instance properties were having an impact
>   on QMP commands that create temporary CPU objects.  On my
>   machine, run time of qmp_query_cpu_definitions() patch changed
>   from ~200ms to ~16ms after applying this patch.
>
> Numbers were obtained with:
>
>  $ sudo perf probe -v -x ./qemu-system-x86_64 -a 
> 'qmp_query_cpu_definitions%return' -a 'qmp_query_cpu_definitions'
>  $ echo -e '{"execute": "qmp_capabilities"}\n{"execute": 
> "query-cpu-definitions"}\n{"execute": "quit"}' | sudo perf trace -e 
> 'probe_qemu:*' ./qemu-system-x86_64 -S -display none -qmp stdio > /dev/null
>
> Before:
>
>  0.000 qemu-system-x8/3103211 
> probe_qemu:qmp_query_cpu_definitions(__probe_ip: 94851767056275)
>204.072 qemu-system-x8/3103211 
> probe_qemu:qmp_query_cpu_definitions__return(__probe_func: 94851767056275, 
> __probe_ret_ip: 94851768499362)
>
> After:
>
>  0.000 qemu-system-x8/3105969 
> probe_qemu:qmp_query_cpu_definitions(__probe_ip: 94554723186579)
> 16.445 qemu-system-x8/3105969 
> probe_qemu:qmp_query_cpu_definitions__return(__probe_func: 94554723186579, 
> __probe_ret_ip: 94554724629631)

Looks good, thanks!




CXL support in QEMU

2020-12-15 Thread Prashant V Agarwal
Hi,
Is there a way to know the support plans for CXL protocol in QEMU?
I see that there is side branch development going on:

https://gitlab.com/bwidawsk/qemu/-/tree/cxl-2.0v2

But when does it get merged and gets released in QEMU formally?
Is there a way to know a rough timeline?

Regards,
Prashant


Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper

2020-12-15 Thread Jiaxun Yang




在 2020/12/16 上午10:50, Jiaxun Yang 写道:



TBH I do think it doesn't sounds like a good idea to make 32-bit
and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
with ISA_MIPS64R6.

We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
is used to tell if a CPU supports 64-bit.

FYI: 
https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg


Just add more cents here...
The current method we handle R6 makes me a little bit annoying.

Given that MIPS is backward compatible until R5, and R6 reorganized a lot
of opcodes, I do think decoding procdure of R6 should be dedicated from 
the rest,
otherwise we may fall into the hell of finding difference between R6 and 
previous

ISAs, also I've heard some R6 only ASEs is occupying opcodes marked as
"removed in R6", so it doesn't looks like a wise idea to check removed in R6
in helpers.

So we may end up having four series of decodetrees for ISA
Series1: MIPS-II, MIPS32, MIPS32R2, MIPS32R5 (32bit "old" ISAs)
Series2: MIPS-III, MIPS64, MIPS64R2, MIPS64R5 (64bit "old" ISAs)

Series3: MIPS32R6 (32bit "new" ISAs)
Series4: MIPS64R6 (64bit "new" ISAs)

Thanks

- Jiaxun


Thanks.

- Jiaxun




Thanks for reviewing the series!

Phil.






Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper

2020-12-15 Thread Jiaxun Yang




在 2020/12/16 上午7:48, Philippe Mathieu-Daudé 写道:

On 12/16/20 12:27 AM, Richard Henderson wrote:

On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:

+bool isa_rel6_available(const CPUMIPSState *env)
+{
+if (TARGET_LONG_BITS == 64) {
+return cpu_supports_isa(env, ISA_MIPS64R6);
+}
+return cpu_supports_isa(env, ISA_MIPS32R6);
+}

So... does qemu-system-mips64 support 32-bit cpus?

Well... TBH I never tested it :S It looks the TCG code
is compiled with 64-bit TL registers, the machine address
space is 64-bit regardless the CPU, and I see various
#ifdef MIPS64 code that look dubious with 32-bit CPU.

qemu-system-mips64 and qemu-system-mips64el do support 32bit
CPUs like M14Kc and P5600 :-)
Sometimes I'm just curious about the necessity of having mips/mipsel 
targets

If so, this needs to be written

   if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
 return true;
   }

Otherwise, this will return false for a mips32r6 cpu.

I see. Rel6 is new to me, so I'll have to look at the ISA
manuals before returning to this thread with an answer.


TBH I do think it doesn't sounds like a good idea to make 32-bit
and 64-bit different. In fact ISA_MIPS32R6 is always set for targets
with ISA_MIPS64R6.

We're treating MIPS64R6 as a superset of MIPS32R6, and ISA_MIPS3
is used to tell if a CPU supports 64-bit.

FYI: https://commons.wikimedia.org/wiki/File:MIPS_instruction_set_family.svg

Thanks.

- Jiaxun




Thanks for reviewing the series!

Phil.




[PATCH 6/7] hw/mips/fuloong2e: Correct cpuclock env

2020-12-15 Thread Jiaxun Yang
It should be 53308.
See clock_set_hz.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/fuloong2e.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 256c7867e4..af2d259dc4 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -159,7 +159,7 @@ static uint64_t load_kernel(CPUMIPSState *env)
 }
 
 /* Setup minimum environment variables */
-prom_set(prom_buf, index++, "cpuclock=1");
+prom_set(prom_buf, index++, "cpuclock=53308");
 prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
 prom_set(prom_buf, index++, NULL);
 
-- 
2.29.2



[PATCH 7/7] hw/mips/fuloong2e: Add highmem support

2020-12-15 Thread Jiaxun Yang
highmem started from 0x2000.
Now we can have up to 2G RAM.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/fuloong2e.c | 49 -
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index af2d259dc4..dec6ac3b13 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -56,6 +56,7 @@
 /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */
 #define BIOS_SIZE   (512 * KiB)
 #define MAX_IDE_BUS 2
+#define HIGHMEM_START   0x2000
 
 /*
  * PMON is not part of qemu and released with BSD license, anyone
@@ -71,7 +72,8 @@
 #define FULOONG2E_RTL8139_SLOT7
 
 static struct _loaderparams {
-int ram_size;
+int ram_low_size;
+int ram_high_size;
 const char *kernel_filename;
 const char *kernel_cmdline;
 const char *initrd_filename;
@@ -128,14 +130,14 @@ static uint64_t load_kernel(CPUMIPSState *env)
 initrd_size = get_image_size(loaderparams.initrd_filename);
 if (initrd_size > 0) {
 initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
-if (initrd_offset + initrd_size > loaderparams.ram_size) {
+if (initrd_offset + initrd_size > loaderparams.ram_low_size) {
 error_report("memory too small for initial ram disk '%s'",
  loaderparams.initrd_filename);
 exit(1);
 }
 initrd_size = load_image_targphys(loaderparams.initrd_filename,
   initrd_offset,
-  loaderparams.ram_size - 
initrd_offset);
+  loaderparams.ram_low_size - 
initrd_offset);
 }
 if (initrd_size == (target_ulong) -1) {
 error_report("could not load initial ram disk '%s'",
@@ -160,7 +162,11 @@ static uint64_t load_kernel(CPUMIPSState *env)
 
 /* Setup minimum environment variables */
 prom_set(prom_buf, index++, "cpuclock=53308");
-prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
+prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_low_size / 
MiB);
+if (loaderparams.ram_high_size > 0) {
+prom_set(prom_buf, index++, "highmemsize=%"PRIi64,
+loaderparams.ram_high_size / MiB);
+}
 prom_set(prom_buf, index++, NULL);
 
 rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
@@ -186,7 +192,7 @@ static void write_bootloader(CPUMIPSState *env, uint8_t 
*base,
 p = (uint32_t *)(base + 0x040);
 
 bl_gen_jump_kernel(&p, ENVP_VADDR - 64, 2, ENVP_VADDR,
-   ENVP_VADDR + 8, loaderparams.ram_size,
+   ENVP_VADDR + 8, loaderparams.ram_low_size,
kernel_addr);
 }
 
@@ -258,8 +264,11 @@ static void mips_fuloong2e_init(MachineState *machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *initrd_filename = machine->initrd_filename;
+ram_addr_t ram_low_size, ram_high_size = 0;
 char *filename;
 MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *ram_low_alias = g_new(MemoryRegion, 1);
+MemoryRegion *ram_high_alias;
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 long bios_size;
 uint8_t *spd_data;
@@ -282,12 +291,31 @@ static void mips_fuloong2e_init(MachineState *machine)
 
 qemu_register_reset(main_cpu_reset, cpu);
 
-/* TODO: support more than 256M RAM as highmem */
-if (machine->ram_size != 256 * MiB) {
-error_report("Invalid RAM size, should be 256MB");
+if (machine->ram_size > 2 * GiB) {
+error_report("Too much memory for this machine: %" PRId64 "MB,"
+ " maximum 2048MB", machine->ram_size / MiB);
 exit(EXIT_FAILURE);
 }
-memory_region_add_subregion(address_space_mem, 0, machine->ram);
+
+ram_low_size = MIN(machine->ram_size, 256 * MiB);
+
+memory_region_init_alias(ram_low_alias, NULL,
+"ram_low_alias",
+machine->ram, 0,
+ram_low_size);
+memory_region_add_subregion(address_space_mem, 0,
+ram_low_alias);
+ 
+if (machine->ram_size > 256 * MiB) {
+ram_high_alias = g_new(MemoryRegion, 1);
+ram_high_size = machine->ram_size - ram_low_size;
+memory_region_init_alias(ram_high_alias, NULL,
+"ram_high_alias",
+machine->ram, ram_low_size,
+ram_high_size);
+memory_region_add_subregion(address_space_mem, HIGHMEM_START,
+ram_high_alias);
+}
 
 /* Boot ROM */
 memory_region_init_rom(bios, NULL, "fuloong2e.bios", BIOS_SIZE,
@@ -300,7 +328,8 @@ static vo

[PATCH 5/7] hw/mips/fuloong2e: Remove unused env entry

2020-12-15 Thread Jiaxun Yang
modetty and busclock is not handled by kernel and the parameter
here seems unreasonable.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/fuloong2e.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index a5b75b230a..256c7867e4 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -159,10 +159,8 @@ static uint64_t load_kernel(CPUMIPSState *env)
 }
 
 /* Setup minimum environment variables */
-prom_set(prom_buf, index++, "busclock=3300");
 prom_set(prom_buf, index++, "cpuclock=1");
 prom_set(prom_buf, index++, "memsize=%"PRIi64, loaderparams.ram_size / 
MiB);
-prom_set(prom_buf, index++, "modetty0=38400n8r");
 prom_set(prom_buf, index++, NULL);
 
 rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR);
-- 
2.29.2



[PATCH 4/7] hw/pci-host/bonito: Fixup pci.lomem mapping

2020-12-15 Thread Jiaxun Yang
The original mapping had wrong base address.
Fix by correct the base adress and merge three alias into
a single.

Signed-off-by: Jiaxun Yang 
---
 hw/pci-host/bonito.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 43b79448a9..3a31ba42f2 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -608,7 +608,7 @@ static void bonito_pcihost_realize(DeviceState *dev, Error 
**errp)
 {
 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
 BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev);
-MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 3);
+MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 1);
 
 memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
BONITO_PCIHI_SIZE);
 phb->bus = pci_register_root_bus(dev, "pci",
@@ -616,16 +616,11 @@ static void bonito_pcihost_realize(DeviceState *dev, 
Error **errp)
  dev, &bs->pci_mem, get_system_io(),
  0x28, 32, TYPE_PCI_BUS);
 
-for (size_t i = 0; i < 3; i++) {
-char *name = g_strdup_printf("pci.lomem%zu", i);
-
-memory_region_init_alias(&pcimem_lo_alias[i], NULL, name,
- &bs->pci_mem, i * 64 * MiB, 64 * MiB);
-memory_region_add_subregion(get_system_memory(),
-BONITO_PCILO_BASE + i * 64 * MiB,
-&pcimem_lo_alias[i]);
-g_free(name);
-}
+memory_region_init_alias(pcimem_lo_alias, OBJECT(dev), "pci.lomem",
+ &bs->pci_mem, BONITO_PCILO_BASE,
+ BONITO_PCILO_SIZE);
+memory_region_add_subregion(get_system_memory(), BONITO_PCILO_BASE,
+pcimem_lo_alias);
 
 create_unimplemented_device("pci.io", BONITO_PCIIO_BASE, 1 * MiB);
 }
-- 
2.29.2



[PATCH 2/7] hw/mips/fuloong2e: Relpace fault links

2020-12-15 Thread Jiaxun Yang
Websites are downing, but GitHub may last forever.
Loongson even doesn't recogonize 2E as their products nowadays..

Signed-off-by: Jiaxun Yang 
---
 hw/mips/fuloong2e.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 055b99e378..a5b75b230a 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -14,8 +14,8 @@
  * Fuloong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 
800MHz)
  * https://www.linux-mips.org/wiki/Fuloong_2E
  *
- * Loongson 2e user manual:
- * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf
+ * Loongson 2e manuals:
+ * https://github.com/loongson-community/docs/tree/master/2E
  */
 
 #include "qemu/osdep.h"
@@ -61,14 +61,7 @@
  * PMON is not part of qemu and released with BSD license, anyone
  * who want to build a pmon binary please first git-clone the source
  * from the git repository at:
- * http://www.loongson.cn/support/git/pmon
- * Then follow the "Compile Guide" available at:
- * http://dev.lemote.com/code/pmon
- *
- * Notes:
- * 1, don't use the source at http://dev.lemote.com/http_git/pmon.git
- * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware"
- * in the "Compile Guide".
+ * https://github.com/loongson-community/pmon-2ef
  */
 #define FULOONG_BIOSNAME "pmon_2e.bin"
 
-- 
2.29.2



[PATCH 3/7] hw/pci-host/bonito: Fixup IRQ mapping

2020-12-15 Thread Jiaxun Yang
Accroading to arch/mips/pci/fixup-fuloong2e.c in kernel,
despites south bridge IRQs needs special care, all other
IRQ pins are mapped by 'LOONGSON_IRQ_BASE + 25 + pin'.

As south bridge IRQs are all handled by ISA bus, we can simply
remove BONITO_IRQ_BASE and direct map IRQs here.

Signed-off-by: Jiaxun Yang 
---
 hw/pci-host/bonito.c | 28 +---
 1 file changed, 5 insertions(+), 23 deletions(-)

diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index a99eced065..43b79448a9 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -546,19 +546,16 @@ static const MemoryRegionOps bonito_spciconf_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-#define BONITO_IRQ_BASE 32
-
 static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
 {
 BonitoState *s = opaque;
 qemu_irq *pic = s->pic;
 PCIBonitoState *bonito_state = s->pci_dev;
-int internal_irq = irq_num - BONITO_IRQ_BASE;
 
-if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
+if (bonito_state->regs[BONITO_INTEDGE] & (1 << irq_num)) {
 qemu_irq_pulse(*pic);
 } else {   /* level triggered */
-if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
+if (bonito_state->regs[BONITO_INTPOL] & (1 << irq_num)) {
 qemu_irq_raise(*pic);
 } else {
 qemu_irq_lower(*pic);
@@ -566,25 +563,10 @@ static void pci_bonito_set_irq(void *opaque, int irq_num, 
int level)
 }
 }
 
-/* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */
-static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num)
+/* PCI slots IRQ pins started from 25 */
+static int pci_bonito_map_irq(PCIDevice *pci_dev, int pin)
 {
-int slot;
-
-slot = (pci_dev->devfn >> 3);
-
-switch (slot) {
-case 5:   /* FULOONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 */
-return irq_num % 4 + BONITO_IRQ_BASE;
-case 6:   /* FULOONG2E_ATI_SLOT, VGA */
-return 4 + BONITO_IRQ_BASE;
-case 7:   /* FULOONG2E_RTL_SLOT, RTL8139 */
-return 5 + BONITO_IRQ_BASE;
-case 8 ... 12: /* PCI slot 1 to 4 */
-return (slot - 8 + irq_num) + 6 + BONITO_IRQ_BASE;
-default:  /* Unknown device, don't do any translation */
-return irq_num;
-}
+return 25 + pin;
 }
 
 static void bonito_reset(void *opaque)
-- 
2.29.2



[PATCH 1/7] hw/mips/fuloong2e: Remove define DEBUG_FULOONG2E_INIT

2020-12-15 Thread Jiaxun Yang
Seems useless

Signed-off-by: Jiaxun Yang 
---
 hw/mips/fuloong2e.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 9b0eb8a314..055b99e378 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -48,8 +48,6 @@
 #include "sysemu/reset.h"
 #include "qemu/error-report.h"
 
-#define DEBUG_FULOONG2E_INIT
-
 #define ENVP_PADDR  0x2000
 #define ENVP_VADDR  cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
 #define ENVP_NB_ENTRIES 16
-- 
2.29.2



[PATCH 0/7] hw/mips/fuloong2e fixes

2020-12-15 Thread Jiaxun Yang
It can now boot Debian installer[1].
I'm going to add acceptance test for it later.

Thanks.

Jiaxun Yang (7):
  hw/mips/fuloong2e: Remove define DEBUG_FULOONG2E_INIT
  hw/mips/fuloong2e: Relpace fault links
  hw/pci-host/bonito: Fixup IRQ mapping
  hw/pci-host/bonito: Fixup pci.lomem mapping
  hw/mips/fuloong2e: Remove unused env entry
  hw/mips/fuloong2e: Correct cpuclock env
  hw/mips/fuloong2e: Add highmem support

 hw/mips/fuloong2e.c  | 68 
 hw/pci-host/bonito.c | 45 +++--
 2 files changed, 54 insertions(+), 59 deletions(-)

-- 
2.29.2



[RFC v2 11/15] target/riscv: rvb: generalized reverse

2020-12-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
---
 target/riscv/bitmanip_helper.c  | 72 +
 target/riscv/helper.h   |  7 +++
 target/riscv/insn32-64.decode   |  2 +
 target/riscv/insn32.decode  |  2 +
 target/riscv/insn_trans/trans_rvb.c.inc | 34 
 target/riscv/meson.build|  1 +
 target/riscv/translate.c| 32 +++
 7 files changed, 150 insertions(+)
 create mode 100644 target/riscv/bitmanip_helper.c

diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
new file mode 100644
index 000..716d80aab59
--- /dev/null
+++ b/target/riscv/bitmanip_helper.c
@@ -0,0 +1,72 @@
+/*
+ * RISC-V Bitmanip Extension Helpers for QEMU.
+ *
+ * Copyright (c) 2020 Kito Cheng, kito.ch...@sifive.com
+ * Copyright (c) 2020 Frank Chang, frank.ch...@sifive.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "tcg/tcg.h"
+
+static const uint64_t adjacent_masks[] = {
+dup_const(MO_8, 0x55),
+dup_const(MO_8, 0x33),
+dup_const(MO_8, 0x0f),
+dup_const(MO_16, 0xff),
+dup_const(MO_32, 0x),
+#ifdef TARGET_RISCV64
+UINT32_MAX
+#endif
+};
+
+static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift)
+{
+return ((x & mask) << shift) | ((x & ~mask) >> shift);
+}
+
+static target_ulong do_grev(target_ulong rs1,
+target_ulong rs2,
+int bits)
+{
+target_ulong x = rs1;
+int i, shift;
+
+for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
+if (rs2 & shift) {
+x = do_swap(x, adjacent_masks[i], shift);
+}
+}
+
+return x;
+}
+
+target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2)
+{
+return do_grev(rs1, rs2, TARGET_LONG_BITS);
+}
+
+/* RV64-only instruction */
+#ifdef TARGET_RISCV64
+
+target_ulong HELPER(grevw)(target_ulong rs1, target_ulong rs2)
+{
+return do_grev(rs1, rs2, 32);
+}
+
+#endif
+
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 939731c345d..a055c539fad 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -66,6 +66,13 @@ DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
 #endif
 DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
 
+/* Bitmanip */
+DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+
+#if defined(TARGET_RISCV64)
+DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+#endif
+
 /* Special functions */
 DEF_HELPER_3(csrrw, tl, env, tl, tl)
 DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index ac0634d754a..a355b91e399 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -102,6 +102,7 @@ slow   001 .. 001 . 0111011 @r
 srow   001 .. 101 . 0111011 @r
 rorw   011 .. 101 . 0111011 @r
 rolw   011 .. 001 . 0111011 @r
+grevw  0110100 .. 101 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
@@ -109,3 +110,4 @@ sbinviw0110100 .. 001 . 0011011 @sh5
 sloiw  001 .. 001 . 0011011 @sh5
 sroiw  001 .. 101 . 0011011 @sh5
 roriw  011 .. 101 . 0011011 @sh5
+greviw 0110100 .. 101 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b4677293582..fd8f4238ef7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -619,6 +619,7 @@ slo001 .. 001 . 0110011 @r
 sro001 .. 101 . 0110011 @r
 ror011 .. 101 . 0110011 @r
 rol011 .. 001 . 0110011 @r
+grev   0110100 .. 101 . 0110011 @r
 
 sbseti 00101. ... 001 . 0010011 @sh
 sbclri 01001. ... 001 . 0010011 @sh
@@ -627,3 +628,4 @@ sbexti 01001. ... 101 . 0010011 @sh
 sloi   00100. ... 001 . 0010011 @sh
 sroi   00100. ... 101 . 0010011 @sh
 rori   01100. ... 101 . 0010011 @sh
+grevi  01101. ... 101 . 0010011 @sh
diff --gi

[RFC v2 14/15] target/riscv: rvb: add/sub with postfix zero-extend

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  3 +++
 target/riscv/insn_trans/trans_rvb.c.inc | 22 ++
 target/riscv/translate.c|  6 ++
 3 files changed, 31 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 1059cab5aa4..f819028266c 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -107,6 +107,7 @@ gorcw  0010100 .. 101 . 0111011 @r
 sh1addu_w  001 .. 010 . 0111011 @r
 sh2addu_w  001 .. 100 . 0111011 @r
 sh3addu_w  001 .. 110 . 0111011 @r
+addu_w 100 .. 000 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
@@ -116,3 +117,5 @@ sroiw  001 .. 101 . 0011011 @sh5
 roriw  011 .. 101 . 0011011 @sh5
 greviw 0110100 .. 101 . 0011011 @sh5
 gorciw 0010100 .. 101 . 0011011 @sh5
+
+slliu_w1. ... 001 . 0011011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 07fe662b005..323ca5eccee 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -441,4 +441,26 @@ GEN_TRANS_SHADDU_W(1)
 GEN_TRANS_SHADDU_W(2)
 GEN_TRANS_SHADDU_W(3)
 
+static bool trans_addu_w(DisasContext *ctx, arg_addu_w *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_addu_w);
+}
+
+static bool trans_slliu_w(DisasContext *ctx, arg_slliu_w *a)
+{
+TCGv source1 = tcg_temp_new();
+gen_get_gpr(source1, a->rs1);
+
+if (a->shamt < 32) {
+tcg_gen_deposit_z_i64(source1, source1, a->shamt, 32);
+} else {
+tcg_gen_shli_i64(source1, source1, a->shamt);
+}
+
+gen_set_gpr(a->rd, source1);
+tcg_temp_free(source1);
+return true;
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f9385bbcd4f..84e55880234 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -955,6 +955,12 @@ GEN_SHADDU_W(1)
 GEN_SHADDU_W(2)
 GEN_SHADDU_W(3)
 
+static void gen_addu_w(TCGv ret, TCGv arg1, TCGv arg2)
+{
+tcg_gen_ext32u_tl(arg1, arg1);
+tcg_gen_add_tl(ret, arg1, arg2);
+}
+
 #endif
 
 static bool gen_arith(DisasContext *ctx, arg_r *a,
-- 
2.17.1




[RFC v2 10/15] target/riscv: rvb: rotate (left/right)

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  3 ++
 target/riscv/insn32.decode  |  3 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 61 +
 target/riscv/translate.c| 36 +++
 4 files changed, 103 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 6d017c70c74..ac0634d754a 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -100,9 +100,12 @@ sbinvw 0110100 .. 001 . 0111011 @r
 sbextw 0100100 .. 101 . 0111011 @r
 slow   001 .. 001 . 0111011 @r
 srow   001 .. 101 . 0111011 @r
+rorw   011 .. 101 . 0111011 @r
+rolw   011 .. 001 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
 sbinviw0110100 .. 001 . 0011011 @sh5
 sloiw  001 .. 001 . 0011011 @sh5
 sroiw  001 .. 101 . 0011011 @sh5
+roriw  011 .. 101 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 78ce4b11097..b4677293582 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -617,6 +617,8 @@ sbinv  0110100 .. 001 . 0110011 @r
 sbext  0100100 .. 101 . 0110011 @r
 slo001 .. 001 . 0110011 @r
 sro001 .. 101 . 0110011 @r
+ror011 .. 101 . 0110011 @r
+rol011 .. 001 . 0110011 @r
 
 sbseti 00101. ... 001 . 0010011 @sh
 sbclri 01001. ... 001 . 0010011 @sh
@@ -624,3 +626,4 @@ sbinvi 01101. ... 001 . 0010011 @sh
 sbexti 01001. ... 101 . 0010011 @sh
 sloi   00100. ... 001 . 0010011 @sh
 sroi   00100. ... 101 . 0010011 @sh
+rori   01100. ... 101 . 0010011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 11b5439e703..433cc7f9fc8 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -189,7 +189,36 @@ static bool trans_sroi(DisasContext *ctx, arg_sroi *a)
 return gen_shifti(ctx, a, &gen_sro);
 }
 
+static bool trans_ror(DisasContext *ctx, arg_ror *a)
 {
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_rotr_tl);
+}
+
+static bool trans_rori(DisasContext *ctx, arg_rori *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+TCGv source1 = tcg_temp_new();
+
+gen_get_gpr(source1, a->rs1);
+tcg_gen_rotri_tl(source1, source1, a->shamt);
+gen_set_gpr(a->rd, source1);
+
+tcg_temp_free(source1);
+return true;
+}
+
+static bool trans_rol(DisasContext *ctx, arg_rol *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_rotl_tl);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
@@ -289,4 +318,36 @@ static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
 return gen_shiftiw(ctx, a, &gen_sro);
 }
 
+static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_rorw);
+}
+
+static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= 32) {
+return false;
+}
+
+if (a->shamt == 0) {
+TCGv t = tcg_temp_new();
+gen_get_gpr(t, a->rs1);
+tcg_gen_ext32s_tl(t, t);
+gen_set_gpr(a->rd, t);
+tcg_temp_free(t);
+return true;
+}
+
+return gen_shiftiw(ctx, a, &gen_rorw);
+}
+
+static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_rolw);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0c00d20ab1b..10b4142a3ab 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -849,6 +849,42 @@ static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(t);
 }
 
+static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+
+/* truncate to 32-bits */
+tcg_gen_trunc_tl_i32(t1, arg1);
+tcg_gen_trunc_tl_i32(t2, arg2);
+
+tcg_gen_rotr_i32(t1, t1, t2);
+
+/* sign-extend 64-bits */
+tcg_gen_ext_i32_tl(ret, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t2);
+}
+
+static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+
+/* truncate to 32-bits */
+tcg_gen_trunc_tl_i32(t1, arg1);
+tcg_gen_trunc_tl_i32(t2, arg2);
+
+tcg_gen_rotl_i32(t1, t1, t2);
+
+/* sign-extend 64-bits */
+tcg_gen_ext_i32_tl(ret, t1);
+
+tcg_te

[RFC v2 12/15] target/riscv: rvb: generalized or-combine

2020-12-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
---
 target/riscv/bitmanip_helper.c  | 31 ++
 target/riscv/helper.h   |  2 ++
 target/riscv/insn32-64.decode   |  2 ++
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 34 +
 target/riscv/translate.c|  6 +
 6 files changed, 77 insertions(+)

diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
index 716d80aab59..6ab55b4b176 100644
--- a/target/riscv/bitmanip_helper.c
+++ b/target/riscv/bitmanip_helper.c
@@ -70,3 +70,34 @@ target_ulong HELPER(grevw)(target_ulong rs1, target_ulong 
rs2)
 
 #endif
 
+static target_ulong do_gorc(target_ulong rs1,
+target_ulong rs2,
+int bits)
+{
+target_ulong x = rs1;
+int i, shift;
+
+for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
+if (rs2 & shift) {
+x |= do_swap(x, adjacent_masks[i], shift);
+}
+}
+
+return x;
+}
+
+target_ulong HELPER(gorc)(target_ulong rs1, target_ulong rs2)
+{
+return do_gorc(rs1, rs2, TARGET_LONG_BITS);
+}
+
+/* RV64-only instruction */
+#ifdef TARGET_RISCV64
+
+target_ulong HELPER(gorcw)(target_ulong rs1, target_ulong rs2)
+{
+return do_gorc(rs1, rs2, 32);
+}
+
+#endif
+
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a055c539fad..de3c341c2f4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -68,9 +68,11 @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
 
 /* Bitmanip */
 DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 
 #if defined(TARGET_RISCV64)
 DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 #endif
 
 /* Special functions */
diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index a355b91e399..46f469700b5 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -103,6 +103,7 @@ srow   001 .. 101 . 0111011 @r
 rorw   011 .. 101 . 0111011 @r
 rolw   011 .. 001 . 0111011 @r
 grevw  0110100 .. 101 . 0111011 @r
+gorcw  0010100 .. 101 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
@@ -111,3 +112,4 @@ sloiw  001 .. 001 . 0011011 @sh5
 sroiw  001 .. 101 . 0011011 @sh5
 roriw  011 .. 101 . 0011011 @sh5
 greviw 0110100 .. 101 . 0011011 @sh5
+gorciw 0010100 .. 101 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index fd8f4238ef7..98d2ee0ab56 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -620,6 +620,7 @@ sro001 .. 101 . 0110011 @r
 ror011 .. 101 . 0110011 @r
 rol011 .. 001 . 0110011 @r
 grev   0110100 .. 101 . 0110011 @r
+gorc   0010100 .. 101 . 0110011 @r
 
 sbseti 00101. ... 001 . 0010011 @sh
 sbclri 01001. ... 001 . 0010011 @sh
@@ -629,3 +630,4 @@ sloi   00100. ... 001 . 0010011 @sh
 sroi   00100. ... 101 . 0010011 @sh
 rori   01100. ... 101 . 0010011 @sh
 grevi  01101. ... 101 . 0010011 @sh
+gorci  00101. ... 101 . 0010011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 142e9123d68..c35fe8c 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -236,6 +236,23 @@ static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
 return gen_grevi(ctx, a);
 }
 
+static bool trans_gorc(DisasContext *ctx, arg_gorc *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_helper_gorc);
+}
+
+static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+return gen_shifti(ctx, a, &gen_helper_gorc);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
@@ -384,4 +401,21 @@ static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
 return gen_shiftiw(ctx, a, &gen_grevw);
 }
 
+static bool trans_gorcw(DisasContext *ctx, arg_gorcw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_gorcw);
+}
+
+static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= 32) {
+return false;
+}
+
+return gen_shiftiw(ctx, a, &gen_gorcw);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b40d170c01b..021daf10875 100644
--- a/target/riscv/translate.c
+++ 

[RFC v2 08/15] target/riscv: rvb: single-bit instructions

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |   8 ++
 target/riscv/insn32.decode  |   9 +++
 target/riscv/insn_trans/trans_rvb.c.inc |  90 +
 target/riscv/translate.c| 102 
 4 files changed, 209 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index fd7e0492372..e2490f791b7 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -94,3 +94,11 @@ pcntw  011 00010 . 001 . 0011011 @r2
 
 packw  100 .. 100 . 0111011 @r
 packuw 0100100 .. 100 . 0111011 @r
+sbsetw 0010100 .. 001 . 0111011 @r
+sbclrw 0100100 .. 001 . 0111011 @r
+sbinvw 0110100 .. 001 . 0111011 @r
+sbextw 0100100 .. 101 . 0111011 @r
+
+sbsetiw0010100 .. 001 . 0011011 @sh5
+sbclriw0100100 .. 001 . 0011011 @sh5
+sbinviw0110100 .. 001 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4baafed21f1..c697ff5c867 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -611,3 +611,12 @@ min101 .. 100 . 0110011 @r
 minu   101 .. 101 . 0110011 @r
 max101 .. 110 . 0110011 @r
 maxu   101 .. 111 . 0110011 @r
+sbset  0010100 .. 001 . 0110011 @r
+sbclr  0100100 .. 001 . 0110011 @r
+sbinv  0110100 .. 001 . 0110011 @r
+sbext  0100100 .. 101 . 0110011 @r
+
+sbseti 00101. ... 001 . 0010011 @sh
+sbclri 01001. ... 001 . 0010011 @sh
+sbinvi 01101. ... 001 . 0010011 @sh
+sbexti 01001. ... 101 . 0010011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 5ea0f0ff81c..43e9b670f73 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -107,6 +107,54 @@ static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
 return gen_unary(ctx, a, &tcg_gen_ext16s_tl);
 }
 
+static bool trans_sbset(DisasContext *ctx, arg_sbset *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_sbset);
+}
+
+static bool trans_sbseti(DisasContext *ctx, arg_sbseti *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shifti(ctx, a, &gen_sbset);
+}
+
+static bool trans_sbclr(DisasContext *ctx, arg_sbclr *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_sbclr);
+}
+
+static bool trans_sbclri(DisasContext *ctx, arg_sbclri *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shifti(ctx, a, &gen_sbclr);
+}
+
+static bool trans_sbinv(DisasContext *ctx, arg_sbinv *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_sbinv);
+}
+
+static bool trans_sbinvi(DisasContext *ctx, arg_sbinvi *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shifti(ctx, a, &gen_sbinv);
+}
+
+static bool trans_sbext(DisasContext *ctx, arg_sbext *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_sbext);
+}
+
+static bool trans_sbexti(DisasContext *ctx, arg_sbexti *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shifti(ctx, a, &gen_sbext);
+}
+
 {
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
@@ -141,4 +189,46 @@ static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
 return gen_arith(ctx, a, &gen_packuw);
 }
 
+static bool trans_sbsetw(DisasContext *ctx, arg_sbsetw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_sbset);
+}
+
+static bool trans_sbsetiw(DisasContext *ctx, arg_sbsetiw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftiw(ctx, a, &gen_sbset);
+}
+
+static bool trans_sbclrw(DisasContext *ctx, arg_sbclrw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_sbclr);
+}
+
+static bool trans_sbclriw(DisasContext *ctx, arg_sbclriw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftiw(ctx, a, &gen_sbclr);
+}
+
+static bool trans_sbinvw(DisasContext *ctx, arg_sbinvw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_sbinv);
+}
+
+static bool trans_sbinviw(DisasContext *ctx, arg_sbinviw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftiw(ctx, a, &gen_sbinv);
+}
+
+static bool trans_sbextw(DisasContext *ctx, arg_sbextw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_sbext);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7b427a9caec..ca176709674 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -755,6 +755,48 @@ static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(t);
 }
 
+static void gen_sbop_mask(TCGv ret, TCGv shamt)
+{
+tcg_gen_movi_tl(ret, 1);
+tcg_gen_shl_tl(ret, ret, shamt);
+}
+
+static void gen_sbset(TCGv ret, TCGv a

[RFC v2 15/15] target/riscv: rvb: support and turn on B-extension from command line

2020-12-15 Thread frank . chang
From: Kito Cheng 

B-extension is default off, use cpu rv32 or rv64 with x-b=true to
enable B-extension.

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/cpu.c | 4 
 target/riscv/cpu.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a0264fc6b1..33fa112c4ac 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -441,6 +441,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 if (cpu->cfg.ext_h) {
 target_misa |= RVH;
 }
+if (cpu->cfg.ext_b) {
+target_misa |= RVB;
+}
 if (cpu->cfg.ext_v) {
 target_misa |= RVV;
 if (!is_power_of_2(cpu->cfg.vlen)) {
@@ -511,6 +514,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 /* This is experimental so mark with 'x-' */
+DEFINE_PROP_BOOL("x-b", RISCVCPU, cfg.ext_b, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c0a326c8430..4868f62f32b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -66,6 +66,7 @@
 #define RVS RV('S')
 #define RVU RV('U')
 #define RVH RV('H')
+#define RVB RV('B')
 
 /* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
@@ -276,6 +277,7 @@ struct RISCVCPU {
 bool ext_f;
 bool ext_d;
 bool ext_c;
+bool ext_b;
 bool ext_s;
 bool ext_u;
 bool ext_h;
-- 
2.17.1




[RFC v2 07/15] target/riscv: rvb: sign-extend instructions

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 13 +
 2 files changed, 15 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 0d6a8a1c0a5..4baafed21f1 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -598,6 +598,8 @@ vsetvl  100 . . 111 . 1010111  @r
 clz011000 00 . 001 . 0010011 @r2
 ctz011000 01 . 001 . 0010011 @r2
 pcnt   011000 10 . 001 . 0010011 @r2
+sext_b 011000 000100 . 001 . 0010011 @r2
+sext_h 011000 000101 . 001 . 0010011 @r2
 
 andn   010 .. 111 . 0110011 @r
 orn010 .. 110 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index bd66c2ad84d..5ea0f0ff81c 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -95,6 +95,19 @@ static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
 return gen_arith(ctx, a, &tcg_gen_umax_tl);
 }
 
+static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &tcg_gen_ext8s_tl);
+}
+
+static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &tcg_gen_ext16s_tl);
+}
+
+{
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
-- 
2.17.1




[RFC v2 06/15] target/riscv: rvb: min/max instructions

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  |  4 
 target/riscv/insn_trans/trans_rvb.c.inc | 24 
 2 files changed, 28 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c337aed8ca3..0d6a8a1c0a5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -605,3 +605,7 @@ xnor   010 .. 100 . 0110011 @r
 pack   100 .. 100 . 0110011 @r
 packu  0100100 .. 100 . 0110011 @r
 packh  100 .. 111 . 0110011 @r
+min101 .. 100 . 0110011 @r
+minu   101 .. 101 . 0110011 @r
+max101 .. 110 . 0110011 @r
+maxu   101 .. 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 3da233047a9..bd66c2ad84d 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -71,6 +71,30 @@ static bool trans_packh(DisasContext *ctx, arg_packh *a)
 return gen_arith(ctx, a, &gen_packh);
 }
 
+static bool trans_min(DisasContext *ctx, arg_min *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_smin_tl);
+}
+
+static bool trans_max(DisasContext *ctx, arg_max *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_smax_tl);
+}
+
+static bool trans_minu(DisasContext *ctx, arg_minu *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_umin_tl);
+}
+
+static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &tcg_gen_umax_tl);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
-- 
2.17.1




[RFC v2 09/15] target/riscv: rvb: shift ones

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  4 ++
 target/riscv/insn32.decode  |  4 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 58 +
 target/riscv/translate.c| 13 ++
 4 files changed, 79 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index e2490f791b7..6d017c70c74 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -98,7 +98,11 @@ sbsetw 0010100 .. 001 . 0111011 @r
 sbclrw 0100100 .. 001 . 0111011 @r
 sbinvw 0110100 .. 001 . 0111011 @r
 sbextw 0100100 .. 101 . 0111011 @r
+slow   001 .. 001 . 0111011 @r
+srow   001 .. 101 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
 sbinviw0110100 .. 001 . 0011011 @sh5
+sloiw  001 .. 001 . 0011011 @sh5
+sroiw  001 .. 101 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c697ff5c867..78ce4b11097 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -615,8 +615,12 @@ sbset  0010100 .. 001 . 0110011 @r
 sbclr  0100100 .. 001 . 0110011 @r
 sbinv  0110100 .. 001 . 0110011 @r
 sbext  0100100 .. 101 . 0110011 @r
+slo001 .. 001 . 0110011 @r
+sro001 .. 101 . 0110011 @r
 
 sbseti 00101. ... 001 . 0010011 @sh
 sbclri 01001. ... 001 . 0010011 @sh
 sbinvi 01101. ... 001 . 0010011 @sh
 sbexti 01001. ... 101 . 0010011 @sh
+sloi   00100. ... 001 . 0010011 @sh
+sroi   00100. ... 101 . 0010011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 43e9b670f73..11b5439e703 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -155,6 +155,40 @@ static bool trans_sbexti(DisasContext *ctx, arg_sbexti *a)
 return gen_shifti(ctx, a, &gen_sbext);
 }
 
+static bool trans_slo(DisasContext *ctx, arg_slo *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_slo);
+}
+
+static bool trans_sloi(DisasContext *ctx, arg_sloi *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+return gen_shifti(ctx, a, &gen_slo);
+}
+
+static bool trans_sro(DisasContext *ctx, arg_sro *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shift(ctx, a, &gen_sro);
+}
+
+static bool trans_sroi(DisasContext *ctx, arg_sroi *a)
+{
+REQUIRE_EXT(ctx, RVB);
+
+if (a->shamt >= TARGET_LONG_BITS) {
+return false;
+}
+
+return gen_shifti(ctx, a, &gen_sro);
+}
+
 {
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
@@ -231,4 +265,28 @@ static bool trans_sbextw(DisasContext *ctx, arg_sbextw *a)
 return gen_shiftw(ctx, a, &gen_sbext);
 }
 
+static bool trans_slow(DisasContext *ctx, arg_slow *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_slo);
+}
+
+static bool trans_sloiw(DisasContext *ctx, arg_sloiw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftiw(ctx, a, &gen_slo);
+}
+
+static bool trans_srow(DisasContext *ctx, arg_srow *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftw(ctx, a, &gen_sro);
+}
+
+static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_shiftiw(ctx, a, &gen_sro);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ca176709674..0c00d20ab1b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -797,6 +797,19 @@ static void gen_sbext(TCGv ret, TCGv arg1, TCGv shamt)
 tcg_gen_andi_tl(ret, ret, 1);
 }
 
+static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
+{
+tcg_gen_not_tl(ret, arg1);
+tcg_gen_shl_tl(ret, ret, arg2);
+tcg_gen_not_tl(ret, ret);
+}
+
+static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
+{
+tcg_gen_not_tl(ret, arg1);
+tcg_gen_shr_tl(ret, ret, arg2);
+tcg_gen_not_tl(ret, ret);
+}
 
 #ifdef TARGET_RISCV64
 
-- 
2.17.1




[RFC v2 13/15] target/riscv: rvb: address calculation

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  3 +++
 target/riscv/insn32.decode  |  3 +++
 target/riscv/insn_trans/trans_rvb.c.inc | 23 ++
 target/riscv/translate.c| 32 +
 4 files changed, 61 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 46f469700b5..1059cab5aa4 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -104,6 +104,9 @@ rorw   011 .. 101 . 0111011 @r
 rolw   011 .. 001 . 0111011 @r
 grevw  0110100 .. 101 . 0111011 @r
 gorcw  0010100 .. 101 . 0111011 @r
+sh1addu_w  001 .. 010 . 0111011 @r
+sh2addu_w  001 .. 100 . 0111011 @r
+sh3addu_w  001 .. 110 . 0111011 @r
 
 sbsetiw0010100 .. 001 . 0011011 @sh5
 sbclriw0100100 .. 001 . 0011011 @sh5
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 98d2ee0ab56..67c8bc5485b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -621,6 +621,9 @@ ror011 .. 101 . 0110011 @r
 rol011 .. 001 . 0110011 @r
 grev   0110100 .. 101 . 0110011 @r
 gorc   0010100 .. 101 . 0110011 @r
+sh1add 001 .. 010 . 0110011 @r
+sh2add 001 .. 100 . 0110011 @r
+sh3add 001 .. 110 . 0110011 @r
 
 sbseti 00101. ... 001 . 0010011 @sh
 sbclri 01001. ... 001 . 0010011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index c35fe8c..07fe662b005 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -253,6 +253,17 @@ static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
 return gen_shifti(ctx, a, &gen_helper_gorc);
 }
 
+#define GEN_TRANS_SHADD(SHAMT) \
+static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
+{  \
+REQUIRE_EXT(ctx, RVB); \
+return gen_arith(ctx, a, &gen_sh##SHAMT##add); \
+}
+
+GEN_TRANS_SHADD(1)
+GEN_TRANS_SHADD(2)
+GEN_TRANS_SHADD(3)
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
@@ -418,4 +429,16 @@ static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a)
 return gen_shiftiw(ctx, a, &gen_gorcw);
 }
 
+#define GEN_TRANS_SHADDU_W(SHAMT) \
+static bool trans_sh##SHAMT##addu_w(DisasContext *ctx,\
+arg_sh##SHAMT##addu_w *a) \
+{ \
+REQUIRE_EXT(ctx, RVB);\
+return gen_arith(ctx, a, &gen_sh##SHAMT##addu_w); \
+}
+
+GEN_TRANS_SHADDU_W(1)
+GEN_TRANS_SHADDU_W(2)
+GEN_TRANS_SHADDU_W(3)
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 021daf10875..f9385bbcd4f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -837,6 +837,21 @@ static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
 return true;
 }
 
+#define GEN_SHADD(SHAMT)   \
+static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
+{  \
+TCGv t = tcg_temp_new();   \
+   \
+tcg_gen_shli_tl(t, arg1, SHAMT);   \
+tcg_gen_add_tl(ret, t, arg2);  \
+   \
+tcg_temp_free(t);  \
+}
+
+GEN_SHADD(1)
+GEN_SHADD(2)
+GEN_SHADD(3)
+
 #ifdef TARGET_RISCV64
 
 static void gen_ctzw(TCGv ret, TCGv arg1)
@@ -923,6 +938,23 @@ static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2)
 gen_helper_gorc(ret, arg1, arg2);
 }
 
+#define GEN_SHADDU_W(SHAMT)   \
+static void gen_sh##SHAMT##addu_w(TCGv ret, TCGv arg1, TCGv arg2) \
+{ \
+TCGv t = tcg_temp_new();  \
+  \
+tcg_gen_ext32u_tl(t, arg1);   \
+  \
+tcg_gen_shli_tl(t, t, SHAMT); \
+tcg_gen_add_tl(ret, t, arg2); \
+  \
+tcg_temp_free(t); 

[RFC v2 03/15] target/riscv: rvb: count bits set

2020-12-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  1 +
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvb.c.inc | 12 
 target/riscv/translate.c|  6 ++
 4 files changed, 20 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index f4c42720fc7..00c56a93151 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -90,3 +90,4 @@ hsv_d 0110111  .   . 100 0 1110011 @r2_s
 # *** RV64B Standard Extension (in addition to RV32B) ***
 clzw   011 0 . 001 . 0011011 @r2
 ctzw   011 1 . 001 . 0011011 @r2
+pcntw  011 00010 . 001 . 0011011 @r2
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 8fe838cf0d0..ac4d8395a45 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -597,3 +597,4 @@ vsetvl  100 . . 111 . 1010111  @r
 # *** RV32B Standard Extension ***
 clz011000 00 . 001 . 0010011 @r2
 ctz011000 01 . 001 . 0010011 @r2
+pcnt   011000 10 . 001 . 0010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index fb6e16143db..f5930f2ad53 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -29,6 +29,12 @@ static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
 return gen_unary(ctx, a, &gen_ctz);
 }
 
+static bool trans_pcnt(DisasContext *ctx, arg_pcnt *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &tcg_gen_ctpop_tl);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
@@ -44,4 +50,10 @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
 return gen_unary(ctx, a, &gen_ctzw);
 }
 
+static bool trans_pcntw(DisasContext *ctx, arg_pcntw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &gen_pcntw);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 398d4502a96..4c9eb86e630 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -726,6 +726,12 @@ static void gen_clzw(TCGv ret, TCGv arg1)
 tcg_gen_subi_i64(ret, ret, 32);
 }
 
+static void gen_pcntw(TCGv ret, TCGv arg1)
+{
+tcg_gen_ext32u_tl(arg1, arg1);
+tcg_gen_ctpop_tl(ret, arg1);
+}
+
 #endif
 
 static bool gen_arith(DisasContext *ctx, arg_r *a,
-- 
2.17.1




[RFC v2 01/15] target/riscv: reformat @sh format encoding for B-extension

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 84080dd18ca..3823b3ea800 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -22,7 +22,7 @@
 %rs1   15:5
 %rd7:5
 
-%sh1020:10
+%sh720:7
 %csr20:12
 %rm 12:3
 %nf 29:3 !function=ex_plus_1
@@ -58,7 +58,7 @@
 @u     . ... &u  imm=%imm_u  
%rd
 @j     . ... &j  imm=%imm_j  
%rd
 
-@sh  ..  .. .  ... . ... &shift  shamt=%sh10  %rs1 
%rd
+@sh  ..  .. .  ... . ... &shift  shamt=%sh7 %rs1 
%rd
 @csr    .  ... . ...   %csr %rs1 
%rd
 
 @atom_ld . aq:1 rl:1 .  . ... &atomic rs2=0 %rs1 
%rd
@@ -122,9 +122,9 @@ sltiu . 011 . 0010011 @i
 xori  . 100 . 0010011 @i
 ori   . 110 . 0010011 @i
 andi  . 111 . 0010011 @i
-slli 00 ... 001 . 0010011 @sh
-srli 00 ... 101 . 0010011 @sh
-srai 01 ... 101 . 0010011 @sh
+slli 0. ... 001 . 0010011 @sh
+srli 0. ... 101 . 0010011 @sh
+srai 01000. ... 101 . 0010011 @sh
 add  000 .. 000 . 0110011 @r
 sub  010 .. 000 . 0110011 @r
 sll  000 .. 001 . 0110011 @r
-- 
2.17.1




[RFC v2 05/15] target/riscv: rvb: pack two words into one register

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  3 ++
 target/riscv/insn32.decode  |  3 ++
 target/riscv/insn_trans/trans_rvb.c.inc | 30 ++
 target/riscv/translate.c| 41 +
 4 files changed, 77 insertions(+)

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 00c56a93151..fd7e0492372 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -91,3 +91,6 @@ hsv_d 0110111  .   . 100 0 1110011 @r2_s
 clzw   011 0 . 001 . 0011011 @r2
 ctzw   011 1 . 001 . 0011011 @r2
 pcntw  011 00010 . 001 . 0011011 @r2
+
+packw  100 .. 100 . 0111011 @r
+packuw 0100100 .. 100 . 0111011 @r
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 85421dccb99..c337aed8ca3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -602,3 +602,6 @@ pcnt   011000 10 . 001 . 0010011 @r2
 andn   010 .. 111 . 0110011 @r
 orn010 .. 110 . 0110011 @r
 xnor   010 .. 100 . 0110011 @r
+pack   100 .. 100 . 0110011 @r
+packu  0100100 .. 100 . 0110011 @r
+packh  100 .. 111 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 6016ceefd64..3da233047a9 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -53,6 +53,24 @@ static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
 return gen_arith(ctx, a, &gen_xnor);
 }
 
+static bool trans_pack(DisasContext *ctx, arg_pack *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_pack);
+}
+
+static bool trans_packu(DisasContext *ctx, arg_packu *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_packu);
+}
+
+static bool trans_packh(DisasContext *ctx, arg_packh *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_packh);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
@@ -74,4 +92,16 @@ static bool trans_pcntw(DisasContext *ctx, arg_pcntw *a)
 return gen_unary(ctx, a, &gen_pcntw);
 }
 
+static bool trans_packw(DisasContext *ctx, arg_packw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_packw);
+}
+
+static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_packuw);
+}
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fb0b2fd0728..7b427a9caec 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -732,6 +732,30 @@ static void gen_xnor(TCGv ret, TCGv arg1, TCGv arg2)
 tcg_temp_free(t);
 }
 
+static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
+{
+tcg_gen_deposit_tl(ret, arg1, arg2,
+   TARGET_LONG_BITS / 2,
+   TARGET_LONG_BITS / 2);
+}
+
+static void gen_packu(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_shri_tl(t, arg1, TARGET_LONG_BITS / 2);
+tcg_gen_deposit_tl(ret, arg2, t, 0, TARGET_LONG_BITS / 2);
+tcg_temp_free(t);
+}
+
+static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_ext8u_tl(t, arg2);
+tcg_gen_deposit_tl(ret, arg1, t, 8, TARGET_LONG_BITS - 8);
+tcg_temp_free(t);
+}
+
+
 #ifdef TARGET_RISCV64
 
 static void gen_ctzw(TCGv ret, TCGv arg1)
@@ -753,6 +777,23 @@ static void gen_pcntw(TCGv ret, TCGv arg1)
 tcg_gen_ctpop_tl(ret, arg1);
 }
 
+static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_ext16s_i64(t, arg2);
+tcg_gen_deposit_i64(ret, arg1, t, 16, 48);
+tcg_temp_free(t);
+}
+
+static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_shri_i64(t, arg1, 16);
+tcg_gen_deposit_i64(ret, arg2, t, 0, 16);
+tcg_gen_ext32s_i64(ret, ret);
+tcg_temp_free(t);
+}
+
 #endif
 
 static bool gen_arith(DisasContext *ctx, arg_r *a,
-- 
2.17.1




[RFC v2 04/15] target/riscv: rvb: logic-with-negate

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  |  4 
 target/riscv/insn_trans/trans_rvb.c.inc | 18 ++
 target/riscv/translate.c| 21 +
 3 files changed, 43 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ac4d8395a45..85421dccb99 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -598,3 +598,7 @@ vsetvl  100 . . 111 . 1010111  @r
 clz011000 00 . 001 . 0010011 @r2
 ctz011000 01 . 001 . 0010011 @r2
 pcnt   011000 10 . 001 . 0010011 @r2
+
+andn   010 .. 111 . 0110011 @r
+orn010 .. 110 . 0110011 @r
+xnor   010 .. 100 . 0110011 @r
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index f5930f2ad53..6016ceefd64 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -35,6 +35,24 @@ static bool trans_pcnt(DisasContext *ctx, arg_pcnt *a)
 return gen_unary(ctx, a, &tcg_gen_ctpop_tl);
 }
 
+static bool trans_andn(DisasContext *ctx, arg_andn *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_andn);
+}
+
+static bool trans_orn(DisasContext *ctx, arg_orn *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_orn);
+}
+
+static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_arith(ctx, a, &gen_xnor);
+}
+
 /* RV64-only instructions */
 #ifdef TARGET_RISCV64
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 4c9eb86e630..fb0b2fd0728 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -711,6 +711,27 @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
 
 #endif
 
+static void gen_andn(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_andc_tl(ret, arg1, arg2);
+tcg_temp_free(t);
+}
+
+static void gen_orn(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_orc_tl(ret, arg1, arg2);
+tcg_temp_free(t);
+}
+
+static void gen_xnor(TCGv ret, TCGv arg1, TCGv arg2)
+{
+TCGv t = tcg_temp_new();
+tcg_gen_eqv_tl(ret, arg1, arg2);
+tcg_temp_free(t);
+}
+
 #ifdef TARGET_RISCV64
 
 static void gen_ctzw(TCGv ret, TCGv arg1)
-- 
2.17.1




[RFC v2 02/15] target/riscv: rvb: count leading/trailing zeros

2020-12-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Frank Chang 
---
 target/riscv/insn32-64.decode   |  4 +++
 target/riscv/insn32.decode  |  7 +++-
 target/riscv/insn_trans/trans_rvb.c.inc | 47 +
 target/riscv/translate.c| 42 ++
 4 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/insn_trans/trans_rvb.c.inc

diff --git a/target/riscv/insn32-64.decode b/target/riscv/insn32-64.decode
index 8157dee8b7c..f4c42720fc7 100644
--- a/target/riscv/insn32-64.decode
+++ b/target/riscv/insn32-64.decode
@@ -86,3 +86,7 @@ fmv_d_x001  0 . 000 . 1010011 @r2
 hlv_wu0110100  1   . 100 . 1110011 @r2
 hlv_d 0110110  0   . 100 . 1110011 @r2
 hsv_d 0110111  .   . 100 0 1110011 @r2_s
+
+# *** RV64B Standard Extension (in addition to RV32B) ***
+clzw   011 0 . 001 . 0011011 @r2
+ctzw   011 1 . 001 . 0011011 @r2
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3823b3ea800..8fe838cf0d0 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -40,6 +40,7 @@
 &iimm rs1 rd
 &jimm rd
 &rrd rs1 rs2
+&r2   rd rs1
 &simm rs1 rs2
 &uimm rd
 &shift shamt rs1 rd
@@ -67,7 +68,7 @@
 @r4_rm   . ..  . . ... . ... %rs3 %rs2 %rs1 %rm %rd
 @r_rm...   . . ... . ... %rs2 %rs1 %rm %rd
 @r2_rm   ...   . . ... . ... %rs1 %rm %rd
-@r2  ...   . . ... . ... %rs1 %rd
+@r2  ...   . . ... . ... &r2 %rs1 %rd
 @r2_nfvm ... ... vm:1 . . ... . ... &r2nfvm %nf %rs1 %rd
 @r2_vm   .. vm:1 . . ... . ... &rmr %rs2 %rd
 @r1_vm   .. vm:1 . . ... . ... %rd
@@ -592,3 +593,7 @@ vcompress_vm010111 - . . 010 . 1010111 @r
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
+
+# *** RV32B Standard Extension ***
+clz011000 00 . 001 . 0010011 @r2
+ctz011000 01 . 001 . 0010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
new file mode 100644
index 000..fb6e16143db
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -0,0 +1,47 @@
+/*
+ * RISC-V translation routines for the RVB Standard Extension.
+ *
+ * Copyright (c) 2020 Kito Cheng, kito.ch...@sifive.com
+ * Copyright (c) 2020 Frank Chang, frank.ch...@sifive.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+static bool trans_clz(DisasContext *ctx, arg_clz *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &gen_clz);
+}
+
+static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &gen_ctz);
+}
+
+/* RV64-only instructions */
+#ifdef TARGET_RISCV64
+
+static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &gen_clzw);
+}
+
+static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
+{
+REQUIRE_EXT(ctx, RVB);
+return gen_unary(ctx, a, &gen_ctzw);
+}
+
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 554d52a4be3..398d4502a96 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -711,6 +711,23 @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
 
 #endif
 
+#ifdef TARGET_RISCV64
+
+static void gen_ctzw(TCGv ret, TCGv arg1)
+{
+tcg_gen_ori_i64(ret, arg1, MAKE_64BIT_MASK(32, 32));
+tcg_gen_ctzi_i64(ret, ret, 32);
+}
+
+static void gen_clzw(TCGv ret, TCGv arg1)
+{
+tcg_gen_ext32u_i64(ret, arg1);
+tcg_gen_clzi_i64(ret, ret, 64);
+tcg_gen_subi_i64(ret, ret, 32);
+}
+
+#endif
+
 static bool gen_arith(DisasContext *ctx, arg_r *a,
   void(*func)(TCGv, TCGv, TCGv))
 {
@@ -747,6 +764,30 @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
 return true;
 }
 
+static void gen_ctz(TCGv ret, TCGv arg1)
+{
+tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
+}
+
+static void gen_clz(TCGv ret, TCGv arg1)
+{
+tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
+}
+
+static bool gen_unary(DisasContext *ctx, arg_r2 *a,
+  void(*func)(TCGv, TCGv))
+{
+TCGv source = tcg_temp_new

[RFC v2 00/15] support subsets of bitmanip extension

2020-12-15 Thread frank . chang
From: Frank Chang 

This patchset implements RISC-V B-extension draft version Zbb, Zbs and
Zba subset instructions. Some Zbp instructions are also implemented as
they have similar behavior with their Zbb-, Zbs- and Zba-family
instructions or for Zbb pseudo instructions (e.g. rev8, orc.b).

Specification:
https://github.com/riscv/riscv-bitmanip

Summary of current proposals for Zb{abcs}:
https://lists.riscv.org/g/tech-bitmanip/topic/summary_of_current_proposals/77924315

The port is available here:
https://github.com/sifive/qemu/tree/rvb-upstream-v2

To test rvb implementation, specify cpu argument with 'x-b=true' to
enable B-extension support.

Changelog:

v2:
 * Add gen_shifti(), gen_shiftw(), gen_shiftiw() helper functions.
 * Remove addwu, subwu and addiwu instructions as they are not longer
   exist in latest draft.
 * Optimize implementation with cleaner tcg ops.

Frank Chang (3):
  target/riscv: rvb: count bits set
  target/riscv: rvb: generalized reverse
  target/riscv: rvb: generalized or-combine

Kito Cheng (12):
  target/riscv: reformat @sh format encoding for B-extension
  target/riscv: rvb: count leading/trailing zeros
  target/riscv: rvb: logic-with-negate
  target/riscv: rvb: pack two words into one register
  target/riscv: rvb: min/max instructions
  target/riscv: rvb: sign-extend instructions
  target/riscv: rvb: single-bit instructions
  target/riscv: rvb: shift ones
  target/riscv: rvb: rotate (left/right)
  target/riscv: rvb: address calculation
  target/riscv: rvb: add/sub with postfix zero-extend
  target/riscv: rvb: support and turn on B-extension from command line

 target/riscv/bitmanip_helper.c  | 103 ++
 target/riscv/cpu.c  |   4 +
 target/riscv/cpu.h  |   2 +
 target/riscv/helper.h   |   9 +
 target/riscv/insn32-64.decode   |  33 ++
 target/riscv/insn32.decode  |  54 ++-
 target/riscv/insn_trans/trans_rvb.c.inc | 466 
 target/riscv/meson.build|   1 +
 target/riscv/translate.c| 337 +
 9 files changed, 1003 insertions(+), 6 deletions(-)
 create mode 100644 target/riscv/bitmanip_helper.c
 create mode 100644 target/riscv/insn_trans/trans_rvb.c.inc

--
2.17.1




[PATCH] configure: Fail when specified cross compiler cannot be found

2020-12-15 Thread Gustavo Romero
Currently if the cross compiler passed to 'configure' (--cross-cc-) does
not exist no error happens and only later when the TCG tests are run they fail
because the cross compiler is not set correctly.

This commit changes that behavior and make 'configure' fail if the specified
cross compiler cannot be found, displaying an error similar to the following:

$ ../configure --target-list=ppc64-softmmu --cross-cc-ppc64=nonexisting_gcc
Specified cross-compiler 'nonexisting_gcc' not found!

Signed-off-by: Gustavo Romero 
---
 configure  | 2 +-
 tests/tcg/configure.sh | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index cb21108d34..c0389f5839 100755
--- a/configure
+++ b/configure
@@ -6854,7 +6854,7 @@ done
   export $i
 done
 export target_list source_path use_containers
-$source_path/tests/tcg/configure.sh)
+$source_path/tests/tcg/configure.sh) || exit 1
 
 # temporary config to build submodules
 for rom in seabios; do
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index e1b70e25f2..6c89d75c38 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -212,8 +212,10 @@ for target in $target_list; do
 
 eval "target_compiler=\${cross_cc_$i}"
 if ! has $target_compiler; then
-  continue
+  echo "Specified cross-compiler '$target_compiler' not found!"
+  exit 1
 fi
+
 write_c_skeleton
 if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC 
-static ; then
   # For host systems we might get away with building without -static
-- 
2.17.1




Re: [PATCH] spapr/xive: Make spapr_xive_pic_print_info() static

2020-12-15 Thread David Gibson
On Tue, Dec 15, 2020 at 06:40:25PM +0100, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater 

Applied to ppc-for-6.0, thanks.

> ---
>  include/hw/ppc/spapr_xive.h | 2 --
>  hw/intc/spapr_xive.c| 2 +-
>  2 files changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h
> index 26c8d90d7196..b282960ad90d 100644
> --- a/include/hw/ppc/spapr_xive.h
> +++ b/include/hw/ppc/spapr_xive.h
> @@ -66,8 +66,6 @@ typedef struct SpaprXiveClass {
>   */
>  #define SPAPR_XIVE_BLOCK_ID 0x0
>  
> -void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
> -
>  struct SpaprMachineState;
>  void spapr_xive_hcall_init(struct SpaprMachineState *spapr);
>  void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index caedd312d745..801bc1934160 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -156,7 +156,7 @@ static void spapr_xive_end_pic_print_info(SpaprXive 
> *xive, XiveEND *end,
>  #define spapr_xive_in_kernel(xive) \
>  (kvm_irqchip_in_kernel() && (xive)->fd != -1)
>  
> -void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
> +static void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
>  {
>  XiveSource *xsrc = &xive->source;
>  int i;

-- 
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] spapr: DRC lookup cannot fail

2020-12-15 Thread David Gibson
On Tue, Dec 15, 2020 at 06:36:51PM +0100, Greg Kurz wrote:
> All memory DRC objects are created during machine init. It is thus safe
> to assume spapr_drc_by_id() cannot return NULL when hot-plug/unplugging
> memory.
> 
> Make this clear with an assertion, like the code already does a few lines
> above when looping over memory DRCs. This fixes Coverity reports 1437757
> and 1437758.
> 
> Signed-off-by: Greg Kurz 

Applied to ppc-for-6.0, thanks.

> ---
>  hw/ppc/spapr.c |2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index dee48a0043bb..c283ff639040 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3424,6 +3424,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
> addr_start, uint64_t size,
>  if (dedicated_hp_event_source) {
>  drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
>addr_start / SPAPR_MEMORY_BLOCK_SIZE);
> +g_assert(drc);
>  
> spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
> nr_lmbs,
> spapr_drc_index(drc));
> @@ -3664,6 +3665,7 @@ static void spapr_memory_unplug_request(HotplugHandler 
> *hotplug_dev,
>  
>  drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
>addr_start / SPAPR_MEMORY_BLOCK_SIZE);
> +g_assert(drc);
>  spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
>nr_lmbs, spapr_drc_index(drc));
>  }
> 
> 

-- 
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 v11 00/13] hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set

2020-12-15 Thread Keith Busch
Hi Dmitry,

Looks good to me, thanks for sticking with it.

Reviewed-by: Keith Busch 



Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper

2020-12-15 Thread Philippe Mathieu-Daudé
On 12/16/20 12:27 AM, Richard Henderson wrote:
> On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
>> +bool isa_rel6_available(const CPUMIPSState *env)
>> +{
>> +if (TARGET_LONG_BITS == 64) {
>> +return cpu_supports_isa(env, ISA_MIPS64R6);
>> +}
>> +return cpu_supports_isa(env, ISA_MIPS32R6);
>> +}
> 
> So... does qemu-system-mips64 support 32-bit cpus?

Well... TBH I never tested it :S It looks the TCG code
is compiled with 64-bit TL registers, the machine address
space is 64-bit regardless the CPU, and I see various
#ifdef MIPS64 code that look dubious with 32-bit CPU.

> 
> If so, this needs to be written
> 
>   if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
> return true;
>   }
> 
> Otherwise, this will return false for a mips32r6 cpu.

I see. Rel6 is new to me, so I'll have to look at the ISA
manuals before returning to this thread with an answer.

Thanks for reviewing the series!

Phil.



Re: [PATCH] tcg: Use memset for large vector byte replication

2020-12-15 Thread Philippe Mathieu-Daudé
On 12/15/20 6:48 PM, Richard Henderson wrote:
> In f47db80cc07, we handled odd-sized tail clearing for
> the case of hosts that have vector operations, but did
> not handle the case of hosts that do not have vector ops.
> 
> This was ok until e2e7168a214b, which changed the encoding
> of simd_desc such that the odd sizes are impossible.
> 
> Add memset as a tcg helper, and use that for all out-of-line
> byte stores to vectors.  This includes, but is not limited to,
> the tail clearing operation in question.
> 
> Cc: qemu-sta...@nongnu.org
> Buglink: https://bugs.launchpad.net/bugs/1907817
> Signed-off-by: Richard Henderson 
> ---
>  accel/tcg/tcg-runtime.h | 11 +++
>  include/exec/helper-proto.h |  4 
>  tcg/tcg-op-gvec.c   | 32 
>  3 files changed, 47 insertions(+)
> 
> diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
> index 4eda24e63a..2e36d6eb0c 100644
> --- a/accel/tcg/tcg-runtime.h
> +++ b/accel/tcg/tcg-runtime.h
> @@ -28,6 +28,17 @@ DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, 
> env)
>  
>  DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)
>  
> +#ifndef IN_HELPER_PROTO
> +/*
> + * Pass calls to memset directly to libc, without a thunk in qemu.
> + * Do not re-declare memset, especially since we fudge the type here;
> + * we assume sizeof(void *) == sizeof(size_t), which is true for
> + * all supported hosts.
> + */
> +#define helper_memset memset
> +DEF_HELPER_FLAGS_3(memset, TCG_CALL_NO_RWG, ptr, ptr, int, ptr)

Nice :)

> +#endif /* IN_HELPER_PROTO */
> +
>  #ifdef CONFIG_SOFTMMU
>  
>  DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG,
> diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
> index a0a8d9aa46..659f9298e8 100644
> --- a/include/exec/helper-proto.h
> +++ b/include/exec/helper-proto.h
> @@ -35,11 +35,15 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), 
> dh_ctype(t3), \
>  dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
>  dh_ctype(t7));
>  
> +#define IN_HELPER_PROTO
> +
>  #include "helper.h"
>  #include "trace/generated-helpers.h"
>  #include "tcg-runtime.h"
>  #include "plugin-helpers.h"
>  
> +#undef IN_HELPER_PROTO
> +
>  #undef DEF_HELPER_FLAGS_0
>  #undef DEF_HELPER_FLAGS_1
>  #undef DEF_HELPER_FLAGS_2
> diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
> index ddbe06b71a..6c42d76f3a 100644
> --- a/tcg/tcg-op-gvec.c
> +++ b/tcg/tcg-op-gvec.c
> @@ -547,6 +547,9 @@ static void do_dup(unsigned vece, uint32_t dofs, uint32_t 
> oprsz,
>  in_c = dup_const(vece, in_c);
>  if (in_c == 0) {
>  oprsz = maxsz;
> +vece = MO_8;
> +} else if (in_c == dup_const(MO_8, in_c)) {
> +vece = MO_8;

Nice optimization.

>  }
>  }
>  
> @@ -628,6 +631,35 @@ static void do_dup(unsigned vece, uint32_t dofs, 
> uint32_t oprsz,
>  /* Otherwise implement out of line.  */
>  t_ptr = tcg_temp_new_ptr();
>  tcg_gen_addi_ptr(t_ptr, cpu_env, dofs);
> +
> +/*
> + * This may be expand_clr for the tail of an operation, e.g.
> + * oprsz == 8 && maxsz == 64.  The size of the clear is misaligned
> + * wrt simd_desc and will assert.  Simply pass all replicated byte
> + * stores through to memset.
> + */
> +if (oprsz == maxsz && vece == MO_8) {
> +TCGv_ptr t_size = tcg_const_ptr(oprsz);
> +TCGv_i32 t_val;
> +
> +if (in_32) {
> +t_val = in_32;
> +} else if (in_64) {
> +t_val = tcg_temp_new_i32();
> +tcg_gen_extrl_i64_i32(t_val, in_64);
> +} else {
> +t_val = tcg_const_i32(in_c);
> +}
> +gen_helper_memset(t_ptr, t_ptr, t_val, t_size);
> +
> +tcg_temp_free_ptr(t_ptr);
> +tcg_temp_free_ptr(t_size);
> +if (!in_32) {
> +tcg_temp_free_i32(t_val);
> +}
> +return;

LGTM but I'd rather have another R-b:
Reviewed-by: Philippe Mathieu-Daudé 

BTW (nitpicking) I'd rewrite the epilogue as:

if (!in_32) {
tcg_temp_free_i32(t_val);
}
tcg_temp_free_ptr(t_size);

tcg_temp_free_ptr(t_ptr);
return;

t_val first, because the !in_32 allocs are few lines earlier,
t_ptr last because allocated in prologue, so keep close to
'return'. Matter of taste ;)

> +}
> +
>  t_desc = tcg_const_i32(simd_desc(oprsz, maxsz, 0));
>  
>  if (vece == MO_64) {
> 




Re: [PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Add the LSA opcode to the MSA32 decodetree config, add DLSA
> to a new config for the MSA64 ASE, and call decode_msa64()
> in the main decode_opc() loop.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/mod-msa32.decode|  4 
>  target/mips/mod-msa64.decode| 17 +
>  target/mips/mod-msa_translate.c | 14 ++
>  target/mips/meson.build |  2 ++
>  4 files changed, 37 insertions(+)
>  create mode 100644 target/mips/mod-msa64.decode

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> +bool isa_rel6_available(const CPUMIPSState *env)
> +{
> +if (TARGET_LONG_BITS == 64) {
> +return cpu_supports_isa(env, ISA_MIPS64R6);
> +}
> +return cpu_supports_isa(env, ISA_MIPS32R6);
> +}

So... does qemu-system-mips64 support 32-bit cpus?

If so, this needs to be written

  if (TARGET_LONG_BITS == 64 && cpu_supports_isa(...)) {
return true;
  }

Otherwise, this will return false for a mips32r6 cpu.


r~



Re: [PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h'

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Make gen_msa() and gen_msa_branch() public declarations
> so we can keep calling them once extracted from the big
> translate.c in the next commit.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.h | 2 ++
>  target/mips/translate.c | 4 ++--
>  2 files changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc()

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> As we will slowly move to decodetree generated decoders,
> extract the legacy decoding from decode_opc(), so new
> decoders are added in decode_opc() while old code is
> removed from decode_opc_legacy().
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.c | 45 -
>  1 file changed, 26 insertions(+), 19 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> translate_init.c.inc mostly contains CPU definitions.
> msa_reset() doesn't belong here, move it with the MSA
> helpers.
> 
> One comment style is updated to avoid checkpatch.pl warning.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/internal.h   |  2 ++
>  target/mips/cpu.c|  1 +
>  target/mips/mod-msa_helper.c | 36 
>  target/mips/cpu-defs.c.inc   | 36 
>  4 files changed, 39 insertions(+), 36 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Simplify gen_check_zero_element() by passing the TCGCond
> argument along.
> 
> Suggested-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
> Maybe this can be named 'msa_translate.c' after all...
> ---
>  target/mips/mod-msa_translate.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> LSA and LDSA opcodes are also available with MIPS release 6.
> Introduce the decodetree config files and call the decode()
> helpers in the main decode_opc() loop.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.h   |  1 +
>  target/mips/isa-mips32r6.decode   | 17 
>  target/mips/isa-mips64r6.decode   | 17 
>  target/mips/isa-mips_rel6_translate.c | 37 +++
>  target/mips/translate.c   |  5 
>  target/mips/meson.build   |  3 +++
>  6 files changed, 80 insertions(+)
>  create mode 100644 target/mips/isa-mips32r6.decode
>  create mode 100644 target/mips/isa-mips64r6.decode
>  create mode 100644 target/mips/isa-mips_rel6_translate.c

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Now that we can decode the MSA ASE opcodes with decode_msa32(),
> use it and remove the unreachable code.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.h | 12 
>  target/mips/mod-msa_translate.c | 29 +
>  target/mips/translate.c | 31 ++-
>  3 files changed, 11 insertions(+), 61 deletions(-)

Need an update to the comment after function name change?

Otherwise,
Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 0/4] clock: Get rid of clock_get_ns()

2020-12-15 Thread Philippe Mathieu-Daudé
On 12/15/20 4:29 PM, Philippe Mathieu-Daudé wrote:
> On 12/15/20 4:09 PM, Peter Maydell wrote:
>> This patchseries makes some changes to the clock API:
>>  * Remove clock_get_ns()
>>  * Add clock_ticks_to_ns() to return number of nanoseconds
>>it will take the clock to tick N times
>>  * clock_display_freq() to return prettily-formatted string
>>for showing humans the approximate clock frequency
>>
...
> 
> Tested using loongson3-virt @2GHz
> https://lists.gnu.org/archive/html/qemu-devel/2020-12/msg04036.html
> 
> Without your series:
> qemu-system-mips64el: target/mips/cpu.c:385: mips_cp0_period_set:
> Assertion `env->cp0_count_ns' failed.
> Aborted (core dumped)
> 
> With: OK (cpu are not displayed in 'info qtree').
> 
> Reviewed-by: Philippe Mathieu-Daudé 

I meant:
Tested-by: Philippe Mathieu-Daudé 

But now I reviewed, so confirming:
Reviewed-by: Philippe Mathieu-Daudé 

Thanks!

Phil.



Re: [PATCH v4 07/43] tcg: Add in_code_gen_buffer

2020-12-15 Thread Philippe Mathieu-Daudé
On 12/15/20 11:43 PM, Richard Henderson wrote:
> On 12/14/20 4:09 PM, Philippe Mathieu-Daudé wrote:
>> On 12/14/20 3:02 PM, Richard Henderson wrote:
>>> Create a function to determine if a pointer is within the buffer.
>>>
>>> Signed-off-by: Richard Henderson 
>>> ---
>>>  include/tcg/tcg.h |  6 ++
>>>  accel/tcg/translate-all.c | 26 --
>>>  2 files changed, 14 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
>>> index bb1e97b13b..e4d0ace44b 100644
>>> --- a/include/tcg/tcg.h
>>> +++ b/include/tcg/tcg.h
>>> @@ -680,6 +680,12 @@ extern __thread TCGContext *tcg_ctx;
>>>  extern void *tcg_code_gen_epilogue;
>>>  extern TCGv_env cpu_env;
>>>  
>>> +static inline bool in_code_gen_buffer(const void *p)
>>> +{
>>> +const TCGContext *s = &tcg_init_ctx;
>>> +return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
>>
>> If 'p == s->code_gen_buffer + s->code_gen_buffer_size',
>> is it really "in" the buffer?
> 
> Well, sort of.
> 
> Compare the fact that in C, a pointer to the end of an array is valid as a
> pointer even though it can't be dereferenced.  This is a pointer to the end of
> the buffer.
> 
> Extra commentary required?

Preferably, since you change from '<' to '<=', this would
make it clearer, then no question asked :)

With it:
Reviewed-by: Philippe Mathieu-Daudé 

Thanks,

Phil.



Re: [PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Introduce the 'mod-msa32' decodetree config for the 32-bit MSA ASE.
> 
> We decode the branch instructions, and all instructions based
> on the MSA opcode.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.h |  3 +++
>  target/mips/mod-msa32.decode| 24 +
>  target/mips/mod-msa_translate.c | 37 -
>  target/mips/translate.c |  1 -
>  target/mips/meson.build |  5 +
>  5 files changed, 68 insertions(+), 2 deletions(-)
>  create mode 100644 target/mips/mod-msa32.decode

Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators

2020-12-15 Thread Richard Henderson
On 12/15/20 4:57 PM, Philippe Mathieu-Daudé wrote:
> Extract gen_lsa() from translate.c and explode it as
> gen_LSA() and gen_DLSA().
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/translate.h|  6 
>  target/mips/translate.c| 35 +++-
>  target/mips/translate_addr_const.c | 52 ++
>  target/mips/meson.build|  1 +
>  4 files changed, 63 insertions(+), 31 deletions(-)
>  create mode 100644 target/mips/translate_addr_const.c

Reviewed-by: Richard Henderson 

r~



[RFC PATCH v2 24/24] target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()

2020-12-15 Thread Philippe Mathieu-Daudé
Simplify gen_check_zero_element() by passing the TCGCond
argument along.

Suggested-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
Maybe this can be named 'msa_translate.c' after all...
---
 target/mips/mod-msa_translate.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index f139ba784dc..7ad14b19b0c 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -309,7 +309,8 @@ static inline int check_msa_access(DisasContext *ctx)
 return 1;
 }
 
-static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
+static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt,
+   TCGCond cond)
 {
 /* generates tcg ops to check if any element is 0 */
 /* Note this function only works with MSA_WRLEN = 128 */
@@ -344,7 +345,7 @@ static void gen_check_zero_element(TCGv tresult, uint8_t 
df, uint8_t wt)
 tcg_gen_or_i64(t0, t0, t1);
 /* if all bits are zero then all elements are not zero */
 /* if some bit is non-zero then some element is zero */
-tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
+tcg_gen_setcondi_i64(cond, t0, t0, 0);
 tcg_gen_trunc_i64_tl(tresult, t0);
 tcg_temp_free_i64(t0);
 tcg_temp_free_i64(t1);
@@ -393,10 +394,7 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, 
int s16, bool if_not)
 return true;
 }
 
-gen_check_zero_element(bcond, df, wt);
-if (if_not) {
-tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
-}
+gen_check_zero_element(bcond, df, wt, if_not ? TCG_COND_EQ : TCG_COND_NE);
 
 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
 ctx->hflags |= MIPS_HFLAG_BC;
-- 
2.26.2




[PATCH v2 23/24] target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes

2020-12-15 Thread Philippe Mathieu-Daudé
LSA and LDSA opcodes are also available with MIPS release 6.
Introduce the decodetree config files and call the decode()
helpers in the main decode_opc() loop.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h   |  1 +
 target/mips/isa-mips32r6.decode   | 17 
 target/mips/isa-mips64r6.decode   | 17 
 target/mips/isa-mips_rel6_translate.c | 37 +++
 target/mips/translate.c   |  5 
 target/mips/meson.build   |  3 +++
 6 files changed, 80 insertions(+)
 create mode 100644 target/mips/isa-mips32r6.decode
 create mode 100644 target/mips/isa-mips64r6.decode
 create mode 100644 target/mips/isa-mips_rel6_translate.c

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 47129de81d9..cbaef53b958 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -161,6 +161,7 @@ extern TCGv bcond;
 void msa_translate_init(void);
 
 /* decodetree generated */
+bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
 
 #endif
diff --git a/target/mips/isa-mips32r6.decode b/target/mips/isa-mips32r6.decode
new file mode 100644
index 000..027585ee042
--- /dev/null
+++ b/target/mips/isa-mips32r6.decode
@@ -0,0 +1,17 @@
+# MIPS32 Release 6 instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#   MIPS Architecture for Programmers Volume II-A
+#   The MIPS32 Instruction Set Reference Manual, Revision 6.06
+#   (Document Number: MD00086-2B-MIPS32BIS-AFP-06.06)
+#
+
+&lsard rt rs sa
+
+@lsa.. rs:5 rt:5 rd:5 ... sa:2 ..   &lsa
+
+LSA 00 . . . 000 .. 000101  @lsa
diff --git a/target/mips/isa-mips64r6.decode b/target/mips/isa-mips64r6.decode
new file mode 100644
index 000..e812224341e
--- /dev/null
+++ b/target/mips/isa-mips64r6.decode
@@ -0,0 +1,17 @@
+# MIPS64 Release 6 instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#   MIPS Architecture for Programmers Volume II-A
+#   The MIPS64 Instruction Set Reference Manual, Revision 6.06
+#   (Document Number: MD00087-2B-MIPS64BIS-AFP-6.06)
+#
+
+&lsard rt rs sa !extern
+
+@lsa.. rs:5 rt:5 rd:5 ... sa:2 ..   &lsa
+
+DLSA00 . . . 000 .. 010101  @lsa
diff --git a/target/mips/isa-mips_rel6_translate.c 
b/target/mips/isa-mips_rel6_translate.c
new file mode 100644
index 000..d5872bbf8fc
--- /dev/null
+++ b/target/mips/isa-mips_rel6_translate.c
@@ -0,0 +1,37 @@
+/*
+ *  MIPS emulation for QEMU - # Release 6 translation routines
+ *
+ *  Copyright (c) 2004-2005 Jocelyn Mayer
+ *  Copyright (c) 2006 Marius Groeger (FPU operations)
+ *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ *  Copyright (c) 2020 Philippe Mathieu-Daudé
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "exec/helper-gen.h"
+#include "translate.h"
+
+/* Include the auto-generated decoder.  */
+#include "decode-isa-mips32r6.c.inc"
+#include "decode-isa-mips64r6.c.inc"
+
+static bool trans_LSA(DisasContext *ctx, arg_LSA *a)
+{
+return gen_LSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+static bool trans_DLSA(DisasContext *ctx, arg_LSA *a)
+{
+return gen_DLSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+bool decode_isa_rel6(DisasContext *ctx, uint32_t insn)
+{
+if (TARGET_LONG_BITS == 64 && decode_mips64r6(ctx, insn)) {
+return true;
+}
+return decode_mips32r6(ctx, insn);
+}
diff --git a/target/mips/translate.c b/target/mips/translate.c
index e0439ba92d8..125b2aac848 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -29027,6 +29027,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 return;
 }
 
+/* ISA */
+if (isa_rel6_available(env) && decode_isa_rel6(ctx, ctx->opcode)) {
+return;
+}
+
 if (!decode_opc_legacy(env, ctx)) {
 gen_reserved_instruction(ctx);
 }
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 8e2e5fa40b8..2d62288d604 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,4 +1,6 @@
 gen = [
+  decodetree.process('isa-mips32r6.decode', extra_args: [ 
'--static-decode=decode_mips32r6' ]),
+  decodetree.process('isa-mips64r6.decode', extra_args: [ 
'--static-decode=decode_mips64r6' ]),
   decodetree.process('mod-msa32.decode', extra_args: [ 
'--static-decode=decode_msa32' ]),
   decodetree.process('mod-msa64.decode', extra_args: [ 
'--static-decode=decode_msa64' ]),
 ]
@@ -12,6 +14,7 @@
 mips_ss.add(when: 'CONFIG_TCG', if_true: files(
   'dsp_helper.c',
   'fpu_helper.c',
+  'isa-mips_rel6_translate.c',
   'lmmi_helper.c',
   'op_helper.c',
   'mod-msa_helper.c',

[PATCH v2 20/24] target/mips: Use decode_ase_msa() generated from decodetree

2020-12-15 Thread Philippe Mathieu-Daudé
Now that we can decode the MSA ASE opcodes with decode_msa32(),
use it and remove the unreachable code.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h | 12 
 target/mips/mod-msa_translate.c | 29 +
 target/mips/translate.c | 31 ++-
 3 files changed, 11 insertions(+), 61 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 7ca92bd6beb..8d84e0c254d 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -82,8 +82,6 @@ enum {
 OPC_BC1  = (0x08 << 21) | OPC_CP1, /* bc */
 OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
-OPC_BZ_V = (0x0B << 21) | OPC_CP1,
-OPC_BNZ_V= (0x0F << 21) | OPC_CP1,
 OPC_S_FMT= (FMT_S << 21) | OPC_CP1,
 OPC_D_FMT= (FMT_D << 21) | OPC_CP1,
 OPC_E_FMT= (FMT_E << 21) | OPC_CP1,
@@ -93,14 +91,6 @@ enum {
 OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
-OPC_BZ_B = (0x18 << 21) | OPC_CP1,
-OPC_BZ_H = (0x19 << 21) | OPC_CP1,
-OPC_BZ_W = (0x1A << 21) | OPC_CP1,
-OPC_BZ_D = (0x1B << 21) | OPC_CP1,
-OPC_BNZ_B= (0x1C << 21) | OPC_CP1,
-OPC_BNZ_H= (0x1D << 21) | OPC_CP1,
-OPC_BNZ_W= (0x1E << 21) | OPC_CP1,
-OPC_BNZ_D= (0x1F << 21) | OPC_CP1,
 };
 
 #define MASK_CP1_FUNC(op)   (MASK_CP1(op) | (op & 0x3F))
@@ -163,8 +153,6 @@ extern TCGv bcond;
 
 /* MSA */
 void msa_translate_init(void);
-void gen_msa(DisasContext *ctx);
-void gen_msa_branch(DisasContext *ctx, uint32_t op1);
 
 /* decodetree generated */
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index d0e393a6831..d1a8a95e62e 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -414,33 +414,6 @@ static bool trans_BNZ_x(DisasContext *ctx, arg_msa_bz *a)
 return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, true);
 }
 
-void gen_msa_branch(DisasContext *ctx, uint32_t op1)
-{
-uint8_t df = (ctx->opcode >> 21) & 0x3;
-uint8_t wt = (ctx->opcode >> 16) & 0x1f;
-int64_t s16 = (int16_t)ctx->opcode;
-
-switch (op1) {
-case OPC_BZ_V:
-case OPC_BNZ_V:
-gen_msa_BxZ_V(ctx, wt, s16, (op1 == OPC_BZ_V) ?
-TCG_COND_EQ : TCG_COND_NE);
-break;
-case OPC_BZ_B:
-case OPC_BZ_H:
-case OPC_BZ_W:
-case OPC_BZ_D:
-gen_msa_BxZ(ctx, df, wt, s16, false);
-break;
-case OPC_BNZ_B:
-case OPC_BNZ_H:
-case OPC_BNZ_W:
-case OPC_BNZ_D:
-gen_msa_BxZ(ctx, df, wt, s16, true);
-break;
-}
-}
-
 static void gen_msa_i8(DisasContext *ctx)
 {
 #define MASK_MSA_I8(op)(MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
@@ -2190,7 +2163,7 @@ static void gen_msa_vec(DisasContext *ctx)
 }
 }
 
-void gen_msa(DisasContext *ctx)
+static void gen_msa(DisasContext *ctx)
 {
 uint32_t opcode = ctx->opcode;
 
diff --git a/target/mips/translate.c b/target/mips/translate.c
index f36255f073a..2ce3dc10dfb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -6,6 +6,7 @@
  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
+ *  Copyright (c) 2020 Philippe Mathieu-Daudé
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -135,8 +136,6 @@ enum {
 OPC_JIALC= (0x3E << 26),
 /* MDMX ASE specific */
 OPC_MDMX = (0x1E << 26),
-/* MSA ASE, same as MDMX */
-OPC_MSA  = OPC_MDMX,
 /* Cache and prefetch */
 OPC_CACHE= (0x2F << 26),
 OPC_PREF = (0x33 << 26),
@@ -28828,20 +28827,6 @@ static bool decode_opc_legacy(CPUMIPSState *env, 
DisasContext *ctx)
 }
 break;
 }
-case OPC_BZ_V:
-case OPC_BNZ_V:
-case OPC_BZ_B:
-case OPC_BZ_H:
-case OPC_BZ_W:
-case OPC_BZ_D:
-case OPC_BNZ_B:
-case OPC_BNZ_H:
-case OPC_BNZ_W:
-case OPC_BNZ_D:
-if (ase_msa_available(env)) {
-gen_msa_branch(ctx, op1);
-break;
-}
 default:
 MIPS_INVAL("cp1");
 gen_reserved_instruction(ctx);
@@ -29023,16 +29008,13 @@ static bool decode_opc_legacy(CPUMIPSState *env, 
DisasContext *ctx)
 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
 }
 break;
-case OPC_MSA: /* OPC_MDMX */
+case OPC_MDMX: /* MMI_OPC_LQ */
 if (ctx->insn_flags & INSN_R5900) {
 #if defined(TARGET_MIPS64)
-gen_mmi_lq(env, ctx);/* MMI_OPC_LQ */
+gen_mmi_lq(env, ctx);
 #endif
 } e

[PATCH v2 13/24] target/mips: Rename msa_helper.c as mod-msa_helper.c

2020-12-15 Thread Philippe Mathieu-Daudé
MSA means 'MIPS SIMD Architecture' and is defined as a Module by
MIPS.
To keep the directory sorted, we use the 'mod' prefix for MIPS
modules. Rename msa_helper.c as mod-msa_helper.c.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20201123204448.3260804-4-f4...@amsat.org>
---
 target/mips/{msa_helper.c => mod-msa_helper.c} | 0
 target/mips/meson.build| 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename target/mips/{msa_helper.c => mod-msa_helper.c} (100%)

diff --git a/target/mips/msa_helper.c b/target/mips/mod-msa_helper.c
similarity index 100%
rename from target/mips/msa_helper.c
rename to target/mips/mod-msa_helper.c
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 596eb1aeeb3..05ed33b75ce 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -7,8 +7,8 @@
   'dsp_helper.c',
   'fpu_helper.c',
   'lmmi_helper.c',
-  'msa_helper.c',
   'op_helper.c',
+  'mod-msa_helper.c',
   'tlb_helper.c',
   'translate.c',
 ))
-- 
2.26.2




[PATCH v2 22/24] target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes

2020-12-15 Thread Philippe Mathieu-Daudé
Add the LSA opcode to the MSA32 decodetree config, add DLSA
to a new config for the MSA64 ASE, and call decode_msa64()
in the main decode_opc() loop.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/mod-msa32.decode|  4 
 target/mips/mod-msa64.decode| 17 +
 target/mips/mod-msa_translate.c | 14 ++
 target/mips/meson.build |  2 ++
 4 files changed, 37 insertions(+)
 create mode 100644 target/mips/mod-msa64.decode

diff --git a/target/mips/mod-msa32.decode b/target/mips/mod-msa32.decode
index d69675132b8..0b2f0863251 100644
--- a/target/mips/mod-msa32.decode
+++ b/target/mips/mod-msa32.decode
@@ -10,11 +10,15 @@
 #   (Document Number: MD00866-2B-MSA32-AFP-01.12)
 #
 
+&lsard rt rs sa
 &msa_bz df wt s16
 
+@lsa.. rs:5 rt:5 rd:5 ... sa:2 ..   &lsa
 @bz .. ... ..   wt:5 s16:16 &msa_bz df=3
 @bz_df  .. ... df:2 wt:5 s16:16 &msa_bz
 
+LSA 00 . . . 000 .. 000101  @lsa
+
 BZ_V010001 01011  . @bz
 BNZ_V   010001 0  . @bz
 
diff --git a/target/mips/mod-msa64.decode b/target/mips/mod-msa64.decode
new file mode 100644
index 000..8dcbbcd8538
--- /dev/null
+++ b/target/mips/mod-msa64.decode
@@ -0,0 +1,17 @@
+# MIPS SIMD Architecture Module instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#   MIPS Architecture for Programmers Volume IV-j
+#   The MIPS64 SIMD Architecture Module, Revision 1.12
+#   (Document Number: MD00868-1D-MSA64-AFP-01.12)
+#
+
+&lsard rt rs sa !extern
+
+@lsa.. rs:5 rt:5 rd:5 ... sa:2 ..   &lsa
+
+DLSA 00 . . . 000 .. 010101 @lsa
diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index d1a8a95e62e..f139ba784dc 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -19,6 +19,7 @@
 
 /* Include the auto-generated decoder.  */
 #include "decode-mod-msa32.c.inc"
+#include "decode-mod-msa64.c.inc"
 
 #define OPC_MSA (0x1E << 26)
 
@@ -2268,7 +2269,20 @@ static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
 return true;
 }
 
+static bool trans_LSA(DisasContext *ctx, arg_LSA *a)
+{
+return gen_LSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
+static bool trans_DLSA(DisasContext *ctx, arg_LSA *a)
+{
+return gen_DLSA(ctx, a->rd, a->rt, a->rs, a->sa);
+}
+
 bool decode_ase_msa(DisasContext *ctx, uint32_t insn)
 {
+if (TARGET_LONG_BITS == 64 && decode_msa64(ctx, insn)) {
+return true;
+}
 return decode_msa32(ctx, insn);
 }
diff --git a/target/mips/meson.build b/target/mips/meson.build
index dce0ca96527..8e2e5fa40b8 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,5 +1,6 @@
 gen = [
   decodetree.process('mod-msa32.decode', extra_args: [ 
'--static-decode=decode_msa32' ]),
+  decodetree.process('mod-msa64.decode', extra_args: [ 
'--static-decode=decode_msa64' ]),
 ]
 
 mips_ss = ss.source_set()
@@ -19,6 +20,7 @@
   'translate_addr_const.c',
   'mod-msa_translate.c',
 ))
+
 mips_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
 
 mips_softmmu_ss = ss.source_set()
-- 
2.26.2




[PATCH v2 12/24] target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ()

2020-12-15 Thread Philippe Mathieu-Daudé
In preparation of using the decodetree script, explode
gen_msa_branch() as following:

- OPC_BZ_V  -> BxZ_V(EQ)
- OPC_BNZ_V -> BxZ_V(NE)
- OPC_BZ_[BHWD] -> BxZ(false)
- OPC_BNZ_[BHWD]-> BxZ(true)

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 71 -
 1 file changed, 49 insertions(+), 22 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index a3618a3beb2..9be946256b3 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28615,49 +28615,76 @@ static void gen_check_zero_element(TCGv tresult, 
uint8_t df, uint8_t wt)
 tcg_temp_free_i64(t1);
 }
 
+static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int s16, TCGCond cond)
+{
+TCGv_i64 t0;
+
+check_msa_access(ctx);
+
+if (ctx->hflags & MIPS_HFLAG_BMASK) {
+gen_reserved_instruction(ctx);
+return true;
+}
+t0 = tcg_temp_new_i64();
+tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
+tcg_gen_setcondi_i64(cond, t0, t0, 0);
+tcg_gen_trunc_i64_tl(bcond, t0);
+tcg_temp_free_i64(t0);
+
+ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
+
+ctx->hflags |= MIPS_HFLAG_BC;
+ctx->hflags |= MIPS_HFLAG_BDS32;
+
+return true;
+}
+
+static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool 
if_not)
+{
+check_msa_access(ctx);
+
+if (ctx->hflags & MIPS_HFLAG_BMASK) {
+gen_reserved_instruction(ctx);
+return true;
+}
+
+gen_check_zero_element(bcond, df, wt);
+if (if_not) {
+tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
+}
+
+ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
+ctx->hflags |= MIPS_HFLAG_BC;
+ctx->hflags |= MIPS_HFLAG_BDS32;
+
+return true;
+}
+
 static void gen_msa_branch(DisasContext *ctx, uint32_t op1)
 {
 uint8_t df = (ctx->opcode >> 21) & 0x3;
 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
 int64_t s16 = (int16_t)ctx->opcode;
 
-check_msa_access(ctx);
-
-if (ctx->hflags & MIPS_HFLAG_BMASK) {
-gen_reserved_instruction(ctx);
-return;
-}
 switch (op1) {
 case OPC_BZ_V:
 case OPC_BNZ_V:
-{
-TCGv_i64 t0 = tcg_temp_new_i64();
-tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
-tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
-TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
-tcg_gen_trunc_i64_tl(bcond, t0);
-tcg_temp_free_i64(t0);
-}
+gen_msa_BxZ_V(ctx, wt, s16, (op1 == OPC_BZ_V) ?
+TCG_COND_EQ : TCG_COND_NE);
 break;
 case OPC_BZ_B:
 case OPC_BZ_H:
 case OPC_BZ_W:
 case OPC_BZ_D:
-gen_check_zero_element(bcond, df, wt);
+gen_msa_BxZ(ctx, df, wt, s16, false);
 break;
 case OPC_BNZ_B:
 case OPC_BNZ_H:
 case OPC_BNZ_W:
 case OPC_BNZ_D:
-gen_check_zero_element(bcond, df, wt);
-tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
+gen_msa_BxZ(ctx, df, wt, s16, true);
 break;
 }
-
-ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
-
-ctx->hflags |= MIPS_HFLAG_BC;
-ctx->hflags |= MIPS_HFLAG_BDS32;
 }
 
 static void gen_msa_i8(DisasContext *ctx)
-- 
2.26.2




[PATCH v2 17/24] target/mips: Declare gen_msa/_branch() in 'translate.h'

2020-12-15 Thread Philippe Mathieu-Daudé
Make gen_msa() and gen_msa_branch() public declarations
so we can keep calling them once extracted from the big
translate.c in the next commit.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h | 2 ++
 target/mips/translate.c | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index f7e7037bab8..77dfec98792 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -163,5 +163,7 @@ extern TCGv bcond;
 
 /* MSA */
 void msa_translate_init(void);
+void gen_msa(DisasContext *ctx);
+void gen_msa_branch(DisasContext *ctx, uint32_t op1);
 
 #endif
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9be946256b3..20174c4aa57 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28660,7 +28660,7 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int 
wt, int s16, bool if_not)
 return true;
 }
 
-static void gen_msa_branch(DisasContext *ctx, uint32_t op1)
+void gen_msa_branch(DisasContext *ctx, uint32_t op1)
 {
 uint8_t df = (ctx->opcode >> 21) & 0x3;
 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
@@ -30436,7 +30436,7 @@ static void gen_msa_vec(DisasContext *ctx)
 }
 }
 
-static void gen_msa(DisasContext *ctx)
+void gen_msa(DisasContext *ctx)
 {
 uint32_t opcode = ctx->opcode;
 
-- 
2.26.2




[PATCH v2 15/24] target/mips: Extract MSA helpers from op_helper.c

2020-12-15 Thread Philippe Mathieu-Daudé
We have ~400 lines of MSA helpers in the generic op_helper.c,
move them with the other helpers in 'mod-msa_helper.c'.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20201123204448.3260804-5-f4...@amsat.org>
---
 target/mips/mod-msa_helper.c | 393 ++
 target/mips/op_helper.c  | 394 ---
 2 files changed, 393 insertions(+), 394 deletions(-)

diff --git a/target/mips/mod-msa_helper.c b/target/mips/mod-msa_helper.c
index f0d728c03f0..1298a1917ce 100644
--- a/target/mips/mod-msa_helper.c
+++ b/target/mips/mod-msa_helper.c
@@ -22,6 +22,7 @@
 #include "internal.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
+#include "exec/memop.h"
 #include "fpu/softfloat.h"
 #include "fpu_helper.h"
 
@@ -8202,6 +8203,398 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 msa_move_v(pwd, pwx);
 }
 
+/* Data format min and max values */
+#define DF_BITS(df) (1 << ((df) + 3))
+
+/* Element-by-element access macros */
+#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
+
+#if !defined(CONFIG_USER_ONLY)
+#define MEMOP_IDX(DF)   \
+TCGMemOpIdx oi = make_memop_idx(MO_TE | DF | MO_UNALN,  \
+cpu_mmu_index(env, false));
+#else
+#define MEMOP_IDX(DF)
+#endif
+
+void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd,
+ target_ulong addr)
+{
+wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+MEMOP_IDX(DF_BYTE)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+#else
+pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+pwd->b[0]  = cpu_ldub_data(env, addr + (0  << DF_BYTE));
+pwd->b[1]  = cpu_ldub_data(env, addr + (1  << DF_BYTE));
+pwd->b[2]  = cpu_ldub_data(env, addr + (2  << DF_BYTE));
+pwd->b[3]  = cpu_ldub_data(env, addr + (3  << DF_BYTE));
+pwd->b[4]  = cpu_ldub_data(env, addr + (4  << DF_BYTE));
+pwd->b[5]  = cpu_ldub_data(env, addr + (5  << DF_BYTE));
+pwd->b[6]  = cpu_ldub_data(env, addr + (6  << DF_BYTE));
+pwd->b[7]  = cpu_ldub_data(env, addr + (7  << DF_BYTE));
+pwd->b[8]  = cpu_ldub_data(env, addr + (8  << DF_BYTE));
+pwd->b[9]  = cpu_ldub_data(env, addr + (9  << DF_BYTE));
+pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
+pwd->b[11] = cpu_ldub_data(env, addr + 

[PATCH v2 21/24] target/mips: Extract LSA/DLSA translation generators

2020-12-15 Thread Philippe Mathieu-Daudé
Extract gen_lsa() from translate.c and explode it as
gen_LSA() and gen_DLSA().

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h|  6 
 target/mips/translate.c| 35 +++-
 target/mips/translate_addr_const.c | 52 ++
 target/mips/meson.build|  1 +
 4 files changed, 63 insertions(+), 31 deletions(-)
 create mode 100644 target/mips/translate_addr_const.c

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 8d84e0c254d..47129de81d9 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -128,6 +128,12 @@ void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int 
reg);
 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
 int get_fp_bit(int cc);
 
+/*
+ * Address Computation and Large Constant Instructions
+ */
+bool gen_LSA(DisasContext *ctx, int rd, int rt, int rs, int sa);
+bool gen_DLSA(DisasContext *ctx, int rd, int rt, int rs, int sa);
+
 extern TCGv cpu_gpr[32], cpu_PC;
 extern TCGv_i32 fpu_fcr0, fpu_fcr31;
 extern TCGv_i64 fpu_f64[32];
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 2ce3dc10dfb..e0439ba92d8 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -6616,31 +6616,6 @@ static void gen_bshfl(DisasContext *ctx, uint32_t op2, 
int rt, int rd)
 tcg_temp_free(t0);
 }
 
-static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
-int imm2)
-{
-TCGv t0;
-TCGv t1;
-if (rd == 0) {
-/* Treat as NOP. */
-return;
-}
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-gen_load_gpr(t0, rs);
-gen_load_gpr(t1, rt);
-tcg_gen_shli_tl(t0, t0, imm2 + 1);
-tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
-if (opc == OPC_LSA) {
-tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
-}
-
-tcg_temp_free(t1);
-tcg_temp_free(t0);
-
-return;
-}
-
 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
int rt, int bits)
 {
@@ -16496,8 +16471,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
DisasContext *ctx)
 return;
 case LSA:
 check_insn(ctx, ISA_MIPS32R6);
-gen_lsa(ctx, OPC_LSA, rd, rs, rt,
-extract32(ctx->opcode, 9, 2));
+gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 9, 2));
 break;
 case ALIGN:
 check_insn(ctx, ISA_MIPS32R6);
@@ -21460,8 +21434,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, 
DisasContext *ctx)
  * amount, meaning that the supported shift values are in
  * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
  */
-gen_lsa(ctx, OPC_LSA, rd, rs, rt,
-extract32(ctx->opcode, 9, 2) - 1);
+gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 9, 2) - 1);
 break;
 case NM_EXTW:
 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
@@ -24347,7 +24320,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
DisasContext *ctx)
 op1 = MASK_SPECIAL(ctx->opcode);
 switch (op1) {
 case OPC_LSA:
-gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
+gen_LSA(ctx, rd, rs, rt, extract32(ctx->opcode, 6, 2));
 break;
 case OPC_MULT:
 case OPC_MULTU:
@@ -24401,7 +24374,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
DisasContext *ctx)
 #if defined(TARGET_MIPS64)
 case OPC_DLSA:
 check_mips_64(ctx);
-gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
+gen_DLSA(ctx, rd, rs, rt, extract32(ctx->opcode, 6, 2));
 break;
 case R6_OPC_DCLO:
 case R6_OPC_DCLZ:
diff --git a/target/mips/translate_addr_const.c 
b/target/mips/translate_addr_const.c
new file mode 100644
index 000..84662933d49
--- /dev/null
+++ b/target/mips/translate_addr_const.c
@@ -0,0 +1,52 @@
+/*
+ * Address Computation and Large Constant Instructions
+ */
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "translate.h"
+
+bool gen_LSA(DisasContext *ctx, int rd, int rt, int rs, int sa)
+{
+TCGv t0;
+TCGv t1;
+
+if (rd == 0) {
+/* Treat as NOP. */
+return true;
+}
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, rs);
+gen_load_gpr(t1, rt);
+tcg_gen_shli_tl(t0, t0, sa + 1);
+tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
+tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+
+tcg_temp_free(t1);
+tcg_temp_free(t0);
+
+return true;
+}
+
+bool gen_DLSA(DisasContext *ctx, int rd, int rt, int rs, int sa)
+{
+TCGv t0;
+TCGv t1;
+
+check_mips_64(ctx);
+
+if (rd == 0) {
+/* Treat as NOP. */
+return true;
+}
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, rs);
+gen_load_gpr(t1, rt);
+tcg_gen_shli_tl(t0, t0, sa + 1);
+tc

[PATCH v2 10/24] target/mips: Extract msa_translate_init() from mips_tcg_init()

2020-12-15 Thread Philippe Mathieu-Daudé
The msa_wr_d[] registers are only initialized/used by MSA.

They are declared static. We want to move them to the new
'mod-msa_translate.c' unit in few commits, without having to
declare them global (with extern).

Extract first the logic initialization of the MSA registers
from the generic initialization. We will later move this
function along with the MSA registers to the new C unit.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h |  3 +++
 target/mips/translate.c | 33 +++--
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 942d803476c..f7e7037bab8 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -161,4 +161,7 @@ extern TCGv bcond;
 } \
 } while (0)
 
+/* MSA */
+void msa_translate_init(void);
+
 #endif
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9b5b551b616..2dc7b446e9a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31550,6 +31550,24 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 }
 }
 
+void msa_translate_init(void)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
+
+/*
+ * The MSA vector registers are mapped on the
+ * scalar floating-point unit (FPU) registers.
+ */
+msa_wr_d[i * 2] = fpu_f64[i];
+off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
+msa_wr_d[i * 2 + 1] =
+tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
+}
+}
+
 void mips_tcg_init(void)
 {
 int i;
@@ -31565,20 +31583,7 @@ void mips_tcg_init(void)
 
 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
 }
-/* MSA */
-for (i = 0; i < 32; i++) {
-int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
-
-/*
- * The MSA vector registers are mapped on the
- * scalar floating-point unit (FPU) registers.
- */
-msa_wr_d[i * 2] = fpu_f64[i];
-off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
-msa_wr_d[i * 2 + 1] =
-tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
-}
-
+msa_translate_init();
 cpu_PC = tcg_global_mem_new(cpu_env,
 offsetof(CPUMIPSState, active_tc.PC), "PC");
 for (i = 0; i < MIPS_DSP_ACC; i++) {
-- 
2.26.2




[PATCH v2 11/24] target/mips: Remove CPUMIPSState* argument from gen_msa*() methods

2020-12-15 Thread Philippe Mathieu-Daudé
The gen_msa*() methods don't use the "CPUMIPSState *env"
argument. Remove it to simplify.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 57 -
 1 file changed, 28 insertions(+), 29 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 2dc7b446e9a..a3618a3beb2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28615,7 +28615,7 @@ static void gen_check_zero_element(TCGv tresult, 
uint8_t df, uint8_t wt)
 tcg_temp_free_i64(t1);
 }
 
-static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
+static void gen_msa_branch(DisasContext *ctx, uint32_t op1)
 {
 uint8_t df = (ctx->opcode >> 21) & 0x3;
 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
@@ -28660,7 +28660,7 @@ static void gen_msa_branch(CPUMIPSState *env, 
DisasContext *ctx, uint32_t op1)
 ctx->hflags |= MIPS_HFLAG_BDS32;
 }
 
-static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_i8(DisasContext *ctx)
 {
 #define MASK_MSA_I8(op)(MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
@@ -28718,7 +28718,7 @@ static void gen_msa_i8(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(ti8);
 }
 
-static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_i5(DisasContext *ctx)
 {
 #define MASK_MSA_I5(op)(MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
 uint8_t df = (ctx->opcode >> 21) & 0x3;
@@ -28791,7 +28791,7 @@ static void gen_msa_i5(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(timm);
 }
 
-static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_bit(DisasContext *ctx)
 {
 #define MASK_MSA_BIT(op)(MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
@@ -28875,7 +28875,7 @@ static void gen_msa_bit(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(tws);
 }
 
-static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_3r(DisasContext *ctx)
 {
 #define MASK_MSA_3R(op)(MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
 uint8_t df = (ctx->opcode >> 21) & 0x3;
@@ -29857,7 +29857,7 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(tdf);
 }
 
-static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_elm_3e(DisasContext *ctx)
 {
 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
 uint8_t source = (ctx->opcode >> 11) & 0x1f;
@@ -29889,8 +29889,7 @@ static void gen_msa_elm_3e(CPUMIPSState *env, 
DisasContext *ctx)
 tcg_temp_free_i32(tsr);
 }
 
-static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
-uint32_t n)
+static void gen_msa_elm_df(DisasContext *ctx, uint32_t df, uint32_t n)
 {
 #define MASK_MSA_ELM(op)(MASK_MSA_MINOR(op) | (op & (0xf << 22)))
 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
@@ -3,7 +2,7 @@ static void gen_msa_elm_df(CPUMIPSState *env, 
DisasContext *ctx, uint32_t df,
 tcg_temp_free_i32(tdf);
 }
 
-static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_elm(DisasContext *ctx)
 {
 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
 uint32_t df = 0, n = 0;
@@ -30019,17 +30018,17 @@ static void gen_msa_elm(CPUMIPSState *env, 
DisasContext *ctx)
 df = DF_DOUBLE;
 } else if (dfn == 0x3E) {
 /* CTCMSA, CFCMSA, MOVE.V */
-gen_msa_elm_3e(env, ctx);
+gen_msa_elm_3e(ctx);
 return;
 } else {
 gen_reserved_instruction(ctx);
 return;
 }
 
-gen_msa_elm_df(env, ctx, df, n);
+gen_msa_elm_df(ctx, df, n);
 }
 
-static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_3rf(DisasContext *ctx)
 {
 #define MASK_MSA_3RF(op)(MASK_MSA_MINOR(op) | (op & (0xf << 22)))
 uint8_t df = (ctx->opcode >> 21) & 0x1;
@@ -30187,7 +30186,7 @@ static void gen_msa_3rf(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(tdf);
 }
 
-static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_2r(DisasContext *ctx)
 {
 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
 (op & (0x7 << 18)))
@@ -30271,7 +30270,7 @@ static void gen_msa_2r(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(tdf);
 }
 
-static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_2rf(DisasContext *ctx)
 {
 #define MASK_MSA_2RF(op)(MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
 (op & (0xf << 17)))
@@ -30342,7 +30341,7 @@ static void gen_msa_2rf(CPUMIPSState *env, DisasContext 
*ctx)
 tcg_temp_free_i32(tdf);
 }
 
-static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
+static void gen_msa_vec_v(DisasContext *ctx)
 {
 #define MASK_MSA_VEC(op)(MASK_MSA_MINOR(op) | (op & 

[PATCH v2 19/24] target/mips: Introduce decode tree bindings for MSA opcodes

2020-12-15 Thread Philippe Mathieu-Daudé
Introduce the 'mod-msa32' decodetree config for the 32-bit MSA ASE.

We decode the branch instructions, and all instructions based
on the MSA opcode.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h |  3 +++
 target/mips/mod-msa32.decode| 24 +
 target/mips/mod-msa_translate.c | 37 -
 target/mips/translate.c |  1 -
 target/mips/meson.build |  5 +
 5 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 target/mips/mod-msa32.decode

diff --git a/target/mips/translate.h b/target/mips/translate.h
index 77dfec98792..7ca92bd6beb 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -166,4 +166,7 @@ void msa_translate_init(void);
 void gen_msa(DisasContext *ctx);
 void gen_msa_branch(DisasContext *ctx, uint32_t op1);
 
+/* decodetree generated */
+bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
+
 #endif
diff --git a/target/mips/mod-msa32.decode b/target/mips/mod-msa32.decode
new file mode 100644
index 000..d69675132b8
--- /dev/null
+++ b/target/mips/mod-msa32.decode
@@ -0,0 +1,24 @@
+# MIPS SIMD Architecture Module instruction set
+#
+# Copyright (C) 2020  Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+#   MIPS Architecture for Programmers Volume IV-j
+#   The MIPS32 SIMD Architecture Module, Revision 1.12
+#   (Document Number: MD00866-2B-MSA32-AFP-01.12)
+#
+
+&msa_bz df wt s16
+
+@bz .. ... ..   wt:5 s16:16 &msa_bz df=3
+@bz_df  .. ... df:2 wt:5 s16:16 &msa_bz
+
+BZ_V010001 01011  . @bz
+BNZ_V   010001 0  . @bz
+
+BZ_x010001 110 .. . @bz_df
+BNZ_x   010001 111 .. . @bz_df
+
+MSA 00 --
diff --git a/target/mips/mod-msa_translate.c b/target/mips/mod-msa_translate.c
index 63feedcb7ca..d0e393a6831 100644
--- a/target/mips/mod-msa_translate.c
+++ b/target/mips/mod-msa_translate.c
@@ -6,6 +6,7 @@
  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
+ *  Copyright (c) 2020 Philippe Mathieu-Daudé
  *
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
@@ -13,10 +14,12 @@
 #include "tcg/tcg-op.h"
 #include "exec/helper-gen.h"
 #include "translate.h"
-#include "fpu_translate.h"
 #include "fpu_helper.h"
 #include "internal.h"
 
+/* Include the auto-generated decoder.  */
+#include "decode-mod-msa32.c.inc"
+
 #define OPC_MSA (0x1E << 26)
 
 #define MASK_MSA_MINOR(op)  (MASK_OP_MAJOR(op) | (op & 0x3F))
@@ -370,6 +373,16 @@ static bool gen_msa_BxZ_V(DisasContext *ctx, int wt, int 
s16, TCGCond cond)
 return true;
 }
 
+static bool trans_BZ_V(DisasContext *ctx, arg_msa_bz *a)
+{
+return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_EQ);
+}
+
+static bool trans_BNZ_V(DisasContext *ctx, arg_msa_bz *a)
+{
+return gen_msa_BxZ_V(ctx, a->wt, a->s16, TCG_COND_NE);
+}
+
 static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, int s16, bool 
if_not)
 {
 check_msa_access(ctx);
@@ -391,6 +404,16 @@ static bool gen_msa_BxZ(DisasContext *ctx, int df, int wt, 
int s16, bool if_not)
 return true;
 }
 
+static bool trans_BZ_x(DisasContext *ctx, arg_msa_bz *a)
+{
+return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, false);
+}
+
+static bool trans_BNZ_x(DisasContext *ctx, arg_msa_bz *a)
+{
+return gen_msa_BxZ(ctx, a->df, a->wt, a->s16, true);
+}
+
 void gen_msa_branch(DisasContext *ctx, uint32_t op1)
 {
 uint8_t df = (ctx->opcode >> 21) & 0x3;
@@ -2264,3 +2287,15 @@ void gen_msa(DisasContext *ctx)
 break;
 }
 }
+
+static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
+{
+gen_msa(ctx);
+
+return true;
+}
+
+bool decode_ase_msa(DisasContext *ctx, uint32_t insn)
+{
+return decode_msa32(ctx, insn);
+}
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 1e20d426388..f36255f073a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2190,7 +2190,6 @@ static TCGv cpu_lladdr, cpu_llval;
 static TCGv_i32 hflags;
 TCGv_i32 fpu_fcr0, fpu_fcr31;
 TCGv_i64 fpu_f64[32];
-static TCGv_i64 msa_wr_d[64];
 
 #if defined(TARGET_MIPS64)
 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
diff --git a/target/mips/meson.build b/target/mips/meson.build
index 41c3fe7c5bb..5ccc9ddc6b8 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -1,4 +1,9 @@
+gen = [
+  decodetree.process('mod-msa32.decode', extra_args: [ 
'--static-decode=decode_msa32' ]),
+]
+
 mips_ss = ss.source_set()
+mips_ss.add(gen)
 mips_ss.add(files(
   'cpu.c',
   'gdbstub.c',
-- 
2.26.2




[PATCH v2 14/24] target/mips: Move msa_reset() to mod-msa_helper.c

2020-12-15 Thread Philippe Mathieu-Daudé
translate_init.c.inc mostly contains CPU definitions.
msa_reset() doesn't belong here, move it with the MSA
helpers.

One comment style is updated to avoid checkpatch.pl warning.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/internal.h   |  2 ++
 target/mips/cpu.c|  1 +
 target/mips/mod-msa_helper.c | 36 
 target/mips/cpu-defs.c.inc   | 36 
 4 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1ab2454e61d..76269cfc7bb 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -199,6 +199,8 @@ static inline bool 
cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
 
 void mips_tcg_init(void);
 
+void msa_reset(CPUMIPSState *env);
+
 /* cp0_timer.c */
 uint32_t cpu_mips_get_count(CPUMIPSState *env);
 void cpu_mips_store_count(CPUMIPSState *env, uint32_t value);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 77ebd94c655..26e110b687e 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -33,6 +33,7 @@
 #include "hw/qdev-clock.h"
 #include "hw/semihosting/semihost.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "fpu_helper.h"
 
 #if !defined(CONFIG_USER_ONLY)
 
diff --git a/target/mips/mod-msa_helper.c b/target/mips/mod-msa_helper.c
index b89b4c44902..f0d728c03f0 100644
--- a/target/mips/mod-msa_helper.c
+++ b/target/mips/mod-msa_helper.c
@@ -8201,3 +8201,39 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t 
df, uint32_t wd,
 
 msa_move_v(pwd, pwx);
 }
+
+void msa_reset(CPUMIPSState *env)
+{
+if (!ase_msa_available(env)) {
+return;
+}
+
+#ifdef CONFIG_USER_ONLY
+/* MSA access enabled */
+env->CP0_Config5 |= 1 << CP0C5_MSAEn;
+env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR);
+#endif
+
+/*
+ * MSA CSR:
+ * - non-signaling floating point exception mode off (NX bit is 0)
+ * - Cause, Enables, and Flags are all 0
+ * - round to nearest / ties to even (RM bits are 0)
+ */
+env->active_tc.msacsr = 0;
+
+restore_msa_fp_status(env);
+
+/* tininess detected after rounding.*/
+set_float_detect_tininess(float_tininess_after_rounding,
+  &env->active_tc.msa_fp_status);
+
+/* clear float_status exception flags */
+set_float_exception_flags(0, &env->active_tc.msa_fp_status);
+
+/* clear float_status nan mode */
+set_default_nan_mode(0, &env->active_tc.msa_fp_status);
+
+/* set proper signanling bit meaning ("1" means "quiet") */
+set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
+}
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 325b24b8e2c..320ebf29f1f 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -18,8 +18,6 @@
  * License along with this library; if not, see .
  */
 
-#include "fpu_helper.h"
-
 /* CPU / CPU family specific config register values. */
 
 /* Have config1, uncached coherency */
@@ -973,37 +971,3 @@ static void mvp_init(CPUMIPSState *env)
  (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
  (0x1 << CP0MVPC1_PCP1);
 }
-
-static void msa_reset(CPUMIPSState *env)
-{
-if (!ase_msa_available(env)) {
-return;
-}
-
-#ifdef CONFIG_USER_ONLY
-/* MSA access enabled */
-env->CP0_Config5 |= 1 << CP0C5_MSAEn;
-env->CP0_Status |= (1 << CP0St_CU1) | (1 << CP0St_FR);
-#endif
-
-/* MSA CSR:
-   - non-signaling floating point exception mode off (NX bit is 0)
-   - Cause, Enables, and Flags are all 0
-   - round to nearest / ties to even (RM bits are 0) */
-env->active_tc.msacsr = 0;
-
-restore_msa_fp_status(env);
-
-/* tininess detected after rounding.*/
-set_float_detect_tininess(float_tininess_after_rounding,
-  &env->active_tc.msa_fp_status);
-
-/* clear float_status exception flags */
-set_float_exception_flags(0, &env->active_tc.msa_fp_status);
-
-/* clear float_status nan mode */
-set_default_nan_mode(0, &env->active_tc.msa_fp_status);
-
-/* set proper signanling bit meaning ("1" means "quiet") */
-set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
-}
-- 
2.26.2




[PATCH v2 09/24] target/mips: Alias MSA vector registers on FPU scalar registers

2020-12-15 Thread Philippe Mathieu-Daudé
Commits 863f264d10f ("add msa_reset(), global msa register") and
cb269f273fd ("fix multiple TCG registers covering same data")
removed the FPU scalar registers and replaced them by aliases to
the MSA vector registers.

It is not very clear to have FPU registers displayed with MSA
register names, even if MSA ASE is not present.

Instead of aliasing FPU registers to the MSA ones (even when MSA
is absent), we now alias the MSA ones to the FPU ones (only when
MSA is present).

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 02ea184f9a3..9b5b551b616 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -31560,16 +31560,20 @@ void mips_tcg_init(void)
 offsetof(CPUMIPSState,
  active_tc.gpr[i]),
 regnames[i]);
-
 for (i = 0; i < 32; i++) {
 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
-msa_wr_d[i * 2] =
-tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
+
+fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
+}
+/* MSA */
+for (i = 0; i < 32; i++) {
+int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
+
 /*
- * The scalar floating-point unit (FPU) registers are mapped on
- * the MSA vector registers.
+ * The MSA vector registers are mapped on the
+ * scalar floating-point unit (FPU) registers.
  */
-fpu_f64[i] = msa_wr_d[i * 2];
+msa_wr_d[i * 2] = fpu_f64[i];
 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
 msa_wr_d[i * 2 + 1] =
 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
-- 
2.26.2




[PATCH v2 05/24] target/mips: Simplify msa_reset()

2020-12-15 Thread Philippe Mathieu-Daudé
Call msa_reset() unconditionally, but only reset
the MSA registers if MSA is implemented.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu.c  | 5 +
 target/mips/cpu-defs.c.inc | 4 
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 1b4c13bc972..77ebd94c655 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -531,10 +531,7 @@ static void mips_cpu_reset(DeviceState *dev)
 env->hflags |= MIPS_HFLAG_M16;
 }
 
-/* MSA */
-if (ase_msa_available(env)) {
-msa_reset(env);
-}
+msa_reset(env);
 
 compute_hflags(env);
 restore_fp_status(env);
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index a788f5a6b6d..bf12e91f715 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -976,6 +976,10 @@ static void mvp_init(CPUMIPSState *env)
 
 static void msa_reset(CPUMIPSState *env)
 {
+if (!ase_msa_available(env)) {
+return;
+}
+
 #ifdef CONFIG_USER_ONLY
 /* MSA access enabled */
 env->CP0_Config5 |= 1 << CP0C5_MSAEn;
-- 
2.26.2




[PATCH v2 08/24] target/mips: Remove now unused ASE_MSA definition

2020-12-15 Thread Philippe Mathieu-Daudé
We don't use ASE_MSA anymore (replaced by ase_msa_available()
checking MSAP bit from CP0_Config3). Remove it.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/mips-defs.h| 1 -
 target/mips/cpu-defs.c.inc | 8 
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index ed6a7a9e545..805034b8956 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -45,7 +45,6 @@
 #define ASE_MT0x4000ULL
 #define ASE_SMARTMIPS 0x8000ULL
 #define ASE_MICROMIPS 0x0001ULL
-#define ASE_MSA   0x0002ULL
 /*
  *   bits 40-51: vendor-specific base instruction sets
  */
diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index bf12e91f715..325b24b8e2c 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -410,7 +410,7 @@ const mips_def_t mips_defs[] =
 .CP1_fcr31_rw_bitmask = 0xFF83,
 .SEGBITS = 32,
 .PABITS = 40,
-.insn_flags = CPU_MIPS32R5 | ASE_MSA,
+.insn_flags = CPU_MIPS32R5,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
@@ -721,7 +721,7 @@ const mips_def_t mips_defs[] =
 .MSAIR = 0x03 << MSAIR_ProcID,
 .SEGBITS = 48,
 .PABITS = 48,
-.insn_flags = CPU_MIPS64R6 | ASE_MSA,
+.insn_flags = CPU_MIPS64R6,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
@@ -761,7 +761,7 @@ const mips_def_t mips_defs[] =
 .MSAIR = 0x03 << MSAIR_ProcID,
 .SEGBITS = 48,
 .PABITS = 48,
-.insn_flags = CPU_MIPS64R6 | ASE_MSA,
+.insn_flags = CPU_MIPS64R6,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
@@ -887,7 +887,7 @@ const mips_def_t mips_defs[] =
 .CP1_fcr31_rw_bitmask = 0xFF83,
 .SEGBITS = 48,
 .PABITS = 48,
-.insn_flags = CPU_LOONGSON3A | ASE_MSA,
+.insn_flags = CPU_LOONGSON3A,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
-- 
2.26.2




[PATCH v2 16/24] target/mips: Extract MSA helper definitions

2020-12-15 Thread Philippe Mathieu-Daudé
Keep all MSA-related code altogether.

Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20201120210844.2625602-4-f4...@amsat.org>
---
 target/mips/helper.h | 436 +-
 target/mips/mod-msa_helper.h.inc | 443 +++
 2 files changed, 445 insertions(+), 434 deletions(-)
 create mode 100644 target/mips/mod-msa_helper.h.inc

diff --git a/target/mips/helper.h b/target/mips/helper.h
index e97655dc0eb..80eb675fa64 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -781,438 +781,6 @@ DEF_HELPER_FLAGS_3(dmthlip, 0, void, tl, tl, env)
 DEF_HELPER_FLAGS_3(wrdsp, 0, void, tl, tl, env)
 DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env)
 
-/* MIPS SIMD Architecture */
-
-DEF_HELPER_3(msa_nloc_b, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_h, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_w, void, env, i32, i32)
-DEF_HELPER_3(msa_nloc_d, void, env, i32, i32)
-
-DEF_HELPER_3(msa_nlzc_b, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_h, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_w, void, env, i32, i32)
-DEF_HELPER_3(msa_nlzc_d, void, env, i32, i32)
-
-DEF_HELPER_3(msa_pcnt_b, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_h, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_w, void, env, i32, i32)
-DEF_HELPER_3(msa_pcnt_d, void, env, i32, i32)
-
-DEF_HELPER_4(msa_binsl_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsl_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_binsr_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_binsr_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bmnz_v, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bmz_v, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bsel_v, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bclr_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bclr_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bneg_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bneg_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_bset_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_bset_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_add_a_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_add_a_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_a_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_a_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_adds_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_adds_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_addv_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_addv_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_hadd_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_hadd_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_hadd_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ave_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ave_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ave_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_aver_s_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_s_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_aver_u_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_aver_u_d, void, env, i32, i32, i32)
-
-DEF_HELPER_4(msa_ceq_b, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_h, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_w, void, env, i32, i32, i32)
-DEF_HELPER_4(msa_ceq_d,

[PATCH v2 07/24] target/mips: Simplify MSA TCG logic

2020-12-15 Thread Philippe Mathieu-Daudé
Only decode MSA opcodes if MSA is present (implemented).

Now than check_msa_access() will only be called if MSA is
present, the only way to have MIPS_HFLAG_MSA unset is if
MSA is disabled (bit CP0C5_MSAEn cleared, see previous
commit). Therefore we can remove the 'reserved instruction'
exception.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index fc658b3be33..02ea184f9a3 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -28568,13 +28568,8 @@ static inline int check_msa_access(DisasContext *ctx)
 }
 
 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
-if (ctx->insn_flags & ASE_MSA) {
-generate_exception_end(ctx, EXCP_MSADIS);
-return 0;
-} else {
-gen_reserved_instruction(ctx);
-return 0;
-}
+generate_exception_end(ctx, EXCP_MSADIS);
+return 0;
 }
 return 1;
 }
@@ -30418,7 +30413,7 @@ static void gen_msa_vec(CPUMIPSState *env, DisasContext 
*ctx)
 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
 {
 uint32_t opcode = ctx->opcode;
-check_insn(ctx, ASE_MSA);
+
 check_msa_access(ctx);
 
 switch (MASK_MSA_MINOR(opcode)) {
@@ -31048,9 +31043,10 @@ static bool decode_opc_legacy(CPUMIPSState *env, 
DisasContext *ctx)
 case OPC_BNZ_H:
 case OPC_BNZ_W:
 case OPC_BNZ_D:
-check_insn(ctx, ASE_MSA);
-gen_msa_branch(env, ctx, op1);
-break;
+if (ase_msa_available(env)) {
+gen_msa_branch(env, ctx, op1);
+break;
+}
 default:
 MIPS_INVAL("cp1");
 gen_reserved_instruction(ctx);
@@ -31239,7 +31235,9 @@ static bool decode_opc_legacy(CPUMIPSState *env, 
DisasContext *ctx)
 #endif
 } else {
 /* MDMX: Not implemented. */
-gen_msa(env, ctx);
+if (ase_msa_available(env)) {
+gen_msa(env, ctx);
+}
 }
 break;
 case OPC_PCREL:
-- 
2.26.2




[PATCH v2 04/24] target/mips: Introduce ase_msa_available() helper

2020-12-15 Thread Philippe Mathieu-Daudé
Instead of accessing CP0_Config3 directly and checking
the 'MSA Present' bit, introduce an explicit helper,
making the code easier to read.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu.h   |  6 ++
 target/mips/cpu.c   |  2 +-
 target/mips/kvm.c   | 12 ++--
 target/mips/translate.c |  6 ++
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index c6a556efad5..1d72307c547 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1291,6 +1291,12 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t 
isa_mask);
 bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa);
 bool isa_rel6_available(const CPUMIPSState *env);
 
+/* Check presence of MSA implementation */
+static inline bool ase_msa_available(CPUMIPSState *env)
+{
+return env->CP0_Config3 & (1 << CP0C3_MSAP);
+}
+
 /* Check presence of multi-threading ASE implementation */
 static inline bool ase_mt_available(CPUMIPSState *env)
 {
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 9f082518076..1b4c13bc972 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -532,7 +532,7 @@ static void mips_cpu_reset(DeviceState *dev)
 }
 
 /* MSA */
-if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+if (ase_msa_available(env)) {
 msa_reset(env);
 }
 
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index a5b6fe35dbc..84fb10ea35d 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -79,7 +79,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
-if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+if (kvm_mips_msa_cap && ase_msa_available(env)) {
 ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0);
 if (ret < 0) {
 /* mark unsupported so it gets disabled on reset */
@@ -105,7 +105,7 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 warn_report("KVM does not support FPU, disabling");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
-if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+if (!kvm_mips_msa_cap && ase_msa_available(env)) {
 warn_report("KVM does not support MSA, disabling");
 env->CP0_Config3 &= ~(1 << CP0C3_MSAP);
 }
@@ -618,7 +618,7 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int 
level)
  * FPU register state is a subset of MSA vector state, so don't put FPU
  * registers if we're emulating a CPU with MSA.
  */
-if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+if (!ase_msa_available(env)) {
 /* Floating point registers */
 for (i = 0; i < 32; ++i) {
 if (env->CP0_Status & (1 << CP0St_FR)) {
@@ -637,7 +637,7 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int 
level)
 }
 
 /* Only put MSA state if we're emulating a CPU with MSA */
-if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+if (ase_msa_available(env)) {
 /* MSA Control Registers */
 if (level == KVM_PUT_FULL_STATE) {
 err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR,
@@ -698,7 +698,7 @@ static int kvm_mips_get_fpu_registers(CPUState *cs)
  * FPU register state is a subset of MSA vector state, so don't save 
FPU
  * registers if we're emulating a CPU with MSA.
  */
-if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+if (!ase_msa_available(env)) {
 /* Floating point registers */
 for (i = 0; i < 32; ++i) {
 if (env->CP0_Status & (1 << CP0St_FR)) {
@@ -717,7 +717,7 @@ static int kvm_mips_get_fpu_registers(CPUState *cs)
 }
 
 /* Only get MSA state if we're emulating a CPU with MSA */
-if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+if (ase_msa_available(env)) {
 /* MSA Control Registers */
 err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_IR,
&env->msair);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index af543d1f375..fc658b3be33 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -24920,8 +24920,7 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 gen_trap(ctx, op1, rs, rt, -1);
 break;
 case OPC_LSA: /* OPC_PMON */
-if ((ctx->insn_flags & ISA_MIPS32R6) ||
-(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+if ((ctx->insn_flags & ISA_MIPS32R6) || ase_msa_available(env)) {
 decode_opc_special_r6(env, ctx);
 } else {
 /* Pmon entry point, also R4010 selsl */
@@ -25023,8 +25022,7 @@ static void decode_opc_special(CPUMIPSState *env, 
DisasContext *ctx)
 }
 break;
 case OPC_DLSA:
-if ((ctx->insn_flags & ISA_MIPS32R6) ||
-(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+if ((ctx->insn_flags & ISA_MIPS32R6) || ase_msa_available(env)) {
 deco

[PATCH v2 01/24] target/mips/translate: Extract decode_opc_legacy() from decode_opc()

2020-12-15 Thread Philippe Mathieu-Daudé
As we will slowly move to decodetree generated decoders,
extract the legacy decoding from decode_opc(), so new
decoders are added in decode_opc() while old code is
removed from decode_opc_legacy().

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.c | 45 -
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index cc876019bf7..5c62b32c6ae 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -30518,30 +30518,13 @@ static void gen_msa(CPUMIPSState *env, DisasContext 
*ctx)
 
 }
 
-static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
+static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
 {
 int32_t offset;
 int rs, rt, rd, sa;
 uint32_t op, op1;
 int16_t imm;
 
-/* make sure instructions are on a word boundary */
-if (ctx->base.pc_next & 0x3) {
-env->CP0_BadVAddr = ctx->base.pc_next;
-generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
-return;
-}
-
-/* Handle blikely not taken case */
-if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
-TCGLabel *l1 = gen_new_label();
-
-tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
-tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
-gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
-gen_set_label(l1);
-}
-
 op = MASK_OP_MAJOR(ctx->opcode);
 rs = (ctx->opcode >> 21) & 0x1f;
 rt = (ctx->opcode >> 16) & 0x1f;
@@ -31269,8 +31252,32 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 break;
 default:/* Invalid */
 MIPS_INVAL("major opcode");
+return false;
+}
+return true;
+}
+
+static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
+{
+/* make sure instructions are on a word boundary */
+if (ctx->base.pc_next & 0x3) {
+env->CP0_BadVAddr = ctx->base.pc_next;
+generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
+return;
+}
+
+/* Handle blikely not taken case */
+if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
+TCGLabel *l1 = gen_new_label();
+
+tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
+tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
+gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
+gen_set_label(l1);
+}
+
+if (!decode_opc_legacy(env, ctx)) {
 gen_reserved_instruction(ctx);
-break;
 }
 }
 
-- 
2.26.2




[PATCH v2 02/24] target/mips/translate: Expose check_mips_64() to 32-bit mode

2020-12-15 Thread Philippe Mathieu-Daudé
To allow compiling 64-bit specific translation code more
generically (and removing #ifdef'ry), allow compiling
check_mips_64() on 32-bit targets.
If ever called on 32-bit, we obviously emit a reserved
instruction exception.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/translate.h | 2 --
 target/mips/translate.c | 8 +++-
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/target/mips/translate.h b/target/mips/translate.h
index a9eab69249f..942d803476c 100644
--- a/target/mips/translate.h
+++ b/target/mips/translate.h
@@ -127,9 +127,7 @@ void generate_exception_err(DisasContext *ctx, int excp, 
int err);
 void generate_exception_end(DisasContext *ctx, int excp);
 void gen_reserved_instruction(DisasContext *ctx);
 void check_insn(DisasContext *ctx, uint64_t flags);
-#ifdef TARGET_MIPS64
 void check_mips_64(DisasContext *ctx);
-#endif
 void check_cp1_enabled(DisasContext *ctx);
 
 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 5c62b32c6ae..af543d1f375 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2972,18 +2972,16 @@ static inline void check_ps(DisasContext *ctx)
 check_cp1_64bitmode(ctx);
 }
 
-#ifdef TARGET_MIPS64
 /*
- * This code generates a "reserved instruction" exception if 64-bit
- * instructions are not enabled.
+ * This code generates a "reserved instruction" exception if cpu is not
+ * 64-bit or 64-bit instructions are not enabled.
  */
 void check_mips_64(DisasContext *ctx)
 {
-if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
+if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
 gen_reserved_instruction(ctx);
 }
 }
-#endif
 
 #ifndef CONFIG_USER_ONLY
 static inline void check_mvh(DisasContext *ctx)
-- 
2.26.2




[PATCH v2 03/24] target/mips/cpu: Introduce isa_rel6_available() helper

2020-12-15 Thread Philippe Mathieu-Daudé
Introduce the isa_rel6_available() helper to check if the
CPU supports the Release 6 ISA.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu.h | 1 +
 target/mips/cpu.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3ac21d0e9c0..c6a556efad5 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1289,6 +1289,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, 
void *puc);
 bool cpu_type_supports_cps_smp(const char *cpu_type);
 bool cpu_supports_isa(const CPUMIPSState *env, uint64_t isa_mask);
 bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa);
+bool isa_rel6_available(const CPUMIPSState *env);
 
 /* Check presence of multi-threading ASE implementation */
 static inline bool ase_mt_available(CPUMIPSState *env)
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 4191c0741f4..9f082518076 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -789,6 +789,14 @@ bool cpu_supports_isa(const CPUMIPSState *env, uint64_t 
isa_mask)
 return (env->cpu_model->insn_flags & isa_mask) != 0;
 }
 
+bool isa_rel6_available(const CPUMIPSState *env)
+{
+if (TARGET_LONG_BITS == 64) {
+return cpu_supports_isa(env, ISA_MIPS64R6);
+}
+return cpu_supports_isa(env, ISA_MIPS32R6);
+}
+
 bool cpu_type_supports_isa(const char *cpu_type, uint64_t isa)
 {
 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
-- 
2.26.2




[PATCH v2 06/24] target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA

2020-12-15 Thread Philippe Mathieu-Daudé
MSA presence is expressed by the MSAP bit of CP0_Config3.
We don't need to check anything else.

Reviewed-by: Jiaxun Yang 
Reviewed-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index 968a3a8db8f..1ab2454e61d 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -378,7 +378,7 @@ static inline void compute_hflags(CPUMIPSState *env)
 env->hflags |= MIPS_HFLAG_COP1X;
 }
 }
-if (env->insn_flags & ASE_MSA) {
+if (ase_msa_available(env)) {
 if (env->CP0_Config5 & (1 << CP0C5_MSAEn)) {
 env->hflags |= MIPS_HFLAG_MSA;
 }
-- 
2.26.2




[PATCH v2 00/24] target/mips: Convert MSA ASE to decodetree

2020-12-15 Thread Philippe Mathieu-Daudé
Missing review: 1-3 14 17 19-24

Since v1:
- rebased
- addressed Richard review comments
- reworded some commit descriptions
- avoid 64-bit ifdef'ry

Finally, we use decodetree with the MIPS target.

Starting easy with the MSA ASE. 2700+ lines extracted
from helper.h and translate.c, now built as an new
object: mod-msa_translate.o.

Phil.

Available:
  https://gitlab.com/philmd/qemu/-/commits/mips_msa_decodetree_v2

Based-on: <20201214183739.500368-1-f4...@amsat.org>

Philippe Mathieu-Daudé (24):
  target/mips/translate: Extract decode_opc_legacy() from decode_opc()
  target/mips/translate: Expose check_mips_64() to 32-bit mode
  target/mips/cpu: Introduce isa_rel6_available() helper
  target/mips: Introduce ase_msa_available() helper
  target/mips: Simplify msa_reset()
  target/mips: Use CP0_Config3 to set MIPS_HFLAG_MSA
  target/mips: Simplify MSA TCG logic
  target/mips: Remove now unused ASE_MSA definition
  target/mips: Alias MSA vector registers on FPU scalar registers
  target/mips: Extract msa_translate_init() from mips_tcg_init()
  target/mips: Remove CPUMIPSState* argument from gen_msa*() methods
  target/mips: Explode gen_msa_branch() as gen_msa_BxZ_V/BxZ()
  target/mips: Rename msa_helper.c as mod-msa_helper.c
  target/mips: Move msa_reset() to mod-msa_helper.c
  target/mips: Extract MSA helpers from op_helper.c
  target/mips: Extract MSA helper definitions
  target/mips: Declare gen_msa/_branch() in 'translate.h'
  target/mips: Extract MSA translation routines
  target/mips: Introduce decode tree bindings for MSA opcodes
  target/mips: Use decode_ase_msa() generated from decodetree
  target/mips: Extract LSA/DLSA translation generators
  target/mips: Introduce decodetree helpers for MSA LSA/DLSA opcodes
  target/mips: Introduce decodetree helpers for Release6 LSA/DLSA
opcodes
  target/mips/mod-msa: Pass TCGCond argument to gen_check_zero_element()

 target/mips/cpu.h |7 +
 target/mips/helper.h  |  436 +--
 target/mips/internal.h|4 +-
 target/mips/mips-defs.h   |1 -
 target/mips/translate.h   |   25 +-
 target/mips/isa-mips32r6.decode   |   17 +
 target/mips/isa-mips64r6.decode   |   17 +
 target/mips/mod-msa32.decode  |   28 +
 target/mips/mod-msa64.decode  |   17 +
 target/mips/cpu.c |   14 +-
 target/mips/isa-mips_rel6_translate.c |   37 +
 target/mips/kvm.c |   12 +-
 .../mips/{msa_helper.c => mod-msa_helper.c}   |  429 +++
 target/mips/mod-msa_translate.c   | 2286 
 target/mips/op_helper.c   |  394 ---
 target/mips/translate.c   | 2352 +
 target/mips/translate_addr_const.c|   52 +
 target/mips/cpu-defs.c.inc|   40 +-
 target/mips/meson.build   |   14 +-
 target/mips/mod-msa_helper.h.inc  |  443 
 20 files changed, 3437 insertions(+), 3188 deletions(-)
 create mode 100644 target/mips/isa-mips32r6.decode
 create mode 100644 target/mips/isa-mips64r6.decode
 create mode 100644 target/mips/mod-msa32.decode
 create mode 100644 target/mips/mod-msa64.decode
 create mode 100644 target/mips/isa-mips_rel6_translate.c
 rename target/mips/{msa_helper.c => mod-msa_helper.c} (93%)
 create mode 100644 target/mips/mod-msa_translate.c
 create mode 100644 target/mips/translate_addr_const.c
 create mode 100644 target/mips/mod-msa_helper.h.inc

-- 
2.26.2




Re: [RFC PATCH 0/9] Support for Virtio-fs daemon crash reconnection

2020-12-15 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20201215162119.27360-1-zhangjiachen.jay...@bytedance.com/



Hi,

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

Type: series
Message-id: 20201215162119.27360-1-zhangjiachen.jay...@bytedance.com
Subject: [RFC PATCH 0/9] Support for Virtio-fs daemon crash reconnection

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20201215162119.27360-1-zhangjiachen.jay...@bytedance.com -> 
patchew/20201215162119.27360-1-zhangjiachen.jay...@bytedance.com
 * [new tag] 
patchew/20201215174824.76017-1-richard.hender...@linaro.org -> 
patchew/20201215174824.76017-1-richard.hender...@linaro.org
Switched to a new branch 'test'
c6015f6 virtiofsd: (work around) Comment qsort in inflight I/O tracking
a285357 virtiofsd: Ensure crash consistency after reconnection
d5f69c8 virtiofsd: Persist/restore lo_map and opened fds to/from QEMU
4e0a56d virtiofsd: Add two new options for crash reconnection
d4b638e virtiofsd: Convert the struct lo_map array to a more flatten layout
6dadec2 libvhost-user: Add vhost-user message types for sending shared memory 
and file fds
91f265b vhost-user-fs: Support virtiofsd crash reconnection
bb587ea vhost: Add vhost-user message types for sending shared memory and file 
fds
ccb8eca vhost-user-fs: Add support for reconnection of vhost-user-fs backend

=== OUTPUT BEGIN ===
1/9 Checking commit ccb8eca38f55 (vhost-user-fs: Add support for reconnection 
of vhost-user-fs backend)
2/9 Checking commit bb587eaf556e (vhost: Add vhost-user message types for 
sending shared memory and file fds)
3/9 Checking commit 91f265b55b12 (vhost-user-fs: Support virtiofsd crash 
reconnection)
4/9 Checking commit 6dadec226d05 (libvhost-user: Add vhost-user message types 
for sending shared memory and file fds)
5/9 Checking commit d4b638e34242 (virtiofsd: Convert the struct lo_map array to 
a more flatten layout)
ERROR: use qemu_real_host_page_size instead of getpagesize()
#195: FILE: tools/virtiofsd/passthrough_ll.c:383:
+int page_size = getpagesize();

total: 1 errors, 0 warnings, 997 lines checked

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

6/9 Checking commit 4e0a56d0217d (virtiofsd: Add two new options for crash 
reconnection)
7/9 Checking commit d5f69c8465ac (virtiofsd: Persist/restore lo_map and opened 
fds to/from QEMU)
8/9 Checking commit a285357c7bff (virtiofsd: Ensure crash consistency after 
reconnection)
9/9 Checking commit c6015f602fb0 (virtiofsd: (work around) Comment qsort in 
inflight I/O tracking)
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH v4 17/43] tcg: Add --accel tcg,split-wx property

2020-12-15 Thread Richard Henderson
On 12/14/20 8:05 PM, Joelle van Dyne wrote:
> Should qemu-options.hx be updated?

Yep, good catch.


r~



  1   2   3   4   5   >