Re: [PATCH v12 16/16] machine: Make smp_parse return a boolean

2021-10-01 Thread Paolo Bonzini

On 01/10/21 19:15, Daniel P. Berrangé wrote:

On Fri, Oct 01, 2021 at 07:08:51PM +0200, Paolo Bonzini wrote:

On 29/09/21 04:58, Yanan Wang wrote:

@@ -933,8 +935,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
   return;
   }
-smp_parse(ms, config, errp);
-if (*errp) {
+if (!smp_parse(ms, config, errp)) {
   qapi_free_SMPConfiguration(config);
   }
   }



This is actually a leak, so I'm replacing this patch with


This patch isn't adding a leak, as there's no change in
control flow / exit paths.  AFAICT, the leak was introduced
in patch 15 instead, so the code below shoudl be squashed
into that, and this patch left as-is.


Yes, even better make it a separate patch and fix the conflict in patch
15.  But I'm still not sure of the wisdom of this patch.

At this point smp_parse has exactly one caller and it doesn't care about
the return value.  The "return a boolean" rule adds some complexity (and
a possibility for things to be wrong/inconsistent) to the function for
the benefit of the callers.  If there is only one caller, as is the case
here or for virtual functions, the benefit can well be zero (this case)
or negative (virtual functions).

Paolo

 8< 
From e7f944bb94a375e8ee7469ffa535ea6e11ce59e1 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini 
Date: Fri, 1 Oct 2021 19:04:03 +0200
Subject: [PATCH] machine: Use g_autoptr in machine_set_smp

Signed-off-by: Paolo Bonzini 
---
 hw/core/machine.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 54f04a5ac6..d49ebc24e2 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -897,7 +897,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
 {
 MachineClass *mc = MACHINE_GET_CLASS(obj);
 MachineState *ms = MACHINE(obj);
-SMPConfiguration *config;
+g_autoptr(SMPConfiguration) config = NULL;
 ERRP_GUARD();
 
 if (!visit_type_SMPConfiguration(v, name, &config, errp)) {

@@ -920,7 +920,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
 
 smp_parse(ms, config, errp);

 if (*errp) {
-goto out_free;
+return;
 }
 
 /* sanity-check smp_cpus and max_cpus against mc */

@@ -935,9 +935,6 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
ms->smp.max_cpus,
mc->name, mc->max_cpus);
 }
-
-out_free:
-qapi_free_SMPConfiguration(config);
 }
 
 static void machine_class_init(ObjectClass *oc, void *data)

--
2.31.1




Re: [PATCH v2] configure: Loosen GCC requirement from 7.5.0 to 7.4.0

2021-10-01 Thread Paolo Bonzini

On 01/10/21 18:15, Richard Henderson wrote:

On 10/1/21 11:30 AM, nia wrote:

As discussed in issue 614, we're shipping GCC 7.4.0 as the
system compiler in NetBSD 9, the most recent stable branch,
and are still actively interested in QEMU on this platform.

The differences between GCC 7.5.0 and 7.4.0 are trivial.

Signed-off-by: Nia Alarie
---
  configure | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Queued, thanks.

Paolo




Re: [PATCH v4 00/13] qapi: static typing conversion, pt5b

2021-10-01 Thread Markus Armbruster
Markus Armbruster  writes:

> John Snow  writes:
>
>> Hello darkness my old friend; This is part five (b), and focuses on
>> QAPIDoc in parser.py.
>
> Series:
> Reviewed-by: Markus Armbruster 

... and queued.  Thanks!




Re: [PATCH 3/3] dtc: Update to version 1.6.1

2021-10-01 Thread David Gibson
On Fri, Oct 01, 2021 at 01:41:04PM +0200, Thomas Huth wrote:
> On 01/10/2021 11.44, Daniel P. Berrangé wrote:
> > On Fri, Oct 01, 2021 at 10:37:51AM +0100, Peter Maydell wrote:
> > > On Fri, 1 Oct 2021 at 10:10, Daniel P. Berrangé  
> > > wrote:
> > > > 
> > > > On Thu, Sep 30, 2021 at 09:10:12AM +0200, Thomas Huth wrote:
> > > > > On 27/08/2021 14.09, Thomas Huth wrote:
> > > > > > The dtc submodule is currently pointing to non-release commit. It's 
> > > > > > nicer
> > > > > > if submodules point to release versions instead and since dtc 1.6.1 
> > > > > > is
> > > > > > available now, let's update to that version.
> > > 
> > > > Most of our supported platforms don't have version 1.6.1 available.
> > > > 
> > > > As a general goal IMHO we should be seeking to eliminate bundling of
> > > > 3rd party modules that are commonly available in distros. We've
> > > > carried dtc for a hell of a long time, and if we keep updating our
> > > > submodule we'll keep relyin on new features, and never be able to
> > > > drop it because it will always be newer than what's in the distros.
> > > > 
> > > > So personally I think we should never again update dtc and capstone
> > > > modules. If we want to take adbantage of new features, then do that
> > > > through conditional compilation, as we do for any of the other 3rd
> > > > party libraries consumed.
> 
> I basically agree, especially for capstone. But for dtc, that also means
> that we cannot compile certain target boards if its not available ... that's
> somewhat more ugly than if there is just a missing backend feature ... but I
> guess it's still ok. Users could always install a recent libfdt first.
> 
> > > I agree in general, but (per the commit message here) our dtc
> > > submodule is currently pointing at some random not-a-release
> > > commit in upstream dtc. We should at least move forward to
> > > whatever the next released dtc after that is, before we say
> > > "no more dtc updates".
> > 
> > Yep, if we want to fix it onto an official version tag, that's
> > OK, just not jumping right to very latest version.
> 
> That was the intention here. Accidentally, the first release tag after the
> commit that we are currently using, is version 1.6.1, which also happens to
> be the latest version, too.

Note that while I think this is a good idea, there's no real stability
difference between official releases and any random git commit.  I
tend to make releases when somebody complains that there's a new
feature or fix they want that isn't yet in a numbered release.  They
don't get any additional testing beyond the build-in make check which
I also run on every commit.. and which is generally fine, because the
coverage is pretty good (a rather contrained problem space makes that
relatively easy).

-- 
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] monitor: Tidy up find_device_state()

2021-10-01 Thread Markus Armbruster
Ping?

Markus Armbruster  writes:

