Re: [PATCH] replay: don't wait in run_on_cpu

2021-03-14 Thread Pavel Dovgalyuk

ping

On 11.03.2021 10:14, Pavel Dovgalyuk wrote:

In record/replay mode waiting for vCPU to execute
the task scheduled by run_on_cpu may lead to deadlock,
because when run_on_cpu is executed in main_loop
(e.g., in loadvm processing) it holds replay mutex.
This patch allows running scheduled task in iothread
when it holds the replay mutex.

Signed-off-by: Pavel Dovgalyuk 
---
  cpus-common.c|9 -
  include/sysemu/replay.h  |1 +
  replay/replay-internal.h |1 -
  stubs/replay-tools.c |5 +
  4 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/cpus-common.c b/cpus-common.c
index 6e73d3e58d..38ff510175 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -23,6 +23,7 @@
  #include "hw/core/cpu.h"
  #include "sysemu/cpus.h"
  #include "qemu/lockable.h"
+#include "sysemu/replay.h"
  
  static QemuMutex qemu_cpu_list_lock;

  static QemuCond exclusive_cond;
@@ -136,7 +137,13 @@ void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, 
run_on_cpu_data data,
  {
  struct qemu_work_item wi;
  
-if (qemu_cpu_is_self(cpu)) {

+if (qemu_cpu_is_self(cpu)
+/*
+ * vCPU thread is waiting when replay mutex is locked
+ * and the task is not exclusive, the function may be called
+ * without other synchronization.
+ */
+|| (replay_mode != REPLAY_MODE_NONE && replay_mutex_locked())) {
  func(cpu, data);
  return;
  }
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 0f3b0f7eac..032256533b 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -62,6 +62,7 @@ extern char *replay_snapshot;
  
  void replay_mutex_lock(void);

  void replay_mutex_unlock(void);
+bool replay_mutex_locked(void);
  
  /* Replay process control functions */
  
diff --git a/replay/replay-internal.h b/replay/replay-internal.h

index 97649ed8d7..dada623527 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -117,7 +117,6 @@ void replay_get_array_alloc(uint8_t **buf, size_t *size);
   * synchronisation between vCPU and main-loop threads. */
  
  void replay_mutex_init(void);

-bool replay_mutex_locked(void);
  
  /*! Checks error status of the file. */

  void replay_check_error(void);
diff --git a/stubs/replay-tools.c b/stubs/replay-tools.c
index 43296b3d4e..a42f2483d5 100644
--- a/stubs/replay-tools.c
+++ b/stubs/replay-tools.c
@@ -48,6 +48,11 @@ void replay_mutex_unlock(void)
  {
  }
  
+bool replay_mutex_locked(void)

+{
+return false;
+}
+
  void replay_register_char_driver(Chardev *chr)
  {
  }






Re: [PATCH v3] multi-process: Initialize variables declared with g_auto*

2021-03-14 Thread Miroslav Rezanina
On Fri, Mar 12, 2021 at 07:21:43PM +0800, Zenghui Yu wrote:
> Quote docs/devel/style.rst (section "Automatic memory deallocation"):
> 
> * Variables declared with g_auto* MUST always be initialized,
>   otherwise the cleanup function will use uninitialized stack memory
> 
> Initialize @name properly to get rid of the compilation error (using
> gcc-7.3.0 on CentOS):
> 
> ../hw/remote/proxy.c: In function 'pci_proxy_dev_realize':
> /usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: 'name' may be 
> used uninitialized in this function [-Werror=maybe-uninitialized]
>g_free (*pp);
>^~~~
> ../hw/remote/proxy.c:350:30: note: 'name' was declared here
>  g_autofree char *name;
>   ^~~~
> 
> Signed-off-by: Zenghui Yu 
> Reviewed-by: Jagannathan Raman 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
> * From v2:
>   - Add OS distro and compiler version into commit message
>   - Add Philippe's R-b
>   - Cc: qemu-triv...@nongnu.org
> 
>  hw/remote/memory.c | 5 ++---
>  hw/remote/proxy.c  | 3 +--
>  2 files changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/remote/memory.c b/hw/remote/memory.c
> index 32085b1e05..d97947d4b8 100644
> --- a/hw/remote/memory.c
> +++ b/hw/remote/memory.c
> @@ -42,10 +42,9 @@ void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp)
>  
>  remote_sysmem_reset();
>  
> -for (region = 0; region < msg->num_fds; region++) {
> -g_autofree char *name;
> +for (region = 0; region < msg->num_fds; region++, suffix++) {
> +g_autofree char *name = g_strdup_printf("remote-mem-%u", suffix);
>  subregion = g_new(MemoryRegion, 1);
> -name = g_strdup_printf("remote-mem-%u", suffix++);
>  memory_region_init_ram_from_fd(subregion, NULL,
> name, sysmem_info->sizes[region],
> true, msg->fds[region],
> diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
> index 4fa4be079d..6dda705fc2 100644
> --- a/hw/remote/proxy.c
> +++ b/hw/remote/proxy.c
> @@ -347,13 +347,12 @@ static void probe_pci_info(PCIDevice *dev, Error **errp)
> PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
>  
>  if (size) {
> -g_autofree char *name;
> +g_autofree char *name = g_strdup_printf("bar-region-%d", i);
>  pdev->region[i].dev = pdev;
>  pdev->region[i].present = true;
>  if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
>  pdev->region[i].memory = true;
>  }
> -name = g_strdup_printf("bar-region-%d", i);
>  memory_region_init_io(>region[i].mr, OBJECT(pdev),
>_mr_ops, >region[i],
>name, size);
> -- 
> 2.19.1
> 
> 

Missing declaration without initialization in hw/s390x/s390-pci-vfio.c
othwerwise correct. Will you send v4 with missing initialization or
should I send then as another patch?

Mirek




Re: [PULL 00/16] Net patches

2021-03-14 Thread Thomas Huth

On 14/03/2021 12.37, Peter Maydell wrote:

On Fri, 12 Mar 2021 at 06:16, Jason Wang  wrote:


The following changes since commit f4abdf32714d1845b7c01ec136dd2b04c2f7db47:

   Merge remote-tracking branch 
'remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2' into staging 
(2021-03-11 16:20:58 +)

are available in the git repository at:

   https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to 9bdb56367679e68e5e71a1c29a1087bda6414b25:

   pvrdma: wean code off pvrdma_ring.h kernel header (2021-03-12 14:08:31 +0800)





Hi; this has a merge conflict in net/nic.c relating to
ID generation: it looks like
"net: unbreak well-form id check for "-nic" (in this pullreq)


Uh, I haven't seen that patch on the list, when did you send it?

Also what about:

 https://patchew.org/QEMU/20210303095910.78277-1-lekir...@yandex-team.ru/

... that has been on the list since quite a while already and should maybe 
go into v6.0, too?


 Thomas




Re: [RFC] nbd: decouple reconnect from drain

2021-03-14 Thread Roman Kagan
On Fri, Mar 12, 2021 at 03:35:25PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> 10.03.2021 12:32, Roman Kagan wrote:
> > NBD connect coroutine takes an extra in_flight reference as if it's a
> > request handler.  This prevents drain from completion until the
> > connection coroutine is releases the reference.
> > 
> > When NBD is configured to reconnect, however, this appears to be fatal
> > to the reconnection idea: the drain procedure wants the reconnection to
> > be suspended, but this is only possible if the in-flight requests are
> > canceled.
> 
> As I remember from our conversation, the problem is not that we don't
> reconnect during drained section, but exactly that we cancel requests
> on drained begins starting from 8c517de24a8a1dcbeb.

Well, I'd put it the other way around: the problem is that we don't
reconnect during the drained section, so the requests can't be
successfully completed if the connection breaks: they can either stall
forever (before 8c517de24a8a1dcbeb) or be aborted (after
8c517de24a8a1dcbeb).

> This is not a problem in scenarios when reconnect is rare case and
> failed request is acceptable. But if we have bad connection and
> requests should often wait for reconnect (so, it may be considered as
> a kind of "latency") then really, cancelling the waiting requests on
> any drain() kills the reconnect feature.

In our experience the primary purpose of reconnect is not to withstand
poor network links, but about being able to restart the NBD server
without disrupting the guest operation.  So failing the requests during
the server maintenance window is never acceptable, no matter how rare it
is (and in our practice it isn't).

> > Fix this by making the connection coroutine stop messing with the
> > in-flight counter.  Instead, certain care is taken to properly move the
> > reconnection stuff from one aio_context to another in
> > .bdrv_{attach,detach}_aio_context callbacks.
> > 
> > Fixes: 5ad81b4946 ("nbd: Restrict connection_co reentrance")
> > Signed-off-by: Roman Kagan 
> > ---
> > This patch passes the regular make check but fails some extra iotests,
> > in particular 277.  It obviously lacks more robust interaction with the
> > connection thread (which in general is fairly complex and hard to reason
> > about), and perhaps has some other drawbacks, so I'll work on this
> > further, but I'd appreciate some feedback on whether the idea is sound.
> > 
> 
> In general I like the idea. The logic around drain in nbd is
> overcomplicated. And I never liked the fact that nbd_read_eof() does
> dec-inc inflight section. Some notes:
> 
> 1. I hope, the patch can be divided into several ones, as there are
> several things done:
> 
> - removing use of in_flight counter introduced by 5ad81b4946
> - do reconnect during drained section
> - stop cancelling requests on .drained_begin

I've split the (somewhat extended) patch into a series of 7, but not
exactly as you suggested.  In particular, I can't just stop aborting the
requests on .drained_begin as this would reintroduce the deadlock, so I
just remove the whole .drained_begin/end in a single patch.

> 2. 5ad81b4946 was needed to make nbd_client_attach_aio_context()
> reenter connection_co only in one (or two) possible places, not on any
> yield.. And I don't see how it is achieved now.. This should be
> described in commit msg..

My problem is that I failed to figure out why it was necessary in the
first place, so I think I don't achieve this with the series.

> 3. About cancelling requests on drained_begin. The behavior was
> introduced by 8c517de24a8a1dcbeb, to fix a deadlock. So, if now the
> deadlock is fixed another way, let's change the logic (don't cancel
> requests) in a separate patch, and note 8c517de24a8a1dcbeb commit and
> the commit that fixes deadlock the other way in the commit message.

As I mentioned earlier I did a patch that removed the root cause; a
separate patch removing just the request cancelation didn't look
justified.  I did mention the commits in the log.

Thanks for the review!  I'm now on to submitting a non-RFC version.
Roman.



Re: [PATCH] utils: Use fma in qemu_strtosz

2021-03-14 Thread Thomas Huth

On 15/03/2021 00.48, Richard Henderson wrote:

Use fma to simulatneously scale and round up fraction.

The libm function will always return a properly rounded double precision
value, which will eliminate any extra precision the x87 co-processor may
give us, which will keep the output predictable vs other hosts.

Adding DBL_EPSILON while scaling should help with fractions like
12.345, where the closest representable number is actually 12.3449*.

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

diff --git a/util/cutils.c b/util/cutils.c
index d89a40a8c3..f7f8e48a68 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -342,7 +342,7 @@ static int do_strtosz(const char *nptr, const char **end,
  retval = -ERANGE;
  goto out;
  }
-*result = val * mul + (uint64_t) (fraction * mul);
+*result = val * mul + (uint64_t)fma(fraction, mul, DBL_EPSILON);
  retval = 0;
  
  out:


Will this fix the failure that we're currently seeing with 32-bit builds?

( https://gitlab.com/qemu-project/qemu/-/jobs/1096980112#L3258 for example )

Reviewed-by: Thomas Huth 




Re: [RFC PATCH 4/8] qtest/fuzz: Restrict CPU I/O instructions

2021-03-14 Thread Thomas Huth

On 15/03/2021 00.29, Philippe Mathieu-Daudé wrote:

Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/qtest/fuzz/generic_fuzz.c   | 16 ++--
  tests/qtest/fuzz/qtest_wrappers.c |  4 
  2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index ee8c17a04c4..3e0089f4a63 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -304,6 +304,13 @@ static bool get_io_address(address_range *result, 
AddressSpace *as,
  return cb_info.found;
  }
  
+static bool get_mmio_address(address_range *result,

+ uint8_t index, uint32_t offset)
+{
+return get_io_address(result, _space_memory, index, offset);
+}
+
+#ifdef TARGET_HAS_IOPORT


Sorry, but the qtests are generic code, I don't think we should introduce 
target specific ifdefs here...?


 Thomas




Re: [PATCH] Hexagon (target/hexagon) fix typo in comment

2021-03-14 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/1615784115-26559-1-git-send-email-tsimp...@quicinc.com/



Hi,

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

Type: series
Message-id: 1615784115-26559-1-git-send-email-tsimp...@quicinc.com
Subject: [PATCH] Hexagon (target/hexagon) fix typo in comment

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
ffe0b01 Hexagon (target/hexagon) fix typo in comment

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

total: 1 errors, 0 warnings, 8 lines checked

Commit ffe0b013056f (Hexagon (target/hexagon) fix typo in comment) has style 
problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

[PATCH] Hexagon (target/hexagon) fix typo in comment

2021-03-14 Thread Taylor Simpson
Signed-of-by: Taylor Simpson 
---
 target/hexagon/op_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 9f19007..7361a07 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -297,7 +297,7 @@ int32_t HELPER(fcircadd)(int32_t RxV, int32_t offset, 
int32_t M, int32_t CS)
 }
 
 /*
- * Hexagon FP operations return ~0 insteat of NaN
+ * Hexagon FP operations return ~0 instead of NaN
  * The hex_check_sfnan/hex_check_dfnan functions perform this check
  */
 static float32 hex_check_sfnan(float32 x)
-- 
2.7.4




Re: [PATCH V3 1/8] hw/block/nvme: support namespace detach

2021-03-14 Thread Keqian Zhu
Hi,

I don't dig into code logic, just some nit below.

On 2021/3/1 0:10, Minwoo Im wrote:
> Given that now we have nvme-subsys device supported, we can manage
> namespace allocated, but not attached: detached.  This patch introduced
s/introduced/introduces

> a parameter for nvme-ns device named 'detached'.  This parameter
> indicates whether the given namespace device is detached from
> a entire NVMe subsystem('subsys' given case, shared namespace) or a
> controller('bus' given case, private namespace).
> 
> - Allocated namespace
> 
>   1) Shared ns in the subsystem 'subsys0':
> 
>  -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,subsys=subsys0,detached=true
> 
>   2) Private ns for the controller 'nvme0' of the subsystem 'subsys0':
> 
>  -device nvme-subsys,id=subsys0
>  -device nvme,serial=foo,id=nvme0,subsys=subsys0
>  -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
> 
>   3) (Invalid case) Controller 'nvme0' has no subsystem to manage ns:
> 
>  -device nvme,serial=foo,id=nvme0
>  -device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
> 
> Signed-off-by: Minwoo Im 
> Tested-by: Klaus Jensen 
> Reviewed-by: Klaus Jensen 
> ---
>  hw/block/nvme-ns.c |  1 +
>  hw/block/nvme-ns.h |  1 +
>  hw/block/nvme-subsys.h |  1 +
>  hw/block/nvme.c| 41 +++--
>  hw/block/nvme.h| 22 ++
>  5 files changed, 64 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
> index 0e8760020483..eda6a0c003a4 100644
> --- a/hw/block/nvme-ns.c
> +++ b/hw/block/nvme-ns.c
> @@ -399,6 +399,7 @@ static Property nvme_ns_props[] = {
>  DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
>  DEFINE_PROP_LINK("subsys", NvmeNamespace, subsys, TYPE_NVME_SUBSYS,
>   NvmeSubsystem *),
> +DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false),
>  DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
>  DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
>  DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128),
> diff --git a/hw/block/nvme-ns.h b/hw/block/nvme-ns.h
> index 7af6884862b5..b0c00e115d81 100644
> --- a/hw/block/nvme-ns.h
> +++ b/hw/block/nvme-ns.h
> @@ -26,6 +26,7 @@ typedef struct NvmeZone {
>  } NvmeZone;
>  
>  typedef struct NvmeNamespaceParams {
> +bool detached;
>  uint32_t nsid;
>  QemuUUID uuid;
>  
> diff --git a/hw/block/nvme-subsys.h b/hw/block/nvme-subsys.h
> index ccf6a71398d3..890d118117dc 100644
> --- a/hw/block/nvme-subsys.h
> +++ b/hw/block/nvme-subsys.h
> @@ -23,6 +23,7 @@ typedef struct NvmeSubsystem {
>  uint8_t subnqn[256];
>  
>  NvmeCtrl*ctrls[NVME_SUBSYS_MAX_CTRLS];
> +/* Allocated namespaces for this subsystem */
>  NvmeNamespace *namespaces[NVME_SUBSYS_MAX_NAMESPACES];
>  } NvmeSubsystem;
>  
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index edd0b85c10ce..f6aeae081840 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -23,7 +23,7 @@
>   *  max_ioqpairs=, \
>   *  aerl=, aer_max_queued=, \
>   *  mdts=,zoned.append_size_limit=, \
> - *  subsys= \
> + *  subsys=,detached=
>   *  -device nvme-ns,drive=,bus=,nsid=,\
>   *  zoned=, \
>   *  subsys=
> @@ -82,6 +82,13 @@
>   *   controllers in the subsystem. Otherwise, `bus` must be given to attach
>   *   this namespace to a specified single controller as a non-shared 
> namespace.
>   *
> + * - `detached`
> + *   Not to attach the namespace device to controllers in the NVMe subsystem
> + *   during boot-up. If not given, namespaces are all attahced to all
s/attahced/attached

> + *   controllers in the subsystem by default.
> + *   It's mutual exclusive with 'bus' parameter. It's only valid in case
> + *   `subsys` is provided.
> + *
>   * Setting `zoned` to true selects Zoned Command Set at the namespace.
>   * In this case, the following namespace properties are available to 
> configure
>   * zoned operation:
> @@ -4613,6 +4620,20 @@ static void nvme_init_state(NvmeCtrl *n)
>  n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1);
>  }
>  
> +static int nvme_attach_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error 
> **errp)
> +{
> +if (nvme_ns_is_attached(n, ns)) {
> +error_setg(errp,
> +   "namespace %d is already attached to controller %d",
> +   nvme_nsid(ns), n->cntlid);
> +return -1;
> +}
> +
> +nvme_ns_attach(n, ns);
> +
> +return 0;
> +}
> +
>  int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
>  {
>  uint32_t nsid = nvme_nsid(ns);
> @@ -4644,7 +4665,23 @@ int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace 
> *ns, Error **errp)
>  
>  trace_pci_nvme_register_namespace(nsid);
>  
> -n->namespaces[nsid - 1] = ns;
> +/*
> + * If subsys is not given, namespae is 

[PATCH] Hexagon (target/hexagon) remove unnecessary semicolons

2021-03-14 Thread Taylor Simpson
Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index e044dea..a30048e 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -83,9 +83,9 @@
 #define fGEN_TCG_L2_loadrub_pr(SHORTCODE)  SHORTCODE
 #define fGEN_TCG_L2_loadrub_pi(SHORTCODE)  SHORTCODE
 #define fGEN_TCG_L2_loadrb_pr(SHORTCODE)   SHORTCODE
-#define fGEN_TCG_L2_loadrb_pi(SHORTCODE)   SHORTCODE;
+#define fGEN_TCG_L2_loadrb_pi(SHORTCODE)   SHORTCODE
 #define fGEN_TCG_L2_loadruh_pr(SHORTCODE)  SHORTCODE
-#define fGEN_TCG_L2_loadruh_pi(SHORTCODE)  SHORTCODE;
+#define fGEN_TCG_L2_loadruh_pi(SHORTCODE)  SHORTCODE
 #define fGEN_TCG_L2_loadrh_pr(SHORTCODE)   SHORTCODE
 #define fGEN_TCG_L2_loadrh_pi(SHORTCODE)   SHORTCODE
 #define fGEN_TCG_L2_loadri_pr(SHORTCODE)   SHORTCODE
-- 
2.7.4




[PATCH] Hexagon (target/hexagon) TCG generation cleanup

2021-03-14 Thread Taylor Simpson
Simplify TCG generation of hex_reg_written

Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson 
---
 target/hexagon/genptr.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 7481f4c..0ad63fe 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -43,9 +43,15 @@ static inline void gen_log_predicated_reg_write(int rnum, 
TCGv val, int slot)
 tcg_gen_movcond_tl(TCG_COND_EQ, hex_new_value[rnum], slot_mask, zero,
val, hex_new_value[rnum]);
 #if HEX_DEBUG
-/* Do this so HELPER(debug_commit_end) will know */
-tcg_gen_movcond_tl(TCG_COND_EQ, hex_reg_written[rnum], slot_mask, zero,
-   one, hex_reg_written[rnum]);
+/*
+ * Do this so HELPER(debug_commit_end) will know
+ *
+ * Note that slot_mask indicates the value is not written
+ * (i.e., slot was cancelled), so we negate the value before
+ * or'ing with hex_reg_written[rnum].
+ */
+tcg_gen_xori_tl(slot_mask, slot_mask, 1 << slot);
+tcg_gen_or_tl(hex_reg_written[rnum], hex_reg_written[rnum], slot_mask);
 #endif
 
 tcg_temp_free(one);
-- 
2.7.4




[PATCH] Hexagon (target/hexagon) remove unnecessary checks in find_iclass_slots

2021-03-14 Thread Taylor Simpson
Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson 
---
 target/hexagon/iclass.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/target/hexagon/iclass.c b/target/hexagon/iclass.c
index 378d8a6..6091286 100644
--- a/target/hexagon/iclass.c
+++ b/target/hexagon/iclass.c
@@ -53,10 +53,6 @@ SlotMask find_iclass_slots(Opcode opcode, int itype)
(opcode == Y2_isync) ||
(opcode == J2_pause) || (opcode == J4_hintjumpr)) {
 return SLOTS_2;
-} else if ((itype == ICLASS_V2LDST) && (GET_ATTRIB(opcode, A_STORE))) {
-return SLOTS_01;
-} else if ((itype == ICLASS_V2LDST) && (!GET_ATTRIB(opcode, A_STORE))) {
-return SLOTS_01;
 } else if (GET_ATTRIB(opcode, A_CRSLOT23)) {
 return SLOTS_23;
 } else if (GET_ATTRIB(opcode, A_RESTRICT_PREFERSLOT0)) {
-- 
2.7.4




[PATCH] Hexagon (target/hexagon) change DECODE_MAPPED_REG operand name to OPNUM

2021-03-14 Thread Taylor Simpson
Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson 
---
 target/hexagon/decode.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index c9bacaa..1c9c074 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -48,8 +48,8 @@ enum {
 DEF_REGMAP(R_16,  16, 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23)
 DEF_REGMAP(R__8,  8,  0, 2, 4, 6, 16, 18, 20, 22)
 
-#define DECODE_MAPPED_REG(REGNO, NAME) \
-insn->regno[REGNO] = DECODE_REGISTER_##NAME[insn->regno[REGNO]];
+#define DECODE_MAPPED_REG(OPNUM, NAME) \
+insn->regno[OPNUM] = DECODE_REGISTER_##NAME[insn->regno[OPNUM]];
 
 typedef struct {
 const struct DectreeTable *table_link;
-- 
2.7.4




[PATCH] Hexagon (target/hexagon) translation changes

2021-03-14 Thread Taylor Simpson
Change cpu_ldl_code to translator_ldl
Don't end the TB after every packet when HEX_DEBUG is on
Make gen_check_store_width a simple call

Address feedback from Richard Henderson <

Signed-off-by: Taylor Simpson 
---
 target/hexagon/translate.c | 26 +-
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index eeaad5f..2317508 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -88,8 +88,8 @@ static int read_packet_words(CPUHexagonState *env, 
DisasContext *ctx,
 
 memset(words, 0, PACKET_WORDS_MAX * sizeof(uint32_t));
 for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) {
-words[nwords] = cpu_ldl_code(env,
-ctx->base.pc_next + nwords * sizeof(uint32_t));
+words[nwords] =
+translator_ldl(env, ctx->base.pc_next + nwords * sizeof(uint32_t));
 found_end = is_packet_end(words[nwords]);
 }
 if (!found_end) {
@@ -292,20 +292,16 @@ static void gen_pred_writes(DisasContext *ctx, Packet 
*pkt)
 tcg_temp_free(pval);
 }
 
-#if HEX_DEBUG
-static inline void gen_check_store_width(DisasContext *ctx, int slot_num)
+static void gen_check_store_width(DisasContext *ctx, int slot_num)
 {
+#if HEX_DEBUG
 TCGv slot = tcg_const_tl(slot_num);
 TCGv check = tcg_const_tl(ctx->store_width[slot_num]);
 gen_helper_debug_check_store_width(cpu_env, slot, check);
 tcg_temp_free(slot);
 tcg_temp_free(check);
-}
-#define HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num) \
-gen_check_store_width(ctx, slot_num)
-#else
-#define HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num)  /* nothing */
 #endif
+}
 
 static bool slot_is_predicated(Packet *pkt, int slot_num)
 {
@@ -355,25 +351,25 @@ void process_store(DisasContext *ctx, Packet *pkt, int 
slot_num)
  */
 switch (ctx->store_width[slot_num]) {
 case 1:
-HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num);
+gen_check_store_width(ctx, slot_num);
 tcg_gen_qemu_st8(hex_store_val32[slot_num],
  hex_store_addr[slot_num],
  ctx->mem_idx);
 break;
 case 2:
-HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num);
+gen_check_store_width(ctx, slot_num);
 tcg_gen_qemu_st16(hex_store_val32[slot_num],
   hex_store_addr[slot_num],
   ctx->mem_idx);
 break;
 case 4:
-HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num);
+gen_check_store_width(ctx, slot_num);
 tcg_gen_qemu_st32(hex_store_val32[slot_num],
   hex_store_addr[slot_num],
   ctx->mem_idx);
 break;
 case 8:
-HEX_DEBUG_GEN_CHECK_STORE_WIDTH(ctx, slot_num);
+gen_check_store_width(ctx, slot_num);
 tcg_gen_qemu_st64(hex_store_val64[slot_num],
   hex_store_addr[slot_num],
   ctx->mem_idx);
@@ -593,10 +589,6 @@ static void hexagon_tr_translate_packet(DisasContextBase 
*dcbase, CPUState *cpu)
 if (hex_cpu->lldb_compat && qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
 ctx->base.is_jmp = DISAS_TOO_MANY;
 }
-#if HEX_DEBUG
-/* When debugging, only put one packet per TB */
-ctx->base.is_jmp = DISAS_TOO_MANY;
-#endif
 }
 }
 
-- 
2.7.4




Re: [PULL 00/16] Net patches

2021-03-14 Thread Jason Wang


> 2021年3月14日 下午7:37,Peter Maydell  写道:
> 
> On Fri, 12 Mar 2021 at 06:16, Jason Wang  > wrote:
>> 
>> The following changes since commit f4abdf32714d1845b7c01ec136dd2b04c2f7db47:
>> 
>>  Merge remote-tracking branch 
>> 'remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2' into staging 
>> (2021-03-11 16:20:58 +)
>> 
>> are available in the git repository at:
>> 
>>  https://github.com/jasowang/qemu.git tags/net-pull-request
>> 
>> for you to fetch changes up to 9bdb56367679e68e5e71a1c29a1087bda6414b25:
>> 
>>  pvrdma: wean code off pvrdma_ring.h kernel header (2021-03-12 14:08:31 
>> +0800)
>> 
>> 
>> 
> 
> Hi; this has a merge conflict in net/nic.c relating to
> ID generation: it looks like
> "net: unbreak well-form id check for "-nic" (in this pullreq)
> "net: Use id_generate() in the network subsystem, too" (in master)
> are both changing the way that NIC ID strings are created, and
> I don't know which is supposed to be the correct way.
> 
> Please can you fix up the conflict appropriately and resend?

Will do.

Thanks


> 
> thanks
> -- PMM



[Bug 1919036] Re: Assertion failure in fifo8_push_all() through am53c974

2021-03-14 Thread Cheolwoo,Myung
Hello Mark,

I tested on fixed version, and checked that it does not trigger the
assertion failure.

Thanks,
- Cheolwoo Myung

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

Title:
  Assertion failure in fifo8_push_all() through am53c974

Status in QEMU:
  New

Bug description:
  Hello,

  Using hypervisor fuzzer, hyfuzz, I found an assertion failure through
  am53c974 emulator.

  A malicious guest user/process could use this flaw to abort the QEMU
  process on the host, resulting in a denial of service.

  This was found in version 5.2.0 (master, 3f8d1885e4)

  
  ```
  qemu-system-i386: ../util/fifo8.c:43: fifo8_push_all: Assertion `fifo->num + 
num <= fifo->capacity' failed.

  #0  0x70218fb7 in __GI_raise (sig=sig@entry=0x6) at 
../sysdeps/unix/sysv/linux/raise.c:51
  #1  0x7021a921 in __GI_abort () at abort.c:79
  #2  0x7020a48a in __assert_fail_base (fmt=0x70391750 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x58ed2400 
"fifo->num + num <= fifo->capacity", file=file@entry=0x58ed2380 
"../util/fifo8.c", line=line@entry=0x2b, function=function@entry=0x58ed2560 
<__PRETTY_FUNCTION__.16583> "fifo8_push_all")
  at assert.c:92
  #3  0x7020a502 in __GI___assert_fail 
(assertion=assertion@entry=0x58ed2400 "fifo->num + num <= fifo->capacity", 
file=file@entry=0x58ed2380 "../util/fifo8.c", line=line@entry=0x2b, 
function=function@entry=0x58ed2560 <__PRETTY_FUNCTION__.16583> 
"fifo8_push_all") at assert.c:101
  #4  0x587749c4 in fifo8_push_all (fifo=fifo@entry=0x61f05200, 
data=data@entry=0x7fff72bfa640 "", num=num@entry=0x24) at ../util/fifo8.c:43
  #5  0x572bd13e in esp_do_dma (s=s@entry=0x61f05088) at 
../hw/scsi/esp.c:577
  #6  0x572bfc8f in handle_ti (s=0x61f05088) at ../hw/scsi/esp.c:845
  #7  0x572c419c in esp_reg_write (s=0x61f05088, 
saddr=saddr@entry=0x3, val=)
  at ../hw/scsi/esp.c:987
  #8  0x57bb916a in esp_pci_io_write (opaque=0x61f04680, 
addr=, val=, size=) at 
../hw/scsi/esp-pci.c:214
  #9  0x5817ea28 in memory_region_write_accessor (mr=0x61f04f70, 
addr=, value=, size=, 
shift=, mask=, attrs=...) at 
../softmmu/memory.c:491
  #10 0x58176671 in access_with_adjusted_size (addr=addr@entry=0xc, 
value=value@entry=0x7fff72bfb2a8, size=size@entry=0x1, 
access_size_min=, access_size_max=, access_fn=
  0x5817e7c0 , mr=0x61f04f70, 
attrs=...) at ../softmmu/memory.c:552
  #11 0x581892aa in memory_region_dispatch_write 
(mr=mr@entry=0x61f04f70, addr=, data=, 
data@entry=0xff90, op=op@entry=MO_8, attrs=..., attrs@entry=...) at 
../softmmu/memory.c:1508
  #12 0x58024b66 in address_space_stb (as=, 
addr=, val=, attrs=..., result=0x0) at 
/home/cwmyung/prj/hyfuzz/src/qemu-master/memory_ldst.c.inc:382
  #13 0x7fff9323641c in code_gen_buffer ()
  #14 0x57e793bb in cpu_tb_exec (tb_exit=, 