> Commit 6287d827d4 "monitor: allow device_del to accept QOM paths"
> extended find_device_state() to accept QOM paths in addition to qdev
> IDs.  This added a checked conversion to TYPE_DEVICE at the end, which
> duplicates the check done for the qdev ID case earlier, except it sets
> a *different* error: GenericError "ID is not a hotpluggable device"
> when passed a QOM path, and DeviceNotFound "Device 'ID' not found"
> when passed a qdev ID.  Fortunately, the latter won't happen as long
> as we add only devices to /machine/peripheral/.
>
> Earlier, commit b6cc36abb2 "qdev: device_del: Search for to be
> unplugged device in 'peripheral' container" rewrote the lookup by qdev
> ID to use QOM instead of qdev_find_recursive(), so it can handle
> buss-less devices.  It does so by constructing an absolute QOM path.
> Works, but object_resolve_path_component() is easier.  Switching to it
> also gets rid of the unclean duplication described above.
>
> While there, avoid converting to TYPE_DEVICE twice, first to check
> whether it's possible, and then for real.
>
> Signed-off-by: Markus Armbruster 
> ---
>  softmmu/qdev-monitor.c | 13 +
>  1 file changed, 5 insertions(+), 8 deletions(-)
>
> diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> index a304754ab9..d1ab3c25fb 100644
> --- a/softmmu/qdev-monitor.c
> +++ b/softmmu/qdev-monitor.c
> @@ -831,16 +831,12 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, 
> Error **errp)
>  static DeviceState *find_device_state(const char *id, Error **errp)
>  {
>  Object *obj;
> +DeviceState *dev;
>  
>  if (id[0] == '/') {
>  obj = object_resolve_path(id, NULL);
>  } else {
> -char *root_path = object_get_canonical_path(qdev_get_peripheral());
> -char *path = g_strdup_printf("%s/%s", root_path, id);
> -
> -g_free(root_path);
> -obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
> -g_free(path);
> +obj = object_resolve_path_component(qdev_get_peripheral(), id);
>  }
>  
>  if (!obj) {
> @@ -849,12 +845,13 @@ static DeviceState *find_device_state(const char *id, 
> Error **errp)
>  return NULL;
>  }
>  
> -if (!object_dynamic_cast(obj, TYPE_DEVICE)) {
> +dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
> +if (!dev) {
>  error_setg(errp, "%s is not a hotpluggable device", id);
>  return NULL;
>  }
>  
> -return DEVICE(obj);
> +return dev;
>  }
>  
>  void qdev_unplug(DeviceState *dev, Error **errp)




Re: [PATCH 1/2] hw/arm/virt: Rename default_bus_bypass_iommu

2021-10-01 Thread Markus Armbruster
Markus Armbruster  writes:

> Markus Armbruster  writes:
>
>> Did this series fall through the cracks for 6.1?
>
> Missed 6.1.  What now?

If I understand this correctly, it's a regression in 6.1.  Paolo, please
advise on what should be done.

>> Jean-Philippe Brucker  writes:
>>
>>> Since commit d8fb7d0969d5 ("vl: switch -M parsing to keyval"), machine
>>> parameter definitions cannot use underscores, because keyval_dashify()
>>> transforms them to dashes and the parser doesn't find the parameter.
>>>
>>> This affects option default_bus_bypass_iommu which was introduced in the
>>> same release:
>>>
>>> $ qemu-system-aarch64 -M virt,default_bus_bypass_iommu=on
>>> qemu-system-aarch64: Property 'virt-6.1-machine.default-bus-bypass-iommu' 
>>> not found
>>>
>>> Rename the parameter to "default-bus-bypass-iommu". Passing
>>> "default_bus_bypass_iommu" is still valid since the underscore are
>>> transformed automatically.
>>>
>>> Fixes: 6d7a85483a06 ("hw/arm/virt: Add default_bus_bypass_iommu machine 
>>> option")
>>> Signed-off-by: Jean-Philippe Brucker 
>>> ---
>>>  hw/arm/virt.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>>> index b4598d3fe6..7075cdc15e 100644
>>> --- a/hw/arm/virt.c
>>> +++ b/hw/arm/virt.c
>>> @@ -2671,10 +2671,10 @@ static void virt_machine_class_init(ObjectClass 
>>> *oc, void *data)
>>>"Set the IOMMU type. "
>>>"Valid values are none and 
>>> smmuv3");
>>>  
>>> -object_class_property_add_bool(oc, "default_bus_bypass_iommu",
>>> +object_class_property_add_bool(oc, "default-bus-bypass-iommu",
>>> virt_get_default_bus_bypass_iommu,
>>> virt_set_default_bus_bypass_iommu);
>>> -object_class_property_set_description(oc, "default_bus_bypass_iommu",
>>> +object_class_property_set_description(oc, "default-bus-bypass-iommu",
>>>"Set on/off to enable/disable "
>>>"bypass_iommu for default root 
>>> bus");




Re: [PATCH v12 16/16] machine: Make smp_parse return a boolean

2021-10-01 Thread Markus Armbruster
Daniel P. Berrangé  writes:

> On Fri, Oct 01, 2021 at 07:08:51PM +0200, Paolo Bonzini wrote:
>> On 29/09/21 04:58, Yanan Wang wrote:
>> > @@ -933,8 +935,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
>> > const char *name,
>> >   return;
>> >   }
>> > -smp_parse(ms, config, errp);
>> > -if (*errp) {
>> > +if (!smp_parse(ms, config, errp)) {
>> >   qapi_free_SMPConfiguration(config);
>> >   }
>> >   }
>> > 
>> 
>> This is actually a leak, so I'm replacing this patch with
>
> This patch isn't adding a leak, as there's no change in
> control flow / exit paths.  AFAICT, the leak was introduced
> in patch 15 instead, so the code below shoudl be squashed
> into that, and this patch left as-is.

Concur.




running TCG tests for xtensaeb

2021-10-01 Thread Max Filippov
Hi Alex,

I've tried to use

  make check-tcg CORE=test_kc705_be CROSS_CC_GUEST=xtensa-test_kc705_be-elf-gcc

to run TCG tests for a big-endian xtensa core. I thought the following change
would be sufficient to do it:

---8<---
diff --git a/tests/tcg/xtensa/Makefile.softmmu-target
b/tests/tcg/xtensa/Makefile.softmmu-target
index 9530cac2ad95..6588388967d9 100644
--- a/tests/tcg/xtensa/Makefile.softmmu-target
+++ b/tests/tcg/xtensa/Makefile.softmmu-target
@@ -2,7 +2,7 @@
# Xtensa softmmu tests
#

-ifneq ($(TARGET_WORDS_BIGENDIAN),y)
+ifneq ($(shell $(QEMU) -cpu help | grep -w $(CORE)),)

XTENSA_SRC = $(SRC_PATH)/tests/tcg/xtensa
XTENSA_ALL = $(filter-out $(XTENSA_SRC)/linker.ld.S,$(wildcard
$(XTENSA_SRC)/*.S))
---8<---

but it turns out that tests/tcg/Makefile.target uses the following
code to load target-specific bits:

-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.softmmu-target

and for big-endian xtensa TARGET_NAME is xtensaeb.
However all xtensa tests are under tests/tcg/xtensa, so
Makefile.softmmu-target isn't getting loaded at all.
If I replace '$(TARGET_NAME)' with 'xtensa' in the above
line everything works as expected.

What do you think would be the best way to fix it?

-- 
Thanks.
-- Max



Re: TCG Floating Point Support (Work in Progress)

2021-10-01 Thread Matt
> Not at the moment but it would certainly be a useful addition for the
> unit tests if we could test arbitrary sequences of TCG ops. I'm not sure
> how much test harness would be needed to exercise that though.

On a related note, in addition to testing TCG->Host translation, it
would be nice to also have a way to make sure TCG->TCG optimization
passes are working as expected. Is there existing work in this area?


> We have a number of multiarch tcg tests for fused multiply-add and the
> various fconv operations. There is also quite an exhaustive set of i386
> specific tests (test-i386-fprem) but it doesn't get run by default as
> the "reference" output is too big to include in the tree and has to be
> generated in-situ. You get it by adding SPEED=slow to your make
> invocation. [...]
> You can run tests/fp/fp-bench -t host under translation to exercise that.

Thanks for the info! This will be useful.


> I know the classic Doom and Quake benchmarks showed a performance
> regression when we switched to softfloat:
>
>   https://diasp.eu/posts/ec86de10240e01376f734061862b8e7b

That post was an interesting read, thanks for sharing!


> Out of interest what game code still uses x87? [...]
> however I kinda assumed more modern games would be taking advantaged of
> SSE and later features. There is however some missing gaps in the x86
> emulation that might mean code falls back to the x87. Maybe that would
> be another area to look at.

This project is an emulator of the original Xbox game console, which
is now...twenty years old (time flies). The Xbox CPU (P3) does feature
SSE (not SSE2+), however most of the games I've tested for this
generation still make heavy use of x87.

I have seen at least one game make noticeable use of MMX/SSE features
though, which I also need to look at accelerating. Profiler indicates
they are also very costly. I have seen the TCG vector ops, which are a
very cool addition.

Matt


On Fri, Oct 1, 2021 at 1:24 AM Alex Bennée  wrote:
>
>
> Matt  writes:
>
> > Thank you Alex, for your quick and thoughtful response.
> >
> >> I've not reviewed the code as it is a rather large diff. For your proper
> >> submission could you please ensure that your patch series is broken up
> >> into discreet commits to aid review.
> >
> > Of course.
> >
> >> The phrase "if the user discovers some issues" is a bit of a red flag.
> >> We should always be striving for correct emulation of floating point.
> >
> > I agree. This is an option that I added for use during feature
> > development. Ultimately I would like not to have such an option, and
> > for it to always *just work*.
>
> The closest I can think of is the --accel thread=single|multi option
> which allowed for verifying if an issue was related to MTTCG. However
> the default would always do the right thing.
>
> >
> >> Indeed we have recently got the code base to the point we pass all of
> >> the Berkey softfloat test suite. This can be checked by running:
> >>
> >>   make check-softfloat
> >>
> >> However the test code links directly to the softfloat code so won't work
> >> with direct code execution.
> >
> > I had planned to leverage the existing soft float test suite, and I
> > think this can be done with the right harnessing. It would be nice to
> > have a mechanism to test translation of individual TCG ops, e.g. be
> > able to run translated blocks from test code and evaluate their
> > output. I'm not sure if any such op level testing like that is being
> > done.
>
> Not at the moment but it would certainly be a useful addition for the
> unit tests if we could test arbitrary sequences of TCG ops. I'm not sure
> how much test harness would be needed to exercise that though.
>
> > There are also guest tests in tests/tcg, which could also be
> > expanded to include more FP tests.
>
> We have a number of multiarch tcg tests for fused multiply-add and the
> various fconv operations. There is also quite an exhaustive set of i386
> specific tests (test-i386-fprem) but it doesn't get run by default as
> the "reference" output is too big to include in the tree and has to be
> generated in-situ. You get it by adding SPEED=slow to your make
> invocation.
>
> >> The existing 32/64 bit hardfloat
> >> optimisations work within the helpers. While generating direct code is
> >> appealing to avoid the cost of helper calls it's fairly well cached and
> >> predicted code. Experience with the initial hardfloat code showed the
> >> was still a performance win even with the cost of the helper call.
> >
> > Unfortunately, even with the existing hardfloat support, the overhead
> > of the helper calls is still too costly for my particular application.
>
> Once you start dealing with flag generation you might find that equation
> changes somewhat if you have to mess around with bit masking and checks
> using TCG ops. However providing benchmark results with your patch would
> be required to argue the point. You can run tests/fp/fp-bench -t host
> under translation to e

Re: [PULL v2 00/33] x86 and misc changes for 2021-09-28

2021-10-01 Thread Richard Henderson

On 9/30/21 10:57 AM, Paolo Bonzini wrote:

The following changes since commit ba0fa56bc06e563de68d2a2bf3ddb0cfea1be4f9:

   Merge remote-tracking branch 'remotes/vivier/tags/q800-for-6.2-pull-request' 
into staging (2021-09-29 21:20:49 +0100)

are available in the Git repository at:

   https://gitlab.com/bonzini/qemu.git  tags/for-upstream

for you to fetch changes up to c1de5858bd39b299d3d8baec38b0376bed7f19e8:

   meson_options.txt: Switch the default value for the vnc option to 'auto' 
(2021-09-30 15:30:25 +0200)


Applied, thanks


r~



RE: hexagon container update

2021-10-01 Thread Brian Cain
> -Original Message-
> From: Brian Cain
...
> > -Original Message-
> > From: Richard Henderson 
> ...
> > On 10/1/21 12:59 PM, Brian Cain wrote:
> > > Alex,
> > >
> > > We need to update the docker container used for hexagon for new test
> cases
> > proposed in Taylor's recent patch series under review.  Thankfully,
> CodeLinaro
> > has provided a binary of the hexagon cross toolchain so now I think we can
> > simplify the hexagon docker file to something like the below.  I hope this 
> > also
> > means that we can remove the exceptional handling for the hexagon
> container.
> > >
> > > I can propose a patch but I'm not quite certain how to test it.
> >
> > make docker-image-debian-hexagon-cross NOCACHE=1 V=1
> >
> > and then make check-tcg to use the new image.
> 
> Ok -- so the intent of the NOCACHE is that it will force the use of my newly
> modified Dockerfile and not the one in the qemu container repository?

Ok, I did this.  It succeeded but I don't know how to connect the dots to 
verify that I was indeed using the new container.

Below is an excerpt of what I saw when I did the build of the attached patch.  
And also attached is the subsequent check-tcg (which succeeded).

~~

  wget
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 902 kB of archives.
After this operation, 3335 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian buster/main amd64 wget amd64 1.20.1-1.1 [902 
kB]
Fetched 902 kB in 0s (6882 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package wget.
(Reading database ... 31442 files and directories currently installed.)
Preparing to unpack .../wget_1.20.1-1.1_amd64.deb ...
Unpacking wget (1.20.1-1.1) ...
Setting up wget (1.20.1-1.1) ...
Processing triggers for man-db (2.8.5-2) ...
5f9c7fa86eccc67cd728c0abb7b9594a07d1b1352cef34071fe4e6b64b1490a0
STEP 3: ENV TOOLCHAIN_INSTALL /usr/local
1ab2399cec0fb86c7dc9dc285624fb9ac3ab8c3003771019adeb119340e447fa
STEP 4: ENV ROOTFS /usr/local
43d148dd8c05e2e15cff0a17c2ad4eabd787f8d510a88750068baa300b396d4c
STEP 5: ENV CLANG_URL 
https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/v2021.09.10/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz
509096591e3bac18547a0920e607568b83d451f729e855f23b3a2e99fc7a909f
STEP 6: RUN cd /tmp && wget --quiet ${CLANG_URL} && cd 
${TOOLCHAIN_INSTALL} && tar xf 
/tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz && rm 
/tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz
9dee02ab62a00f1d01dd67d6d2feb79756a2a6d87522939ae65fc78dc2188b41
STEP 7: LABEL 
com.qemu.dockerfile-checksum=c0890fe4ecc53a1d1d03e57bc44db32033c7aa75
a6127bcadaf0a1a50323e091400351046fc86ccf732189df2537ab119abdeec8
STEP 8: LABEL 
com.qemu./home/brian/src/qemu/tests/docker/dockerfiles/debian-hexagon-cross.docker.d/build-toolchain.sh-checksum=a032ac0a66c02f586b1c1d9476c6d4cced9f8d1a
STEP 9: COMMIT qemu/debian-hexagon-cross
2acafd2af1be90a2491fcf6445a64674d1fd7b146c1487d6784942145e7f3d65


$ podman image ls|grep hexagon-cross
localhost/qemu/debian-hexagon-cross  latest 
81492ed2e4c1   4 months ago3.3 GB
registry.gitlab.com/qemu-project/qemu/qemu/debian-hexagon-cross  latest 
81492ed2e4c1   4 months ago3.3 GB
localhost/qemu   
debian-hexagon-cross   779040354471   14 months ago   2.32 GB

$ podman image ls|head
REPOSITORY   TAG
IMAGE ID   CREATED SIZE

ca368e4baacb   About an hour ago   3.3 GB

f67f015ae642   About an hour ago   3.3 GB

823263f1f065   About an hour ago   3.3 GB

2acafd2af1be   About an hour ago   2.56 GB
~

> > > The "--no-check-certificate" argument to wget is very bad but I'm not 
> > > quite
> > certain how to upgrade/change the container's certificate store to accept 
> > the
> > apparently-legit-but-perhaps-newer-than-expected certificate presented by
> > codelinaro.jfrog.io.
> >
> > Hum.  This all suggests that it would be better to update the 
> > build-toolchain
> > script.
> 
> If there's any trust concerns we can verify the download in the dockerfile 
> using
> the hash file for the tarball and/or the gpg signature.

This looks like it's moot, maybe due to some system or proxy 
[mis]configuration.  I moved to another system and didn't encounter the 
certificate issue.




check_tcg.log
Description: check_tcg.log


0001-Hexagon-cross-tools-docker-image-update

Re: [PATCH v3 8/9] Revert "vfio: Avoid disabling and enabling vectors repeatedly in VFIO migration"

2021-10-01 Thread Alex Williamson
On Tue, 21 Sep 2021 07:02:01 +0800
"Longpeng(Mike)"  wrote:

> Commit ecebe53fe993 ("vfio: Avoid disabling and enabling vectors
> repeatedly in VFIO migration") avoid inefficiently disabling and

s/avoid/avoids/

> enabling vectors repeatedly and let the unmasked vectors to be

s/let/lets/  s/to//

> enabled one by one.
> 
> But we want to batch multiple routes and defer the commit, and only
> commit once out side the loop of setting vector notifiers, so we

s/out side/outside/

> cannot to enable the vectors one by one in the loop now.

s/to//

Thanks,
Alex

> 
> Revert that commit and we will take another way in the next patch,
> it can not only avoid disabling/enabling vectors repeatedly, but
> also satisfy our requirement of defer to commit.
> 
> Signed-off-by: Longpeng(Mike) 
> ---
>  hw/vfio/pci.c | 20 +++-
>  1 file changed, 3 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 8fe238b11d..2de1cc5425 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -610,9 +610,6 @@ static __attribute__((unused)) void 
> vfio_commit_kvm_msi_virq(VFIOPCIDevice *vdev
>  
>  static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  {
> -PCIDevice *pdev = &vdev->pdev;
> -unsigned int nr, max_vec = 0;
> -
>  vfio_disable_interrupts(vdev);
>  
>  vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
> @@ -631,22 +628,11 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
>   * triggering to userspace, then immediately release the vector, leaving
>   * the physical device with no vectors enabled, but MSI-X enabled, just
>   * like the guest view.
> - * If there are already unmasked vectors (in migration resume phase and
> - * some guest startups) which will be enabled soon, we can allocate all
> - * of them here to avoid inefficiently disabling and enabling vectors
> - * repeatedly later.
>   */
> -if (!pdev->msix_function_masked) {
> -for (nr = 0; nr < msix_nr_vectors_allocated(pdev); nr++) {
> -if (!msix_is_masked(pdev, nr)) {
> -max_vec = nr;
> -}
> -}
> -}
> -vfio_msix_vector_do_use(pdev, max_vec, NULL, NULL);
> -vfio_msix_vector_release(pdev, max_vec);
> +vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
> +vfio_msix_vector_release(&vdev->pdev, 0);
>  
> -if (msix_set_vector_notifiers(pdev, vfio_msix_vector_use,
> +if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
>vfio_msix_vector_release, NULL)) {
>  error_report("vfio: msix_set_vector_notifiers failed");
>  }




Re: [PATCH v3 7/9] vfio: add infrastructure to commit the deferred kvm routing

2021-10-01 Thread Alex Williamson
On Tue, 21 Sep 2021 07:02:00 +0800
"Longpeng(Mike)"  wrote:

> 'defer_kvm_irq_routing' indicates whether we should defer to commit
> the kvm routing.
> 
> Signed-off-by: Longpeng(Mike) 
> ---
>  hw/vfio/pci.c | 43 ++-
>  hw/vfio/pci.h |  1 +
>  2 files changed, 43 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 8e97ca93cf..8fe238b11d 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -423,12 +423,24 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, 
> VFIOMSIVector *vector,
>  return;
>  }
>  
> -virq = kvm_irqchip_add_msi_route(kvm_state, vector_n, &vdev->pdev);
> +virq = kvm_irqchip_add_deferred_msi_route(kvm_state, vector_n, 
> &vdev->pdev);
>  if (virq < 0) {
>  event_notifier_cleanup(&vector->kvm_interrupt);
>  return;
>  }
>  
> +if (vdev->defer_kvm_irq_routing) {
> +/*
> + * Hold the allocated virq in vector->virq temporarily, will
> + * reset it to -1 when we fail to add the corresponding irqfd
> + * in vfio_commit_kvm_msi_virq().

s/when/if/

> + */
> +vector->virq = virq;

Do we need to make this unique to the deferred case or could we use
vector->virq directly and fill it with -1 on all error paths like we do
on a failure in vfio_commit_kvm_msi_virq()?


> +return;
> +}
> +
> +kvm_irqchip_commit_routes(kvm_state);
> +
>  if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,
> NULL, virq) < 0) {
>  kvm_irqchip_release_virq(kvm_state, virq);
> @@ -567,6 +579,35 @@ static void vfio_msix_vector_release(PCIDevice *pdev, 
> unsigned int nr)
>  }
>  }
>  
> +/* TODO: invoked when enclabe msi/msix vectors */

"enclabe"?  Is this meant to be "enable"?

> +static __attribute__((unused)) void vfio_commit_kvm_msi_virq(VFIOPCIDevice 
> *vdev)

I'd move this function, if not this entire change, to patch 9 rather
than adding these attributes for an unused function.  Thanks,

Alex

> +{
> +int i;
> +VFIOMSIVector *vector;
> +
> +if (!vdev->defer_kvm_irq_routing || !vdev->nr_vectors) {
> +return;
> +}
> +
> +kvm_irqchip_commit_routes(kvm_state);
> +
> +for (i = 0; i < vdev->nr_vectors; i++) {
> +vector = &vdev->msi_vectors[i];
> +
> +if (!vector->use || vector->virq < 0) {
> +continue;
> +}
> +
> +if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state,
> +   &vector->kvm_interrupt,
> +   NULL, vector->virq) < 0) {
> +kvm_irqchip_release_virq(kvm_state, vector->virq);
> +event_notifier_cleanup(&vector->kvm_interrupt);
> +vector->virq = -1;
> +}
> +}
> +}
> +
>  static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  {
>  PCIDevice *pdev = &vdev->pdev;
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index 64777516d1..d3c5177d37 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -171,6 +171,7 @@ struct VFIOPCIDevice {
>  bool no_kvm_ioeventfd;
>  bool no_vfio_ioeventfd;
>  bool enable_ramfb;
> +bool defer_kvm_irq_routing;
>  VFIODisplay *dpy;
>  Notifier irqchip_change_notifier;
>  };




Re: [PATCH v3 9/9] vfio: defer to commit kvm irq routing when enable msi/msix

2021-10-01 Thread Alex Williamson
On Tue, 21 Sep 2021 07:02:02 +0800
"Longpeng(Mike)"  wrote:

> In migration resume phase, all unmasked msix vectors need to be
> setup when load the VF state. However, the setup operation would

s/load/loading/

> take longer if the VM has more VFs and each VF has more unmasked
> vectors.
> 
> The hot spot is kvm_irqchip_commit_routes, it'll scan and update
> all irqfds that already assigned each invocation, so more vectors

s/that/that are/

> means need more time to process them.
> 
> vfio_pci_load_config
>   vfio_msix_enable
> msix_set_vector_notifiers
>   for (vector = 0; vector < dev->msix_entries_nr; vector++) {
> vfio_msix_vector_do_use
>   vfio_add_kvm_msi_virq
> kvm_irqchip_commit_routes <-- expensive
>   }
> 
> We can reduce the cost by only commit once outside the loop. The

s/commit/committing/

> routes is cached in kvm_state, we commit them first and then bind

s/is/are/

> irqfd for each vector.
> 
> The test VM has 128 vcpus and 8 VF (each one has 65 vectors),
> we measure the cost of the vfio_msix_enable for each VF, and
> we can see 90+% costs can be reduce.
> 
> VF  Count of irqfds[*]  OriginalWith this patch
> 
> 1st   658   2
> 2nd   130   15  2
> 3rd   195   22  2
> 4th   260   24  3
> 5th   325   36  2
> 6th   390   44  3
> 7th   455   51  3
> 8th   520   58  4
> Total   258ms   21ms
> 
> [*] Count of irqfds
> How many irqfds that already assigned and need to process in this
> round.
> 
> The optimition can be applied to msi type too.

s/optimition/optimization/

> 
> Signed-off-by: Longpeng(Mike) 
> ---
>  hw/vfio/pci.c | 36 
>  1 file changed, 28 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 2de1cc5425..b26129bddf 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -513,11 +513,13 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, 
> unsigned int nr,
>   * increase them as needed.
>   */
>  if (vdev->nr_vectors < nr + 1) {
> -vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
>  vdev->nr_vectors = nr + 1;
> -ret = vfio_enable_vectors(vdev, true);
> -if (ret) {
> -error_report("vfio: failed to enable vectors, %d", ret);
> +if (!vdev->defer_kvm_irq_routing) {
> +vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
> +ret = vfio_enable_vectors(vdev, true);
> +if (ret) {
> +error_report("vfio: failed to enable vectors, %d", ret);
> +}
>  }
>  } else {
>  Error *err = NULL;
> @@ -579,8 +581,7 @@ static void vfio_msix_vector_release(PCIDevice *pdev, 
> unsigned int nr)
>  }
>  }
>  
> -/* TODO: invoked when enclabe msi/msix vectors */
> -static __attribute__((unused)) void vfio_commit_kvm_msi_virq(VFIOPCIDevice 
> *vdev)
> +static void vfio_commit_kvm_msi_virq(VFIOPCIDevice *vdev)
>  {
>  int i;
>  VFIOMSIVector *vector;
> @@ -610,6 +611,9 @@ static __attribute__((unused)) void 
> vfio_commit_kvm_msi_virq(VFIOPCIDevice *vdev
>  
>  static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  {
> +PCIDevice *pdev = &vdev->pdev;
> +int ret;
> +
>  vfio_disable_interrupts(vdev);
>  
>  vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
> @@ -632,11 +636,22 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
>  vfio_msix_vector_release(&vdev->pdev, 0);
>  
> -if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
> -  vfio_msix_vector_release, NULL)) {

A comment would be useful here, maybe something like:

/*
 * Setting vector notifiers triggers synchronous vector-use
 * callbacks for each active vector.  Deferring to commit the KVM
 * routes once rather than per vector provides a substantial
 * performance improvement.
 */

> +vdev->defer_kvm_irq_routing = true;
> +
> +ret = msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
> +vfio_msix_vector_release, NULL);
> +if (ret < 0) {
>  error_report("vfio: msix_set_vector_notifiers failed");
> +} else if (!pdev->msix_function_masked) {
> +vfio_commit_kvm_msi_virq(vdev);
> +vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);

Couldn't we also optimize the do_use/release on vector 0 above to avoid
this gratuitous disable here?  We only want to make sure MSIX is always
enabled on the device when we exit this function, so maybe that code
becomes an "else" branch below?

> +ret = vfio_enable_vectors(vdev, true);
> +if

Re: [PATCH v3 4/9] msix: simplify the conditional in msix_set/unset_vector_notifiers

2021-10-01 Thread Alex Williamson
On Tue, 21 Sep 2021 07:01:57 +0800
"Longpeng(Mike)"  wrote:

> 'msix_function_masked' is synchronized with the device's config,
> we can use it to replace the complex conditional statementis in
> msix_set/unset_vector_notifiers.
> 
> Signed-off-by: Longpeng(Mike) 
> ---
>  hw/pci/msix.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/pci/msix.c b/hw/pci/msix.c
> index ae9331cd0b..67682289af 100644
> --- a/hw/pci/msix.c
> +++ b/hw/pci/msix.c
> @@ -592,8 +592,7 @@ int msix_set_vector_notifiers(PCIDevice *dev,
>  dev->msix_vector_release_notifier = release_notifier;
>  dev->msix_vector_poll_notifier = poll_notifier;
>  
> -if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
> -(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
> +if (!dev->msix_function_masked) {
>  for (vector = 0; vector < dev->msix_entries_nr; vector++) {
>  ret = msix_set_notifier_for_vector(dev, vector);
>  if (ret < 0) {
> @@ -622,8 +621,7 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
>  assert(dev->msix_vector_use_notifier &&
> dev->msix_vector_release_notifier);
>  
> -if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
> -(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
> +if (!dev->msix_function_masked) {
>  for (vector = 0; vector < dev->msix_entries_nr; vector++) {
>  msix_unset_notifier_for_vector(dev, vector);
>  }

This appears to be a cleanup that's not required for the functionality
of this series.  I'd suggest proposing it separately.  Same for the
patch 5/9 in this series.  If it makes a functional difference it
should be described in the commit log.  Thanks,

Alex




RE: [PATCH v3 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill

2021-10-01 Thread Taylor Simpson
> -Original Message-
> From: Richard Henderson 
> Sent: Friday, October 1, 2021 12:12 PM
> To: qemu-devel@nongnu.org
> Cc: laur...@vivier.eu; alex.ben...@linaro.org; Taylor Simpson
> 
> Subject: [PATCH v3 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill
> 
> The fallback code in raise_sigsegv is sufficient for hexagon.
> Remove the code from cpu_loop that raises SIGSEGV.
> 
> Cc: Taylor Simpson 
> Signed-off-by: Richard Henderson 
> ---
>  linux-user/hexagon/cpu_loop.c | 24 +---
>  target/hexagon/cpu.c  | 23 ---
>  2 files changed, 1 insertion(+), 46 deletions(-)

You should update the commit comment because raise_sigsegv was changed to 
cpu_loop_exit_segv in v3 of the patch series.

Otherwise,
Reviewed-by: Taylor Simpson 



Re: hexagon container update

2021-10-01 Thread Alex Bennée
On Fri, 1 Oct 2021, 18:59 Brian Cain,  wrote:

> > -Original Message-
> > From: Richard Henderson 
> ...
> > On 10/1/21 12:59 PM, Brian Cain wrote:
> > > Alex,
> > >
> > > We need to update the docker container used for hexagon for new test
> cases
> > proposed in Taylor's recent patch series under review.  Thankfully,
> CodeLinaro
> > has provided a binary of the hexagon cross toolchain so now I think we
> can
> > simplify the hexagon docker file to something like the below.  I hope
> this also
> > means that we can remove the exceptional handling for the hexagon
> container.
> > >
> > > I can propose a patch but I'm not quite certain how to test it.
> >
> > make docker-image-debian-hexagon-cross NOCACHE=1 V=1
> >
> > and then make check-tcg to use the new image.
>
> Ok -- so the intent of the NOCACHE is that it will force the use of my
> newly modified Dockerfile and not the one in the qemu container repository?
>
> > > The "--no-check-certificate" argument to wget is very bad but I'm not
> quite
> > certain how to upgrade/change the container's certificate store to
> accept the
> > apparently-legit-but-perhaps-newer-than-expected certificate presented by
> > codelinaro.jfrog.io.
> >
> > Hum.  This all suggests that it would be better to update the
> build-toolchain
> > script.
>
> If there's any trust concerns we can verify the download in the dockerfile
> using the hash file for the tarball and/or the gpg signature.
>
> The build-toolchain is a bit of a hassle given the processing time, it'd
> be great to avoid it.  If the hash or signature check doesn't suffice I
> will investigate how to update debian10's signatures.  Are we bound to
> debian10 for all the containers?  If using a different basis was effective
> at resolving this issue, could I select a different one?
>

Sure, debian11 is now stable. We try and avoid rolling releases as a base
but the latest debian should be fine.


> > > RUN cd /tmp && \
> > >  wget --quiet --no-check-certificate ${CLANG_URL}
> > > RUN cd /opt && \
> > >  tar xf /tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-
> > musl.tar.xz
> >
> > You'd want to remove the tarball as well.
>
> Yes, good point.
>


[RFC PATCH 0/4] Misc OHCI patches

2021-10-01 Thread BALATON Zoltan
Hello,

This is a first attempt to make some progress with the problems found
with OHCI especially when trying to pass through a usb sound card on
mac99. This does not go all the way to allow multiple async packets on
different endpoints yet but as a first step just try to fix the
interaction and potential breakage of pending async packet by
isochronous transfers. Plus some small clean ups I've found while
trying to make sense of this device model.

Posted as RFC because it's unfinfished and untested as there seems to
be some regression with mac99 so it does not boot for me for some
reason I haven't debugged yet. Hope Howard can test it and see if it
changes any of the traces seen before.

BALATON Zoltan (4):
  usb/ohci: Move cancelling async packet to ohci_stop_endpoints()
  usb/ohci: Move USBPortOps related functions together
  usb/ohci: Merge ohci_async_cancel_device() into ohci_child_detach()
  usb/ohci: Don't use packet from OHCIState for isochronous transfers

 hw/usb/hcd-ohci.c | 281 ++
 1 file changed, 136 insertions(+), 145 deletions(-)

-- 
2.21.4




[RFC PATCH 4/4] usb/ohci: Don't use packet from OHCIState for isochronous transfers

2021-10-01 Thread BALATON Zoltan
Since isochronous transfers cannot be handled async (the function
returns error in that case) we don't need to remember the packet.
Avoid using the usb_pkt in OHCIState (as that can be a waiting async
packet on another endpoint) and allocate and use a local USBPacket for
the iso transfer instead. After this we don't have to care if we're
called from a completion callback or not so we can drop that parameter
as well.

Signed-off-by: BALATON Zoltan 
---
 hw/usb/hcd-ohci.c | 70 +--
 1 file changed, 37 insertions(+), 33 deletions(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 212d0aabbe..18170e7256 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -542,8 +542,7 @@ static int ohci_copy_iso_td(OHCIState *ohci,
 
 #define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
 
-static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
-   int completion)
+static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
 {
 int dir;
 size_t len = 0;
@@ -553,6 +552,9 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 int i;
 USBDevice *dev;
 USBEndpoint *ep;
+USBPacket *pkt;
+uint8_t buf[8192];
+bool int_req;
 struct ohci_iso_td iso_td;
 uint32_t addr;
 uint16_t starting_frame;
@@ -687,40 +689,42 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 } else {
 len = end_addr - start_addr + 1;
 }
-if (len > sizeof(ohci->usb_buf)) {
-len = sizeof(ohci->usb_buf);
+if (len > sizeof(buf)) {
+len = sizeof(buf);
 }
 
 if (len && dir != OHCI_TD_DIR_IN) {
-if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len,
+if (ohci_copy_iso_td(ohci, start_addr, end_addr, buf, len,
  DMA_DIRECTION_TO_DEVICE)) {
 ohci_die(ohci);
 return 1;
 }
 }
 
-if (!completion) {
-bool int_req = relative_frame_number == frame_count &&
-   OHCI_BM(iso_td.flags, TD_DI) == 0;
-dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
-if (dev == NULL) {
-trace_usb_ohci_td_dev_error();
-return 1;
-}
-ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
-usb_packet_setup(&ohci->usb_packet, pid, ep, 0, addr, false, int_req);
-usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
-usb_handle_packet(dev, &ohci->usb_packet);
-if (ohci->usb_packet.status == USB_RET_ASYNC) {
-usb_device_flush_ep_queue(dev, ep);
-return 1;
-}
+dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
+if (dev == NULL) {
+trace_usb_ohci_td_dev_error();
+return 1;
 }
-if (ohci->usb_packet.status == USB_RET_SUCCESS) {
-ret = ohci->usb_packet.actual_length;
+ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
+pkt = g_new0(USBPacket, 1);
+usb_packet_init(pkt);
+int_req = relative_frame_number == frame_count &&
+  OHCI_BM(iso_td.flags, TD_DI) == 0;
+usb_packet_setup(pkt, pid, ep, 0, addr, false, int_req);
+usb_packet_addbuf(pkt, buf, len);
+usb_handle_packet(dev, pkt);
+if (pkt->status == USB_RET_ASYNC) {
+usb_device_flush_ep_queue(dev, ep);
+g_free(pkt);
+return 1;
+}
+if (pkt->status == USB_RET_SUCCESS) {
+ret = pkt->actual_length;
 } else {
-ret = ohci->usb_packet.status;
+ret = pkt->status;
 }
+g_free(pkt);
 
 trace_usb_ohci_iso_td_so(start_offset, end_offset, start_addr, end_addr,
  str, len, ret);
@@ -728,7 +732,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 /* Writeback */
 if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
 /* IN transfer succeeded */
-if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret,
+if (ohci_copy_iso_td(ohci, start_addr, end_addr, buf, ret,
  DMA_DIRECTION_FROM_DEVICE)) {
 ohci_die(ohci);
 return 1;
@@ -1051,7 +1055,7 @@ exit_no_retire:
 }
 
 /* Service an endpoint list.  Returns nonzero if active TD were found.  */
-static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
+static int ohci_service_ed_list(OHCIState *ohci, uint32_t head)
 {
 struct ohci_ed ed;
 uint32_t next_ed;
@@ -1102,7 +1106,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t 
head, int completion)
 break;
 } else {
 /* Handle isochronous endpoints */
-if (ohci_service_iso_td(ohci, &ed, completion))
+if (ohci_service_iso_td(ohci, &ed))
 break;
 }
 }
@@ -1130,20 +1134,20 @@ static void ohci_sof(OHCIState *ohci)
 }
 
 /* Process Control

[RFC PATCH 3/4] usb/ohci: Merge ohci_async_cancel_device() into ohci_child_detach()

2021-10-01 Thread BALATON Zoltan
These two do the same and only used once so no need to have two
functions, simplify by merging them.

Signed-off-by: BALATON Zoltan 
---
 hw/usb/hcd-ohci.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index f8761370e3..212d0aabbe 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1719,8 +1719,10 @@ static void ohci_attach(USBPort *port1)
 }
 }
 
-static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
+static void ohci_child_detach(USBPort *port1, USBDevice *dev)
 {
+OHCIState *ohci = port1->opaque;
+
 if (ohci->async_td &&
 usb_packet_is_inflight(&ohci->usb_packet) &&
 ohci->usb_packet.ep->dev == dev) {
@@ -1729,20 +1731,13 @@ static void ohci_async_cancel_device(OHCIState *ohci, 
USBDevice *dev)
 }
 }
 
-static void ohci_child_detach(USBPort *port1, USBDevice *child)
-{
-OHCIState *s = port1->opaque;
-
-ohci_async_cancel_device(s, child);
-}
-
 static void ohci_detach(USBPort *port1)
 {
 OHCIState *s = port1->opaque;
 OHCIPort *port = &s->rhport[port1->index];
 uint32_t old_state = port->ctrl;
 
-ohci_async_cancel_device(s, port1->dev);
+ohci_child_detach(port1, port1->dev);
 
 /* set connect status */
 if (port->ctrl & OHCI_PORT_CCS) {
-- 
2.21.4




[RFC PATCH 1/4] usb/ohci: Move cancelling async packet to ohci_stop_endpoints()

2021-10-01 Thread BALATON Zoltan
This is always done before calling this function so remove duplicated
code and do it within the function at one place.

Signed-off-by: BALATON Zoltan 
---
 hw/usb/hcd-ohci.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 1cf2816772..405abbb62d 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -369,6 +369,10 @@ void ohci_stop_endpoints(OHCIState *ohci)
 USBDevice *dev;
 int i, j;
 
+if (ohci->async_td) {
+usb_cancel_packet(&ohci->usb_packet);
+ohci->async_td = 0;
+}
 for (i = 0; i < ohci->num_ports; i++) {
 dev = ohci->rhport[i].port.dev;
 if (dev && dev->attached) {
@@ -398,10 +402,6 @@ static void ohci_roothub_reset(OHCIState *ohci)
 usb_port_reset(&port->port);
 }
 }
-if (ohci->async_td) {
-usb_cancel_packet(&ohci->usb_packet);
-ohci->async_td = 0;
-}
 ohci_stop_endpoints(ohci);
 }
 
@@ -1271,10 +1271,6 @@ static void ohci_frame_boundary(void *opaque)
 
 /* Cancel all pending packets if either of the lists has been disabled.  */
 if (ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
-if (ohci->async_td) {
-usb_cancel_packet(&ohci->usb_packet);
-ohci->async_td = 0;
-}
 ohci_stop_endpoints(ohci);
 }
 ohci->old_ctl = ohci->ctl;
-- 
2.21.4




[RFC PATCH 2/4] usb/ohci: Move USBPortOps related functions together

2021-10-01 Thread BALATON Zoltan
This also allows removing two forward declarations

Signed-off-by: BALATON Zoltan 
---
 hw/usb/hcd-ohci.c | 204 +++---
 1 file changed, 100 insertions(+), 104 deletions(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 405abbb62d..f8761370e3 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -58,8 +58,6 @@ struct ohci_hcca {
 #define ED_WBACK_OFFSET offsetof(struct ohci_ed, head)
 #define ED_WBACK_SIZE   4
 
-static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
-
 /* Bitfields for the first word of an Endpoint Desciptor.  */
 #define OHCI_ED_FA_SHIFT  0
 #define OHCI_ED_FA_MASK   (0x7frhport[port1->index];
-uint32_t old_state = port->ctrl;
-
-/* set connect status */
-port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
-
-/* update speed */
-if (port->port.dev->speed == USB_SPEED_LOW) {
-port->ctrl |= OHCI_PORT_LSDA;
-} else {
-port->ctrl &= ~OHCI_PORT_LSDA;
-}
-
-/* notify of remote-wakeup */
-if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
-ohci_set_interrupt(s, OHCI_INTR_RD);
-}
-
-trace_usb_ohci_port_attach(port1->index);
-
-if (old_state != port->ctrl) {
-ohci_set_interrupt(s, OHCI_INTR_RHSC);
-}
-}
-
-static void ohci_detach(USBPort *port1)
-{
-OHCIState *s = port1->opaque;
-OHCIPort *port = &s->rhport[port1->index];
-uint32_t old_state = port->ctrl;
-
-ohci_async_cancel_device(s, port1->dev);
-
-/* set connect status */
-if (port->ctrl & OHCI_PORT_CCS) {
-port->ctrl &= ~OHCI_PORT_CCS;
-port->ctrl |= OHCI_PORT_CSC;
-}
-/* disable port */
-if (port->ctrl & OHCI_PORT_PES) {
-port->ctrl &= ~OHCI_PORT_PES;
-port->ctrl |= OHCI_PORT_PESC;
-}
-trace_usb_ohci_port_detach(port1->index);
-
-if (old_state != port->ctrl) {
-ohci_set_interrupt(s, OHCI_INTR_RHSC);
-}
-}
-
-static void ohci_wakeup(USBPort *port1)
-{
-OHCIState *s = port1->opaque;
-OHCIPort *port = &s->rhport[port1->index];
-uint32_t intr = 0;
-if (port->ctrl & OHCI_PORT_PSS) {
-trace_usb_ohci_port_wakeup(port1->index);
-port->ctrl |= OHCI_PORT_PSSC;
-port->ctrl &= ~OHCI_PORT_PSS;
-intr = OHCI_INTR_RHSC;
-}
-/* Note that the controller can be suspended even if this port is not */
-if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
-trace_usb_ohci_remote_wakeup(s->name);
-/* This is the one state transition the controller can do by itself */
-s->ctl &= ~OHCI_CTL_HCFS;
-s->ctl |= OHCI_USB_RESUME;
-/* In suspend mode only ResumeDetected is possible, not RHSC:
- * see the OHCI spec 5.1.2.3.
- */
-intr = OHCI_INTR_RD;
-}
-ohci_set_interrupt(s, intr);
-}
-
-static void ohci_child_detach(USBPort *port1, USBDevice *child)
-{
-OHCIState *s = port1->opaque;
-
-ohci_async_cancel_device(s, child);
-}
-
 static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr)
 {
 USBDevice *dev;
@@ -628,17 +540,6 @@ static int ohci_copy_iso_td(OHCIState *ohci,
 return 0;
 }
 
-static void ohci_process_lists(OHCIState *ohci, int completion);
-
-static void ohci_async_complete_packet(USBPort *port, USBPacket *packet)
-{
-OHCIState *ohci = container_of(packet, OHCIState, usb_packet);
-
-trace_usb_ohci_async_complete();
-ohci->async_complete = true;
-ohci_process_lists(ohci, 1);
-}
-
 #define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b)))
 
 static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
@@ -1783,6 +1684,41 @@ static void ohci_mem_write(void *opaque,
 }
 }
 
+static const MemoryRegionOps ohci_mem_ops = {
+.read = ohci_mem_read,
+.write = ohci_mem_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+/* USBPortOps */
+static void ohci_attach(USBPort *port1)
+{
+OHCIState *s = port1->opaque;
+OHCIPort *port = &s->rhport[port1->index];
+uint32_t old_state = port->ctrl;
+
+/* set connect status */
+port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
+
+/* update speed */
+if (port->port.dev->speed == USB_SPEED_LOW) {
+port->ctrl |= OHCI_PORT_LSDA;
+} else {
+port->ctrl &= ~OHCI_PORT_LSDA;
+}
+
+/* notify of remote-wakeup */
+if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
+ohci_set_interrupt(s, OHCI_INTR_RD);
+}
+
+trace_usb_ohci_port_attach(port1->index);
+
+if (old_state != port->ctrl) {
+ohci_set_interrupt(s, OHCI_INTR_RHSC);
+}
+}
+
 static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
 {
 if (ohci->async_td &&
@@ -1793,11 +1729,71 @@ static void ohci_async_cancel_device(OHCIState *ohci, 
USBDevice *dev)
 }
 }
 
-static const MemoryRegionOps ohci_mem_ops = {
-.read = ohci_mem_read,
-.write = ohci_mem_write,
-.endianness = DEVICE_LITTLE_ENDIAN,
-};
+static void ohci_chi

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

2021-10-01 Thread Raphael Norwitz
On Thu, Sep 30, 2021 at 10:48:09AM +0100, Stefan Hajnoczi wrote:
> On Thu, Sep 30, 2021 at 05:29:06AM +, Raphael Norwitz wrote:
> > On Tue, Sep 28, 2021 at 10:55:00AM +0200, Stefan Hajnoczi wrote:
> > > On Mon, Sep 27, 2021 at 05:17:01PM +, Raphael Norwitz wrote:
> > > > In the vhost-user-blk-test, as of now there is nothing stoping
> > > > vhost-user-blk in QEMU writing to the socket right after forking off the
> > > > storage daemon before it has a chance to come up properly, leaving the
> > > > test hanging forever. This intermittently hanging test has caused QEMU
> > > > automation failures reported multiple times on the mailing list [1].
> > > > 
> > > > This change makes the storage-daemon notify the vhost-user-blk-test
> > > > that it is fully initialized and ready to handle client connections by
> > > > creating a pidfile on initialiation. This ensures that the 
> > > > storage-daemon
> > > > backend won't miss vhost-user messages and thereby resolves the hang.
> > > > 
> > > > [1] 
> > > > https://lore.kernel.org/qemu-devel/CAFEAcA8kYpz9LiPNxnWJAPSjc=nv532bedyfynabemeohqb...@mail.gmail.com/
> > > 
> > 
> > Hey Stefan,
> > 
> > > Hi Raphael,
> > > I would like to understand the issue that is being worked around in the
> > > patch.
> > > 
> > > QEMU should be okay with listen fd passing. The qemu-storage-daemon
> > > documentation even contains example code for this
> > > (docs/tools/qemu-storage-daemon.rst) and that may need to be updated if
> > > listen fd passing is fundamentally broken.
> > > 
> > 
> > The issue is that the "client" (in this case vhost-user-blk in QEMU) can
> > proceed to use the socket before the storage-daemon has a chance to
> > properly start up and monitor it. This is nothing unique to the
> > storage-daemon - I've seen races like this happen happend with different
> > vhost-user backends before.
> > 
> > Yes - I do think the docs can be improved to explicitly state that the
> > storage-daemon must be allowed to properly initialize before any data is
> > sent over the socket. Maybe we should even perscribe the use of the pidfile
> > option?
> > 
> > > Can you share more details about the problem?
> > > 
> > 
> > Did you see my analysis [1]?
> > 
> > [1] 
> > https://lore.kernel.org/qemu-devel/20210827165253.GA14291@raphael-debian-dev/
> > 
> > Basically QEMU sends VHOST_USER_GET_PROTOCOL_FEATURES across the vhost
> > socket and the storage daemon never receives it. Looking at the
> > QEMU state we see it is stuck waiting for a vhost-user response. Meanwhile
> > the storage-daemon never receives any message to begin with. AFAICT
> > there is nothing stopping QEMU from running first and sending a message
> > before vhost-user-blk comes up, and from testing we can see that waiting
> > for the storage-daemon to come up resolves the problem completely.
> 
> The root cause has not been determined yet. QEMU should accept the
> incoming connection and then read the previously-sent
> VHOST_USER_GET_PROTOCOL_FEATURES message. There is no reason at the
> Sockets API level why the message should get lost, so there is probably
> a QEMU bug here.
> 
> > > Does "writing to the socket" mean writing vhost-user protocol messages
> > > or does it mean connect(2)?
> > > 
> > 
> > Yes - it means writing vhost-user messages. We see a message sent from
> > QEMU to the backend.
> > 
> > Note that in qtest_socket_server() (called from create_listen_socket())
> > we have already called listen() on the socket, so I would expect QEMU
> > calling connect(2) to succeed and proceed to successfully send messages
> > whether or not there is another listener. I even tried commenting out the
> > execlp for the storage-daemon and I saw the same behavior from QEMU - it
> > sends the message and hangs indefinitely.
> 
> QEMU is correct in waiting for a vhost-user reply. The question is why
> qemu-storage-daemon's vhost-user-block export isn't processing the
> request and replying to it?
> 
> > > Could the problem be that vhost-user-blk-test.c creates the listen fds
> > > and does not close them? This means the host network stack doesn't
> > > consider the socket closed after QEMU terminates and therefore the test
> > > process hangs after QEMU is gone? In that case vhost-user-blk-test needs
> > > to close the fds after spawning qemu-storage-daemon.
> > > 
> > 
> > When the test hangs both QEMU and storage-daemon are still up and
> > connected to the socket and waiting for messages from each other. I don't
> > see how we would close the FD in this state or how it would help.
> 
> Yes, I see. In that case the theory about fds doesn't apply.
> 
> > We may want to think about implementing some kind of timeoout for initial
> > vhost-user messages so that we fail instead of hang in cases like these,
> > as I proposed in [1]. What do you think?
> 
> Let's hold off on workarounds until the root cause has been found.
> 
> Do you have time to debug why vu_accept() and vu_message_read() don't
> see the pending VHO

Re: [PATCH v3 40/41] target/xtensa: Make xtensa_cpu_tlb_fill sysemu only

2021-10-01 Thread Max Filippov
On Fri, Oct 1, 2021 at 10:15 AM Richard Henderson
 wrote:
>
> The fallback code in raise_sigsegv is sufficient for xtensa.
> Remove the code from cpu_loop that raised SIGSEGV.
>
> Cc: Max Filippov 
> Signed-off-by: Richard Henderson 
> ---
>  target/xtensa/cpu.h  |  2 +-
>  linux-user/xtensa/cpu_loop.c |  9 -
>  target/xtensa/cpu.c  |  2 +-
>  target/xtensa/helper.c   | 22 +-
>  4 files changed, 3 insertions(+), 32 deletions(-)

Acked-by: Max Filippov 

-- 
Thanks.
-- Max



Re: Running 297 from GitLab CI

2021-10-01 Thread Eric Blake
On Fri, Oct 01, 2021 at 10:21:36AM +0200, Kevin Wolf wrote:
> Am 30.09.2021 um 23:28 hat John Snow geschrieben:
> > Hiya, I was talking this over with Hanna in review to '[PATCH v3 00/16]
> > python/iotests: Run iotest linters during Python CI' [1] and I have some
> > doubt about what you'd personally like to see happen, here.
> > 
> > In a nutshell, I split out 'linters.py' from 297 and keep all of the
> > iotest-bits in 297 and all of the generic "run the linters" bits in
> > linters.py, then I run linters.py from the GitLab python CI jobs.
> > 
> > I did this so that iotest #297 would continue to work exactly as it had,
> > but trying to serve "two masters" in the form of two test suites means some
> > non-beautiful design decisions. Hanna suggested we just outright drop test
> > 297 to possibly improve the factoring of the tests.
> > 
> > I don't want to do that unless you give it the go-ahead, though. I wanted
> > to hear your feelings on if we still want to keep 297 around or not.
> 
> My basic requirement is that the checks are run somewhere in my local
> testing before I prepare a pull request. This means it could be done by
> iotests in any test that runs for -raw or -qcow2, or in 'make check'.
> 
> So if you have a replacement somewhere in 'make check', dropping 297 is
> fine with me. If I have to run something entirely different, you may
> need to invest a bit more effort to convince me. ;-)

I'll echo that sentiment - if it's easy to automate, we can run it
under 'make check', and then we don't need the duplication of also
running it under iotests (especially since it isn't "really" an
iotest, so much as a test that makes the rest of the iotests more
consistent).  If it's harder to automate, or requires me to run one
more thing, then keeping it in iotests for the short term is not too
drastic of a request, so that I don't accidentally skip it.

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




Re: Running 297 from GitLab CI

2021-10-01 Thread John Snow
On Fri, Oct 1, 2021 at 4:21 AM Kevin Wolf  wrote:

> Am 30.09.2021 um 23:28 hat John Snow geschrieben:
> > Hiya, I was talking this over with Hanna in review to '[PATCH v3 00/16]
> > python/iotests: Run iotest linters during Python CI' [1] and I have some
> > doubt about what you'd personally like to see happen, here.
> >
> > In a nutshell, I split out 'linters.py' from 297 and keep all of the
> > iotest-bits in 297 and all of the generic "run the linters" bits in
> > linters.py, then I run linters.py from the GitLab python CI jobs.
> >
> > I did this so that iotest #297 would continue to work exactly as it had,
> > but trying to serve "two masters" in the form of two test suites means
> some
> > non-beautiful design decisions. Hanna suggested we just outright drop
> test
> > 297 to possibly improve the factoring of the tests.
> >
> > I don't want to do that unless you give it the go-ahead, though. I wanted
> > to hear your feelings on if we still want to keep 297 around or not.
>
> My basic requirement is that the checks are run somewhere in my local
> testing before I prepare a pull request. This means it could be done by
> iotests in any test that runs for -raw or -qcow2, or in 'make check'.
>
> So if you have a replacement somewhere in 'make check', dropping 297 is
> fine with me. If I have to run something entirely different, you may
> need to invest a bit more effort to convince me. ;-)
>
>
I love a good set of solid criteria ;-)

Understood! At the moment it *would* require a separate invocation. The
Python tests that run under CI generally set up their own environments to
ensure they'll run with minimum fuss or intervention from humans, though
there is an invocation in that Makefile that performs no environment setup
whatsoever -- but since no automated test uses it, it's not really a big
problem if your environment is "wrong" for that one. (But that also makes
it useless for make check!) It's similar to how iotest 297 does not really
check to see what version of pylint or mypy you might have, so sometimes
that test fails if your environment isn't suitable. But that one isn't part
of 'make check' either, so this feels like a bridge we've never crossed
anywhere in the whole source tree.

I have so far abstained from introducing such a step into 'make check'
because it might require some additional engineering to ensure that I get
the temporary directories all correct, tolerate the different types of
builds we do, uses the correct Python interpreter for all steps, etc.

So for now I'll propose leaving 297 as-is for convenience, but I will start
working towards finding the right way to include those tests from 'make
check'. I think there's no barrier (other than subjectively, beauty) to
leaving both avenues in for running the test for the time being. Maybe I
will find a way to convince Hanna to accept the interim solution as "well,
not THAT ugly."

Thanks for your input!

--js


Re: [PATCH v4 03/13] qapi/parser: fix unused check_args_section arguments

2021-10-01 Thread John Snow
On Fri, Oct 1, 2021 at 10:11 AM Markus Armbruster  wrote:

> John Snow  writes:
>
> > Pylint informs us we're not using these arguments. Oops, it's
> > right. Correct the error message and remove the remaining unused
> > parameter.
> >
> > Fix test output now that the error message is improved.
> > Fixes: e151941d1b
> >
> > Signed-off-by: John Snow 
>
> In v3, the blank line was where it belongs:
>
>   Fix test output now that the error message is improved.
>
>   Fixes: e151941d1b
>   Signed-off-by: John Snow 
>
> The change looks accidental.  Can tidy up in my tree.
>

Yes please, thank you :)


[PATCH v1] vsock: don't send messages when vsock device is not started

2021-10-01 Thread Jiang Wang
Added a check in vhost_vsock_common_send_transport_reset,
and only send messages on event queue when the vsock host
device is started.

Suggested-by: Stefano Garzarella 
Signed-off-by: Jiang Wang 
---
 hw/virtio/vhost-vsock-common.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index 4ad6e234ad..64425719a2 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -138,8 +138,10 @@ static void 
vhost_vsock_common_send_transport_reset(VHostVSockCommon *vvc)
 goto out;
 }
 
-virtqueue_push(vq, elem, sizeof(event));
-virtio_notify(VIRTIO_DEVICE(vvc), vq);
+if (vvc->vhost_dev.started) {
+virtqueue_push(vq, elem, sizeof(event));
+virtio_notify(VIRTIO_DEVICE(vvc), vq);
+}
 
 out:
 g_free(elem);
-- 
2.20.1




Re: [PATCH 3/3] dtc: Update to version 1.6.1

2021-10-01 Thread Brad Smith

On 10/1/2021 1:54 PM, Brad Smith wrote:


On 10/1/2021 5:44 AM, Daniel P. Berrangé wrote:


On Fri, Oct 01, 2021 at 10:37:51AM +0100, Peter Maydell wrote:
On Fri, 1 Oct 2021 at 10:10, Daniel P. Berrangé 
 wrote:

On Thu, Sep 30, 2021 at 09:10:12AM +0200, Thomas Huth wrote:

On 27/08/2021 14.09, Thomas Huth wrote:
The dtc submodule is currently pointing to non-release commit. 
It's nicer
if submodules point to release versions instead and since dtc 
1.6.1 is

available now, let's update to that version.

Most of our supported platforms don't have version 1.6.1 available.

As a general goal IMHO we should be seeking to eliminate bundling of
3rd party modules that are commonly available in distros. We've
carried dtc for a hell of a long time, and if we keep updating our
submodule we'll keep relyin on new features, and never be able to
drop it because it will always be newer than what's in the distros.

So personally I think we should never again update dtc and capstone
modules. If we want to take adbantage of new features, then do that
through conditional compilation, as we do for any of the other 3rd
party libraries consumed.

I agree in general, but (per the commit message here) our dtc
submodule is currently pointing at some random not-a-release
commit in upstream dtc. We should at least move forward to
whatever the next released dtc after that is, before we say
"no more dtc updates".

Yep, if we want to fix it onto an official version tag, that's
OK, just not jumping right to very latest version. We might want
to move it backwards to better align with what we're targetting
in the support

Best I can tell the distros currently have these versions:

  - Alpine 3.14 - 1.6.1
  - CentOS 8 - 1.6.0
  - Debian 10 - 1.4.7
  - Fedora 33 - 1.6.0
  - OpenSUSE Leap 15.3 - 1.5.1
  - Ubuntu 18.04 - 1.4.5
  - FreeBSD Ports - 1.6.0
  - OpenBSD Ports - 1.6.0

I already updated OpenBSD to 1.6.1.

and NetBSD is at 1.4.7.

  - macOS HomeBrew - 1.6.1
  - Windows MSys2 - 1.6.0

Regards,
Daniel




[PATCH v4 11/11] tests/acpi: add expected blobs for VIOT test on q35 machine

2021-10-01 Thread Jean-Philippe Brucker
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
q35 machine.

Since the test instantiates a virtio device and two PCIe expander
bridges, DSDT.viot has more blocks than the base DSDT (long diff not
shown here). The VIOT table generated for the q35 test is:

[000h    4]Signature : "VIOT"[Virtual I/O 
Translation Table]
[004h 0004   4] Table Length : 0070
[008h 0008   1] Revision : 00
[009h 0009   1] Checksum : 3D
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   2]   Node count : 0003
[026h 0038   2]  Node offset : 0030
[028h 0040   8] Reserved : 

[030h 0048   1] Type : 03 [VirtIO-PCI IOMMU]
[031h 0049   1] Reserved : 00
[032h 0050   2]   Length : 0010

[034h 0052   2]  PCI Segment : 
[036h 0054   2]   PCI BDF number : 0010
[038h 0056   8] Reserved : 

[040h 0064   1] Type : 01 [PCI Range]
[041h 0065   1] Reserved : 00
[042h 0066   2]   Length : 0018

[044h 0068   4]   Endpoint start : 3000
[048h 0072   2]PCI Segment start : 
[04Ah 0074   2]  PCI Segment end : 
[04Ch 0076   2]PCI BDF start : 3000
[04Eh 0078   2]  PCI BDF end : 30FF
[050h 0080   2]  Output node : 0030
[052h 0082   6] Reserved : 

[058h 0088   1] Type : 01 [PCI Range]
[059h 0089   1] Reserved : 00
[05Ah 0090   2]   Length : 0018

[05Ch 0092   4]   Endpoint start : 1000
[060h 0096   2]PCI Segment start : 
[062h 0098   2]  PCI Segment end : 
[064h 0100   2]PCI BDF start : 1000
[066h 0102   2]  PCI BDF end : 10FF
[068h 0104   2]  Output node : 0030
[06Ah 0106   6] Reserved : 

Signed-off-by: Jean-Philippe Brucker 
---
 tests/qtest/bios-tables-test-allowed-diff.h |   2 --
 tests/data/acpi/q35/DSDT.viot   | Bin 0 -> 9398 bytes
 tests/data/acpi/q35/VIOT.viot   | Bin 0 -> 112 bytes
 3 files changed, 2 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index fa213e4738..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,3 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/DSDT.viot",
-"tests/data/acpi/q35/VIOT.viot",
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b41270ff6d63493c2ae379ddd1d3e28f190a6c01
 100644
GIT binary patch
literal 9398
zcmeHNO>7&-8J*>iv|O&FB}G~OOGG$M|57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
z5(9Az1F`}niVsB-#zBvCpa8wKr(7GLxfJNZhXOUwQxCo5S`_gq>icGPq#2R|qEj!C
zfZhFO-E)yj*v)_%j$|bWD4v61&3MJ6@sGF_Mv(
z(Y~GJ$Ji9i%ul_-ddc|xw*RT`zx{!4bOW~WnR9oe8@#vYZ!iK~-v}&=4xHj-r&;K<
zcU`OQR&r*iT=DGueakdEt~iRCoxImzW@o+PvCPVNXSM0Z?!3la@A7=V7VmARrY)yk
z{pY1`=FY$P>E*ZcU;gqRzq<396$4-adlUOh0d4%7zBT9fosWB0jax+L=jQvi=J#J~?>_G}@-A=VM7>texw(0?%WX7MbJqC}W*M`obLj6+2L}g#
z7KhBa!JMioR2I#0z1Wf}4QL}(?VWPHRb@6~_rFcDSo^j^@$^f@nwPCNyiPXrY^T}E
zvw%wcfQq{B`j+GO?T>ms>-oupgMHSY{HWJupLA{Zum8sP*}gR;+Lp2=-%n6m?tjZ-
zjG;9@c#>K}{oUR@TWRJyyo-^34o#_78fy{Dw`^y5>Zzy%5~{uX^m4%iSX`qhT8~!A
zG^eeZlHoI-8Ai$2Vq4f>h#*^g_hNN*{g5>^t+7liet~+Zy}PhdZ_UfPW8!)n8rHEU
zO2#|UccP|wVTaee;I38=IdP!Tn8Og6~%fzLjz(wD!XR-0J?VV(s-yiwD&A+AC-UHoLQ!1-
zZTt}HXS}hx*Q`$VSHhuj|GB^ZyZOw!)sJSsuAcdeTMekL*MH;pAM0IX{WHC*Rsr)E9$^!#8~A%&#`e2rz2YvijNQTB2(~G5e*20+
zH;dzb%?EP5(W}h7mC(G{QI&P|ie1Otgk$qns&Q5M{)a(5PSn%9#j>DYIZ)
z2`sNC#+ect6HM87gsRTCrZdi&5*imw*?5Gi&M{5r7-vf8n649{s&ib^Ij-p(*L5OP
zb()$^Q`2ecIuWWm@dQ$OI-%)I=sFRqIxS77rRlVEod{K(Nlj-`)0xzDB2;zaS*To3
zThnRlIuWWmCp4WCn$8JbCqh-{q^5IH(>bZ@M5yYV(sWK~I;V7<2vwbqrqj`MI=W7T
zs?LqMyPoYr(sYdWWOod{K(8BJ$K)0xqAB2;zGXgX&!
zoin;lgsRR{n$A<2&QrQhgsM)=Byji1=g_RCb5_@hP}O-_(|KCcd0N+rP}O;cGxOn-
z@C;`b!iU`%!E}#8VtOI=tj0X6G0*Bugevo##yqDn&*@BrD)YR?Jg+g&>r8|y^AU~t
zh{k+GXChRYk8-ATnMXNOKI0!1O!?qONKAPJ=d_%2TFyB=Cqj|agn{N211&WxNX^aE
zz%des28sY_MG!?Glfpm+j$4w!h$Y)+AgO>J8Yn_34F)Q((m)j`8K{6B8Yn`vMjEKV
zh7sjd4OBo64HO|-#IZ0?feoWjBZrcK3aAWKoiI>QEoZ_&6(|`fLg|WRpa`W-7^uK<
zCJa=8l7R{+&q)S~Q0jz%3M^;BKouw%sDN@N87M-j69y``0?L_Wpa`W-7^uKf}LawZulLa7r5DzKah16818paRO7
zWS|J8P8g`bawZH^fs%m=C})y^B9uB|paRR8Fi-_b1}dPONd}5g>V$y`EN8+%6(|{~
zfN~}oC_Az;Y%GRDqI#3Mglifg+STVW0xbnJ`cV
zN(L&RoJj_XQ0jz%3M^;BKouw%sDN@N87M-j69y`)?813@y+dqFQO

[PATCH v4 08/11] tests/acpi: allow updates of VIOT expected data files

2021-10-01 Thread Jean-Philippe Brucker
Create empty data files and allow updates for the upcoming VIOT tests.

Signed-off-by: Jean-Philippe Brucker 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 tests/data/acpi/q35/DSDT.viot   | 0
 tests/data/acpi/q35/VIOT.viot   | 0
 tests/data/acpi/virt/VIOT   | 0
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/DSDT.viot
 create mode 100644 tests/data/acpi/q35/VIOT.viot
 create mode 100644 tests/data/acpi/virt/VIOT

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..29b5b1eabc 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/VIOT",
+"tests/data/acpi/q35/DSDT.viot",
+"tests/data/acpi/q35/VIOT.viot",
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
new file mode 100644
index 00..e69de29bb2
-- 
2.33.0




[PATCH v4 09/11] tests/acpi: add test cases for VIOT

2021-10-01 Thread Jean-Philippe Brucker
Add two test cases for VIOT, one on the q35 machine and the other on
virt. To test complex topologies the q35 test has two PCIe buses that
bypass the IOMMU (and are therefore not described by VIOT), and two
buses that are translated by virtio-iommu.

Signed-off-by: Jean-Philippe Brucker 
---
 tests/qtest/bios-tables-test.c | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 4f11d03055..b6cb383bd9 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1403,6 +1403,42 @@ static void test_acpi_virt_tcg(void)
 free_test_data(&data);
 }
 
+static void test_acpi_q35_viot(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".viot",
+};
+
+/*
+ * To keep things interesting, two buses bypass the IOMMU.
+ * VIOT should only describes the other two buses.
+ */
+test_acpi_one("-machine default_bus_bypass_iommu=on "
+  "-device virtio-iommu "
+  "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
+  "-device 
pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
+  "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
+  &data);
+free_test_data(&data);
+}
+
+static void test_acpi_virt_viot(void)
+{
+test_data data = {
+.machine = "virt",
+.uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+.ram_start = 0x4000ULL,
+.scan_len = 128ULL * 1024 * 1024,
+};
+
+test_acpi_one("-cpu cortex-a57 "
+  "-device virtio-iommu", &data);
+free_test_data(&data);
+}
+
 static void test_oem_fields(test_data *data)
 {
 int i;
@@ -1567,12 +1603,14 @@ int main(int argc, char *argv[])
 if (strcmp(arch, "x86_64") == 0) {
 qtest_add_func("acpi/microvm/pcie", test_acpi_microvm_pcie_tcg);
 }
+qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
 } else if (strcmp(arch, "aarch64") == 0) {
 qtest_add_func("acpi/virt", test_acpi_virt_tcg);
 qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
 qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
 qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
 qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
+qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
 }
 ret = g_test_run();
 boot_sector_cleanup(disk);
-- 
2.33.0




[PATCH v4 06/11] hw/i386: Move vIOMMU uniqueness check into pc.c

2021-10-01 Thread Jean-Philippe Brucker
We're about to need this check for a third vIOMMU, virtio-iommu, which
doesn't inherit X86IOMMUState as it doesn't support IRQ remapping and is
a virtio device. Move the check into the pre_plug callback to be shared
by all three vIOMMUs.

Signed-off-by: Jean-Philippe Brucker 
---
 hw/i386/pc.c| 10 +-
 hw/i386/x86-iommu.c |  6 --
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 557d49c9f8..789ccb6ef4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1367,6 +1367,13 @@ static void pc_virtio_md_pci_unplug(HotplugHandler 
*hotplug_dev,
 static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
+if (object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE) &&
+x86_iommu_get_default()) {
+error_setg(errp, "QEMU does not support multiple vIOMMUs "
+   "for x86 yet.");
+return;
+}
+
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_memory_pre_plug(hotplug_dev, dev, errp);
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
@@ -1428,7 +1435,8 @@ static HotplugHandler 
*pc_get_hotplug_handler(MachineState *machine,
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
 object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
-object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
+object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||
+object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE)) {
 return HOTPLUG_HANDLER(machine);
 }
 
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
index 86ad03972e..550e551993 100644
--- a/hw/i386/x86-iommu.c
+++ b/hw/i386/x86-iommu.c
@@ -84,12 +84,6 @@ static void x86_iommu_set_default(X86IOMMUState *x86_iommu)
 {
 assert(x86_iommu);
 
-if (x86_iommu_default) {
-error_report("QEMU does not support multiple vIOMMUs "
- "for x86 yet.");
-exit(1);
-}
-
 x86_iommu_default = x86_iommu;
 }
 
-- 
2.33.0




RE: hexagon container update

2021-10-01 Thread Brian Cain
> -Original Message-
> From: Richard Henderson 
...
> On 10/1/21 12:59 PM, Brian Cain wrote:
> > Alex,
> >
> > We need to update the docker container used for hexagon for new test cases
> proposed in Taylor's recent patch series under review.  Thankfully, CodeLinaro
> has provided a binary of the hexagon cross toolchain so now I think we can
> simplify the hexagon docker file to something like the below.  I hope this 
> also
> means that we can remove the exceptional handling for the hexagon container.
> >
> > I can propose a patch but I'm not quite certain how to test it.
> 
> make docker-image-debian-hexagon-cross NOCACHE=1 V=1
> 
> and then make check-tcg to use the new image.

Ok -- so the intent of the NOCACHE is that it will force the use of my newly 
modified Dockerfile and not the one in the qemu container repository?

> > The "--no-check-certificate" argument to wget is very bad but I'm not quite
> certain how to upgrade/change the container's certificate store to accept the
> apparently-legit-but-perhaps-newer-than-expected certificate presented by
> codelinaro.jfrog.io.
> 
> Hum.  This all suggests that it would be better to update the build-toolchain
> script.

If there's any trust concerns we can verify the download in the dockerfile 
using the hash file for the tarball and/or the gpg signature.

The build-toolchain is a bit of a hassle given the processing time, it'd be 
great to avoid it.  If the hash or signature check doesn't suffice I will 
investigate how to update debian10's signatures.  Are we bound to debian10 for 
all the containers?  If using a different basis was effective at resolving this 
issue, could I select a different one?

> > RUN cd /tmp && \
> >  wget --quiet --no-check-certificate ${CLANG_URL}
> > RUN cd /opt && \
> >  tar xf /tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-
> musl.tar.xz
> 
> You'd want to remove the tarball as well.

Yes, good point.


[PATCH v4 02/11] hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu

2021-10-01 Thread Jean-Philippe Brucker
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
table.

Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/virt-acpi-build.c | 7 +++
 hw/arm/Kconfig   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6cec97352b..e26639e1e1 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -55,6 +55,7 @@
 #include "kvm_arm.h"
 #include "migration/vmstate.h"
 #include "hw/acpi/ghes.h"
+#include "hw/acpi/viot.h"
 
 #define ARM_SPI_BASE 32
 
@@ -934,6 +935,12 @@ void virt_acpi_build(VirtMachineState *vms, 
AcpiBuildTables *tables)
 }
 #endif
 
+if (vms->iommu == VIRT_IOMMU_VIRTIO) {
+acpi_add_table(table_offsets, tables_blob);
+build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
+   vms->oem_id, vms->oem_table_id);
+}
+
 /* XSDT is pointed to by RSDP */
 xsdt = tables_blob->len;
 build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 18832abf7d..a05d75faca 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -27,6 +27,7 @@ config ARM_VIRT
 select DIMM
 select ACPI_HW_REDUCED
 select ACPI_APEI
+select ACPI_VIOT
 
 config CHEETAH
 bool
-- 
2.33.0




[PATCH v4 07/11] pc: Allow instantiating a virtio-iommu device

2021-10-01 Thread Jean-Philippe Brucker
Allow instantiating a virtio-iommu device by adding an ACPI Virtual I/O
Translation table (VIOT), which describes the relation between the
virtio-iommu and the endpoints it manages.

Add a hotplug handler for virtio-iommu on x86 and set the necessary
reserved region property. On x86, the [0xfee0, 0xfeef] DMA
region is reserved for MSIs. DMA transactions to this range either
trigger IRQ remapping in the IOMMU or bypasses IOMMU translation.

Although virtio-iommu does not support IRQ remapping it must be informed
of the reserved region so that it can forward DMA transactions targeting
this region.

Signed-off-by: Jean-Philippe Brucker 
---
 include/hw/i386/pc.h |  2 ++
 hw/i386/acpi-build.c |  5 +
 hw/i386/pc.c | 24 ++--
 hw/i386/Kconfig  |  1 +
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 82cf7b7e30..f3ba1ee4c0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -45,6 +45,8 @@ typedef struct PCMachineState {
 bool pit_enabled;
 bool hpet_enabled;
 bool default_bus_bypass_iommu;
+bool virtio_iommu;
+uint16_t virtio_iommu_bdf;
 uint64_t max_fw_size;
 
 /* ACPI Memory hotplug IO base address */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d1c28440f4..4e46585709 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -71,6 +71,7 @@
 
 #include "hw/acpi/ipmi.h"
 #include "hw/acpi/hmat.h"
+#include "hw/acpi/viot.h"
 
 /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
  * -M pc-i440fx-2.0.  Even if the actual amount of AML generated grows
@@ -2593,6 +2594,10 @@ void acpi_build(AcpiBuildTables *tables, MachineState 
*machine)
 build_dmar_q35(tables_blob, tables->linker, x86ms->oem_id,
x86ms->oem_table_id);
 }
+} else if (pcms->virtio_iommu) {
+acpi_add_table(table_offsets, tables_blob);
+build_viot(machine, tables_blob, tables->linker, 
pcms->virtio_iommu_bdf,
+   x86ms->oem_id, x86ms->oem_table_id);
 }
 if (machine->nvdimms_state->is_enabled) {
 nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 789ccb6ef4..31710bc4fb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -83,6 +83,7 @@
 #include "hw/i386/intel_iommu.h"
 #include "hw/net/ne2000-isa.h"
 #include "standard-headers/asm-x86/bootparam.h"
+#include "hw/virtio/virtio-iommu.h"
 #include "hw/virtio/virtio-pmem-pci.h"
 #include "hw/virtio/virtio-mem-pci.h"
 #include "hw/mem/memory-device.h"
@@ -1367,8 +1368,11 @@ static void pc_virtio_md_pci_unplug(HotplugHandler 
*hotplug_dev,
 static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
-if (object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE) &&
-x86_iommu_get_default()) {
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if ((object_dynamic_cast(OBJECT(dev), TYPE_X86_IOMMU_DEVICE) ||
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) &&
+(x86_iommu_get_default() || pcms->virtio_iommu)) {
 error_setg(errp, "QEMU does not support multiple vIOMMUs "
"for x86 yet.");
 return;
@@ -1381,6 +1385,15 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
 pc_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+/* Declare the APIC range as the reserved MSI region */
+char *resv_prop_str = g_strdup_printf("0xfee0:0xfeef:%d",
+  VIRTIO_IOMMU_RESV_MEM_T_MSI);
+
+object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
+object_property_set_str(OBJECT(dev), "reserved-regions[0]",
+resv_prop_str, errp);
+g_free(resv_prop_str);
 }
 }
 
@@ -1394,6 +1407,12 @@ static void pc_machine_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
 pc_virtio_md_pci_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+PCIDevice *pdev = PCI_DEVICE(dev);
+
+pcms->virtio_iommu = true;
+pcms->virtio_iommu_bdf = pci_get_bdf(pdev);
 }
 }
 
@@ -1436,6 +1455,7 @@ static HotplugHandler 
*pc_get_hotplug_handler(MachineState *machine,
 object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
 object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_PMEM_PCI) ||
 object_dyna

[PATCH v4 05/11] hw/arm/virt: Use object_property_set instead of qdev_prop_set

2021-10-01 Thread Jean-Philippe Brucker
To propagate errors to the caller of the pre_plug callback, use the
object_poperty_set*() functions directly instead of the qdev_prop_set*()
helpers.

Suggested-by: Igor Mammedov 
Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/virt.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 36f0261ef4..ac307b6030 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2465,8 +2465,9 @@ static void 
virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 db_start, db_end,
 VIRTIO_IOMMU_RESV_MEM_T_MSI);
 
-qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
-qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
+object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
+object_property_set_str(OBJECT(dev), "reserved-regions[0]",
+resv_prop_str, errp);
 g_free(resv_prop_str);
 }
 }
-- 
2.33.0




[RFC PATCH] hw/arm: fix the position of vcram for raspi

2021-10-01 Thread Alex Bennée
The previous calculation fell over when I tried to create a 8gb Pi 4
because the values where only 32 bit. However the quirk of the Pi
hardware is the vcram can only appear in the first 1gb of address
space. This also limits where the initial kernel and DTB can be
loaded (notice the DTS for the 8gb Pi4 still only uses 32 bit sizes).
Fix this cleaning up setup_boot to directly use vcram_base and
documenting what is going on.

NB: the aliases are confusing.

Signed-off-by: Alex Bennée 
Cc: Michael Bishop 
Cc: Philippe Mathieu-Daudé 
---
 hw/arm/bcm2835_peripherals.c | 14 +++---
 hw/arm/bcm2836.c |  2 ++
 hw/arm/raspi.c   | 19 ---
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 1f2f0ad486..3856c7d267 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "qemu/units.h"
 #include "hw/arm/bcm2835_peripherals.h"
 #include "hw/misc/bcm2835_mbox_defs.h"
 #include "hw/arm/raspi_platform.h"
@@ -74,6 +75,7 @@ static void bcm2835_peripherals_init(Object *obj)
 /* Framebuffer */
 object_initialize_child(obj, "fb", &s->fb, TYPE_BCM2835_FB);
 object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size");
+object_property_add_alias(obj, "vcram-base", OBJECT(&s->fb), "vcram-base");
 
 object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
OBJECT(&s->gpu_bus_mr));
@@ -138,7 +140,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, 
Error **errp)
 Object *obj;
 MemoryRegion *ram;
 Error *err = NULL;
-uint64_t ram_size, vcram_size;
+uint64_t ram_size, vcram_size, vcram_base;
 int n;
 
 obj = object_property_get_link(OBJECT(dev), "ram", &error_abort);
@@ -235,15 +237,21 @@ static void bcm2835_peripherals_realize(DeviceState *dev, 
Error **errp)
 qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
INTERRUPT_ARM_MAILBOX));
 
-/* Framebuffer */
+/*
+ * The framebuffer has to live in the first 1gb of addressable
+ * space which is fine for older Pi's with less than 1gb of RAM
+ * but we need to take care not to put it too high otherwise
+ */
 vcram_size = object_property_get_uint(OBJECT(s), "vcram-size", &err);
 if (err) {
 error_propagate(errp, err);
 return;
 }
 
+vcram_base = MIN(ram_size, 1 * GiB) - vcram_size;
+
 if (!object_property_set_uint(OBJECT(&s->fb), "vcram-base",
-  ram_size - vcram_size, errp)) {
+  vcram_base, errp)) {
 return;
 }
 
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 3477f1..18034c4131 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -79,6 +79,8 @@ static void bcm2836_init(Object *obj)
   "board-rev");
 object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
   "vcram-size");
+object_property_add_alias(obj, "vcram-base", OBJECT(&s->peripherals),
+  "vcram-base");
 }
 
 static bool bcm283x_common_realize(DeviceState *dev, Error **errp)
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 50462bc04c..0342aeab03 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -198,14 +198,19 @@ static void reset_secondary(ARMCPU *cpu, const struct 
arm_boot_info *info)
 cpu_set_pc(cs, info->smp_loader_start);
 }
 
+/*
+ * NB: ram_limit isn't the same as ram_size - it indicates the portion
+ * of RAM that boot components can live in (up to the first 1gb - the
+ * vcram_size, aka vcram_base)
+ */
 static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
-   size_t ram_size)
+   size_t ram_limit)
 {
 RaspiMachineState *s = RASPI_MACHINE(machine);
 int r;
 
 s->binfo.board_id = MACH_TYPE_BCM2708;
-s->binfo.ram_size = ram_size;
+s->binfo.ram_size = ram_limit;
 s->binfo.nb_cpus = machine->smp.cpus;
 
 if (processor_id <= PROCESSOR_ID_BCM2836) {
@@ -241,7 +246,7 @@ static void setup_boot(MachineState *machine, 
RaspiProcessorId processor_id,
  ? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3;
 /* load the firmware image (typically kernel.img) */
 r = load_image_targphys(machine->firmware, firmware_addr,
-ram_size - firmware_addr);
+ram_limit - firmware_addr);
 if (r < 0) {
 error_report("Failed to load firmware from %s", machine->firmware);
 exit(1);
@@ -260,7 +265,7 @@ static void raspi_machine_init(MachineState *machine)
 RaspiMachineState *s = RASPI_MACHINE(machine);
 uint32_t board_rev = mc->board_rev;
 uint64_t ram_size = board_ram_si

[PATCH v3 37/41] target/s390x: Implement s390_cpu_record_sigsegv

2021-10-01 Thread Richard Henderson
Move the masking of the address from cpu_loop into
s390_cpu_record_sigsegv -- this is governed by hw, not linux.
This does mean we have to raise our own exception, rather
than return to the fallback.

Use maperr to choose between PGM_PROTECTION and PGM_ADDRESSING.
Use the appropriate si_code for each in cpu_loop.

Cc: qemu-s3...@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/s390x/s390x-internal.h  | 13 ++---
 linux-user/s390x/cpu_loop.c| 13 ++---
 target/s390x/cpu.c |  6 --
 target/s390x/tcg/excp_helper.c | 18 +++---
 4 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
index 27d4a03ca1..163aa4f94a 100644
--- a/target/s390x/s390x-internal.h
+++ b/target/s390x/s390x-internal.h
@@ -270,13 +270,20 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int mmu_idx,
uintptr_t retaddr) QEMU_NORETURN;
 
+#ifdef CONFIG_USER_ONLY
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t retaddr);
+#else
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+#endif
+
 
 /* fpu_helper.c */
 uint32_t set_cc_nz_f32(float32 v);
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index 69b69981f6..d089c8417e 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -24,8 +24,6 @@
 #include "cpu_loop-common.h"
 #include "signal-common.h"
 
-/* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS 
*/
-#define S390X_FAIL_ADDR_MASK -4096LL
 
 static int get_pgm_data_si_code(int dxc_code)
 {
@@ -111,12 +109,13 @@ void cpu_loop(CPUS390XState *env)
 n = TARGET_ILL_ILLOPC;
 goto do_signal_pc;
 case PGM_PROTECTION:
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR,
+env->__excp_addr);
+break;
 case PGM_ADDRESSING:
-sig = TARGET_SIGSEGV;
-/* XXX: check env->error_code */
-n = TARGET_SEGV_MAPERR;
-addr = env->__excp_addr & S390X_FAIL_ADDR_MASK;
-goto do_signal;
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR,
+env->__excp_addr);
+break;
 case PGM_EXECUTE:
 case PGM_SPECIFICATION:
 case PGM_SPECIAL_OP:
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 7b7b05f1d3..593dda75c4 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -266,9 +266,11 @@ static void s390_cpu_reset_full(DeviceState *dev)
 
 static const struct TCGCPUOps s390_tcg_ops = {
 .initialize = s390x_translate_init,
-.tlb_fill = s390_cpu_tlb_fill,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = s390_cpu_record_sigsegv,
+#else
+.tlb_fill = s390_cpu_tlb_fill,
 .cpu_exec_interrupt = s390_cpu_exec_interrupt,
 .do_interrupt = s390_cpu_do_interrupt,
 .debug_excp_handler = s390x_cpu_debug_excp_handler,
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index 3d6662a53c..b923d080fc 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -89,16 +89,20 @@ void s390_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = -1;
 }
 
-bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
+void s390_cpu_record_sigsegv(CPUState *cs, vaddr address,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t retaddr)
 {
 S390CPU *cpu = S390_CPU(cs);
 
-trigger_pgm_exception(&cpu->env, PGM_ADDRESSING);
-/* On real machines this value is dropped into LowMem.  Since this
-   is userland, simply put this someplace that cpu_loop can find it.  */
-cpu->env.__excp_addr = address;
+trigger_pgm_exception(&cpu->env, maperr ? PGM_ADDRESSING : PGM_PROTECTION);
+/*
+ * On real machines this value is dropped into LowMem. Since this
+ * is userland, simply put this someplace that cpu_loop can find it.
+ * S390 o

Re: [PATCH 3/3] dtc: Update to version 1.6.1

2021-10-01 Thread Brad Smith

On 10/1/2021 5:44 AM, Daniel P. Berrangé wrote:


On Fri, Oct 01, 2021 at 10:37:51AM +0100, Peter Maydell wrote:

On Fri, 1 Oct 2021 at 10:10, Daniel P. Berrangé  wrote:

On Thu, Sep 30, 2021 at 09:10:12AM +0200, Thomas Huth wrote:

On 27/08/2021 14.09, Thomas Huth wrote:

The dtc submodule is currently pointing to non-release commit. It's nicer
if submodules point to release versions instead and since dtc 1.6.1 is
available now, let's update to that version.

Most of our supported platforms don't have version 1.6.1 available.

As a general goal IMHO we should be seeking to eliminate bundling of
3rd party modules that are commonly available in distros. We've
carried dtc for a hell of a long time, and if we keep updating our
submodule we'll keep relyin on new features, and never be able to
drop it because it will always be newer than what's in the distros.

So personally I think we should never again update dtc and capstone
modules. If we want to take adbantage of new features, then do that
through conditional compilation, as we do for any of the other 3rd
party libraries consumed.

I agree in general, but (per the commit message here) our dtc
submodule is currently pointing at some random not-a-release
commit in upstream dtc. We should at least move forward to
whatever the next released dtc after that is, before we say
"no more dtc updates".

Yep, if we want to fix it onto an official version tag, that's
OK, just not jumping right to very latest version. We might want
to move it backwards to better align with what we're targetting
in the support

Best I can tell the distros currently have these versions:

  - Alpine 3.14 - 1.6.1
  - CentOS 8 - 1.6.0
  - Debian 10 - 1.4.7
  - Fedora 33 - 1.6.0
  - OpenSUSE Leap 15.3 - 1.5.1
  - Ubuntu 18.04 - 1.4.5
  - FreeBSD Ports - 1.6.0
  - OpenBSD Ports - 1.6.0

I already updated OpenBSD to 1.6.1.

  - macOS HomeBrew - 1.6.1
  - Windows MSys2 - 1.6.0


Regards,
Daniel




Re: hexagon container update

2021-10-01 Thread Richard Henderson

On 10/1/21 12:59 PM, Brian Cain wrote:

Alex,

We need to update the docker container used for hexagon for new test cases 
proposed in Taylor's recent patch series under review.  Thankfully, CodeLinaro 
has provided a binary of the hexagon cross toolchain so now I think we can 
simplify the hexagon docker file to something like the below.  I hope this also 
means that we can remove the exceptional handling for the hexagon container.

I can propose a patch but I'm not quite certain how to test it.


make docker-image-debian-hexagon-cross NOCACHE=1 V=1

and then make check-tcg to use the new image.



The "--no-check-certificate" argument to wget is very bad but I'm not quite 
certain how to upgrade/change the container's certificate store to accept the 
apparently-legit-but-perhaps-newer-than-expected certificate presented by 
codelinaro.jfrog.io.


Hum.  This all suggests that it would be better to update the build-toolchain 
script.


RUN cd /tmp && \
 wget --quiet --no-check-certificate ${CLANG_URL}
RUN cd /opt && \
 tar xf /tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz


You'd want to remove the tarball as well.


r~



[PATCH v3 31/41] target/nios2: Implement nios2_cpu_record_sigsegv

2021-10-01 Thread Richard Henderson
Because the linux-user kuser page handling is currently implemented
by detecting magic addresses in the unnamed 0xaa trap, we cannot
simply remove nios2_cpu_tlb_fill and rely on the fallback code.

Signed-off-by: Richard Henderson 
---
 target/nios2/cpu.h| 6 ++
 target/nios2/cpu.c| 6 --
 target/nios2/helper.c | 7 ---
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index a80587338a..1a69ed7a49 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -218,9 +218,15 @@ static inline int cpu_mmu_index(CPUNios2State *env, bool 
ifetch)
   MMU_SUPERVISOR_IDX;
 }
 
+#ifdef CONFIG_USER_ONLY
+void nios2_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t ra);
+#else
 bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
+#endif
 
 static inline int cpu_interrupts_enabled(CPUNios2State *env)
 {
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 947bb09bc1..421cad114a 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -220,9 +220,11 @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
 
 static const struct TCGCPUOps nios2_tcg_ops = {
 .initialize = nios2_tcg_init,
-.tlb_fill = nios2_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = nios2_cpu_record_sigsegv,
+#else
+.tlb_fill = nios2_cpu_tlb_fill,
 .cpu_exec_interrupt = nios2_cpu_exec_interrupt,
 .do_interrupt = nios2_cpu_do_interrupt,
 .do_unaligned_access = nios2_cpu_do_unaligned_access,
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index 53be8398e9..e5c98650e1 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -38,10 +38,11 @@ void nios2_cpu_do_interrupt(CPUState *cs)
 env->regs[R_EA] = env->regs[R_PC] + 4;
 }
 
-bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
+void nios2_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t retaddr)
 {
+/* FIXME: Disentangle kuser page from linux-user sigsegv handling. */
 cs->exception_index = 0xaa;
 cpu_loop_exit_restore(cs, retaddr);
 }
-- 
2.25.1




[PATCH v3 41/41] accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu

2021-10-01 Thread Richard Henderson
We have replaced tlb_fill with record_sigsegv for user mod.
Move the declaration to restrict it to system emulation.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 22 ++
 linux-user/signal.c   |  3 ---
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 41718b695b..8eadd404c8 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -35,18 +35,6 @@ struct TCGCPUOps {
 void (*cpu_exec_enter)(CPUState *cpu);
 /** @cpu_exec_exit: Callback for cpu_exec cleanup */
 void (*cpu_exec_exit)(CPUState *cpu);
-/**
- * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
- *
- * For system mode, if the access is valid, call tlb_set_page
- * and return true; if the access is invalid, and probe is
- * true, return false; otherwise raise an exception and do
- * not return.  For user-only mode, always raise an exception
- * and do not return.
- */
-bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
 /** @debug_excp_handler: Callback for handling debug exceptions */
 void (*debug_excp_handler)(CPUState *cpu);
 
@@ -68,6 +56,16 @@ struct TCGCPUOps {
 #ifdef CONFIG_SOFTMMU
 /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
 bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
+/**
+ * @tlb_fill: Handle a softmmu tlb miss
+ *
+ * If the access is valid, call tlb_set_page and return true;
+ * if the access is invalid and probe is true, return false;
+ * otherwise raise an exception and do not return.
+ */
+bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 /**
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 8c22f711f1..d32bc5e1e5 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -694,9 +694,6 @@ void cpu_loop_exit_segv(CPUState *cpu, target_ulong addr,
 
 if (tcg_ops->record_sigsegv) {
 tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
-} else if (tcg_ops->tlb_fill) {
-tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
-g_assert_not_reached();
 }
 
 force_sig_fault(TARGET_SIGSEGV,
-- 
2.25.1




[PATCH v4 01/11] hw/acpi: Add VIOT table

2021-10-01 Thread Jean-Philippe Brucker
Add a function that generates a Virtual I/O Translation table (VIOT),
describing the topology of paravirtual IOMMUs. The table is created when
instantiating a virtio-iommu device. It contains a virtio-iommu node and
PCI Range nodes for endpoints managed by the IOMMU. By default, a single
node describes all PCI devices. When passing the "default_bus_bypass_iommu"
machine option and "bypass_iommu" PXB option, only buses that do not
bypass the IOMMU are described by PCI Range nodes.

Reviewed-by: Eric Auger 
Tested-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 hw/acpi/viot.h  |  13 +
 hw/acpi/viot.c  | 112 
 hw/acpi/Kconfig |   4 ++
 hw/acpi/meson.build |   1 +
 4 files changed, 130 insertions(+)
 create mode 100644 hw/acpi/viot.h
 create mode 100644 hw/acpi/viot.c

diff --git a/hw/acpi/viot.h b/hw/acpi/viot.h
new file mode 100644
index 00..9fe565bb87
--- /dev/null
+++ b/hw/acpi/viot.h
@@ -0,0 +1,13 @@
+/*
+ * ACPI Virtual I/O Translation Table implementation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef VIOT_H
+#define VIOT_H
+
+void build_viot(MachineState *ms, GArray *table_data, BIOSLinker *linker,
+uint16_t virtio_iommu_bdf, const char *oem_id,
+const char *oem_table_id);
+
+#endif /* VIOT_H */
diff --git a/hw/acpi/viot.c b/hw/acpi/viot.c
new file mode 100644
index 00..e33d468e11
--- /dev/null
+++ b/hw/acpi/viot.c
@@ -0,0 +1,112 @@
+/*
+ * ACPI Virtual I/O Translation table implementation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/viot.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+
+struct viot_pci_ranges {
+GArray *blob;
+size_t count;
+uint16_t output_node;
+};
+
+/* Build PCI range for a given PCI host bridge */
+static int build_pci_range_node(Object *obj, void *opaque)
+{
+struct viot_pci_ranges *pci_ranges = opaque;
+GArray *blob = pci_ranges->blob;
+
+if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) {
+PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus;
+
+if (bus && !pci_bus_bypass_iommu(bus)) {
+int min_bus, max_bus;
+
+pci_bus_range(bus, &min_bus, &max_bus);
+
+/* Type (PCI range) */
+build_append_int_noprefix(blob, 1, 1);
+/* Reserved */
+build_append_int_noprefix(blob, 0, 1);
+/* Length */
+build_append_int_noprefix(blob, 24, 2);
+/* Endpoint start */
+build_append_int_noprefix(blob, PCI_BUILD_BDF(min_bus, 0), 4);
+/* PCI Segment start */
+build_append_int_noprefix(blob, 0, 2);
+/* PCI Segment end */
+build_append_int_noprefix(blob, 0, 2);
+/* PCI BDF start */
+build_append_int_noprefix(blob, PCI_BUILD_BDF(min_bus, 0), 2);
+/* PCI BDF end */
+build_append_int_noprefix(blob, PCI_BUILD_BDF(max_bus, 0xff), 2);
+/* Output node */
+build_append_int_noprefix(blob, pci_ranges->output_node, 2);
+/* Reserved */
+build_append_int_noprefix(blob, 0, 6);
+
+pci_ranges->count++;
+}
+}
+
+return 0;
+}
+
+/*
+ * Generate a VIOT table with one PCI-based virtio-iommu that manages PCI
+ * endpoints.
+ */
+void build_viot(MachineState *ms, GArray *table_data, BIOSLinker *linker,
+uint16_t virtio_iommu_bdf, const char *oem_id,
+const char *oem_table_id)
+{
+/* The virtio-iommu node follows the 48-bytes header */
+int viommu_off = 48;
+AcpiTable table = { .sig = "VIOT", .rev = 0,
+.oem_id = oem_id, .oem_table_id = oem_table_id };
+struct viot_pci_ranges pci_ranges = {
+.output_node = viommu_off,
+.blob = g_array_new(false, true /* clear */, 1),
+};
+
+/* Build the list of PCI ranges that this viommu manages */
+object_child_foreach_recursive(OBJECT(ms), build_pci_range_node,
+   &pci_ranges);
+
+/* ACPI table header */
+acpi_table_begin(&table, table_data);
+/* Node count */
+build_append_int_noprefix(table_data, pci_ranges.count + 1, 2);
+/* Node offset */
+build_append_int_noprefix(table_data, viommu_off, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 8);
+
+/* Virtio-iommu node */
+/* Type (virtio-pci IOMMU)  */
+build_append_int_noprefix(table_data, 3, 1);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 1);
+/* Length */
+build_append_int_noprefix(table_data, 16, 2);
+/* PCI Segment */
+build_append_int_noprefix(table_data, 0, 2);
+/* PCI BDF number */
+build_append_int_noprefix(table_data, virtio_iommu_bdf, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 8);
+
+/* PCI ranges 

[PATCH v4 03/11] hw/arm/virt: Remove device tree restriction for virtio-iommu

2021-10-01 Thread Jean-Philippe Brucker
virtio-iommu is now supported with ACPI VIOT as well as device tree.
Remove the restriction that prevents from instantiating a virtio-iommu
device under ACPI.

Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/virt.c| 10 ++
 hw/virtio/virtio-iommu-pci.c |  7 ---
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1d59f0e59f..56e8fc7059 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2561,16 +2561,10 @@ static HotplugHandler 
*virt_machine_get_hotplug_handler(MachineState *machine,
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 
 if (device_is_dynamic_sysbus(mc, dev) ||
-   (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
+object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
 return HOTPLUG_HANDLER(machine);
 }
-if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
-VirtMachineState *vms = VIRT_MACHINE(machine);
-
-if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
-return HOTPLUG_HANDLER(machine);
-}
-}
 return NULL;
 }
 
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
index 770c286be7..f30eb16cbf 100644
--- a/hw/virtio/virtio-iommu-pci.c
+++ b/hw/virtio/virtio-iommu-pci.c
@@ -48,16 +48,9 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
 
 if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
-MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
-
-error_setg(errp,
-   "%s machine fails to create iommu-map device tree bindings",
-   mc->name);
 error_append_hint(errp,
   "Check your machine implements a hotplug handler "
   "for the virtio-iommu-pci device\n");
-error_append_hint(errp, "Check the guest is booted without FW or with "
-  "-no-acpi\n");
 return;
 }
 for (int i = 0; i < s->nb_reserved_regions; i++) {
-- 
2.33.0




[PATCH v3 36/41] target/s390x: Use probe_access_flags in s390_probe_access

2021-10-01 Thread Richard Henderson
Not sure why the user-only code wasn't rewritten to use
probe_access_flags at the same time that the sysemu code
was converted.  For the purpose of user-only, this is an
exact replacement.

Cc: qemu-s3...@nongnu.org
Signed-off-by: Richard Henderson 
---
 target/s390x/tcg/mem_helper.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index 0bf775a37d..596270e45d 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -142,20 +142,12 @@ static int s390_probe_access(CPUArchState *env, 
target_ulong addr, int size,
  MMUAccessType access_type, int mmu_idx,
  bool nonfault, void **phost, uintptr_t ra)
 {
+#if defined(CONFIG_USER_ONLY)
+return probe_access_flags(env, addr, access_type, mmu_idx,
+  nonfault, phost, ra);
+#else
 int flags;
 
-#if defined(CONFIG_USER_ONLY)
-flags = page_get_flags(addr);
-if (!(flags & (access_type == MMU_DATA_LOAD ?  PAGE_READ : 
PAGE_WRITE_ORG))) {
-env->__excp_addr = addr;
-flags = (flags & PAGE_VALID) ? PGM_PROTECTION : PGM_ADDRESSING;
-if (nonfault) {
-return flags;
-}
-tcg_s390_program_interrupt(env, flags, ra);
-}
-*phost = g2h(env_cpu(env), addr);
-#else
 /*
  * For !CONFIG_USER_ONLY, we cannot rely on TLB_INVALID_MASK or haddr==NULL
  * to detect if there was an exception during tlb_fill().
@@ -174,8 +166,8 @@ static int s390_probe_access(CPUArchState *env, 
target_ulong addr, int size,
  (access_type == MMU_DATA_STORE
   ? BP_MEM_WRITE : BP_MEM_READ), ra);
 }
-#endif
 return 0;
+#endif
 }
 
 static int access_prepare_nf(S390Access *access, CPUS390XState *env,
-- 
2.25.1




[PATCH v4 00/11] virtio-iommu: Add ACPI support

2021-10-01 Thread Jean-Philippe Brucker
Allow instantiating a virtio-iommu device on ACPI systems by adding a
Virtual I/O Translation table (VIOT). Enable x86 support for VIOT.

Changes since v3 [1]:
* Cleaned the IOMMU-uniqueness checks. Added patch 6 to have a
  single check on x86.
* Added patch 5 that allows to gracefully propagate errors when setting
  resv_mem properties.
* Squashed table blobs into patch 11.
* Addressed all other comments from v3.

Caveats:

* Series depends on "acpi: refactor error prone build_header() and
  packed structures usage in ACPI tables" [2]

* Since virtio-iommu doesn't support boot-bypass at the moment, firmware
  can't access storage behind the IOMMU to load bootloader or kernel.
  This will be solved by another series currently in flight [3]. In the
  meantime you can use a storage device that bypasses the IOMMU such as
  virtio-blk-pci (without iommu_platform property) or a bypass bridge
  (docs/iommu-bypass.txt).

You can find a description of the VIOT table, which will be included in
next ACPI version, here: https://jpbrucker.net/virtio-iommu/viot/viot-v9.pdf

[1] 
https://lore.kernel.org/qemu-devel/20210914142004.2433568-1-jean-phili...@linaro.org/
[2] 
https://lore.kernel.org/qemu-devel/20210924122802.1455362-1-imamm...@redhat.com/
[3] 
https://lore.kernel.org/qemu-devel/20210930185050.262759-1-jean-phili...@linaro.org/

Jean-Philippe Brucker (11):
  hw/acpi: Add VIOT table
  hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
  hw/arm/virt: Remove device tree restriction for virtio-iommu
  hw/arm/virt: Reject instantiation of multiple IOMMUs
  hw/arm/virt: Use object_property_set instead of qdev_prop_set
  hw/i386: Move vIOMMU uniqueness check into pc.c
  pc: Allow instantiating a virtio-iommu device
  tests/acpi: allow updates of VIOT expected data files
  tests/acpi: add test cases for VIOT
  tests/acpi: add expected blob for VIOT test on virt machine
  tests/acpi: add expected blobs for VIOT test on q35 machine

 hw/acpi/viot.h |  13 
 include/hw/i386/pc.h   |   2 +
 hw/acpi/viot.c | 112 +
 hw/arm/virt-acpi-build.c   |   7 +++
 hw/arm/virt.c  |  20 +++---
 hw/i386/acpi-build.c   |   5 ++
 hw/i386/pc.c   |  30 -
 hw/i386/x86-iommu.c|   6 --
 hw/virtio/virtio-iommu-pci.c   |   7 ---
 tests/qtest/bios-tables-test.c |  38 +++
 hw/acpi/Kconfig|   4 ++
 hw/acpi/meson.build|   1 +
 hw/arm/Kconfig |   1 +
 hw/i386/Kconfig|   1 +
 tests/data/acpi/q35/DSDT.viot  | Bin 0 -> 9398 bytes
 tests/data/acpi/q35/VIOT.viot  | Bin 0 -> 112 bytes
 tests/data/acpi/virt/VIOT  | Bin 0 -> 88 bytes
 17 files changed, 223 insertions(+), 24 deletions(-)
 create mode 100644 hw/acpi/viot.h
 create mode 100644 hw/acpi/viot.c
 create mode 100644 tests/data/acpi/q35/DSDT.viot
 create mode 100644 tests/data/acpi/q35/VIOT.viot
 create mode 100644 tests/data/acpi/virt/VIOT

-- 
2.33.0




[PATCH v4 10/11] tests/acpi: add expected blob for VIOT test on virt machine

2021-10-01 Thread Jean-Philippe Brucker
The VIOT blob contains the following:

[000h    4]Signature : "VIOT"[Virtual I/O 
Translation Table]
[004h 0004   4] Table Length : 0058
[008h 0008   1] Revision : 00
[009h 0009   1] Checksum : 66
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   2]   Node count : 0002
[026h 0038   2]  Node offset : 0030
[028h 0040   8] Reserved : 

[030h 0048   1] Type : 03 [VirtIO-PCI IOMMU]
[031h 0049   1] Reserved : 00
[032h 0050   2]   Length : 0010

[034h 0052   2]  PCI Segment : 
[036h 0054   2]   PCI BDF number : 0008
[038h 0056   8] Reserved : 

[040h 0064   1] Type : 01 [PCI Range]
[041h 0065   1] Reserved : 00
[042h 0066   2]   Length : 0018

[044h 0068   4]   Endpoint start : 
[048h 0072   2]PCI Segment start : 
[04Ah 0074   2]  PCI Segment end : 
[04Ch 0076   2]PCI BDF start : 
[04Eh 0078   2]  PCI BDF end : 00FF
[050h 0080   2]  Output node : 0030
[052h 0082   6] Reserved : 

Signed-off-by: Jean-Philippe Brucker 
---
 tests/qtest/bios-tables-test-allowed-diff.h |   1 -
 tests/data/acpi/virt/VIOT   | Bin 0 -> 88 bytes
 2 files changed, 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 29b5b1eabc..fa213e4738 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,4 +1,3 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/virt/VIOT",
 "tests/data/acpi/q35/DSDT.viot",
 "tests/data/acpi/q35/VIOT.viot",
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..921f40d88c28ba2171a4d664e119914335309e7d
 100644
GIT binary patch
literal 88
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
I{D-Rq0Q5fy0RR91

literal 0
HcmV?d1

-- 
2.33.0




[PATCH v3 23/41] target/arm: Implement arm_cpu_record_sigsegv

2021-10-01 Thread Richard Henderson
Because of the complexity of setting ESR, continue to use
arm_deliver_fault.  This means we cannot remove the code
within cpu_loop that decodes EXCP_DATA_ABORT and
EXCP_PREFETCH_ABORT.

But using the new hook means that we don't have to do the
page_get_flags check manually, and we'll be able to restrict
the tlb_fill hook to sysemu later.

Signed-off-by: Richard Henderson 
---
 target/arm/internals.h  |  6 ++
 target/arm/cpu.c|  6 --
 target/arm/cpu_tcg.c|  6 --
 target/arm/tlb_helper.c | 36 +++-
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 9fbb364968..984c84d27e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -544,9 +544,15 @@ static inline bool arm_extabort_type(MemTxResult result)
 return result != MEMTX_DECODE_ERROR;
 }
 
+#ifdef CONFIG_USER_ONLY
+void arm_cpu_record_sigsegv(CPUState *cpu, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr);
+#endif
 
 static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
 {
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 641a8c2d3d..7a18a58ca0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2031,10 +2031,12 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
 static const struct TCGCPUOps arm_tcg_ops = {
 .initialize = arm_translate_init,
 .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-.tlb_fill = arm_cpu_tlb_fill,
 .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = arm_cpu_record_sigsegv,
+#else
+.tlb_fill = arm_cpu_tlb_fill,
 .cpu_exec_interrupt = arm_cpu_exec_interrupt,
 .do_interrupt = arm_cpu_do_interrupt,
 .do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0d5adccf1a..7b3bea2fbb 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -898,10 +898,12 @@ static void pxa270c5_initfn(Object *obj)
 static const struct TCGCPUOps arm_v7m_tcg_ops = {
 .initialize = arm_translate_init,
 .synchronize_from_tb = arm_cpu_synchronize_from_tb,
-.tlb_fill = arm_cpu_tlb_fill,
 .debug_excp_handler = arm_debug_excp_handler,
 
-#if !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_USER_ONLY
+.record_sigsegv = arm_cpu_record_sigsegv,
+#else
+.tlb_fill = arm_cpu_tlb_fill,
 .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
 .do_interrupt = arm_v7m_cpu_do_interrupt,
 .do_transaction_failed = arm_cpu_do_transaction_failed,
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index 3107f9823e..dc5860180f 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -147,28 +147,12 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
 }
 
-#endif /* !defined(CONFIG_USER_ONLY) */
-
 bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr)
 {
 ARMCPU *cpu = ARM_CPU(cs);
 ARMMMUFaultInfo fi = {};
-
-#ifdef CONFIG_USER_ONLY
-int flags = page_get_flags(useronly_clean_ptr(address));
-if (flags & PAGE_VALID) {
-fi.type = ARMFault_Permission;
-} else {
-fi.type = ARMFault_Translation;
-}
-fi.level = 3;
-
-/* now we have a real cpu fault */
-cpu_restore_state(cs, retaddr, true);
-arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
-#else
 hwaddr phys_addr;
 target_ulong page_size;
 int prot, ret;
@@ -210,5 +194,23 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 cpu_restore_state(cs, retaddr, true);
 arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
 }
-#endif
 }
+#else
+void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra)
+{
+ARMMMUFaultInfo fi = {
+.type = maperr ? ARMFault_Translation : ARMFault_Permission,
+.level = 3,
+};
+ARMCPU *cpu = ARM_CPU(cs);
+
+/*
+ * We report both ESR and FAR to signal handlers.
+ * For now, it's easiest to deliver the fault normally.
+ */
+cpu_restore_state(cs, ra, true);
+arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi);
+}
+#endif /* !defined(CONFIG_USER_ONLY) */
-- 
2.25.1




[PATCH v3 39/41] target/sparc: Make sparc_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for sparc.

This makes all of the code in mmu_helper.c sysemu only, so remove
the ifdefs and move the file to sparc_softmmu_ss.  Remove the code
from cpu_loop that handled TT_DFAULT and TT_TFAULT.

Cc: Mark Cave-Ayland 
Signed-off-by: Richard Henderson 
---
 linux-user/sparc/cpu_loop.c | 25 -
 target/sparc/cpu.c  |  2 +-
 target/sparc/mmu_helper.c   | 25 -
 target/sparc/meson.build|  2 +-
 4 files changed, 2 insertions(+), 52 deletions(-)

diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index ad29b4eb6a..0ba65e431c 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -219,17 +219,6 @@ void cpu_loop (CPUSPARCState *env)
 case TT_WIN_UNF: /* window underflow */
 restore_window(env);
 break;
-case TT_TFAULT:
-case TT_DFAULT:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->mmuregs[4];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-break;
 #else
 case TT_SPILL: /* window overflow */
 save_window(env);
@@ -237,20 +226,6 @@ void cpu_loop (CPUSPARCState *env)
 case TT_FILL: /* window underflow */
 restore_window(env);
 break;
-case TT_TFAULT:
-case TT_DFAULT:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-if (trapnr == TT_DFAULT)
-info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
-else
-info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-break;
 #ifndef TARGET_ABI32
 case 0x16e:
 flush_windows(env);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 21dd27796d..55268ed2a1 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -865,9 +865,9 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
 static const struct TCGCPUOps sparc_tcg_ops = {
 .initialize = sparc_tcg_init,
 .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
-.tlb_fill = sparc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = sparc_cpu_tlb_fill,
 .cpu_exec_interrupt = sparc_cpu_exec_interrupt,
 .do_interrupt = sparc_cpu_do_interrupt,
 .do_transaction_failed = sparc_cpu_do_transaction_failed,
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index a44473a1c7..2ad47391d0 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -25,30 +25,6 @@
 
 /* Sparc MMU emulation */
 
-#if defined(CONFIG_USER_ONLY)
-
-bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
-{
-SPARCCPU *cpu = SPARC_CPU(cs);
-CPUSPARCState *env = &cpu->env;
-
-if (access_type == MMU_INST_FETCH) {
-cs->exception_index = TT_TFAULT;
-} else {
-cs->exception_index = TT_DFAULT;
-#ifdef TARGET_SPARC64
-env->dmmu.mmuregs[4] = address;
-#else
-env->mmuregs[4] = address;
-#endif
-}
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else
-
 #ifndef TARGET_SPARC64
 /*
  * Sparc V8 Reference MMU (SRMMU)
@@ -926,4 +902,3 @@ hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 }
 return phys_addr;
 }
-#endif
diff --git a/target/sparc/meson.build b/target/sparc/meson.build
index a3638b9503..a801802ee2 100644
--- a/target/sparc/meson.build
+++ b/target/sparc/meson.build
@@ -6,7 +6,6 @@ sparc_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'ldst_helper.c',
-  'mmu_helper.c',
   'translate.c',
   'win_helper.c',
 ))
@@ -16,6 +15,7 @@ sparc_ss.add(when: 'TARGET_SPARC64', if_true: 
files('int64_helper.c', 'vis_helpe
 sparc_softmmu_ss = ss.source_set()
 sparc_softmmu_ss.add(files(
   'machine.c',
+  'mmu_helper.c',
   'monitor.c',
 ))
 
-- 
2.25.1




[PATCH v4 04/11] hw/arm/virt: Reject instantiation of multiple IOMMUs

2021-10-01 Thread Jean-Philippe Brucker
We do not support instantiating multiple IOMMUs. Before adding a
virtio-iommu, check that no other IOMMU is present. This will detect
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.

Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
Reviewed-by: Eric Auger 
Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/virt.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 56e8fc7059..36f0261ef4 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2441,6 +2441,11 @@ static void 
virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 hwaddr db_start = 0, db_end = 0;
 char *resv_prop_str;
 
+if (vms->iommu != VIRT_IOMMU_NONE) {
+error_setg(errp, "virt machine does not support multiple IOMMUs");
+return;
+}
+
 switch (vms->msi_controller) {
 case VIRT_MSI_CTRL_NONE:
 return;
-- 
2.33.0




[PATCH v3 35/41] target/riscv: Make riscv_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for riscv.
Remove the code from cpu_loop that raised SIGSEGV.

Cc: qemu-ri...@nongnu.org
Signed-off-by: Richard Henderson 
---
 linux-user/riscv/cpu_loop.c |  7 ---
 target/riscv/cpu.c  |  2 +-
 target/riscv/cpu_helper.c   | 21 +
 3 files changed, 2 insertions(+), 28 deletions(-)

diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 9859a366e4..aef019b1c8 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -87,13 +87,6 @@ void cpu_loop(CPURISCVState *env)
 sigcode = TARGET_TRAP_BRKPT;
 sigaddr = env->pc;
 break;
-case RISCV_EXCP_INST_PAGE_FAULT:
-case RISCV_EXCP_LOAD_PAGE_FAULT:
-case RISCV_EXCP_STORE_PAGE_FAULT:
-signum = TARGET_SIGSEGV;
-sigcode = TARGET_SEGV_MAPERR;
-sigaddr = env->badaddr;
-break;
 case RISCV_EXCP_SEMIHOST:
 env->gpr[xA0] = do_common_semihosting(cs);
 env->pc += 4;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c626d89cd..0292a72feb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -675,9 +675,9 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
 static const struct TCGCPUOps riscv_tcg_ops = {
 .initialize = riscv_translate_init,
 .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
-.tlb_fill = riscv_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = riscv_cpu_tlb_fill,
 .cpu_exec_interrupt = riscv_cpu_exec_interrupt,
 .do_interrupt = riscv_cpu_do_interrupt,
 .do_transaction_failed = riscv_cpu_do_transaction_failed,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index d41d5cd27c..b520d6fc78 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -748,7 +748,6 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 riscv_cpu_two_stage_lookup(mmu_idx);
 riscv_raise_exception(env, cs->exception_index, retaddr);
 }
-#endif /* !CONFIG_USER_ONLY */
 
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
@@ -756,7 +755,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = &cpu->env;
-#ifndef CONFIG_USER_ONLY
 vaddr im_address;
 hwaddr pa = 0;
 int prot, prot2, prot_pmp;
@@ -888,25 +886,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 
 return true;
-
-#else
-switch (access_type) {
-case MMU_INST_FETCH:
-cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
-break;
-case MMU_DATA_LOAD:
-cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
-break;
-case MMU_DATA_STORE:
-cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
-break;
-default:
-g_assert_not_reached();
-}
-env->badaddr = address;
-cpu_loop_exit_restore(cs, retaddr);
-#endif
 }
+#endif /* !CONFIG_USER_ONLY */
 
 /*
  * Handle Traps
-- 
2.25.1




[PATCH v3 20/41] linux-user: Add cpu_loop_exit_segv

2021-10-01 Thread Richard Henderson
This is a new interface to be provided by the os emulator for
raising SIGSEGV on fault.  Use the new record_sigsegv target hook.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 15 +++
 accel/tcg/user-exec.c   | 33 ++---
 linux-user/signal.c | 30 ++
 3 files changed, 55 insertions(+), 23 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5dd663c153..14e554d27d 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,6 +685,21 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
  uintptr_t host_pc, abi_ptr guest_addr);
 
+/**
+ * cpu_loop_exit_segv:
+ * @cpu: the cpu context
+ * @addr: the guest address of the fault
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGSEGV, and jump to the main cpu loop.
+ */
+void QEMU_NORETURN cpu_loop_exit_segv(CPUState *cpu, target_ulong addr,
+  MMUAccessType access_type,
+  bool maperr, uintptr_t ra);
+
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 01e7e69e7f..1fd38ea624 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -143,35 +143,38 @@ static int probe_access_internal(CPUArchState *env, 
target_ulong addr,
  int fault_size, MMUAccessType access_type,
  bool nonfault, uintptr_t ra)
 {
-int flags;
+int acc_flag;
+bool maperr;
 
 switch (access_type) {
 case MMU_DATA_STORE:
-flags = PAGE_WRITE;
+acc_flag = PAGE_WRITE_ORG;
 break;
 case MMU_DATA_LOAD:
-flags = PAGE_READ;
+acc_flag = PAGE_READ;
 break;
 case MMU_INST_FETCH:
-flags = PAGE_EXEC;
+acc_flag = PAGE_EXEC;
 break;
 default:
 g_assert_not_reached();
 }
 
-if (!guest_addr_valid_untagged(addr) ||
-page_check_range(addr, 1, flags) < 0) {
-if (nonfault) {
-return TLB_INVALID_MASK;
-} else {
-CPUState *cpu = env_cpu(env);
-CPUClass *cc = CPU_GET_CLASS(cpu);
-cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type,
-  MMU_USER_IDX, false, ra);
-g_assert_not_reached();
+if (guest_addr_valid_untagged(addr)) {
+int page_flags = page_get_flags(addr);
+if (page_flags & acc_flag) {
+return 0; /* success */
 }
+maperr = !(page_flags & PAGE_VALID);
+} else {
+maperr = true;
 }
-return 0;
+
+if (nonfault) {
+return TLB_INVALID_MASK;
+}
+
+cpu_loop_exit_segv(env_cpu(env), addr, access_type, maperr, ra);
 }
 
 int probe_access_flags(CPUArchState *env, target_ulong addr,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 537c6c41c0..8c22f711f1 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -685,9 +685,27 @@ void force_sigsegv(int oldsig)
 }
 force_sig(TARGET_SIGSEGV);
 }
-
 #endif
 
+void cpu_loop_exit_segv(CPUState *cpu, target_ulong addr,
+MMUAccessType access_type, bool maperr, uintptr_t ra)
+{
+const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
+
+if (tcg_ops->record_sigsegv) {
+tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
+} else if (tcg_ops->tlb_fill) {
+tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
+g_assert_not_reached();
+}
+
+force_sig_fault(TARGET_SIGSEGV,
+maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
+addr);
+cpu->exception_index = EXCP_INTERRUPT;
+cpu_loop_exit_restore(cpu, ra);
+}
+
 /* abort execution with signal */
 static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 {
@@ -803,7 +821,7 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 access_type = adjust_signal_pc(&pc, is_write);
 
 if (host_sig == SIGSEGV) {
-const struct TCGCPUOps *tcg_ops;
+bool maperr = true;
 
 if (info->si_code == SEGV_ACCERR && h2g_valid(host_addr)) {
 /* If this was a write to a TB protected page, restart. */
@@ -818,18 +836,14 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
  * which means that we may get ACCERR when we want MAPERR.
  */
 if (page_get_flags(guest_addr) & PAG

[PATCH v3 38/41] target/sh4: Make sh4_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for sh4.
Remove the code from cpu_loop that raised SIGSEGV.

Cc: Yoshinori Sato 
Signed-off-by: Richard Henderson 
---
 target/sh4/cpu.h  | 6 +++---
 linux-user/sh4/cpu_loop.c | 8 
 target/sh4/cpu.c  | 2 +-
 target/sh4/helper.c   | 9 +
 4 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index dc81406646..4cfb109f56 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -213,12 +213,12 @@ void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr 
addr,
 uintptr_t retaddr) QEMU_NORETURN;
 
 void sh4_translate_init(void);
+void sh4_cpu_list(void);
+
+#if !defined(CONFIG_USER_ONLY)
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
-
-void sh4_cpu_list(void);
-#if !defined(CONFIG_USER_ONLY)
 void superh_cpu_do_interrupt(CPUState *cpu);
 bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index 65b8972e3c..ac9b01840c 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -65,14 +65,6 @@ void cpu_loop(CPUSH4State *env)
 info.si_code = TARGET_TRAP_BRKPT;
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 break;
-case 0xa0:
-case 0xc0:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->tea;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_ATOMIC:
 cpu_exec_step_atomic(cs);
 arch_interrupt = false;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 2047742d03..06b2691dc4 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -236,9 +236,9 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
 static const struct TCGCPUOps superh_tcg_ops = {
 .initialize = sh4_translate_init,
 .synchronize_from_tb = superh_cpu_synchronize_from_tb,
-.tlb_fill = superh_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = superh_cpu_tlb_fill,
 .cpu_exec_interrupt = superh_cpu_exec_interrupt,
 .do_interrupt = superh_cpu_do_interrupt,
 .do_unaligned_access = superh_cpu_do_unaligned_access,
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 53cb9c3b63..6a620e36fc 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -796,8 +796,6 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 return false;
 }
 
-#endif /* !CONFIG_USER_ONLY */
-
 bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr)
@@ -806,11 +804,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 CPUSH4State *env = &cpu->env;
 int ret;
 
-#ifdef CONFIG_USER_ONLY
-ret = (access_type == MMU_DATA_STORE ? MMU_DTLB_VIOLATION_WRITE :
-   access_type == MMU_INST_FETCH ? MMU_ITLB_VIOLATION :
-   MMU_DTLB_VIOLATION_READ);
-#else
 target_ulong physical;
 int prot;
 
@@ -829,7 +822,6 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) {
 env->pteh = (env->pteh & PTEH_ASID_MASK) | (address & PTEH_VPN_MASK);
 }
-#endif
 
 env->tea = address;
 switch (ret) {
@@ -868,3 +860,4 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
-- 
2.25.1




[PATCH v3 34/41] target/ppc: Implement ppc_cpu_record_sigsegv

2021-10-01 Thread Richard Henderson
Record DAR, DSISR, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

This is exactly what the user-mode ppc_cpu_tlb_fill does,
so simply rename it as ppc_cpu_record_sigsegv.

Cc: qemu-...@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h  |  3 ---
 target/ppc/internal.h |  9 +
 target/ppc/cpu_init.c |  6 --
 target/ppc/user_only_helper.c | 15 +++
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 01d3773bc7..60d1117845 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1278,9 +1278,6 @@ extern const VMStateDescription vmstate_ppc_cpu;
 
 /*/
 void ppc_translate_init(void);
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index 55284369f5..339974b7d8 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -283,5 +283,14 @@ static inline void pte_invalidate(target_ulong *pte0)
 #define PTE_PTEM_MASK 0x7FBF
 #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
 
+#ifdef CONFIG_USER_ONLY
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
+#endif
 
 #endif /* PPC_INTERNAL_H */
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6aad01d1d3..ec8da08f0b 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -9014,9 +9014,11 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
 
 static const struct TCGCPUOps ppc_tcg_ops = {
   .initialize = ppc_translate_init,
-  .tlb_fill = ppc_cpu_tlb_fill,
 
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+  .record_sigsegv = ppc_cpu_record_sigsegv,
+#else
+  .tlb_fill = ppc_cpu_tlb_fill,
   .cpu_exec_interrupt = ppc_cpu_exec_interrupt,
   .do_interrupt = ppc_cpu_do_interrupt,
   .cpu_exec_enter = ppc_cpu_exec_enter,
diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c
index aa3f867596..7ff76f7a06 100644
--- a/target/ppc/user_only_helper.c
+++ b/target/ppc/user_only_helper.c
@@ -21,16 +21,23 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
+#include "internal.h"
 
-
-bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr)
+void ppc_cpu_record_sigsegv(CPUState *cs, vaddr address,
+MMUAccessType access_type,
+bool maperr, uintptr_t retaddr)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
 CPUPPCState *env = &cpu->env;
 int exception, error_code;
 
+/*
+ * Both DSISR and the "trap number" (exception vector offset,
+ * looked up from exception_index) are present in the linux-user
+ * signal frame.
+ * FIXME: we don't actually populate the trap number properly.
+ * It would be easiest to fill in an env->trap value now.
+ */
 if (access_type == MMU_INST_FETCH) {
 exception = POWERPC_EXCP_ISI;
 error_code = 0x4000;
-- 
2.25.1




[PATCH v3 26/41] target/hppa: Make hppa_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for hppa-linux-user.
Remove the code from cpu_loop that raised SIGSEGV.

This makes all of the code in mem_helper.c sysemu only, so remove the
ifdefs and move the file to hppa_softmmu_ss.

Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h  |  2 +-
 linux-user/hppa/cpu_loop.c | 16 
 target/hppa/cpu.c  |  2 +-
 target/hppa/mem_helper.c   | 15 ---
 target/hppa/meson.build|  6 --
 5 files changed, 6 insertions(+), 35 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index d3cb7a279f..294fd7297f 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -323,10 +323,10 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr);
 int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
+#ifndef CONFIG_USER_ONLY
 bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 81607a9b27..e0a62deeb9 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -144,22 +144,6 @@ void cpu_loop(CPUHPPAState *env)
 env->iaoq_f = env->gr[31];
 env->iaoq_b = env->gr[31] + 4;
 break;
-case EXCP_ITLB_MISS:
-case EXCP_DTLB_MISS:
-case EXCP_NA_ITLB_MISS:
-case EXCP_NA_DTLB_MISS:
-case EXCP_IMP:
-case EXCP_DMP:
-case EXCP_DMB:
-case EXCP_PAGE_REF:
-case EXCP_DMAR:
-case EXCP_DMPI:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_ACCERR;
-info._sifields._sigfault._addr = env->cr[CR_IOR];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_UNALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 89cba9d7a2..23eb254228 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -145,9 +145,9 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
 static const struct TCGCPUOps hppa_tcg_ops = {
 .initialize = hppa_translate_init,
 .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
-.tlb_fill = hppa_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = hppa_cpu_tlb_fill,
 .cpu_exec_interrupt = hppa_cpu_exec_interrupt,
 .do_interrupt = hppa_cpu_do_interrupt,
 .do_unaligned_access = hppa_cpu_do_unaligned_access,
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index afc5b56c3e..bf07445cd1 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -24,20 +24,6 @@
 #include "hw/core/cpu.h"
 #include "trace.h"
 
-#ifdef CONFIG_USER_ONLY
-bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
-{
-HPPACPU *cpu = HPPA_CPU(cs);
-
-/* ??? Test between data page fault and data memory protection trap,
-   which would affect si_code.  */
-cs->exception_index = EXCP_DMP;
-cpu->env.cr[CR_IOR] = address;
-cpu_loop_exit_restore(cs, retaddr);
-}
-#else
 static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
 {
 int i;
@@ -392,4 +378,3 @@ int hppa_artype_for_page(CPUHPPAState *env, target_ulong 
vaddr)
 hppa_tlb_entry *ent = hppa_find_tlb(env, vaddr);
 return ent ? ent->ar_type : -1;
 }
-#endif /* CONFIG_USER_ONLY */
diff --git a/target/hppa/meson.build b/target/hppa/meson.build
index 8a7ff82efc..021e42a2d0 100644
--- a/target/hppa/meson.build
+++ b/target/hppa/meson.build
@@ -7,13 +7,15 @@ hppa_ss.add(files(
   'gdbstub.c',
   'helper.c',
   'int_helper.c',
-  'mem_helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 hppa_softmmu_ss = ss.source_set()
-hppa_softmmu_ss.add(files('machine.c'))
+hppa_softmmu_ss.add(files(
+  'machine.c',
+  'mem_helper.c',
+))
 
 target_arch += {'hppa': hppa_ss}
 target_softmmu_arch += {'hppa': hppa_softmmu_ss}
-- 
2.25.1




[PATCH v3 14/41] linux-user/host/mips: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/mips/host-signal.h | 62 +-
 accel/tcg/user-exec.c  | 52 +
 2 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/linux-user/host/mips/host-signal.h 
b/linux-user/host/mips/host-signal.h
index f4b4d65031..9c83e51130 100644
--- a/linux-user/host/mips/host-signal.h
+++ b/linux-user/host/mips/host-signal.h
@@ -1 +1,61 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef MIPS_HOST_SIGNAL_H
+#define MIPS_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.pc;
+}
+
+#if defined(__misp16) || defined(__mips_micromips)
+#error "Unsupported encoding"
+#endif
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+/* Detect all store instructions at program counter. */
+switch ((insn >> 26) & 077) {
+case 050: /* SB */
+case 051: /* SH */
+case 052: /* SWL */
+case 053: /* SW */
+case 054: /* SDL */
+case 055: /* SDR */
+case 056: /* SWR */
+case 070: /* SC */
+case 071: /* SWC1 */
+case 074: /* SCD */
+case 075: /* SDC1 */
+case 077: /* SD */
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
+case 072: /* SWC2 */
+case 076: /* SDC2 */
+#endif
+return true;
+case 023: /* COP1X */
+/*
+ * Required in all versions of MIPS64 since
+ * MIPS64r1 and subsequent versions of MIPS32r2.
+ */
+switch (insn & 077) {
+case 010: /* SWXC1 */
+case 011: /* SDXC1 */
+case 015: /* SUXC1 */
+return true;
+}
+break;
+}
+return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 0810b71ba0..42d1ad189b 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,57 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__mips__)
-
-#if defined(__misp16) || defined(__mips_micromips)
-#error "Unsupported encoding"
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-uintptr_t pc = uc->uc_mcontext.pc;
-uint32_t insn = *(uint32_t *)pc;
-int is_write = 0;
-
-/* Detect all store instructions at program counter. */
-switch((insn >> 26) & 077) {
-case 050: /* SB */
-case 051: /* SH */
-case 052: /* SWL */
-case 053: /* SW */
-case 054: /* SDL */
-case 055: /* SDR */
-case 056: /* SWR */
-case 070: /* SC */
-case 071: /* SWC1 */
-case 074: /* SCD */
-case 075: /* SDC1 */
-case 077: /* SD */
-#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
-case 072: /* SWC2 */
-case 076: /* SDC2 */
-#endif
-is_write = 1;
-break;
-case 023: /* COP1X */
-/* Required in all versions of MIPS64 since
-   MIPS64r1 and subsequent versions of MIPS32r2. */
-switch (insn & 077) {
-case 010: /* SWXC1 */
-case 011: /* SDXC1 */
-case 015: /* SUXC1 */
-is_write = 1;
-}
-break;
-}
-
-return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__riscv)
+#if defined(__riscv)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
-- 
2.25.1




[PATCH v3 33/41] target/openrisc: Make openrisc_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for openrisc.
This makes all of the code in mmu.c sysemu only, so remove
the ifdefs and move the file to openrisc_softmmu_ss.
Remove the code from cpu_loop that handled EXCP_DPF.

Cc: Stafford Horne 
Signed-off-by: Richard Henderson 
---
 target/openrisc/cpu.h  | 7 ---
 linux-user/openrisc/cpu_loop.c | 8 
 target/openrisc/cpu.c  | 2 +-
 target/openrisc/mmu.c  | 8 
 target/openrisc/meson.build| 2 +-
 5 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 187a4a114e..ee069b080c 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -317,14 +317,15 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, 
vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
-bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 int print_insn_or1k(bfd_vma addr, disassemble_info *info);
 
 #define cpu_list cpu_openrisc_list
 
 #ifndef CONFIG_USER_ONLY
+bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+
 extern const VMStateDescription vmstate_openrisc_cpu;
 
 void openrisc_cpu_do_interrupt(CPUState *cpu);
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index de5417a262..fb37fb7651 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -54,14 +54,6 @@ void cpu_loop(CPUOpenRISCState *env)
 cpu_set_gpr(env, 11, ret);
 }
 break;
-case EXCP_DPF:
-case EXCP_IPF:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_RANGE:
 case EXCP_FPE:
 /* ??? The kernel vectors both of these to unhandled_exception. */
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 27cb04152f..dfbafc5236 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -186,9 +186,9 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
 
 static const struct TCGCPUOps openrisc_tcg_ops = {
 .initialize = openrisc_translate_init,
-.tlb_fill = openrisc_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = openrisc_cpu_tlb_fill,
 .cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
 .do_interrupt = openrisc_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 94df8c7bef..91cedf4125 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -23,11 +23,8 @@
 #include "exec/exec-all.h"
 #include "exec/gdbstub.h"
 #include "qemu/host-utils.h"
-#ifndef CONFIG_USER_ONLY
 #include "hw/loader.h"
-#endif
 
-#ifndef CONFIG_USER_ONLY
 static inline void get_phys_nommu(hwaddr *phys_addr, int *prot,
   target_ulong address)
 {
@@ -94,7 +91,6 @@ static int get_phys_mmu(OpenRISCCPU *cpu, hwaddr *phys_addr, 
int *prot,
 return need & PAGE_EXEC ? EXCP_ITLBMISS : EXCP_DTLBMISS;
 }
 }
-#endif
 
 static void raise_mmu_exception(OpenRISCCPU *cpu, target_ulong address,
 int exception)
@@ -113,7 +109,6 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int 
size,
 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
 int excp = EXCP_DPF;
 
-#ifndef CONFIG_USER_ONLY
 int prot;
 hwaddr phys_addr;
 
@@ -138,13 +133,11 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int 
size,
 if (probe) {
 return false;
 }
-#endif
 
 raise_mmu_exception(cpu, addr, excp);
 cpu_loop_exit_restore(cs, retaddr);
 }
 
-#ifndef CONFIG_USER_ONLY
 hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
@@ -177,4 +170,3 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return phys_addr;
 }
 }
-#endif
diff --git a/target/openrisc/meson.build b/target/openrisc/meson.build
index e445dec4a0..84322086ec 100644
--- a/target/openrisc/meson.build
+++ b/target/openrisc/meson.build
@@ -10,7 +10,6 @@ openrisc_ss.add(files(
   'fpu_helper.c',
   'gdbstub.c',
   'interrupt_helper.c',
-  'mmu.c',
   'sys_helper.c',
   'translate.c',
 ))
@@ -19,6 +18,7 @@ openrisc_softmmu_ss = ss.source_set()
 openrisc_softmmu_ss.add(files(
   'interrupt.c',
   'machine.c',
+  'mmu.c',
 ))
 
 target_arch += {'openrisc': openrisc_ss}
-- 
2.25.1




[PATCH v3 24/41] target/cris: Make cris_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for cris-linux-user.
Remove the code from cpu_loop that handled the unnamed 0xaa exception.

This makes all of the code in helper.c sysemu only, so remove the
ifdefs and move the file to cris_softmmu_ss.

Cc: Edgar E. Iglesias 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/cris/cpu.h  |  8 
 linux-user/cris/cpu_loop.c | 10 --
 target/cris/cpu.c  |  4 ++--
 target/cris/helper.c   | 18 --
 target/cris/meson.build|  7 +--
 5 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 6603565f83..b445b194ea 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -189,6 +189,10 @@ extern const VMStateDescription vmstate_cris_cpu;
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
 bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 #endif
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);
@@ -251,10 +255,6 @@ static inline int cpu_mmu_index (CPUCRISState *env, bool 
ifetch)
return !!(env->pregs[PR_CCS] & U_FLAG);
 }
 
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
-
 /* Support function regs.  */
 #define SFR_RW_GC_CFG  0][0
 #define SFR_RW_MM_CFG  env->pregs[PR_SRS]][0
diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index b9085619c4..0d5d268609 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -37,16 +37,6 @@ void cpu_loop(CPUCRISState *env)
 process_queued_cpu_work(cs);
 
 switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->pregs[PR_EDA];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-break;
 case EXCP_INTERRUPT:
   /* just indicate that signals should be handled asap */
   break;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index c2e7483f5b..ed6c781342 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -205,9 +205,9 @@ static const struct SysemuCPUOps cris_sysemu_ops = {
 
 static const struct TCGCPUOps crisv10_tcg_ops = {
 .initialize = cris_initialize_crisv10_tcg,
-.tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = cris_cpu_tlb_fill,
 .cpu_exec_interrupt = cris_cpu_exec_interrupt,
 .do_interrupt = crisv10_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
@@ -215,9 +215,9 @@ static const struct TCGCPUOps crisv10_tcg_ops = {
 
 static const struct TCGCPUOps crisv32_tcg_ops = {
 .initialize = cris_initialize_tcg,
-.tlb_fill = cris_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = cris_cpu_tlb_fill,
 .cpu_exec_interrupt = cris_cpu_exec_interrupt,
 .do_interrupt = cris_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 36926faf32..a0d6ecdcd3 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -39,22 +39,6 @@
 #define D_LOG(...) do { } while (0)
 #endif
 
-#if defined(CONFIG_USER_ONLY)
-
-bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr)
-{
-CRISCPU *cpu = CRIS_CPU(cs);
-
-cs->exception_index = 0xaa;
-cpu->env.pregs[PR_EDA] = address;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
-
 static void cris_shift_ccs(CPUCRISState *env)
 {
 uint32_t ccs;
@@ -304,5 +288,3 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 return ret;
 }
-
-#endif /* !CONFIG_USER_ONLY */
diff --git a/target/cris/meson.build b/target/cris/meson.build
index 67c3793c85..c1e326d950 100644
--- a/target/cris/meson.build
+++ b/target/cris/meson.build
@@ -2,13 +2,16 @@ cris_ss = ss.source_set()
 cris_ss.add(files(
   'cpu.c',
   'gdbstub.c',
-  'helper.c',
   'op_helper.c',
   'translate.c',
 ))
 
 cris_softmmu_ss = ss.source_set()
-cris_softmmu_ss.add(files('mmu.c', 'machine.c'))
+cris_softmmu_ss.add(files(
+  'helper.c',
+  'machine.c',
+  'mmu.c',
+))
 
 target_arch += {'cris': cris_ss}
 target_softmmu_arch += {'cris': cris_softmmu_ss}
-- 
2.25.1




[PATCH v3 16/41] target/arm: Fixup comment re handle_cpu_signal

2021-10-01 Thread Richard Henderson
The named function no longer exists.
Refer to host_signal_handler instead.

Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index dab5f1d1cd..07be55b7e1 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -6118,7 +6118,7 @@ DO_LDN_2(4, dd, MO_64)
  * linux-user/ in its get_user/put_user macros.
  *
  * TODO: Construct some helpers, written in assembly, that interact with
- * handle_cpu_signal to produce memory ops which can properly report errors
+ * host_signal_handler to produce memory ops which can properly report errors
  * without racing.
  */
 
-- 
2.25.1




Re: [PATCH v12 16/16] machine: Make smp_parse return a boolean

2021-10-01 Thread Daniel P . Berrangé
On Fri, Oct 01, 2021 at 07:08:51PM +0200, Paolo Bonzini wrote:
> On 29/09/21 04:58, Yanan Wang wrote:
> > @@ -933,8 +935,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> > const char *name,
> >   return;
> >   }
> > -smp_parse(ms, config, errp);
> > -if (*errp) {
> > +if (!smp_parse(ms, config, errp)) {
> >   qapi_free_SMPConfiguration(config);
> >   }
> >   }
> > 
> 
> This is actually a leak, so I'm replacing this patch with

This patch isn't adding a leak, as there's no change in
control flow / exit paths.  AFAICT, the leak was introduced
in patch 15 instead, so the code below shoudl be squashed
into that, and this patch left as-is.

> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 54f04a5ac6..d49ebc24e2 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -897,7 +897,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> const char *name,
>  {
>  MachineClass *mc = MACHINE_GET_CLASS(obj);
>  MachineState *ms = MACHINE(obj);
> -SMPConfiguration *config;
> +g_autoptr(SMPConfiguration) config = NULL;
>  ERRP_GUARD();
>  if (!visit_type_SMPConfiguration(v, name, &config, errp)) {
> @@ -920,7 +920,7 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> const char *name,
>  smp_parse(ms, config, errp);
>  if (*errp) {
> -goto out_free;
> +return;
>  }
>  /* sanity-check smp_cpus and max_cpus against mc */
> @@ -935,9 +935,6 @@ static void machine_set_smp(Object *obj, Visitor *v, 
> const char *name,
> ms->smp.max_cpus,
> mc->name, mc->max_cpus);
>  }
> -
> -out_free:
> -qapi_free_SMPConfiguration(config);
>  }
>  static void machine_class_init(ObjectClass *oc, void *data)
> 
> which removes the need.

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




[PATCH v3 22/41] target/arm: Use cpu_loop_exit_segv for mte tag lookup

2021-10-01 Thread Richard Henderson
Use the new os interface for raising the exception,
rather than calling arm_cpu_tlb_fill directly.

Signed-off-by: Richard Henderson 
---
 target/arm/mte_helper.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 724175210b..1500a498b0 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -84,10 +84,8 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int 
ptr_mmu_idx,
 uintptr_t index;
 
 if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE_ORG : 
PAGE_READ))) {
-/* SIGSEGV */
-arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
- ptr_mmu_idx, false, ra);
-g_assert_not_reached();
+cpu_loop_exit_segv(env_cpu(env), ptr, ptr_access,
+   !(flags & PAGE_VALID), ra);
 }
 
 /* Require both MAP_ANON and PROT_MTE for the page. */
-- 
2.25.1




[PATCH v3 13/41] linux-user/host/s390: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/s390/host-signal.h  | 93 -
 linux-user/host/s390x/host-signal.h |  2 +-
 accel/tcg/user-exec.c   | 88 +--
 3 files changed, 94 insertions(+), 89 deletions(-)

diff --git a/linux-user/host/s390/host-signal.h 
b/linux-user/host/s390/host-signal.h
index f4b4d65031..21f59b612a 100644
--- a/linux-user/host/s390/host-signal.h
+++ b/linux-user/host/s390/host-signal.h
@@ -1 +1,92 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef S390_HOST_SIGNAL_H
+#define S390_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.psw.addr;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
+
+/*
+ * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
+ * of the normal 2 arguments.  The 4th argument contains the "Translation-
+ * Exception Identification for DAT Exceptions" from the hardware (aka
+ * "int_parm_long"), which does in fact contain the is_write value.
+ * The rt signal handler, as far as I can tell, does not give this value
+ * at all.  Not that we could get to it from here even if it were.
+ * So fall back to parsing instructions.  Treat read-modify-write ones as
+ * writes, which is not fully correct, but for tracking self-modifying code
+ * this is better than treating them as reads.  Checking si_addr page flags
+ * might be a viable improvement, albeit a racy one.
+ */
+/* ??? This is not even close to complete.  */
+switch (pinsn[0] >> 8) {
+case 0x50: /* ST */
+case 0x42: /* STC */
+case 0x40: /* STH */
+case 0xba: /* CS */
+case 0xbb: /* CDS */
+return true;
+case 0xc4: /* RIL format insns */
+switch (pinsn[0] & 0xf) {
+case 0xf: /* STRL */
+case 0xb: /* STGRL */
+case 0x7: /* STHRL */
+return true;
+}
+break;
+case 0xc8: /* SSF format insns */
+switch (pinsn[0] & 0xf) {
+case 0x2: /* CSST */
+return true;
+}
+break;
+case 0xe3: /* RXY format insns */
+switch (pinsn[2] & 0xff) {
+case 0x50: /* STY */
+case 0x24: /* STG */
+case 0x72: /* STCY */
+case 0x70: /* STHY */
+case 0x8e: /* STPQ */
+case 0x3f: /* STRVH */
+case 0x3e: /* STRV */
+case 0x2f: /* STRVG */
+return true;
+}
+break;
+case 0xeb: /* RSY format insns */
+switch (pinsn[2] & 0xff) {
+case 0x14: /* CSY */
+case 0x30: /* CSG */
+case 0x31: /* CDSY */
+case 0x3e: /* CDSG */
+case 0xe4: /* LANG */
+case 0xe6: /* LAOG */
+case 0xe7: /* LAXG */
+case 0xe8: /* LAAG */
+case 0xea: /* LAALG */
+case 0xf4: /* LAN */
+case 0xf6: /* LAO */
+case 0xf7: /* LAX */
+case 0xfa: /* LAAL */
+case 0xf8: /* LAA */
+return true;
+}
+break;
+}
+return false;
+}
+
+#endif
diff --git a/linux-user/host/s390x/host-signal.h 
b/linux-user/host/s390x/host-signal.h
index f4b4d65031..0e83f9358d 100644
--- a/linux-user/host/s390x/host-signal.h
+++ b/linux-user/host/s390x/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../s390/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 8f4e788304..0810b71ba0 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,93 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-unsigned long pc;
-uint16_t *pinsn;
-int is_write = 0;
-
-pc = uc->uc_mcontext.psw.addr;
-
-/*
- * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
- * of the normal 2 arguments.  The 4th argument contains the "Translation-
- * Exception Identification for DAT Exceptions" from the hardware (aka
- * "int_parm_long"), which does in fact contain the is_write value.
- * The rt signal handler, as far as I can tell, does not give this value
- * at all.  Not that we could get to it from here even if it were.
- * So fall back to parsing instructions.  Treat read-modify-write ones as
- * writes, which is not fully correct, but for tracking self

[PATCH v3 32/41] linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE

2021-10-01 Thread Richard Henderson
The kernel vectors both of these through unhandled_exception, which
results in force_sig(SIGSEGV).  This isn't very useful for userland
when enabling overflow traps or fpu traps, but c'est la vie.

Cc: Stafford Horne 
Signed-off-by: Richard Henderson 
---
 linux-user/openrisc/cpu_loop.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index f6360db47c..de5417a262 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -56,13 +56,17 @@ void cpu_loop(CPUOpenRISCState *env)
 break;
 case EXCP_DPF:
 case EXCP_IPF:
-case EXCP_RANGE:
 info.si_signo = TARGET_SIGSEGV;
 info.si_errno = 0;
 info.si_code = TARGET_SEGV_MAPERR;
 info._sifields._sigfault._addr = env->pc;
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 break;
+case EXCP_RANGE:
+case EXCP_FPE:
+/* ??? The kernel vectors both of these to unhandled_exception. */
+force_sig(TARGET_SIGSEGV);
+break;
 case EXCP_ALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
@@ -77,13 +81,6 @@ void cpu_loop(CPUOpenRISCState *env)
 info._sifields._sigfault._addr = env->pc;
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 break;
-case EXCP_FPE:
-info.si_signo = TARGET_SIGFPE;
-info.si_errno = 0;
-info.si_code = 0;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_INTERRUPT:
 /* We processed the pending cpu work above.  */
 break;
-- 
2.25.1




[PATCH v3 40/41] target/xtensa: Make xtensa_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for xtensa.
Remove the code from cpu_loop that raised SIGSEGV.

Cc: Max Filippov 
Signed-off-by: Richard Henderson 
---
 target/xtensa/cpu.h  |  2 +-
 linux-user/xtensa/cpu_loop.c |  9 -
 target/xtensa/cpu.c  |  2 +-
 target/xtensa/helper.c   | 22 +-
 4 files changed, 3 insertions(+), 32 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index f9a510ca46..02143f2f77 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -563,10 +563,10 @@ struct XtensaCPU {
 };
 
 
+#ifndef CONFIG_USER_ONLY
 bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
-#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr 
addr,
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index 622afbcd34..a83490ab35 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -226,15 +226,6 @@ void cpu_loop(CPUXtensaState *env)
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 break;
 
-case LOAD_PROHIBITED_CAUSE:
-case STORE_PROHIBITED_CAUSE:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_ACCERR;
-info._sifields._sigfault._addr = env->sregs[EXCVADDR];
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
-
 default:
 fprintf(stderr, "exccause = %d\n", env->sregs[EXCCAUSE]);
 g_assert_not_reached();
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index c1cbd03595..224f723236 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -192,10 +192,10 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
 
 static const struct TCGCPUOps xtensa_tcg_ops = {
 .initialize = xtensa_translate_init,
-.tlb_fill = xtensa_cpu_tlb_fill,
 .debug_excp_handler = xtensa_breakpoint_handler,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = xtensa_cpu_tlb_fill,
 .cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
 .do_interrupt = xtensa_cpu_do_interrupt,
 .do_transaction_failed = xtensa_cpu_do_transaction_failed,
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index f18ab383fd..29d216ec1b 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -242,27 +242,7 @@ void xtensa_cpu_list(void)
 }
 }
 
-#ifdef CONFIG_USER_ONLY
-
-bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-XtensaCPU *cpu = XTENSA_CPU(cs);
-CPUXtensaState *env = &cpu->env;
-
-qemu_log_mask(CPU_LOG_INT,
-  "%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n",
-  __func__, access_type, address, size);
-env->sregs[EXCVADDR] = address;
-env->sregs[EXCCAUSE] = (access_type == MMU_DATA_STORE ?
-STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE);
-cs->exception_index = EXC_USER;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 void xtensa_cpu_do_unaligned_access(CPUState *cs,
 vaddr addr, MMUAccessType access_type,
 int mmu_idx, uintptr_t retaddr)
-- 
2.25.1




[PATCH v3 29/41] target/microblaze: Make mb_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for mb linux-user.
Remove the code from cpu_loop that handled the unnamed 0xaa exception.

Cc: Edgar E. Iglesias 
Signed-off-by: Richard Henderson 
---
 target/microblaze/cpu.h  |  8 
 linux-user/microblaze/cpu_loop.c | 10 --
 target/microblaze/cpu.c  |  2 +-
 target/microblaze/helper.c   | 13 +
 4 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index b7a848bbae..e9cd0b88de 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -394,10 +394,6 @@ void mb_tcg_init(void);
 #define MMU_USER_IDX2
 /* See NB_MMU_MODES further up the file.  */
 
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
 typedef CPUMBState CPUArchState;
 typedef MicroBlazeCPU ArchCPU;
 
@@ -415,6 +411,10 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, 
target_ulong *pc,
 }
 
 #if !defined(CONFIG_USER_ONLY)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
+
 void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
unsigned size, MMUAccessType access_type,
int mmu_idx, MemTxAttrs attrs,
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 5eb93f..a94467dd2d 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -37,16 +37,6 @@ void cpu_loop(CPUMBState *env)
 process_queued_cpu_work(cs);
 
 switch (trapnr) {
-case 0xaa:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = 0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-break;
 case EXCP_INTERRUPT:
   /* just indicate that signals should be handled asap */
   break;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 15db277925..b9c888b87e 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -365,9 +365,9 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
 static const struct TCGCPUOps mb_tcg_ops = {
 .initialize = mb_tcg_init,
 .synchronize_from_tb = mb_cpu_synchronize_from_tb,
-.tlb_fill = mb_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = mb_cpu_tlb_fill,
 .cpu_exec_interrupt = mb_cpu_exec_interrupt,
 .do_interrupt = mb_cpu_do_interrupt,
 .do_transaction_failed = mb_cpu_transaction_failed,
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index dd2aecd1d5..a607fe68e5 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -24,18 +24,7 @@
 #include "qemu/host-utils.h"
 #include "exec/log.h"
 
-#if defined(CONFIG_USER_ONLY)
-
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-cs->exception_index = 0xaa;
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
 static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
 MMUAccessType access_type)
 {
-- 
2.25.1




[PATCH v3 17/41] linux-user/host/riscv: Improve host_signal_write

2021-10-01 Thread Richard Henderson
Do not read 4 bytes before we determine the size of the insn.
Simplify triple switches in favor of checking major opcodes.
Include the missing cases of compact fsd and fsdsp.

Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv/host-signal.h | 83 ++---
 1 file changed, 28 insertions(+), 55 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
index 5860dce7d7..ab06d70964 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -17,65 +17,38 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
 
 static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
 {
-uint32_t insn = *(uint32_t *)host_signal_pc(uc);
-
 /*
- * Detect store by reading the instruction at the program
- * counter. Note: we currently only generate 32-bit
- * instructions so we thus only detect 32-bit stores
+ * Detect store by reading the instruction at the program counter.
+ * Do not read more than 16 bits, because we have not yet determined
+ * the size of the instruction.
  */
-switch (((insn >> 0) & 0b11)) {
-case 3:
-switch (((insn >> 2) & 0b1)) {
-case 8:
-switch (((insn >> 12) & 0b111)) {
-case 0: /* sb */
-case 1: /* sh */
-case 2: /* sw */
-case 3: /* sd */
-case 4: /* sq */
-return true;
-default:
-break;
-}
-break;
-case 9:
-switch (((insn >> 12) & 0b111)) {
-case 2: /* fsw */
-case 3: /* fsd */
-case 4: /* fsq */
-return true;
-default:
-break;
-}
-break;
-default:
-break;
-}
+const uint16_t *pinsn = (const uint16_t *)host_signal_pc(uc);
+uint16_t insn = pinsn[0];
+
+/* 16-bit instructions */
+switch (insn & 0xe003) {
+case 0xa000: /* c.fsd */
+case 0xc000: /* c.sw */
+case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */
+case 0xa002: /* c.fsdsp */
+case 0xc002: /* c.swsp */
+case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */
+return true;
 }
 
-/* Check for compressed instructions */
-switch (((insn >> 13) & 0b111)) {
-case 7:
-switch (insn & 0b11) {
-case 0: /*c.sd */
-case 2: /* c.sdsp */
-return true;
-default:
-break;
-}
-break;
-case 6:
-switch (insn & 0b11) {
-case 0: /* c.sw */
-case 3: /* c.swsp */
-return true;
-default:
-break;
-}
-break;
-default:
-break;
+/* 32-bit instructions, major opcodes */
+switch (insn & 0x7f) {
+case 0x23: /* store */
+case 0x27: /* store-fp */
+return true;
+case 0x2f: /* amo */
+/*
+ * The AMO function code is in bits 25-31, unread as yet.
+ * The AMO functions are LR (read), SC (write), and the
+ * rest are all read-modify-write.
+ */
+insn = pinsn[1];
+return (insn >> 11) != 2; /* LR */
 }
 
 return false;
-- 
2.25.1




[PATCH v3 10/41] linux-user/host/sparc: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.
Drop the Solais code as completely unused.

Signed-off-by: Richard Henderson 
---
 linux-user/host/sparc/host-signal.h   | 54 ++-
 linux-user/host/sparc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c | 62 +--
 3 files changed, 55 insertions(+), 63 deletions(-)

diff --git a/linux-user/host/sparc/host-signal.h 
b/linux-user/host/sparc/host-signal.h
index f4b4d65031..232943a1db 100644
--- a/linux-user/host/sparc/host-signal.h
+++ b/linux-user/host/sparc/host-signal.h
@@ -1 +1,53 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef SPARC_HOST_SIGNAL_H
+#define SPARC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+#ifdef __arch64__
+return uc->uc_mcontext.mc_gregs[MC_PC];
+#else
+return uc->uc_mcontext.gregs[REG_PC];
+#endif
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+if ((insn >> 30) == 3) {
+switch ((insn >> 19) & 0x3f) {
+case 0x05: /* stb */
+case 0x15: /* stba */
+case 0x06: /* sth */
+case 0x16: /* stha */
+case 0x04: /* st */
+case 0x14: /* sta */
+case 0x07: /* std */
+case 0x17: /* stda */
+case 0x0e: /* stx */
+case 0x1e: /* stxa */
+case 0x24: /* stf */
+case 0x34: /* stfa */
+case 0x27: /* stdf */
+case 0x37: /* stdfa */
+case 0x26: /* stqf */
+case 0x36: /* stqfa */
+case 0x25: /* stfsr */
+case 0x3c: /* casa */
+case 0x3e: /* casxa */
+return true;
+}
+}
+return false;
+}
+
+#endif
diff --git a/linux-user/host/sparc64/host-signal.h 
b/linux-user/host/sparc64/host-signal.h
index f4b4d65031..1191fe2d40 100644
--- a/linux-user/host/sparc64/host-signal.h
+++ b/linux-user/host/sparc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../sparc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b895b5c8bd..c7d083db92 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,67 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-int is_write;
-uint32_t insn;
-#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
-uint32_t *regs = (uint32_t *)(info + 1);
-void *sigmask = (regs + 20);
-/* XXX: is there a standard glibc define ? */
-unsigned long pc = regs[1];
-#else
-#ifdef __linux__
-struct sigcontext *sc = puc;
-unsigned long pc = sc->sigc_regs.tpc;
-void *sigmask = (void *)sc->sigc_mask;
-#elif defined(__OpenBSD__)
-struct sigcontext *uc = puc;
-unsigned long pc = uc->sc_pc;
-void *sigmask = (void *)(long)uc->sc_mask;
-#elif defined(__NetBSD__)
-ucontext_t *uc = puc;
-unsigned long pc = _UC_MACHINE_PC(uc);
-void *sigmask = (void *)&uc->uc_sigmask;
-#endif
-#endif
-
-/* XXX: need kernel patch to get write flag faster */
-is_write = 0;
-insn = *(uint32_t *)pc;
-if ((insn >> 30) == 3) {
-switch ((insn >> 19) & 0x3f) {
-case 0x05: /* stb */
-case 0x15: /* stba */
-case 0x06: /* sth */
-case 0x16: /* stha */
-case 0x04: /* st */
-case 0x14: /* sta */
-case 0x07: /* std */
-case 0x17: /* stda */
-case 0x0e: /* stx */
-case 0x1e: /* stxa */
-case 0x24: /* stf */
-case 0x34: /* stfa */
-case 0x27: /* stdf */
-case 0x37: /* stdfa */
-case 0x26: /* stqf */
-case 0x36: /* stqfa */
-case 0x25: /* stfsr */
-case 0x3c: /* casa */
-case 0x3e: /* casxa */
-is_write = 1;
-break;
-}
-}
-return handle_cpu_signal(pc, info, is_write, sigmask);
-}
-
-#elif defined(__arm__)
+#if defined(__arm__)
 
 #if defined(__NetBSD__)
 #include 
-- 
2.25.1




[PATCH v3 30/41] target/mips: Make mips_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for mips linux-user.
This means we can remove tcg/user/tlb_helper.c entirely.
Remove the code from cpu_loop that raised SIGSEGV.

Signed-off-by: Richard Henderson 
---
 target/mips/tcg/tcg-internal.h|  7 ++--
 linux-user/mips/cpu_loop.c| 11 --
 target/mips/cpu.c |  2 +-
 target/mips/tcg/user/tlb_helper.c | 59 ---
 target/mips/tcg/meson.build   |  3 --
 target/mips/tcg/user/meson.build  |  3 --
 6 files changed, 5 insertions(+), 80 deletions(-)
 delete mode 100644 target/mips/tcg/user/tlb_helper.c
 delete mode 100644 target/mips/tcg/user/meson.build

diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h
index bad3deb611..466768aec4 100644
--- a/target/mips/tcg/tcg-internal.h
+++ b/target/mips/tcg/tcg-internal.h
@@ -18,9 +18,6 @@
 void mips_tcg_init(void);
 
 void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
-bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-   MMUAccessType access_type, int mmu_idx,
-   bool probe, uintptr_t retaddr);
 void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
   MMUAccessType access_type, int mmu_idx,
   uintptr_t retaddr) QEMU_NORETURN;
@@ -60,6 +57,10 @@ void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 MemTxResult response, uintptr_t retaddr);
 void cpu_mips_tlb_flush(CPUMIPSState *env);
 
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+
 #endif /* !CONFIG_USER_ONLY */
 
 #endif
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index cb03fb066b..b735c99a24 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -158,17 +158,6 @@ done_syscall:
 }
 env->active_tc.gpr[2] = ret;
 break;
-case EXCP_TLBL:
-case EXCP_TLBS:
-case EXCP_AdEL:
-case EXCP_AdES:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->CP0_BadVAddr;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_CpU:
 case EXCP_RI:
 info.si_signo = TARGET_SIGILL;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 00e0c55d0e..4aae23934b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -539,9 +539,9 @@ static const struct SysemuCPUOps mips_sysemu_ops = {
 static const struct TCGCPUOps mips_tcg_ops = {
 .initialize = mips_tcg_init,
 .synchronize_from_tb = mips_cpu_synchronize_from_tb,
-.tlb_fill = mips_cpu_tlb_fill,
 
 #if !defined(CONFIG_USER_ONLY)
+.tlb_fill = mips_cpu_tlb_fill,
 .cpu_exec_interrupt = mips_cpu_exec_interrupt,
 .do_interrupt = mips_cpu_do_interrupt,
 .do_transaction_failed = mips_cpu_do_transaction_failed,
diff --git a/target/mips/tcg/user/tlb_helper.c 
b/target/mips/tcg/user/tlb_helper.c
deleted file mode 100644
index 210c6d529e..00
--- a/target/mips/tcg/user/tlb_helper.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * MIPS TLB (Translation lookaside buffer) helpers.
- *
- *  Copyright (c) 2004-2005 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "internal.h"
-
-static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
-MMUAccessType access_type)
-{
-CPUState *cs = env_cpu(env);
-
-env->error_code = 0;
-if (access_type == MMU_INST_FETCH) {
-env->error_code |= EXCP_INST_NOTAVAIL;
-}
-
-/* Reference to kernel address from user mode or supervisor mode */
-/* Reference to supervisor address from user mode */
-if (access_type == MMU_DATA_STORE) {
-cs->exception_index = EXCP_AdES;
-} else {
-cs->exception_index = EXCP_AdEL;
-}
-
-/* Raise exception */
-if (!(env->hflags & MIPS_HFLAG_DM)) {
-env->CP0_BadVAddr = a

[PATCH v3 09/41] linux-user/host/alpha: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/host/alpha/host-signal.h | 41 +
 accel/tcg/user-exec.c   | 31 +-
 2 files changed, 42 insertions(+), 30 deletions(-)
 create mode 100644 linux-user/host/alpha/host-signal.h

diff --git a/linux-user/host/alpha/host-signal.h 
b/linux-user/host/alpha/host-signal.h
new file mode 100644
index 00..e27704d832
--- /dev/null
+++ b/linux-user/host/alpha/host-signal.h
@@ -0,0 +1,41 @@
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ALPHA_HOST_SIGNAL_H
+#define ALPHA_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.sc_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t *pc = (uint32_t *)host_signal_pc(uc);
+uint32_t insn = *pc;
+
+/* XXX: need kernel patch to get write flag faster */
+switch (insn >> 26) {
+case 0x0d: /* stw */
+case 0x0e: /* stb */
+case 0x0f: /* stq_u */
+case 0x24: /* stf */
+case 0x25: /* stg */
+case 0x26: /* sts */
+case 0x27: /* stt */
+case 0x2c: /* stl */
+case 0x2d: /* stq */
+case 0x2e: /* stl_c */
+case 0x2f: /* stq_c */
+return true;
+}
+return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e9e530e2e1..b895b5c8bd 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,36 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-uint32_t *pc = uc->uc_mcontext.sc_pc;
-uint32_t insn = *pc;
-int is_write = 0;
-
-/* XXX: need kernel patch to get write flag faster */
-switch (insn >> 26) {
-case 0x0d: /* stw */
-case 0x0e: /* stb */
-case 0x0f: /* stq_u */
-case 0x24: /* stf */
-case 0x25: /* stg */
-case 0x26: /* sts */
-case 0x27: /* stt */
-case 0x2c: /* stl */
-case 0x2d: /* stq */
-case 0x2e: /* stl_c */
-case 0x2f: /* stq_c */
-is_write = 1;
-}
-
-return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-#elif defined(__sparc__)
+#if defined(__sparc__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
void *puc)
-- 
2.25.1




[PATCH v3 28/41] target/m68k: Make m68k_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for m68k-linux-user.
Remove the code from cpu_loop that handled EXCP_ACCESS.

Signed-off-by: Richard Henderson 
---
 linux-user/m68k/cpu_loop.c | 10 --
 target/m68k/cpu.c  |  2 +-
 target/m68k/helper.c   |  6 +-
 3 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index ebf32be78f..790bd558c3 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -90,16 +90,6 @@ void cpu_loop(CPUM68KState *env)
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
 break;
-case EXCP_ACCESS:
-{
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = env->mmu.ar;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-}
-break;
 case EXCP_DEBUG:
 info.si_signo = TARGET_SIGTRAP;
 info.si_errno = 0;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 66d22d1189..c7aeb7da9c 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -515,9 +515,9 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
 
 static const struct TCGCPUOps m68k_tcg_ops = {
 .initialize = m68k_tcg_init,
-.tlb_fill = m68k_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = m68k_cpu_tlb_fill,
 .cpu_exec_interrupt = m68k_cpu_exec_interrupt,
 .do_interrupt = m68k_cpu_do_interrupt,
 .do_transaction_failed = m68k_cpu_transaction_failed,
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 137a3e1a3d..5728e48585 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -978,16 +978,12 @@ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t 
vector)
 }
 }
 
-#endif
-
 bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType qemu_access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
 {
 M68kCPU *cpu = M68K_CPU(cs);
 CPUM68KState *env = &cpu->env;
-
-#ifndef CONFIG_USER_ONLY
 hwaddr physical;
 int prot;
 int access_type;
@@ -1051,12 +1047,12 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 if (!(access_type & ACCESS_STORE)) {
 env->mmu.ssw |= M68K_RW_040;
 }
-#endif
 
 cs->exception_index = EXCP_ACCESS;
 env->mmu.ar = address;
 cpu_loop_exit_restore(cs, retaddr);
 }
+#endif /* !CONFIG_USER_ONLY */
 
 uint32_t HELPER(bitrev)(uint32_t x)
 {
-- 
2.25.1




[PATCH v3 18/41] linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER

2021-10-01 Thread Richard Henderson
Now that all of the linux-user hosts have been converted
to host-signal.h, drop the compatibility code.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h | 12 
 linux-user/signal.c | 14 --
 2 files changed, 26 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5f94d799aa..5dd663c153 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -685,18 +685,6 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write);
 bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
  uintptr_t host_pc, abi_ptr guest_addr);
 
-/**
- * cpu_signal_handler
- * @signum: host signal number
- * @pinfo: host siginfo_t
- * @puc: host ucontext_t
- *
- * To be called from the SIGBUS and SIGSEGV signal handler to inform the
- * virtual cpu of exceptions.  Returns true if the signal was handled by
- * the virtual CPU.
- */
-int cpu_signal_handler(int signum, void *pinfo, void *puc);
-
 #else
 static inline void mmap_lock(void) {}
 static inline void mmap_unlock(void) {}
diff --git a/linux-user/signal.c b/linux-user/signal.c
index bab47a6962..537c6c41c0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -777,17 +777,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 ucontext_t *uc = puc;
 struct emulated_sigtable *k;
 int guest_sig;
-
-#ifdef HOST_SIGNAL_PLACEHOLDER
-/* the CPU emulator uses some host signals to detect exceptions,
-   we forward to it some signals */
-if ((host_sig == SIGSEGV || host_sig == SIGBUS)
-&& info->si_code > 0) {
-if (cpu_signal_handler(host_sig, info, puc)) {
-return;
-}
-}
-#else
 uintptr_t pc = 0;
 bool sync_sig = false;
 
@@ -847,7 +836,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 
 sync_sig = true;
 }
-#endif
 
 /* get target signal number */
 guest_sig = host_to_target_signal(host_sig);
@@ -862,7 +850,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 k->pending = guest_sig;
 ts->signal_pending = 1;
 
-#ifndef HOST_SIGNAL_PLACEHOLDER
 /*
  * For synchronous signals, unwind the cpu state to the faulting
  * insn and then exit back to the main loop so that the signal
@@ -872,7 +859,6 @@ static void host_signal_handler(int host_sig, siginfo_t 
*info, void *puc)
 cpu->exception_index = EXCP_INTERRUPT;
 cpu_loop_exit_restore(cpu, pc);
 }
-#endif
 
 rewind_if_in_safe_syscall(puc);
 
-- 
2.25.1




[PATCH v3 27/41] target/i386: Implement x86_cpu_record_sigsegv

2021-10-01 Thread Richard Henderson
Record cr2, error_code, and exception_index.  That last means
that we must exit to cpu_loop ourselves, instead of letting
exception_index being overwritten.

Use the maperr parameter to properly set PG_ERROR_P_MASK.

Reviewed by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/i386/tcg/helper-tcg.h   |  6 ++
 target/i386/tcg/tcg-cpu.c  |  3 ++-
 target/i386/tcg/user/excp_helper.c | 23 +--
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 60ca09e95e..0a4401e917 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -43,9 +43,15 @@ bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
 #endif
 
 /* helper.c */
+#ifdef CONFIG_USER_ONLY
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra);
+#else
 bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
   MMUAccessType access_type, int mmu_idx,
   bool probe, uintptr_t retaddr);
+#endif
 
 void breakpoint_handler(CPUState *cs);
 
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 3ecfae34cb..6fdfdf9598 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -72,10 +72,11 @@ static const struct TCGCPUOps x86_tcg_ops = {
 .synchronize_from_tb = x86_cpu_synchronize_from_tb,
 .cpu_exec_enter = x86_cpu_exec_enter,
 .cpu_exec_exit = x86_cpu_exec_exit,
-.tlb_fill = x86_cpu_tlb_fill,
 #ifdef CONFIG_USER_ONLY
 .fake_user_interrupt = x86_cpu_do_interrupt,
+.record_sigsegv = x86_cpu_record_sigsegv,
 #else
+.tlb_fill = x86_cpu_tlb_fill,
 .do_interrupt = x86_cpu_do_interrupt,
 .cpu_exec_interrupt = x86_cpu_exec_interrupt,
 .debug_excp_handler = breakpoint_handler,
diff --git a/target/i386/tcg/user/excp_helper.c 
b/target/i386/tcg/user/excp_helper.c
index a89b5228fd..cd507e2a1b 100644
--- a/target/i386/tcg/user/excp_helper.c
+++ b/target/i386/tcg/user/excp_helper.c
@@ -22,18 +22,29 @@
 #include "exec/exec-all.h"
 #include "tcg/helper-tcg.h"
 
-bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
-  MMUAccessType access_type, int mmu_idx,
-  bool probe, uintptr_t retaddr)
+void x86_cpu_record_sigsegv(CPUState *cs, vaddr addr,
+MMUAccessType access_type,
+bool maperr, uintptr_t ra)
 {
 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = &cpu->env;
 
+/*
+ * The error_code that hw reports as part of the exception frame
+ * is copied to linux sigcontext.err.  The exception_index is
+ * copied to linux sigcontext.trapno.  Short of inventing a new
+ * place to store the trapno, we cannot let our caller raise the
+ * signal and set exception_index to EXCP_INTERRUPT.
+ */
 env->cr[2] = addr;
-env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
-env->error_code |= PG_ERROR_U_MASK;
+env->error_code = ((access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT)
+| (maperr ? 0 : PG_ERROR_P_MASK)
+| PG_ERROR_U_MASK;
 cs->exception_index = EXCP0E_PAGE;
+
+/* Disable do_interrupt_user. */
 env->exception_is_int = 0;
 env->exception_next_eip = -1;
-cpu_loop_exit_restore(cs, retaddr);
+
+cpu_loop_exit_restore(cs, ra);
 }
-- 
2.25.1




[PATCH v3 19/41] hw/core: Add TCGCPUOps.record_sigsegv

2021-10-01 Thread Richard Henderson
Add a new user-only interface for updating cpu state before
raising a signal.  This will replace tlb_fill for user-only
and should result in less boilerplate for each guest.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/core/tcg-cpu-ops.h | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 6cbe17f2e6..41718b695b 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -111,6 +111,32 @@ struct TCGCPUOps {
  */
 bool (*io_recompile_replay_branch)(CPUState *cpu,
const TranslationBlock *tb);
+#else
+/**
+ * record_sigsegv:
+ * @cpu: cpu context
+ * @addr: faulting guest address
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * We are about to raise SIGSEGV with si_code set for @maperr,
+ * and si_addr set for @addr.  Record anything further needed
+ * for the signal ucontext_t.
+ *
+ * If the emulated kernel does not provide anything to the signal
+ * handler with anything besides the user context registers, and
+ * the siginfo_t, then this hook need do nothing and may be omitted.
+ * Otherwise, record the data and return; the caller will raise
+ * the signal, unwind the cpu state, and return to the main loop.
+ *
+ * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided
+ * so that a "normal" cpu exception can be raised.  In this case,
+ * the signal must be raised by the architecture cpu_loop.
+ */
+void (*record_sigsegv)(CPUState *cpu, vaddr addr,
+   MMUAccessType access_type,
+   bool maperr, uintptr_t ra);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */
 
-- 
2.25.1




[PATCH v3 15/41] linux-user/host/riscv: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.

Signed-off-by: Richard Henderson 
---
 linux-user/host/riscv/host-signal.h |  85 +-
 accel/tcg/user-exec.c   | 134 
 2 files changed, 84 insertions(+), 135 deletions(-)

diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
index f4b4d65031..5860dce7d7 100644
--- a/linux-user/host/riscv/host-signal.h
+++ b/linux-user/host/riscv/host-signal.h
@@ -1 +1,84 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef RISCV_HOST_SIGNAL_H
+#define RISCV_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.__gregs[REG_PC];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+uint32_t insn = *(uint32_t *)host_signal_pc(uc);
+
+/*
+ * Detect store by reading the instruction at the program
+ * counter. Note: we currently only generate 32-bit
+ * instructions so we thus only detect 32-bit stores
+ */
+switch (((insn >> 0) & 0b11)) {
+case 3:
+switch (((insn >> 2) & 0b1)) {
+case 8:
+switch (((insn >> 12) & 0b111)) {
+case 0: /* sb */
+case 1: /* sh */
+case 2: /* sw */
+case 3: /* sd */
+case 4: /* sq */
+return true;
+default:
+break;
+}
+break;
+case 9:
+switch (((insn >> 12) & 0b111)) {
+case 2: /* fsw */
+case 3: /* fsd */
+case 4: /* fsq */
+return true;
+default:
+break;
+}
+break;
+default:
+break;
+}
+}
+
+/* Check for compressed instructions */
+switch (((insn >> 13) & 0b111)) {
+case 7:
+switch (insn & 0b11) {
+case 0: /*c.sd */
+case 2: /* c.sdsp */
+return true;
+default:
+break;
+}
+break;
+case 6:
+switch (insn & 0b11) {
+case 0: /* c.sw */
+case 3: /* c.swsp */
+return true;
+default:
+break;
+}
+break;
+default:
+break;
+}
+
+return false;
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 42d1ad189b..01e7e69e7f 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -139,64 +139,6 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t 
*old_set,
 }
 }
 
-/*
- * 'pc' is the host PC at which the exception was raised.
- * 'address' is the effective address of the memory exception.
- * 'is_write' is 1 if a write caused the exception and otherwise 0.
- * 'old_set' is the signal set which should be restored.
- */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-int is_write, sigset_t *old_set)
-{
-CPUState *cpu = current_cpu;
-CPUClass *cc;
-unsigned long host_addr = (unsigned long)info->si_addr;
-MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
-abi_ptr guest_addr;
-
-/* For synchronous signals we expect to be coming from the vCPU
- * thread (so current_cpu should be valid) and either from running
- * code or during translation which can fault as we cross pages.
- *
- * If neither is true then something has gone wrong and we should
- * abort rather than try and restart the vCPU execution.
- */
-if (!cpu || !cpu->running) {
-printf("qemu:%s received signal outside vCPU context @ pc=0x%"
-   PRIxPTR "\n",  __func__, pc);
-abort();
-}
-
-#if defined(DEBUG_SIGNAL)
-printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-   pc, host_addr, is_write, *(unsigned long *)old_set);
-#endif
-
-/* Convert forcefully to guest address space, invalid addresses
-   are still valid segv ones */
-guest_addr = h2g_nocheck(host_addr);
-
-/* XXX: locking issue */
-if (is_write &&
-info->si_signo == SIGSEGV &&
-info->si_code == SEGV_ACCERR &&
-h2g_valid(host_addr) &&
-handle_sigsegv_accerr_write(cpu, old_set, pc, guest_addr)) {
-return 1;
-}
-
-/*
- * There is no way the target can handle this other than raising
- * an exception.  Undo signal and retaddr state prior to longjmp.
- */
-sigprocmask(SIG_SETMASK, old_set, NULL);
-
-cc = CPU_GET_CLASS(cpu);
-cc->tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
-  MMU_USER_IDX, false, pc);
-g_assert_not_reached();
-}
-
 static int probe_access_internal(CPUArchState 

[PATCH v3 04/41] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller

2021-10-01 Thread Richard Henderson
Remove the comment about siglongjmp.  We do use sigsetjmp
in the main cpu loop, but we do not save the signal mask
as most exits from the cpu loop do not require them.

Signed-off-by: Richard Henderson 
---
 accel/tcg/user-exec.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 6f4fc01b60..de4565f13e 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -46,17 +46,6 @@ __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
 
-/* exit the current TB from a signal handler. The host registers are
-   restored in a state compatible with the CPU emulator
- */
-static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu,
-  sigset_t *old_set)
-{
-/* XXX: use siglongjmp ? */
-sigprocmask(SIG_SETMASK, old_set, NULL);
-cpu_loop_exit_noexc(cpu);
-}
-
 /*
  * Adjust the pc to pass to cpu_restore_state; return the memop type.
  */
@@ -155,7 +144,8 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t 
*old_set,
  * currently executing TB was modified and must be exited
  * immediately.  Clear helper_retaddr for next execution.
  */
-cpu_exit_tb_from_sighandler(cpu, old_set);
+sigprocmask(SIG_SETMASK, old_set, NULL);
+cpu_loop_exit_noexc(cpu);
 /* NORETURN */
 default:
 g_assert_not_reached();
-- 
2.25.1




[PATCH v3 25/41] target/hexagon: Remove hexagon_cpu_tlb_fill

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for hexagon.
Remove the code from cpu_loop that raises SIGSEGV.

Cc: Taylor Simpson 
Signed-off-by: Richard Henderson 
---
 linux-user/hexagon/cpu_loop.c | 24 +---
 target/hexagon/cpu.c  | 23 ---
 2 files changed, 1 insertion(+), 46 deletions(-)

diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index bee2a9e4ea..6b24cbaba9 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -28,8 +28,7 @@
 void cpu_loop(CPUHexagonState *env)
 {
 CPUState *cs = env_cpu(env);
-int trapnr, signum, sigcode;
-target_ulong sigaddr;
+int trapnr;
 target_ulong syscallnum;
 target_ulong ret;
 
@@ -39,10 +38,6 @@ void cpu_loop(CPUHexagonState *env)
 cpu_exec_end(cs);
 process_queued_cpu_work(cs);
 
-signum = 0;
-sigcode = 0;
-sigaddr = 0;
-
 switch (trapnr) {
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
@@ -65,12 +60,6 @@ void cpu_loop(CPUHexagonState *env)
 env->gpr[0] = ret;
 }
 break;
-case HEX_EXCP_FETCH_NO_UPAGE:
-case HEX_EXCP_PRIV_NO_UREAD:
-case HEX_EXCP_PRIV_NO_UWRITE:
-signum = TARGET_SIGSEGV;
-sigcode = TARGET_SEGV_MAPERR;
-break;
 case EXCP_ATOMIC:
 cpu_exec_step_atomic(cs);
 break;
@@ -79,17 +68,6 @@ void cpu_loop(CPUHexagonState *env)
  trapnr);
 exit(EXIT_FAILURE);
 }
-
-if (signum) {
-target_siginfo_t info = {
-.si_signo = signum,
-.si_errno = 0,
-.si_code = sigcode,
-._sifields._sigfault._addr = sigaddr
-};
-queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
-}
-
 process_pending_signals(env);
 }
 }
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 3338365c16..160a46a3d5 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -245,34 +245,11 @@ static void hexagon_cpu_init(Object *obj)
 qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property);
 }
 
-static bool hexagon_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
-#ifdef CONFIG_USER_ONLY
-switch (access_type) {
-case MMU_INST_FETCH:
-cs->exception_index = HEX_EXCP_FETCH_NO_UPAGE;
-break;
-case MMU_DATA_LOAD:
-cs->exception_index = HEX_EXCP_PRIV_NO_UREAD;
-break;
-case MMU_DATA_STORE:
-cs->exception_index = HEX_EXCP_PRIV_NO_UWRITE;
-break;
-}
-cpu_loop_exit_restore(cs, retaddr);
-#else
-#error System mode not implemented for Hexagon
-#endif
-}
-
 #include "hw/core/tcg-cpu-ops.h"
 
 static const struct TCGCPUOps hexagon_tcg_ops = {
 .initialize = hexagon_translate_init,
 .synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
-.tlb_fill = hexagon_tlb_fill,
 };
 
 static void hexagon_cpu_class_init(ObjectClass *c, void *data)
-- 
2.25.1




[PATCH v3 11/41] linux-user/host/arm: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson 
---
 linux-user/host/arm/host-signal.h | 30 -
 accel/tcg/user-exec.c | 45 +--
 2 files changed, 30 insertions(+), 45 deletions(-)

diff --git a/linux-user/host/arm/host-signal.h 
b/linux-user/host/arm/host-signal.h
index f4b4d65031..6932224c1c 100644
--- a/linux-user/host/arm/host-signal.h
+++ b/linux-user/host/arm/host-signal.h
@@ -1 +1,29 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef ARM_HOST_SIGNAL_H
+#define ARM_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.arm_pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+/*
+ * In the FSR, bit 11 is WnR, assuming a v6 or
+ * later processor.  On v5 we will always report
+ * this as a read, which will fail later.
+ */
+uint32_t fsr = uc->uc_mcontext.error_code;
+return extract32(fsr, 11, 1);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index c7d083db92..e9c29f917d 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,50 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__arm__)
-
-#if defined(__NetBSD__)
-#include 
-#include 
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__NetBSD__)
-ucontext_t *uc = puc;
-siginfo_t *si = pinfo;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-uint32_t fsr;
-int is_write;
-
-#if defined(__NetBSD__)
-pc = uc->uc_mcontext.__gregs[_REG_R15];
-#elif defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && 
__GLIBC_MINOR__ <= 3))
-pc = uc->uc_mcontext.gregs[R15];
-#else
-pc = uc->uc_mcontext.arm_pc;
-#endif
-
-#ifdef __NetBSD__
-fsr = si->si_trap;
-#else
-fsr = uc->uc_mcontext.error_code;
-#endif
-/*
- * In the FSR, bit 11 is WnR, assuming a v6 or
- * later processor.  On v5 we will always report
- * this as a read, which will fail later.
- */
-is_write = extract32(fsr, 11, 1);
-return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
 
 #if defined(__NetBSD__)
 
-- 
2.25.1




[PATCH v3 21/41] target/alpha: Make alpha_cpu_tlb_fill sysemu only

2021-10-01 Thread Richard Henderson
The fallback code in raise_sigsegv is sufficient for alpha-linux-user.
Remove the code from cpu_loop that handled EXCP_MMFAULT.

Signed-off-by: Richard Henderson 
---
 target/alpha/cpu.h  |  7 ---
 linux-user/alpha/cpu_loop.c |  8 
 target/alpha/cpu.c  |  2 +-
 target/alpha/helper.c   | 13 +
 4 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 772828cc26..ec6657a490 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -439,9 +439,6 @@ void alpha_translate_init(void);
 #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
 
 void alpha_cpu_list(void);
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr);
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 
@@ -449,12 +446,16 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
 uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
 void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
+
 #ifndef CONFIG_USER_ONLY
 void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
  vaddr addr, unsigned size,
  MMUAccessType access_type,
  int mmu_idx, MemTxAttrs attrs,
  MemTxResult response, uintptr_t retaddr);
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 #endif
 
 static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 1b00a81385..4cc8e0a55c 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -54,14 +54,6 @@ void cpu_loop(CPUAlphaState *env)
 fprintf(stderr, "External interrupt. Exit\n");
 exit(EXIT_FAILURE);
 break;
-case EXCP_MMFAULT:
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
-? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
-info._sifields._sigfault._addr = env->trap_arg0;
-queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
-break;
 case EXCP_UNALIGN:
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 93e16a2ffb..52031ca981 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,9 +218,9 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
 
 static const struct TCGCPUOps alpha_tcg_ops = {
 .initialize = alpha_translate_init,
-.tlb_fill = alpha_cpu_tlb_fill,
 
 #ifndef CONFIG_USER_ONLY
+.tlb_fill = alpha_cpu_tlb_fill,
 .cpu_exec_interrupt = alpha_cpu_exec_interrupt,
 .do_interrupt = alpha_cpu_do_interrupt,
 .do_transaction_failed = alpha_cpu_do_transaction_failed,
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 81550d9e2f..266d56ea73 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -119,18 +119,7 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, 
uint64_t val)
 *cpu_alpha_addr_gr(env, reg) = val;
 }
 
-#if defined(CONFIG_USER_ONLY)
-bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
-MMUAccessType access_type, int mmu_idx,
-bool probe, uintptr_t retaddr)
-{
-AlphaCPU *cpu = ALPHA_CPU(cs);
-
-cs->exception_index = EXCP_MMFAULT;
-cpu->env.trap_arg0 = address;
-cpu_loop_exit_restore(cs, retaddr);
-}
-#else
+#ifndef CONFIG_USER_ONLY
 /* Returns the OSF/1 entMM failure indication, or -1 on success.  */
 static int get_physical_address(CPUAlphaState *env, target_ulong addr,
 int prot_need, int mmu_idx,
-- 
2.25.1




[PATCH v3 01/41] accel/tcg: Split out adjust_signal_pc

2021-10-01 Thread Richard Henderson
Split out a function to adjust the raw signal pc into a
value that could be passed to cpu_restore_state.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v2: Adjust pc in place; return MMUAccessType.
---
 include/exec/exec-all.h | 10 ++
 accel/tcg/user-exec.c   | 41 +
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 9d5987ba04..e54f8e5d65 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -663,6 +663,16 @@ static inline tb_page_addr_t 
get_page_addr_code_hostp(CPUArchState *env,
 return addr;
 }
 
+/**
+ * adjust_signal_pc:
+ * @pc: raw pc from the host signal ucontext_t.
+ * @is_write: host memory operation was write, or read-modify-write.
+ *
+ * Alter @pc as required for unwinding.  Return the type of the
+ * guest memory access -- host reads may be for guest execution.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 8fed542622..cef025d001 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -57,18 +57,11 @@ static void QEMU_NORETURN 
cpu_exit_tb_from_sighandler(CPUState *cpu,
 cpu_loop_exit_noexc(cpu);
 }
 
-/* 'pc' is the host PC at which the exception was raised. 'address' is
-   the effective address of the memory exception. 'is_write' is 1 if a
-   write caused the exception and otherwise 0'. 'old_set' is the
-   signal set which should be restored */
-static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
-int is_write, sigset_t *old_set)
+/*
+ * Adjust the pc to pass to cpu_restore_state; return the memop type.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
 {
-CPUState *cpu = current_cpu;
-CPUClass *cc;
-unsigned long address = (unsigned long)info->si_addr;
-MMUAccessType access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
-
 switch (helper_retaddr) {
 default:
 /*
@@ -77,7 +70,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * pointer into the generated code that will unwind to the
  * correct guest pc.
  */
-pc = helper_retaddr;
+*pc = helper_retaddr;
 break;
 
 case 0:
@@ -97,7 +90,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * Therefore, adjust to compensate for what will be done later
  * by cpu_restore_state_from_tb.
  */
-pc += GETPC_ADJ;
+*pc += GETPC_ADJ;
 break;
 
 case 1:
@@ -113,12 +106,28 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
  *
  * Like tb_gen_code, release the memory lock before cpu_loop_exit.
  */
-pc = 0;
-access_type = MMU_INST_FETCH;
 mmap_unlock();
-break;
+*pc = 0;
+return MMU_INST_FETCH;
 }
 
+return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
+}
+
+/*
+ * 'pc' is the host PC at which the exception was raised.
+ * 'address' is the effective address of the memory exception.
+ * 'is_write' is 1 if a write caused the exception and otherwise 0.
+ * 'old_set' is the signal set which should be restored.
+ */
+static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
+int is_write, sigset_t *old_set)
+{
+CPUState *cpu = current_cpu;
+CPUClass *cc;
+unsigned long address = (unsigned long)info->si_addr;
+MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
+
 /* For synchronous signals we expect to be coming from the vCPU
  * thread (so current_cpu should be valid) and either from running
  * code or during translation which can fault as we cross pages.
-- 
2.25.1




[PATCH v3 12/41] linux-user/host/aarch64: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson 
---
 linux-user/host/aarch64/host-signal.h | 74 -
 accel/tcg/user-exec.c | 94 +--
 2 files changed, 74 insertions(+), 94 deletions(-)

diff --git a/linux-user/host/aarch64/host-signal.h 
b/linux-user/host/aarch64/host-signal.h
index f4b4d65031..02a55c3372 100644
--- a/linux-user/host/aarch64/host-signal.h
+++ b/linux-user/host/aarch64/host-signal.h
@@ -1 +1,73 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef AARCH64_HOST_SIGNAL_H
+#define AARCH64_HOST_SIGNAL_H
+
+/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
+#ifndef ESR_MAGIC
+#define ESR_MAGIC 0x45535201
+struct esr_context {
+struct _aarch64_ctx head;
+uint64_t esr;
+};
+#endif
+
+static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
+{
+return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
+}
+
+static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
+{
+return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
+}
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.pc;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+struct _aarch64_ctx *hdr;
+uint32_t insn;
+
+/* Find the esr_context, which has the WnR bit in it */
+for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
+if (hdr->magic == ESR_MAGIC) {
+struct esr_context const *ec = (struct esr_context const *)hdr;
+uint64_t esr = ec->esr;
+
+/* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */
+return extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
+}
+}
+
+/*
+ * Fall back to parsing instructions; will only be needed
+ * for really ancient (pre-3.16) kernels.
+ */
+insn = *(uint32_t *)host_signal_pc(uc);
+
+return (insn & 0xbfff) == 0x0c00   /* C3.3.1 */
+|| (insn & 0xbfe0) == 0x0c80   /* C3.3.2 */
+|| (insn & 0xbfdf) == 0x0d00   /* C3.3.3 */
+|| (insn & 0xbfc0) == 0x0d80   /* C3.3.4 */
+|| (insn & 0x3f40) == 0x0800   /* C3.3.6 */
+|| (insn & 0x3bc0) == 0x3900   /* C3.3.13 */
+|| (insn & 0x3fc0) == 0x3d80   /* ... 128bit */
+/* Ignore bits 10, 11 & 21, controlling indexing.  */
+|| (insn & 0x3bc0) == 0x3800   /* C3.3.8-12 */
+|| (insn & 0x3fe0) == 0x3c80   /* ... 128bit */
+/* Ignore bits 23 & 24, controlling indexing.  */
+|| (insn & 0x3a40) == 0x2800; /* C3.3.7,14-16 */
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e9c29f917d..8f4e788304 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,99 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__aarch64__)
-
-#if defined(__NetBSD__)
-
-#include 
-#include 
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-ucontext_t *uc = puc;
-siginfo_t *si = pinfo;
-unsigned long pc;
-int is_write;
-uint32_t esr;
-
-pc = uc->uc_mcontext.__gregs[_REG_PC];
-esr = si->si_trap;
-
-/*
- * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC
- * is 0b10010x: then bit 6 is the WnR bit
- */
-is_write = extract32(esr, 27, 5) == 0x12 && extract32(esr, 6, 1) == 1;
-return handle_cpu_signal(pc, si, is_write, &uc->uc_sigmask);
-}
-
-#else
-
-#ifndef ESR_MAGIC
-/* Pre-3.16 kernel headers don't have these, so provide fallback definitions */
-#define ESR_MAGIC 0x45535201
-struct esr_context {
-struct _aarch64_ctx head;
-uint64_t esr;
-};
-#endif
-
-static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc)
-{
-return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved;
-}
-
-static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr)
-{
-return (struct _aarch64_ctx *)((char *)hdr + hdr->size);
-}
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-siginfo_t *info = pinfo;
-ucontext_t *uc = puc;
-uintptr_t pc = uc->uc_mcontext.pc;
-bool is_write;
-struct _aarch64_ctx *hdr;
-struct esr_context const *esrctx = NULL;
-
-/* Find the esr_context, which has the WnR bit in it */
-for (hdr = first_ctx(uc); hdr->magic; hdr = next_ctx(hdr)) {
-if (hdr->magic == ESR_MAGIC) {
-esrctx = (struct esr_context const *)hdr;
-break;
-}
-}
-
-if (esrct

[PATCH v3 05/41] configure: Merge riscv32 and riscv64 host architectures

2021-10-01 Thread Richard Henderson
The existing code for safe-syscall.inc.S will compile
without change for riscv32 and riscv64.  We may also
drop the meson.build stanza that merges them for tcg/.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 configure |  8 ++--
 meson.build   |  4 +---
 linux-user/host/{riscv64 => riscv}/hostdep.h  |  4 ++--
 linux-user/host/riscv32/hostdep.h | 11 ---
 linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S |  0
 5 files changed, 5 insertions(+), 22 deletions(-)
 rename linux-user/host/{riscv64 => riscv}/hostdep.h (94%)
 delete mode 100644 linux-user/host/riscv32/hostdep.h
 rename linux-user/host/{riscv64 => riscv}/safe-syscall.inc.S (100%)

diff --git a/configure b/configure
index 1043ccce4f..23ede08582 100755
--- a/configure
+++ b/configure
@@ -650,11 +650,7 @@ elif check_define __s390__ ; then
 cpu="s390"
   fi
 elif check_define __riscv ; then
-  if check_define _LP64 ; then
-cpu="riscv64"
-  else
-cpu="riscv32"
-  fi
+  cpu="riscv"
 elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
@@ -667,7 +663,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
+  ppc|ppc64|s390x|sparc64|x32|riscv)
   ;;
   ppc64le)
 ARCH="ppc64"
diff --git a/meson.build b/meson.build
index 7bdbbbdf02..30cb165b3b 100644
--- a/meson.build
+++ b/meson.build
@@ -56,7 +56,7 @@ have_block = have_system or have_tools
 python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
-supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 
'x86_64',
+supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
 
 cpu = host_machine.cpu_family()
@@ -278,8 +278,6 @@ if not get_option('tcg').disabled()
 tcg_arch = 'i386'
   elif config_host['ARCH'] == 'ppc64'
 tcg_arch = 'ppc'
-  elif config_host['ARCH'] in ['riscv32', 'riscv64']
-tcg_arch = 'riscv'
   endif
   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / 
tcg_arch,
 language: ['c', 'cpp', 'objc'])
diff --git a/linux-user/host/riscv64/hostdep.h b/linux-user/host/riscv/hostdep.h
similarity index 94%
rename from linux-user/host/riscv64/hostdep.h
rename to linux-user/host/riscv/hostdep.h
index 865f0fb9ff..2ba07456ae 100644
--- a/linux-user/host/riscv64/hostdep.h
+++ b/linux-user/host/riscv/hostdep.h
@@ -5,8 +5,8 @@
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef RISCV64_HOSTDEP_H
-#define RISCV64_HOSTDEP_H
+#ifndef RISCV_HOSTDEP_H
+#define RISCV_HOSTDEP_H
 
 /* We have a safe-syscall.inc.S */
 #define HAVE_SAFE_SYSCALL
diff --git a/linux-user/host/riscv32/hostdep.h 
b/linux-user/host/riscv32/hostdep.h
deleted file mode 100644
index adf9edbf2d..00
--- a/linux-user/host/riscv32/hostdep.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef RISCV32_HOSTDEP_H
-#define RISCV32_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/riscv64/safe-syscall.inc.S 
b/linux-user/host/riscv/safe-syscall.inc.S
similarity index 100%
rename from linux-user/host/riscv64/safe-syscall.inc.S
rename to linux-user/host/riscv/safe-syscall.inc.S
-- 
2.25.1




[PATCH v3 02/41] accel/tcg: Move clear_helper_retaddr to cpu loop

2021-10-01 Thread Richard Henderson
Currently there are only two places that require we reset this
value before exiting to the main loop, but that will change.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 accel/tcg/cpu-exec.c  | 3 ++-
 accel/tcg/user-exec.c | 2 --
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 5fd1ed3422..410588d08a 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -451,6 +451,7 @@ void cpu_exec_step_atomic(CPUState *cpu)
  * memory.
  */
 #ifndef CONFIG_SOFTMMU
+clear_helper_retaddr();
 tcg_debug_assert(!have_mmap_lock());
 #endif
 if (qemu_mutex_iothread_locked()) {
@@ -460,7 +461,6 @@ void cpu_exec_step_atomic(CPUState *cpu)
 qemu_plugin_disable_mem_helpers(cpu);
 }
 
-
 /*
  * As we start the exclusive region before codegen we must still
  * be in the region if we longjump out of either the codegen or
@@ -905,6 +905,7 @@ int cpu_exec(CPUState *cpu)
 #endif
 
 #ifndef CONFIG_SOFTMMU
+clear_helper_retaddr();
 tcg_debug_assert(!have_mmap_lock());
 #endif
 if (qemu_mutex_iothread_locked()) {
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index cef025d001..e94f1fed00 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -175,7 +175,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * currently executing TB was modified and must be exited
  * immediately.  Clear helper_retaddr for next execution.
  */
-clear_helper_retaddr();
 cpu_exit_tb_from_sighandler(cpu, old_set);
 /* NORETURN */
 
@@ -193,7 +192,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
  * an exception.  Undo signal and retaddr state prior to longjmp.
  */
 sigprocmask(SIG_SETMASK, old_set, NULL);
-clear_helper_retaddr();
 
 cc = CPU_GET_CLASS(cpu);
 cc->tcg_ops->tlb_fill(cpu, address, 0, access_type,
-- 
2.25.1




[PATCH v3 08/41] linux-user/host/ppc: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Reviewed-by: Warner Losh 
Signed-off-by: Richard Henderson 
---
 linux-user/host/ppc/host-signal.h   | 25 -
 linux-user/host/ppc64/host-signal.h |  2 +-
 accel/tcg/user-exec.c   | 79 +
 3 files changed, 26 insertions(+), 80 deletions(-)

diff --git a/linux-user/host/ppc/host-signal.h 
b/linux-user/host/ppc/host-signal.h
index f4b4d65031..e09756c691 100644
--- a/linux-user/host/ppc/host-signal.h
+++ b/linux-user/host/ppc/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef PPC_HOST_SIGNAL_H
+#define PPC_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.regs->nip;
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.regs->trap != 0x400
+&& (uc->uc_mcontext.regs->dsisr & 0x0200);
+}
+
+#endif
diff --git a/linux-user/host/ppc64/host-signal.h 
b/linux-user/host/ppc64/host-signal.h
index f4b4d65031..a353c22a90 100644
--- a/linux-user/host/ppc64/host-signal.h
+++ b/linux-user/host/ppc64/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../ppc/host-signal.h"
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index b5d06183db..e9e530e2e1 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -255,84 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(_ARCH_PPC)
-
-/***
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-#define REG_sig(reg_name, context)  \
-((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access  */
-#define GPR_sig(reg_num, context)  REG_sig(gpr[reg_num], context)
-/* Program counter */
-#define IAR_sig(context)   REG_sig(nip, context)
-/* Machine State Register (Supervisor) */
-#define MSR_sig(context)   REG_sig(msr, context)
-/* Count register */
-#define CTR_sig(context)   REG_sig(ctr, context)
-/* User's integer exception register */
-#define XER_sig(context)   REG_sig(xer, context)
-/* Link register */
-#define LR_sig(context)REG_sig(link, context)
-/* Condition register */
-#define CR_sig(context)REG_sig(ccr, context)
-
-/* Float Registers access  */
-#define FLOAT_sig(reg_num, context) \
-(((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
-#define FPSCR_sig(context) \
-(*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
-/* Exception Registers access */
-#define DAR_sig(context)   REG_sig(dar, context)
-#define DSISR_sig(context) REG_sig(dsisr, context)
-#define TRAP_sig(context)  REG_sig(trap, context)
-#endif /* linux */
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include 
-#define IAR_sig(context)   ((context)->uc_mcontext.mc_srr0)
-#define MSR_sig(context)   ((context)->uc_mcontext.mc_srr1)
-#define CTR_sig(context)   ((context)->uc_mcontext.mc_ctr)
-#define XER_sig(context)   ((context)->uc_mcontext.mc_xer)
-#define LR_sig(context)((context)->uc_mcontext.mc_lr)
-#define CR_sig(context)((context)->uc_mcontext.mc_cr)
-/* Exception Registers access */
-#define DAR_sig(context)   ((context)->uc_mcontext.mc_dar)
-#define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr)
-#define TRAP_sig(context)  ((context)->uc_mcontext.mc_exc)
-#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-ucontext_t *uc = puc;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-int is_write;
-
-pc = IAR_sig(uc);
-is_write = 0;
-#if 0
-/* ppc 4xx case */
-if (DSISR_sig(uc) & 0x0080) {
-is_write = 1;
-}
-#else
-if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x0200)) {
-is_write = 1;
-}
-#endif
-return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
-}
-
-#elif defined(__alpha__)
+#if defined(__alpha__)
 
 int cpu_signal_handler(int host_signum, void *pinfo,
void *pu

[PATCH v3 06/41] linux-user: Reorg handling for SIGSEGV

2021-10-01 Thread Richard Henderson
Add stub host-signal.h for all linux-user hosts.
Add new code replacing cpu_signal_handler.
Full migration will happen one host at a time.

Reviewed-by: Warner Losh 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 linux-user/host/aarch64/host-signal.h |   1 +
 linux-user/host/arm/host-signal.h |   1 +
 linux-user/host/i386/host-signal.h|   1 +
 linux-user/host/mips/host-signal.h|   1 +
 linux-user/host/ppc/host-signal.h |   1 +
 linux-user/host/ppc64/host-signal.h   |   1 +
 linux-user/host/riscv/host-signal.h   |   1 +
 linux-user/host/s390/host-signal.h|   1 +
 linux-user/host/s390x/host-signal.h   |   1 +
 linux-user/host/sparc/host-signal.h   |   1 +
 linux-user/host/sparc64/host-signal.h |   1 +
 linux-user/host/x32/host-signal.h |   1 +
 linux-user/host/x86_64/host-signal.h  |   1 +
 linux-user/signal.c   | 109 ++
 14 files changed, 106 insertions(+), 16 deletions(-)
 create mode 100644 linux-user/host/aarch64/host-signal.h
 create mode 100644 linux-user/host/arm/host-signal.h
 create mode 100644 linux-user/host/i386/host-signal.h
 create mode 100644 linux-user/host/mips/host-signal.h
 create mode 100644 linux-user/host/ppc/host-signal.h
 create mode 100644 linux-user/host/ppc64/host-signal.h
 create mode 100644 linux-user/host/riscv/host-signal.h
 create mode 100644 linux-user/host/s390/host-signal.h
 create mode 100644 linux-user/host/s390x/host-signal.h
 create mode 100644 linux-user/host/sparc/host-signal.h
 create mode 100644 linux-user/host/sparc64/host-signal.h
 create mode 100644 linux-user/host/x32/host-signal.h
 create mode 100644 linux-user/host/x86_64/host-signal.h

diff --git a/linux-user/host/aarch64/host-signal.h 
b/linux-user/host/aarch64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/aarch64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/arm/host-signal.h 
b/linux-user/host/arm/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/arm/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/i386/host-signal.h 
b/linux-user/host/i386/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/i386/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/mips/host-signal.h 
b/linux-user/host/mips/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/mips/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc/host-signal.h 
b/linux-user/host/ppc/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/ppc64/host-signal.h 
b/linux-user/host/ppc64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/ppc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/riscv/host-signal.h 
b/linux-user/host/riscv/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/riscv/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390/host-signal.h 
b/linux-user/host/s390/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/s390x/host-signal.h 
b/linux-user/host/s390x/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/s390x/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc/host-signal.h 
b/linux-user/host/sparc/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/sparc64/host-signal.h 
b/linux-user/host/sparc64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/sparc64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x32/host-signal.h 
b/linux-user/host/x32/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x32/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/host/x86_64/host-signal.h 
b/linux-user/host/x86_64/host-signal.h
new file mode 100644
index 00..f4b4d65031
--- /dev/null
+++ b/linux-user/host/x86_64/host-signal.h
@@ -0,0 +1 @@
+#define HOST_SIGNAL_PLACEHOLDER
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 2038216455..bab47a6962 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -

[PATCH v3 03/41] accel/tcg: Split out handle_sigsegv_accerr_write

2021-10-01 Thread Richard Henderson
This is the major portion of handle_cpu_signal which is specific
to tcg, handling the page protections for the translations.
Most of the rest will migrate to linux-user/ shortly.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v2: Pass guest address to handle_sigsegv_accerr_write.
---
 include/exec/exec-all.h |  12 +
 accel/tcg/user-exec.c   | 103 
 2 files changed, 74 insertions(+), 41 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e54f8e5d65..5f94d799aa 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -673,6 +673,18 @@ static inline tb_page_addr_t 
get_page_addr_code_hostp(CPUArchState *env,
  */
 MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @host_addr: the host address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+ uintptr_t host_pc, abi_ptr guest_addr);
+
 /**
  * cpu_signal_handler
  * @signum: host signal number
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index e94f1fed00..6f4fc01b60 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -114,6 +114,54 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool 
is_write)
 return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
 }
 
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @guest_addr: the guest address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ *
+ * Note that it is important that we don't call page_unprotect() unless
+ * this is really a "write to nonwriteable page" fault, because
+ * page_unprotect() assumes that if it is called for an access to
+ * a page that's writeable this means we had two threads racing and
+ * another thread got there first and already made the page writeable;
+ * so we will retry the access. If we were to call page_unprotect()
+ * for some other kind of fault that should really be passed to the
+ * guest, we'd end up in an infinite loop of retrying the faulting access.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+ uintptr_t host_pc, abi_ptr guest_addr)
+{
+switch (page_unprotect(guest_addr, host_pc)) {
+case 0:
+/*
+ * Fault not caused by a page marked unwritable to protect
+ * cached translations, must be the guest binary's problem.
+ */
+return false;
+case 1:
+/*
+ * Fault caused by protection of cached translation; TBs
+ * invalidated, so resume execution.  Retain helper_retaddr
+ * for a possible second fault.
+ */
+return true;
+case 2:
+/*
+ * Fault caused by protection of cached translation, and the
+ * currently executing TB was modified and must be exited
+ * immediately.  Clear helper_retaddr for next execution.
+ */
+cpu_exit_tb_from_sighandler(cpu, old_set);
+/* NORETURN */
+default:
+g_assert_not_reached();
+}
+}
+
 /*
  * 'pc' is the host PC at which the exception was raised.
  * 'address' is the effective address of the memory exception.
@@ -125,8 +173,9 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
 {
 CPUState *cpu = current_cpu;
 CPUClass *cc;
-unsigned long address = (unsigned long)info->si_addr;
+unsigned long host_addr = (unsigned long)info->si_addr;
 MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
+abi_ptr guest_addr;
 
 /* For synchronous signals we expect to be coming from the vCPU
  * thread (so current_cpu should be valid) and either from running
@@ -143,49 +192,21 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
 
 #if defined(DEBUG_SIGNAL)
 printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-   pc, address, is_write, *(unsigned long *)old_set);
+   pc, host_addr, is_write, *(unsigned long *)old_set);
 #endif
-/* XXX: locking issue */
-/* Note that it is important that we don't call page_unprotect() unless
- * this is really a "write to nonwriteable page" fault, because
- * page_unprotect() assumes that if it is called for an access to
- * a page that's writeable this means we had two threads racing and
- * another thread got there first and already made the page writeable;
- * so we will retry the access. If we were to call page_unprotect()
- * for some other kind of fault that should really be passed to the
- * guest, we'd end up i

[PATCH v3 00/41] linux-user: Streamline handling of SIGSEGV

2021-10-01 Thread Richard Henderson
Changes for v3:
  * Rebased on master, as force_sig_fault is now upstream.
  * Minimized nios2 changes; there's another patch set that cleans
up nios2, but I don't want to force that as a dependency.
  * Renamed raise_sigsegv to cpu_loop_exit_segv (f4bug).

Patches lacking review:
  04-accel-tcg-Fold-cpu_exit_tb_from_sighandler-into-c.patch
  07-linux-user-host-x86-Populate-host_signal.h.patch
  10-linux-user-host-sparc-Populate-host_signal.h.patch
  11-linux-user-host-arm-Populate-host_signal.h.patch
  12-linux-user-host-aarch64-Populate-host_signal.h.patch
  15-linux-user-host-riscv-Populate-host_signal.h.patch
  16-target-arm-Fixup-comment-re-handle_cpu_signal.patch
  17-linux-user-host-riscv-Improve-host_signal_write.patch
  21-target-alpha-Make-alpha_cpu_tlb_fill-sysemu-only.patch
  22-target-arm-Use-cpu_loop_exit_segv-for-mte-tag-loo.patch
  23-target-arm-Implement-arm_cpu_record_sigsegv.patch
  25-target-hexagon-Remove-hexagon_cpu_tlb_fill.patch
  26-target-hppa-Make-hppa_cpu_tlb_fill-sysemu-only.patch
  28-target-m68k-Make-m68k_cpu_tlb_fill-sysemu-only.patch
  29-target-microblaze-Make-mb_cpu_tlb_fill-sysemu-onl.patch
  30-target-mips-Make-mips_cpu_tlb_fill-sysemu-only.patch
  31-target-nios2-Implement-nios2_cpu_record_sigsegv.patch
  32-linux-user-openrisc-Adjust-signal-for-EXCP_RANGE-.patch
  33-target-openrisc-Make-openrisc_cpu_tlb_fill-sysemu.patch
  35-target-riscv-Make-riscv_cpu_tlb_fill-sysemu-only.patch
  36-target-s390x-Use-probe_access_flags-in-s390_probe.patch
  38-target-sh4-Make-sh4_cpu_tlb_fill-sysemu-only.patch
  39-target-sparc-Make-sparc_cpu_tlb_fill-sysemu-only.patch
  40-target-xtensa-Make-xtensa_cpu_tlb_fill-sysemu-onl.patch


r~


Richard Henderson (41):
  accel/tcg: Split out adjust_signal_pc
  accel/tcg: Move clear_helper_retaddr to cpu loop
  accel/tcg: Split out handle_sigsegv_accerr_write
  accel/tcg: Fold cpu_exit_tb_from_sighandler into caller
  configure: Merge riscv32 and riscv64 host architectures
  linux-user: Reorg handling for SIGSEGV
  linux-user/host/x86: Populate host_signal.h
  linux-user/host/ppc: Populate host_signal.h
  linux-user/host/alpha: Populate host_signal.h
  linux-user/host/sparc: Populate host_signal.h
  linux-user/host/arm: Populate host_signal.h
  linux-user/host/aarch64: Populate host_signal.h
  linux-user/host/s390: Populate host_signal.h
  linux-user/host/mips: Populate host_signal.h
  linux-user/host/riscv: Populate host_signal.h
  target/arm: Fixup comment re handle_cpu_signal
  linux-user/host/riscv: Improve host_signal_write
  linux-user/signal: Drop HOST_SIGNAL_PLACEHOLDER
  hw/core: Add TCGCPUOps.record_sigsegv
  linux-user: Add cpu_loop_exit_segv
  target/alpha: Make alpha_cpu_tlb_fill sysemu only
  target/arm: Use cpu_loop_exit_segv for mte tag lookup
  target/arm: Implement arm_cpu_record_sigsegv
  target/cris: Make cris_cpu_tlb_fill sysemu only
  target/hexagon: Remove hexagon_cpu_tlb_fill
  target/hppa: Make hppa_cpu_tlb_fill sysemu only
  target/i386: Implement x86_cpu_record_sigsegv
  target/m68k: Make m68k_cpu_tlb_fill sysemu only
  target/microblaze: Make mb_cpu_tlb_fill sysemu only
  target/mips: Make mips_cpu_tlb_fill sysemu only
  target/nios2: Implement nios2_cpu_record_sigsegv
  linux-user/openrisc: Adjust signal for EXCP_RANGE, EXCP_FPE
  target/openrisc: Make openrisc_cpu_tlb_fill sysemu only
  target/ppc: Implement ppc_cpu_record_sigsegv
  target/riscv: Make riscv_cpu_tlb_fill sysemu only
  target/s390x: Use probe_access_flags in s390_probe_access
  target/s390x: Implement s390_cpu_record_sigsegv
  target/sh4: Make sh4_cpu_tlb_fill sysemu only
  target/sparc: Make sparc_cpu_tlb_fill sysemu only
  target/xtensa: Make xtensa_cpu_tlb_fill sysemu only
  accel/tcg: Restrict TCGCPUOps::tlb_fill() to sysemu

 configure |   8 +-
 meson.build   |   4 +-
 include/exec/exec-all.h   |  41 +-
 include/hw/core/tcg-cpu-ops.h |  48 +-
 linux-user/host/aarch64/host-signal.h |  73 ++
 linux-user/host/alpha/host-signal.h   |  41 +
 linux-user/host/arm/host-signal.h |  29 +
 linux-user/host/i386/host-signal.h|  24 +
 linux-user/host/mips/host-signal.h|  61 ++
 linux-user/host/ppc/host-signal.h |  24 +
 linux-user/host/ppc64/host-signal.h   |   1 +
 linux-user/host/riscv/host-signal.h   |  57 ++
 linux-user/host/{riscv64 => riscv}/hostdep.h  |   4 +-
 linux-user/host/riscv32/hostdep.h |  11 -
 linux-user/host/s390/host-signal.h|  92 ++
 linux-user/host/s390x/host-signal.h   |   1 +
 linux-user/host/sparc/host-signal.h   |  53 ++
 linux-user/host/sparc64/host-signal.h |   1 +
 linux-user/host/x32/host-signal.h |   1 +
 linux-user/host/x86_64/host-signal.h  |  24 +
 target/alpha/cpu.h|   7 +-
 target/arm/internals.h|   6 +
 target/cris/cpu.h

[PATCH v3 07/41] linux-user/host/x86: Populate host_signal.h

2021-10-01 Thread Richard Henderson
Split host_signal_pc and host_signal_write out of user-exec.c.
Drop the *BSD code, to be re-created under bsd-user/ later.

Signed-off-by: Richard Henderson 
---
 linux-user/host/i386/host-signal.h   |  25 -
 linux-user/host/x32/host-signal.h|   2 +-
 linux-user/host/x86_64/host-signal.h |  25 -
 accel/tcg/user-exec.c| 136 +--
 4 files changed, 50 insertions(+), 138 deletions(-)

diff --git a/linux-user/host/i386/host-signal.h 
b/linux-user/host/i386/host-signal.h
index f4b4d65031..ccbbee5082 100644
--- a/linux-user/host/i386/host-signal.h
+++ b/linux-user/host/i386/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef I386_HOST_SIGNAL_H
+#define I386_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_EIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+&& (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/linux-user/host/x32/host-signal.h 
b/linux-user/host/x32/host-signal.h
index f4b4d65031..26800591d3 100644
--- a/linux-user/host/x32/host-signal.h
+++ b/linux-user/host/x32/host-signal.h
@@ -1 +1 @@
-#define HOST_SIGNAL_PLACEHOLDER
+#include "../x86_64/host-signal.h"
diff --git a/linux-user/host/x86_64/host-signal.h 
b/linux-user/host/x86_64/host-signal.h
index f4b4d65031..883d2fcf65 100644
--- a/linux-user/host/x86_64/host-signal.h
+++ b/linux-user/host/x86_64/host-signal.h
@@ -1 +1,24 @@
-#define HOST_SIGNAL_PLACEHOLDER
+/*
+ * host-signal.h: signal info dependent on the host architecture
+ *
+ * Copyright (C) 2021 Linaro Limited
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef X86_64_HOST_SIGNAL_H
+#define X86_64_HOST_SIGNAL_H
+
+static inline uintptr_t host_signal_pc(ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_RIP];
+}
+
+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
+{
+return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
+&& (uc->uc_mcontext.gregs[REG_ERR] & 0x2);
+}
+
+#endif
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index de4565f13e..b5d06183db 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -29,19 +29,6 @@
 #include "trace/trace-root.h"
 #include "trace/mem.h"
 
-#undef EAX
-#undef ECX
-#undef EDX
-#undef EBX
-#undef ESP
-#undef EBP
-#undef ESI
-#undef EDI
-#undef EIP
-#ifdef __linux__
-#include 
-#endif
-
 __thread uintptr_t helper_retaddr;
 
 //#define DEBUG_SIGNAL
@@ -268,123 +255,7 @@ void *probe_access(CPUArchState *env, target_ulong addr, 
int size,
 return size ? g2h(env_cpu(env), addr) : NULL;
 }
 
-#if defined(__i386__)
-
-#if defined(__NetBSD__)
-#include 
-#include 
-
-#define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP])
-#define TRAP_sig(context)((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
-#include 
-#include 
-
-#define EIP_sig(context)  (*((unsigned long *)&(context)->uc_mcontext.mc_eip))
-#define TRAP_sig(context)((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)   ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#elif defined(__OpenBSD__)
-#include 
-#define EIP_sig(context) ((context)->sc_eip)
-#define TRAP_sig(context)((context)->sc_trapno)
-#define ERROR_sig(context)   ((context)->sc_err)
-#define MASK_sig(context)((context)->sc_mask)
-#define PAGE_FAULT_TRAP  T_PAGEFLT
-#else
-#define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
-#define TRAP_sig(context)((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)((context)->uc_sigmask)
-#define PAGE_FAULT_TRAP  0xe
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-   void *puc)
-{
-siginfo_t *info = pinfo;
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
-ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-struct sigcontext *uc = puc;
-#else
-ucontext_t *uc = puc;
-#endif
-unsigned long pc;
-int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIPEIP
-#define REG_ERRERR
-#define REG_TRAPNO TRAPNO
-#endif
-pc = EIP_sig(uc);
-trapno = TRAP_sig(uc);
-return handle_cpu_signal(pc, info,
-

Re: [PATCH v12 16/16] machine: Make smp_parse return a boolean

2021-10-01 Thread Paolo Bonzini

On 29/09/21 04:58, Yanan Wang wrote:

@@ -933,8 +935,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
  return;
  }
  
-smp_parse(ms, config, errp);

-if (*errp) {
+if (!smp_parse(ms, config, errp)) {
  qapi_free_SMPConfiguration(config);
  }
  }



This is actually a leak, so I'm replacing this patch with

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 54f04a5ac6..d49ebc24e2 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -897,7 +897,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
 {
 MachineClass *mc = MACHINE_GET_CLASS(obj);
 MachineState *ms = MACHINE(obj);
-SMPConfiguration *config;
+g_autoptr(SMPConfiguration) config = NULL;
 ERRP_GUARD();
 
 if (!visit_type_SMPConfiguration(v, name, &config, errp)) {

@@ -920,7 +920,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
 
 smp_parse(ms, config, errp);

 if (*errp) {
-goto out_free;
+return;
 }
 
 /* sanity-check smp_cpus and max_cpus against mc */

@@ -935,9 +935,6 @@ static void machine_set_smp(Object *obj, Visitor *v, const 
char *name,
ms->smp.max_cpus,
mc->name, mc->max_cpus);
 }
-
-out_free:
-qapi_free_SMPConfiguration(config);
 }
 
 static void machine_class_init(ObjectClass *oc, void *data)


which removes the need.

Paolo




hexagon container update

2021-10-01 Thread Brian Cain
Alex,

We need to update the docker container used for hexagon for new test cases 
proposed in Taylor's recent patch series under review.  Thankfully, CodeLinaro 
has provided a binary of the hexagon cross toolchain so now I think we can 
simplify the hexagon docker file to something like the below.  I hope this also 
means that we can remove the exceptional handling for the hexagon container.

I can propose a patch but I'm not quite certain how to test it.

The "--no-check-certificate" argument to wget is very bad but I'm not quite 
certain how to upgrade/change the container's certificate store to accept the 
apparently-legit-but-perhaps-newer-than-expected certificate presented by 
codelinaro.jfrog.io.

~~~

FROM qemu/debian10

RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
DEBIAN_FRONTEND=noninteractive eatmydata \
apt install -y --no-install-recommends \
xz-utils \
wget

ENV CLANG_URL 
https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/v2021.09.10/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz

RUN cd /tmp && \
wget --quiet --no-check-certificate ${CLANG_URL}
RUN cd /opt && \
tar xf /tmp/clang+llvm-Sept-2021-cross-hexagon-unknown-linux-musl.tar.xz




Re: [RFC PATCH 00/13] x86 User Interrupts support

2021-10-01 Thread Richard Henderson

On 10/1/21 12:35 PM, Stefan Hajnoczi wrote:

QEMU's TCG threads execute translated code. There are events that
require interrupting these threads. Today a check is performed at the
start of every translated block. Most of the time the check is false and
it's a waste of CPU.

User interrupts can eliminate the need for checks by interrupting TCG
threads when events occur.


We used to use interrupts, and stopped because we need to wait until the guest is in a 
stable state.  The guest is always in a stable state at the beginning of each TB.


See 378df4b2375.


r~



Re: [RFC PATCH 00/13] x86 User Interrupts support

2021-10-01 Thread Stefan Hajnoczi
On Thu, Sep 30, 2021 at 10:24:24AM -0700, Sohil Mehta wrote:
> 
> On 9/30/2021 9:30 AM, Stefan Hajnoczi wrote:
> > On Tue, Sep 28, 2021 at 09:31:34PM -0700, Andy Lutomirski wrote:
> > > 
> > > I spent some time reviewing the docs (ISE) and contemplating how this all 
> > > fits together, and I have a high level question:
> > > 
> > > Can someone give an example of a realistic workload that would benefit 
> > > from SENDUIPI and precisely how it would use SENDUIPI?  Or an example of 
> > > a realistic workload that would benefit from hypothetical 
> > > device-initiated user interrupts and how it would use them?  I'm having 
> > > trouble imagining something that wouldn't work as well or better by 
> > > simply polling, at least on DMA-coherent architectures like x86.
> > I was wondering the same thing. One thing came to mind:
> > 
> > An application that wants to be *interrupted* from what it's doing
> > rather than waiting until the next polling point. For example,
> > applications that are CPU-intensive and have green threads. I can't name
> > a real application like this though :P.
> 
> Thank you Stefan and Andy for giving this some thought.
> 
> We are consolidating the information internally on where and how exactly we
> expect to see benefits with real workloads for the various sources of User
> Interrupts. It will take a few days to get back on this one.

One possible use case came to mind in QEMU's TCG just-in-time compiler:

QEMU's TCG threads execute translated code. There are events that
require interrupting these threads. Today a check is performed at the
start of every translated block. Most of the time the check is false and
it's a waste of CPU.

User interrupts can eliminate the need for checks by interrupting TCG
threads when events occur.

I don't know whether this will improve performance or how feasible it is
to implement, but I've added people who might have ideas. (For a summary
of user interrupts, see
https://lwn.net/SubscriberLink/871113/60652640e11fc5df/.)

Stefan


signature.asc
Description: PGP signature


Re: [PATCH 3/3] hw/intc/arm_gicv3: Support multiple redistributor regions

2021-10-01 Thread Richard Henderson

On 9/30/21 11:08 AM, Peter Maydell wrote:

Our GICv3 QOM interface includes an array property
redist-region-count which allows board models to specify that the
registributor registers are not in a single contiguous range, but
split into multiple pieces.  We implemented this for KVM, but
currently the TCG GICv3 model insists that there is only one region.
You can see the limit being hit with a setup like:
   qemu-system-aarch64 -machine virt,gic-version=3 -smp 124

Add support for split regions to the TCG GICv3.  To do this we switch
from allocating a simple array of MemoryRegions to an array of
GICv3RedistRegion structs so that we can use the GICv3RedistRegion as
the opaque pointer in the MemoryRegion read/write callbacks.  Each
GICv3RedistRegion contains the MemoryRegion, a backpointer allowing
the read/write callback to get hold of the GICv3State, and an index
which allows us to calculate which CPU's redistributor is being
accessed.

Note that arm_gicv3_kvm always passes in NULL as the ops argument
to gicv3_init_irqs_and_mmio(), so the only MemoryRegion read/write
callbacks we need to update to handle this new scheme are the
gicv3_redist_read/write functions used by the emulated GICv3.

Signed-off-by: Peter Maydell
---


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 2/3] hw/intc/arm_gicv3: Set GICR_TYPER.Last correctly when nb_redist_regions > 1

2021-10-01 Thread Richard Henderson

On 9/30/21 11:08 AM, Peter Maydell wrote:

The 'Last' bit in the GICR_TYPER GICv3 redistributor register is
supposed to be set to 1 if this is the last redistributor in a series
of contiguous redistributor pages.  Currently we set Last only for
the redistributor for CPU (num_cpu - 1).  This only works if there is
a single redistributor region; if there are multiple redistributor
regions then we need to set the Last bit for the last redistributor
in each region.

This doesn't cause any problems currently because only the KVM GICv3
supports multiple redistributor regions, and it ignores the value in
GICv3State::gicr_typer.  But we need to fix this before we can enable
support for multiple regions in the emulated GICv3.

Signed-off-by: Peter Maydell
---


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 1/3] hw/intc/arm_gicv3: Move checking of redist-region-count to arm_gicv3_common_realize

2021-10-01 Thread Richard Henderson

On 9/30/21 11:08 AM, Peter Maydell wrote:

The GICv3 devices have an array property redist-region-count.
Currently we check this for errors (bad values) in
gicv3_init_irqs_and_mmio(), just before we use it.  Move this error
checking to the arm_gicv3_common_realize() function, where we
sanity-check all of the other base-class properties. (This will
always be before gicv3_init_irqs_and_mmio() is called, because
that function is called in the subclass realize methods, after
they have called the parent-class realize.)

The motivation for this refactor is:
  * we would like to use the redist_region_count[] values in
arm_gicv3_common_realize() in a subsequent patch, so we need
to have already done the sanity-checking first
  * this removes the only use of the Error** argument to
gicv3_init_irqs_and_mmio(), so we can remove some error-handling
boilerplate

Signed-off-by: Peter Maydell
---


Reviewed-by: Richard Henderson 

r~



RE: [PATCH v2] Hexagon (target/hexagon) probe the stores in a packet at start of commit

2021-10-01 Thread Taylor Simpson


> -Original Message-
> From: Richard Henderson 
> Sent: Friday, October 1, 2021 10:55 AM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: f4...@amsat.org; a...@rev.ng; Brian Cain 
> Subject: Re: [PATCH v2] Hexagon (target/hexagon) probe the stores in a
> packet at start of commit
> 
> On 9/30/21 5:16 PM, Taylor Simpson wrote:
> > +} else if (has_store_s0 && has_store_s1) {
> > +TCGv mem_idx = tcg_const_tl(ctx->mem_idx);
> > +gen_helper_probe_pkt_scalar_store_s0(cpu_env, mem_idx);
> > +tcg_temp_free(mem_idx);
> > +}
> 
> So we're assuming that the s1 store happens first?
> If so, you could expand the comment above.

Yes, there's a comment in process_store_log (with a typo fixed here).
/*
 *  When a packet has two stores, the hardware processes
 *  slot 1 and then slot 0.  This will be important when
 *  the memory accesses overlap.
 */
I'll fix the typo and expand the comment in the above code.

Also, tests/tcg/hexagon/dual_stores.c tests for this behavior.

> Otherwise, it looks good.
> Reviewed-by: Richard Henderson 

Thanks!




Re: [PATCH v2] configure: Loosen GCC requirement from 7.5.0 to 7.4.0

2021-10-01 Thread Richard Henderson

On 10/1/21 11:30 AM, nia wrote:

As discussed in issue 614, we're shipping GCC 7.4.0 as the
system compiler in NetBSD 9, the most recent stable branch,
and are still actively interested in QEMU on this platform.

The differences between GCC 7.5.0 and 7.4.0 are trivial.

Signed-off-by: Nia Alarie
---
  configure | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2] Hexagon (target/hexagon) probe the stores in a packet at start of commit

2021-10-01 Thread Richard Henderson

On 9/30/21 5:16 PM, Taylor Simpson wrote:

+} else if (has_store_s0 && has_store_s1) {
+TCGv mem_idx = tcg_const_tl(ctx->mem_idx);
+gen_helper_probe_pkt_scalar_store_s0(cpu_env, mem_idx);
+tcg_temp_free(mem_idx);
+}


So we're assuming that the s1 store happens first?
If so, you could expand the comment above.

Otherwise, it looks good.
Reviewed-by: Richard Henderson 


r~



Re: [PATCH v3 07/10] tests/acpi: add test cases for VIOT

2021-10-01 Thread Jean-Philippe Brucker
On Mon, Sep 20, 2021 at 10:39:36AM +0200, Igor Mammedov wrote:
> > +static void test_acpi_q35_viot(void)
> > +{
> > +test_data data = {
> > +.machine = MACHINE_Q35,
> > +.variant = ".viot",
> 
> > +.blkdev = "virtio-blk,bus=pcie.0",
> why is this necessary?

It isn't actually, I think an earlier version of the patch needed it.
I'll remove this.

Thanks,
Jean




[PATCH 1/9] tests/docker: Add debian-nios2-cross image

2021-10-01 Thread Richard Henderson
Build the entire cross tool chain from source.
For this reason, default to caching.

Signed-off-by: Richard Henderson 
---
 tests/docker/Makefile.include | 19 
 .../dockerfiles/debian-nios2-cross.docker | 34 +++
 .../build-toolchain.sh| 97 +++
 3 files changed, 150 insertions(+)
 create mode 100644 tests/docker/dockerfiles/debian-nios2-cross.docker
 create mode 100755 
tests/docker/dockerfiles/debian-nios2-cross.docker.d/build-toolchain.sh

diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index ff5d732889..2ccd93caa4 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -168,10 +168,28 @@ docker-image-debian-hexagon-cross: 
$(DOCKER_FILES_DIR)/debian-hexagon-cross.dock
qemu/debian-hexagon-cross --add-current-user,   
\
"PREPARE", "debian-hexagon-cross"))
 
+docker-image-debian-nios2-cross: $(DOCKER_FILES_DIR)/debian-nios2-cross.docker
+   $(if $(NOCACHE),
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) build -t qemu/debian-nios2-cross -f $< 
\
+   $(if $V,,--quiet) --no-cache
\
+   --registry $(DOCKER_REGISTRY) --extra-files 
\
+   
$(DOCKER_FILES_DIR)/debian-nios2-cross.docker.d/build-toolchain.sh, \
+   "BUILD", "debian-nios2-cross"), 
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) fetch $(if $V,,--quiet)
\
+   qemu/debian-nios2-cross $(DOCKER_REGISTRY), 
\
+   "FETCH", "debian-nios2-cross")  
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) update $(if $V,,--quiet)   
\
+   qemu/debian-nios2-cross --add-current-user, 
\
+   "PREPARE", "debian-nios2-cross"))
+
 # Specialist build images, sometimes very limited tools
 docker-image-debian-tricore-cross: docker-image-debian10
 docker-image-debian-all-test-cross: docker-image-debian10
 docker-image-debian-arm64-test-cross: docker-image-debian11
+docker-image-debian-nios2-cross: docker-image-debian10
 docker-image-debian-powerpc-test-cross: docker-image-debian11
 
 # These images may be good enough for building tests but not for test builds
@@ -180,6 +198,7 @@ DOCKER_PARTIAL_IMAGES += debian-arm64-test-cross
 DOCKER_PARTIAL_IMAGES += debian-powerpc-test-cross
 DOCKER_PARTIAL_IMAGES += debian-hppa-cross
 DOCKER_PARTIAL_IMAGES += debian-m68k-cross debian-mips64-cross
+DOCKER_PARTIAL_IMAGES += debian-nios2-cross
 DOCKER_PARTIAL_IMAGES += debian-riscv64-cross
 DOCKER_PARTIAL_IMAGES += debian-sh4-cross debian-sparc64-cross
 DOCKER_PARTIAL_IMAGES += debian-tricore-cross
diff --git a/tests/docker/dockerfiles/debian-nios2-cross.docker 
b/tests/docker/dockerfiles/debian-nios2-cross.docker
new file mode 100644
index 00..208737fc5e
--- /dev/null
+++ b/tests/docker/dockerfiles/debian-nios2-cross.docker
@@ -0,0 +1,34 @@
+#
+# Docker NIOS2 cross-compiler target
+#
+# This docker target is used for building tests. As it also needs to be
+# able to build QEMU itself in CI we include it's build-deps. It is also
+# a "stand-alone" image so as not to be triggered by re-builds on other
+# base images given it takes a long time to build.
+#
+FROM qemu/debian10
+
+# Install build utilities for building gcc and glibc.
+# ??? The build-dep isn't working, missing a number of
+# minimal build dependiencies, e.g. libmpc.
+
+RUN apt update && \
+DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
+DEBIAN_FRONTEND=noninteractive eatmydata \
+apt install -y --no-install-recommends \
+bison \
+flex \
+gawk \
+libmpc-dev \
+libmpfr-dev \
+rsync \
+texinfo \
+wget \
+$(apt-get -s build-dep --arch-only gcc | egrep ^Inst | fgrep '[all]' | 
cut -d\  -f2) \
+$(apt-get -s build-dep --arch-only glibc | egrep ^Inst | fgrep '[all]' 
| cut -d\  -f2)
+
+ADD build-toolchain.sh /root/build-toolchain.sh
+
+RUN cd /root && ./build-toolchain.sh
+
+ENV PATH $PATH:/usr/local/bin/
diff --git 
a/tests/docker/dockerfiles/debian-nios2-cross.docker.d/build-toolchain.sh 
b/tests/docker/dockerfiles/debian-nios2-cross.docker.d/build-toolchain.sh
new file mode 100755
index 00..d8cb428dab
--- /dev/null
+++ b/tests/docker/dockerfiles/debian-nios2-cross.docker.d/build-toolchain.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+
+set -e
+
+TARGET=nios2-l

  1   2   >