itb=, cpu=0x62e004b4)
  at ../accel/tcg/cpu-exec.c:190
  #15 0x57e793bb in cpu_loop_exec_tb (tb_exit=, 
last_tb=, tb=, cpu=0x62e004b4) at 
../accel/tcg/cpu-exec.c:673
  #16 0x57e793bb in cpu_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/cpu-exec.c:798
  #17 0x57f5fc5a in tcg_cpus_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/tcg-accel-ops.c:68
  #18 0x582260af in mttcg_cpu_thread_fn (arg=arg@entry=0x62e00400) 
at ../accel/tcg/tcg-accel-ops-mttcg.c:70
  #19 0x58777b05 in qemu_thread_start (args=) at 
../util/qemu-thread-posix.c:521
  #20 0x705d26db in start_thread (arg=0x7fff72bff700) at 
pthread_create.c:463
  #21 0x702fb71f in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:95
  ```

  
  To reproduce the assertion failure, please run the QEMU with the following 
command line.

  ```

  $ ./qemu-system-i386 -m 512 -drive
  file=./hyfuzz.img,index=0,media=disk,format=raw -device
  am53c974,id=scsi -device scsi-hd,drive=SysDisk -drive
  id=SysDisk,if=none,file=./disk.img

  ```

  Please let me know if I can provide any further info.

  Thank you.

  - Cheolwoo, Myung (Seoul National University)

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



[Bug 1907909] Re: assertion failure in am53c974

2021-03-14 Thread Alexander Bulekov
It looks like this reproducer  triggers the same bug as #1919036, as of
3f8d1885e

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

Title:
  assertion failure in am53c974

Status in QEMU:
  New

Bug description:
  Hello,

  Using hypervisor fuzzer, hyfuzz, I found an assertion failure through
  am53c974 emulator.

  A malicious guest user/process could use this flaw to abort the QEMU
  process on the host, resulting in a denial of service.

  This was found in version 5.2.0 (master)

  
  qemu-system-i386: ../hw/scsi/esp.c:402: void esp_do_dma(ESPState *): 
Assertion `s->cmdlen <= sizeof(s->cmdbuf) && len <= sizeof(s->cmdbuf) - 
s->cmdlen' failed.

  #0  __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
  51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
  [Current thread is 1 (Thread 0x7fdd25dc4700 (LWP 28983))]
  gdb-peda$ bt
  #0  0x7fdd3f8b5f47 in __GI_raise (sig=sig@entry=0x6) at 
../sysdeps/unix/sysv/linux/raise.c:51
  #1  0x7fdd3f8b78b1 in __GI_abort () at abort.c:79
  #2  0x7fdd3f8a742a in __assert_fail_base (fmt=0x7fdd3fa2ea38 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\\n%n", assertion=assertion@entry=0x55b3e11a51c6 
"s->cmdlen <= sizeof(s->cmdbuf) && len <= sizeof(s->cmdbuf) - s->cmdlen", 
file=file@entry=0x55b3e11a4f73 "../hw/scsi/esp.c", line=line@entry=0x192, 
function=function@entry=0x55b3e11a520d "void esp_do_dma(ESPState *)") at 
assert.c:92
  #3  0x7fdd3f8a74a2 in __GI___assert_fail (assertion=0x55b3e11a51c6 
"s->cmdlen <= sizeof(s->cmdbuf) && len <= sizeof(s->cmdbuf) - s->cmdlen", 
file=0x55b3e11a4f73 "../hw/scsi/esp.c", line=0x192, function=0x55b3e11a520d 
"void esp_do_dma(ESPState *)") at assert.c:101
  #4  0x55b3e0941441 in esp_do_dma (s=0x55b3e49d1c88) at 
../hw/scsi/esp.c:401
  #5  0x55b3e0944261 in handle_ti (s=0x55b3e49d1c88) at ../hw/scsi/esp.c:549
  #6  0x55b3e093fdf9 in esp_dma_enable (s=0x55b3e49d1c88, irq=, level=)
  at ../hw/scsi/esp.c:79
  #7  0x55b3e0897930 in esp_pci_dma_write (pci=, 
saddr=, val=) at ../hw/scsi/esp-pci.c:83
  #8  0x55b3e0897930 in esp_pci_io_write (opaque=, 
addr=, val=0xcf, size=0x4) at ../hw/scsi/esp-pci.c:209
  #9  0x55b3e0e8f798 in memory_region_write_accessor (mr=, 
addr=, value=, size=, 
shift=, mask=, attrs=...)
  at ../softmmu/memory.c:491
  #10 0x55b3e0e8f58e in access_with_adjusted_size (addr=, 
value=, size=, access_size_min=, 
access_size_max=, access_fn=, mr=, 
attrs=...) at ../softmmu/memory.c:552
  #11 0x55b3e0e8f58e in memory_region_dispatch_write (mr=0x55b3e49d1b70, 
addr=, data=, op=, attrs=...) at 
../softmmu/memory.c:1501
  #12 0x55b3e0e21541 in address_space_stb (as=, 
addr=, val=0xffcf, attrs=..., result=0x0) at 
../memory_ldst.c.inc:382
  #13 0x7fdcd84a4a7f in code_gen_buffer ()
  #14 0x55b3e0e57da0 in cpu_tb_exec (cpu=0x55b3e3c33650, itb=)
  at ../accel/tcg/cpu-exec.c:178
  #15 0x55b3e0e589eb in cpu_loop_exec_tb (tb=, 
cpu=, last_tb=, tb_exit=) at ../accel/tcg/cpu-exec.c:658
  #16 0x55b3e0e589eb in cpu_exec (cpu=0x55b3e3c33650) at 
../accel/tcg/cpu-exec.c:771
  #17 0x55b3e0e87b9f in tcg_cpu_exec (cpu=) at 
../accel/tcg/tcg-cpus.c:243
  #18 0x55b3e0e87b9f in tcg_cpu_thread_fn (arg=0x55b3e3c33650) at 
../accel/tcg/tcg-cpus.c:427
  #19 0x55b3e115f775 in qemu_thread_start (args=) at 
../util/qemu-thread-posix.c:521
  #20 0x7fdd3fc6f6db in start_thread (arg=0x7fdd25dc4700) at 
pthread_create.c:463
  #21 0x7fdd3f998a3f in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:95

  To reproduce the assertion failure, please run the QEMU with the
  following command line.

  
  $ ./qemu-system-i386 -m 512 -drive 
file=./hyfuzz.img,index=0,media=disk,format=raw -device am53c974,id=scsi 
-device scsi-hd,drive=SysDisk -drive id=SysDisk,if=none,file=./disk.img

  Please let me know if I can provide any further info.

  Thank you.

  - Cheolwoo, Myung (Seoul National University)

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



[Bug 1909247] Re: QEMU: use after free vulnerability in esp_do_dma() in hw/scsi/esp.c

2021-03-14 Thread Alexander Bulekov
Looks the same, or very similar to this one:
/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, \
 * -m 4G -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001010
 * outl 0xcfc 0xc000
 * outl 0xcf8 0x80001004
 * outw 0xcfc 0x01
 * outl 0xc046 0x02
 * outl 0xc03f 0x0300
 * outw 0xc00b 0x4300
 * outl 0xc00b 0x9000
 * EOF
 */
static void test_fuzz(void)
{
QTestState *s = qtest_init(
"-display none , -m 4G -device am53c974,id=scsi -device "
"scsi-hd,drive=disk0 -drive "
"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
qtest_outl(s, 0xcf8, 0x80001010);
qtest_outl(s, 0xcfc, 0xc000);
qtest_outl(s, 0xcf8, 0x80001004);
qtest_outw(s, 0xcfc, 0x01);
qtest_outl(s, 0xc046, 0x02);
qtest_outl(s, 0xc03f, 0x0300);
qtest_outw(s, 0xc00b, 0x4300);
qtest_outl(s, 0xc00b, 0x9000);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();

g_test_init(, , NULL);

if (strcmp(arch, "i386") == 0) {
qtest_add_func("fuzz/test_fuzz", test_fuzz);
}

return g_test_run();
}

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

Title:
  QEMU: use after free vulnerability in esp_do_dma() in hw/scsi/esp.c

Status in QEMU:
  New

Bug description:
  A use-after-free vulnerability was found in the am53c974 SCSI host bus
  adapter emulation of QEMU. It could occur in the esp_do_dma() function
  in hw/scsi/esp.c while handling the 'Information Transfer' command
  (CMD_TI). A privileged guest user may abuse this flaw to crash the
  QEMU process on the host, resulting in a denial of service or
  potential code execution with the privileges of the QEMU process.

  This issue was reported by Cheolwoo Myung (Seoul National University).

  Original report:
  Using hypervisor fuzzer, hyfuzz, I found a use-after-free issue in
  am53c974 emulator of QEMU enabled ASan.

  It occurs while transferring information, as it does not check the
  buffer to be transferred.

  A malicious guest user/process could use this flaw to crash the QEMU
  process resulting in DoS scenario.

  To reproduce this issue, please run the QEMU with the following command
  line.

  # To enable ASan option, please set configuration with the following
  $ ./configure --target-list=i386-softmmu --disable-werror --enable-sanitizers
  $ make

  # To reproduce this issue, please run the QEMU process with the following 
command line
  $ ./qemu-system-i386 -m 512 -drive 
file=./hyfuzz.img,index=0,media=disk,format=raw \
  -device am53c974,id=scsi -device scsi-hd,drive=SysDisk \
  -drive id=SysDisk,if=none,file=./disk.img

  Please find attached the disk images to reproduce this issue.

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



[Bug 1919035] Re: Assertion failure in fifo8_pop_buf() through am53c974

2021-03-14 Thread Alexander Bulekov
QTest reproducer:

/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, \
 * -m 4G -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001004
 * outw 0xcfc 0x01
 * outl 0xcf8 0x8000100e
 * outl 0xcfc 0x8a00
 * outl 0x8a09 0x4200
 * outl 0x8a0d 0x00
 * outl 0x8a0b 0x1000
 * EOF
 */
static void test_fuzz(void)
{
QTestState *s = qtest_init(
"-display none , -m 4G -device am53c974,id=scsi -device "
"scsi-hd,drive=disk0 -drive "
"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
qtest_outl(s, 0xcf8, 0x80001004);
qtest_outw(s, 0xcfc, 0x01);
qtest_outl(s, 0xcf8, 0x8000100e);
qtest_outl(s, 0xcfc, 0x8a00);
qtest_outl(s, 0x8a09, 0x4200);
qtest_outl(s, 0x8a0d, 0x00);
qtest_outl(s, 0x8a0b, 0x1000);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();

g_test_init(, , NULL);

if (strcmp(arch, "i386") == 0) {
qtest_add_func("fuzz/test_fuzz", test_fuzz);
}

return g_test_run();
}

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

Title:
  Assertion failure in fifo8_pop_buf() through am53c974

Status in QEMU:
  New

Bug description:
  Hello,

  Using hypervisor fuzzer, hyfuzz, I found an assertion failure through
  am53c974 emulator.

  A malicious guest user/process could use this flaw to abort the QEMU
  process on the host, resulting in a denial of service.

  This was found in version 5.2.0 (master, 3f8d1885e4)

  
  ```
  qemu-system-i386: ../util/fifo8.c:73: fifo8_pop_buf: Assertion `max > 0 && 
max <= fifo->num' failed.

  #0  0x70218fb7 in __GI_raise (sig=sig@entry=0x6) at 
../sysdeps/unix/sysv/linux/raise.c:51
  #1  0x7021a921 in __GI_abort () at abort.c:79
  #2  0x7020a48a in __assert_fail_base (fmt=0x70391750 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x58ed24a0 "max 
> 0 && max <= fifo->num", file=file@entry=0x58ed2380 "../util/fifo8.c", 
line=line@entry=0x49, function=function@entry=0x58ed24e0 
<__PRETTY_FUNCTION__.16603> "fifo8_pop_buf") at assert.c:92
  #3  0x7020a502 in __GI___assert_fail 
(assertion=assertion@entry=0x58ed24a0 "max > 0 && max <= fifo->num", 
file=file@entry=0x58ed2380 "../util/fifo8.c", line=line@entry=0x49, 
function=function@entry=0x58ed24e0 <__PRETTY_FUNCTION__.16603> 
"fifo8_pop_buf") at assert.c:101
  #4  0x5877519a in fifo8_pop_buf (fifo=fifo@entry=0x61f05200, 
max=max@entry=0xff, num=num@entry=0x7fff72bfa550) at ../util/fifo8.c:73
  #5  0x572b7d9a in do_cmd (s=s@entry=0x61f05088) at 
../hw/scsi/esp.c:328
  #6  0x572b879a in esp_do_nodma (s=s@entry=0x61f05088) at 
../hw/scsi/esp.c:701
  #7  0x572bfd79 in handle_ti (s=0x61f05088) at ../hw/scsi/esp.c:848
  #8  0x572c419c in esp_reg_write (s=0x61f05088, 
saddr=saddr@entry=0x3, val=) at ../hw/scsi/esp.c:987
  #9  0x57bb916a in esp_pci_io_write (opaque=0x61f04680, 
addr=, val=, size=) at 
../hw/scsi/esp-pci.c:214
  #10 0x5817ea28 in memory_region_write_accessor (mr=0x61f04f70, 
addr=, value=, size=, 
shift=, mask=, attrs=...) at 
../softmmu/memory.c:491
  #11 0x58176671 in access_with_adjusted_size (addr=addr@entry=0xc, 
value=value@entry=0x7fff72bfb2a8, size=size@entry=0x1, 
access_size_min=, access_size_max=, access_fn=
  0x5817e7c0 , mr=0x61f04f70, 
attrs=...) at ../softmmu/memory.c:552
  #12 0x581892aa in memory_region_dispatch_write 
(mr=mr@entry=0x61f04f70, addr=, data=, 
data@entry=0x10, op=op@entry=MO_8, attrs=..., attrs@entry=...) at 
../softmmu/memory.c:1508
  #13 0x58024b66 in address_space_stb (as=, 
addr=, val=, attrs=..., result=0x0) at 
/home/cwmyung/prj/hyfuzz/src/qemu-master/memory_ldst.c.inc:382
  #14 0x7fff93236d3c in code_gen_buffer ()
  #15 0x57e793bb in cpu_tb_exec (tb_exit=, 
itb=, cpu=0x62e004b4) at ../accel/tcg/cpu-exec.c:190
  #16 0x57e793bb in cpu_loop_exec_tb (tb_exit=, 
last_tb=, tb=, cpu=0x62e004b4) at 
../accel/tcg/cpu-exec.c:673
  #17 0x57e793bb in cpu_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/cpu-exec.c:798
  #18 0x57f5fc5a in tcg_cpus_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/tcg-accel-ops.c:68
  #19 0x582260af in mttcg_cpu_thread_fn (arg=arg@entry=0x62e00400) 
at ../accel/tcg/tcg-accel-ops-mttcg.c:70
  #20 0x58777b05 in qemu_thread_start (args=) at 
../util/qemu-thread-posix.c:521
  #21 0x705d26db in start_thread 

RE: [PATCH v8 26/35] Hexagon (target/hexagon) TCG generation

2021-03-14 Thread Taylor Simpson


> -Original Message-
> From: Richard Henderson 
> Sent: Saturday, March 13, 2021 7:40 PM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com; alex.ben...@linaro.org; laur...@vivier.eu;
> a...@rev.ng; Brian Cain 
> Subject: Re: [PATCH v8 26/35] Hexagon (target/hexagon) TCG generation
>
> >> Except for HEX_DEBUG, why would we not know whether or not a
> predicate
> >> has been
> >> written twice?  It seems like we shouldn't need hex_pred_written for the
> >> non-debug case.
> >
> > It's legal to write to a predicate more than once in the same packet.
>
> I repeat -- why would you not know that?  You should be able to examine the
> packet and see whether it does or does not write to a predicate register
> more
> than once.
>
> Simply always generating code that assumes it has is lazy.

Sorry misunderstood the question - yes, it should be possible at TCG generation 
time (rather than TCG execution time) to determine if the predicate has already 
been written.  I will code this up.

Thanks,
Taylor



RE: [PATCH v8 29/35] Hexagon (target/hexagon) translation

2021-03-14 Thread Taylor Simpson

> -Original Message-
> From: Richard Henderson 
> Sent: Saturday, March 13, 2021 7:44 PM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com; alex.ben...@linaro.org; laur...@vivier.eu;
> a...@rev.ng; Brian Cain 
> Subject: Re: [PATCH v8 29/35] Hexagon (target/hexagon) translation
>
> >> -Original Message-
> >> From: Richard Henderson 
> >> Sent: Sunday, February 14, 2021 7:04 PM
> >> To: Taylor Simpson ; qemu-devel@nongnu.org
> >> Cc: phi...@redhat.com; alex.ben...@linaro.org; laur...@vivier.eu;
> >> a...@rev.ng; Brian Cain 
> >> Subject: Re: [PATCH v8 29/35] Hexagon (target/hexagon) translation
> >>
> >> On 2/7/21 9:46 PM, Taylor Simpson wrote:
> >>> +case DISAS_NORETURN:
> >>> +gen_exec_counters(ctx);
> >>> +tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
> >>> +if (ctx->base.singlestep_enabled) {
> >>> +gen_exception_debug();
> >>> +} else {
> >>> +tcg_gen_exit_tb(NULL, 0);
> >>> +}
> >>
> >> DISAS_NORETURN says that we have *already* exited the TB.  None of the 
> >> code you emit here will be reachable.
> >
> > Isn't this called before the TB ends?
>
> Yes, but DISAS_NORETURN still means we've already exited.
>
> Just like calling abort() in C means that we won't reach any following return 
> statement.

Then I'm missing something because the code emitted here does get executed.  I 
thought the tb_stop function is a place for the target to add code.  Should I 
push this up to all the places where we set ctx->base.is_jmp to DISAS_NORETURN?


Taylor



[Bug 1919036] Re: Assertion failure in fifo8_push_all() through am53c974

2021-03-14 Thread Alexander Bulekov
QTest Reproducer:
/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, \
 * -m 512M -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001004
 * outw 0xcfc 0x01
 * outl 0xcf8 0x8000100e
 * outl 0xcfc 0x0e00
 * outl 0xe40 0x03
 * outl 0xe0b 0x4100
 * outl 0xe0b 0x9000
 * EOF
 */
static void test_fuzz(void)
{
QTestState *s = qtest_init(
"-display none , -m 512M -device am53c974,id=scsi -device "
"scsi-hd,drive=disk0 -drive "
"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
qtest_outl(s, 0xcf8, 0x80001004);
qtest_outw(s, 0xcfc, 0x01);
qtest_outl(s, 0xcf8, 0x8000100e);
qtest_outl(s, 0xcfc, 0x0e00);
qtest_outl(s, 0xe40, 0x03);
qtest_outl(s, 0xe0b, 0x4100);
qtest_outl(s, 0xe0b, 0x9000);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();

g_test_init(, , NULL);

if (strcmp(arch, "i386") == 0) {
qtest_add_func("fuzz/test_fuzz", test_fuzz);
}

return g_test_run();
}

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

Title:
  Assertion failure in fifo8_push_all() through am53c974

Status in QEMU:
  New

Bug description:
  Hello,

  Using hypervisor fuzzer, hyfuzz, I found an assertion failure through
  am53c974 emulator.

  A malicious guest user/process could use this flaw to abort the QEMU
  process on the host, resulting in a denial of service.

  This was found in version 5.2.0 (master, 3f8d1885e4)

  
  ```
  qemu-system-i386: ../util/fifo8.c:43: fifo8_push_all: Assertion `fifo->num + 
num <= fifo->capacity' failed.

  #0  0x70218fb7 in __GI_raise (sig=sig@entry=0x6) at 
../sysdeps/unix/sysv/linux/raise.c:51
  #1  0x7021a921 in __GI_abort () at abort.c:79
  #2  0x7020a48a in __assert_fail_base (fmt=0x70391750 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x58ed2400 
"fifo->num + num <= fifo->capacity", file=file@entry=0x58ed2380 
"../util/fifo8.c", line=line@entry=0x2b, function=function@entry=0x58ed2560 
<__PRETTY_FUNCTION__.16583> "fifo8_push_all")
  at assert.c:92
  #3  0x7020a502 in __GI___assert_fail 
(assertion=assertion@entry=0x58ed2400 "fifo->num + num <= fifo->capacity", 
file=file@entry=0x58ed2380 "../util/fifo8.c", line=line@entry=0x2b, 
function=function@entry=0x58ed2560 <__PRETTY_FUNCTION__.16583> 
"fifo8_push_all") at assert.c:101
  #4  0x587749c4 in fifo8_push_all (fifo=fifo@entry=0x61f05200, 
data=data@entry=0x7fff72bfa640 "", num=num@entry=0x24) at ../util/fifo8.c:43
  #5  0x572bd13e in esp_do_dma (s=s@entry=0x61f05088) at 
../hw/scsi/esp.c:577
  #6  0x572bfc8f in handle_ti (s=0x61f05088) at ../hw/scsi/esp.c:845
  #7  0x572c419c in esp_reg_write (s=0x61f05088, 
saddr=saddr@entry=0x3, val=)
  at ../hw/scsi/esp.c:987
  #8  0x57bb916a in esp_pci_io_write (opaque=0x61f04680, 
addr=, val=, size=) at 
../hw/scsi/esp-pci.c:214
  #9  0x5817ea28 in memory_region_write_accessor (mr=0x61f04f70, 
addr=, value=, size=, 
shift=, mask=, attrs=...) at 
../softmmu/memory.c:491
  #10 0x58176671 in access_with_adjusted_size (addr=addr@entry=0xc, 
value=value@entry=0x7fff72bfb2a8, size=size@entry=0x1, 
access_size_min=, access_size_max=, access_fn=
  0x5817e7c0 , mr=0x61f04f70, 
attrs=...) at ../softmmu/memory.c:552
  #11 0x581892aa in memory_region_dispatch_write 
(mr=mr@entry=0x61f04f70, addr=, data=, 
data@entry=0xff90, op=op@entry=MO_8, attrs=..., attrs@entry=...) at 
../softmmu/memory.c:1508
  #12 0x58024b66 in address_space_stb (as=, 
addr=, val=, attrs=..., result=0x0) at 
/home/cwmyung/prj/hyfuzz/src/qemu-master/memory_ldst.c.inc:382
  #13 0x7fff9323641c in code_gen_buffer ()
  #14 0x57e793bb in cpu_tb_exec (tb_exit=, 
itb=, cpu=0x62e004b4)
  at ../accel/tcg/cpu-exec.c:190
  #15 0x57e793bb in cpu_loop_exec_tb (tb_exit=, 
last_tb=, tb=, cpu=0x62e004b4) at 
../accel/tcg/cpu-exec.c:673
  #16 0x57e793bb in cpu_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/cpu-exec.c:798
  #17 0x57f5fc5a in tcg_cpus_exec (cpu=cpu@entry=0x62e00400) at 
../accel/tcg/tcg-accel-ops.c:68
  #18 0x582260af in mttcg_cpu_thread_fn (arg=arg@entry=0x62e00400) 
at ../accel/tcg/tcg-accel-ops-mttcg.c:70
  #19 0x58777b05 in qemu_thread_start (args=) at 
../util/qemu-thread-posix.c:521
  #20 0x705d26db in start_thread (arg=0x7fff72bff700) at 
pthread_create.c:463
  

[Bug 1910723] Re: NULL pointer dereference issues in am53c974 SCSI host bus adapter

2021-03-14 Thread Alexander Bulekov
QTest Reproducer for the first:
/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, -m \
 * 512M -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001010
 * outl 0xcfc 0xc000
 * outl 0xcf8 0x80001004
 * outw 0xcfc 0x05
 * outb 0xc046 0x02
 * outl 0xc00b 0xc100
 * outl 0xc040 0x03
 * outl 0xc040 0x03
 * write 0x0 0x1 0x41
 * outl 0xc00b 0xc100
 * outw 0xc040 0x02
 * outw 0xc040 0x81
 * outl 0xc00b 0x9000
 * EOF
 */
static void test_fuzz(void)
{
QTestState *s = qtest_init(
"-display none , -m 512M -device am53c974,id=scsi -device "
"scsi-hd,drive=disk0 -drive "
"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
qtest_outl(s, 0xcf8, 0x80001010);
qtest_outl(s, 0xcfc, 0xc000);
qtest_outl(s, 0xcf8, 0x80001004);
qtest_outw(s, 0xcfc, 0x05);
qtest_outb(s, 0xc046, 0x02);
qtest_outl(s, 0xc00b, 0xc100);
qtest_outl(s, 0xc040, 0x03);
qtest_outl(s, 0xc040, 0x03);
qtest_bufwrite(s, 0x0, "\x41", 0x1);
qtest_outl(s, 0xc00b, 0xc100);
qtest_outw(s, 0xc040, 0x02);
qtest_outw(s, 0xc040, 0x81);
qtest_outl(s, 0xc00b, 0x9000);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();

g_test_init(, , NULL);

if (strcmp(arch, "i386") == 0) {
qtest_add_func("fuzz/test_fuzz", test_fuzz);
}

return g_test_run();
}

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

Title:
  NULL pointer dereference issues in am53c974 SCSI host bus adapter

Status in QEMU:
  New

Bug description:
  Two NULL pointer dereference issues were found in the am53c974 SCSI
  host bus adapter emulation of QEMU. They could occur while handling
  the 'Information Transfer' command (CMD_TI) in function handle_ti() in
  hw/scsi/esp.c, and could be abused by a malicious guest to crash the
  QEMU process on the host resulting in a denial of service.

  Both issues were reported by Cheolwoo Myung (Seoul National
  University). To reproduce them, configure and run QEMU as follows.
  Please find attached the required disk images.

  $ ./configure --target-list=x86_64-softmmu --enable-kvm --enable-sanitizers
  $ make
  $ ./qemu-system-x86_64 -m 512 -drive 
file=./hyfuzz.img,index=0,media=disk,format=raw \
  -device am53c974,id=scsi -device scsi-hd,drive=SysDisk \
  -drive id=SysDisk,if=none,file=./disk.img

  Additional info:
  RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1909766
  RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1909769

  ASAN logs:
  ==672133== 
  hw/scsi/scsi-bus.c:1385:12: runtime error: member access within null pointer 
of type 'struct SCSIRequest'
  AddressSanitizer:DEADLYSIGNAL 
   
  = 
  ==672133==ERROR: AddressSanitizer: SEGV on unknown address 0x0171 (pc 
0x55bd63e20b85 bp 0x7f4b6fffdfa0 sp 0x7f4b6fffdf70 T7)
  ==672133==The signal is caused by a READ memory access. 
  ==672133==Hint: address points to the zero page.  
   
  #0 0x55bd63e20b85 in scsi_req_continue hw/scsi/scsi-bus.c:1385
  #1 0x55bd63ab34fb in esp_do_dma hw/scsi/esp.c:453   
  #2 0x55bd63ab4b3c in handle_ti hw/scsi/esp.c:549  
  #3 0x55bd63ab72a9 in esp_reg_write hw/scsi/esp.c:691 
  #4 0x55bd63d7b5dd in esp_pci_io_write hw/scsi/esp-pci.c:206
  #5 0x55bd645d55a3 in memory_region_write_accessor softmmu/memory.c:491
  #6 0x55bd645d5a24 in access_with_adjusted_size softmmu/memory.c:552
  #7 0x55bd645e2baa in memory_region_dispatch_write softmmu/memory.c:1501
  #8 0x55bd646b75ff in flatview_write_continue softmmu/physmem.c:2759
  #9 0x55bd646b79d1 in flatview_write softmmu/physmem.c:2799
  #10 0x55bd646b8341 in address_space_write softmmu/physmem.c:2891   
  #11 0x55bd646b83f9 in address_space_rw softmmu/physmem.c:2901
  #12 0x55bd648c4736 in kvm_handle_io accel/kvm/kvm-all.c:2285
  #13 0x55bd648c69c8 in kvm_cpu_exec accel/kvm/kvm-all.c:2531
  #14 0x55bd647b2413 in kvm_vcpu_thread_fn accel/kvm/kvm-cpus.c:49
  #15 0x55bd64f560de in qemu_thread_start util/qemu-thread-posix.c:521
  #16 0x7f4b981763f8 in start_thread (/lib64/libpthread.so.0+0x93f8)
  #17 0x7f4b980a3902 in __GI___clone (/lib64/libc.so.6+0x101902)

  ---

  ==672020==
  hw/scsi/esp.c:196:62: runtime error: member access within null pointer of 
type 'struct SCSIDevice'
  

[Bug 1910723] Re: NULL pointer dereference issues in am53c974 SCSI host bus adapter

2021-03-14 Thread Alexander Bulekov
QTest Reproducer for the second:
/*
 * Autogenerated Fuzzer Test Case
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * later. See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "libqos/libqtest.h"

/*
 * cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, \
 * -m 512M -device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
 * id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest stdio
 * outl 0xcf8 0x80001001
 * outl 0xcfc 0x0100
 * outl 0xcf8 0x8000100e
 * outl 0xcfc 0xef80
 * outl 0xef8b 0x4100
 * outw 0xef80 0x01
 * outl 0xefc0 0x03
 * outl 0xef8b 0xc100
 * outl 0xef8b 0x9000
 * EOF
 */
static void test_fuzz(void)
{
QTestState *s = qtest_init(
"-display none , -m 512M -device am53c974,id=scsi -device "
"scsi-hd,drive=disk0 -drive "
"id=disk0,if=none,file=null-co://,format=raw -nodefaults");
qtest_outl(s, 0xcf8, 0x80001001);
qtest_outl(s, 0xcfc, 0x0100);
qtest_outl(s, 0xcf8, 0x8000100e);
qtest_outl(s, 0xcfc, 0xef80);
qtest_outl(s, 0xef8b, 0x4100);
qtest_outw(s, 0xef80, 0x01);
qtest_outl(s, 0xefc0, 0x03);
qtest_outl(s, 0xef8b, 0xc100);
qtest_outl(s, 0xef8b, 0x9000);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();

g_test_init(, , NULL);

if (strcmp(arch, "i386") == 0) {
qtest_add_func("fuzz/test_fuzz", test_fuzz);
}

return g_test_run();
}

** Tags added: fuzzer

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

Title:
  NULL pointer dereference issues in am53c974 SCSI host bus adapter

Status in QEMU:
  New

Bug description:
  Two NULL pointer dereference issues were found in the am53c974 SCSI
  host bus adapter emulation of QEMU. They could occur while handling
  the 'Information Transfer' command (CMD_TI) in function handle_ti() in
  hw/scsi/esp.c, and could be abused by a malicious guest to crash the
  QEMU process on the host resulting in a denial of service.

  Both issues were reported by Cheolwoo Myung (Seoul National
  University). To reproduce them, configure and run QEMU as follows.
  Please find attached the required disk images.

  $ ./configure --target-list=x86_64-softmmu --enable-kvm --enable-sanitizers
  $ make
  $ ./qemu-system-x86_64 -m 512 -drive 
file=./hyfuzz.img,index=0,media=disk,format=raw \
  -device am53c974,id=scsi -device scsi-hd,drive=SysDisk \
  -drive id=SysDisk,if=none,file=./disk.img

  Additional info:
  RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1909766
  RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1909769

  ASAN logs:
  ==672133== 
  hw/scsi/scsi-bus.c:1385:12: runtime error: member access within null pointer 
of type 'struct SCSIRequest'
  AddressSanitizer:DEADLYSIGNAL 
   
  = 
  ==672133==ERROR: AddressSanitizer: SEGV on unknown address 0x0171 (pc 
0x55bd63e20b85 bp 0x7f4b6fffdfa0 sp 0x7f4b6fffdf70 T7)
  ==672133==The signal is caused by a READ memory access. 
  ==672133==Hint: address points to the zero page.  
   
  #0 0x55bd63e20b85 in scsi_req_continue hw/scsi/scsi-bus.c:1385
  #1 0x55bd63ab34fb in esp_do_dma hw/scsi/esp.c:453   
  #2 0x55bd63ab4b3c in handle_ti hw/scsi/esp.c:549  
  #3 0x55bd63ab72a9 in esp_reg_write hw/scsi/esp.c:691 
  #4 0x55bd63d7b5dd in esp_pci_io_write hw/scsi/esp-pci.c:206
  #5 0x55bd645d55a3 in memory_region_write_accessor softmmu/memory.c:491
  #6 0x55bd645d5a24 in access_with_adjusted_size softmmu/memory.c:552
  #7 0x55bd645e2baa in memory_region_dispatch_write softmmu/memory.c:1501
  #8 0x55bd646b75ff in flatview_write_continue softmmu/physmem.c:2759
  #9 0x55bd646b79d1 in flatview_write softmmu/physmem.c:2799
  #10 0x55bd646b8341 in address_space_write softmmu/physmem.c:2891   
  #11 0x55bd646b83f9 in address_space_rw softmmu/physmem.c:2901
  #12 0x55bd648c4736 in kvm_handle_io accel/kvm/kvm-all.c:2285
  #13 0x55bd648c69c8 in kvm_cpu_exec accel/kvm/kvm-all.c:2531
  #14 0x55bd647b2413 in kvm_vcpu_thread_fn accel/kvm/kvm-cpus.c:49
  #15 0x55bd64f560de in qemu_thread_start util/qemu-thread-posix.c:521
  #16 0x7f4b981763f8 in start_thread (/lib64/libpthread.so.0+0x93f8)
  #17 0x7f4b980a3902 in __GI___clone (/lib64/libc.so.6+0x101902)

  ---

  ==672020==
  hw/scsi/esp.c:196:62: runtime error: member access within null pointer of 
type 'struct SCSIDevice'
  AddressSanitizer:DEADLYSIGNAL 
   
  = 
  

RE: [PATCH v8 27/35] Hexagon (target/hexagon) TCG for instructions with multiple definitions

2021-03-14 Thread Taylor Simpson


> -Original Message-
> From: Richard Henderson 
> Sent: Sunday, March 14, 2021 1:02 PM
> To: Taylor Simpson ; qemu-devel@nongnu.org
> Cc: phi...@redhat.com; alex.ben...@linaro.org; laur...@vivier.eu;
> a...@rev.ng; Brian Cain 
> Subject: Re: [PATCH v8 27/35] Hexagon (target/hexagon) TCG for instructions
> with multiple definitions
>
> On 3/13/21 6:41 PM, Taylor Simpson wrote:
> >>> +#define fGEN_TCG_L2_loadrub_pr(SHORTCODE)  SHORTCODE
> >>> +#define fGEN_TCG_L2_loadrub_pi(SHORTCODE)  SHORTCODE
> >>> +#define fGEN_TCG_L2_loadrb_pr(SHORTCODE)   SHORTCODE
> >>> +#define fGEN_TCG_L2_loadrb_pi(SHORTCODE)   SHORTCODE;
> >>> +#define fGEN_TCG_L2_loadruh_pr(SHORTCODE)  SHORTCODE
> >>> +#define fGEN_TCG_L2_loadruh_pi(SHORTCODE)  SHORTCODE;
> >>
> >> Why have some of these ; but not all?
> >
> > The initial series only has overrides that are required for correct 
> > execution.
>
> This does not answer the question re the semicolon inconsistency.

Sorry, misunderstood the question.  The semi's must've been needed at some 
point, but they're not needed now.  I'll remove them.

Taylor



Re: [PATCH] fuzz: check machine, before PC-specific code

2021-03-14 Thread Alexander Bulekov
On 210315 0031, Philippe Mathieu-Daudé wrote:
> On 3/15/21 12:13 AM, Alexander Bulekov wrote:
> > On 210314 1910, Alexander Bulekov wrote:
> >> We enumerate PCI devices on PC machines, but this breaks the fuzzer for
> >> non-PC machines and architectures. Add checks to avoid this.
> >>
> >> Reported-by: Philippe Mathieu-Daudé 
> >> Signed-off-by: Alexander Bulekov 
> >> ---
> >>  tests/qtest/fuzz/generic_fuzz.c | 11 ---
> >>  1 file changed, 8 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/tests/qtest/fuzz/generic_fuzz.c 
> >> b/tests/qtest/fuzz/generic_fuzz.c
> >> index ee8c17a04c..d2b74028fe 100644
> >> --- a/tests/qtest/fuzz/generic_fuzz.c
> >> +++ b/tests/qtest/fuzz/generic_fuzz.c
> >> @@ -784,6 +784,7 @@ static void generic_pre_fuzz(QTestState *s)
> >>  MemoryRegion *mr;
> >>  QPCIBus *pcibus;
> >>  char **result;
> >> +const char* machine_type;
> >>  
> >>  if (!getenv("QEMU_FUZZ_OBJECTS")) {
> >>  usage();
> >> @@ -827,9 +828,13 @@ static void generic_pre_fuzz(QTestState *s)
> >>  exit(1);
> >>  }
> >>  
> >> -pcibus = qpci_new_pc(s, NULL);
> >> -g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> >> -qpci_free_pc(pcibus);
> >> +machine_type = object_get_typename(qdev_get_machine());
> >> +if(fuzzable_pci_devices->len && strstr(machine_type, "pc") == 
> >> machine_type)
> >   Should at least be "pc-" --^
> > Maybe there's a more cannonical way to do this..
> 
> This doesn't scale with tests/qtest/libqos/pci-spapr.h :(

True - though the existing code wouldn't work for that anyway.

> 
> Maybe use the QOSOps structures?
> 
> > -Alex
> > 
> >> +{
> >> +pcibus = qpci_new_pc(s, NULL);
> >> +g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> >> +qpci_free_pc(pcibus);
> >> +}
> >>  
> >>  counter_shm_init();
> >>  }
> >> -- 
> >> 2.27.0
> >>
> > 



Re: [RFC PATCH 4/8] qtest/fuzz: Restrict CPU I/O instructions

2021-03-14 Thread Alexander Bulekov
On 210315 0029, Philippe Mathieu-Daudé wrote:
> Restrict CPU I/O instructions to architectures providing
> I/O bus.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  tests/qtest/fuzz/generic_fuzz.c   | 16 ++--
>  tests/qtest/fuzz/qtest_wrappers.c |  4 
>  2 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
> index ee8c17a04c4..3e0089f4a63 100644
> --- a/tests/qtest/fuzz/generic_fuzz.c
> +++ b/tests/qtest/fuzz/generic_fuzz.c
> @@ -304,6 +304,13 @@ static bool get_io_address(address_range *result, 
> AddressSpace *as,
>  return cb_info.found;
>  }
>  
> +static bool get_mmio_address(address_range *result,
> + uint8_t index, uint32_t offset)
> +{
> +return get_io_address(result, _space_memory, index, offset);
> +}
> +
> +#ifdef TARGET_HAS_IOPORT
>  static bool get_pio_address(address_range *result,
>  uint8_t index, uint16_t offset)
>  {
> @@ -318,12 +325,6 @@ static bool get_pio_address(address_range *result,
>  return result->addr <= 0x ? found : false;
>  }
>  
> -static bool get_mmio_address(address_range *result,
> - uint8_t index, uint32_t offset)
> -{
> -return get_io_address(result, _space_memory, index, offset);
> -}
> -
>  static void op_in(QTestState *s, const unsigned char * data, size_t len)
>  {
>  enum Sizes {Byte, Word, Long, end_sizes};
> @@ -395,6 +396,7 @@ static void op_out(QTestState *s, const unsigned char * 
> data, size_t len)
>  break;
>  }
>  }
> +#endif /* TARGET_HAS_IOPORT */
>  
>  static void op_read(QTestState *s, const unsigned char * data, size_t len)
>  {
> @@ -626,8 +628,10 @@ static void handle_timeout(int sig)
>  static void generic_fuzz(QTestState *s, const unsigned char *Data, size_t 
> Size)
>  {
>  void (*ops[]) (QTestState *s, const unsigned char* , size_t) = {
> +#ifdef TARGET_HAS_IOPORT
>  [OP_IN] = op_in,
>  [OP_OUT]= op_out,

I think op_pci_read and op_pci_write would need to be disabled as well
(at least the way they are implemented now).

> +#endif /* TARGET_HAS_IOPORT */
>  [OP_READ]   = op_read,
>  [OP_WRITE]  = op_write,
>  [OP_PCI_READ]   = op_pci_read,
> diff --git a/tests/qtest/fuzz/qtest_wrappers.c 
> b/tests/qtest/fuzz/qtest_wrappers.c
> index 921d1e5ed3a..d56dda9e9b8 100644
> --- a/tests/qtest/fuzz/qtest_wrappers.c
> +++ b/tests/qtest/fuzz/qtest_wrappers.c
> @@ -24,12 +24,14 @@ static bool serialize = true;
>  RET_TYPE __wrap_##NAME_AND_ARGS;\
>  RET_TYPE __real_##NAME_AND_ARGS;
>  
> +#ifdef TARGET_HAS_IOPORT
>  WRAP(uint8_t  , qtest_inb(QTestState *s, uint16_t addr))
>  WRAP(uint16_t , qtest_inw(QTestState *s, uint16_t addr))
>  WRAP(uint32_t , qtest_inl(QTestState *s, uint16_t addr))
>  WRAP(void , qtest_outb(QTestState *s, uint16_t addr, uint8_t value))
>  WRAP(void , qtest_outw(QTestState *s, uint16_t addr, uint16_t value))
>  WRAP(void , qtest_outl(QTestState *s, uint16_t addr, uint32_t value))
> +#endif /* TARGET_HAS_IOPORT */
>  WRAP(uint8_t  , qtest_readb(QTestState *s, uint64_t addr))
>  WRAP(uint16_t , qtest_readw(QTestState *s, uint64_t addr))
>  WRAP(uint32_t , qtest_readl(QTestState *s, uint64_t addr))
> @@ -50,6 +52,7 @@ WRAP(void,  qtest_memset(QTestState *s, uint64_t addr,
>   uint8_t patt, size_t size))
>  
>  
> +#ifdef TARGET_HAS_IOPORT
>  uint8_t __wrap_qtest_inb(QTestState *s, uint16_t addr)
>  {
>  if (!serialize) {
> @@ -103,6 +106,7 @@ void __wrap_qtest_outl(QTestState *s, uint16_t addr, 
> uint32_t value)
>  __real_qtest_outl(s, addr, value);
>  }
>  }
> +#endif /* TARGET_HAS_IOPORT */
>  
>  uint8_t __wrap_qtest_readb(QTestState *s, uint64_t addr)
>  {
> -- 
> 2.26.2
> 



[PATCH] utils: Use fma in qemu_strtosz

2021-03-14 Thread Richard Henderson
Use fma to simulatneously scale and round up fraction.

The libm function will always return a properly rounded double precision
value, which will eliminate any extra precision the x87 co-processor may
give us, which will keep the output predictable vs other hosts.

Adding DBL_EPSILON while scaling should help with fractions like
12.345, where the closest representable number is actually 12.3449*.

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

diff --git a/util/cutils.c b/util/cutils.c
index d89a40a8c3..f7f8e48a68 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -342,7 +342,7 @@ static int do_strtosz(const char *nptr, const char **end,
 retval = -ERANGE;
 goto out;
 }
-*result = val * mul + (uint64_t) (fraction * mul);
+*result = val * mul + (uint64_t)fma(fraction, mul, DBL_EPSILON);
 retval = 0;
 
 out:
-- 
2.25.1




[PULL 3/4] target/avr: Fix some comment spelling errors

2021-03-14 Thread Philippe Mathieu-Daudé
From: Lichang Zhao 

I found that there are many spelling errors in the comments of qemu/target/avr.
I used spellcheck to check the spelling errors and found some errors in the 
folder.

Signed-off-by: Lichang Zhao 
Reviewed-by: David Edmondson 
Reviewed-by: Philippe Mathieu-Daude
Message-Id: <20201009064449.2336-12-zhaolich...@huawei.com>
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Rolnik 
---
 target/avr/helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/avr/helper.c b/target/avr/helper.c
index 65880b9928c..b4532de2523 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -98,7 +98,7 @@ int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t 
*buf,
 
 hwaddr avr_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
-return addr; /* I assume 1:1 address correspondance */
+return addr; /* I assume 1:1 address correspondence */
 }
 
 bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
@@ -299,7 +299,7 @@ void helper_outb(CPUAVRState *env, uint32_t port, uint32_t 
data)
 }
 
 /*
- *  this function implements LD instruction when there is a posibility to read
+ *  this function implements LD instruction when there is a possibility to read
  *  from a CPU register
  */
 target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr)
@@ -323,7 +323,7 @@ target_ulong helper_fullrd(CPUAVRState *env, uint32_t addr)
 }
 
 /*
- *  this function implements ST instruction when there is a posibility to write
+ *  this function implements ST instruction when there is a possibility to 
write
  *  into a CPU register
  */
 void helper_fullwr(CPUAVRState *env, uint32_t data, uint32_t addr)
-- 
2.26.2




[PULL 1/4] hw/misc/led: Add yellow LED

2021-03-14 Thread Philippe Mathieu-Daudé
Add the yellow "lime" LED.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Rolnik 
Message-Id: <20210313165445.2113938-2-f4...@amsat.org>
---
 include/hw/misc/led.h | 1 +
 hw/misc/led.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/hw/misc/led.h b/include/hw/misc/led.h
index aa359b87c20..29c08795708 100644
--- a/include/hw/misc/led.h
+++ b/include/hw/misc/led.h
@@ -27,6 +27,7 @@ typedef enum {  /* Coarse wavelength range */
 LED_COLOR_BLUE, /* 475 nm */
 LED_COLOR_CYAN, /* 500 nm */
 LED_COLOR_GREEN,/* 535 nm */
+LED_COLOR_YELLOW,   /* 567 nm */
 LED_COLOR_AMBER,/* 590 nm */
 LED_COLOR_ORANGE,   /* 615 nm */
 LED_COLOR_RED,  /* 630 nm */
diff --git a/hw/misc/led.c b/hw/misc/led.c
index 5266d026d0b..f552b8b6483 100644
--- a/hw/misc/led.c
+++ b/hw/misc/led.c
@@ -20,6 +20,7 @@ static const char * const led_color_name[] = {
 [LED_COLOR_BLUE]= "blue",
 [LED_COLOR_CYAN]= "cyan",
 [LED_COLOR_GREEN]   = "green",
+[LED_COLOR_YELLOW]  = "yellow",
 [LED_COLOR_AMBER]   = "amber",
 [LED_COLOR_ORANGE]  = "orange",
 [LED_COLOR_RED] = "red",
-- 
2.26.2




[PULL 4/4] target/avr: Fix interrupt execution

2021-03-14 Thread Philippe Mathieu-Daudé
From: Ivanov Arkasha 

Only one interrupt is in progress at the moment.
It is only necessary to set to reset interrupt_request
after all interrupts have been executed.

Signed-off-by: Ivanov Arkasha 
Message-Id: <20210312164754.18437-1-arkaisp2...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Rolnik 
---
 target/avr/helper.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/avr/helper.c b/target/avr/helper.c
index b4532de2523..35e10195940 100644
--- a/target/avr/helper.c
+++ b/target/avr/helper.c
@@ -49,7 +49,9 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 cc->tcg_ops->do_interrupt(cs);
 
 env->intsrc &= env->intsrc - 1; /* clear the interrupt */
-cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+if (!env->intsrc) {
+cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+}
 
 ret = true;
 }
-- 
2.26.2




[PULL 2/4] hw/avr/arduino: List board schematic links

2021-03-14 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Rolnik 
Message-Id: <20210313165445.2113938-3-f4...@amsat.org>
---
 hw/avr/arduino.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
index 3c8388490d6..3ff31492fa6 100644
--- a/hw/avr/arduino.c
+++ b/hw/avr/arduino.c
@@ -75,7 +75,10 @@ static void arduino_duemilanove_class_init(ObjectClass *oc, 
void *data)
 MachineClass *mc = MACHINE_CLASS(oc);
 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
 
-/* https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove */
+/*
+ * https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove
+ * https://www.arduino.cc/en/uploads/Main/arduino-duemilanove-schematic.pdf
+ */
 mc->desc= "Arduino Duemilanove (ATmega168)",
 mc->alias   = "2009";
 amc->mcu_type   = TYPE_ATMEGA168_MCU;
@@ -87,7 +90,10 @@ static void arduino_uno_class_init(ObjectClass *oc, void 
*data)
 MachineClass *mc = MACHINE_CLASS(oc);
 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
 
-/* https://store.arduino.cc/arduino-uno-rev3 */
+/*
+ * https://store.arduino.cc/arduino-uno-rev3
+ * https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf
+ */
 mc->desc= "Arduino UNO (ATmega328P)";
 mc->alias   = "uno";
 amc->mcu_type   = TYPE_ATMEGA328_MCU;
@@ -99,7 +105,10 @@ static void arduino_mega_class_init(ObjectClass *oc, void 
*data)
 MachineClass *mc = MACHINE_CLASS(oc);
 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
 
-/* https://www.arduino.cc/en/Main/ArduinoBoardMega */
+/*
+ * https://www.arduino.cc/en/Main/ArduinoBoardMega
+ * https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf
+ */
 mc->desc= "Arduino Mega (ATmega1280)";
 mc->alias   = "mega";
 amc->mcu_type   = TYPE_ATMEGA1280_MCU;
@@ -111,7 +120,10 @@ static void arduino_mega2560_class_init(ObjectClass *oc, 
void *data)
 MachineClass *mc = MACHINE_CLASS(oc);
 ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
 
-/* https://store.arduino.cc/arduino-mega-2560-rev3 */
+/*
+ * https://store.arduino.cc/arduino-mega-2560-rev3
+ * https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf
+ */
 mc->desc= "Arduino Mega 2560 (ATmega2560)";
 mc->alias   = "mega2560";
 amc->mcu_type   = TYPE_ATMEGA2560_MCU;
-- 
2.26.2




[PULL 0/4] AVR patches for 2021-03-15

2021-03-14 Thread Philippe Mathieu-Daudé
The following changes since commit 6157b0e19721aadb4c7fdcfe57b2924af6144b14:

  Merge remote-tracking branch 
'remotes/vivier2/tags/linux-user-for-6.0-pull-request' into staging (2021-03-14 
17:47:49 +)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/avr-20210315

for you to fetch changes up to 56b90e60c4019b08012bd8bd1459efc00b055577:

  target/avr: Fix interrupt execution (2021-03-15 00:39:52 +0100)


AVR patches queue

- Only reset 'interrupt_request' mask once all interrupts executed
- Documentation and typo fixes


Ivanov Arkasha (1):
  target/avr: Fix interrupt execution

Lichang Zhao (1):
  target/avr: Fix some comment spelling errors

Philippe Mathieu-Daudé (2):
  hw/misc/led: Add yellow LED
  hw/avr/arduino: List board schematic links

 include/hw/misc/led.h |  1 +
 hw/avr/arduino.c  | 20 
 hw/misc/led.c |  1 +
 target/avr/helper.c   | 10 ++
 4 files changed, 24 insertions(+), 8 deletions(-)

-- 
2.26.2




Re: [PATCH 00/11] AVR patch queue for QEMU 6.0

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/13/21 5:54 PM, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> This series contains all the AVR patches I could find on the list.
> 
> Niteesh, I fixed minor issues. Do you mind reviewing on top?
> 
> Pull request planned for Monday if no problem arises.
> 
> Thanks,
> 
> Phil.
> 
> G S Niteesh Babu (2):
>   hw/gpio/avr_gpio: Add tracing for reads and writes
>   hw/avr/arduino: Add D13 LED
> 
> Heecheol Yang (1):
>   hw/avr: Add limited support for avr gpio registers
> 
> Ivanov Arkasha (1):
>   target/avr: Fix interrupt execution
> 
> Lichang Zhao (1):
>   target/avr: Fix some comment spelling errors
> 
> Philippe Mathieu-Daudé (6):
>   hw/misc/led: Add yellow LED
>   hw/avr/arduino: List board schematic links
>   hw/gpio/avr_gpio: Add migration VMstate
>   hw/gpio/avr_gpio: Add 'id' field in AVRGPIOState
>   hw/gpio/avr_gpio: Simplify avr_gpio_write_port using extract32()
>   hw/avr/arduino: Replace magic number by gpio_port_index() call
> 
>  hw/avr/atmega.h|   2 +
>  include/hw/gpio/avr_gpio.h |  54 
>  include/hw/misc/led.h  |   1 +
>  hw/avr/arduino.c   |  44 +-
>  hw/avr/atmega.c|   8 +-
>  hw/gpio/avr_gpio.c | 173 +
>  hw/misc/led.c  |   1 +
>  target/avr/helper.c|  10 ++-
>  hw/avr/Kconfig |   2 +
>  hw/gpio/Kconfig|   3 +
>  hw/gpio/meson.build|   1 +
>  hw/gpio/trace-events   |   5 ++
>  12 files changed, 294 insertions(+), 10 deletions(-)
>  create mode 100644 include/hw/gpio/avr_gpio.h
>  create mode 100644 hw/gpio/avr_gpio.c

Patches 1, 2, 10, 11 queued to avr-next.



Re: [PATCH 03/11] hw/avr: Add limited support for avr gpio registers

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/14/21 11:26 AM, Mark Cave-Ayland wrote:
> On 13/03/2021 16:54, Philippe Mathieu-Daudé wrote:
> 
>> From: Heecheol Yang 
>>
>> Add some of these features for AVR GPIO:
>>
>>    - GPIO I/O : PORTx registers
>>    - Data Direction : DDRx registers
>>    - DDRx toggling : PINx registers
>>
>> Following things are not supported yet:
>>    - MCUR registers
>>
>> Signed-off-by: Heecheol Yang 
>> Reviewed-by: Michael Rolnik 
>> Message-Id:
>> 
>>
>> [PMD: Use AVR_GPIO_COUNT]
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>>   hw/avr/atmega.h    |   2 +
>>   include/hw/gpio/avr_gpio.h |  53 ++
>>   hw/avr/atmega.c    |   7 +-
>>   hw/gpio/avr_gpio.c | 138 +
>>   hw/avr/Kconfig |   1 +
>>   hw/gpio/Kconfig    |   3 +
>>   hw/gpio/meson.build    |   1 +
>>   7 files changed, 203 insertions(+), 2 deletions(-)
>>   create mode 100644 include/hw/gpio/avr_gpio.h
>>   create mode 100644 hw/gpio/avr_gpio.c
>>
>> diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
>> index a99ee15c7e1..e2289d5744e 100644
>> --- a/hw/avr/atmega.h
>> +++ b/hw/avr/atmega.h
>> @@ -13,6 +13,7 @@
>>     #include "hw/char/avr_usart.h"
>>   #include "hw/timer/avr_timer16.h"
>> +#include "hw/gpio/avr_gpio.h"
>>   #include "hw/misc/avr_power.h"
>>   #include "target/avr/cpu.h"
>>   #include "qom/object.h"
>> @@ -44,6 +45,7 @@ struct AtmegaMcuState {
>>   DeviceState *io;
>>   AVRMaskState pwr[POWER_MAX];
>>   AVRUsartState usart[USART_MAX];
>> +    AVRGPIOState gpio[GPIO_MAX];
>>   AVRTimer16State timer[TIMER_MAX];
>>   uint64_t xtal_freq_hz;
>>   };
>> diff --git a/include/hw/gpio/avr_gpio.h b/include/hw/gpio/avr_gpio.h
>> new file mode 100644
>> index 000..498a7275f05
>> --- /dev/null
>> +++ b/include/hw/gpio/avr_gpio.h
>> @@ -0,0 +1,53 @@
>> +/*
>> + * AVR processors GPIO registers definition.
>> + *
>> + * Copyright (C) 2020 Heecheol Yang 
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 or
>> + * (at your option) version 3 of the License.
> 
> Minor nit: isn't the wording of the existing QEMU license "licensed
> under the terms of the GNU GPL, version 2 or later" rather than
> explicitly stating versions 2 and 3?

Good point.

Heecheol Yang, do you mind resending your patch with the correct
license please?

> 
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> along
>> + * with this program; if not, see .
>> + */
>> +
>> +#ifndef AVR_GPIO_H
>> +#define AVR_GPIO_H
>> +
>> +#include "hw/sysbus.h"
>> +#include "qom/object.h"
>> +
>> +/* Offsets of registers. */
>> +#define GPIO_PIN   0x00
>> +#define GPIO_DDR   0x01
>> +#define GPIO_PORT  0x02
>> +
>> +#define TYPE_AVR_GPIO "avr-gpio"
>> +OBJECT_DECLARE_SIMPLE_TYPE(AVRGPIOState, AVR_GPIO)
>> +#define AVR_GPIO_COUNT 8
>> +
>> +struct AVRGPIOState {
>> +    /*< private >*/
>> +    SysBusDevice parent_obj;
>> +
>> +    /*< public >*/
>> +    MemoryRegion mmio;
>> +
>> +    struct {
>> +    uint8_t pin;
>> +    uint8_t ddr;
>> +    uint8_t port;
>> +    } reg;
>> +
>> +    /* PORTx data changed IRQs */
>> +    qemu_irq out[8u];
>> +
>> +};
>> +
>> +#endif /* AVR_GPIO_H */
>> diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
>> index 44c6afebbb6..19c3122189f 100644
>> --- a/hw/avr/atmega.c
>> +++ b/hw/avr/atmega.c
>> @@ -283,8 +283,11 @@ static void atmega_realize(DeviceState *dev,
>> Error **errp)
>>   continue;
>>   }
>>   devname = g_strdup_printf("atmega-gpio-%c", 'a' + (char)i);
>> -    create_unimplemented_device(devname,
>> -    OFFSET_DATA + mc->dev[idx].addr, 3);
>> +    object_initialize_child(OBJECT(dev), devname, >gpio[i],
>> +    TYPE_AVR_GPIO);
>> +    sysbus_realize(SYS_BUS_DEVICE(>gpio[i]), _abort);
>> +    sysbus_mmio_map(SYS_BUS_DEVICE(>gpio[i]), 0,
>> +    OFFSET_DATA + mc->dev[idx].addr);
>>   g_free(devname);
>>   }
>>   diff --git a/hw/gpio/avr_gpio.c b/hw/gpio/avr_gpio.c
>> new file mode 100644
>> index 000..cdb574ef0d8
>> --- /dev/null
>> +++ b/hw/gpio/avr_gpio.c
>> @@ -0,0 +1,138 @@
>> +/*
>> + * AVR processors GPIO registers emulation.
>> + *
>> + * Copyright (C) 2020 Heecheol Yang 
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 or
>> + * (at your option) 

Re: [Virtio-fs] [PATCH 1/3] virtiofsd: Don't allow empty paths in lookup_name()

2021-03-14 Thread Vivek Goyal
On Fri, Mar 12, 2021 at 03:10:01PM +0100, Greg Kurz wrote:
> When passed an empty filename, lookup_name() returns the inode of
> the parent directory, unless the parent is the root in which case
> the st_dev doesn't match and lo_find() returns NULL. This is
> because lookup_name() passes AT_EMPTY_PATH down to fstatat() or
> statx().
> 
> This behavior doesn't quite make sense because users of lookup_name()
> then pass the name to unlinkat(), renameat() or renameat2(), all of
> which will always fail on empty names.
> 
> Drop AT_EMPTY_PATH from the flags in lookup_name() so that it has
> the consistent behavior of "returning an existing child inode or
> NULL" for all directories.
> 
> Signed-off-by: Greg Kurz 

Looks good to me. Can't think in what cases fuse will need to pass in
empty path for lookup.

Reviewed-by: Vivek Goyal 

Vivek
> ---
>  tools/virtiofsd/passthrough_ll.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index fc7e1b1e8e2b..27a6c636dcaf 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -1308,8 +1308,7 @@ static struct lo_inode *lookup_name(fuse_req_t req, 
> fuse_ino_t parent,
>  return NULL;
>  }
>  
> -res = do_statx(lo, dir->fd, name, ,
> -   AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, _id);
> +res = do_statx(lo, dir->fd, name, , AT_SYMLINK_NOFOLLOW, _id);
>  lo_inode_put(lo, );
>  if (res == -1) {
>  return NULL;
> -- 
> 2.26.2
> 
> ___
> Virtio-fs mailing list
> virtio...@redhat.com
> https://listman.redhat.com/mailman/listinfo/virtio-fs




Re: [Virtio-fs] [PATCH 3/3] virtiofsd: Don't allow empty filenames

2021-03-14 Thread Vivek Goyal
On Fri, Mar 12, 2021 at 03:10:03PM +0100, Greg Kurz wrote:
> POSIX.1-2017 clearly stipulates that empty filenames aren't
> allowed ([1] and [2]). Since virtiofsd is supposed to mirror
> the host file system hierarchy and the host can be assumed to
> be linux, we don't really expect clients to pass requests with
> an empty path in it. If they do so anyway, this would eventually
> cause an error when trying to create/lookup the actual inode
> on the underlying POSIX filesystem. But this could still confuse
> some code that wouldn't be ready to cope with this.
> 
> Filter out empty names coming from the client at the top level,
> so that the rest doesn't have to care about it. This is done
> everywhere we already call is_safe_path_component(), but
> in a separate helper since the usual error for empty path
> names is ENOENT instead of EINVAL.
> 
> [1] 
> https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_170
> [2] 
> https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
> 
> Signed-off-by: Greg Kurz 

Hi Greg,

Minor nit, if you happen to respin this patch, it probably should come
before the first patch in series. Once we make it clear that file server
is not expecting empty path in these top level functions, then it is
easy to clear AT_EMPTY_PATH in function these paths are calling as
appropriate.

What about lo_create(). Should we put a check in there as well.

We are passed xattr names in lo_getxattr()/lo_removexattr()/lo_setxattr().
In general, should we put an empty in_name check there as well and
probably simply return -EINVAL.

Thanks
Vivek

> ---
>  tools/virtiofsd/passthrough_ll.c | 35 
>  1 file changed, 35 insertions(+)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index f63016d35626..bff9dc2cd26d 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -237,6 +237,11 @@ static bool is_safe_path_component(const char *path)
>  return !is_dot_or_dotdot(path);
>  }
>  
> +static bool is_empty(const char *name)
> +{
> +return name[0] == '\0';
> +}
> +
>  static struct lo_data *lo_data(fuse_req_t req)
>  {
>  return (struct lo_data *)fuse_req_userdata(req);
> @@ -1083,6 +1088,11 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t 
> parent, const char *name)
>  fuse_log(FUSE_LOG_DEBUG, "lo_lookup(parent=%" PRIu64 ", name=%s)\n", 
> parent,
>   name);
>  
> +if (is_empty(name)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  /*
>   * Don't use is_safe_path_component(), allow "." and ".." for NFS export
>   * support.
> @@ -1174,6 +1184,11 @@ static void lo_mknod_symlink(fuse_req_t req, 
> fuse_ino_t parent,
>  struct fuse_entry_param e;
>  struct lo_cred old = {};
>  
> +if (is_empty(name)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  if (!is_safe_path_component(name)) {
>  fuse_reply_err(req, EINVAL);
>  return;
> @@ -1246,6 +1261,11 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, 
> fuse_ino_t parent,
>  char procname[64];
>  int saverr;
>  
> +if (is_empty(name)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  if (!is_safe_path_component(name)) {
>  fuse_reply_err(req, EINVAL);
>  return;
> @@ -1323,6 +1343,11 @@ static void lo_rmdir(fuse_req_t req, fuse_ino_t 
> parent, const char *name)
>  struct lo_inode *inode;
>  struct lo_data *lo = lo_data(req);
>  
> +if (is_empty(name)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  if (!is_safe_path_component(name)) {
>  fuse_reply_err(req, EINVAL);
>  return;
> @@ -1352,6 +1377,11 @@ static void lo_rename(fuse_req_t req, fuse_ino_t 
> parent, const char *name,
>  struct lo_inode *newinode = NULL;
>  struct lo_data *lo = lo_data(req);
>  
> +if (is_empty(name) || is_empty(newname)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  if (!is_safe_path_component(name) || !is_safe_path_component(newname)) {
>  fuse_reply_err(req, EINVAL);
>  return;
> @@ -1405,6 +1435,11 @@ static void lo_unlink(fuse_req_t req, fuse_ino_t 
> parent, const char *name)
>  struct lo_inode *inode;
>  struct lo_data *lo = lo_data(req);
>  
> +if (is_empty(name)) {
> +fuse_reply_err(req, ENOENT);
> +return;
> +}
> +
>  if (!is_safe_path_component(name)) {
>  fuse_reply_err(req, EINVAL);
>  return;
> -- 
> 2.26.2
> 
> ___
> Virtio-fs mailing list
> virtio...@redhat.com
> https://listman.redhat.com/mailman/listinfo/virtio-fs




Re: [Virtio-fs] [PATCH 2/3] virtiofsd: Convert some functions to return bool

2021-03-14 Thread Vivek Goyal
On Fri, Mar 12, 2021 at 03:10:02PM +0100, Greg Kurz wrote:
> Both currently only return 0 or 1.
> 
> Signed-off-by: Greg Kurz 

Looks good to me.

Reviewed-by: Vivek Goyal 

Vivek

> ---
>  tools/virtiofsd/passthrough_ll.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index 27a6c636dcaf..f63016d35626 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -221,17 +221,17 @@ static struct lo_inode *lo_find(struct lo_data *lo, 
> struct stat *st,
>  static int xattr_map_client(const struct lo_data *lo, const char 
> *client_name,
>  char **out_name);
>  
> -static int is_dot_or_dotdot(const char *name)
> +static bool is_dot_or_dotdot(const char *name)
>  {
>  return name[0] == '.' &&
> (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
>  }
>  
>  /* Is `path` a single path component that is not "." or ".."? */
> -static int is_safe_path_component(const char *path)
> +static bool is_safe_path_component(const char *path)
>  {
>  if (strchr(path, '/')) {
> -return 0;
> +return false;
>  }
>  
>  return !is_dot_or_dotdot(path);
> -- 
> 2.26.2
> 
> ___
> Virtio-fs mailing list
> virtio...@redhat.com
> https://listman.redhat.com/mailman/listinfo/virtio-fs




Re: [PATCH] fuzz: check machine, before PC-specific code

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/15/21 12:13 AM, Alexander Bulekov wrote:
> On 210314 1910, Alexander Bulekov wrote:
>> We enumerate PCI devices on PC machines, but this breaks the fuzzer for
>> non-PC machines and architectures. Add checks to avoid this.
>>
>> Reported-by: Philippe Mathieu-Daudé 
>> Signed-off-by: Alexander Bulekov 
>> ---
>>  tests/qtest/fuzz/generic_fuzz.c | 11 ---
>>  1 file changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/tests/qtest/fuzz/generic_fuzz.c 
>> b/tests/qtest/fuzz/generic_fuzz.c
>> index ee8c17a04c..d2b74028fe 100644
>> --- a/tests/qtest/fuzz/generic_fuzz.c
>> +++ b/tests/qtest/fuzz/generic_fuzz.c
>> @@ -784,6 +784,7 @@ static void generic_pre_fuzz(QTestState *s)
>>  MemoryRegion *mr;
>>  QPCIBus *pcibus;
>>  char **result;
>> +const char* machine_type;
>>  
>>  if (!getenv("QEMU_FUZZ_OBJECTS")) {
>>  usage();
>> @@ -827,9 +828,13 @@ static void generic_pre_fuzz(QTestState *s)
>>  exit(1);
>>  }
>>  
>> -pcibus = qpci_new_pc(s, NULL);
>> -g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
>> -qpci_free_pc(pcibus);
>> +machine_type = object_get_typename(qdev_get_machine());
>> +if(fuzzable_pci_devices->len && strstr(machine_type, "pc") == 
>> machine_type)
>   Should at least be "pc-" --^
> Maybe there's a more cannonical way to do this..

This doesn't scale with tests/qtest/libqos/pci-spapr.h :(

Maybe use the QOSOps structures?

> -Alex
> 
>> +{
>> +pcibus = qpci_new_pc(s, NULL);
>> +g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
>> +qpci_free_pc(pcibus);
>> +}
>>  
>>  counter_shm_init();
>>  }
>> -- 
>> 2.27.0
>>
> 



[RFC PATCH 8/8] softmmu: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/softmmu/meson.build b/softmmu/meson.build
index ebf063b8990..3df196917a0 100644
--- a/softmmu/meson.build
+++ b/softmmu/meson.build
@@ -2,7 +2,6 @@
   'arch_init.c',
   'balloon.c',
   'cpus.c',
-  'cpu-io.c',
   'cpu-throttle.c',
   'datadir.c',
   'globals.c',
@@ -16,6 +15,7 @@
   'cpu-timers.c',
   'runstate-action.c',
 )])
+specific_ss.add(when: 'TARGET_HAS_IOPORT', if_true: files('cpu-io.c'))
 
 specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: [files(
   'icount.c'
-- 
2.26.2




[RFC PATCH 7/8] monitor: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
 monitor/misc.c  | 4 
 hmp-commands.hx | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/monitor/misc.c b/monitor/misc.c
index d40c7d5afc0..b59f11433eb 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -77,7 +77,9 @@
 #include "qapi/qmp-event.h"
 #include "sysemu/cpus.h"
 #include "qemu/cutils.h"
+#ifdef TARGET_HAS_IOPORT
 #include "exec/cpu-io.h"
+#endif
 #if defined(TARGET_S390X)
 #include "hw/s390x/storage-keys.h"
 #include "hw/s390x/storage-attributes.h"
@@ -884,6 +886,7 @@ static void hmp_mouse_button(Monitor *mon, const QDict 
*qdict)
 mouse_button_state = button_state;
 }
 
+#ifdef TARGET_HAS_IOPORT
 static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
 {
 int size = qdict_get_int(qdict, "size");
@@ -939,6 +942,7 @@ static void hmp_ioport_write(Monitor *mon, const QDict 
*qdict)
 break;
 }
 }
+#endif /* TARGET_HAS_IOPORT */
 
 static void hmp_boot_set(Monitor *mon, const QDict *qdict)
 {
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d4001f9c5dc..cedcedf7d8d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -561,6 +561,7 @@ SRST
   used.
 ERST
 
+#ifdef TARGET_HAS_IOPORT
 {
 .name   = "i",
 .args_type  = "fmt:/,addr:i,index:i.",
@@ -586,6 +587,7 @@ SRST
 ``o/``\ *fmt* *addr* *val*
   Write to I/O port.
 ERST
+#endif /* TARGET_HAS_IOPORT */
 
 {
 .name   = "sendkey",
-- 
2.26.2




[RFC PATCH 5/8] qtest/libqos: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/qtest/libqos/fw_cfg.h | 3 +++
 tests/qtest/libqos/fw_cfg.c | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/tests/qtest/libqos/fw_cfg.h b/tests/qtest/libqos/fw_cfg.h
index c6a7cf8cf05..3bfb6d6d55b 100644
--- a/tests/qtest/libqos/fw_cfg.h
+++ b/tests/qtest/libqos/fw_cfg.h
@@ -36,6 +36,8 @@ size_t qfw_cfg_get_file(QFWCFG *fw_cfg, const char *filename,
 
 QFWCFG *mm_fw_cfg_init(QTestState *qts, uint64_t base);
 void mm_fw_cfg_uninit(QFWCFG *fw_cfg);
+
+#ifdef TARGET_HAS_IOPORT
 QFWCFG *io_fw_cfg_init(QTestState *qts, uint16_t base);
 void io_fw_cfg_uninit(QFWCFG *fw_cfg);
 
@@ -48,6 +50,7 @@ static inline void pc_fw_cfg_uninit(QFWCFG *fw_cfg)
 {
 io_fw_cfg_uninit(fw_cfg);
 }
+#endif /* TARGET_HAS_IOPORT */
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(QFWCFG, mm_fw_cfg_uninit)
 
diff --git a/tests/qtest/libqos/fw_cfg.c b/tests/qtest/libqos/fw_cfg.c
index 6b8e1babe51..db2b83f5212 100644
--- a/tests/qtest/libqos/fw_cfg.c
+++ b/tests/qtest/libqos/fw_cfg.c
@@ -131,6 +131,7 @@ void mm_fw_cfg_uninit(QFWCFG *fw_cfg)
 g_free(fw_cfg);
 }
 
+#ifdef TARGET_HAS_IOPORT
 static void io_fw_cfg_select(QFWCFG *fw_cfg, uint16_t key)
 {
 qtest_outw(fw_cfg->qts, fw_cfg->base, key);
@@ -162,3 +163,4 @@ void io_fw_cfg_uninit(QFWCFG *fw_cfg)
 {
 g_free(fw_cfg);
 }
+#endif /* TARGET_HAS_IOPORT */
-- 
2.26.2




[RFC PATCH 6/8] qtest: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/qtest.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/softmmu/qtest.c b/softmmu/qtest.c
index ff253068657..51fe256297a 100644
--- a/softmmu/qtest.c
+++ b/softmmu/qtest.c
@@ -31,7 +31,9 @@
 #ifdef CONFIG_PSERIES
 #include "hw/ppc/spapr_rtas.h"
 #endif
+#ifdef TARGET_HAS_IOPORT
 #include "exec/cpu-io.h"
+#endif
 
 #define MAX_IRQ 256
 
@@ -462,7 +464,9 @@ static void qtest_process_command(CharBackend *chr, gchar 
**words)
 qemu_set_irq(irq, level);
 qtest_send_prefix(chr);
 qtest_send(chr, "OK\n");
-} else if (strcmp(words[0], "outb") == 0 ||
+}
+#ifdef TARGET_HAS_IOPORT
+else if (strcmp(words[0], "outb") == 0 ||
strcmp(words[0], "outw") == 0 ||
strcmp(words[0], "outl") == 0) {
 unsigned long addr;
@@ -506,7 +510,9 @@ static void qtest_process_command(CharBackend *chr, gchar 
**words)
 }
 qtest_send_prefix(chr);
 qtest_sendf(chr, "OK 0x%04x\n", value);
-} else if (strcmp(words[0], "writeb") == 0 ||
+}
+#endif /* TARGET_HAS_IOPORT */
+else if (strcmp(words[0], "writeb") == 0 ||
strcmp(words[0], "writew") == 0 ||
strcmp(words[0], "writel") == 0 ||
strcmp(words[0], "writeq") == 0) {
-- 
2.26.2




[RFC PATCH 4/8] qtest/fuzz: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
Restrict CPU I/O instructions to architectures providing
I/O bus.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/qtest/fuzz/generic_fuzz.c   | 16 ++--
 tests/qtest/fuzz/qtest_wrappers.c |  4 
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index ee8c17a04c4..3e0089f4a63 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -304,6 +304,13 @@ static bool get_io_address(address_range *result, 
AddressSpace *as,
 return cb_info.found;
 }
 
+static bool get_mmio_address(address_range *result,
+ uint8_t index, uint32_t offset)
+{
+return get_io_address(result, _space_memory, index, offset);
+}
+
+#ifdef TARGET_HAS_IOPORT
 static bool get_pio_address(address_range *result,
 uint8_t index, uint16_t offset)
 {
@@ -318,12 +325,6 @@ static bool get_pio_address(address_range *result,
 return result->addr <= 0x ? found : false;
 }
 
-static bool get_mmio_address(address_range *result,
- uint8_t index, uint32_t offset)
-{
-return get_io_address(result, _space_memory, index, offset);
-}
-
 static void op_in(QTestState *s, const unsigned char * data, size_t len)
 {
 enum Sizes {Byte, Word, Long, end_sizes};
@@ -395,6 +396,7 @@ static void op_out(QTestState *s, const unsigned char * 
data, size_t len)
 break;
 }
 }
+#endif /* TARGET_HAS_IOPORT */
 
 static void op_read(QTestState *s, const unsigned char * data, size_t len)
 {
@@ -626,8 +628,10 @@ static void handle_timeout(int sig)
 static void generic_fuzz(QTestState *s, const unsigned char *Data, size_t Size)
 {
 void (*ops[]) (QTestState *s, const unsigned char* , size_t) = {
+#ifdef TARGET_HAS_IOPORT
 [OP_IN] = op_in,
 [OP_OUT]= op_out,
+#endif /* TARGET_HAS_IOPORT */
 [OP_READ]   = op_read,
 [OP_WRITE]  = op_write,
 [OP_PCI_READ]   = op_pci_read,
diff --git a/tests/qtest/fuzz/qtest_wrappers.c 
b/tests/qtest/fuzz/qtest_wrappers.c
index 921d1e5ed3a..d56dda9e9b8 100644
--- a/tests/qtest/fuzz/qtest_wrappers.c
+++ b/tests/qtest/fuzz/qtest_wrappers.c
@@ -24,12 +24,14 @@ static bool serialize = true;
 RET_TYPE __wrap_##NAME_AND_ARGS;\
 RET_TYPE __real_##NAME_AND_ARGS;
 
+#ifdef TARGET_HAS_IOPORT
 WRAP(uint8_t  , qtest_inb(QTestState *s, uint16_t addr))
 WRAP(uint16_t , qtest_inw(QTestState *s, uint16_t addr))
 WRAP(uint32_t , qtest_inl(QTestState *s, uint16_t addr))
 WRAP(void , qtest_outb(QTestState *s, uint16_t addr, uint8_t value))
 WRAP(void , qtest_outw(QTestState *s, uint16_t addr, uint16_t value))
 WRAP(void , qtest_outl(QTestState *s, uint16_t addr, uint32_t value))
+#endif /* TARGET_HAS_IOPORT */
 WRAP(uint8_t  , qtest_readb(QTestState *s, uint64_t addr))
 WRAP(uint16_t , qtest_readw(QTestState *s, uint64_t addr))
 WRAP(uint32_t , qtest_readl(QTestState *s, uint64_t addr))
@@ -50,6 +52,7 @@ WRAP(void,  qtest_memset(QTestState *s, uint64_t addr,
  uint8_t patt, size_t size))
 
 
+#ifdef TARGET_HAS_IOPORT
 uint8_t __wrap_qtest_inb(QTestState *s, uint16_t addr)
 {
 if (!serialize) {
@@ -103,6 +106,7 @@ void __wrap_qtest_outl(QTestState *s, uint16_t addr, 
uint32_t value)
 __real_qtest_outl(s, addr, value);
 }
 }
+#endif /* TARGET_HAS_IOPORT */
 
 uint8_t __wrap_qtest_readb(QTestState *s, uint64_t addr)
 {
-- 
2.26.2




[RFC PATCH 2/8] exec: Extract CPU I/O instructions to "cpu-io.h"

2021-03-14 Thread Philippe Mathieu-Daudé
Not all architectures use an I/O bus. Extract the CPU I/O
instruction helpers into a specific unit named cpu-io.c
(and its equivalent "cpu-io.h" header).

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/exec/cpu-io.h | 30 +++
 include/exec/ioport.h |  7 ---
 hw/i386/xen/xen-hvm.c |  1 +
 monitor/misc.c|  2 +-
 softmmu/cpu-io.c  | 88 +++
 softmmu/ioport.c  | 60 -
 softmmu/qtest.c   |  1 +
 tests/qtest/fuzz/qtest_wrappers.c |  3 +-
 softmmu/meson.build   |  3 +-
 9 files changed, 125 insertions(+), 70 deletions(-)
 create mode 100644 include/exec/cpu-io.h
 create mode 100644 softmmu/cpu-io.c

diff --git a/include/exec/cpu-io.h b/include/exec/cpu-io.h
new file mode 100644
index 000..6538c451177
--- /dev/null
+++ b/include/exec/cpu-io.h
@@ -0,0 +1,30 @@
+/*
+ * QEMU CPU I/O instructions
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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 .
+ */
+
+#ifndef CPU_IO_H
+#define CPU_IO_H
+
+void cpu_outb(uint32_t addr, uint8_t val);
+void cpu_outw(uint32_t addr, uint16_t val);
+void cpu_outl(uint32_t addr, uint32_t val);
+uint8_t cpu_inb(uint32_t addr);
+uint16_t cpu_inw(uint32_t addr);
+uint32_t cpu_inl(uint32_t addr);
+
+#endif /* CPU_IO_H */
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998d..e58f475a7f0 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -44,13 +44,6 @@ typedef struct MemoryRegionPortio {
 extern const MemoryRegionOps unassigned_io_ops;
 #endif
 
-void cpu_outb(uint32_t addr, uint8_t val);
-void cpu_outw(uint32_t addr, uint16_t val);
-void cpu_outl(uint32_t addr, uint32_t val);
-uint8_t cpu_inb(uint32_t addr);
-uint16_t cpu_inw(uint32_t addr);
-uint32_t cpu_inl(uint32_t addr);
-
 typedef struct PortioList {
 const struct MemoryRegionPortio *ports;
 Object *owner;
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 7ce672e5a5c..56e0018a50e 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -34,6 +34,7 @@
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
 #include "exec/address-spaces.h"
+#include "exec/cpu-io.h"
 
 #include 
 #include 
diff --git a/monitor/misc.c b/monitor/misc.c
index a7650ed7470..d40c7d5afc0 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -77,7 +77,7 @@
 #include "qapi/qmp-event.h"
 #include "sysemu/cpus.h"
 #include "qemu/cutils.h"
-
+#include "exec/cpu-io.h"
 #if defined(TARGET_S390X)
 #include "hw/s390x/storage-keys.h"
 #include "hw/s390x/storage-attributes.h"
diff --git a/softmmu/cpu-io.c b/softmmu/cpu-io.c
new file mode 100644
index 000..6ee03555f2c
--- /dev/null
+++ b/softmmu/cpu-io.c
@@ -0,0 +1,88 @@
+/*
+ * QEMU CPU I/O instructions
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/address-spaces.h"
+#include "exec/cpu-io.h"
+#include "cpu.h"
+#include "trace.h"
+
+void cpu_outb(uint32_t addr, uint8_t val)
+{
+trace_cpu_out(addr, 'b', val);
+address_space_write(_space_io, addr, MEMTXATTRS_UNSPECIFIED,
+, 1);
+}
+
+void cpu_outw(uint32_t addr, uint16_t val)
+{
+uint8_t buf[2];
+
+

[RFC PATCH 3/8] target: Introduce TARGET_HAS_IOPORT

2021-03-14 Thread Philippe Mathieu-Daudé
Have target architectures providing CPU access to I/O bus
define TARGET_HAS_IOPORT.

Signed-off-by: Philippe Mathieu-Daudé 
---
 default-configs/targets/avr-softmmu.mak| 1 +
 default-configs/targets/i386-softmmu.mak   | 1 +
 default-configs/targets/x86_64-softmmu.mak | 1 +
 3 files changed, 3 insertions(+)

diff --git a/default-configs/targets/avr-softmmu.mak 
b/default-configs/targets/avr-softmmu.mak
index e3f921c0199..4652ce136bc 100644
--- a/default-configs/targets/avr-softmmu.mak
+++ b/default-configs/targets/avr-softmmu.mak
@@ -1,2 +1,3 @@
 TARGET_ARCH=avr
+TARGET_HAS_IOPORT=y
 TARGET_XML_FILES= gdb-xml/avr-cpu.xml
diff --git a/default-configs/targets/i386-softmmu.mak 
b/default-configs/targets/i386-softmmu.mak
index 5babf71895d..969008859b6 100644
--- a/default-configs/targets/i386-softmmu.mak
+++ b/default-configs/targets/i386-softmmu.mak
@@ -1,3 +1,4 @@
 TARGET_ARCH=i386
+TARGET_HAS_IOPORT=y
 TARGET_SUPPORTS_MTTCG=y
 TARGET_XML_FILES= gdb-xml/i386-32bit.xml
diff --git a/default-configs/targets/x86_64-softmmu.mak 
b/default-configs/targets/x86_64-softmmu.mak
index 75e42bc8404..2d35270f020 100644
--- a/default-configs/targets/x86_64-softmmu.mak
+++ b/default-configs/targets/x86_64-softmmu.mak
@@ -1,4 +1,5 @@
 TARGET_ARCH=x86_64
 TARGET_BASE_ARCH=i386
+TARGET_HAS_IOPORT=y
 TARGET_SUPPORTS_MTTCG=y
 TARGET_XML_FILES= gdb-xml/i386-64bit.xml
-- 
2.26.2




[RFC PATCH 1/8] softmmu/physmem: Rename io_mem_unassigned -> unassigned_mr

2021-03-14 Thread Philippe Mathieu-Daudé
'io_mem_unassigned' memory region is not specific to I/O,
rename it using a more generic 'unassigned_mr', matching
the '_mr' suffix pattern used in various places in the code
base.

Signed-off-by: Philippe Mathieu-Daudé 
---
 softmmu/physmem.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 7e8b0fab89a..115679f8d1a 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -93,7 +93,7 @@ static MemoryRegion *system_io;
 AddressSpace address_space_io;
 AddressSpace address_space_memory;
 
-static MemoryRegion io_mem_unassigned;
+static MemoryRegion unassigned_mr;
 
 typedef struct PhysPageEntry PhysPageEntry;
 
@@ -458,7 +458,7 @@ static MemoryRegionSection 
address_space_translate_iommu(IOMMUMemoryRegion *iomm
 return *section;
 
 unassigned:
-return (MemoryRegionSection) { .mr = _mem_unassigned };
+return (MemoryRegionSection) { .mr = _mr };
 }
 
 /**
@@ -534,7 +534,7 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace 
*as, hwaddr addr,
 attrs);
 
 /* Illegal translation */
-if (section.mr == _mem_unassigned) {
+if (section.mr == _mr) {
 goto iotlb_fail;
 }
 
@@ -1212,7 +1212,7 @@ static void register_subpage(FlatView *fv, 
MemoryRegionSection *section)
 };
 hwaddr start, end;
 
-assert(existing->mr->subpage || existing->mr == _mem_unassigned);
+assert(existing->mr->subpage || existing->mr == _mr);
 
 if (!(existing->mr->subpage)) {
 subpage = subpage_init(fv, base);
@@ -2573,7 +2573,7 @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu,
 
 static void io_mem_init(void)
 {
-memory_region_init_io(_mem_unassigned, NULL, _mem_ops, NULL,
+memory_region_init_io(_mr, NULL, _mem_ops, NULL,
   NULL, UINT64_MAX);
 }
 
@@ -2582,7 +2582,7 @@ AddressSpaceDispatch *address_space_dispatch_new(FlatView 
*fv)
 AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
 uint16_t n;
 
-n = dummy_section(>map, fv, _mem_unassigned);
+n = dummy_section(>map, fv, _mr);
 assert(n == PHYS_SECTION_UNASSIGNED);
 
 d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
-- 
2.26.2




[RFC PATCH 0/8] softmmu: Restrict CPU I/O instructions

2021-03-14 Thread Philippe Mathieu-Daudé
An attempt to restrict CPU I/O instructions to targets
where it makes sense. If it does, I'll send the next
series which restrict the I/O address space to X86/AVR.

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

Philippe Mathieu-Daudé (8):
  softmmu/physmem: Rename io_mem_unassigned -> unassigned_mr
  exec: Extract CPU I/O instructions to "cpu-io.h"
  target: Introduce TARGET_HAS_IOPORT
  qtest/fuzz: Restrict CPU I/O instructions
  qtest/libqos: Restrict CPU I/O instructions
  qtest: Restrict CPU I/O instructions
  monitor: Restrict CPU I/O instructions
  softmmu: Restrict CPU I/O instructions

 default-configs/targets/avr-softmmu.mak|  1 +
 default-configs/targets/i386-softmmu.mak   |  1 +
 default-configs/targets/x86_64-softmmu.mak |  1 +
 include/exec/cpu-io.h  | 30 
 include/exec/ioport.h  |  7 --
 tests/qtest/libqos/fw_cfg.h|  3 +
 hw/i386/xen/xen-hvm.c  |  1 +
 monitor/misc.c |  6 +-
 softmmu/cpu-io.c   | 88 ++
 softmmu/ioport.c   | 60 ---
 softmmu/physmem.c  | 12 +--
 softmmu/qtest.c| 11 ++-
 tests/qtest/fuzz/generic_fuzz.c| 16 ++--
 tests/qtest/fuzz/qtest_wrappers.c  |  7 +-
 tests/qtest/libqos/fw_cfg.c|  2 +
 hmp-commands.hx|  2 +
 softmmu/meson.build|  3 +-
 17 files changed, 167 insertions(+), 84 deletions(-)
 create mode 100644 include/exec/cpu-io.h
 create mode 100644 softmmu/cpu-io.c

-- 
2.26.2




Re: [PATCH] qtest/libqos/meson: Restrict architecture specific objects

2021-03-14 Thread Alexander Bulekov
On 210314 2353, Philippe Mathieu-Daudé wrote:
> Various libqos files are architecture specific.
> Restrict the ARM/PPC/X86 units to their targets.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---

I thought qos-test is reused for all the machines, and all the arch
checking is done at runtime. Also, are these variables actually defined
when building tests? There seem to be some link failures:

ninja -j`nproc` tests/qtest/qos-test
clang-11  -o tests/qtest/qos-test ...
/usr/bin/ld: tests/qtest/qos-test.p/virtio-blk-test.c.o: in function 
`pci_hotplug':
undefined reference to `qpci_unplug_acpi_device_test

-Alex

>  tests/qtest/libqos/meson.build | 51 ++
>  1 file changed, 34 insertions(+), 17 deletions(-)
> 
> diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
> index 1cddf5bdaa1..817c2cc2c20 100644
> --- a/tests/qtest/libqos/meson.build
> +++ b/tests/qtest/libqos/meson.build
> @@ -1,4 +1,8 @@
> -libqos_srcs = files('../libqtest.c',
> +libqos_ss = ss.source_set()
> +
> +libqos_ss.add(genh)
> +
> +libqos_ss.add(files('../libqtest.c',
>  'qgraph.c',
>  'qos_external.c',
>  'pci.c',
> @@ -6,18 +10,6 @@
>  'malloc.c',
>  'libqos.c',
>  
> -# spapr
> -'malloc-spapr.c',
> -'libqos-spapr.c',
> -'rtas.c',
> -'pci-spapr.c',
> -
> -# pc
> -'pci-pc.c',
> -'malloc-pc.c',
> -'libqos-pc.c',
> -'ahci.c',
> -
>  # usb
>  'usb.c',
>  
> @@ -39,7 +31,28 @@
>  'virtio-rng.c',
>  'virtio-scsi.c',
>  'virtio-serial.c',
> +))
>  
> +libqos_ss.add(when: 'TARGET_I386', if_true: files(
> +'pci-pc.c',
> +'malloc-pc.c',
> +'libqos-pc.c',
> +
> +'ahci.c',
> +
> +# qgraph machines:
> +'x86_64_pc-machine.c',
> +))
> +libqos_ss.add(when: 'TARGET_PPC64', if_true: files(
> +'malloc-spapr.c',
> +'libqos-spapr.c',
> +'rtas.c',
> +'pci-spapr.c',
> +
> +# qgraph machines:
> +'ppc64_pseries-machine.c',
> +))
> +libqos_ss.add(when: 'TARGET_ARM', if_true: files(
>  # qgraph machines:
>  'aarch64-xlnx-zcu102-machine.c',
>  'arm-imx25-pdk-machine.c',
> @@ -49,11 +62,15 @@
>  'arm-smdkc210-machine.c',
>  'arm-virt-machine.c',
>  'arm-xilinx-zynq-a9-machine.c',
> -'ppc64_pseries-machine.c',
> -'x86_64_pc-machine.c',
> -)
> +))
> +libqos_ss.add(when: 'TARGET_AARCH64', if_true: files(
> +# qgraph machines:
> +'aarch64-xlnx-zcu102-machine.c',
> +))
>  
> -libqos = static_library('qos', libqos_srcs + genh,
> +libqos_ss = libqos_ss.apply(config_host, strict: false)
> +
> +libqos = static_library('qos', libqos_ss.sources() + genh,
>  name_suffix: 'fa',
>  build_by_default: false)
>  
> -- 
> 2.26.2
> 



Re: [PATCH] fuzz: check machine, before PC-specific code

2021-03-14 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20210314231015.29166-1-alx...@bu.edu/



Hi,

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

Type: series
Message-id: 20210314231015.29166-1-alx...@bu.edu
Subject: [PATCH] fuzz: check machine, before PC-specific code

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/20210314231015.29166-1-alx...@bu.edu -> 
patchew/20210314231015.29166-1-alx...@bu.edu
Switched to a new branch 'test'
bb8e08d fuzz: check machine, before PC-specific code

=== OUTPUT BEGIN ===
ERROR: "foo* bar" should be "foo *bar"
#25: FILE: tests/qtest/fuzz/generic_fuzz.c:787:
+const char* machine_type;

ERROR: space required before the open parenthesis '('
#37: FILE: tests/qtest/fuzz/generic_fuzz.c:832:
+if(fuzzable_pci_devices->len && strstr(machine_type, "pc") == machine_type)

total: 2 errors, 0 warnings, 23 lines checked

Commit bb8e08d89398 (fuzz: check machine, before PC-specific code) has style 
problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


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

Re: [PATCH v2 1/3] memory: add a sparse memory device for fuzzing

2021-03-14 Thread Alexander Bulekov
On 210313 1818, Alexander Bulekov wrote:
> For testing, it can be useful to simulate an enormous amount of memory
> (e.g. 2^64 RAM). This adds an MMIO device that acts as sparse memory.
> When something writes a nonzero value to a sparse-mem address, we
> allocate a block of memory. This block is kept around, until all of the
> bytes within the block are zero-ed. The device has a very low priority
> (so it can be mapped beneath actual RAM, and virtual device MMIO
> regions).
> 
> Signed-off-by: Alexander Bulekov 
> ---
>  MAINTAINERS |   1 +
>  hw/mem/meson.build  |   1 +
>  hw/mem/sparse-mem.c | 152 
>  include/hw/mem/sparse-mem.h |  19 +
>  4 files changed, 173 insertions(+)
>  create mode 100644 hw/mem/sparse-mem.c
>  create mode 100644 include/hw/mem/sparse-mem.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f22d83c178..9e3d8b1401 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2618,6 +2618,7 @@ R: Thomas Huth 
>  S: Maintained
>  F: tests/qtest/fuzz/
>  F: scripts/oss-fuzz/
> +F: hw/mem/sparse-mem.c
>  F: docs/devel/fuzzing.rst
>  
>  Register API
> diff --git a/hw/mem/meson.build b/hw/mem/meson.build
> index 0d22f2b572..ef79e04678 100644
> --- a/hw/mem/meson.build
> +++ b/hw/mem/meson.build
> @@ -1,5 +1,6 @@
>  mem_ss = ss.source_set()
>  mem_ss.add(files('memory-device.c'))
> +mem_ss.add(when: 'CONFIG_FUZZ', if_true: files('sparse-mem.c'))
>  mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc-dimm.c'))
>  mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c'))
>  mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c'))
> diff --git a/hw/mem/sparse-mem.c b/hw/mem/sparse-mem.c
> new file mode 100644
> index 00..575a287f59
> --- /dev/null
> +++ b/hw/mem/sparse-mem.c
> @@ -0,0 +1,152 @@
> +/*
> + * A sparse memory device. Useful for fuzzing
> + *
> + * Copyright Red Hat Inc., 2021
> + *
> + * Authors:
> + *  Alexander Bulekov   
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "exec/address-spaces.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qapi/error.h"
> +#include "qemu/units.h"
> +#include "sysemu/qtest.h"
> +#include "hw/mem/sparse-mem.h"
> +
> +#define SPARSE_MEM(obj) OBJECT_CHECK(SparseMemState, (obj), TYPE_SPARSE_MEM)
> +#define SPARSE_BLOCK_SIZE 0x1000
> +
> +typedef struct SparseMemState {
> +SysBusDevice parent_obj;
> +MemoryRegion mmio;
> +uint64_t baseaddr;
> +uint64_t length;
> +uint64_t size_used;
> +uint64_t maxsize;
> +GHashTable *mapped;
> +} SparseMemState;
> +
> +typedef struct sparse_mem_block {
> +uint8_t data[SPARSE_BLOCK_SIZE];
> +} sparse_mem_block;
> +
> +static uint64_t sparse_mem_read(void *opaque, hwaddr addr, unsigned int size)
> +{
> +printf("SPARSEREAD %lx\n", addr);
This debug-printf shouldn't be here..
-Alex



Re: [PATCH] fuzz: check machine, before PC-specific code

2021-03-14 Thread Alexander Bulekov
On 210314 1910, Alexander Bulekov wrote:
> We enumerate PCI devices on PC machines, but this breaks the fuzzer for
> non-PC machines and architectures. Add checks to avoid this.
> 
> Reported-by: Philippe Mathieu-Daudé 
> Signed-off-by: Alexander Bulekov 
> ---
>  tests/qtest/fuzz/generic_fuzz.c | 11 ---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
> index ee8c17a04c..d2b74028fe 100644
> --- a/tests/qtest/fuzz/generic_fuzz.c
> +++ b/tests/qtest/fuzz/generic_fuzz.c
> @@ -784,6 +784,7 @@ static void generic_pre_fuzz(QTestState *s)
>  MemoryRegion *mr;
>  QPCIBus *pcibus;
>  char **result;
> +const char* machine_type;
>  
>  if (!getenv("QEMU_FUZZ_OBJECTS")) {
>  usage();
> @@ -827,9 +828,13 @@ static void generic_pre_fuzz(QTestState *s)
>  exit(1);
>  }
>  
> -pcibus = qpci_new_pc(s, NULL);
> -g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> -qpci_free_pc(pcibus);
> +machine_type = object_get_typename(qdev_get_machine());
> +if(fuzzable_pci_devices->len && strstr(machine_type, "pc") == 
> machine_type)
  Should at least be "pc-" --^
Maybe there's a more cannonical way to do this..
-Alex

> +{
> +pcibus = qpci_new_pc(s, NULL);
> +g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> +qpci_free_pc(pcibus);
> +}
>  
>  counter_shm_init();
>  }
> -- 
> 2.27.0
> 



[PATCH] fuzz: check machine, before PC-specific code

2021-03-14 Thread Alexander Bulekov
We enumerate PCI devices on PC machines, but this breaks the fuzzer for
non-PC machines and architectures. Add checks to avoid this.

Reported-by: Philippe Mathieu-Daudé 
Signed-off-by: Alexander Bulekov 
---
 tests/qtest/fuzz/generic_fuzz.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index ee8c17a04c..d2b74028fe 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -784,6 +784,7 @@ static void generic_pre_fuzz(QTestState *s)
 MemoryRegion *mr;
 QPCIBus *pcibus;
 char **result;
+const char* machine_type;
 
 if (!getenv("QEMU_FUZZ_OBJECTS")) {
 usage();
@@ -827,9 +828,13 @@ static void generic_pre_fuzz(QTestState *s)
 exit(1);
 }
 
-pcibus = qpci_new_pc(s, NULL);
-g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
-qpci_free_pc(pcibus);
+machine_type = object_get_typename(qdev_get_machine());
+if(fuzzable_pci_devices->len && strstr(machine_type, "pc") == machine_type)
+{
+pcibus = qpci_new_pc(s, NULL);
+g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
+qpci_free_pc(pcibus);
+}
 
 counter_shm_init();
 }
-- 
2.27.0




[PATCH] qtest/libqos/meson: Restrict architecture specific objects

2021-03-14 Thread Philippe Mathieu-Daudé
Various libqos files are architecture specific.
Restrict the ARM/PPC/X86 units to their targets.

Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/qtest/libqos/meson.build | 51 ++
 1 file changed, 34 insertions(+), 17 deletions(-)

diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 1cddf5bdaa1..817c2cc2c20 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -1,4 +1,8 @@
-libqos_srcs = files('../libqtest.c',
+libqos_ss = ss.source_set()
+
+libqos_ss.add(genh)
+
+libqos_ss.add(files('../libqtest.c',
 'qgraph.c',
 'qos_external.c',
 'pci.c',
@@ -6,18 +10,6 @@
 'malloc.c',
 'libqos.c',
 
-# spapr
-'malloc-spapr.c',
-'libqos-spapr.c',
-'rtas.c',
-'pci-spapr.c',
-
-# pc
-'pci-pc.c',
-'malloc-pc.c',
-'libqos-pc.c',
-'ahci.c',
-
 # usb
 'usb.c',
 
@@ -39,7 +31,28 @@
 'virtio-rng.c',
 'virtio-scsi.c',
 'virtio-serial.c',
+))
 
+libqos_ss.add(when: 'TARGET_I386', if_true: files(
+'pci-pc.c',
+'malloc-pc.c',
+'libqos-pc.c',
+
+'ahci.c',
+
+# qgraph machines:
+'x86_64_pc-machine.c',
+))
+libqos_ss.add(when: 'TARGET_PPC64', if_true: files(
+'malloc-spapr.c',
+'libqos-spapr.c',
+'rtas.c',
+'pci-spapr.c',
+
+# qgraph machines:
+'ppc64_pseries-machine.c',
+))
+libqos_ss.add(when: 'TARGET_ARM', if_true: files(
 # qgraph machines:
 'aarch64-xlnx-zcu102-machine.c',
 'arm-imx25-pdk-machine.c',
@@ -49,11 +62,15 @@
 'arm-smdkc210-machine.c',
 'arm-virt-machine.c',
 'arm-xilinx-zynq-a9-machine.c',
-'ppc64_pseries-machine.c',
-'x86_64_pc-machine.c',
-)
+))
+libqos_ss.add(when: 'TARGET_AARCH64', if_true: files(
+# qgraph machines:
+'aarch64-xlnx-zcu102-machine.c',
+))
 
-libqos = static_library('qos', libqos_srcs + genh,
+libqos_ss = libqos_ss.apply(config_host, strict: false)
+
+libqos = static_library('qos', libqos_ss.sources() + genh,
 name_suffix: 'fa',
 build_by_default: false)
 
-- 
2.26.2




Re: [PATCH v3] fuzz: map all BARs and enable PCI devices

2021-03-14 Thread Philippe Mathieu-Daudé
On 12/21/20 7:12 PM, Alexander Bulekov wrote:
> Prior to this patch, the fuzzer found inputs to map PCI device BARs and
> enable the device. While it is nice that the fuzzer can do this, it
> added significant overhead, since the fuzzer needs to map all the
> BARs (regenerating the memory topology), at the start of each input.
> With this patch, we do this once, before fuzzing, mitigating some of
> this overhead.
> 
> Signed-off-by: Alexander Bulekov 
> Reviewed-by: Darren Kenny 
> ---
> 
> v3: Plug the memory-leak pointed out by Thomas:
> https://gitlab.com/huth/qemu/-/jobs/920543745#L309
> 
>  tests/qtest/fuzz/generic_fuzz.c | 24 
>  1 file changed, 24 insertions(+)
> 
> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
> index 07ad690683..be76d47d2d 100644
> --- a/tests/qtest/fuzz/generic_fuzz.c
> +++ b/tests/qtest/fuzz/generic_fuzz.c
> @@ -16,6 +16,7 @@
>  
>  #include "hw/core/cpu.h"
>  #include "tests/qtest/libqos/libqtest.h"
> +#include "tests/qtest/libqos/pci-pc.h"
>  #include "fuzz.h"
>  #include "fork_fuzz.h"
>  #include "exec/address-spaces.h"
> @@ -762,10 +763,29 @@ static int locate_fuzz_objects(Object *child, void 
> *opaque)
>  return 0;
>  }
>  
> +
> +static void pci_enum(gpointer pcidev, gpointer bus)
> +{
> +PCIDevice *dev = pcidev;
> +QPCIDevice *qdev;
> +int i;
> +
> +qdev = qpci_device_find(bus, dev->devfn);
> +g_assert(qdev != NULL);
> +for (i = 0; i < 6; i++) {
> +if (dev->io_regions[i].size) {
> +qpci_iomap(qdev, i, NULL);
> +}
> +}
> +qpci_device_enable(qdev);
> +g_free(qdev);
> +}
> +
>  static void generic_pre_fuzz(QTestState *s)
>  {
>  GHashTableIter iter;
>  MemoryRegion *mr;
> +QPCIBus *pcibus;
>  char **result;
>  
>  if (!getenv("QEMU_FUZZ_OBJECTS")) {
> @@ -810,6 +830,10 @@ static void generic_pre_fuzz(QTestState *s)
>  exit(1);
>  }
>  
> +pcibus = qpci_new_pc(s, NULL);

FYI this patch restricted the "generic" fuzzer to the x86 arch.

> +g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> +qpci_free_pc(pcibus);
> +
>  counter_shm_init();
>  }
>  
> 




Re: [RFC PATCH 0/6] vhost-user: Shutdown/Flush slave channel properly

2021-03-14 Thread Vivek Goyal
On Sun, Mar 14, 2021 at 06:21:04PM -0400, Michael S. Tsirkin wrote:
> On Mon, Jan 25, 2021 at 01:01:09PM -0500, Vivek Goyal wrote:
> > Hi,
> > 
> > We are working on DAX support in virtiofs and have some patches out of
> > the tree hosted here.
> > 
> > https://gitlab.com/virtio-fs/qemu/-/commits/virtio-fs-dev
> 
> ping anyone wants to pick this up and post a non-rfc version?

Hi Michael,

Greg has picked this work and has alredy posted V2 of patches here.

https://lore.kernel.org/qemu-devel/20210312092212.782255-8-gr...@kaod.org/T/

Please have a look.

Thanks
Vivek

> 
> > These patches have not been proposed for merge yet, becasue David
> > Gilbert noticed that we can run into a deadlock during an emergency
> > reboot of guest kernel. (echo b > /proc/sysrq-trigger).
> > 
> > I have provided details of deadlock in 4th path of the series with
> > subject "qemu, vhost-user: Extend protocol to start/stop/flush slave
> > channel".
> > 
> > Basic problem seems to be that we don't have a proper mechanism to
> > shutdown slave channel when vhost-user device is stopping. This means
> > there might be pending messages in slave channel and slave is blocked
> > and waiting for response.
> > 
> > This is an RFC patch series to enhance vhost-user protocol to 
> > properly shutdown/flush slave channel and avoid the deadlock. Though
> > we faced the issue in the context of virtiofs, any vhost-user
> > device using slave channel can potentially run into issues and
> > can benefit from these patches.
> > 
> > Any feedback is welcome. Currently patches are based on out of
> > tree code but after I get some feedback, I can only take pieces
> > which are relevant to upstream and post separately.
> > 
> > Thanks
> > Vivek
> > 
> > Vivek Goyal (6):
> >   virtiofsd: Drop ->vu_dispatch_rwlock while waiting for thread to exit
> >   libvhost-user: Use slave_mutex in all slave messages
> >   vhost-user: Return error code from slave_read()
> >   qemu, vhost-user: Extend protocol to start/stop/flush slave channel
> >   libvhost-user: Add support to start/stop/flush slave channel
> >   virtiofsd: Opt in for slave start/stop/shutdown functionality
> > 
> >  hw/virtio/vhost-user.c| 151 +-
> >  subprojects/libvhost-user/libvhost-user.c | 147 +
> >  subprojects/libvhost-user/libvhost-user.h |   8 +-
> >  tools/virtiofsd/fuse_virtio.c |  20 +++
> >  4 files changed, 294 insertions(+), 32 deletions(-)
> > 
> > -- 
> > 2.25.4
> 




Re: [RFC PATCH 0/6] vhost-user: Shutdown/Flush slave channel properly

2021-03-14 Thread Michael S. Tsirkin
On Mon, Jan 25, 2021 at 01:01:09PM -0500, Vivek Goyal wrote:
> Hi,
> 
> We are working on DAX support in virtiofs and have some patches out of
> the tree hosted here.
> 
> https://gitlab.com/virtio-fs/qemu/-/commits/virtio-fs-dev

ping anyone wants to pick this up and post a non-rfc version?

> These patches have not been proposed for merge yet, becasue David
> Gilbert noticed that we can run into a deadlock during an emergency
> reboot of guest kernel. (echo b > /proc/sysrq-trigger).
> 
> I have provided details of deadlock in 4th path of the series with
> subject "qemu, vhost-user: Extend protocol to start/stop/flush slave
> channel".
> 
> Basic problem seems to be that we don't have a proper mechanism to
> shutdown slave channel when vhost-user device is stopping. This means
> there might be pending messages in slave channel and slave is blocked
> and waiting for response.
> 
> This is an RFC patch series to enhance vhost-user protocol to 
> properly shutdown/flush slave channel and avoid the deadlock. Though
> we faced the issue in the context of virtiofs, any vhost-user
> device using slave channel can potentially run into issues and
> can benefit from these patches.
> 
> Any feedback is welcome. Currently patches are based on out of
> tree code but after I get some feedback, I can only take pieces
> which are relevant to upstream and post separately.
> 
> Thanks
> Vivek
> 
> Vivek Goyal (6):
>   virtiofsd: Drop ->vu_dispatch_rwlock while waiting for thread to exit
>   libvhost-user: Use slave_mutex in all slave messages
>   vhost-user: Return error code from slave_read()
>   qemu, vhost-user: Extend protocol to start/stop/flush slave channel
>   libvhost-user: Add support to start/stop/flush slave channel
>   virtiofsd: Opt in for slave start/stop/shutdown functionality
> 
>  hw/virtio/vhost-user.c| 151 +-
>  subprojects/libvhost-user/libvhost-user.c | 147 +
>  subprojects/libvhost-user/libvhost-user.h |   8 +-
>  tools/virtiofsd/fuse_virtio.c |  20 +++
>  4 files changed, 294 insertions(+), 32 deletions(-)
> 
> -- 
> 2.25.4




Re: [PATCH v2 00/29] tcg: Workaround macOS 11.2 mprotect bug

2021-03-14 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210314212724.1917075-1-richard.hender...@linaro.org/



Hi,

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

Type: series
Message-id: 20210314212724.1917075-1-richard.hender...@linaro.org
Subject: [PATCH v2 00/29] tcg: Workaround macOS 11.2 mprotect bug

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20210314163927.1184-1-peter.mayd...@linaro.org -> 
patchew/20210314163927.1184-1-peter.mayd...@linaro.org
 * [new tag] 
patchew/20210314212724.1917075-1-richard.hender...@linaro.org -> 
patchew/20210314212724.1917075-1-richard.hender...@linaro.org
Switched to a new branch 'test'
9906c07 tcg: Move tcg_init_ctx and tcg_ctx from accel/tcg/
ef1e2c0 tcg: When allocating for !splitwx, begin with PROT_NONE
76e12ad tcg: Merge buffer protection and guard page protection
1e9c899 tcg: Round the tb_size default from qemu_get_host_physmem
4bdfded util/osdep: Add qemu_mprotect_rw
a1751c5 tcg: Do not set guard pages in the rx buffer
40483ad tcg: Sink qemu_madvise call to common code
856c724 tcg: Return the map protection from alloc_code_gen_buffer
7622097 tcg: Allocate code_gen_buffer into struct tcg_region_state
251d71e tcg: Move in_code_gen_buffer and tests to region.c
a6a064d tcg: Tidy split_cross_256mb
af03a0d tcg: Tidy tcg_n_regions
218436d tcg: Rename region.start to region.after_prologue
9f3981e tcg: Replace region.end with region.total_size
276ecb9 tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h
683f5af tcg: Introduce tcg_max_ctxs
d7bf2f6 accel/tcg: Pass down max_cpus to tcg_init
a1cd412 accel/tcg: Merge tcg_exec_init into tcg_init_machine
4940162 tcg: Create tcg_init
4ab59ad accel/tcg: Rename tcg_init to tcg_init_machine
e27bd38 accel/tcg: Move alloc_code_gen_buffer to tcg/region.c
d4c3608 accel/tcg: Inline cpu_gen_init
2245d5c tcg: Split out region.c
a284234 tcg: Split out tcg_region_prologue_set
d116828 tcg: Split out tcg_region_initial_alloc
c75ce79 tcg: Remove error return from tcg_region_initial_alloc__locked
0df4d6c tcg: Re-order tcg_region_init vs tcg_prologue_init
cc0f7f7 meson: Split out fpu/meson.build
b0a2113 meson: Split out tcg/meson.build

=== OUTPUT BEGIN ===
1/29 Checking commit b0a211318ba3 (meson: Split out tcg/meson.build)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#44: 
new file mode 100644

total: 0 errors, 1 warnings, 35 lines checked

Patch 1/29 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
2/29 Checking commit cc0f7f7fdc1a (meson: Split out fpu/meson.build)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

total: 0 errors, 1 warnings, 17 lines checked

Patch 2/29 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/29 Checking commit 0df4d6c7ee67 (tcg: Re-order tcg_region_init vs 
tcg_prologue_init)
4/29 Checking commit c75ce79d8926 (tcg: Remove error return from 
tcg_region_initial_alloc__locked)
5/29 Checking commit d116828491cc (tcg: Split out tcg_region_initial_alloc)
6/29 Checking commit a284234d3909 (tcg: Split out tcg_region_prologue_set)
7/29 Checking commit 2245d5c83ec4 (tcg: Split out region.c)
Use of uninitialized value $acpi_testexpected in string eq at 
./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#17: 
new file mode 100644

total: 0 errors, 1 warnings, 1189 lines checked

Patch 7/29 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/29 Checking commit d4c36080e021 (accel/tcg: Inline cpu_gen_init)
9/29 Checking commit e27bd38f652c (accel/tcg: Move alloc_code_gen_buffer to 
tcg/region.c)
WARNING: Block comments use a leading /* on a separate line
#499: FILE: tcg/region.c:411:
+/* Minimum size of the code gen buffer.  This number is randomly chosen,

WARNING: Block comments use * on subsequent lines
#500: FILE: tcg/region.c:412:
+/* Minimum size of the code gen buffer.  This number is randomly chosen,
+   but not so small that we can't have a fair number of TB's live.  */

WARNING: Block comments use a trailing */ on a separate line
#500: FILE: tcg/region.c:412:
+   but not so small that we can't have a fair number of TB's live.  */


Re: [PATCH v2 22/29] tcg: Return the map protection from alloc_code_gen_buffer

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/14/21 10:27 PM, Richard Henderson wrote:
> Change the interface from a boolean error indication to a
> negative error vs a non-negative protection.  For the moment
> this is only interface change, not making use of the new data.
> 
> Signed-off-by: Richard Henderson 
> ---
>  tcg/region.c | 63 +++-
>  1 file changed, 33 insertions(+), 30 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé 



[PATCH v2 25/29] util/osdep: Add qemu_mprotect_rw

2021-03-14 Thread Richard Henderson
For --enable-tcg-interpreter on Windows, we will need this.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/qemu/osdep.h | 1 +
 util/osdep.c | 9 +
 2 files changed, 10 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ba15be9c56..5cc2e57bdf 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -494,6 +494,7 @@ void sigaction_invoke(struct sigaction *action,
 #endif
 
 int qemu_madvise(void *addr, size_t len, int advice);
+int qemu_mprotect_rw(void *addr, size_t size);
 int qemu_mprotect_rwx(void *addr, size_t size);
 int qemu_mprotect_none(void *addr, size_t size);
 
diff --git a/util/osdep.c b/util/osdep.c
index 66d01b9160..42a0a4986a 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -97,6 +97,15 @@ static int qemu_mprotect__osdep(void *addr, size_t size, int 
prot)
 #endif
 }
 
+int qemu_mprotect_rw(void *addr, size_t size)
+{
+#ifdef _WIN32
+return qemu_mprotect__osdep(addr, size, PAGE_READWRITE);
+#else
+return qemu_mprotect__osdep(addr, size, PROT_READ | PROT_WRITE);
+#endif
+}
+
 int qemu_mprotect_rwx(void *addr, size_t size)
 {
 #ifdef _WIN32
-- 
2.25.1




Re: [PATCH v2 29/29] tcg: Move tcg_init_ctx and tcg_ctx from accel/tcg/

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/14/21 10:27 PM, Richard Henderson wrote:
> These variables belong to the jit side, not the user side.
> 
> Since tcg_init_ctx is no longer used outside of tcg/, move
> the declaration to tcg/internal.h.
> 
> Suggested-by: Philippe Mathieu-Daudé 
> Signed-off-by: Richard Henderson 
> ---
>  include/tcg/tcg.h | 1 -
>  tcg/internal.h| 1 +
>  accel/tcg/translate-all.c | 3 ---
>  tcg/tcg.c | 3 +++
>  4 files changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH] include/ui/console.h: Delete is_surface_bgr()

2021-03-14 Thread Philippe Mathieu-Daudé
On 3/14/21 5:39 PM, Peter Maydell wrote:
> The function is_surface_bgr() is no longer used anywhere,
> so we can delete it.
> 
> Signed-off-by: Peter Maydell 
> ---
>  include/ui/console.h | 10 --
>  1 file changed, 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé 



[PATCH v2 29/29] tcg: Move tcg_init_ctx and tcg_ctx from accel/tcg/

2021-03-14 Thread Richard Henderson
These variables belong to the jit side, not the user side.

Since tcg_init_ctx is no longer used outside of tcg/, move
the declaration to tcg/internal.h.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h | 1 -
 tcg/internal.h| 1 +
 accel/tcg/translate-all.c | 3 ---
 tcg/tcg.c | 3 +++
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index a19deb529f..eef8857cca 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -690,7 +690,6 @@ static inline bool temp_readonly(TCGTemp *ts)
 return ts->kind >= TEMP_FIXED;
 }
 
-extern TCGContext tcg_init_ctx;
 extern __thread TCGContext *tcg_ctx;
 extern const void *tcg_code_gen_epilogue;
 extern uintptr_t tcg_splitwx_diff;
diff --git a/tcg/internal.h b/tcg/internal.h
index f9906523da..181f86507a 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -27,6 +27,7 @@
 
 #define TCG_HIGHWATER 1024
 
+extern TCGContext tcg_init_ctx;
 extern TCGContext **tcg_ctxs;
 extern unsigned int tcg_cur_ctxs;
 extern unsigned int tcg_max_ctxs;
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 40aeecf611..b32760c253 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -218,9 +218,6 @@ static int v_l2_levels;
 
 static void *l1_map[V_L1_MAX_SIZE];
 
-/* code generation context */
-TCGContext tcg_init_ctx;
-__thread TCGContext *tcg_ctx;
 TBContext tb_ctx;
 
 static void page_table_config_init(void)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 65f9cf01d5..77335fb60f 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -149,6 +149,9 @@ static int tcg_target_const_match(tcg_target_long val, 
TCGType type,
 static int tcg_out_ldst_finalize(TCGContext *s);
 #endif
 
+TCGContext tcg_init_ctx;
+__thread TCGContext *tcg_ctx;
+
 TCGContext **tcg_ctxs;
 unsigned int tcg_cur_ctxs;
 unsigned int tcg_max_ctxs;
-- 
2.25.1




[PATCH v2 28/29] tcg: When allocating for !splitwx, begin with PROT_NONE

2021-03-14 Thread Richard Henderson
There's a change in mprotect() behaviour [1] in the latest macOS
on M1 and it's not yet clear if it's going to be fixed by Apple.

In this case, instead of changing permissions of N guard pages,
we change permissions of N rwx regions.  The same number of
syscalls are required either way.

[1] https://gist.github.com/hikalium/75ae822466ee4da13cbbe486498a191f

Buglink: https://bugs.launchpad.net/qemu/+bug/1914849
Signed-off-by: Richard Henderson 
---
 tcg/region.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index fac416ebf5..53f78965c7 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -765,12 +765,15 @@ static int alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
 error_free_or_abort(errp);
 }
 
-prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+/*
+ * macOS 11.2 has a bug (Apple Feedback FB8994773) in which mprotect
+ * rejects a permission change from RWX -> NONE when reserving the
+ * guard pages later.  We can go the other way with the same number
+ * of syscalls, so always begin with PROT_NONE.
+ */
+prot = PROT_NONE;
 flags = MAP_PRIVATE | MAP_ANONYMOUS;
-#ifdef CONFIG_TCG_INTERPRETER
-/* The tcg interpreter does not need execute permission. */
-prot = PROT_READ | PROT_WRITE;
-#elif defined(CONFIG_DARWIN)
+#ifdef CONFIG_DARWIN
 /* Applicable to both iOS and macOS (Apple Silicon). */
 if (!splitwx) {
 flags |= MAP_JIT;
-- 
2.25.1




[PATCH v2 26/29] tcg: Round the tb_size default from qemu_get_host_physmem

2021-03-14 Thread Richard Henderson
If qemu_get_host_physmem returns an odd number of pages,
then physmem / 8 will not be a multiple of the page size.

The following was observed on a gitlab runner:

ERROR qtest-arm/boot-serial-test - Bail out!
ERROR:../util/osdep.c:80:qemu_mprotect__osdep: \
  assertion failed: (!(size & ~qemu_real_host_page_mask))

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 47 +--
 1 file changed, 21 insertions(+), 26 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 27a7e35c8e..4dc1237ff4 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -469,26 +469,6 @@ static size_t tcg_n_regions(size_t tb_size, unsigned 
max_cpus)
   (DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
 
-static size_t size_code_gen_buffer(size_t tb_size)
-{
-/* Size the buffer.  */
-if (tb_size == 0) {
-size_t phys_mem = qemu_get_host_physmem();
-if (phys_mem == 0) {
-tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
-} else {
-tb_size = MIN(DEFAULT_CODE_GEN_BUFFER_SIZE, phys_mem / 8);
-}
-}
-if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
-tb_size = MIN_CODE_GEN_BUFFER_SIZE;
-}
-if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
-tb_size = MAX_CODE_GEN_BUFFER_SIZE;
-}
-return tb_size;
-}
-
 #ifdef __mips__
 /* In order to use J and JAL within the code_gen_buffer, we require
that the buffer not cross a 256MB boundary.  */
@@ -836,13 +816,29 @@ static int alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
  */
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
-size_t page_size;
+const size_t page_size = qemu_real_host_page_size;
 size_t region_size;
 size_t i;
 int have_prot;
 
-have_prot = alloc_code_gen_buffer(size_code_gen_buffer(tb_size),
-  splitwx, _fatal);
+/* Size the buffer.  */
+if (tb_size == 0) {
+size_t phys_mem = qemu_get_host_physmem();
+if (phys_mem == 0) {
+tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
+} else {
+tb_size = QEMU_ALIGN_DOWN(phys_mem / 8, page_size);
+tb_size = MIN(DEFAULT_CODE_GEN_BUFFER_SIZE, tb_size);
+}
+}
+if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
+tb_size = MIN_CODE_GEN_BUFFER_SIZE;
+}
+if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
+tb_size = MAX_CODE_GEN_BUFFER_SIZE;
+}
+
+have_prot = alloc_code_gen_buffer(tb_size, splitwx, _fatal);
 assert(have_prot >= 0);
 
 /* Request large pages for the buffer and the splitwx.  */
@@ -857,9 +853,8 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
  * As a result of this we might end up with a few extra pages at the end of
  * the buffer; we will assign those to the last region.
  */
-region.n = tcg_n_regions(region.total_size, max_cpus);
-page_size = qemu_real_host_page_size;
-region_size = region.total_size / region.n;
+region.n = tcg_n_regions(tb_size, max_cpus);
+region_size = tb_size / region.n;
 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
 
 /* A region must have at least 2 pages; one code, one guard */
-- 
2.25.1




[PATCH v2 16/29] tcg: Replace region.end with region.total_size

2021-03-14 Thread Richard Henderson
A size is easier to work with than an end point,
particularly during initial buffer allocation.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index ae22308290..8e4dd0480b 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -48,7 +48,7 @@ struct tcg_region_state {
 /* fields set at init time */
 void *start;
 void *start_aligned;
-void *end;
+size_t total_size; /* size of entire buffer */
 size_t n;
 size_t size; /* size of one region */
 size_t stride; /* .size + guard size */
@@ -279,7 +279,7 @@ static void tcg_region_bounds(size_t curr_region, void 
**pstart, void **pend)
 start = region.start;
 }
 if (curr_region == region.n - 1) {
-end = region.end;
+end = region.start_aligned + region.total_size;
 }
 
 *pstart = start;
@@ -813,8 +813,8 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
  */
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
-void *buf, *aligned;
-size_t size;
+void *buf, *aligned, *end;
+size_t total_size;
 size_t page_size;
 size_t region_size;
 size_t n_regions;
@@ -827,19 +827,20 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
 assert(ok);
 
 buf = tcg_init_ctx.code_gen_buffer;
-size = tcg_init_ctx.code_gen_buffer_size;
+total_size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
 n_regions = tcg_n_regions(max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-g_assert(aligned < tcg_init_ctx.code_gen_buffer + size);
+g_assert(aligned < tcg_init_ctx.code_gen_buffer + total_size);
+
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
  * the buffer; we will assign those to the last region.
  */
-region_size = (size - (aligned - buf)) / n_regions;
+region_size = (total_size - (aligned - buf)) / n_regions;
 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
 
 /* A region must have at least 2 pages; one code, one guard */
@@ -853,9 +854,11 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 region.start = buf;
 region.start_aligned = aligned;
 /* page-align the end, since its last page will be a guard page */
-region.end = QEMU_ALIGN_PTR_DOWN(buf + size, page_size);
+end = QEMU_ALIGN_PTR_DOWN(buf + total_size, page_size);
 /* account for that last guard page */
-region.end -= page_size;
+end -= page_size;
+total_size = end - aligned;
+region.total_size = total_size;
 
 /* set guard pages */
 splitwx_diff = tcg_splitwx_diff;
@@ -893,7 +896,7 @@ void tcg_region_prologue_set(TCGContext *s)
 
 /* Register the balance of the buffer with gdb. */
 tcg_register_jit(tcg_splitwx_to_rx(region.start),
- region.end - region.start);
+ region.start_aligned + region.total_size - region.start);
 }
 
 /*
@@ -934,8 +937,10 @@ size_t tcg_code_capacity(void)
 
 /* no need for synchronization; these variables are set at init time */
 guard_size = region.stride - region.size;
-capacity = region.end + guard_size - region.start;
-capacity -= region.n * (guard_size + TCG_HIGHWATER);
+capacity = region.total_size;
+capacity -= (region.n - 1) * guard_size;
+capacity -= region.n * TCG_HIGHWATER;
+
 return capacity;
 }
 
-- 
2.25.1




[PATCH v2 19/29] tcg: Tidy split_cross_256mb

2021-03-14 Thread Richard Henderson
Return output buffer and size via output pointer arguments,
rather than returning size via tcg_ctx->code_gen_buffer_size.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 23b3459c61..45c1178815 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -467,7 +467,8 @@ static inline bool cross_256mb(void *addr, size_t size)
 /* We weren't able to allocate a buffer without crossing that boundary,
so make do with the larger portion of the buffer that doesn't cross.
Returns the new base of the buffer, and adjusts code_gen_buffer_size.  */
-static inline void *split_cross_256mb(void *buf1, size_t size1)
+static inline void split_cross_256mb(void **obuf, size_t *osize,
+ void *buf1, size_t size1)
 {
 void *buf2 = (void *)(((uintptr_t)buf1 + size1) & ~0x0ffful);
 size_t size2 = buf1 + size1 - buf2;
@@ -478,8 +479,8 @@ static inline void *split_cross_256mb(void *buf1, size_t 
size1)
 buf1 = buf2;
 }
 
-tcg_ctx->code_gen_buffer_size = size1;
-return buf1;
+*obuf = buf1;
+*osize = size1;
 }
 #endif
 
@@ -509,12 +510,10 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 if (size > tb_size) {
 size = QEMU_ALIGN_DOWN(tb_size, qemu_real_host_page_size);
 }
-tcg_ctx->code_gen_buffer_size = size;
 
 #ifdef __mips__
 if (cross_256mb(buf, size)) {
-buf = split_cross_256mb(buf, size);
-size = tcg_ctx->code_gen_buffer_size;
+split_cross_256mb(, , buf, size);
 }
 #endif
 
@@ -525,6 +524,7 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
 tcg_ctx->code_gen_buffer = buf;
+tcg_ctx->code_gen_buffer_size = size;
 return true;
 }
 #elif defined(_WIN32)
@@ -583,8 +583,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 /* fallthru */
 default:
 /* Split the original buffer.  Free the smaller half.  */
-buf2 = split_cross_256mb(buf, size);
-size2 = tcg_ctx->code_gen_buffer_size;
+split_cross_256mb(, , buf, size);
 if (buf == buf2) {
 munmap(buf + size2, size - size2);
 } else {
-- 
2.25.1




[PATCH v2 18/29] tcg: Tidy tcg_n_regions

2021-03-14 Thread Richard Henderson
Compute the value using straight division and bounds,
rather than a loop.  Pass in tb_size rather than reading
from tcg_init_ctx.code_gen_buffer_size,

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 29 -
 1 file changed, 12 insertions(+), 17 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 23261561a1..23b3459c61 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -363,38 +363,33 @@ void tcg_region_reset_all(void)
 tcg_region_tree_reset_all();
 }
 
-static size_t tcg_n_regions(unsigned max_cpus)
+static size_t tcg_n_regions(size_t tb_size, unsigned max_cpus)
 {
 #ifdef CONFIG_USER_ONLY
 return 1;
 #else
+size_t n_regions;
+
 /*
  * It is likely that some vCPUs will translate more code than others,
  * so we first try to set more regions than max_cpus, with those regions
  * being of reasonable size. If that's not possible we make do by evenly
  * dividing the code_gen_buffer among the vCPUs.
  */
-size_t i;
-
 /* Use a single region if all we have is one vCPU thread */
 if (max_cpus == 1 || !qemu_tcg_mttcg_enabled()) {
 return 1;
 }
 
-/* Try to have more regions than max_cpus, with each region being >= 2 MB 
*/
-for (i = 8; i > 0; i--) {
-size_t regions_per_thread = i;
-size_t region_size;
-
-region_size = tcg_init_ctx.code_gen_buffer_size;
-region_size /= max_cpus * regions_per_thread;
-
-if (region_size >= 2 * 1024u * 1024) {
-return max_cpus * regions_per_thread;
-}
+/*
+ * Try to have more regions than max_cpus, with each region being >= 2 MB.
+ * If we can't, then just allocate one region per vCPU thread.
+ */
+n_regions = tb_size / (2 * MiB);
+if (n_regions <= max_cpus) {
+return max_cpus;
 }
-/* If we can't, then just allocate one region per vCPU thread */
-return max_cpus;
+return MIN(n_regions, max_cpus * 8);
 #endif
 }
 
@@ -829,7 +824,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 buf = tcg_init_ctx.code_gen_buffer;
 total_size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions(max_cpus);
+n_regions = tcg_n_regions(total_size, max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-- 
2.25.1




[PATCH v2 13/29] accel/tcg: Pass down max_cpus to tcg_init

2021-03-14 Thread Richard Henderson
Start removing the include of hw/boards.h from tcg/.
Pass down the max_cpus value from tcg_init_machine,
where we have the MachineState already.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h   |  2 +-
 tcg/internal.h  |  2 +-
 accel/tcg/tcg-all.c | 10 +-
 tcg/region.c| 32 +++-
 tcg/tcg.c   | 10 --
 5 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 3ad77ec34d..a0122c0dd3 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -906,7 +906,7 @@ static inline void *tcg_malloc(int size)
 }
 }
 
-void tcg_init(size_t tb_size, int splitwx);
+void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus);
 void tcg_register_thread(void);
 void tcg_prologue_init(TCGContext *s);
 void tcg_func_start(TCGContext *s);
diff --git a/tcg/internal.h b/tcg/internal.h
index f13c564d9b..fcfeca232f 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -30,7 +30,7 @@
 extern TCGContext **tcg_ctxs;
 extern unsigned int n_tcg_ctxs;
 
-void tcg_region_init(size_t tb_size, int splitwx);
+void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus);
 bool tcg_region_alloc(TCGContext *s);
 void tcg_region_initial_alloc(TCGContext *s);
 void tcg_region_prologue_set(TCGContext *s);
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 0e83acbfe5..d2f2ddb844 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -32,6 +32,9 @@
 #include "qemu/error-report.h"
 #include "qemu/accel.h"
 #include "qapi/qapi-builtin-visit.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/boards.h"
+#endif
 #include "internal.h"
 
 struct TCGState {
@@ -109,13 +112,18 @@ bool mttcg_enabled;
 static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
+#ifdef CONFIG_USER_ONLY
+unsigned max_cpus = 1;
+#else
+unsigned max_cpus = ms->smp.max_cpus;
+#endif
 
 tcg_allowed = true;
 mttcg_enabled = s->mttcg_enabled;
 
 page_init();
 tb_htable_init();
-tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled, max_cpus);
 
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
diff --git a/tcg/region.c b/tcg/region.c
index 8d88144a22..04b699da63 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -27,9 +27,6 @@
 #include "qapi/error.h"
 #include "exec/exec-all.h"
 #include "tcg/tcg.h"
-#if !defined(CONFIG_USER_ONLY)
-#include "hw/boards.h"
-#endif
 #include "internal.h"
 
 
@@ -366,27 +363,20 @@ void tcg_region_reset_all(void)
 tcg_region_tree_reset_all();
 }
 
+static size_t tcg_n_regions(unsigned max_cpus)
+{
 #ifdef CONFIG_USER_ONLY
-static size_t tcg_n_regions(void)
-{
 return 1;
-}
 #else
-/*
- * It is likely that some vCPUs will translate more code than others, so we
- * first try to set more regions than max_cpus, with those regions being of
- * reasonable size. If that's not possible we make do by evenly dividing
- * the code_gen_buffer among the vCPUs.
- */
-static size_t tcg_n_regions(void)
-{
+/*
+ * It is likely that some vCPUs will translate more code than others,
+ * so we first try to set more regions than max_cpus, with those regions
+ * being of reasonable size. If that's not possible we make do by evenly
+ * dividing the code_gen_buffer among the vCPUs.
+ */
 size_t i;
 
 /* Use a single region if all we have is one vCPU thread */
-#if !defined(CONFIG_USER_ONLY)
-MachineState *ms = MACHINE(qdev_get_machine());
-unsigned int max_cpus = ms->smp.max_cpus;
-#endif
 if (max_cpus == 1 || !qemu_tcg_mttcg_enabled()) {
 return 1;
 }
@@ -405,8 +395,8 @@ static size_t tcg_n_regions(void)
 }
 /* If we can't, then just allocate one region per vCPU thread */
 return max_cpus;
-}
 #endif
+}
 
 /* Minimum size of the code gen buffer.  This number is randomly chosen,
but not so small that we can't have a fair number of TB's live.  */
@@ -838,7 +828,7 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
  * in practice. Multi-threaded guests share most if not all of their translated
  * code, which makes parallel code generation less appealing than in softmmu.
  */
-void tcg_region_init(size_t tb_size, int splitwx)
+void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
 void *buf, *aligned;
 size_t size;
@@ -856,7 +846,7 @@ void tcg_region_init(size_t tb_size, int splitwx)
 buf = tcg_init_ctx.code_gen_buffer;
 size = tcg_init_ctx.code_gen_buffer_size;
 page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions();
+n_regions = tcg_n_regions(max_cpus);
 
 /* The first region will be 'aligned - buf' bytes larger than the others */
 aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 65a63bda8a..a89d8f6b81 100644
--- 

[PATCH v2 11/29] tcg: Create tcg_init

2021-03-14 Thread Richard Henderson
Perform both tcg_context_init and tcg_region_init.
Do not leave this split to the caller.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h | 3 +--
 tcg/internal.h| 1 +
 accel/tcg/translate-all.c | 3 +--
 tcg/tcg.c | 9 -
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 7a435bf807..3ad77ec34d 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -874,7 +874,6 @@ void *tcg_malloc_internal(TCGContext *s, int size);
 void tcg_pool_reset(TCGContext *s);
 TranslationBlock *tcg_tb_alloc(TCGContext *s);
 
-void tcg_region_init(size_t tb_size, int splitwx);
 void tb_destroy(TranslationBlock *tb);
 void tcg_region_reset_all(void);
 
@@ -907,7 +906,7 @@ static inline void *tcg_malloc(int size)
 }
 }
 
-void tcg_context_init(TCGContext *s);
+void tcg_init(size_t tb_size, int splitwx);
 void tcg_register_thread(void);
 void tcg_prologue_init(TCGContext *s);
 void tcg_func_start(TCGContext *s);
diff --git a/tcg/internal.h b/tcg/internal.h
index b1dda343c2..f13c564d9b 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -30,6 +30,7 @@
 extern TCGContext **tcg_ctxs;
 extern unsigned int n_tcg_ctxs;
 
+void tcg_region_init(size_t tb_size, int splitwx);
 bool tcg_region_alloc(TCGContext *s);
 void tcg_region_initial_alloc(TCGContext *s);
 void tcg_region_prologue_set(TCGContext *s);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 4071edda16..050b4bff46 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -920,10 +920,9 @@ static void tb_htable_init(void)
 void tcg_exec_init(unsigned long tb_size, int splitwx)
 {
 tcg_allowed = true;
-tcg_context_init(_init_ctx);
 page_init();
 tb_htable_init();
-tcg_region_init(tb_size, splitwx);
+tcg_init(tb_size, splitwx);
 
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 10a571d41c..65a63bda8a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -576,8 +576,9 @@ static void process_op_defs(TCGContext *s);
 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
 TCGReg reg, const char *name);
 
-void tcg_context_init(TCGContext *s)
+static void tcg_context_init(void)
 {
+TCGContext *s = _init_ctx;
 int op, total_args, n, i;
 TCGOpDef *def;
 TCGArgConstraint *args_ct;
@@ -654,6 +655,12 @@ void tcg_context_init(TCGContext *s)
 cpu_env = temp_tcgv_ptr(ts);
 }
 
+void tcg_init(size_t tb_size, int splitwx)
+{
+tcg_context_init();
+tcg_region_init(tb_size, splitwx);
+}
+
 /*
  * Allocate TBs right before their corresponding translated code, making
  * sure that TBs and code are on different cache lines.
-- 
2.25.1




[PATCH v2 10/29] accel/tcg: Rename tcg_init to tcg_init_machine

2021-03-14 Thread Richard Henderson
We shortly want to use tcg_init for something else.
Since the hook is called init_machine, match that.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-all.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index f132033999..30d81ff7f5 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -105,7 +105,7 @@ static void tcg_accel_instance_init(Object *obj)
 
 bool mttcg_enabled;
 
-static int tcg_init(MachineState *ms)
+static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
 
@@ -189,7 +189,7 @@ static void tcg_accel_class_init(ObjectClass *oc, void 
*data)
 {
 AccelClass *ac = ACCEL_CLASS(oc);
 ac->name = "tcg";
-ac->init_machine = tcg_init;
+ac->init_machine = tcg_init_machine;
 ac->allowed = _allowed;
 
 object_class_property_add_str(oc, "thread",
-- 
2.25.1




[PATCH v2 09/29] accel/tcg: Move alloc_code_gen_buffer to tcg/region.c

2021-03-14 Thread Richard Henderson
Buffer management is integral to tcg.  Do not leave the allocation
to code outside of tcg/.  This is code movement, with further
cleanups to follow.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h |   2 +-
 accel/tcg/translate-all.c | 414 +
 tcg/region.c  | 421 +-
 3 files changed, 418 insertions(+), 419 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 0f0695e90d..7a435bf807 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -874,7 +874,7 @@ void *tcg_malloc_internal(TCGContext *s, int size);
 void tcg_pool_reset(TCGContext *s);
 TranslationBlock *tcg_tb_alloc(TCGContext *s);
 
-void tcg_region_init(void);
+void tcg_region_init(size_t tb_size, int splitwx);
 void tb_destroy(TranslationBlock *tb);
 void tcg_region_reset_all(void);
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 6d3184e7da..4071edda16 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -18,7 +18,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/units.h"
 #include "qemu-common.h"
 
 #define NO_CPU_IO_DEFS
@@ -51,7 +50,6 @@
 #include "exec/tb-hash.h"
 #include "exec/translate-all.h"
 #include "qemu/bitmap.h"
-#include "qemu/error-report.h"
 #include "qemu/qemu-print.h"
 #include "qemu/timer.h"
 #include "qemu/main-loop.h"
@@ -895,408 +893,6 @@ static void page_lock_pair(PageDesc **ret_p1, 
tb_page_addr_t phys1,
 }
 }
 
-/* Minimum size of the code gen buffer.  This number is randomly chosen,
-   but not so small that we can't have a fair number of TB's live.  */
-#define MIN_CODE_GEN_BUFFER_SIZE (1 * MiB)
-
-/* Maximum size of the code gen buffer we'd like to use.  Unless otherwise
-   indicated, this is constrained by the range of direct branches on the
-   host cpu, as used by the TCG implementation of goto_tb.  */
-#if defined(__x86_64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__sparc__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__powerpc64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__powerpc__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
-#elif defined(__aarch64__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
-#elif defined(__s390x__)
-  /* We have a +- 4GB range on the branches; leave some slop.  */
-# define MAX_CODE_GEN_BUFFER_SIZE  (3 * GiB)
-#elif defined(__mips__)
-  /* We have a 256MB branch region, but leave room to make sure the
- main executable is also within that region.  */
-# define MAX_CODE_GEN_BUFFER_SIZE  (128 * MiB)
-#else
-# define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
-#endif
-
-#if TCG_TARGET_REG_BITS == 32
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32 * MiB)
-#ifdef CONFIG_USER_ONLY
-/*
- * For user mode on smaller 32 bit systems we may run into trouble
- * allocating big chunks of data in the right place. On these systems
- * we utilise a static code generation buffer directly in the binary.
- */
-#define USE_STATIC_CODE_GEN_BUFFER
-#endif
-#else /* TCG_TARGET_REG_BITS == 64 */
-#ifdef CONFIG_USER_ONLY
-/*
- * As user-mode emulation typically means running multiple instances
- * of the translator don't go too nuts with our default code gen
- * buffer lest we make things too hard for the OS.
- */
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (128 * MiB)
-#else
-/*
- * We expect most system emulation to run one or two guests per host.
- * Users running large scale system emulation may want to tweak their
- * runtime setup via the tb-size control on the command line.
- */
-#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (1 * GiB)
-#endif
-#endif
-
-#define DEFAULT_CODE_GEN_BUFFER_SIZE \
-  (DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
-   ? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
-
-static size_t size_code_gen_buffer(size_t tb_size)
-{
-/* Size the buffer.  */
-if (tb_size == 0) {
-size_t phys_mem = qemu_get_host_physmem();
-if (phys_mem == 0) {
-tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
-} else {
-tb_size = MIN(DEFAULT_CODE_GEN_BUFFER_SIZE, phys_mem / 8);
-}
-}
-if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
-tb_size = MIN_CODE_GEN_BUFFER_SIZE;
-}
-if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
-tb_size = MAX_CODE_GEN_BUFFER_SIZE;
-}
-return tb_size;
-}
-
-#ifdef __mips__
-/* In order to use J and JAL within the code_gen_buffer, we require
-   that the buffer not cross a 256MB boundary.  */
-static inline bool cross_256mb(void *addr, size_t size)
-{
-return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & ~0x0ffful;
-}
-
-/* We weren't able to allocate a buffer without crossing that boundary,
-   so make do with the larger portion of the buffer that doesn't cross.
-   Returns the new base of the buffer, and adjusts code_gen_buffer_size.  */
-static inline void *split_cross_256mb(void *buf1, size_t size1)
-{
-void *buf2 = (void 

[PATCH v2 27/29] tcg: Merge buffer protection and guard page protection

2021-03-14 Thread Richard Henderson
Do not handle protections on a case-by-case basis in the
various alloc_code_gen_buffer instances; do it within a
single loop in tcg_region_init.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 40 +---
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 4dc1237ff4..fac416ebf5 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -530,11 +530,6 @@ static int alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 }
 #endif
 
-if (qemu_mprotect_rwx(buf, size)) {
-error_setg_errno(errp, errno, "mprotect of jit buffer");
-return false;
-}
-
 region.start_aligned = buf;
 region.total_size = size;
 
@@ -818,8 +813,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 {
 const size_t page_size = qemu_real_host_page_size;
 size_t region_size;
-size_t i;
-int have_prot;
+int have_prot, need_prot;
 
 /* Size the buffer.  */
 if (tb_size == 0) {
@@ -875,14 +869,38 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
 /* init the region struct */
 qemu_mutex_init();
 
-/* Set guard pages.  No need to do this for the rx_buf, only the rw_buf. */
-for (i = 0; i < region.n; i++) {
+/*
+ * Set guard pages.  No need to do this for the rx_buf, only the rw_buf.
+ * Work with the page protections set up with the initial mapping.
+ */
+need_prot = PAGE_READ | PAGE_WRITE;
+#ifndef CONFIG_TCG_INTERPRETER
+if (tcg_splitwx_diff == 0) {
+need_prot |= PAGE_EXEC;
+}
+#endif
+for (size_t i = 0, n = region.n; i < n; i++) {
 void *start, *end;
 int rc;
 
 tcg_region_bounds(i, , );
-rc = qemu_mprotect_none(end, page_size);
-g_assert(!rc);
+if (have_prot != need_prot) {
+if (need_prot == (PAGE_READ | PAGE_WRITE | PAGE_EXEC)) {
+rc = qemu_mprotect_rwx(start, end - start);
+} else if (need_prot == (PAGE_READ | PAGE_WRITE)) {
+rc = qemu_mprotect_rw(start, end - start);
+} else {
+g_assert_not_reached();
+}
+if (rc) {
+error_setg_errno(_fatal, errno,
+ "mprotect of jit buffer");
+}
+}
+if (have_prot != 0) {
+/* If guard-page permissions don't change, it isn't fatal. */
+(void)qemu_mprotect_none(end, page_size);
+}
 }
 
 tcg_region_trees_init();
-- 
2.25.1




[PATCH v2 07/29] tcg: Split out region.c

2021-03-14 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/internal.h  |  37 
 tcg/region.c| 570 
 tcg/tcg.c   | 545 +
 tcg/meson.build |   1 +
 4 files changed, 611 insertions(+), 542 deletions(-)
 create mode 100644 tcg/internal.h
 create mode 100644 tcg/region.c

diff --git a/tcg/internal.h b/tcg/internal.h
new file mode 100644
index 00..b1dda343c2
--- /dev/null
+++ b/tcg/internal.h
@@ -0,0 +1,37 @@
+/*
+ * Internal declarations for Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef TCG_INTERNAL_H
+#define TCG_INTERNAL_H 1
+
+#define TCG_HIGHWATER 1024
+
+extern TCGContext **tcg_ctxs;
+extern unsigned int n_tcg_ctxs;
+
+bool tcg_region_alloc(TCGContext *s);
+void tcg_region_initial_alloc(TCGContext *s);
+void tcg_region_prologue_set(TCGContext *s);
+
+#endif /* TCG_INTERNAL_H */
diff --git a/tcg/region.c b/tcg/region.c
new file mode 100644
index 00..af45a0174e
--- /dev/null
+++ b/tcg/region.c
@@ -0,0 +1,570 @@
+/*
+ * Memory region management for Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/exec-all.h"
+#include "tcg/tcg.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/boards.h"
+#endif
+#include "internal.h"
+
+
+struct tcg_region_tree {
+QemuMutex lock;
+GTree *tree;
+/* padding to avoid false sharing is computed at run-time */
+};
+
+/*
+ * We divide code_gen_buffer into equally-sized "regions" that TCG threads
+ * dynamically allocate from as demand dictates. Given appropriate region
+ * sizing, this minimizes flushes even when some TCG threads generate a lot
+ * more code than others.
+ */
+struct tcg_region_state {
+QemuMutex lock;
+
+/* fields set at init time */
+void *start;
+void *start_aligned;
+void *end;
+size_t n;
+size_t size; /* size of one region */
+size_t stride; /* .size + guard size */
+
+/* fields protected by the lock */
+size_t current; /* current region index */
+size_t agg_size_full; /* aggregate size of full regions */
+};
+
+static struct tcg_region_state region;
+
+/*
+ * This is an array of struct tcg_region_tree's, with padding.
+ * We use void * to simplify the computation of region_trees[i]; each
+ * struct is found every tree_size bytes.
+ */
+static void *region_trees;
+static size_t tree_size;
+
+/* compare a pointer @ptr and a tb_tc @s */
+static int ptr_cmp_tb_tc(const void *ptr, const struct tb_tc *s)
+{
+if (ptr >= s->ptr + s->size) {
+return 1;
+} else if (ptr < s->ptr) {
+return -1;
+}
+return 0;
+}
+
+static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp)
+{
+const struct tb_tc *a = ap;
+const struct 

[PATCH v2 21/29] tcg: Allocate code_gen_buffer into struct tcg_region_state

2021-03-14 Thread Richard Henderson
Do not mess around with setting values within tcg_init_ctx.
Put the values into 'region' directly, which is where they
will live for the lifetime of the program.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 64 ++--
 1 file changed, 27 insertions(+), 37 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index bf4167e467..9a2b014838 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -70,13 +70,12 @@ static size_t tree_size;
 
 bool in_code_gen_buffer(const void *p)
 {
-const TCGContext *s = _init_ctx;
 /*
  * Much like it is valid to have a pointer to the byte past the
  * end of an array (so long as you don't dereference it), allow
  * a pointer to the byte past the end of the code gen buffer.
  */
-return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
+return (size_t)(p - region.start_aligned) <= region.total_size;
 }
 
 #ifdef CONFIG_DEBUG_TCG
@@ -557,8 +556,8 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 }
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
-tcg_ctx->code_gen_buffer = buf;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 #elif defined(_WIN32)
@@ -579,8 +578,8 @@ static bool alloc_code_gen_buffer(size_t size, int splitwx, 
Error **errp)
 return false;
 }
 
-tcg_ctx->code_gen_buffer = buf;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 #else
@@ -595,7 +594,6 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
  "allocate %zu bytes for jit buffer", size);
 return false;
 }
-tcg_ctx->code_gen_buffer_size = size;
 
 #ifdef __mips__
 if (cross_256mb(buf, size)) {
@@ -633,7 +631,8 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 /* Request large pages for the buffer.  */
 qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
-tcg_ctx->code_gen_buffer = buf;
+region.start_aligned = buf;
+region.total_size = size;
 return true;
 }
 
@@ -654,8 +653,8 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 return false;
 }
 /* The size of the mapping may have been adjusted. */
-size = tcg_ctx->code_gen_buffer_size;
-buf_rx = tcg_ctx->code_gen_buffer;
+buf_rx = region.start_aligned;
+size = region.total_size;
 #endif
 
 buf_rw = qemu_memfd_alloc("tcg-jit", size, 0, , errp);
@@ -677,8 +676,8 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 #endif
 
 close(fd);
-tcg_ctx->code_gen_buffer = buf_rw;
-tcg_ctx->code_gen_buffer_size = size;
+region.start_aligned = buf_rw;
+region.total_size = size;
 tcg_splitwx_diff = buf_rx - buf_rw;
 
 /* Request large pages for the buffer and the splitwx.  */
@@ -729,7 +728,7 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 return false;
 }
 
-buf_rw = (mach_vm_address_t)tcg_ctx->code_gen_buffer;
+buf_rw = region.start_aligned;
 buf_rx = 0;
 ret = mach_vm_remap(mach_task_self(),
 _rx,
@@ -841,11 +840,8 @@ static bool alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
  */
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus)
 {
-void *buf, *aligned, *end;
-size_t total_size;
 size_t page_size;
 size_t region_size;
-size_t n_regions;
 size_t i;
 uintptr_t splitwx_diff;
 bool ok;
@@ -854,39 +850,33 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
splitwx, _fatal);
 assert(ok);
 
-buf = tcg_init_ctx.code_gen_buffer;
-total_size = tcg_init_ctx.code_gen_buffer_size;
-page_size = qemu_real_host_page_size;
-n_regions = tcg_n_regions(total_size, max_cpus);
-
-/* The first region will be 'aligned - buf' bytes larger than the others */
-aligned = QEMU_ALIGN_PTR_UP(buf, page_size);
-g_assert(aligned < tcg_init_ctx.code_gen_buffer + total_size);
-
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
  * the buffer; we will assign those to the last region.
  */
-region_size = (total_size - (aligned - buf)) / n_regions;
+region.n = tcg_n_regions(region.total_size, max_cpus);
+page_size = qemu_real_host_page_size;
+region_size = region.total_size / region.n;
 region_size = QEMU_ALIGN_DOWN(region_size, page_size);
 
 /* A region must have at least 2 pages; one code, one guard */
 g_assert(region_size >= 2 * page_size);
+region.stride = region_size;
+
+/* Reserve space for guard pages. */
+region.size = region_size - page_size;
+region.total_size -= page_size;
+
+

[PATCH v2 24/29] tcg: Do not set guard pages in the rx buffer

2021-03-14 Thread Richard Henderson
We only need guard pages in the rw buffer to avoid buffer overruns.
Let the rx buffer keep large pages all the way through.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 994c083343..27a7e35c8e 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -839,7 +839,6 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 size_t page_size;
 size_t region_size;
 size_t i;
-uintptr_t splitwx_diff;
 int have_prot;
 
 have_prot = alloc_code_gen_buffer(size_code_gen_buffer(tb_size),
@@ -881,8 +880,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 /* init the region struct */
 qemu_mutex_init();
 
-/* set guard pages */
-splitwx_diff = tcg_splitwx_diff;
+/* Set guard pages.  No need to do this for the rx_buf, only the rw_buf. */
 for (i = 0; i < region.n; i++) {
 void *start, *end;
 int rc;
@@ -890,10 +888,6 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 tcg_region_bounds(i, , );
 rc = qemu_mprotect_none(end, page_size);
 g_assert(!rc);
-if (splitwx_diff) {
-rc = qemu_mprotect_none(end + splitwx_diff, page_size);
-g_assert(!rc);
-}
 }
 
 tcg_region_trees_init();
-- 
2.25.1




[PATCH v2 05/29] tcg: Split out tcg_region_initial_alloc

2021-03-14 Thread Richard Henderson
This has only one user, and currently needs an ifdef,
but will make more sense after some code motion.

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2b631fccdf..3316a22bde 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -726,6 +726,15 @@ static void tcg_region_initial_alloc__locked(TCGContext *s)
 g_assert(!err);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void tcg_region_initial_alloc(TCGContext *s)
+{
+qemu_mutex_lock();
+tcg_region_initial_alloc__locked(s);
+qemu_mutex_unlock();
+}
+#endif
+
 /* Call from a safe-work context */
 void tcg_region_reset_all(void)
 {
@@ -957,9 +966,7 @@ void tcg_register_thread(void)
 }
 
 tcg_ctx = s;
-qemu_mutex_lock();
-tcg_region_initial_alloc__locked(s);
-qemu_mutex_unlock();
+tcg_region_initial_alloc(s);
 }
 #endif /* !CONFIG_USER_ONLY */
 
-- 
2.25.1




[PATCH v2 23/29] tcg: Sink qemu_madvise call to common code

2021-03-14 Thread Richard Henderson
Move the call out of the N versions of alloc_code_gen_buffer
and into tcg_region_init.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 3ca0d01fa4..994c083343 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -554,7 +554,6 @@ static int alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 error_setg_errno(errp, errno, "mprotect of jit buffer");
 return false;
 }
-qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
 
 region.start_aligned = buf;
 region.total_size = size;
@@ -630,9 +629,6 @@ static int alloc_code_gen_buffer_anon(size_t size, int prot,
 }
 #endif
 
-/* Request large pages for the buffer.  */
-qemu_madvise(buf, size, QEMU_MADV_HUGEPAGE);
-
 region.start_aligned = buf;
 region.total_size = size;
 return prot;
@@ -682,9 +678,6 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 region.total_size = size;
 tcg_splitwx_diff = buf_rx - buf_rw;
 
-/* Request large pages for the buffer and the splitwx.  */
-qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
-qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
 return PROT_READ | PROT_WRITE;
 
  fail_rx:
@@ -853,6 +846,13 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
   splitwx, _fatal);
 assert(have_prot >= 0);
 
+/* Request large pages for the buffer and the splitwx.  */
+qemu_madvise(region.start_aligned, region.total_size, QEMU_MADV_HUGEPAGE);
+if (tcg_splitwx_diff) {
+qemu_madvise(region.start_aligned + tcg_splitwx_diff,
+ region.total_size, QEMU_MADV_HUGEPAGE);
+}
+
 /*
  * Make region_size a multiple of page_size, using aligned as the start.
  * As a result of this we might end up with a few extra pages at the end of
-- 
2.25.1




[PATCH v2 22/29] tcg: Return the map protection from alloc_code_gen_buffer

2021-03-14 Thread Richard Henderson
Change the interface from a boolean error indication to a
negative error vs a non-negative protection.  For the moment
this is only interface change, not making use of the new data.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 63 +++-
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 9a2b014838..3ca0d01fa4 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -521,14 +521,14 @@ static inline void split_cross_256mb(void **obuf, size_t 
*osize,
 static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
 __attribute__((aligned(CODE_GEN_ALIGN)));
 
-static bool alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
+static int alloc_code_gen_buffer(size_t tb_size, int splitwx, Error **errp)
 {
 void *buf, *end;
 size_t size;
 
 if (splitwx > 0) {
 error_setg(errp, "jit split-wx not supported");
-return false;
+return -1;
 }
 
 /* page-align the beginning and end of the buffer */
@@ -558,16 +558,17 @@ static bool alloc_code_gen_buffer(size_t tb_size, int 
splitwx, Error **errp)
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+
+return PROT_READ | PROT_WRITE;
 }
 #elif defined(_WIN32)
-static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
+static int alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
 {
 void *buf;
 
 if (splitwx > 0) {
 error_setg(errp, "jit split-wx not supported");
-return false;
+return -1;
 }
 
 buf = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
@@ -580,11 +581,12 @@ static bool alloc_code_gen_buffer(size_t size, int 
splitwx, Error **errp)
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+
+return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 }
 #else
-static bool alloc_code_gen_buffer_anon(size_t size, int prot,
-   int flags, Error **errp)
+static int alloc_code_gen_buffer_anon(size_t size, int prot,
+  int flags, Error **errp)
 {
 void *buf;
 
@@ -592,7 +594,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 if (buf == MAP_FAILED) {
 error_setg_errno(errp, errno,
  "allocate %zu bytes for jit buffer", size);
-return false;
+return -1;
 }
 
 #ifdef __mips__
@@ -633,7 +635,7 @@ static bool alloc_code_gen_buffer_anon(size_t size, int 
prot,
 
 region.start_aligned = buf;
 region.total_size = size;
-return true;
+return prot;
 }
 
 #ifndef CONFIG_TCG_INTERPRETER
@@ -647,9 +649,9 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 
 #ifdef __mips__
 /* Find space for the RX mapping, vs the 256MiB regions. */
-if (!alloc_code_gen_buffer_anon(size, PROT_NONE,
-MAP_PRIVATE | MAP_ANONYMOUS |
-MAP_NORESERVE, errp)) {
+if (alloc_code_gen_buffer_anon(size, PROT_NONE,
+   MAP_PRIVATE | MAP_ANONYMOUS |
+   MAP_NORESERVE, errp) < 0) {
 return false;
 }
 /* The size of the mapping may have been adjusted. */
@@ -683,7 +685,7 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 /* Request large pages for the buffer and the splitwx.  */
 qemu_madvise(buf_rw, size, QEMU_MADV_HUGEPAGE);
 qemu_madvise(buf_rx, size, QEMU_MADV_HUGEPAGE);
-return true;
+return PROT_READ | PROT_WRITE;
 
  fail_rx:
 error_setg_errno(errp, errno, "failed to map shared memory for execute");
@@ -697,7 +699,7 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t 
size, Error **errp)
 if (fd >= 0) {
 close(fd);
 }
-return false;
+return -1;
 }
 #endif /* CONFIG_POSIX */
 
@@ -716,7 +718,7 @@ extern kern_return_t mach_vm_remap(vm_map_t target_task,
vm_prot_t *max_protection,
vm_inherit_t inheritance);
 
-static bool alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
+static int alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
 {
 kern_return_t ret;
 mach_vm_address_t buf_rw, buf_rx;
@@ -725,7 +727,7 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 /* Map the read-write portion via normal anon memory. */
 if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
 MAP_PRIVATE | MAP_ANONYMOUS, errp)) {
-return false;
+return -1;
 }
 
 buf_rw = region.start_aligned;
@@ -745,23 +747,23 @@ static bool alloc_code_gen_buffer_splitwx_vmremap(size_t 
size, Error **errp)
 /* TODO: Convert "ret" to a human readable error message. */
 error_setg(errp, "vm_remap for jit splitwx 

[PATCH v2 20/29] tcg: Move in_code_gen_buffer and tests to region.c

2021-03-14 Thread Richard Henderson
Shortly, the full code_gen_buffer will only be visible
to region.c, so move in_code_gen_buffer out-of-line.

Move the debugging versions of tcg_splitwx_to_{rx,rw}
to region.c as well, so that the compiler gets to see
the implementation of in_code_gen_buffer.

This leaves exactly one use of in_code_gen_buffer outside
of region.c, in cpu_restore_state.  Which, being on the
exception path, is not performance critical.

Signed-off-by: Richard Henderson 
---
 include/tcg/tcg.h | 11 +--
 tcg/region.c  | 34 ++
 tcg/tcg.c | 23 ---
 3 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index a0122c0dd3..a19deb529f 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -696,16 +696,7 @@ extern const void *tcg_code_gen_epilogue;
 extern uintptr_t tcg_splitwx_diff;
 extern TCGv_env cpu_env;
 
-static inline bool in_code_gen_buffer(const void *p)
-{
-const TCGContext *s = _init_ctx;
-/*
- * Much like it is valid to have a pointer to the byte past the
- * end of an array (so long as you don't dereference it), allow
- * a pointer to the byte past the end of the code gen buffer.
- */
-return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
-}
+bool in_code_gen_buffer(const void *p);
 
 #ifdef CONFIG_DEBUG_TCG
 const void *tcg_splitwx_to_rx(void *rw);
diff --git a/tcg/region.c b/tcg/region.c
index 45c1178815..bf4167e467 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -68,6 +68,40 @@ static struct tcg_region_state region;
 static void *region_trees;
 static size_t tree_size;
 
+bool in_code_gen_buffer(const void *p)
+{
+const TCGContext *s = _init_ctx;
+/*
+ * Much like it is valid to have a pointer to the byte past the
+ * end of an array (so long as you don't dereference it), allow
+ * a pointer to the byte past the end of the code gen buffer.
+ */
+return (size_t)(p - s->code_gen_buffer) <= s->code_gen_buffer_size;
+}
+
+#ifdef CONFIG_DEBUG_TCG
+const void *tcg_splitwx_to_rx(void *rw)
+{
+/* Pass NULL pointers unchanged. */
+if (rw) {
+g_assert(in_code_gen_buffer(rw));
+rw += tcg_splitwx_diff;
+}
+return rw;
+}
+
+void *tcg_splitwx_to_rw(const void *rx)
+{
+/* Pass NULL pointers unchanged. */
+if (rx) {
+rx -= tcg_splitwx_diff;
+/* Assert that we end with a pointer in the rw region. */
+g_assert(in_code_gen_buffer(rx));
+}
+return (void *)rx;
+}
+#endif /* CONFIG_DEBUG_TCG */
+
 /* compare a pointer @ptr and a tb_tc @s */
 static int ptr_cmp_tb_tc(const void *ptr, const struct tb_tc *s)
 {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a82d3a0861..65f9cf01d5 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -416,29 +416,6 @@ static const TCGTargetOpDef constraint_sets[] = {
 
 #include "tcg-target.c.inc"
 
-#ifdef CONFIG_DEBUG_TCG
-const void *tcg_splitwx_to_rx(void *rw)
-{
-/* Pass NULL pointers unchanged. */
-if (rw) {
-g_assert(in_code_gen_buffer(rw));
-rw += tcg_splitwx_diff;
-}
-return rw;
-}
-
-void *tcg_splitwx_to_rw(const void *rx)
-{
-/* Pass NULL pointers unchanged. */
-if (rx) {
-rx -= tcg_splitwx_diff;
-/* Assert that we end with a pointer in the rw region. */
-g_assert(in_code_gen_buffer(rx));
-}
-return (void *)rx;
-}
-#endif /* CONFIG_DEBUG_TCG */
-
 static void alloc_tcg_plugin_context(TCGContext *s)
 {
 #ifdef CONFIG_PLUGIN
-- 
2.25.1




[PATCH v2 15/29] tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h

2021-03-14 Thread Richard Henderson
Remove the ifdef ladder and move each define into the
appropriate header file.

Signed-off-by: Richard Henderson 
---
v2: Retain comment about M_C_G_B_S constraint (balaton)
---
 tcg/aarch64/tcg-target.h |  1 +
 tcg/arm/tcg-target.h |  1 +
 tcg/i386/tcg-target.h|  2 ++
 tcg/mips/tcg-target.h|  6 ++
 tcg/ppc/tcg-target.h |  2 ++
 tcg/riscv/tcg-target.h   |  1 +
 tcg/s390/tcg-target.h|  3 +++
 tcg/sparc/tcg-target.h   |  1 +
 tcg/tci/tcg-target.h |  1 +
 tcg/region.c | 35 +--
 10 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 5ec30dba25..ef55f7c185 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -15,6 +15,7 @@
 
 #define TCG_TARGET_INSN_UNIT_SIZE  4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 24
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #undef TCG_TARGET_STACK_GROWSUP
 
 typedef enum {
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 8d1fee6327..b9a85d0f83 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -60,6 +60,7 @@ extern int arm_arch;
 #undef TCG_TARGET_STACK_GROWSUP
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
+#define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX
 
 typedef enum {
 TCG_REG_R0 = 0,
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b693d3692d..ac10066c3e 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -31,9 +31,11 @@
 #ifdef __x86_64__
 # define TCG_TARGET_REG_BITS  64
 # define TCG_TARGET_NB_REGS   32
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #else
 # define TCG_TARGET_REG_BITS  32
 # define TCG_TARGET_NB_REGS   24
+# define MAX_CODE_GEN_BUFFER_SIZE  UINT32_MAX
 #endif
 
 typedef enum {
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index c2c32fb38f..e81e824cab 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -39,6 +39,12 @@
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 16
 #define TCG_TARGET_NB_REGS 32
 
+/*
+ * We have a 256MB branch region, but leave room to make sure the
+ * main executable is also within that region.
+ */
+#define MAX_CODE_GEN_BUFFER_SIZE  (128 * MiB)
+
 typedef enum {
 TCG_REG_ZERO = 0,
 TCG_REG_AT,
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index d1339afc66..c13ed5640a 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -27,8 +27,10 @@
 
 #ifdef _ARCH_PPC64
 # define TCG_TARGET_REG_BITS  64
+# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 #else
 # define TCG_TARGET_REG_BITS  32
+# define MAX_CODE_GEN_BUFFER_SIZE  (32 * MiB)
 #endif
 
 #define TCG_TARGET_NB_REGS 64
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 727c8df418..87ea94666b 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -34,6 +34,7 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 20
 #define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 typedef enum {
 TCG_REG_ZERO,
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 641464eea4..b04b72b7eb 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -28,6 +28,9 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 2
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 19
 
+/* We have a +- 4GB range on the branches; leave some slop.  */
+#define MAX_CODE_GEN_BUFFER_SIZE  (3 * GiB)
+
 typedef enum TCGReg {
 TCG_REG_R0 = 0,
 TCG_REG_R1,
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index f66f5d07dc..86bb9a2d39 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -30,6 +30,7 @@
 #define TCG_TARGET_INSN_UNIT_SIZE 4
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
 #define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
 
 typedef enum {
 TCG_REG_G0 = 0,
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 9c0021a26f..03cf527cb4 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -43,6 +43,7 @@
 #define TCG_TARGET_INTERPRETER 1
 #define TCG_TARGET_INSN_UNIT_SIZE 1
 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 #if UINTPTR_MAX == UINT32_MAX
 # define TCG_TARGET_REG_BITS 32
diff --git a/tcg/region.c b/tcg/region.c
index e3fbf6a7e7..ae22308290 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -398,34 +398,17 @@ static size_t tcg_n_regions(unsigned max_cpus)
 #endif
 }
 
-/* Minimum size of the code gen buffer.  This number is randomly chosen,
-   but not so small that we can't have a fair number of TB's live.  */
+/*
+ * Minimum size of the code gen buffer.  This number is randomly chosen,
+ * but not so small that we can't have a fair number of TB's live.
+ *
+ * Maximum size, MAX_CODE_GEN_BUFFER_SIZE, is defined in tcg-target.h.
+ * Unless otherwise indicated, this is constrained by the range of
+ * direct branches on the host cpu, as used by the TCG implementation
+ * of goto_tb.
+ */
 #define MIN_CODE_GEN_BUFFER_SIZE 

[PATCH v2 17/29] tcg: Rename region.start to region.after_prologue

2021-03-14 Thread Richard Henderson
Give the field a name reflecting its actual meaning.

Signed-off-by: Richard Henderson 
---
 tcg/region.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 8e4dd0480b..23261561a1 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -46,8 +46,8 @@ struct tcg_region_state {
 QemuMutex lock;
 
 /* fields set at init time */
-void *start;
 void *start_aligned;
+void *after_prologue;
 size_t total_size; /* size of entire buffer */
 size_t n;
 size_t size; /* size of one region */
@@ -276,7 +276,7 @@ static void tcg_region_bounds(size_t curr_region, void 
**pstart, void **pend)
 end = start + region.size;
 
 if (curr_region == 0) {
-start = region.start;
+start = region.after_prologue;
 }
 if (curr_region == region.n - 1) {
 end = region.start_aligned + region.total_size;
@@ -851,7 +851,7 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned 
max_cpus)
 region.n = n_regions;
 region.size = region_size - page_size;
 region.stride = region_size;
-region.start = buf;
+region.after_prologue = buf;
 region.start_aligned = aligned;
 /* page-align the end, since its last page will be a guard page */
 end = QEMU_ALIGN_PTR_DOWN(buf + total_size, page_size);
@@ -888,15 +888,16 @@ void tcg_region_init(size_t tb_size, int splitwx, 
unsigned max_cpus)
 void tcg_region_prologue_set(TCGContext *s)
 {
 /* Deduct the prologue from the first region.  */
-g_assert(region.start == s->code_gen_buffer);
-region.start = s->code_ptr;
+g_assert(region.start_aligned == s->code_gen_buffer);
+region.after_prologue = s->code_ptr;
 
 /* Recompute boundaries of the first region. */
 tcg_region_assign(s, 0);
 
 /* Register the balance of the buffer with gdb. */
-tcg_register_jit(tcg_splitwx_to_rx(region.start),
- region.start_aligned + region.total_size - region.start);
+tcg_register_jit(tcg_splitwx_to_rx(region.after_prologue),
+ region.start_aligned + region.total_size -
+ region.after_prologue);
 }
 
 /*
-- 
2.25.1




[PATCH v2 02/29] meson: Split out fpu/meson.build

2021-03-14 Thread Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 meson.build | 4 +---
 fpu/meson.build | 1 +
 2 files changed, 2 insertions(+), 3 deletions(-)
 create mode 100644 fpu/meson.build

diff --git a/meson.build b/meson.build
index 742f45c8d8..bfa24b836e 100644
--- a/meson.build
+++ b/meson.build
@@ -1934,9 +1934,6 @@ subdir('softmmu')
 common_ss.add(capstone)
 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
 specific_ss.add(files('exec-vary.c'))
-specific_ss.add(when: 'CONFIG_TCG', if_true: files(
-  'fpu/softfloat.c',
-))
 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c'))
 
 subdir('backends')
@@ -1948,6 +1945,7 @@ subdir('replay')
 subdir('semihosting')
 subdir('hw')
 subdir('tcg')
+subdir('fpu')
 subdir('accel')
 subdir('plugins')
 subdir('bsd-user')
diff --git a/fpu/meson.build b/fpu/meson.build
new file mode 100644
index 00..1a9992ded5
--- /dev/null
+++ b/fpu/meson.build
@@ -0,0 +1 @@
+specific_ss.add(when: 'CONFIG_TCG', if_true: files('softfloat.c'))
-- 
2.25.1




[PATCH v2 12/29] accel/tcg: Merge tcg_exec_init into tcg_init_machine

2021-03-14 Thread Richard Henderson
There is only one caller, and shortly we will need access
to the MachineState, which tcg_init_machine already has.

Signed-off-by: Richard Henderson 
---
 accel/tcg/internal.h  |  2 ++
 include/sysemu/tcg.h  |  2 --
 accel/tcg/tcg-all.c   | 14 +-
 accel/tcg/translate-all.c | 21 ++---
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h
index e9c145e0fb..881bc1ede0 100644
--- a/accel/tcg/internal.h
+++ b/accel/tcg/internal.h
@@ -16,5 +16,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc,
   int cflags);
 
 void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
+void page_init(void);
+void tb_htable_init(void);
 
 #endif /* ACCEL_TCG_INTERNAL_H */
diff --git a/include/sysemu/tcg.h b/include/sysemu/tcg.h
index 00349fb18a..53352450ff 100644
--- a/include/sysemu/tcg.h
+++ b/include/sysemu/tcg.h
@@ -8,8 +8,6 @@
 #ifndef SYSEMU_TCG_H
 #define SYSEMU_TCG_H
 
-void tcg_exec_init(unsigned long tb_size, int splitwx);
-
 #ifdef CONFIG_TCG
 extern bool tcg_allowed;
 #define tcg_enabled() (tcg_allowed)
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 30d81ff7f5..0e83acbfe5 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -32,6 +32,7 @@
 #include "qemu/error-report.h"
 #include "qemu/accel.h"
 #include "qapi/qapi-builtin-visit.h"
+#include "internal.h"
 
 struct TCGState {
 AccelState parent_obj;
@@ -109,8 +110,19 @@ static int tcg_init_machine(MachineState *ms)
 {
 TCGState *s = TCG_STATE(current_accel());
 
-tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+tcg_allowed = true;
 mttcg_enabled = s->mttcg_enabled;
+
+page_init();
+tb_htable_init();
+tcg_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
+
+#if defined(CONFIG_SOFTMMU)
+/* There's no guest base to take into account, so go ahead and
+   initialize the prologue now.  */
+tcg_prologue_init(tcg_ctx);
+#endif
+
 return 0;
 }
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 050b4bff46..40aeecf611 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -408,7 +408,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, 
bool will_exit)
 return false;
 }
 
-static void page_init(void)
+void page_init(void)
 {
 page_size_init();
 page_table_config_init();
@@ -907,30 +907,13 @@ static bool tb_cmp(const void *ap, const void *bp)
 a->page_addr[1] == b->page_addr[1];
 }
 
-static void tb_htable_init(void)
+void tb_htable_init(void)
 {
 unsigned int mode = QHT_MODE_AUTO_RESIZE;
 
 qht_init(_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode);
 }
 
-/* Must be called before using the QEMU cpus. 'tb_size' is the size
-   (in bytes) allocated to the translation buffer. Zero means default
-   size. */
-void tcg_exec_init(unsigned long tb_size, int splitwx)
-{
-tcg_allowed = true;
-page_init();
-tb_htable_init();
-tcg_init(tb_size, splitwx);
-
-#if defined(CONFIG_SOFTMMU)
-/* There's no guest base to take into account, so go ahead and
-   initialize the prologue now.  */
-tcg_prologue_init(tcg_ctx);
-#endif
-}
-
 /* call with @p->lock held */
 static inline void invalidate_page_bitmap(PageDesc *p)
 {
-- 
2.25.1




[PATCH v2 08/29] accel/tcg: Inline cpu_gen_init

2021-03-14 Thread Richard Henderson
It consists of one function call and has only one caller.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 accel/tcg/translate-all.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index b9057567f4..6d3184e7da 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -245,11 +245,6 @@ static void page_table_config_init(void)
 assert(v_l2_levels >= 0);
 }
 
-static void cpu_gen_init(void)
-{
-tcg_context_init(_init_ctx);
-}
-
 /* Encode VAL as a signed leb128 sequence at P.
Return P incremented past the encoded value.  */
 static uint8_t *encode_sleb128(uint8_t *p, target_long val)
@@ -1331,7 +1326,7 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
 bool ok;
 
 tcg_allowed = true;
-cpu_gen_init();
+tcg_context_init(_init_ctx);
 page_init();
 tb_htable_init();
 
-- 
2.25.1




[PATCH v2 14/29] tcg: Introduce tcg_max_ctxs

2021-03-14 Thread Richard Henderson
Finish the divorce of tcg/ from hw/, and do not take
the max cpu value from MachineState; just remember what
we were passed in tcg_init.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/internal.h |  3 ++-
 tcg/region.c   |  6 +++---
 tcg/tcg.c  | 23 ++-
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/tcg/internal.h b/tcg/internal.h
index fcfeca232f..f9906523da 100644
--- a/tcg/internal.h
+++ b/tcg/internal.h
@@ -28,7 +28,8 @@
 #define TCG_HIGHWATER 1024
 
 extern TCGContext **tcg_ctxs;
-extern unsigned int n_tcg_ctxs;
+extern unsigned int tcg_cur_ctxs;
+extern unsigned int tcg_max_ctxs;
 
 void tcg_region_init(size_t tb_size, int splitwx, unsigned max_cpus);
 bool tcg_region_alloc(TCGContext *s);
diff --git a/tcg/region.c b/tcg/region.c
index 04b699da63..e3fbf6a7e7 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -347,7 +347,7 @@ void tcg_region_initial_alloc(TCGContext *s)
 /* Call from a safe-work context */
 void tcg_region_reset_all(void)
 {
-unsigned int n_ctxs = qatomic_read(_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(_cur_ctxs);
 unsigned int i;
 
 qemu_mutex_lock();
@@ -922,7 +922,7 @@ void tcg_region_prologue_set(TCGContext *s)
  */
 size_t tcg_code_size(void)
 {
-unsigned int n_ctxs = qatomic_read(_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(_cur_ctxs);
 unsigned int i;
 size_t total;
 
@@ -958,7 +958,7 @@ size_t tcg_code_capacity(void)
 
 size_t tcg_tb_phys_invalidate_count(void)
 {
-unsigned int n_ctxs = qatomic_read(_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(_cur_ctxs);
 unsigned int i;
 size_t total = 0;
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index a89d8f6b81..a82d3a0861 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -44,11 +44,6 @@
 #include "cpu.h"
 
 #include "exec/exec-all.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#include "hw/boards.h"
-#endif
-
 #include "tcg/tcg-op.h"
 
 #if UINTPTR_MAX == UINT32_MAX
@@ -155,7 +150,8 @@ static int tcg_out_ldst_finalize(TCGContext *s);
 #endif
 
 TCGContext **tcg_ctxs;
-unsigned int n_tcg_ctxs;
+unsigned int tcg_cur_ctxs;
+unsigned int tcg_max_ctxs;
 TCGv_env cpu_env = 0;
 const void *tcg_code_gen_epilogue;
 uintptr_t tcg_splitwx_diff;
@@ -475,7 +471,6 @@ void tcg_register_thread(void)
 #else
 void tcg_register_thread(void)
 {
-MachineState *ms = MACHINE(qdev_get_machine());
 TCGContext *s = g_malloc(sizeof(*s));
 unsigned int i, n;
 
@@ -491,8 +486,8 @@ void tcg_register_thread(void)
 }
 
 /* Claim an entry in tcg_ctxs */
-n = qatomic_fetch_inc(_tcg_ctxs);
-g_assert(n < ms->smp.max_cpus);
+n = qatomic_fetch_inc(_cur_ctxs);
+g_assert(n < tcg_max_ctxs);
 qatomic_set(_ctxs[n], s);
 
 if (n > 0) {
@@ -643,9 +638,11 @@ static void tcg_context_init(unsigned max_cpus)
  */
 #ifdef CONFIG_USER_ONLY
 tcg_ctxs = _ctx;
-n_tcg_ctxs = 1;
+tcg_cur_ctxs = 1;
+tcg_max_ctxs = 1;
 #else
-tcg_ctxs = g_new(TCGContext *, max_cpus);
+tcg_max_ctxs = max_cpus;
+tcg_ctxs = g_new0(TCGContext *, max_cpus);
 #endif
 
 tcg_debug_assert(!tcg_regset_test_reg(s->reserved_regs, TCG_AREG0));
@@ -3937,7 +3934,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 static inline
 void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
 {
-unsigned int n_ctxs = qatomic_read(_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(_cur_ctxs);
 unsigned int i;
 
 for (i = 0; i < n_ctxs; i++) {
@@ -4000,7 +3997,7 @@ void tcg_dump_op_count(void)
 
 int64_t tcg_cpu_exec_time(void)
 {
-unsigned int n_ctxs = qatomic_read(_tcg_ctxs);
+unsigned int n_ctxs = qatomic_read(_cur_ctxs);
 unsigned int i;
 int64_t ret = 0;
 
-- 
2.25.1




[PATCH v2 01/29] meson: Split out tcg/meson.build

2021-03-14 Thread Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 meson.build |  9 ++---
 tcg/meson.build | 13 +
 2 files changed, 15 insertions(+), 7 deletions(-)
 create mode 100644 tcg/meson.build

diff --git a/meson.build b/meson.build
index a7d2dd429d..742f45c8d8 100644
--- a/meson.build
+++ b/meson.build
@@ -1936,14 +1936,8 @@ specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), 
capstone)
 specific_ss.add(files('exec-vary.c'))
 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
   'fpu/softfloat.c',
-  'tcg/optimize.c',
-  'tcg/tcg-common.c',
-  'tcg/tcg-op-gvec.c',
-  'tcg/tcg-op-vec.c',
-  'tcg/tcg-op.c',
-  'tcg/tcg.c',
 ))
-specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 
'tcg/tci.c'))
+specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c'))
 
 subdir('backends')
 subdir('disas')
@@ -1953,6 +1947,7 @@ subdir('net')
 subdir('replay')
 subdir('semihosting')
 subdir('hw')
+subdir('tcg')
 subdir('accel')
 subdir('plugins')
 subdir('bsd-user')
diff --git a/tcg/meson.build b/tcg/meson.build
new file mode 100644
index 00..84064a341e
--- /dev/null
+++ b/tcg/meson.build
@@ -0,0 +1,13 @@
+tcg_ss = ss.source_set()
+
+tcg_ss.add(files(
+  'optimize.c',
+  'tcg.c',
+  'tcg-common.c',
+  'tcg-op.c',
+  'tcg-op-gvec.c',
+  'tcg-op-vec.c',
+))
+tcg_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
+
+specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
-- 
2.25.1




[PATCH v2 06/29] tcg: Split out tcg_region_prologue_set

2021-03-14 Thread Richard Henderson
This has only one user, but will make more sense after some
code motion.

Always leave the tcg_init_ctx initialized to the first region,
in preparation for tcg_prologue_init().  This also requires
that we don't re-allocate the region for the first cpu, lest
we hit the assertion for total number of regions allocated .

Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 3316a22bde..5b3525d52a 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -880,10 +880,26 @@ void tcg_region_init(void)
 
 tcg_region_trees_init();
 
-/* In user-mode we support only one ctx, so do the initial allocation now 
*/
-#ifdef CONFIG_USER_ONLY
-tcg_region_initial_alloc__locked(tcg_ctx);
-#endif
+/*
+ * Leave the initial context initialized to the first region.
+ * This will be the context into which we generate the prologue.
+ * It is also the only context for CONFIG_USER_ONLY.
+ */
+tcg_region_initial_alloc__locked(_init_ctx);
+}
+
+static void tcg_region_prologue_set(TCGContext *s)
+{
+/* Deduct the prologue from the first region.  */
+g_assert(region.start == s->code_gen_buffer);
+region.start = s->code_ptr;
+
+/* Recompute boundaries of the first region. */
+tcg_region_assign(s, 0);
+
+/* Register the balance of the buffer with gdb. */
+tcg_register_jit(tcg_splitwx_to_rx(region.start),
+ region.end - region.start);
 }
 
 #ifdef CONFIG_DEBUG_TCG
@@ -963,10 +979,10 @@ void tcg_register_thread(void)
 
 if (n > 0) {
 alloc_tcg_plugin_context(s);
+tcg_region_initial_alloc(s);
 }
 
 tcg_ctx = s;
-tcg_region_initial_alloc(s);
 }
 #endif /* !CONFIG_USER_ONLY */
 
@@ -1206,8 +1222,6 @@ void tcg_prologue_init(TCGContext *s)
 {
 size_t prologue_size;
 
-/* Put the prologue at the beginning of code_gen_buffer.  */
-tcg_region_assign(s, 0);
 s->code_ptr = s->code_gen_ptr;
 s->code_buf = s->code_gen_ptr;
 s->data_gen_ptr = NULL;
@@ -1239,14 +1253,7 @@ void tcg_prologue_init(TCGContext *s)
 (uintptr_t)s->code_buf, prologue_size);
 #endif
 
-/* Deduct the prologue from the first region.  */
-region.start = s->code_ptr;
-
-/* Recompute boundaries of the first region. */
-tcg_region_assign(s, 0);
-
-tcg_register_jit(tcg_splitwx_to_rx(region.start),
- region.end - region.start);
+tcg_region_prologue_set(s);
 
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
-- 
2.25.1




[PATCH v2 03/29] tcg: Re-order tcg_region_init vs tcg_prologue_init

2021-03-14 Thread Richard Henderson
Instead of delaying tcg_region_init until after tcg_prologue_init
is complete, do tcg_region_init first and let tcg_prologue_init
shrink the first region by the size of the generated prologue.

Signed-off-by: Richard Henderson 
---
 accel/tcg/tcg-all.c   | 11 -
 accel/tcg/translate-all.c |  3 +++
 bsd-user/main.c   |  1 -
 linux-user/main.c |  1 -
 tcg/tcg.c | 52 ++-
 5 files changed, 22 insertions(+), 46 deletions(-)

diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index e378c2db73..f132033999 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -111,17 +111,6 @@ static int tcg_init(MachineState *ms)
 
 tcg_exec_init(s->tb_size * 1024 * 1024, s->splitwx_enabled);
 mttcg_enabled = s->mttcg_enabled;
-
-/*
- * Initialize TCG regions only for softmmu.
- *
- * This needs to be done later for user mode, because the prologue
- * generation needs to be delayed so that GUEST_BASE is already set.
- */
-#ifndef CONFIG_USER_ONLY
-tcg_region_init();
-#endif /* !CONFIG_USER_ONLY */
-
 return 0;
 }
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index f32df8b240..b9057567f4 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1339,6 +1339,9 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
splitwx, _fatal);
 assert(ok);
 
+/* TODO: allocating regions is hand-in-glove with code_gen_buffer. */
+tcg_region_init();
+
 #if defined(CONFIG_SOFTMMU)
 /* There's no guest base to take into account, so go ahead and
initialize the prologue now.  */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 798aba512c..3669d2b89e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -994,7 +994,6 @@ int main(int argc, char **argv)
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account.  */
 tcg_prologue_init(tcg_ctx);
-tcg_region_init();
 
 /* build Task State */
 memset(ts, 0, sizeof(TaskState));
diff --git a/linux-user/main.c b/linux-user/main.c
index 4f4746dce8..1bc48ca954 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -850,7 +850,6 @@ int main(int argc, char **argv, char **envp)
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account.  */
 tcg_prologue_init(tcg_ctx);
-tcg_region_init();
 
 target_cpu_copy_regs(env, regs);
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 2991112829..0a2e5710de 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1204,32 +1204,18 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
 
 void tcg_prologue_init(TCGContext *s)
 {
-size_t prologue_size, total_size;
-void *buf0, *buf1;
+size_t prologue_size;
 
 /* Put the prologue at the beginning of code_gen_buffer.  */
-buf0 = s->code_gen_buffer;
-total_size = s->code_gen_buffer_size;
-s->code_ptr = buf0;
-s->code_buf = buf0;
+tcg_region_assign(s, 0);
+s->code_ptr = s->code_gen_ptr;
+s->code_buf = s->code_gen_ptr;
 s->data_gen_ptr = NULL;
 
-/*
- * The region trees are not yet configured, but tcg_splitwx_to_rx
- * needs the bounds for an assert.
- */
-region.start = buf0;
-region.end = buf0 + total_size;
-
 #ifndef CONFIG_TCG_INTERPRETER
-tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(buf0);
+tcg_qemu_tb_exec = (tcg_prologue_fn *)tcg_splitwx_to_rx(s->code_ptr);
 #endif
 
-/* Compute a high-water mark, at which we voluntarily flush the buffer
-   and start over.  The size here is arbitrary, significantly larger
-   than we expect the code generation for any one opcode to require.  */
-s->code_gen_highwater = s->code_gen_buffer + (total_size - TCG_HIGHWATER);
-
 #ifdef TCG_TARGET_NEED_POOL_LABELS
 s->pool_labels = NULL;
 #endif
@@ -1246,32 +1232,32 @@ void tcg_prologue_init(TCGContext *s)
 }
 #endif
 
-buf1 = s->code_ptr;
+prologue_size = tcg_current_code_size(s);
+
 #ifndef CONFIG_TCG_INTERPRETER
-flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(buf0), (uintptr_t)buf0,
-tcg_ptr_byte_diff(buf1, buf0));
+flush_idcache_range((uintptr_t)tcg_splitwx_to_rx(s->code_buf),
+(uintptr_t)s->code_buf, prologue_size);
 #endif
 
-/* Deduct the prologue from the buffer.  */
-prologue_size = tcg_current_code_size(s);
-s->code_gen_ptr = buf1;
-s->code_gen_buffer = buf1;
-s->code_buf = buf1;
-total_size -= prologue_size;
-s->code_gen_buffer_size = total_size;
+/* Deduct the prologue from the first region.  */
+region.start = s->code_ptr;
 
-tcg_register_jit(tcg_splitwx_to_rx(s->code_gen_buffer), total_size);
+/* Recompute boundaries of the first region. */
+tcg_region_assign(s, 0);
+
+tcg_register_jit(tcg_splitwx_to_rx(region.start),
+ 

[PATCH v2 04/29] tcg: Remove error return from tcg_region_initial_alloc__locked

2021-03-14 Thread Richard Henderson
All callers immediately assert on error, so move the assert
into the function itself.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/tcg.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0a2e5710de..2b631fccdf 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -720,9 +720,10 @@ static bool tcg_region_alloc(TCGContext *s)
  * Perform a context's first region allocation.
  * This function does _not_ increment region.agg_size_full.
  */
-static inline bool tcg_region_initial_alloc__locked(TCGContext *s)
+static void tcg_region_initial_alloc__locked(TCGContext *s)
 {
-return tcg_region_alloc__locked(s);
+bool err = tcg_region_alloc__locked(s);
+g_assert(!err);
 }
 
 /* Call from a safe-work context */
@@ -737,9 +738,7 @@ void tcg_region_reset_all(void)
 
 for (i = 0; i < n_ctxs; i++) {
 TCGContext *s = qatomic_read(_ctxs[i]);
-bool err = tcg_region_initial_alloc__locked(s);
-
-g_assert(!err);
+tcg_region_initial_alloc__locked(s);
 }
 qemu_mutex_unlock();
 
@@ -874,11 +873,7 @@ void tcg_region_init(void)
 
 /* In user-mode we support only one ctx, so do the initial allocation now 
*/
 #ifdef CONFIG_USER_ONLY
-{
-bool err = tcg_region_initial_alloc__locked(tcg_ctx);
-
-g_assert(!err);
-}
+tcg_region_initial_alloc__locked(tcg_ctx);
 #endif
 }
 
@@ -940,7 +935,6 @@ void tcg_register_thread(void)
 MachineState *ms = MACHINE(qdev_get_machine());
 TCGContext *s = g_malloc(sizeof(*s));
 unsigned int i, n;
-bool err;
 
 *s = tcg_init_ctx;
 
@@ -964,8 +958,7 @@ void tcg_register_thread(void)
 
 tcg_ctx = s;
 qemu_mutex_lock();
-err = tcg_region_initial_alloc__locked(tcg_ctx);
-g_assert(!err);
+tcg_region_initial_alloc__locked(s);
 qemu_mutex_unlock();
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.25.1




[PATCH v2 00/29] tcg: Workaround macOS 11.2 mprotect bug

2021-03-14 Thread Richard Henderson
Changes for v2:
  * Move tcg_init_ctx someplace more private (patch 29)
  * Round result of tb_size based on qemu_get_host_physmem (patch 26)

Blurb for v1:
  It took a few more patches than imagined to unify the two
  places in which we manipulate the tcg code_gen buffer, but
  the result is surely cleaner.

  There's a lot more that could be done to clean up this part
  of tcg too.  I tried to not get too side-tracked, but didn't
  wholly succeed.


r~


Richard Henderson (29):
  meson: Split out tcg/meson.build
  meson: Split out fpu/meson.build
  tcg: Re-order tcg_region_init vs tcg_prologue_init
  tcg: Remove error return from tcg_region_initial_alloc__locked
  tcg: Split out tcg_region_initial_alloc
  tcg: Split out tcg_region_prologue_set
  tcg: Split out region.c
  accel/tcg: Inline cpu_gen_init
  accel/tcg: Move alloc_code_gen_buffer to tcg/region.c
  accel/tcg: Rename tcg_init to tcg_init_machine
  tcg: Create tcg_init
  accel/tcg: Merge tcg_exec_init into tcg_init_machine
  accel/tcg: Pass down max_cpus to tcg_init
  tcg: Introduce tcg_max_ctxs
  tcg: Move MAX_CODE_GEN_BUFFER_SIZE to tcg-target.h
  tcg: Replace region.end with region.total_size
  tcg: Rename region.start to region.after_prologue
  tcg: Tidy tcg_n_regions
  tcg: Tidy split_cross_256mb
  tcg: Move in_code_gen_buffer and tests to region.c
  tcg: Allocate code_gen_buffer into struct tcg_region_state
  tcg: Return the map protection from alloc_code_gen_buffer
  tcg: Sink qemu_madvise call to common code
  tcg: Do not set guard pages in the rx buffer
  util/osdep: Add qemu_mprotect_rw
  tcg: Round the tb_size default from qemu_get_host_physmem
  tcg: Merge buffer protection and guard page protection
  tcg: When allocating for !splitwx, begin with PROT_NONE
  tcg: Move tcg_init_ctx and tcg_ctx from accel/tcg/

 meson.build   |  13 +-
 accel/tcg/internal.h  |   2 +
 include/qemu/osdep.h  |   1 +
 include/sysemu/tcg.h  |   2 -
 include/tcg/tcg.h |  15 +-
 tcg/aarch64/tcg-target.h  |   1 +
 tcg/arm/tcg-target.h  |   1 +
 tcg/i386/tcg-target.h |   2 +
 tcg/internal.h|  40 ++
 tcg/mips/tcg-target.h |   6 +
 tcg/ppc/tcg-target.h  |   2 +
 tcg/riscv/tcg-target.h|   1 +
 tcg/s390/tcg-target.h |   3 +
 tcg/sparc/tcg-target.h|   1 +
 tcg/tci/tcg-target.h  |   1 +
 accel/tcg/tcg-all.c   |  33 +-
 accel/tcg/translate-all.c | 439 +
 bsd-user/main.c   |   1 -
 linux-user/main.c |   1 -
 tcg/region.c  | 991 ++
 tcg/tcg.c | 634 ++--
 util/osdep.c  |   9 +
 fpu/meson.build   |   1 +
 tcg/meson.build   |  14 +
 24 files changed, 1139 insertions(+), 1075 deletions(-)
 create mode 100644 tcg/internal.h
 create mode 100644 tcg/region.c
 create mode 100644 fpu/meson.build
 create mode 100644 tcg/meson.build

-- 
2.25.1




[PATCH] virtio: Fix virtio_mmio_read()/virtio_mmio_write()

2021-03-14 Thread Laurent Vivier
Both functions don't check the personality of the interface (legacy or
modern) before accessing the configuration memory and always use
virtio_config_readX()/virtio_config_writeX().

With this patch, they now check the personality and in legacy mode
call virtio_config_readX()/virtio_config_writeX(), otherwise call
virtio_config_modern_readX()/virtio_config_modern_writeX().

This change has been tested with virtio-mmio guests (virt stretch/armhf and
virt sid/m68k) and virtio-pci guests (pseries RHEL-7.3/ppc64 and /ppc64le).

Signed-off-by: Laurent Vivier 
---
 hw/virtio/virtio-mmio.c | 74 +
 1 file changed, 52 insertions(+), 22 deletions(-)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 6990b9879cf0..342c918ea7b7 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -112,15 +112,28 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr 
offset, unsigned size)
 
 if (offset >= VIRTIO_MMIO_CONFIG) {
 offset -= VIRTIO_MMIO_CONFIG;
-switch (size) {
-case 1:
-return virtio_config_readb(vdev, offset);
-case 2:
-return virtio_config_readw(vdev, offset);
-case 4:
-return virtio_config_readl(vdev, offset);
-default:
-abort();
+if (proxy->legacy) {
+switch (size) {
+case 1:
+return virtio_config_readb(vdev, offset);
+case 2:
+return virtio_config_readw(vdev, offset);
+case 4:
+return virtio_config_readl(vdev, offset);
+default:
+abort();
+}
+} else {
+switch (size) {
+case 1:
+return virtio_config_modern_readb(vdev, offset);
+case 2:
+return virtio_config_modern_readw(vdev, offset);
+case 4:
+return virtio_config_modern_readl(vdev, offset);
+default:
+abort();
+}
 }
 }
 if (size != 4) {
@@ -245,20 +258,37 @@ static void virtio_mmio_write(void *opaque, hwaddr 
offset, uint64_t value,
 
 if (offset >= VIRTIO_MMIO_CONFIG) {
 offset -= VIRTIO_MMIO_CONFIG;
-switch (size) {
-case 1:
-virtio_config_writeb(vdev, offset, value);
-break;
-case 2:
-virtio_config_writew(vdev, offset, value);
-break;
-case 4:
-virtio_config_writel(vdev, offset, value);
-break;
-default:
-abort();
+if (proxy->legacy) {
+switch (size) {
+case 1:
+virtio_config_writeb(vdev, offset, value);
+break;
+case 2:
+virtio_config_writew(vdev, offset, value);
+break;
+case 4:
+virtio_config_writel(vdev, offset, value);
+break;
+default:
+abort();
+}
+return;
+} else {
+switch (size) {
+case 1:
+virtio_config_modern_writeb(vdev, offset, value);
+break;
+case 2:
+virtio_config_modern_writew(vdev, offset, value);
+break;
+case 4:
+virtio_config_modern_writel(vdev, offset, value);
+break;
+default:
+abort();
+}
+return;
 }
-return;
 }
 if (size != 4) {
 qemu_log_mask(LOG_GUEST_ERROR,
-- 
2.29.2




Re: [PATCH v4 2/4] util/qemu-sockets.c: Split host:port parsing out of inet_parse

2021-03-14 Thread Doug Evans
On Sat, Mar 6, 2021 at 11:29 AM Samuel Thibault 
wrote:

> Hello,
>
> Doug Evans, le ven. 05 mars 2021 17:00:13 -0800, a ecrit:
> > Is it possible for QEMU to lazily determine the guest's IPv6
> > address? I.e., postpone the ""->guest address mapping until it's
> > needed and then, say, take the first entry in the NDP table?
>
> That would probably be possible, yes, by moving the
>
> if (!guest_addr.s_addr) {
> guest_addr = slirp->vdhcp_startaddr;
> }
>
> from slirp_add_hostfwd() and alike to tcp_connect() and sorecvfrom()
> (along the other sotranslate call).
>
> > That feels a bit fragile: what if someone else gets the first entry in
> > the NDP table? But is that any more fragile than assuming the first
> > handed out DHCP address is to the guest?
>
> I don't think it's really more fragile.
>


Good to know, thanks.


> > [<<-- Honest question, can we assume the first handed out DHCP address
> > will necessarily be the guest?]
>
> It "cannot" be anything else. What could happen is a PXE loader that
> uses DHCP/NDP, and then the OS that does it again.
>
> > But that would mean the defaults for the guest would have to be
> > different than for the host. E.g.,
> > host: ",ipv4" means both,
>
> Why would it mean both? I don't follow you here.
>
> > whereas guest: ",ipv4" (ideally) means ipv4 (since both is meaningless)
>


I guess one has to define:
- how these flags work,
- do they have defaults,
- and if they do have defaults what is the default value?

For the host, neither flag present means "both are on", which could mean,
effectively, that the defaults for
ipv4[={off,on}] and ipv6[={off,on}] are both "on".
[Assuming they have defaults. See above: Do they?
For the guest ipv4=on,ipv6=on is an error.]
But does that then mean that the presence of only "ipv4=on" or "ipv6=on" is
a no-op?
After all, why specify "ipv4=on" at all if it's the default?
I think a reader would get confused if they saw only one of "ipv4=on" or
"ipv6=on"
specified and learned that both were on.
It also means that to specify only one of ipv4 or ipv6 you have to turn the
other off.
It's a bit awkward, but it is consistent and easy to explain (if awkward to
use and read).

On the other hand, for the host, one could, for example,
make these flags tri-state (or call it whatever).
Is specifying only "ipv4=off" the equivalent of specifying only "ipv6=on"?
Presumably it must (it makes the most sense).
There is also the invalid setting of ipv4=off,ipv6=off.
One also needs to specify the order in which the flags are processed,
to define what ipv6=on,ipv6=off means.
Either that or document that specifying them multiple times is undefined.

This is getting a bit verbose to have to explain in documentation,
but it is what it is.
I don't have a say in the decision. I just need to know what to implement.


RE: [PATCH v5 01/13] hw/block/nvme: fix zone management receive reporting too many zones

2021-03-14 Thread Dmitry Fomichev
LGTM,
Reviewed-by: Dmitry Fomichev 

> -Original Message-
> From: Klaus Jensen 
> Sent: Wednesday, March 10, 2021 4:54 AM
> To: qemu-devel@nongnu.org
> Cc: Stefan Hajnoczi ; Klaus Jensen
> ; Fam Zheng ; Max Reitz
> ; Kevin Wolf ; qemu-
> bl...@nongnu.org; Gollu Appalanaidu ; Keith
> Busch ; Klaus Jensen ;
> Dmitry Fomichev 
> Subject: [PATCH v5 01/13] hw/block/nvme: fix zone management receive
> reporting too many zones
> 
> From: Klaus Jensen 
> 
> nvme_zone_mgmt_recv uses nvme_ns_nlbas() to get the number of LBAs in
> the namespace and then calculates the number of zones to report by
> incrementing slba with ZSZE until exceeding the number of LBAs as
> returned by nvme_ns_nlbas().
> 
> This is bad because the namespace might be of such as size that some
> LBAs are valid, but are not part of any zone, causing zone management
> receive to report one additional (but non-existing) zone.
> 
> Fix this with a conventional loop on i < ns->num_zones instead.
> 
> Fixes: a479335bfaf3 ("hw/block/nvme: Support Zoned Namespace Command
> Set")
> Cc: Dmitry Fomichev 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/block/nvme.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> index d439e44db839..c7b9a1663dd7 100644
> --- a/hw/block/nvme.c
> +++ b/hw/block/nvme.c
> @@ -2619,12 +2619,13 @@ static uint16_t
> nvme_zone_mgmt_recv(NvmeCtrl *n, NvmeRequest *req)
>  uint32_t zone_idx, zra, zrasf, partial;
>  uint64_t max_zones, nr_zones = 0;
>  uint16_t status;
> -uint64_t slba, capacity = nvme_ns_nlbas(ns);
> +uint64_t slba;
>  NvmeZoneDescr *z;
>  NvmeZone *zone;
>  NvmeZoneReportHeader *header;
>  void *buf, *buf_p;
>  size_t zone_entry_sz;
> +int i;
> 
>  req->status = NVME_SUCCESS;
> 
> @@ -2666,7 +2667,7 @@ static uint16_t nvme_zone_mgmt_recv(NvmeCtrl
> *n, NvmeRequest *req)
>  buf = g_malloc0(data_size);
> 
>  zone = >zone_array[zone_idx];
> -for (; slba < capacity; slba += ns->zone_size) {
> +for (i = zone_idx; i < ns->num_zones; i++) {
>  if (partial && nr_zones >= max_zones) {
>  break;
>  }
> --
> 2.30.1




Re: [PULL 0/5] Linux user for 6.0 patches

2021-03-14 Thread Peter Maydell
On Sat, 13 Mar 2021 at 09:50, Laurent Vivier  wrote:
>
> The following changes since commit 3f8d1885e48e4d72eab0688f604de62e0aea7a38:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/ui-20210311-pull-request'=
>  into staging (2021-03-12 13:53:44 +)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/linux-user-for-6.0-pull-request
>
> for you to fetch changes up to 0266e8e3b3981b492e82be20bb97e8ed9792ed00:
>
>   linux-user/elfload: fix address calculation in fallback scenario (2021-03-1=
> 3 10:45:11 +0100)
>
> 
> linux-user pull request 20210313
>
> - fix elfload
> - fix executable page of /proc/self/maps
> - add preserve-arg[0] support for binfmt_misc
>
> 


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.0
for any user-visible changes.

-- PMM



Re: [PATCH] ui/cocoa: Do not raise keys before QEMU resigns active

2021-03-14 Thread Akihiko Odaki
2021年3月14日(日) 21:55 BALATON Zoltan :
>
> On Sun, 14 Mar 2021, Akihiko Odaki wrote:
> > ui/cocoa used to raise all keys before it resigns active to prevent a
> > stuck key problem caused by key up events it does not see while it is
> > inactive. The problem is solved by checking -[NSEvent modifierFlags] in
> > commit 6d73bb643aa725348aabe6a885ac5fb0b7f70252, which is better
> > because it handles the case that key *down* events are missed while it
> > is inactive.
>
> Does that commit also handle other keys than modifier keys? It's unlikely
> those get stuck but is that possible? The most likely case to happen is
> pressing Cmd+Tab to switch away and Cmd may get stuck. Can Tab get also
> stuck? Or what if you hold down space or some other key while switching
> away either with Cmd+Tab or with the mouse? That may not be a common case
> but is this here to handle that or they are already handled elsewhere so
> this is really not necessary to prevent stuck keys?

I experimented with Cmd+Tab and ui/cocoa did not respond to it at all.
Apparently events for the particular key combination is not delivered
to the application.

If you switch away while holding space or some other key, the key
remains pressed on the guest, but the guest will receive a key up
event as soon as the key are released. If an event with
NSEventTypeKeyUp is fired, a corresponding event with
NSEventTypeKeyDown will be fired eventually whether the application
remains active or not. Events with NSEventTypeFlagsChanged do not have
such assurance and the modifier state tracking requires some tricks
like the new -[NSEvent modifierFlags] checks or the obsolete solution
deleted with this patch.

Actually -[QemuCocoaView raiseAllKeys] before introducing the new
-[NSEvent modifierFlags] checks only dealt with modifiers (event
though its name suggests it raises all keys) so there should be no
regression.

Regards,
Akihiko Odaki

>
> Regards,
> BALATON Zoltan
>
> > Signed-off-by: Akihiko Odaki 
> > ---
> > ui/cocoa.m | 20 
> > 1 file changed, 20 deletions(-)
> >
> > diff --git a/ui/cocoa.m b/ui/cocoa.m
> > index a7848ae0a30..ac8989947f5 100644
> > --- a/ui/cocoa.m
> > +++ b/ui/cocoa.m
> > @@ -326,7 +326,6 @@ - (BOOL) isAbsoluteEnabled;
> > - (float) cdx;
> > - (float) cdy;
> > - (QEMUScreen) gscreen;
> > -- (void) raiseAllKeys;
> > @end
> >
> > QemuCocoaView *cocoaView;
> > @@ -996,18 +995,6 @@ - (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
> > - (float) cdx {return cdx;}
> > - (float) cdy {return cdy;}
> > - (QEMUScreen) gscreen {return screen;}
> > -
> > -/*
> > - * Makes the target think all down keys are being released.
> > - * This prevents a stuck key problem, since we will not see
> > - * key up events for those keys after we have lost focus.
> > - */
> > -- (void) raiseAllKeys
> > -{
> > -with_iothread_lock(^{
> > -qkbd_state_lift_all_keys(kbd);
> > -});
> > -}
> > @end
> >
> >
> > @@ -1143,13 +1130,6 @@ - (BOOL)windowShouldClose:(id)sender
> > return NO;
> > }
> >
> > -/* Called when QEMU goes into the background */
> > -- (void) applicationWillResignActive: (NSNotification *)aNotification
> > -{
> > -COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
> > -[cocoaView raiseAllKeys];
> > -}
> > -
> > /* We abstract the method called by the Enter Fullscreen menu item
> >  * because Mac OS 10.7 and higher disables it. This is because of the
> >  * menu item's old selector's name toggleFullScreen:
> >



Re: [PATCH v8 27/35] Hexagon (target/hexagon) TCG for instructions with multiple definitions

2021-03-14 Thread Richard Henderson

On 3/13/21 6:41 PM, Taylor Simpson wrote:

+#define fGEN_TCG_L2_loadrub_pr(SHORTCODE)  SHORTCODE
+#define fGEN_TCG_L2_loadrub_pi(SHORTCODE)  SHORTCODE
+#define fGEN_TCG_L2_loadrb_pr(SHORTCODE)   SHORTCODE
+#define fGEN_TCG_L2_loadrb_pi(SHORTCODE)   SHORTCODE;
+#define fGEN_TCG_L2_loadruh_pr(SHORTCODE)  SHORTCODE
+#define fGEN_TCG_L2_loadruh_pi(SHORTCODE)  SHORTCODE;


Why have some of these ; but not all?


The initial series only has overrides that are required for correct execution.


This does not answer the question re the semicolon inconsistency.


r~



[PATCH v3 16/16] target/ppc: Validate hflags with CONFIG_DEBUG_TCG

2021-03-14 Thread Richard Henderson
Verify that hflags was updated correctly whenever we change
cpu state that is used by hflags.

Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h |  5 +
 target/ppc/helper_regs.c | 29 +++--
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2f8d7fa13c..7ee5c9a66e 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2424,6 +2424,10 @@ void cpu_write_xer(CPUPPCState *env, target_ulong xer);
  */
 #define is_book3s_arch2x(ctx) (!!((ctx)->insns_flags & PPC_SEGMENT_64B))
 
+#ifdef CONFIG_DEBUG_TCG
+void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
+  target_ulong *cs_base, uint32_t *flags);
+#else
 static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *flags)
 {
@@ -2431,6 +2435,7 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, 
target_ulong *pc,
 *cs_base = 0;
 *flags = env->hflags;
 }
+#endif
 
 void QEMU_NORETURN raise_exception(CPUPPCState *env, uint32_t exception);
 void QEMU_NORETURN raise_exception_ra(CPUPPCState *env, uint32_t exception,
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index b28037ca24..9df1098fec 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -43,7 +43,7 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env)
 env->tgpr[3] = tmp;
 }
 
-void hreg_compute_hflags(CPUPPCState *env)
+static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
 {
 target_ulong msr = env->msr;
 uint32_t ppc_flags = env->flags;
@@ -147,9 +147,34 @@ void hreg_compute_hflags(CPUPPCState *env)
 hflags |= dmmu_idx << HFLAGS_DMMU_IDX;
 #endif
 
-env->hflags = hflags | (msr & msr_mask);
+return hflags | (msr & msr_mask);
 }
 
+void hreg_compute_hflags(CPUPPCState *env)
+{
+env->hflags = hreg_compute_hflags_value(env);
+}
+
+#ifdef CONFIG_DEBUG_TCG
+void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
+  target_ulong *cs_base, uint32_t *flags)
+{
+uint32_t hflags_current = env->hflags;
+uint32_t hflags_rebuilt;
+
+*pc = env->nip;
+*cs_base = 0;
+*flags = hflags_current;
+
+hflags_rebuilt = hreg_compute_hflags_value(env);
+if (unlikely(hflags_current != hflags_rebuilt)) {
+cpu_abort(env_cpu(env),
+  "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
+  hflags_current, hflags_rebuilt);
+}
+}
+#endif
+
 void cpu_interrupt_exittb(CPUState *cs)
 {
 if (!kvm_enabled()) {
-- 
2.25.1




[PATCH v3 05/16] target/ppc: Retain hflags_nmsr only for migration

2021-03-14 Thread Richard Henderson
We have eliminated all normal uses of hflags_nmsr.  We need
not even compute it except when we want to migrate.  Rename
the field to emphasize this.

Remove the fixme comment for migrating access_type.  This value
is only ever used with the current executing instruction, and
is never live when the cpu is halted for migration.

Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h | 4 ++--
 target/ppc/helper_regs.c | 2 --
 target/ppc/machine.c | 9 ++---
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 061d2eed1b..79c4033a42 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1105,8 +1105,8 @@ struct CPUPPCState {
 #endif
 
 /* These resources are used only in QEMU core */
-target_ulong hflags;  /* hflags is MSR & HFLAGS_MASK */
-target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
+target_ulong hflags;
+target_ulong hflags_compat_nmsr; /* for migration compatibility */
 int immu_idx; /* precomputed MMU index to speed up insn accesses */
 int dmmu_idx; /* precomputed MMU index to speed up data accesses */
 
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 95b9aca61f..a87e354ca2 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -104,8 +104,6 @@ void hreg_compute_hflags(CPUPPCState *env)
  */
 uint32_t le = extract32(env->spr[SPR_HID0], 3, 1);
 env->hflags |= le << MSR_LE;
-/* Retain for backward compatibility with migration. */
-env->hflags_nmsr = le << MSR_LE;
 }
 }
 
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index f6eeda9642..1f7a353c78 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -310,6 +310,10 @@ static int cpu_pre_save(void *opaque)
 }
 }
 
+/* Retain migration compatibility for pre 6.0 for 601 machines. */
+env->hflags_compat_nmsr = (env->flags & POWERPC_FLAG_HID0_LE
+   ? env->hflags & MSR_LE : 0);
+
 return 0;
 }
 
@@ -829,9 +833,8 @@ const VMStateDescription vmstate_ppc_cpu = {
 /* Supervisor mode architected state */
 VMSTATE_UINTTL(env.msr, PowerPCCPU),
 
-/* Internal state */
-VMSTATE_UINTTL(env.hflags_nmsr, PowerPCCPU),
-/* FIXME: access_type? */
+/* Backward compatible internal state */
+VMSTATE_UINTTL(env.hflags_compat_nmsr, PowerPCCPU),
 
 /* Sanity checking */
 VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration),
-- 
2.25.1




[PATCH v3 15/16] linux-user/ppc: Fix msr updates

2021-03-14 Thread Richard Henderson
In save_user_regs, there are two bugs where we OR in a bit number
instead of the bit, clobbering the low bits of MSR.  However:

The MSR_VR and MSR_SPE bits control the availability of the insns.
If the bits were not already set in MSR, then any attempt to access
those registers would result in SIGILL.

For linux-user, we always initialize MSR to the capabilities
of the cpu.  We *could* add checks vs MSR where we currently
check insn_flags and insn_flags2, but we know they match.

Also, there's a stray cut-and-paste comment in restore.

Then, do not force little-endian binaries into big-endian mode.

Finally, use ppc_store_msr for the update to affect hflags.
Which is the reason none of these bugs were previously noticed.

Signed-off-by: Richard Henderson 
---
 linux-user/ppc/cpu_loop.c |  5 +++--
 linux-user/ppc/signal.c   | 23 +++
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index df71e15a25..4a0f6c8dc2 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -492,11 +492,12 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 #if defined(TARGET_PPC64)
 int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF;
 #if defined(TARGET_ABI32)
-env->msr &= ~((target_ulong)1 << flag);
+ppc_store_msr(env, env->msr & ~((target_ulong)1 << flag));
 #else
-env->msr |= (target_ulong)1 << flag;
+ppc_store_msr(env, env->msr | (target_ulong)1 << flag);
 #endif
 #endif
+
 env->nip = regs->nip;
 for(i = 0; i < 32; i++) {
 env->gpr[i] = regs->gpr[i];
diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
index b78613f7c8..bad38f8ed9 100644
--- a/linux-user/ppc/signal.c
+++ b/linux-user/ppc/signal.c
@@ -261,9 +261,6 @@ static void save_user_regs(CPUPPCState *env, struct 
target_mcontext *frame)
 __put_user(avr->u64[PPC_VEC_HI], >u64[0]);
 __put_user(avr->u64[PPC_VEC_LO], >u64[1]);
 }
-/* Set MSR_VR in the saved MSR value to indicate that
-   frame->mc_vregs contains valid data.  */
-msr |= MSR_VR;
 #if defined(TARGET_PPC64)
 vrsave = (uint32_t *)>mc_vregs.altivec[33];
 /* 64-bit needs to put a pointer to the vectors in the frame */
@@ -300,9 +297,6 @@ static void save_user_regs(CPUPPCState *env, struct 
target_mcontext *frame)
 for (i = 0; i < ARRAY_SIZE(env->gprh); i++) {
 __put_user(env->gprh[i], >mc_vregs.spe[i]);
 }
-/* Set MSR_SPE in the saved MSR value to indicate that
-   frame->mc_vregs contains valid data.  */
-msr |= MSR_SPE;
 __put_user(env->spe_fscr, >mc_vregs.spe[32]);
 }
 #endif
@@ -354,8 +348,10 @@ static void restore_user_regs(CPUPPCState *env,
 __get_user(msr, >mc_gregs[TARGET_PT_MSR]);
 
 /* If doing signal return, restore the previous little-endian mode.  */
-if (sig)
-env->msr = (env->msr & ~(1ull << MSR_LE)) | (msr & (1ull << MSR_LE));
+if (sig) {
+ppc_store_msr(env, ((env->msr & ~(1ull << MSR_LE)) |
+(msr & (1ull << MSR_LE;
+}
 
 /* Restore Altivec registers if necessary.  */
 if (env->insns_flags & PPC_ALTIVEC) {
@@ -376,8 +372,6 @@ static void restore_user_regs(CPUPPCState *env,
 __get_user(avr->u64[PPC_VEC_HI], >u64[0]);
 __get_user(avr->u64[PPC_VEC_LO], >u64[1]);
 }
-/* Set MSR_VEC in the saved MSR value to indicate that
-   frame->mc_vregs contains valid data.  */
 #if defined(TARGET_PPC64)
 vrsave = (uint32_t *)_regs[33];
 #else
@@ -468,7 +462,7 @@ void setup_frame(int sig, struct target_sigaction *ka,
 env->nip = (target_ulong) ka->_sa_handler;
 
 /* Signal handlers are entered in big-endian mode.  */
-env->msr &= ~(1ull << MSR_LE);
+ppc_store_msr(env, env->msr & ~(1ull << MSR_LE));
 
 unlock_user_struct(frame, frame_addr, 1);
 return;
@@ -563,8 +557,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
 env->nip = (target_ulong) ka->_sa_handler;
 #endif
 
+#ifdef TARGET_WORDS_BIGENDIAN
 /* Signal handlers are entered in big-endian mode.  */
-env->msr &= ~(1ull << MSR_LE);
+ppc_store_msr(env, env->msr & ~(1ull << MSR_LE));
+#else
+/* Signal handlers are entered in little-endian mode.  */
+ppc_store_msr(env, env->msr | (1ull << MSR_LE));
+#endif
 
 unlock_user_struct(rt_sf, rt_sf_addr, 1);
 return;
-- 
2.25.1




  1   2   >