Re: [Qemu-devel] [PATCH] net/slirp: fix the error message when the prefix len is invalid

2019-05-09 Thread Markus Armbruster
Stefano Garzarella  writes:

> On Thu, May 09, 2019 at 04:54:35PM +0200, Markus Armbruster wrote:
>> Stefano Garzarella  writes:
>> 
>> > Add a missing parentheses at the end of the error message,
>> > when we have an invalid prefix len.
>> >
>> > Signed-off-by: Stefano Garzarella 
>> > ---
>> >  net/slirp.c | 3 ++-
>> >  1 file changed, 2 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/net/slirp.c b/net/slirp.c
>> > index 95934fb36d..0f4ae0abc0 100644
>> > --- a/net/slirp.c
>> > +++ b/net/slirp.c
>> > @@ -498,7 +498,8 @@ static int net_slirp_init(NetClientState *peer, const 
>> > char *model,
>> >  }
>> >  if (vprefix6_len < 0 || vprefix6_len > 126) {
>> >  error_setg(errp,
>> > -   "Invalid prefix provided (prefix len must be in range 
>> > 0-126");
>> > +   "Invalid prefix provided "
>> > +   "(prefix len must be in range 0-126)");
>> >  return -1;
>> >  }
>> 
>> Preexisting: the error message fails to identify the offending
>> parameter.  The user needs to make the connection to "ipv6-prefixlen"
>> based on the fact that the only parameters with "prefix" in name or
>> description are "ipv6-prefix" and "ipv6-prefixlen", and only the latter
>> is a length.
>> 
>> What about "Parameter 'ipv6-prefixlen' expects a length below 127", or
>> "Parameter 'ipv6-prefixlen' expects a value between 0 and 126"?
>
> "Parameter 'ipv6-prefixlen' expects a value between 0 and 126" should be
> fine.
>
> Otherwise, since other errors didn't refer to the parameter name, we can
> simply add IPv6 in this way:
> "Invalid IPv6 prefix provided (IPv6 prefix len must be between 0 and 126)"

"len" is not a word.  Either say "ipv6-prefixlen", or say "IPv6 prefix
length".

> But I'm fine also with your proposal.

It's just a suggestion.  Feel free to leave the error messages
consistently vague (apply your patch as is), improve just this one, or
improve more messages.



[Qemu-devel] [PATCH] tests/libqtest: Remove unused global_qtest-related wrapper functions

2019-05-09 Thread Thomas Huth
A bunch of the wrapper functions that use global_qtest are not used
anymore. Remove them to avoid that they are used in new code again.

Signed-off-by: Thomas Huth 
---
 tests/libqtest.c |  11 +
 tests/libqtest.h | 108 ---
 2 files changed, 1 insertion(+), 118 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index c49b85482d..8ac0c02af4 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -1038,15 +1038,6 @@ QDict *qmp(const char *fmt, ...)
 return response;
 }
 
-void qmp_send(const char *fmt, ...)
-{
-va_list ap;
-
-va_start(ap, fmt);
-qtest_qmp_vsend(global_qtest, fmt, ap);
-va_end(ap);
-}
-
 char *hmp(const char *fmt, ...)
 {
 va_list ap;
@@ -1232,7 +1223,7 @@ void qtest_qmp_device_del(const char *id)
 _event);
 qobject_unref(rsp);
 if (!got_event) {
-rsp = qmp_receive();
+rsp = qtest_qmp_receive(global_qtest);
 g_assert_cmpstr(qdict_get_try_str(rsp, "event"),
 ==, "DEVICE_DELETED");
 qobject_unref(rsp);
diff --git a/tests/libqtest.h b/tests/libqtest.h
index a16acd58a6..3f7675fcf0 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -618,26 +618,6 @@ static inline void qtest_end(void)
  */
 QDict *qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 
-/**
- * qmp_send:
- * @fmt...: QMP message to send to qemu, formatted like
- * qobject_from_jsonf_nofail().  See parse_escape() for what's
- * supported after '%'.
- *
- * Sends a QMP message to QEMU and leaves the response in the stream.
- */
-void qmp_send(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-
-/**
- * qmp_receive:
- *
- * Reads a QMP message from QEMU and returns the response.
- */
-static inline QDict *qmp_receive(void)
-{
-return qtest_qmp_receive(global_qtest);
-}
-
 /**
  * qmp_eventwait:
  * @s: #event event to wait for.
@@ -649,18 +629,6 @@ static inline void qmp_eventwait(const char *event)
 return qtest_qmp_eventwait(global_qtest, event);
 }
 
-/**
- * qmp_eventwait_ref:
- * @s: #event event to wait for.
- *
- * Continuously polls for QMP responses until it receives the desired event.
- * Returns a copy of the event for further investigation.
- */
-static inline QDict *qmp_eventwait_ref(const char *event)
-{
-return qtest_qmp_eventwait_ref(global_qtest, event);
-}
-
 /**
  * hmp:
  * @fmt...: HMP command to send to QEMU, formats arguments like sprintf().
@@ -682,30 +650,6 @@ static inline bool get_irq(int num)
 return qtest_get_irq(global_qtest, num);
 }
 
-/**
- * irq_intercept_in:
- * @string: QOM path of a device.
- *
- * Associate qtest irqs with the GPIO-in pins of the device
- * whose path is specified by @string.
- */
-static inline void irq_intercept_in(const char *string)
-{
-qtest_irq_intercept_in(global_qtest, string);
-}
-
-/**
- * qtest_irq_intercept_out:
- * @string: QOM path of a device.
- *
- * Associate qtest irqs with the GPIO-out pins of the device
- * whose path is specified by @string.
- */
-static inline void irq_intercept_out(const char *string)
-{
-qtest_irq_intercept_out(global_qtest, string);
-}
-
 /**
  * outb:
  * @addr: I/O port to write to.
@@ -894,19 +838,6 @@ static inline void memread(uint64_t addr, void *data, 
size_t size)
 qtest_memread(global_qtest, addr, data, size);
 }
 
-/**
- * bufread:
- * @addr: Guest address to read from.
- * @data: Pointer to where memory contents will be stored.
- * @size: Number of bytes to read.
- *
- * Read guest memory into a buffer, receive using a base64 encoding.
- */
-static inline void bufread(uint64_t addr, void *data, size_t size)
-{
-qtest_bufread(global_qtest, addr, data, size);
-}
-
 /**
  * memwrite:
  * @addr: Guest address to write to.
@@ -920,32 +851,6 @@ static inline void memwrite(uint64_t addr, const void 
*data, size_t size)
 qtest_memwrite(global_qtest, addr, data, size);
 }
 
-/**
- * bufwrite:
- * @addr: Guest address to write to.
- * @data: Pointer to the bytes that will be written to guest memory.
- * @size: Number of bytes to write.
- *
- * Write a buffer to guest memory, transmit using a base64 encoding.
- */
-static inline void bufwrite(uint64_t addr, const void *data, size_t size)
-{
-qtest_bufwrite(global_qtest, addr, data, size);
-}
-
-/**
- * qmemset:
- * @addr: Guest address to write to.
- * @patt: Byte pattern to fill the guest memory region with.
- * @size: Number of bytes to write.
- *
- * Write a pattern to guest memory.
- */
-static inline void qmemset(uint64_t addr, uint8_t patt, size_t size)
-{
-qtest_memset(global_qtest, addr, patt, size);
-}
-
 /**
  * clock_step_next:
  *
@@ -971,19 +876,6 @@ static inline int64_t clock_step(int64_t step)
 return qtest_clock_step(global_qtest, step);
 }
 
-/**
- * clock_set:
- * @val: Nanoseconds value to advance the clock to.
- *
- * Advance the QEMU_CLOCK_VIRTUAL to @val nanoseconds since the VM was 
launched.
- *
- * Returns: The current value of the 

Re: [Qemu-devel] [PATCH 3/3] ramfb enhancement

2019-05-09 Thread Gerd Hoffmann
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -3080,8 +3080,10 @@ static void vfio_realize(PCIDevice *pdev, Error
> **errp)
>  error_setg(errp, "xres and yres properties require
> display=on");
>  goto out_teardown;
>  }
> -if (vdev->dpy->edid_regs == NULL) {
> -error_setg(errp, "xres and yres properties need edid support");
> +if (vdev->dpy->edid_regs == NULL && !vdev->enable_ramfb) {
> +error_setg(errp,
> +   "xres and yres properties need edid support"
> +   " or ramfb=on");
>  goto out_teardown;
>  }
>  }

I don't think this is useful.  We should continue to allow xres and yres
only in case the vfio device actually has edid support.

cheers,
  Gerd




Re: [Qemu-devel] [PATCH 2/3] ramfb enhancement

2019-05-09 Thread Gerd Hoffmann
On Thu, May 09, 2019 at 03:58:02PM +0800, Hou Qiming wrote:
> Only allow one resolution change per guest boot, which prevents a
> crash when the guest writes garbage to the configuration space (e.g.
> when rebooting).

Hmm?  Did you see that happen in practice?
It is not easy to write to fw_cfg by accident ...

> 
> Signed-off-by: HOU Qiming 
> ---
>  hw/display/ramfb.c | 26 ++
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
> index c27fcc7..fa6296b 100644
> --- a/hw/display/ramfb.c
> +++ b/hw/display/ramfb.c
> @@ -31,6 +31,7 @@ struct RAMFBState {
>  uint32_t width, height;
>  hwaddr addr, length;
>  struct RAMFBCfg cfg;
> +bool locked;
>  };
> 
>  static void qemu_unmap_displaysurface_guestmem(pixman_image_t *image,
> @@ -73,11 +74,11 @@ static DisplaySurface
> *qemu_create_displaysurface_guestmem(
>  static void ramfb_fw_cfg_write(void *dev, off_t offset, size_t len)
>  {
>  RAMFBState *s = dev;
> -uint32_t fourcc, format;
> +uint32_t fourcc, format, width, height;
>  hwaddr stride, addr, length;
> 
> -s->width  = be32_to_cpu(s->cfg.width);
> -s->height = be32_to_cpu(s->cfg.height);
> +width = be32_to_cpu(s->cfg.width);
> +height= be32_to_cpu(s->cfg.height);
>  stride= be32_to_cpu(s->cfg.stride);
>  fourcc= be32_to_cpu(s->cfg.fourcc);
>  addr  = be64_to_cpu(s->cfg.addr);
> @@ -85,9 +86,16 @@ static void ramfb_fw_cfg_write(void *dev, off_t offset,
> size_t len)
>  format= qemu_drm_format_to_pixman(fourcc);
> 
>  fprintf(stderr, "%s: %dx%d @ 0x%" PRIx64 "\n", __func__,
> -s->width, s->height, addr);
> +width, height, addr);
> +if (s->locked) {
> +fprintf(stderr, "%s: resolution locked, change rejected\n",
> __func__);
> +return;
> +}
> +s->locked = true;
>  s->addr = addr;
>  s->length = length;
> +s->width = width;
> +s->height = height;
>  s->ds = qemu_create_displaysurface_guestmem(s->width, s->height,
>  format, stride, s->addr);
>  }
> @@ -107,6 +115,13 @@ void ramfb_display_update(QemuConsole *con, RAMFBState
> *s)
>  dpy_gfx_update_full(con);
>  }
> 
> +static void ramfb_reset(void *opaque)
> +{
> +RAMFBState *s = (RAMFBState *)opaque;
> +s->locked = false;
> +memset(>cfg, 0, sizeof(s->cfg));
> +}
> +
>  RAMFBState *ramfb_setup(Error **errp)
>  {
>  FWCfgState *fw_cfg = fw_cfg_find();
> @@ -119,9 +134,12 @@ RAMFBState *ramfb_setup(Error **errp)
> 
>  s = g_new0(RAMFBState, 1);
> 
> +s->locked = false;
> +
>  rom_add_vga("vgabios-ramfb.bin");
>  fw_cfg_add_file_callback(fw_cfg, "etc/ramfb",
>   NULL, ramfb_fw_cfg_write, s,
>   >cfg, sizeof(s->cfg), false);
> +qemu_register_reset(ramfb_reset, s);
>  return s;
>  }
> -- 
> 2.17.1



Re: [Qemu-devel] [PATCH 1/3] ramfb enhancement

2019-05-09 Thread Gerd Hoffmann
On Thu, May 09, 2019 at 03:57:24PM +0800, Hou Qiming wrote:
> Pulled back the `qemu_create_displaysurface_guestmem` function to create
> the display surface so that the guest memory gets properly unmaped.
> 
> Signed-off-by: HOU Qiming 
> ---
>  hw/display/ramfb.c | 53 --
>  1 file changed, 42 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
> index 25c8ad7..c27fcc7 100644
> --- a/hw/display/ramfb.c
> +++ b/hw/display/ramfb.c
> @@ -29,13 +29,50 @@ struct QEMU_PACKED RAMFBCfg {
>  struct RAMFBState {
>  DisplaySurface *ds;
>  uint32_t width, height;
> +hwaddr addr, length;

Why do you add these?  Seem not to be used anywhere in the patch ...

Also a more descriptive subject line would be good.

cheers,
  Gerd




Re: [Qemu-devel] [PATCH v1 22/23] tests/qemu-iotests: re-format output to for make check-block

2019-05-09 Thread Thomas Huth
On 09/05/2019 18.59, Alex Bennée wrote:
> This attempts to clean-up the output to better match the output of the
> rest of the QEMU check system. This includes:
> 
>   - formatting as "  TESTiotest: nnn"
>   - calculating time diff at the end
>   - only dumping config on failure
> 
> Signed-off-by: Alex Bennée 
> Message-Id: <20190503143904.31211-1-alex.ben...@linaro.org>
> ---
>  tests/qemu-iotests/check | 101 +++
>  1 file changed, 61 insertions(+), 40 deletions(-)
[...]
> -cat < -QEMU  -- "$QEMU_PROG" $QEMU_OPTIONS
> -QEMU_IMG  -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
> -QEMU_IO   -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
> -QEMU_NBD  -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
> -IMGFMT-- $FULL_IMGFMT_DETAILS
> -IMGPROTO  -- $IMGPROTO
> -PLATFORM  -- $FULL_HOST_DETAILS
> -TEST_DIR  -- $TEST_DIR
> -SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
> -
> -EOF
> +if ! $pretty; then
> +_full_env_details
> +fi
>  
>  seq="check"
[...]
> @@ -852,9 +869,13 @@ do
>  #
>  if $err
>  then
> +_report_test_result $seq "FAILED $reason"
> +_full_env_details

I'd suggest to wrap the _full_env_details with a "if $pretty" statement,
otherwise the env will be printed out twice, one time at the beginning,
and one time in case of an error.

>  bad="$bad $seq"
>  n_bad=$(expr $n_bad + 1)
>  quick=false
> +else
> +_report_test_result $seq "$results"
>  fi
>  [ -f $seq.notrun ] || try=$(expr $try + 1)
>  
> 

 Thomas



Re: [Qemu-devel] [PATCH v3 7/7] tests: Run the iotests during "make check" again

2019-05-09 Thread Thomas Huth
On 09/05/2019 20.08, Max Reitz wrote:
> On 02.05.19 10:45, Thomas Huth wrote:
>> People often forget to run the iotests before submitting patches or
>> pull requests - this is likely due to the fact that we do not run the
>> tests during our mandatory "make check" tests yet. Now that we've got
>> a proper "auto" group of iotests that should be fine to run in every
>> environment, we can enable the iotests during "make check" again by
>> running the "auto" tests by default from the check-block.sh script.
>>
>> Some cases still need to be checked first, though: iotests need bash
>> and GNU sed (otherwise they fail), and if gprof is enabled, it spoils
>> the output of some test cases causing them to fail. So if we detect
>> that one of the required programs is missing or that gprof is enabled,
>> we still have to skip the iotests to avoid failures.
>>
>> And finally, since we are using check-block.sh now again, this patch also
>> removes the qemu-iotests-quick.sh script since we do not need that anymore
>> (and having two shell wrapper scripts around the block tests seem
>> rather confusing than helpful).
>>
>> Signed-off-by: Thomas Huth 
>> ---
>>  tests/Makefile.include  |  8 +++
>>  tests/check-block.sh| 44 -
>>  tests/qemu-iotests-quick.sh |  8 ---
>>  3 files changed, 38 insertions(+), 22 deletions(-)
>>  delete mode 100755 tests/qemu-iotests-quick.sh
> 
> Can I interest you in a Makefile target that explicitly excludes
> check-block?  I run the iotests anyway, but I also run make check.
> Running some iotests twice would be a bit pointless.

Can't you simply run

 ./check -qcow2 -x auto

instead?

 Thomas



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 00/13] tests/vm: serial console autoinstall, misc fixes.

2019-05-09 Thread Gerd Hoffmann
On Thu, May 09, 2019 at 08:52:23PM +0200, Kamil Rytarowski wrote:
> On 08.05.2019 10:56, Gerd Hoffmann wrote:
> > This patch series changes the way virtual machines for test builds are
> > managed.  They are created locally on the developer machine now.  The
> > installer is booted on the serial console and the scripts walks through
> > the dialogs to install and configure the guest.
> > 
> > That takes the download.patchew.org server out of the loop and makes it
> > alot easier to tweak the guest images (adding build dependencies for
> > example).
> > 
> > The install scripts take care to apply host proxy settings (from *_proxy
> > environment variables) to the guest, so any package downloads will be
> > routed through the proxy and can be cached that way.  This also makes
> > them work behind strict firewalls.
> > 
> > There are also a bunch of smaller tweaks for tests/vm to fix issues I
> > was struggling with.  See commit messages of individual patches for
> > details.
> > 
> > Known issue:  NetBSD package install is not working for me right now.
> > It did work a while ago.  Not sure what is going on here.
> > 
> 
> Error log? What is the command? pkgin install?

Looked like a dependency problem, the error log complained that it
couldn't find a new enough tcl version for tk.

"fixed" that by installing git-base instead of git, which drop the tk
dependency of git.

cheers,
  Gerd




[Qemu-devel] [PATCH v2 8/8] scripts/qemu-binfmt-conf: Update for sparc64

2019-05-09 Thread Richard Henderson
Also note that we were missing the qemu_target_list entry
for plain sparc; fix that at the same time.

Signed-off-by: Richard Henderson 
---
 scripts/qemu-binfmt-conf.sh | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index b5a16742a1..9f1580a91c 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 # Enable automatic program execution by the kernel.
 
-qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k 
\
-mips mipsel mipsn32 mipsn32el mips64 mips64el \
+qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \
+ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \
 sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
 microblaze microblazeel or1k x86_64"
 
@@ -38,6 +38,10 @@ 
sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
 
sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
 sparc32plus_family=sparc
 
+sparc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'
+sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sparc64_family=sparc
+
 
ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
 
ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
 ppc_family=ppc
-- 
2.17.1




[Qemu-devel] [PATCH v2 7/8] linux-user/sparc: Flush register windows before clone

2019-05-09 Thread Richard Henderson
As seen as the very first instruction of sys_clone in the kernel.

Ideally this would be done in or before cpu_copy, and not with a
separate explicit test vs the syscall number, but this is a more
minimal solution.

Signed-off-by: Richard Henderson 
---
 linux-user/sparc/cpu_loop.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 9e357229c0..ff04f67847 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -169,6 +169,9 @@ void cpu_loop (CPUSPARCState *env)
 case 0x110:
 case 0x16d:
 #endif
+if (env->gregs[1] == TARGET_NR_clone) {
+flush_windows(env);
+}
 ret = do_syscall (env, env->gregs[1],
   env->regwptr[0], env->regwptr[1],
   env->regwptr[2], env->regwptr[3],
-- 
2.17.1




[Qemu-devel] [PATCH v2 2/8] linux-user: Pass the parent env to cpu_clone_regs

2019-05-09 Thread Richard Henderson
Implementing clone for sparc requires that we make modifications
to both the parent and child cpu state.  In all other cases, the
new argument can be ignored.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_cpu.h| 3 ++-
 linux-user/alpha/target_cpu.h  | 3 ++-
 linux-user/arm/target_cpu.h| 3 ++-
 linux-user/cris/target_cpu.h   | 3 ++-
 linux-user/hppa/target_cpu.h   | 3 ++-
 linux-user/i386/target_cpu.h   | 3 ++-
 linux-user/m68k/target_cpu.h   | 3 ++-
 linux-user/microblaze/target_cpu.h | 3 ++-
 linux-user/mips/target_cpu.h   | 3 ++-
 linux-user/nios2/target_cpu.h  | 3 ++-
 linux-user/openrisc/target_cpu.h   | 4 +++-
 linux-user/ppc/target_cpu.h| 3 ++-
 linux-user/riscv/target_cpu.h  | 3 ++-
 linux-user/s390x/target_cpu.h  | 3 ++-
 linux-user/sh4/target_cpu.h| 3 ++-
 linux-user/sparc/target_cpu.h  | 3 ++-
 linux-user/tilegx/target_cpu.h | 3 ++-
 linux-user/xtensa/target_cpu.h | 3 ++-
 linux-user/syscall.c   | 2 +-
 19 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index a021c95fa4..130177115e 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -19,7 +19,8 @@
 #ifndef AARCH64_TARGET_CPU_H
 #define AARCH64_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUARMState *env, CPUARMState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->xregs[31] = newsp;
diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
index ac4d255ae7..750ffb50d7 100644
--- a/linux-user/alpha/target_cpu.h
+++ b/linux-user/alpha/target_cpu.h
@@ -19,7 +19,8 @@
 #ifndef ALPHA_TARGET_CPU_H
 #define ALPHA_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUAlphaState *env, CPUAlphaState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->ir[IR_SP] = newsp;
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index 8a3764919a..5538b6cb29 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -23,7 +23,8 @@
See validate_guest_space in linux-user/elfload.c.  */
 #define MAX_RESERVED_VA  0xul
 
-static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUARMState *env, CPUARMState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->regs[13] = newsp;
diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
index 2309343979..baf842b400 100644
--- a/linux-user/cris/target_cpu.h
+++ b/linux-user/cris/target_cpu.h
@@ -20,7 +20,8 @@
 #ifndef CRIS_TARGET_CPU_H
 #define CRIS_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUCRISState *env, CPUCRISState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->regs[14] = newsp;
diff --git a/linux-user/hppa/target_cpu.h b/linux-user/hppa/target_cpu.h
index 1c539bdbd6..7cd8d168a7 100644
--- a/linux-user/hppa/target_cpu.h
+++ b/linux-user/hppa/target_cpu.h
@@ -19,7 +19,8 @@
 #ifndef HPPA_TARGET_CPU_H
 #define HPPA_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUHPPAState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUHPPAState *env, CPUHPPAState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->gr[30] = newsp;
diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
index ece04d0966..8fbe36670f 100644
--- a/linux-user/i386/target_cpu.h
+++ b/linux-user/i386/target_cpu.h
@@ -20,7 +20,8 @@
 #ifndef I386_TARGET_CPU_H
 #define I386_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUX86State *env, CPUX86State *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->regs[R_ESP] = newsp;
diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
index 7a26f3c3fc..00b3535fae 100644
--- a/linux-user/m68k/target_cpu.h
+++ b/linux-user/m68k/target_cpu.h
@@ -21,7 +21,8 @@
 #ifndef M68K_TARGET_CPU_H
 #define M68K_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
+static inline void cpu_clone_regs(CPUM68KState *env, CPUM68KState *old_env,
+  target_ulong newsp)
 {
 if (newsp) {
 env->aregs[7] = newsp;
diff --git a/linux-user/microblaze/target_cpu.h 
b/linux-user/microblaze/target_cpu.h
index 73e139938c..3394e98918 100644
--- a/linux-user/microblaze/target_cpu.h
+++ b/linux-user/microblaze/target_cpu.h
@@ -19,7 +19,8 @@
 #ifndef 

[Qemu-devel] [PATCH v2 4/8] linux-user/sparc: Use WREG constants in sparc/target_cpu.h

2019-05-09 Thread Richard Henderson
This fixes a naming bug wherein we used "UREG_FP" to access the
stack pointer.  OTOH, the "UREG_FP" constant was also defined
incorrectly such that it *did* reference the stack pointer.

Signed-off-by: Richard Henderson 
---
 linux-user/sparc/target_cpu.h | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index a92748cae3..567351d564 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -42,15 +42,9 @@ static inline void cpu_set_tls(CPUSPARCState *env, 
target_ulong newtls)
 env->gregs[7] = newtls;
 }
 
-#ifndef UREG_I6
-#define UREG_I66
-#endif
-#ifndef UREG_FP
-#define UREG_FPUREG_I6
-#endif
-
 static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
 {
-return state->regwptr[UREG_FP];
+return state->regwptr[WREG_SP];
 }
+
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v2 5/8] linux-user/sparc: Use WREG constants in sparc/signal.c

2019-05-09 Thread Richard Henderson
Remove the incorrectly defined UREG constants.

Maddeningly, in some cases we used the correct constant getting
the env register wrong, and in other cases we used the incorrect
constant getting the env register right.

In the case of getcontext/setcontext, we are aided by the fact
that the "other" constant, e.g. SPARC_MC_O0, is correct.  So we
can easily guess that the WREG_* constant on the other side
should also be O0.

Signed-off-by: Richard Henderson 
---
 linux-user/sparc/signal.c | 96 +--
 1 file changed, 32 insertions(+), 64 deletions(-)

diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index ead169fbaa..243f237528 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -104,20 +104,6 @@ struct target_rt_signal_frame {
 qemu_siginfo_fpu_t  fpu_state;
 };
 
-#define UREG_O016
-#define UREG_O622
-#define UREG_I00
-#define UREG_I11
-#define UREG_I22
-#define UREG_I33
-#define UREG_I44
-#define UREG_I55
-#define UREG_I66
-#define UREG_I77
-#define UREG_L08
-#define UREG_FPUREG_I6
-#define UREG_SPUREG_O6
-
 static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
  CPUSPARCState *env,
  unsigned long framesize)
@@ -159,30 +145,12 @@ setup___siginfo(__siginfo_t *si, CPUSPARCState *env, 
abi_ulong mask)
 __put_user(env->gregs[i], >si_regs.u_regs[i]);
 }
 for (i=0; i < 8; i++) {
-__put_user(env->regwptr[UREG_I0 + i], >si_regs.u_regs[i+8]);
+__put_user(env->regwptr[WREG_O0 + i], >si_regs.u_regs[i+8]);
 }
 __put_user(mask, >si_mask);
 return err;
 }
 
-#if 0
-static int
-setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
- CPUSPARCState *env, unsigned long mask)
-{
-int err = 0;
-
-__put_user(mask, >sigc_mask);
-__put_user(env->regwptr[UREG_SP], >sigc_sp);
-__put_user(env->pc, >sigc_pc);
-__put_user(env->npc, >sigc_npc);
-__put_user(env->psr, >sigc_psr);
-__put_user(env->gregs[1], >sigc_g1);
-__put_user(env->regwptr[UREG_O0], >sigc_o0);
-
-return err;
-}
-#endif
 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
 
 void setup_frame(int sig, struct target_sigaction *ka,
@@ -221,20 +189,20 @@ void setup_frame(int sig, struct target_sigaction *ka,
 }
 
 for (i = 0; i < 8; i++) {
-__put_user(env->regwptr[i + UREG_L0], >ss.locals[i]);
+__put_user(env->regwptr[i + WREG_L0], >ss.locals[i]);
 }
 for (i = 0; i < 8; i++) {
-__put_user(env->regwptr[i + UREG_I0], >ss.ins[i]);
+__put_user(env->regwptr[i + WREG_I0], >ss.ins[i]);
 }
 if (err)
 goto sigsegv;
 
 /* 3. signal handler back-trampoline and parameters */
-env->regwptr[UREG_FP] = sf_addr;
-env->regwptr[UREG_I0] = sig;
-env->regwptr[UREG_I1] = sf_addr +
+env->regwptr[WREG_FP] = sf_addr;
+env->regwptr[WREG_I0] = sig;
+env->regwptr[WREG_I1] = sf_addr +
 offsetof(struct target_signal_frame, info);
-env->regwptr[UREG_I2] = sf_addr +
+env->regwptr[WREG_I2] = sf_addr +
 offsetof(struct target_signal_frame, info);
 
 /* 4. signal handler */
@@ -242,11 +210,11 @@ void setup_frame(int sig, struct target_sigaction *ka,
 env->npc = (env->pc + 4);
 /* 5. return to kernel instructions */
 if (ka->ka_restorer) {
-env->regwptr[UREG_I7] = ka->ka_restorer;
+env->regwptr[WREG_I7] = ka->ka_restorer;
 } else {
 uint32_t val32;
 
-env->regwptr[UREG_I7] = sf_addr +
+env->regwptr[WREG_I7] = sf_addr +
 offsetof(struct target_signal_frame, insns) - 2 * 4;
 
 /* mov __NR_sigreturn, %g1 */
@@ -284,7 +252,7 @@ long do_sigreturn(CPUSPARCState *env)
 sigset_t host_set;
 int i;
 
-sf_addr = env->regwptr[UREG_FP];
+sf_addr = env->regwptr[WREG_SP];
 trace_user_do_sigreturn(env, sf_addr);
 if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
 goto segv_and_exit;
@@ -316,7 +284,7 @@ long do_sigreturn(CPUSPARCState *env)
 __get_user(env->gregs[i], >info.si_regs.u_regs[i]);
 }
 for (i=0; i < 8; i++) {
-__get_user(env->regwptr[i + UREG_I0], >info.si_regs.u_regs[i+8]);
+__get_user(env->regwptr[i + WREG_O0], >info.si_regs.u_regs[i+8]);
 }
 
 /* FIXME: implement FPU save/restore:
@@ -433,7 +401,7 @@ void sparc64_set_context(CPUSPARCState *env)
 abi_ulong fp, i7, w_addr;
 unsigned int i;
 
-ucp_addr = env->regwptr[UREG_I0];
+ucp_addr = env->regwptr[WREG_O0];
 if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
 goto do_sigsegv;
 }
@@ -443,7 +411,7 @@ void sparc64_set_context(CPUSPARCState *env)
 if ((pc | npc) & 3) {
 goto do_sigsegv;
 }
-if (env->regwptr[UREG_I1]) {
+if 

[Qemu-devel] [PATCH v2 3/8] target/sparc: Define an enumeration for accessing env->regwptr

2019-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/sparc/cpu.h | 33 +
 1 file changed, 33 insertions(+)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 85b9665ccc..08f7d1a3c6 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -31,6 +31,39 @@
 
 /*#define EXCP_INTERRUPT 0x100*/
 
+/* Windowed register indexes.  */
+enum {
+WREG_O0,
+WREG_O1,
+WREG_O2,
+WREG_O3,
+WREG_O4,
+WREG_O5,
+WREG_O6,
+WREG_O7,
+
+WREG_L0,
+WREG_L1,
+WREG_L2,
+WREG_L3,
+WREG_L4,
+WREG_L5,
+WREG_L6,
+WREG_L7,
+
+WREG_I0,
+WREG_I1,
+WREG_I2,
+WREG_I3,
+WREG_I4,
+WREG_I5,
+WREG_I6,
+WREG_I7,
+
+WREG_SP = WREG_O6,
+WREG_FP = WREG_I6,
+};
+
 /* trap definitions */
 #ifndef TARGET_SPARC64
 #define TT_TFAULT   0x01
-- 
2.17.1




[Qemu-devel] [PATCH v2 0/8] linux-user sparc fixes

2019-05-09 Thread Richard Henderson
Version 1 was posted back in July 2018.  Oops.  ;-)

https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg05788.html

--- v1 cover letter

There are at least 4 separate bugs preventing clone from working.

(1) cpu_copy left both cpus sharing the same register window (!)

(2) cpu_clone_regs did not initialize %o1, so the new thread path
in the guest __clone was always taken, even for the parent
(old %o1 value was newsp, and so non-zero).

(3) cpu_clone_regs did not advance the pc past the syscall in the
child, which meant that the child re-executed the syscall
(and because of (1), with essentially random inputs).

(4) clone did not flush register windows, which would cause the
parent stack to be clobbered by the child writing out old
windows in order to allocate a new one.

This is enough for Alex's atomic-test to make progress, but not
quite enough for it to actually work.  What I'm seeing now is a
legitimate SEGV for a write to a r-xp memory segment.  I'll need
to examine the testcase further to see why that is happening.

---

I have now traced the remaining problem to cpu_clone_regs putting the
newsp into the frame pointer, not the stack pointer.  In fixing this,
I define a set of WREG_* constants in target/sparc/cpu.h, and then go
on to fix some related problems in linux-user/sparc/signal.c.


r~


Richard Henderson (8):
  linux-user: Disallow setting newsp for fork
  linux-user: Pass the parent env to cpu_clone_regs
  target/sparc: Define an enumeration for accessing env->regwptr
  linux-user/sparc: Use WREG constants in sparc/target_cpu.h
  linux-user/sparc: Use WREG constants in sparc/signal.c
  linux-user/sparc: Fix cpu_clone_regs
  linux-user/sparc: Flush register windows before clone
  scripts/qemu-binfmt-conf: Update for sparc64

 linux-user/aarch64/target_cpu.h|  3 +-
 linux-user/alpha/target_cpu.h  |  3 +-
 linux-user/arm/target_cpu.h|  3 +-
 linux-user/cris/target_cpu.h   |  3 +-
 linux-user/hppa/target_cpu.h   |  3 +-
 linux-user/i386/target_cpu.h   |  3 +-
 linux-user/m68k/target_cpu.h   |  3 +-
 linux-user/microblaze/target_cpu.h |  3 +-
 linux-user/mips/target_cpu.h   |  3 +-
 linux-user/nios2/target_cpu.h  |  3 +-
 linux-user/openrisc/target_cpu.h   |  4 +-
 linux-user/ppc/target_cpu.h|  3 +-
 linux-user/riscv/target_cpu.h  |  3 +-
 linux-user/s390x/target_cpu.h  |  3 +-
 linux-user/sh4/target_cpu.h|  3 +-
 linux-user/sparc/target_cpu.h  | 41 -
 linux-user/tilegx/target_cpu.h |  3 +-
 linux-user/xtensa/target_cpu.h |  3 +-
 target/sparc/cpu.h | 33 ++
 linux-user/sparc/cpu_loop.c|  3 +
 linux-user/sparc/signal.c  | 96 ++
 linux-user/syscall.c   |  9 ++-
 scripts/qemu-binfmt-conf.sh|  8 ++-
 23 files changed, 141 insertions(+), 101 deletions(-)

-- 
2.17.1




[Qemu-devel] [PATCH v2 6/8] linux-user/sparc: Fix cpu_clone_regs

2019-05-09 Thread Richard Henderson
We failed to set the secondary return value in %o1
we failed to advance the PC past the syscall,
we failed to adjust regwptr into the new structure,
we stored the stack pointer into the wrong register.

Signed-off-by: Richard Henderson 
---
 linux-user/sparc/target_cpu.h | 28 ++--
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index 567351d564..bbcb3a92ed 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -23,18 +23,34 @@
 static inline void cpu_clone_regs(CPUSPARCState *env, CPUSPARCState *old_env,
   target_ulong newsp)
 {
-if (newsp) {
-env->regwptr[22] = newsp;
-}
-/* syscall return for clone child: 0, and clear CF since
- * this counts as a success return value.
+/*
+ * After cpu_copy, env->regwptr is pointing into old_env.
+ * Update the new cpu to use its own register window.
  */
-env->regwptr[0] = 0;
+env->regwptr = env->regbase + (env->cwp * 16);
+
+/* Set a new stack, if requested.  */
+if (newsp) {
+env->regwptr[WREG_SP] = newsp;
+}
+
+/*
+ * Syscall return for clone child: %o0 = 0 and clear CF since
+ * this counts as a success return value.  %o1 = 1 to indicate
+ * this is the child.  Advance the PC past the syscall.
+ */
+env->regwptr[WREG_O0] = 0;
 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
 env->xcc &= ~PSR_CARRY;
 #else
 env->psr &= ~PSR_CARRY;
 #endif
+env->regwptr[WREG_O1] = 1;
+env->pc = env->npc;
+env->npc = env->npc + 4;
+
+/* Set the second return value for the parent: %o1 = 0.  */
+old_env->regwptr[WREG_O1] = 0;
 }
 
 static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
-- 
2.17.1




[Qemu-devel] [PATCH v2 1/8] linux-user: Disallow setting newsp for fork

2019-05-09 Thread Richard Henderson
Or really, just clone devolving into fork.  This should not ever happen
in practice.  We do want to reserve calling cpu_clone_regs for the case
in which we are actually performing a clone.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 96cd4bf86d..f7d0754c8d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5553,10 +5553,14 @@ static int do_fork(CPUArchState *env, unsigned int 
flags, abi_ulong newsp,
 pthread_mutex_destroy();
 pthread_mutex_unlock(_lock);
 } else {
-/* if no CLONE_VM, we consider it is a fork */
+/* If no CLONE_VM, we consider it is a fork.  */
 if (flags & CLONE_INVALID_FORK_FLAGS) {
 return -TARGET_EINVAL;
 }
+/* As a fork, setting a new sp does not make sense.  */
+if (newsp) {
+return -TARGET_EINVAL;
+}
 
 /* We can't support custom termination signals */
 if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
@@ -5571,7 +5575,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, 
abi_ulong newsp,
 ret = fork();
 if (ret == 0) {
 /* Child Process.  */
-cpu_clone_regs(env, newsp);
 fork_end(1);
 /* There is a race condition here.  The parent process could
theoretically read the TID in the child process before the child
-- 
2.17.1




Re: [Qemu-devel] [QEMU-PPC] [PATCH 05/13] target/ppc: Add privileged message send facilities

2019-05-09 Thread David Gibson
On Fri, May 03, 2019 at 03:53:08PM +1000, Suraj Jitindar Singh wrote:
> Privileged message send facilities exist on POWER8 processors and later
> and include a register and instructions which can be used to generate,
> observe/modify the state of and clear privileged doorbell exceptions as
> described below.
> 
> The Directed Privileged Doorbell Exception State (DPDES) register
> reflects the state of pending privileged doorbell exceptions and can
> also be used to modify that state. The register can be used to read and
> modify the state of privileged doorbell exceptions for all threads of a
> subprocessor and thus is a shared facility for that subprocessor. The
> register can be read/written by the hypervisor and read by the
> supervisor if enabled in the HFSCR, otherwise a hypervisor facility
> unavailable exception is generated.
> 
> The privileged message send and clear instructions (msgsndp & msgclrp)
> are used to generate and clear the presence of a directed privileged
> doorbell exception, respectively. The msgsndp instruction can be used to
> target any thread of the current subprocessor, msgclrp acts on the
> thread issuing the instruction. These instructions are privileged, but
> will generate a hypervisor facility unavailable exception if not enabled
> in the HFSCR and executed in privileged non-hypervisor state.
> 
> Add and implement this register and instructions by reading or modifying the
> pending interrupt state of the cpu.
> 
> Note that TCG only supports one thread per core and so we only need to
> worry about the cpu making the access.
> 
> Signed-off-by: Suraj Jitindar Singh 

I think this would be clearer if you put the framework for the
facility unavailable exception into a separate patch.  Apart from
that, LGTM.

> ---
>  target/ppc/cpu.h|  7 +
>  target/ppc/excp_helper.c| 63 
> +
>  target/ppc/helper.h |  5 
>  target/ppc/misc_helper.c| 46 ++
>  target/ppc/translate.c  | 28 ++
>  target/ppc/translate_init.inc.c | 40 ++
>  6 files changed, 184 insertions(+), 5 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index e324064111..1d2a088391 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -425,6 +425,10 @@ typedef struct ppc_v3_pate_t {
>  #define PSSCR_ESL PPC_BIT(42) /* Enable State Loss */
>  #define PSSCR_EC  PPC_BIT(43) /* Exit Criterion */
>  
> +/* HFSCR bits */
> +#define HFSCR_MSGSNDP PPC_BIT(53) /* Privileged Message Send Facilities 
> */
> +#define HFSCR_IC_MSGSNDP  0xA
> +
>  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
>  #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
>  #define msr_shv  ((env->msr >> MSR_SHV)  & 1)
> @@ -1355,6 +1359,8 @@ void cpu_ppc_set_vhyp(PowerPCCPU *cpu, 
> PPCVirtualHypervisor *vhyp);
>  #endif
>  
>  void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
> +void gen_hfscr_facility_check(DisasContext *ctx, int facility_sprn, int bit,
> +  int sprn, int cause);
>  
>  static inline uint64_t ppc_dump_gpr(CPUPPCState *env, int gprn)
>  {
> @@ -1501,6 +1507,7 @@ void ppc_compat_add_property(Object *obj, const char 
> *name,
>  #define SPR_MPC_ICTRL (0x09E)
>  #define SPR_MPC_BAR   (0x09F)
>  #define SPR_PSPB  (0x09F)
> +#define SPR_DPDES (0x0B0)
>  #define SPR_DAWR  (0x0B4)
>  #define SPR_RPR   (0x0BA)
>  #define SPR_CIABR (0x0BB)
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index beafcf1ebd..7a4da7bdba 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -461,6 +461,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp_model, int excp)
>  env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
>  #endif
>  break;
> +case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable 
> Exception */
> +env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << 
> FSCR_IC_POS);
> +srr0 = SPR_HSRR0;
> +srr1 = SPR_HSRR1;
> +new_msr |= (target_ulong)MSR_HVB;
> +new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> +break;
>  case POWERPC_EXCP_PIT:   /* Programmable interval timer interrupt
> */
>  LOG_EXCP("PIT exception\n");
>  break;
> @@ -884,7 +891,11 @@ static void ppc_hw_interrupt(CPUPPCState *env)
>  }
>  if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
>  env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
> -powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
> +if (env->insns_flags & PPC_SEGMENT_64B) {
> +powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR);
> +} else {
> +powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
> +   

Re: [Qemu-devel] [QEMU-PPC] [PATCH 08/13] target/ppc: Implement hcall H_SET_PARTITION_TABLE

2019-05-09 Thread David Gibson
On Fri, May 03, 2019 at 03:53:11PM +1000, Suraj Jitindar Singh wrote:
> The hcall H_SET_PARTITION_TABLE is used by a guest acting as a nested
> hypervisor to register the partition table entry for one of its guests
> with the real hypervisor.
> 
> Implement this hcall for a spapr guest.
> 
> Signed-off-by: Suraj Jitindar Singh 
> ---
>  hw/ppc/spapr_hcall.c   | 22 ++
>  include/hw/ppc/spapr.h |  4 +++-
>  2 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 4d7fe337a1..704ceff8e1 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -1828,6 +1828,25 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, 
> SpaprMachineState *spapr,
>  return H_SUCCESS;
>  }
>  
> +static target_ulong h_set_partition_table(PowerPCCPU *cpu,
> +  SpaprMachineState *spapr,
> +  target_ulong opcode,
> +  target_ulong *args)
> +{
> +CPUPPCState *env = >env;
> +target_ulong ptcr = args[0];
> +
> +if (spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV) == 0) {
> +return H_FUNCTION;
> +}
> +
> +if ((ptcr & PTCR_PATS) > 24)
> +return H_PARAMETER;
> +
> +env->spr[SPR_PTCR] = ptcr;
> +return H_SUCCESS;
> +}
> +
>  static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
>  static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - 
> KVMPPC_HCALL_BASE + 1];
>  
> @@ -1934,6 +1953,9 @@ static void hypercall_register_types(void)
>  
>  spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
>  
> +/* Platform-specific hcalls used for nested HV KVM */
> +spapr_register_hypercall(H_SET_PARTITION_TABLE, h_set_partition_table);
> +
>  /* Virtual Processor Home Node */
>  spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
>   h_home_node_associativity);
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 4251215908..e591ee0ba0 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -501,7 +501,9 @@ struct SpaprMachineState {
>  /* Client Architecture support */
>  #define KVMPPC_H_CAS(KVMPPC_HCALL_BASE + 0x2)
>  #define KVMPPC_H_UPDATE_DT  (KVMPPC_HCALL_BASE + 0x3)
> -#define KVMPPC_HCALL_MAXKVMPPC_H_UPDATE_DT
> +/* Platform-specific hcalls used for nested HV KVM */
> +#define H_SET_PARTITION_TABLE   0xF800

Urgh, vastly expanding the size of the kvmppc specific hcall table
here.  I guess that can't really be helped.

> +#define KVMPPC_HCALL_MAXH_SET_PARTITION_TABLE
>  
>  typedef struct SpaprDeviceTreeUpdateHeader {
>  uint32_t version_id;

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [QEMU-PPC] [PATCH 07/13] target/ppc: Handle partition scoped radix tree translation

2019-05-09 Thread David Gibson
On Fri, May 03, 2019 at 03:53:10PM +1000, Suraj Jitindar Singh wrote:
> Radix tree translation is a 2 step process:
> 
> Process Scoped Translation:
> Effective Address (EA) -> Virtual Address (VA)
> 
> Paritition Scoped Translation:
> Virtual Address (VA) -> Real Address (RA)
> 
> Performed based on:
>   MSR[HV]
>---
>| | HV = 0| HV = 1|
>---
>| Relocation  |   Partition   |  No   |
>| = Off   |Scoped |  Translation  |
> Relocation ---
>| Relocation  |  Partition &  |Process|
>| = On|Process Scoped |Scoped |
>---
> 
> Currently only process scoped translation is handled.
> Implement partitition scoped translation.
> 
> The process of using the radix trees to perform partition scoped
> translation is identical to process scoped translation, however
> hypervisor exceptions are generated, and thus we can reuse the radix
> tree traversing code.
> 
> Signed-off-by: Suraj Jitindar Singh 
> ---
>  target/ppc/cpu.h |   2 +
>  target/ppc/excp_helper.c |   3 +-
>  target/ppc/mmu-radix64.c | 407 
> +--
>  3 files changed, 293 insertions(+), 119 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 1d2a088391..3acc248f40 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -501,6 +501,8 @@ typedef struct ppc_v3_pate_t {
>  /* Unsupported Radix Tree Configuration */
>  #define DSISR_R_BADCONFIG0x0008
>  #define DSISR_ATOMIC_RC  0x0004
> +/* Unable to translate address of (guest) pde or process/page table entry */
> +#define DSISR_PRTABLE_FAULT  0x0002
>  
>  /* SRR1 error code fields */
>  
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 7a4da7bdba..10091d4624 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -441,9 +441,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp_model, int excp)
>  case POWERPC_EXCP_ISEG:  /* Instruction segment exception
> */
>  case POWERPC_EXCP_TRACE: /* Trace exception  
> */
>  break;
> +case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage exception 
> */
> +msr |= env->error_code;
>  case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception 
> */
>  case POWERPC_EXCP_HDSI:  /* Hypervisor data storage exception
> */
> -case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage exception 
> */
>  case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception
> */
>  case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception 
> */
>  case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt
> */
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index afa5ba506a..6118ad1b00 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -112,9 +112,31 @@ static void ppc_radix64_raise_si(PowerPCCPU *cpu, int 
> rwx, vaddr eaddr,
>  }
>  }
>  
> +static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, int rwx, vaddr eaddr,
> +  hwaddr g_raddr, uint32_t cause)
> +{
> +CPUState *cs = CPU(cpu);
> +CPUPPCState *env = >env;
> +
> +if (rwx == 2) { /* H Instruction Storage Interrupt */
> +cs->exception_index = POWERPC_EXCP_HISI;
> +env->spr[SPR_ASDR] = g_raddr;
> +env->error_code = cause;
> +} else { /* H Data Storage Interrupt */
> +cs->exception_index = POWERPC_EXCP_HDSI;
> +if (rwx == 1) { /* Write -> Store */
> +cause |= DSISR_ISSTORE;
> +}
> +env->spr[SPR_HDSISR] = cause;
> +env->spr[SPR_HDAR] = eaddr;
> +env->spr[SPR_ASDR] = g_raddr;
> +env->error_code = 0;
> +}
> +}
>  
>  static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int rwx, uint64_t pte,
> -   int *fault_cause, int *prot)
> +   int *fault_cause, int *prot,
> +   bool partition_scoped)
>  {
>  CPUPPCState *env = >env;
>  const int need_prot[] = { PAGE_READ, PAGE_WRITE, PAGE_EXEC };
> @@ -130,11 +152,11 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int 
> rwx, uint64_t pte,
>  }
>  
>  /* Determine permissions allowed by Encoded Access Authority */
> -if ((pte & R_PTE_EAA_PRIV) && msr_pr) { /* Insufficient Privilege */
> +if (!partition_scoped && (pte & R_PTE_EAA_PRIV) && msr_pr) {
>  *prot = 0;
> -} else if (msr_pr || (pte & R_PTE_EAA_PRIV)) {
> +} else if (msr_pr || (pte & R_PTE_EAA_PRIV) 

Re: [Qemu-devel] [PATCH v3 16/27] target/ppc: Convert to CPUClass::tlb_fill

2019-05-09 Thread David Gibson
On Thu, May 09, 2019 at 03:26:20PM -0700, Richard Henderson wrote:
> Cc: qemu-...@nongnu.org
> Cc: David Gibson 
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Acked-by: David Gibson 

> ---
>  target/ppc/cpu.h|  7 +++
>  target/ppc/mmu_helper.c | 22 +-
>  target/ppc/translate_init.inc.c |  5 ++---
>  target/ppc/user_only_helper.c   | 14 --
>  4 files changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 5e7cf54b2f..d7f23ad5e0 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1311,10 +1311,9 @@ void ppc_translate_init(void);
>   * is returned if the signal was handled by the virtual CPU.
>   */
>  int cpu_ppc_signal_handler(int host_signum, void *pinfo, void *puc);
> -#if defined(CONFIG_USER_ONLY)
> -int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
> - int mmu_idx);
> -#endif
> +bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> +  MMUAccessType access_type, int mmu_idx,
> +  bool probe, uintptr_t retaddr);
>  
>  #if !defined(CONFIG_USER_ONLY)
>  void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index 1dbc9acb75..afcca50530 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -3057,15 +3057,9 @@ void helper_check_tlb_flush_global(CPUPPCState *env)
>  
>  
> /*/
>  
> -/*
> - * try to fill the TLB and return an exception if error. If retaddr is
> - * NULL, it means that the function was called in C code (i.e. not
> - * from generated code or from helper.c)
> - *
> - * XXX: fix it to restore all registers
> - */
> -void tlb_fill(CPUState *cs, target_ulong addr, int size,
> -  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
> +bool ppc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
> +  MMUAccessType access_type, int mmu_idx,
> +  bool probe, uintptr_t retaddr)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
> @@ -3078,7 +3072,17 @@ void tlb_fill(CPUState *cs, target_ulong addr, int 
> size,
>  ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx);
>  }
>  if (unlikely(ret != 0)) {
> +if (probe) {
> +return false;
> +}
>  raise_exception_err_ra(env, cs->exception_index, env->error_code,
> retaddr);
>  }
> +return true;
> +}
> +
> +void tlb_fill(CPUState *cs, target_ulong addr, int size,
> +  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
> +{
> +ppc_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
>  }
> diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
> index 0394a9ddad..3f847de36c 100644
> --- a/target/ppc/translate_init.inc.c
> +++ b/target/ppc/translate_init.inc.c
> @@ -10592,9 +10592,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
> *data)
>  cc->gdb_read_register = ppc_cpu_gdb_read_register;
>  cc->gdb_write_register = ppc_cpu_gdb_write_register;
>  cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
> -#ifdef CONFIG_USER_ONLY
> -cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
> -#else
> +cc->tlb_fill = ppc_cpu_tlb_fill;
> +#ifndef CONFIG_USER_ONLY
>  cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
>  cc->vmsd = _ppc_cpu;
>  #endif
> diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c
> index 2f1477f102..683c03390d 100644
> --- a/target/ppc/user_only_helper.c
> +++ b/target/ppc/user_only_helper.c
> @@ -20,21 +20,24 @@
>  
>  #include "qemu/osdep.h"
>  #include "cpu.h"
> +#include "exec/exec-all.h"
>  
> -int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
> - int mmu_idx)
> +
> +bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> +  MMUAccessType access_type, int mmu_idx,
> +  bool probe, uintptr_t retaddr)
>  {
>  PowerPCCPU *cpu = POWERPC_CPU(cs);
>  CPUPPCState *env = >env;
>  int exception, error_code;
>  
> -if (rw == 2) {
> +if (access_type == MMU_INST_FETCH) {
>  exception = POWERPC_EXCP_ISI;
>  error_code = 0x4000;
>  } else {
>  exception = POWERPC_EXCP_DSI;
>  error_code = 0x4000;
> -if (rw) {
> +if (access_type == MMU_DATA_STORE) {
>  error_code |= 0x0200;
>  }
>  env->spr[SPR_DAR] = address;
> @@ -42,6 +45,5 @@ int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
> int size, int rw,
>  }
>  cs->exception_index = exception;
>  env->error_code = error_code;
> -
> -return 1;

Re: [Qemu-devel] [PATCH] Fix typo on "info pic" monitor cmd output for xive

2019-05-09 Thread David Gibson
On Thu, May 09, 2019 at 01:37:50PM +0530, sathn...@linux.vnet.ibm.com wrote:
> From: Satheesh Rajendran 
> 
> Instead of LISN i.e "Logical Interrupt Source Number" as per
> Xive PAPR document "info pic" prints as LSIN, let's fix it.
> 
> Signed-off-by: Satheesh Rajendran 

Applied to ppc-for-4.1, thanks.

> ---
>  hw/intc/spapr_xive.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
> index 7faf03b1fb..df3c879826 100644
> --- a/hw/intc/spapr_xive.c
> +++ b/hw/intc/spapr_xive.c
> @@ -141,7 +141,7 @@ void spapr_xive_pic_print_info(SpaprXive *xive, Monitor 
> *mon)
>  XiveSource *xsrc = >source;
>  int i;
>  
> -monitor_printf(mon, "  LSIN PQEISN CPU/PRIO EQ\n");
> +monitor_printf(mon, "  LISN PQEISN CPU/PRIO EQ\n");
>  
>  for (i = 0; i < xive->nr_irqs; i++) {
>  uint8_t pq = xive_source_esb_get(xsrc, i);

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [QEMU-PPC] [PATCH 09/13] target/ppc: Implement hcall H_ENTER_NESTED

2019-05-09 Thread David Gibson
On Fri, May 03, 2019 at 03:53:12PM +1000, Suraj Jitindar Singh wrote:
> The hcall H_ENTER_NESTED is used by a guest acting as a nested
> hypervisor to provide the state of one of its guests which it would
> like the real hypervisor to load onto the cpu and execute on its behalf.
> 
> The hcall takes as arguments 2 guest real addresses which provide the
> location of a regs struct and a hypervisor regs struct which provide the
> values to use to execute the guest. These are loaded into the cpu state
> and then the function returns to continue tcg execution in the new
> context. When an interrupt requires us to context switch back we restore
> the old register values and save the cpu state back into the guest
> memory.
> 
> Signed-off-by: Suraj Jitindar Singh 
> ---
>  hw/ppc/spapr_hcall.c | 285 
> +++
>  include/hw/ppc/spapr.h   |   3 +-
>  target/ppc/cpu.h |  55 +
>  target/ppc/excp_helper.c |  13 ++-
>  4 files changed, 353 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 704ceff8e1..68f3282214 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -16,6 +16,7 @@
>  #include "hw/ppc/spapr_ovec.h"
>  #include "mmu-book3s-v3.h"
>  #include "hw/mem/memory-device.h"
> +#include "hw/ppc/ppc.h"
>  
>  static bool has_spr(PowerPCCPU *cpu, int spr)
>  {
> @@ -1847,6 +1848,289 @@ static target_ulong h_set_partition_table(PowerPCCPU 
> *cpu,
>  return H_SUCCESS;
>  }
>  
> +static void byteswap_pt_regs(struct pt_regs *regs)
> +{
> +target_ulong *addr = (target_ulong *) regs;
> +
> +for (; addr < ((target_ulong *) (regs + 1)); addr++) {
> +*addr = bswap64(*addr);

Hrm.  pt_regs is defined in terms of target_ulongs, but this is
explicitly 64-bit.

> +}
> +}
> +
> +static void byteswap_hv_regs(struct hv_guest_state *hr)

Bulk byteswapping structures like this always gives me the
heeby-jeebies.  It means whenever we have such a structure there's an
invisible bit of state: whether it is currently in originally
supplied, or "fixed" endianness at this moment.  That's not obvious to
either the compiler or future people looking at the code.  You can't
even use tools like sparse to help you, because the same type is used
for the swapped and unswapped versions.

I think it would be preferable to treat the hv_guest_state structure
as always being the L1-supplied endianness version and do the swaps
value by value at the point you transcribe from this into / out of the
qemu internal structures (host endianness).

Of course, that has its own complications since then we need to pass
what the actual endianness of the guest structure is down to those
functions.

I don't suppose there's any chance we could retcon the paravirt nested
interfaces to define these structures as always being of a fixed
endianness (I guess it would have to be LE), rather than L1 mode
dependent?

> +{
> +hr->version = bswap64(hr->version);
> +hr->lpid = bswap32(hr->lpid);
> +hr->vcpu_token = bswap32(hr->vcpu_token);
> +hr->lpcr = bswap64(hr->lpcr);
> +hr->pcr = bswap64(hr->pcr);
> +hr->amor = bswap64(hr->amor);
> +hr->dpdes = bswap64(hr->dpdes);
> +hr->hfscr = bswap64(hr->hfscr);
> +hr->tb_offset = bswap64(hr->tb_offset);
> +hr->dawr0 = bswap64(hr->dawr0);
> +hr->dawrx0 = bswap64(hr->dawrx0);
> +hr->ciabr = bswap64(hr->ciabr);
> +hr->hdec_expiry = bswap64(hr->hdec_expiry);
> +hr->purr = bswap64(hr->purr);
> +hr->spurr = bswap64(hr->spurr);
> +hr->ic = bswap64(hr->ic);
> +hr->vtb = bswap64(hr->vtb);
> +hr->hdar = bswap64(hr->hdar);
> +hr->hdsisr = bswap64(hr->hdsisr);
> +hr->heir = bswap64(hr->heir);
> +hr->asdr = bswap64(hr->asdr);
> +hr->srr0 = bswap64(hr->srr0);
> +hr->srr1 = bswap64(hr->srr1);
> +hr->sprg[0] = bswap64(hr->sprg[0]);
> +hr->sprg[1] = bswap64(hr->sprg[1]);
> +hr->sprg[2] = bswap64(hr->sprg[2]);
> +hr->sprg[3] = bswap64(hr->sprg[3]);
> +hr->pidr = bswap64(hr->pidr);
> +hr->cfar = bswap64(hr->cfar);
> +hr->ppr = bswap64(hr->ppr);
> +}
> +
> +static void save_regs(PowerPCCPU *cpu, struct pt_regs *regs)
> +{
> +CPUPPCState env = cpu->env;
> +int i;
> +
> +for (i = 0; i < 32; i++)
> +regs->gpr[i] = env.gpr[i];
> +regs->nip = env.nip;
> +regs->msr = env.msr;
> +regs->ctr = env.ctr;
> +regs->link = env.lr;
> +regs->xer = env.xer;
> +regs->ccr = 0UL;
> +for (i = 0; i < 8; i++)
> +regs->ccr |= ((env.crf[i] & 0xF) << ((7 - i) * 4));
> +regs->dar = env.spr[SPR_DAR];
> +regs->dsisr = env.spr[SPR_DSISR];
> +}
> +
> +static void save_hv_regs(PowerPCCPU *cpu, struct hv_guest_state *hv_regs)
> +{
> +CPUPPCState env = cpu->env;
> +
> +hv_regs->lpid = env.spr[SPR_LPIDR];
> +hv_regs->lpcr = env.spr[SPR_LPCR];
> +hv_regs->pcr = env.spr[SPR_PCR];
> +hv_regs->amor = env.spr[SPR_AMOR];
> +hv_regs->dpdes = 

Re: [Qemu-devel] [QEMU-PPC] [PATCH 06/13] target/ppc: Enforce that the root page directory size must be at least 5

2019-05-09 Thread David Gibson
On Fri, May 03, 2019 at 03:53:09PM +1000, Suraj Jitindar Singh wrote:
> According to the ISA the root page directory size of a radix tree for
> either process or partition scoped translation must be >= 5.
> 
> Thus add this to the list of conditions checked when validating the
> partition table entry in validate_pate();
> 
> Signed-off-by: Suraj Jitindar Singh 

Reviewed-by: David Gibson 

> ---
>  target/ppc/mmu-radix64.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index a6ab290323..afa5ba506a 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -249,6 +249,8 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, 
> ppc_v3_pate_t *pate)
>  if (lpid == 0 && !msr_hv) {
>  return false;
>  }
> +if ((pate->dw0 & PATE1_R_PRTS) < 5)
> +return false;
>  /* More checks ... */
>  return true;
>  }

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v2 1/2] vfio/mdev: add version attribute for mdev device

2019-05-09 Thread Yan Zhao
On Thu, May 09, 2019 at 11:24:49PM +0800, Cornelia Huck wrote:
> On Wed, 8 May 2019 07:57:05 -0400
> Yan Zhao  wrote:
> 
> > On Tue, May 07, 2019 at 05:19:54PM +0800, Cornelia Huck wrote:
> > > On Sun,  5 May 2019 21:49:04 -0400
> > > Yan Zhao  wrote:
> > >   
> > > > version attribute is used to check two mdev devices' compatibility.
> > > > 
> > > > The key point of this version attribute is that it's rw.
> > > > User space has no need to understand internal of device version and no
> > > > need to compare versions by itself.
> > > > Compared to reading version strings from both two mdev devices being
> > > > checked, user space only reads from one mdev device's version attribute.
> > > > After getting its version string, user space writes this string into the
> > > > other mdev device's version attribute. Vendor driver of mdev device
> > > > whose version attribute being written will check device compatibility of
> > > > the two mdev devices for user space and return success for compatibility
> > > > or errno for incompatibility.  
> > > 
> > > I'm still missing a bit _what_ is actually supposed to be
> > > compatible/incompatible. I'd assume some internal state descriptions
> > > (even if this is not actually limited to migration).
> > >  
> > right.
> > originally, I thought this attribute should only contain a device's hardware
> > compatibility info. But seems also including vendor specific software 
> > migration
> > version is more reasonable, because general VFIO migration code cannot know
> > version of vendor specific software migration code until migration data is
> > transferring to the target vm. Then renaming it to migration_version is more
> > appropriate.
> > :)
> 
> Nod.
> 
> (...)
> 
> > > > @@ -246,6 +249,143 @@ Directories and files under the sysfs for Each 
> > > > Physical Device
> > > >This attribute should show the number of devices of type  
> > > > that can be
> > > >created.
> > > >  
> > > > +* version
> > > > +
> > > > +  This attribute is rw, and is optional.
> > > > +  It is used to check device compatibility between two mdev devices 
> > > > and is
> > > > +  accessed in pairs between the two mdev devices being checked.
> > > > +  The intent of this attribute is to make an mdev device's version 
> > > > opaque to
> > > > +  user space, so instead of reading two mdev devices' version strings 
> > > > and
> > > > +  comparing in userspace, user space should only read one mdev 
> > > > device's version
> > > > +  attribute, and writes this version string into the other mdev 
> > > > device's version
> > > > +  attribute. Then vendor driver of mdev device whose version attribute 
> > > > being
> > > > +  written would check the incoming version string and tell user space 
> > > > whether
> > > > +  the two mdev devices are compatible via return value. That's why this
> > > > +  attribute is writable.  
> > > 
> > > I would reword this a bit:
> > > 
> > > "This attribute provides a way to check device compatibility between
> > > two mdev devices from userspace. The intended usage is for userspace to
> > > read the version attribute from one mdev device and then writing that
> > > value to the version attribute of the other mdev device. The second
> > > mdev device indicates compatibility via the return code of the write
> > > operation. This makes compatibility between mdev devices completely
> > > vendor-defined and opaque to userspace."
> > > 
> > > We still should explain _what_ compatibility we're talking about here,
> > > though.
> > >   
> > Thanks. It's much better than mine:) 
> > Then I'll change compatibility --> migration compatibility.
> 
> Ok, with that it should be clear enough.
> 
> > 
> > > > +
> > > > +  when reading this attribute, it should show device version string of
> > > > +  the device of type .
> > > > +
> > > > +  This string is private to vendor driver itself. Vendor driver is 
> > > > able to
> > > > +  freely define format and length of device version string.
> > > > +  e.g. It can use a combination of pciid of parent device + mdev type.
> > > > +
> > > > +  When writing a string to this attribute, vendor driver should 
> > > > analyze this
> > > > +  string and check whether the mdev device being identified by this 
> > > > string is
> > > > +  compatible with the mdev device for this attribute. vendor driver 
> > > > should then
> > > > +  return written string's length if it regards the two mdev devices are
> > > > +  compatible; vendor driver should return negative errno if it regards 
> > > > the two
> > > > +  mdev devices are not compatible.
> > > > +
> > > > +  User space should treat ANY of below conditions as two mdev devices 
> > > > not
> > > > +  compatible:
> > > > +  (1) any one of the two mdev devices does not have a version attribute
> > > > +  (2) error when read from one mdev device's version attribute  
> > > 
> > > s/read/reading/
> > >   
> > > > +  (3) error when write one mdev device's version string to the other 
> 

Re: [Qemu-devel] [PATCH 3/3] ramfb enhancement

2019-05-09 Thread Hou Qiming
> Please format the commit subject with a prefix and do not use the same
> subject for all the pacthes
> in the series, for this patch it can be something like:

I'll resend the patches with improved title lines after other issues are
cleared. Thanks for the advice.

> Will this result in a silent failure? So we need to add something to the
> log?

Based on my experience with OVMF, the "silent failure" only happens when
the firmware is malicious. In the current workflow, the only failure modes
are:
- The firmware does not support ramfb, in which case the patch is never
reached
- The firmware fails to allocate a big framebuffer, in which case it writes
log to the serial and hangs / reboots, likely before reaching the patch

If you insist, I can add a log. I need to ask though, what is the standard
way to change something in [PATCH 1/3]? I've never done it before and there
doesn't seem to be an easy git command for that.

> It is actually a cool feature, changing the resolution following a
> display window
> resize, but sadly is not stable enough. Let's hope it will be fixed
someday.

I agree. It's kind of hard to validate everything properly...

Then again, ramfb is not exactly efficient (requiring a full screen
glTexSubImage2D every frame). After the boot screen, I feel it's better to
leave such fancy features to GVT / virtio-gl / ...

> Write an initial resolution to the configuration space on guest reset,
> > which a later BIOS / OVMF patch can take advantage of.
> >
>
I like the idea of moving the ramfb configuration to the PCI
> configuration space,
> do you think is possible to move all the ramfb configuration there so we
> will
> not need the fw-config file?
> ()
>

I need to clarify that when I say "configuration space", I mean the
fw-config file. What I did is to initialize that fw-config content to the
resolution specified on the command line instead of all-zeros.

ramfb is not a PCI device and I don't think it's possible to move its
configuration there. Even when it's attached to vfio-pci, it's technically
a separate thing from the guest's POV.

Is this chunk related to this patch? If not, you may want to split it.
>

Yes. That last chunk lets the user specify an initial resolution without an
EDID when ramfb is created as `-device vfio-pci,ramfb=on`. It can be useful
when debugging GPU passthrough in EFI shell or the Windows Recovery thing
(which shows up in ramfb).

Qiming


Re: [Qemu-devel] [PATCH 0/3] Optimize COLO related codes and description

2019-05-09 Thread Zhang, Chen
Hi Dave,

I noticed that you have reviewed all the patches in this series, can you queue 
it?

Thanks
Zhang Chen


> -Original Message-
> From: Zhang, Chen
> Sent: Friday, April 26, 2019 5:07 PM
> To: Laurent Vivier ; Dr. David Alan Gilbert
> ; Juan Quintela ; zhanghailiang
> ; Markus Armbruster
> ; qemu-dev 
> Cc: Zhang Chen ; Zhang, Chen 
> Subject: [PATCH 0/3] Optimize COLO related codes and description
> 
> From: Zhang Chen 
> 
> In this series we optimize codes and fix some tiny issues.
> 
> Zhang Chen (3):
>   migration/colo.c: Remove redundant input parameter
>   migration/colo.h: Remove obsolete codes
>   qemu-option.hx: Update missed parameter for colo-compare
> 
>  include/migration/colo.h  | 4 +---
>  migration/colo-failover.c | 2 +-
>  migration/colo.c  | 2 +-
>  qemu-options.hx   | 9 ++---
>  4 files changed, 9 insertions(+), 8 deletions(-)
> 
> --
> 2.17.GIT




[Qemu-devel] [PATCH v5 22/24] target/arm: Implement ARMv8.5-RNG

2019-05-09 Thread Richard Henderson
Cc: qemu-...@nongnu.org
Cc: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v3: Log errors with -d unimp, for lack of a better flag.
---
 target/arm/cpu.h|  5 +
 target/arm/cpu64.c  |  1 +
 target/arm/helper.c | 44 
 3 files changed, 50 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 892f9a4ad2..c34207611b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3521,6 +3521,11 @@ static inline bool isar_feature_aa64_condm_5(const 
ARMISARegisters *id)
 return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
 }
 
+static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
+{
+return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
+}
+
 static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 228906f267..835f73cceb 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -310,6 +310,7 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
 t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
 t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
+t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
 cpu->isar.id_aa64isar0 = t;
 
 t = cpu->isar.id_aa64isar1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7e88b2cadd..9642070194 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -22,6 +22,8 @@
 #include "fpu/softfloat.h"
 #include "qemu/range.h"
 #include "qapi/qapi-commands-target.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 #define ARM_CPU_FREQ 10 /* FIXME: 1 GHz, should be configurable */
 
@@ -5746,6 +5748,45 @@ static const ARMCPRegInfo pauth_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
 REGINFO_SENTINEL
 };
+
+static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+Error *err = NULL;
+uint64_t ret;
+
+/* Success sets NZCV = .  */
+env->NF = env->CF = env->VF = 0, env->ZF = 1;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+/*
+ * ??? Failed, for unknown reasons in the crypto subsystem.
+ * The best we can do is log the reason and return the
+ * timed-out indication to the guest.  There is no reason
+ * we know to expect this failure to be transitory, so the
+ * guest may well hang retrying the operation.
+ */
+qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
+  ri->name, error_get_pretty(err));
+error_free(err);
+
+env->ZF = 0; /* NZCF = 0100 */
+return 0;
+}
+return ret;
+}
+
+/* We do not support re-seeding, so the two registers operate the same.  */
+static const ARMCPRegInfo rndr_reginfo[] = {
+{ .name = "RNDR", .state = ARM_CP_STATE_AA64,
+  .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
+  .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
+  .access = PL0_R, .readfn = rndr_readfn },
+{ .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
+  .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
+  .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
+  .access = PL0_R, .readfn = rndr_readfn },
+REGINFO_SENTINEL
+};
 #endif
 
 static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -6690,6 +6731,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 define_arm_cp_regs(cpu, pauth_reginfo);
 }
+if (cpu_isar_feature(aa64_rndr, cpu)) {
+define_arm_cp_regs(cpu, rndr_reginfo);
+}
 #endif
 
 /*
-- 
2.17.1




[Qemu-devel] [PATCH v5 03/24] crypto: Reverse code blocks in random-platform.c

2019-05-09 Thread Richard Henderson
Use #ifdef _WIN32 instead of #ifndef _WIN32.
This will make other tests easier to sequence.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 35 +--
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 7541b4cae7..f995fc0ef1 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -32,7 +32,14 @@ static int fd; /* a file handle to either /dev/urandom or 
/dev/random */
 
 int qcrypto_random_init(Error **errp)
 {
-#ifndef _WIN32
+#ifdef _WIN32
+if (!CryptAcquireContext(, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
+error_setg_win32(errp, GetLastError(),
+ "Unable to create cryptographic provider");
+return -1;
+}
+#else
 /* TBD perhaps also add support for BSD getentropy / Linux
  * getrandom syscalls directly */
 fd = open("/dev/urandom", O_RDONLY);
@@ -44,15 +51,7 @@ int qcrypto_random_init(Error **errp)
 error_setg(errp, "No /dev/urandom or /dev/random found");
 return -1;
 }
-#else
-if (!CryptAcquireContext(, NULL, NULL, PROV_RSA_FULL,
- CRYPT_SILENT | CRYPT_VERIFYCONTEXT)) {
-error_setg_win32(errp, GetLastError(),
- "Unable to create cryptographic provider");
-return -1;
-}
 #endif
-
 return 0;
 }
 
@@ -60,7 +59,15 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
  size_t buflen G_GNUC_UNUSED,
  Error **errp)
 {
-#ifndef _WIN32
+#ifdef _WIN32
+if (!CryptGenRandom(hCryptProv, buflen, buf)) {
+error_setg_win32(errp, GetLastError(),
+ "Unable to read random bytes");
+return -1;
+}
+
+return 0;
+#else
 int ret = -1;
 int got;
 
@@ -82,13 +89,5 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
 ret = 0;
  cleanup:
 return ret;
-#else
-if (!CryptGenRandom(hCryptProv, buflen, buf)) {
-error_setg_win32(errp, GetLastError(),
- "Unable to read random bytes");
-return -1;
-}
-
-return 0;
 #endif
 }
-- 
2.17.1




[Qemu-devel] [PATCH v5 01/24] configure: Link test before auto-enabling crypto libraries

2019-05-09 Thread Richard Henderson
At least ubuntu 18.04 does not package static gnutls libraries.
At least Fedora 30 does not ship static nettle and gcrypt libraries.

Signed-off-by: Richard Henderson 
---
v5: Include nettle, gcrypt.
---
 configure | 72 +--
 1 file changed, 44 insertions(+), 28 deletions(-)

diff --git a/configure b/configure
index 63f312bd1f..c4f27ed453 100755
--- a/configure
+++ b/configure
@@ -2784,17 +2784,24 @@ fi
 # GNUTLS probe
 
 if test "$gnutls" != "no"; then
+pass="no"
 if $pkg_config --exists "gnutls >= 3.1.18"; then
 gnutls_cflags=$($pkg_config --cflags gnutls)
 gnutls_libs=$($pkg_config --libs gnutls)
-libs_softmmu="$gnutls_libs $libs_softmmu"
-libs_tools="$gnutls_libs $libs_tools"
-   QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
-gnutls="yes"
-elif test "$gnutls" = "yes"; then
+# Packaging for the static libraries is not always correct.
+# At least ubuntu 18.04 ships only shared libraries.
+write_c_skeleton
+if compile_prog "" "$gnutls_libs" ; then
+libs_softmmu="$gnutls_libs $libs_softmmu"
+libs_tools="$gnutls_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
+pass="yes"
+fi
+fi
+if test "$pass" = "no" && test "$gnutls" = "yes"; then
feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
 else
-gnutls="no"
+gnutls="$pass"
 fi
 fi
 
@@ -2849,43 +2856,54 @@ has_libgcrypt() {
 
 
 if test "$nettle" != "no"; then
+pass="no"
 if $pkg_config --exists "nettle >= 2.7.1"; then
 nettle_cflags=$($pkg_config --cflags nettle)
 nettle_libs=$($pkg_config --libs nettle)
 nettle_version=$($pkg_config --modversion nettle)
-libs_softmmu="$nettle_libs $libs_softmmu"
-libs_tools="$nettle_libs $libs_tools"
-QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
-nettle="yes"
-
-if test -z "$gcrypt"; then
-   gcrypt="no"
+# Link test to make sure the given libraries work (e.g for static).
+write_c_skeleton
+if compile_prog "" "$nettle_libs" ; then
+libs_softmmu="$nettle_libs $libs_softmmu"
+libs_tools="$nettle_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+if test -z "$gcrypt"; then
+   gcrypt="no"
+fi
+pass="yes"
 fi
+fi
+if test "$pass" = "no" && test "$nettle" = "yes"; then
+feature_not_found "nettle" "Install nettle devel >= 2.7.1"
 else
-if test "$nettle" = "yes"; then
-feature_not_found "nettle" "Install nettle devel >= 2.7.1"
-else
-nettle="no"
-fi
+nettle="$pass"
 fi
 fi
 
 if test "$gcrypt" != "no"; then
+pass="no"
 if has_libgcrypt; then
 gcrypt_cflags=$(libgcrypt-config --cflags)
 gcrypt_libs=$(libgcrypt-config --libs)
-# Debian has remove -lgpg-error from libgcrypt-config
+# Debian has removed -lgpg-error from libgcrypt-config
 # as it "spreads unnecessary dependencies" which in
 # turn breaks static builds...
 if test "$static" = "yes"
 then
 gcrypt_libs="$gcrypt_libs -lgpg-error"
 fi
-libs_softmmu="$gcrypt_libs $libs_softmmu"
-libs_tools="$gcrypt_libs $libs_tools"
-QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
-gcrypt="yes"
 
+# Link test to make sure the given libraries work (e.g for static).
+write_c_skeleton
+if compile_prog "" "$gcrypt_libs" ; then
+libs_softmmu="$gcrypt_libs $libs_softmmu"
+libs_tools="$gcrypt_libs $libs_tools"
+QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
+pass="yes"
+fi
+fi
+if test "$pass" = "yes"; then
+gcrypt="yes"
 cat > $TMPC << EOF
 #include 
 int main(void) {
@@ -2898,12 +2916,10 @@ EOF
 if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
 gcrypt_hmac=yes
 fi
+elif test "$gcrypt" = "yes"; then
+feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
 else
-if test "$gcrypt" = "yes"; then
-feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
-else
-gcrypt="no"
-fi
+gcrypt="no"
 fi
 fi
 
-- 
2.17.1




[Qemu-devel] [PATCH v5 10/24] util: Add qemu_guest_getrandom and associated routines

2019-05-09 Thread Richard Henderson
This routine is intended to produce high-quality random numbers to the
guest.  Normally, such numbers are crypto quality from the host, but a
command-line option can force the use of a fully deterministic sequence
for use while debugging.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/qemu/guest-random.h | 68 +++
 util/guest-random.c | 93 +
 util/Makefile.objs  |  1 +
 3 files changed, 162 insertions(+)
 create mode 100644 include/qemu/guest-random.h
 create mode 100644 util/guest-random.c

diff --git a/include/qemu/guest-random.h b/include/qemu/guest-random.h
new file mode 100644
index 00..09ff9c2236
--- /dev/null
+++ b/include/qemu/guest-random.h
@@ -0,0 +1,68 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef QEMU_GUEST_RANDOM_H
+#define QEMU_GUEST_RANDOM_H
+
+/**
+ * qemu_guest_random_seed_main(const char *optarg, Error **errp)
+ * @optarg: a non-NULL pointer to a C string
+ * @errp: an error indicator
+ *
+ * The @optarg value is that which accompanies the -seed argument.
+ * This forces qemu_guest_getrandom into deterministic mode.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_random_seed_main(const char *optarg, Error **errp);
+
+/**
+ * qemu_guest_random_seed_thread_part1(void)
+ *
+ * If qemu_getrandom is in deterministic mode, returns an
+ * independent seed for the new thread.  Otherwise returns 0.
+ */
+uint64_t qemu_guest_random_seed_thread_part1(void);
+
+/**
+ * qemu_guest_random_seed_thread_part2(uint64_t seed)
+ * @seed: a value for the new thread.
+ *
+ * If qemu_guest_getrandom is in deterministic mode, this stores an
+ * independent seed for the new thread.  Otherwise a no-op.
+ */
+void qemu_guest_random_seed_thread_part2(uint64_t seed);
+
+/**
+ * qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ * @errp: an error indicator
+ *
+ * Fills len bytes in buf with random data.  This should only be used
+ * for data presented to the guest.  Host-side crypto services should
+ * use qcrypto_random_bytes.
+ *
+ * Returns 0 on success, < 0 on failure while setting *errp.
+ */
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp);
+
+/**
+ * qemu_guest_getrandom_nofail(void *buf, size_t len)
+ * @buf: a buffer of bytes to be written
+ * @len: the number of bytes in @buf
+ *
+ * Like qemu_guest_getrandom, but will assert for failure.
+ * Use this when there is no reasonable recovery.
+ */
+void qemu_guest_getrandom_nofail(void *buf, size_t len);
+
+#endif /* QEMU_GUEST_RANDOM_H */
diff --git a/util/guest-random.c b/util/guest-random.c
new file mode 100644
index 00..e8124a3cad
--- /dev/null
+++ b/util/guest-random.c
@@ -0,0 +1,93 @@
+/*
+ * QEMU guest-visible random functions
+ *
+ * Copyright 2019 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
+#include "crypto/random.h"
+
+
+static __thread GRand *thread_rand;
+static bool deterministic;
+
+
+static int glib_random_bytes(void *buf, size_t len)
+{
+GRand *rand = thread_rand;
+size_t i;
+uint32_t x;
+
+if (unlikely(rand == NULL)) {
+/* Thread not initialized for a cpu, or main w/o -seed.  */
+thread_rand = rand = g_rand_new();
+}
+
+for (i = 0; i + 4 <= len; i += 4) {
+x = g_rand_int(rand);
+__builtin_memcpy(buf + i, , 4);
+}
+if (i < len) {
+x = g_rand_int(rand);
+__builtin_memcpy(buf + i, , i - len);
+}
+return 0;
+}
+
+int qemu_guest_getrandom(void *buf, size_t len, Error **errp)
+{
+if (unlikely(deterministic)) {
+/* Deterministic implementation using Glib's Mersenne Twister.  */
+return glib_random_bytes(buf, len);
+} else {
+/* Non-deterministic implementation using crypto routines.  */
+return qcrypto_random_bytes(buf, len, errp);
+}
+}
+
+void qemu_guest_getrandom_nofail(void *buf, size_t len)
+{
+qemu_guest_getrandom(buf, len, _fatal);
+}
+
+uint64_t qemu_guest_random_seed_thread_part1(void)
+{
+if (deterministic) {
+uint64_t ret;
+glib_random_bytes(, sizeof(ret));
+return ret;
+}
+

[Qemu-devel] [PATCH v5 16/24] linux-user: Remove srand call

2019-05-09 Thread Richard Henderson
We no longer use rand() within linux-user.

Cc: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index e455bff1b7..5d1c6a115b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -623,8 +623,6 @@ int main(int argc, char **argv, char **envp)
 
 cpu_model = NULL;
 
-srand(time(NULL));
-
 qemu_add_opts(_trace_opts);
 
 optind = parse_args(argc, argv);
@@ -692,15 +690,6 @@ int main(int argc, char **argv, char **envp)
 {
 Error *err = NULL;
 if (seed_optarg != NULL) {
-unsigned long long seed;
-
-/* This will go away with the last user of rand(). */
-if (parse_uint_full(seed_optarg, , 0) != 0) {
-fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
-exit(EXIT_FAILURE);
-}
-srand(seed);
-
 qemu_guest_random_seed_main(seed_optarg, );
 } else {
 /* ??? Assumes qcrypto is only used by qemu_guest_getrandom.  */
-- 
2.17.1




[Qemu-devel] [PATCH v5 21/24] target/arm: Put all PAC keys into a structure

2019-05-09 Thread Richard Henderson
This allows us to use a single syscall to initialize them all.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h  | 12 +++-
 linux-user/aarch64/cpu_loop.c |  6 +-
 linux-user/syscall.c  | 10 +-
 target/arm/helper.c   | 20 ++--
 target/arm/pauth_helper.c | 18 +-
 5 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 733b840a71..892f9a4ad2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -636,11 +636,13 @@ typedef struct CPUARMState {
 } iwmmxt;
 
 #ifdef TARGET_AARCH64
-ARMPACKey apia_key;
-ARMPACKey apib_key;
-ARMPACKey apda_key;
-ARMPACKey apdb_key;
-ARMPACKey apga_key;
+struct {
+ARMPACKey apia;
+ARMPACKey apib;
+ARMPACKey apda;
+ARMPACKey apdb;
+ARMPACKey apga;
+} keys;
 #endif
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index cedad39ca0..2f2f63e3e8 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -175,11 +175,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 #endif
 
 if (cpu_isar_feature(aa64_pauth, cpu)) {
-qemu_guest_getrandom_nofail(>apia_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apib_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apda_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apdb_key, sizeof(ARMPACKey));
-qemu_guest_getrandom_nofail(>apga_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>keys, sizeof(env->keys));
 }
 
 ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b73d1d9f65..3c26f6f9d4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9734,23 +9734,23 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return -TARGET_EINVAL;
 }
 if (arg2 & TARGET_PR_PAC_APIAKEY) {
-ret |= qemu_guest_getrandom(>apia_key,
+ret |= qemu_guest_getrandom(>keys.apia,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APIBKEY) {
-ret |= qemu_guest_getrandom(>apib_key,
+ret |= qemu_guest_getrandom(>keys.apib,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDAKEY) {
-ret |= qemu_guest_getrandom(>apda_key,
+ret |= qemu_guest_getrandom(>keys.apda,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDBKEY) {
-ret |= qemu_guest_getrandom(>apdb_key,
+ret |= qemu_guest_getrandom(>keys.apdb,
 sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APGAKEY) {
-ret |= qemu_guest_getrandom(>apga_key,
+ret |= qemu_guest_getrandom(>keys.apga,
 sizeof(ARMPACKey), );
 }
 if (ret != 0) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1e6eb0d0f3..7e88b2cadd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5707,43 +5707,43 @@ static const ARMCPRegInfo pauth_reginfo[] = {
 { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
+  .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
 { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
+  .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
 { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
+  .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
 { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
   .access = PL1_RW, .accessfn = access_pauth,
-  .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
+  .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
 { .name = "APGAKEYLO_EL1", .state = 

[Qemu-devel] [PATCH v5 17/24] aspeed/scu: Use qemu_guest_getrandom_nofail

2019-05-09 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of rolling our own error handling locally.

Cc: qemu-...@nongnu.org
Cc: Andrew Jeffery 
Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
Signed-off-by: Richard Henderson 
---
 hw/misc/aspeed_scu.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index c8217740ef..ab1e18ed4b 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -16,7 +16,7 @@
 #include "qapi/visitor.h"
 #include "qemu/bitops.h"
 #include "qemu/log.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 #include "trace.h"
 
 #define TO_REG(offset) ((offset) >> 2)
@@ -157,14 +157,8 @@ static const uint32_t 
ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
 
 static uint32_t aspeed_scu_get_random(void)
 {
-Error *err = NULL;
 uint32_t num;
-
-if (qcrypto_random_bytes((uint8_t *), sizeof(num), )) {
-error_report_err(err);
-exit(1);
-}
-
+qemu_guest_getrandom_nofail(, sizeof(num));
 return num;
 }
 
-- 
2.17.1




[Qemu-devel] [PATCH v5 19/24] hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail

2019-05-09 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of rolling our own error handling locally.

Cc: qemu-...@nongnu.org
Cc: Andrew Baumann 
Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 hw/misc/bcm2835_rng.c | 32 ++--
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/hw/misc/bcm2835_rng.c b/hw/misc/bcm2835_rng.c
index 4d62143b24..fe59c868f5 100644
--- a/hw/misc/bcm2835_rng.c
+++ b/hw/misc/bcm2835_rng.c
@@ -9,30 +9,26 @@
 
 #include "qemu/osdep.h"
 #include "qemu/log.h"
-#include "qapi/error.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 #include "hw/misc/bcm2835_rng.h"
 
 static uint32_t get_random_bytes(void)
 {
 uint32_t res;
-Error *err = NULL;
 
-if (qcrypto_random_bytes((uint8_t *), sizeof(res), ) < 0) {
-/* On failure we don't want to return the guest a non-random
- * value in case they're really using it for cryptographic
- * purposes, so the best we can do is die here.
- * This shouldn't happen unless something's broken.
- * In theory we could implement this device's full FIFO
- * and interrupt semantics and then just stop filling the
- * FIFO. That's a lot of work, though, so we assume any
- * errors are systematic problems and trust that if we didn't
- * fail as the guest inited then we won't fail later on
- * mid-run.
- */
-error_report_err(err);
-exit(1);
-}
+/*
+ * On failure we don't want to return the guest a non-random
+ * value in case they're really using it for cryptographic
+ * purposes, so the best we can do is die here.
+ * This shouldn't happen unless something's broken.
+ * In theory we could implement this device's full FIFO
+ * and interrupt semantics and then just stop filling the
+ * FIFO. That's a lot of work, though, so we assume any
+ * errors are systematic problems and trust that if we didn't
+ * fail as the guest inited then we won't fail later on
+ * mid-run.
+ */
+qemu_guest_getrandom_nofail(, sizeof(res));
 return res;
 }
 
-- 
2.17.1




[Qemu-devel] [PATCH v5 08/24] ui/vnc: Split out authentication_failed

2019-05-09 Thread Richard Henderson
There were 3 copies of this code, one of which used the wrong
data size for the failure indicator.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Gerd Hoffmann 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 ui/vnc.c | 37 +++--
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 1871422e1d..785edf3af1 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2535,6 +2535,18 @@ void start_client_init(VncState *vs)
 vnc_read_when(vs, protocol_client_init, 1);
 }
 
+static void authentication_failed(VncState *vs)
+{
+vnc_write_u32(vs, 1); /* Reject auth */
+if (vs->minor >= 8) {
+static const char err[] = "Authentication failed";
+vnc_write_u32(vs, sizeof(err));
+vnc_write(vs, err, sizeof(err));
+}
+vnc_flush(vs);
+vnc_client_error(vs);
+}
+
 static void make_challenge(VncState *vs)
 {
 int i;
@@ -2609,14 +2621,7 @@ static int protocol_client_auth_vnc(VncState *vs, 
uint8_t *data, size_t len)
 return 0;
 
 reject:
-vnc_write_u32(vs, 1); /* Reject auth */
-if (vs->minor >= 8) {
-static const char err[] = "Authentication failed";
-vnc_write_u32(vs, sizeof(err));
-vnc_write(vs, err, sizeof(err));
-}
-vnc_flush(vs);
-vnc_client_error(vs);
+authentication_failed(vs);
 qcrypto_cipher_free(cipher);
 return 0;
 }
@@ -2638,13 +2643,7 @@ static int protocol_client_auth(VncState *vs, uint8_t 
*data, size_t len)
  * must pick the one we sent. Verify this */
 if (data[0] != vs->auth) { /* Reject auth */
trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
-   vnc_write_u32(vs, 1);
-   if (vs->minor >= 8) {
-   static const char err[] = "Authentication failed";
-   vnc_write_u32(vs, sizeof(err));
-   vnc_write(vs, err, sizeof(err));
-   }
-   vnc_client_error(vs);
+   authentication_failed(vs);
 } else { /* Accept requested auth */
trace_vnc_auth_start(vs, vs->auth);
switch (vs->auth) {
@@ -2673,13 +2672,7 @@ static int protocol_client_auth(VncState *vs, uint8_t 
*data, size_t len)
 
default: /* Should not be possible, but just in case */
trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
-   vnc_write_u8(vs, 1);
-   if (vs->minor >= 8) {
-   static const char err[] = "Authentication failed";
-   vnc_write_u32(vs, sizeof(err));
-   vnc_write(vs, err, sizeof(err));
-   }
-   vnc_client_error(vs);
+   authentication_failed(vs);
}
 }
 return 0;
-- 
2.17.1




[Qemu-devel] [PATCH v5 18/24] hw/misc/nrf51_rng: Use qemu_guest_getrandom_nofail

2019-05-09 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.  Use the *_nofail routine
instead of error_abort directly.

Cc: qemu-...@nongnu.org
Reviewed-by: Laurent Vivier 
Reviewed-by: Joel Stanley 
Signed-off-by: Richard Henderson 
---
 hw/misc/nrf51_rng.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
index d188f044f4..3400e90a9b 100644
--- a/hw/misc/nrf51_rng.c
+++ b/hw/misc/nrf51_rng.c
@@ -14,7 +14,7 @@
 #include "qapi/error.h"
 #include "hw/arm/nrf51.h"
 #include "hw/misc/nrf51_rng.h"
-#include "crypto/random.h"
+#include "qemu/guest-random.h"
 
 static void update_irq(NRF51RNGState *s)
 {
@@ -145,7 +145,7 @@ static void nrf51_rng_timer_expire(void *opaque)
 {
 NRF51RNGState *s = NRF51_RNG(opaque);
 
-qcrypto_random_bytes(>value, 1, _abort);
+qemu_guest_getrandom_nofail(>value, 1);
 
 s->event_valrdy = 1;
 qemu_set_irq(s->eep_valrdy, 1);
-- 
2.17.1




[Qemu-devel] [PATCH v5 15/24] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys

2019-05-09 Thread Richard Henderson
Use a better interface for random numbers than rand() * 3.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  2 --
 linux-user/aarch64/cpu_loop.c   | 29 ++-
 linux-user/syscall.c| 31 -
 3 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index b595e5da82..995e475c73 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -29,6 +29,4 @@ struct target_pt_regs {
 # define TARGET_PR_PAC_APDBKEY   (1 << 3)
 # define TARGET_PR_PAC_APGAKEY   (1 << 4)
 
-void arm_init_pauth_key(ARMPACKey *key);
-
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index d75fd9d3e2..cedad39ca0 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu.h"
 #include "cpu_loop-common.h"
+#include "qemu/guest-random.h"
 
 #define get_user_code_u32(x, gaddr, env)\
 ({ abi_long __r = get_user_u32((x), (gaddr));   \
@@ -147,24 +148,6 @@ void cpu_loop(CPUARMState *env)
 }
 }
 
-static uint64_t arm_rand64(void)
-{
-int shift = 64 - clz64(RAND_MAX);
-int i, n = 64 / shift + (64 % shift != 0);
-uint64_t ret = 0;
-
-for (i = 0; i < n; i++) {
-ret = (ret << shift) | rand();
-}
-return ret;
-}
-
-void arm_init_pauth_key(ARMPACKey *key)
-{
-key->lo = arm_rand64();
-key->hi = arm_rand64();
-}
-
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
 ARMCPU *cpu = arm_env_get_cpu(env);
@@ -192,11 +175,11 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 #endif
 
 if (cpu_isar_feature(aa64_pauth, cpu)) {
-arm_init_pauth_key(>apia_key);
-arm_init_pauth_key(>apib_key);
-arm_init_pauth_key(>apda_key);
-arm_init_pauth_key(>apdb_key);
-arm_init_pauth_key(>apga_key);
+qemu_guest_getrandom_nofail(>apia_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apib_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apda_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apdb_key, sizeof(ARMPACKey));
+qemu_guest_getrandom_nofail(>apga_key, sizeof(ARMPACKey));
 }
 
 ts->stack_base = info->start_stack;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce377b2fc1..b73d1d9f65 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -111,6 +111,7 @@
 
 #include "qemu.h"
 #include "qemu/guest-random.h"
+#include "qapi/error.h"
 #include "fd-trans.h"
 
 #ifndef CLONE_IO
@@ -9724,25 +9725,45 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
TARGET_PR_PAC_APGAKEY);
+int ret = 0;
+Error *err = NULL;
+
 if (arg2 == 0) {
 arg2 = all;
 } else if (arg2 & ~all) {
 return -TARGET_EINVAL;
 }
 if (arg2 & TARGET_PR_PAC_APIAKEY) {
-arm_init_pauth_key(>apia_key);
+ret |= qemu_guest_getrandom(>apia_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APIBKEY) {
-arm_init_pauth_key(>apib_key);
+ret |= qemu_guest_getrandom(>apib_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDAKEY) {
-arm_init_pauth_key(>apda_key);
+ret |= qemu_guest_getrandom(>apda_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APDBKEY) {
-arm_init_pauth_key(>apdb_key);
+ret |= qemu_guest_getrandom(>apdb_key,
+sizeof(ARMPACKey), );
 }
 if (arg2 & TARGET_PR_PAC_APGAKEY) {
-arm_init_pauth_key(>apga_key);
+ret |= qemu_guest_getrandom(>apga_key,
+sizeof(ARMPACKey), );
+}
+if (ret != 0) {
+/*
+ * Some unknown failure in the crypto.  The best
+ * we can do is log it and fail the syscall.
+  

[Qemu-devel] [PATCH v5 11/24] cpus: Initialize pseudo-random seeds for all guest cpus

2019-05-09 Thread Richard Henderson
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode.  Pass derived seeds
to each cpu created; which is a no-op unless the subsystem is in
deterministic mode.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/qom/cpu.h |  1 +
 cpus.c|  9 +
 vl.c  |  4 
 qemu-options.hx   | 10 ++
 4 files changed, 24 insertions(+)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 08abcbd3fe..9793ec39bc 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -369,6 +369,7 @@ struct CPUState {
 int singlestep_enabled;
 int64_t icount_budget;
 int64_t icount_extra;
+uint64_t random_seed;
 sigjmp_buf jmp_env;
 
 QemuMutex work_mutex;
diff --git a/cpus.c b/cpus.c
index e58e7ab0f6..ffc57119ca 100644
--- a/cpus.c
+++ b/cpus.c
@@ -50,6 +50,7 @@
 #include "qemu/option.h"
 #include "qemu/bitmap.h"
 #include "qemu/seqlock.h"
+#include "qemu/guest-random.h"
 #include "tcg.h"
 #include "hw/nmi.h"
 #include "sysemu/replay.h"
@@ -1276,6 +1277,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1319,6 +1321,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 qemu_mutex_unlock_iothread();
@@ -1478,6 +1481,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
 cpu->created = true;
 cpu->can_do_io = 1;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 /* wait for initial kick-off after machine start */
 while (first_cpu->stopped) {
@@ -1592,6 +1596,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
 
 hax_init_vcpu(cpu);
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1631,6 +1636,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1671,6 +1677,7 @@ static void *qemu_whpx_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 cpu->created = true;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 do {
 if (cpu_can_run(cpu)) {
@@ -1724,6 +1731,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 cpu->can_do_io = 1;
 current_cpu = cpu;
 qemu_cond_signal(_cpu_cond);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
 /* process any pending work */
 cpu->exit_request = 1;
@@ -2071,6 +2079,7 @@ void qemu_init_vcpu(CPUState *cpu)
 cpu->nr_cores = smp_cores;
 cpu->nr_threads = smp_threads;
 cpu->stopped = true;
+cpu->random_seed = qemu_guest_random_seed_thread_part1();
 
 if (!cpu->as) {
 /* If the target cpu hasn't set up any address spaces itself,
diff --git a/vl.c b/vl.c
index b6709514c1..e1d75a047f 100644
--- a/vl.c
+++ b/vl.c
@@ -128,6 +128,7 @@ int main(int argc, char **argv)
 #include "qapi/qapi-commands-ui.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/iothread.h"
+#include "qemu/guest-random.h"
 
 #define MAX_VIRTIO_CONSOLES 1
 
@@ -3347,6 +3348,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_DFILTER:
 qemu_set_dfilter_ranges(optarg, _fatal);
 break;
+case QEMU_OPTION_seed:
+qemu_guest_random_seed_main(optarg, _fatal);
+break;
 case QEMU_OPTION_s:
 add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
 break;
diff --git a/qemu-options.hx b/qemu-options.hx
index 51802cbb26..0191ef8b1e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3601,6 +3601,16 @@ the 0x200 sized block starting at 0xffc8 and 
another 0x1000 sized
 block starting at 0xffc5f000.
 ETEXI
 
+DEF("seed", HAS_ARG, QEMU_OPTION_seed, \
+"-seed number   seed the pseudo-random number generator\n",
+QEMU_ARCH_ALL)
+STEXI
+@item -seed @var{number}
+@findex -seed
+Force the guest to use a deterministic pseudo-random number generator, seeded
+with @var{number}.  This does not affect crypto routines within the host.
+ETEXI
+
 DEF("L", HAS_ARG, QEMU_OPTION_L, \
 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n",
 QEMU_ARCH_ALL)
-- 
2.17.1




[Qemu-devel] [PATCH v5 07/24] crypto: Change the qcrypto_random_bytes buffer type to void*

2019-05-09 Thread Richard Henderson
Using uint8_t* merely requires useless casts for use with
other types to be filled with randomness.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 include/crypto/random.h  | 2 +-
 crypto/random-gcrypt.c   | 2 +-
 crypto/random-gnutls.c   | 2 +-
 crypto/random-platform.c | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/crypto/random.h b/include/crypto/random.h
index 8764ca0562..fde592904e 100644
--- a/include/crypto/random.h
+++ b/include/crypto/random.h
@@ -34,7 +34,7 @@
  *
  * Returns 0 on success, -1 on error
  */
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp);
 
diff --git a/crypto/random-gcrypt.c b/crypto/random-gcrypt.c
index 9f1c9ee60e..7aea4ac81f 100644
--- a/crypto/random-gcrypt.c
+++ b/crypto/random-gcrypt.c
@@ -24,7 +24,7 @@
 
 #include 
 
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp G_GNUC_UNUSED)
 {
diff --git a/crypto/random-gnutls.c b/crypto/random-gnutls.c
index 445fd6a30b..ed6c9ca12f 100644
--- a/crypto/random-gnutls.c
+++ b/crypto/random-gnutls.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-int qcrypto_random_bytes(uint8_t *buf,
+int qcrypto_random_bytes(void *buf,
  size_t buflen,
  Error **errp)
 {
diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index cb3ca1bc09..66624106fe 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -64,8 +64,8 @@ int qcrypto_random_init(Error **errp)
 return 0;
 }
 
-int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
- size_t buflen G_GNUC_UNUSED,
+int qcrypto_random_bytes(void *buf,
+ size_t buflen,
  Error **errp)
 {
 #ifdef _WIN32
-- 
2.17.1




[Qemu-devel] [PATCH v5 24/24] target/i386: Implement CPUID_EXT_RDRAND

2019-05-09 Thread Richard Henderson
We now have an interface for guest visible random numbers.

Cc: Paolo Bonzini 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Richard Henderson 
---
 target/i386/helper.h |  2 ++
 target/i386/cpu.c|  5 ++--
 target/i386/int_helper.c | 21 +++
 target/i386/translate.c  | 55 +---
 4 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 6fb8fb9b74..8f9e1905c3 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -226,3 +226,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
 DEF_HELPER_3(rclq, tl, env, tl, tl)
 DEF_HELPER_3(rcrq, tl, env, tl, tl)
 #endif
+
+DEF_HELPER_1(rdrand, tl, env)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 722c5514d4..1386814957 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -730,13 +730,14 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
   CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
   CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */   \
-  CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
+  CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
+  CPUID_EXT_RDRAND)
   /* missing:
   CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
   CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
   CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
   CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
-  CPUID_EXT_F16C, CPUID_EXT_RDRAND */
+  CPUID_EXT_F16C */
 
 #ifdef TARGET_X86_64
 #define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
diff --git a/target/i386/int_helper.c b/target/i386/int_helper.c
index 4dc5c65991..334469ca8c 100644
--- a/target/i386/int_helper.c
+++ b/target/i386/int_helper.c
@@ -22,6 +22,8 @@
 #include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 //#define DEBUG_MULDIV
 
@@ -470,3 +472,22 @@ void helper_cr4_testbit(CPUX86State *env, uint32_t bit)
 raise_exception_ra(env, EXCP06_ILLOP, GETPC());
 }
 }
+
+target_ulong HELPER(rdrand)(CPUX86State *env)
+{
+Error *err = NULL;
+target_ulong ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "rdrand: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+/* Failure clears CF and all other flags, and returns 0.  */
+env->cc_src = 0;
+return 0;
+}
+
+/* Success sets CF and clears all others.  */
+env->cc_src = CC_C;
+return ret;
+}
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 77d6b73e42..62fa45d778 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5332,31 +5332,56 @@ static target_ulong disas_insn(DisasContext *s, 
CPUState *cpu)
 case 0x1c7: /* cmpxchg8b */
 modrm = x86_ldub_code(env, s);
 mod = (modrm >> 6) & 3;
-if ((mod == 3) || ((modrm & 0x38) != 0x8))
-goto illegal_op;
-#ifdef TARGET_X86_64
-if (dflag == MO_64) {
-if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
+switch ((modrm >> 3) & 7) {
+case 1: /* CMPXCHG8, CMPXCHG16 */
+if (mod == 3) {
 goto illegal_op;
-gen_lea_modrm(env, s, modrm);
-if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & 
CF_PARALLEL)) {
-gen_helper_cmpxchg16b(cpu_env, s->A0);
-} else {
-gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
 }
-} else
+#ifdef TARGET_X86_64
+if (dflag == MO_64) {
+if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
+goto illegal_op;
+}
+gen_lea_modrm(env, s, modrm);
+if ((s->prefix & PREFIX_LOCK) &&
+(tb_cflags(s->base.tb) & CF_PARALLEL)) {
+gen_helper_cmpxchg16b(cpu_env, s->A0);
+} else {
+gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
+}
+set_cc_op(s, CC_OP_EFLAGS);
+break;
+}
 #endif
-{
-if (!(s->cpuid_features & CPUID_CX8))
+if (!(s->cpuid_features & CPUID_CX8)) {
 goto illegal_op;
+}
 gen_lea_modrm(env, s, modrm);
-if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) & 
CF_PARALLEL)) {
+if ((s->prefix & PREFIX_LOCK) &&
+(tb_cflags(s->base.tb) & CF_PARALLEL)) {
 gen_helper_cmpxchg8b(cpu_env, s->A0);
 } else {
 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
 }
+set_cc_op(s, 

[Qemu-devel] [PATCH v5 14/24] linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM

2019-05-09 Thread Richard Henderson
Use a better interface for random numbers than rand * 16.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index c1a26021f8..e673f7ea55 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -7,6 +7,7 @@
 #include "qemu.h"
 #include "disas/disas.h"
 #include "qemu/path.h"
+#include "qemu/guest-random.h"
 
 #ifdef _ARCH_PPC64
 #undef ARCH_DLINFO
@@ -1883,12 +1884,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int 
argc, int envc,
 }
 
 /*
- * Generate 16 random bytes for userspace PRNG seeding (not
- * cryptically secure but it's not the aim of QEMU).
+ * Generate 16 random bytes for userspace PRNG seeding.
  */
-for (i = 0; i < 16; i++) {
-k_rand_bytes[i] = rand();
-}
+qemu_guest_getrandom_nofail(k_rand_bytes, sizeof(k_rand_bytes));
 if (STACK_GROWS_DOWN) {
 sp -= 16;
 u_rand_bytes = sp;
-- 
2.17.1




[Qemu-devel] [PATCH v5 12/24] linux-user: Initialize pseudo-random seeds for all guest cpus

2019-05-09 Thread Richard Henderson
When the -seed option is given, call qemu_guest_random_seed_main,
putting the subsystem into deterministic mode.  Pass derived seeds
to each cpu created during clone; which is a no-op unless the
subsystem is in deterministic mode.

Cc: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v5: Retain srand() until last user goes away.
---
 linux-user/main.c| 30 +++---
 linux-user/syscall.c |  3 +++
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 3d2230320b..7e704845c0 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -34,6 +34,7 @@
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
+#include "qemu/guest-random.h"
 #include "elf.h"
 #include "trace/control.h"
 #include "target_elf.h"
@@ -48,6 +49,7 @@ static int gdbstub_port;
 static envlist_t *envlist;
 static const char *cpu_model;
 static const char *cpu_type;
+static const char *seed_optarg;
 unsigned long mmap_min_addr;
 unsigned long guest_base;
 int have_guest_base;
@@ -290,15 +292,9 @@ static void handle_arg_pagesize(const char *arg)
 }
 }
 
-static void handle_arg_randseed(const char *arg)
+static void handle_arg_seed(const char *arg)
 {
-unsigned long long seed;
-
-if (parse_uint_full(arg, , 0) != 0 || seed > UINT_MAX) {
-fprintf(stderr, "Invalid seed number: %s\n", arg);
-exit(EXIT_FAILURE);
-}
-srand(seed);
+seed_optarg = arg;
 }
 
 static void handle_arg_gdb(const char *arg)
@@ -433,7 +429,7 @@ static const struct qemu_argument arg_table[] = {
  "",   "run in singlestep mode"},
 {"strace", "QEMU_STRACE",  false, handle_arg_strace,
  "",   "log system calls"},
-{"seed",   "QEMU_RAND_SEED",   true,  handle_arg_randseed,
+{"seed",   "QEMU_RAND_SEED",   true,  handle_arg_seed,
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
@@ -689,8 +685,20 @@ int main(int argc, char **argv, char **envp)
 do_strace = 1;
 }
 
-if (getenv("QEMU_RAND_SEED")) {
-handle_arg_randseed(getenv("QEMU_RAND_SEED"));
+if (seed_optarg == NULL) {
+seed_optarg = getenv("QEMU_RAND_SEED");
+}
+if (seed_optarg != NULL) {
+unsigned long long seed;
+
+/* This will go away with the last user of rand(). */
+if (parse_uint_full(seed_optarg, , 0) != 0) {
+fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+exit(EXIT_FAILURE);
+}
+srand(seed);
+
+qemu_guest_random_seed_main(seed_optarg, _fatal);
 }
 
 target_environ = envlist_to_environ(envlist, NULL);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 96cd4bf86d..ce377b2fc1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -110,6 +110,7 @@
 #include "uname.h"
 
 #include "qemu.h"
+#include "qemu/guest-random.h"
 #include "fd-trans.h"
 
 #ifndef CLONE_IO
@@ -5441,6 +5442,7 @@ static void *clone_func(void *arg)
 put_user_u32(info->tid, info->child_tidptr);
 if (info->parent_tidptr)
 put_user_u32(info->tid, info->parent_tidptr);
+qemu_guest_random_seed_thread_part2(cpu->random_seed);
 /* Enable signals.  */
 sigprocmask(SIG_SETMASK, >sigmask, NULL);
 /* Signal to the parent that we're ready.  */
@@ -5527,6 +5529,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, 
abi_ulong newsp,
initializing, so temporarily block all signals.  */
 sigfillset();
 sigprocmask(SIG_BLOCK, , );
+cpu->random_seed = qemu_guest_random_seed_thread_part1();
 
 /* If this is our first additional thread, we need to ensure we
  * generate code for parallel execution and flush old translations.
-- 
2.17.1




[Qemu-devel] [PATCH v5 13/24] linux-user: Call qcrypto_init if not using -seed

2019-05-09 Thread Richard Henderson
Cc: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 linux-user/main.c | 29 -
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 7e704845c0..e455bff1b7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -39,6 +39,7 @@
 #include "trace/control.h"
 #include "target_elf.h"
 #include "cpu_loop-common.h"
+#include "crypto/init.h"
 
 char *exec_path;
 
@@ -688,17 +689,27 @@ int main(int argc, char **argv, char **envp)
 if (seed_optarg == NULL) {
 seed_optarg = getenv("QEMU_RAND_SEED");
 }
-if (seed_optarg != NULL) {
-unsigned long long seed;
+{
+Error *err = NULL;
+if (seed_optarg != NULL) {
+unsigned long long seed;
 
-/* This will go away with the last user of rand(). */
-if (parse_uint_full(seed_optarg, , 0) != 0) {
-fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
-exit(EXIT_FAILURE);
+/* This will go away with the last user of rand(). */
+if (parse_uint_full(seed_optarg, , 0) != 0) {
+fprintf(stderr, "Invalid seed number: %s\n", seed_optarg);
+exit(EXIT_FAILURE);
+}
+srand(seed);
+
+qemu_guest_random_seed_main(seed_optarg, );
+} else {
+/* ??? Assumes qcrypto is only used by qemu_guest_getrandom.  */
+qcrypto_init();
+}
+if (err) {
+error_reportf_err(err, "cannot initialize crypto: ");
+exit(1);
 }
-srand(seed);
-
-qemu_guest_random_seed_main(seed_optarg, _fatal);
 }
 
 target_environ = envlist_to_environ(envlist, NULL);
-- 
2.17.1




[Qemu-devel] [PATCH v5 04/24] crypto: Do not fail for EINTR during qcrypto_random_bytes

2019-05-09 Thread Richard Henderson
We can always get EINTR for read; /dev/urandom is no exception.

Rearrange the order of tests for likelihood; allow degenerate buflen==0
case to perform a no-op zero-length read.  This means that the normal
success path is a straight line with a single test for success.

Reviewed-by: Laurent Vivier 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
v3: Rearrage the read loop again.
---
 crypto/random-platform.c | 36 +++-
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index f995fc0ef1..260b64564d 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -65,29 +65,23 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
  "Unable to read random bytes");
 return -1;
 }
-
-return 0;
 #else
-int ret = -1;
-int got;
-
-while (buflen > 0) {
-got = read(fd, buf, buflen);
-if (got < 0) {
-error_setg_errno(errp, errno,
- "Unable to read random bytes");
-goto cleanup;
-} else if (!got) {
-error_setg(errp,
-   "Unexpected EOF reading random bytes");
-goto cleanup;
+while (1) {
+ssize_t got = read(fd, buf, buflen);
+if (likely(got == buflen)) {
+return 0;
+}
+if (got > 0) {
+buflen -= got;
+buf += got;
+} else if (got == 0) {
+error_setg(errp, "Unexpected EOF reading random bytes");
+return -1;
+} else if (errno != EINTR) {
+error_setg_errno(errp, errno, "Unable to read random bytes");
+return -1;
 }
-buflen -= got;
-buf += got;
 }
-
-ret = 0;
- cleanup:
-return ret;
 #endif
+return 0;
 }
-- 
2.17.1




[Qemu-devel] [PATCH v5 05/24] crypto: Use O_CLOEXEC in qcrypto_random_init

2019-05-09 Thread Richard Henderson
Avoids leaking the /dev/urandom fd into any child processes.

Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 crypto/random-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 260b64564d..6df40744c7 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -42,9 +42,9 @@ int qcrypto_random_init(Error **errp)
 #else
 /* TBD perhaps also add support for BSD getentropy / Linux
  * getrandom syscalls directly */
-fd = open("/dev/urandom", O_RDONLY);
+fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
 if (fd == -1 && errno == ENOENT) {
-fd = open("/dev/random", O_RDONLY);
+fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
 }
 
 if (fd < 0) {
-- 
2.17.1




[Qemu-devel] [PATCH v5 23/24] target/ppc: Use qemu_guest_getrandom for DARN

2019-05-09 Thread Richard Henderson
We now have an interface for guest visible random numbers.

Acked-by: David Gibson 
Signed-off-by: Richard Henderson 
---
v5: Do not loop for darn64; use sizeof.
---
 target/ppc/int_helper.c | 39 +++
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index f6a088ac08..9af779ad38 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -23,6 +23,8 @@
 #include "exec/helper-proto.h"
 #include "crypto/aes.h"
 #include "fpu/softfloat.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
 
 #include "helper_regs.h"
 /*/
@@ -158,25 +160,38 @@ uint32_t helper_cmpeqb(target_ulong ra, target_ulong rb)
 #undef hasvalue
 
 /*
- * Return invalid random number.
- *
- * FIXME: Add rng backend or other mechanism to get cryptographically suitable
- * random number
+ * Return a random number.
  */
-target_ulong helper_darn32(void)
+uint64_t helper_darn32(void)
 {
-return -1;
+Error *err = NULL;
+uint32_t ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+return -1;
+}
+
+return ret;
 }
 
-target_ulong helper_darn64(void)
+uint64_t helper_darn64(void)
 {
-return -1;
+Error *err = NULL;
+uint64_t ret;
+
+if (qemu_guest_getrandom(, sizeof(ret), ) < 0) {
+qemu_log_mask(LOG_UNIMP, "darn: Crypto failure: %s",
+  error_get_pretty(err));
+error_free(err);
+return -1;
+}
+
+return ret;
 }
 
-#endif
-
-#if defined(TARGET_PPC64)
-
 uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
 {
 int i;
-- 
2.17.1




[Qemu-devel] [PATCH v5 06/24] crypto: Use getrandom for qcrypto_random_bytes

2019-05-09 Thread Richard Henderson
Prefer it to direct use of /dev/urandom.

Reviewed-by: Laurent Vivier 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
v3: If getrandom is not present, fall back on /dev/(u)random.
---
 crypto/random-platform.c | 37 -
 configure| 18 +-
 2 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/crypto/random-platform.c b/crypto/random-platform.c
index 6df40744c7..cb3ca1bc09 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-platform.c
@@ -27,7 +27,11 @@
 #include 
 static HCRYPTPROV hCryptProv;
 #else
-static int fd; /* a file handle to either /dev/urandom or /dev/random */
+# ifdef CONFIG_GETRANDOM
+#  include 
+# endif
+/* This is -1 for getrandom(), or a file handle for /dev/{u,}random.  */
+static int fd;
 #endif
 
 int qcrypto_random_init(Error **errp)
@@ -40,15 +44,20 @@ int qcrypto_random_init(Error **errp)
 return -1;
 }
 #else
-/* TBD perhaps also add support for BSD getentropy / Linux
- * getrandom syscalls directly */
+# ifdef CONFIG_GETRANDOM
+if (getrandom(NULL, 0, 0) == 0) {
+/* Use getrandom() */
+fd = -1;
+return 0;
+}
+/* Fall through to /dev/urandom case.  */
+# endif
 fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
 if (fd == -1 && errno == ENOENT) {
 fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
 }
-
 if (fd < 0) {
-error_setg(errp, "No /dev/urandom or /dev/random found");
+error_setg_errno(errp, errno, "No /dev/urandom or /dev/random");
 return -1;
 }
 #endif
@@ -66,6 +75,24 @@ int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED,
 return -1;
 }
 #else
+# ifdef CONFIG_GETRANDOM
+if (likely(fd < 0)) {
+while (1) {
+ssize_t got = getrandom(buf, buflen, 0);
+if (likely(got == buflen)) {
+return 0;
+}
+if (got >= 0) {
+buflen -= got;
+buf += got;
+} else if (errno != EINTR) {
+error_setg_errno(errp, errno, "getrandom");
+return -1;
+}
+}
+}
+/* Fall through to /dev/urandom case.  */
+# endif
 while (1) {
 ssize_t got = read(fd, buf, buflen);
 if (likely(got == buflen)) {
diff --git a/configure b/configure
index 68b34a93eb..346f89ea6c 100755
--- a/configure
+++ b/configure
@@ -5815,6 +5815,20 @@ if compile_prog "" "" ; then
 have_utmpx=yes
 fi
 
+##
+# check for getrandom()
+
+have_getrandom=no
+cat > $TMPC << EOF
+#include 
+int main(void) {
+return getrandom(0, 0, GRND_NONBLOCK);
+}
+EOF
+if compile_prog "" "" ; then
+have_getrandom=yes
+fi
+
 ##
 # checks for sanitizers
 
@@ -7202,7 +7216,9 @@ fi
 if test "$have_utmpx" = "yes" ; then
   echo "HAVE_UTMPX=y" >> $config_host_mak
 fi
-
+if test "$have_getrandom" = "yes" ; then
+  echo "CONFIG_GETRANDOM=y" >> $config_host_mak
+fi
 if test "$ivshmem" = "yes" ; then
   echo "CONFIG_IVSHMEM=y" >> $config_host_mak
 fi
-- 
2.17.1




[Qemu-devel] [PATCH v5 20/24] hw/misc/exynos4210_rng: Use qemu_guest_getrandom

2019-05-09 Thread Richard Henderson
The random number is intended for use by the guest.  As such, we should
honor the -seed argument for reproducibility.

Cc: qemu-...@nongnu.org
Cc: Igor Mitsyanko 
Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 hw/misc/exynos4210_rng.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c
index 4ecbebd2d7..0e70ffb404 100644
--- a/hw/misc/exynos4210_rng.c
+++ b/hw/misc/exynos4210_rng.c
@@ -18,10 +18,10 @@
  */
 
 #include "qemu/osdep.h"
-#include "crypto/random.h"
 #include "hw/sysbus.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
+#include "qemu/guest-random.h"
 
 #define DEBUG_EXYNOS_RNG 0
 
@@ -109,7 +109,6 @@ static void exynos4210_rng_set_seed(Exynos4210RngState *s, 
unsigned int i,
 static void exynos4210_rng_run_engine(Exynos4210RngState *s)
 {
 Error *err = NULL;
-int ret;
 
 /* Seed set? */
 if ((s->reg_status & EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE) == 0) {
@@ -127,13 +126,11 @@ static void exynos4210_rng_run_engine(Exynos4210RngState 
*s)
 }
 
 /* Get randoms */
-ret = qcrypto_random_bytes((uint8_t *)s->randr_value,
-   sizeof(s->randr_value), );
-if (!ret) {
+if (qemu_guest_getrandom(s->randr_value, sizeof(s->randr_value), )) {
+error_report_err(err);
+} else {
 /* Notify that PRNG is ready */
 s->reg_status |= EXYNOS4210_RNG_STATUS_PRNG_DONE;
-} else {
-error_report_err(err);
 }
 
 out:
-- 
2.17.1




[Qemu-devel] [PATCH v5 02/24] crypto: Merge crypto-obj-y into libqemuutil.a

2019-05-09 Thread Richard Henderson
We will shortly need this in the user-only binaries, so drop the split
into system and tools binaries.  This also means that crypto-aes-obj-y
can be merged back into crypto-obj-y.

Cc: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
 Makefile | 12 +---
 Makefile.objs|  8 ++--
 Makefile.target  |  4 
 configure|  9 +++--
 crypto/Makefile.objs |  5 +
 5 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/Makefile b/Makefile
index a971247cac..7c9c208207 100644
--- a/Makefile
+++ b/Makefile
@@ -410,7 +410,6 @@ dummy := $(call unnest-vars,, \
 block-obj-y \
 block-obj-m \
 crypto-obj-y \
-crypto-aes-obj-y \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
@@ -446,7 +445,6 @@ SOFTMMU_SUBDIR_RULES=$(filter %-softmmu,$(SUBDIR_RULES))
 
 $(SOFTMMU_SUBDIR_RULES): $(authz-obj-y)
 $(SOFTMMU_SUBDIR_RULES): $(block-obj-y)
-$(SOFTMMU_SUBDIR_RULES): $(crypto-obj-y)
 $(SOFTMMU_SUBDIR_RULES): $(io-obj-y)
 $(SOFTMMU_SUBDIR_RULES): config-all-devices.mak
 $(SOFTMMU_SUBDIR_RULES): $(edk2-decompressed)
@@ -502,7 +500,7 @@ Makefile: $(version-obj-y)
 ##
 # Build libraries
 
-libqemuutil.a: $(util-obj-y) $(trace-obj-y) $(stub-obj-y)
+libqemuutil.a: $(util-obj-y) $(trace-obj-y) $(stub-obj-y) $(crypto-obj-y)
 libvhost-user.a: $(libvhost-user-obj-y) $(util-obj-y) $(stub-obj-y)
 
 ##
@@ -511,9 +509,9 @@ COMMON_LDADDS = libqemuutil.a
 
 qemu-img.o: qemu-img-cmds.h
 
-qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) 
$(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) 
$(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
-qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) 
$(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) 
$(qom-obj-y) $(COMMON_LDADDS)
+qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) 
$(qom-obj-y) $(COMMON_LDADDS)
+qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(io-obj-y) 
$(qom-obj-y) $(COMMON_LDADDS)
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
 
@@ -524,7 +522,7 @@ qemu-edid$(EXESUF): qemu-edid.o hw/display/edid-generate.o 
$(COMMON_LDADDS)
 fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o 
fsdev/9p-marshal.o fsdev/9p-iov-marshal.o $(COMMON_LDADDS)
 fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
 
-scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o 
$(authz-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+scsi/qemu-pr-helper$(EXESUF): scsi/qemu-pr-helper.o scsi/utils.o 
$(authz-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
 ifdef CONFIG_MPATH
 scsi/qemu-pr-helper$(EXESUF): LIBS += -ludev -lmultipath -lmpathpersist
 endif
diff --git a/Makefile.objs b/Makefile.objs
index cf065de5ed..0ce429c1af 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -3,6 +3,8 @@
 stub-obj-y = stubs/ util/ crypto/
 util-obj-y = util/ qobject/ qapi/
 
+crypto-obj-y = crypto/
+
 chardev-obj-y = chardev/
 
 ###
@@ -21,12 +23,6 @@ block-obj-$(CONFIG_REPLICATION) += replication.o
 
 block-obj-m = block/
 
-###
-# crypto-obj-y is code used by both qemu system emulation and qemu-img
-
-crypto-obj-y = crypto/
-crypto-aes-obj-y = crypto/
-
 ###
 # qom-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index ae02495951..ce02924ffb 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -179,8 +179,6 @@ dummy := $(call unnest-vars,.., \
block-obj-y \
block-obj-m \
chardev-obj-y \
-   crypto-obj-y \
-   crypto-aes-obj-y \
qom-obj-y \
io-obj-y \
common-obj-y \
@@ -189,8 +187,6 @@ all-obj-y += $(common-obj-y)
 all-obj-y += $(qom-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
-all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
-all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
 
 ifdef CONFIG_SOFTMMU
diff --git a/configure b/configure
index c4f27ed453..68b34a93eb 100755
--- a/configure
+++ b/configure
@@ -2792,8 +2792,7 @@ if test "$gnutls" != "no"; then
 # At least ubuntu 18.04 ships only shared libraries.
 write_c_skeleton
 if compile_prog "" "$gnutls_libs" ; then
-libs_softmmu="$gnutls_libs $libs_softmmu"
-libs_tools="$gnutls_libs 

[Qemu-devel] [PATCH v5 00/24] Add qemu_getrandom and ARMv8.5-RNG etc

2019-05-09 Thread Richard Henderson
Patches without review/ack:
0001-configure-Link-test-before-auto-enabling-crypto-l.patch
0002-crypto-Merge-crypto-obj-y-into-libqemuutil.a.patch
0022-target-arm-Implement-ARMv8.5-RNG.patch

Changes since v4:
  * Do not autoenable nettle or gcrypt if linking is broken.
Fixes --static on fedora 30.
  * Delay removal of srand() for -seed.
  * Do not loop for -1 result for ppc64 DARN.

Changes since v3:
  * Do not autoenable gnutls if linking is broken.
Fixes --static on ubuntu 18.04.

Changes since v2:
  * Changes from review.
- getrandom is not exclusive of /dev/urandom fallback.
- vnc fails gracefully on crypto failure.
- a great renaming.
  * Drop the "nonblock" argument, as it's not deliverable from the backend.
  * Propagate Error back through qemu_guest_getrandom.
  * Add qemu_guest_getrandom_nofail to centralize "Argh! Death!".
  * Convert hw/misc/
  * Implement ppc darn.
  * Implement x86 rdrand.

Changes since v1:
  * Build crypto-obj-y for linux-user as well.
  * Several patches to tidy crypto/random-platform.c.
  * Use getrandom(2) in crypto/random-platform.c.
  * Use qcrypto_random_bytes in ui/vnc.c.
  * In qemu_getrandom:
- Use g_rand_int instead of srand48.
- Use qcrypto_random_bytes instead of getrandom directly.

Richard Henderson (24):
  configure: Link test before auto-enabling crypto libraries
  crypto: Merge crypto-obj-y into libqemuutil.a
  crypto: Reverse code blocks in random-platform.c
  crypto: Do not fail for EINTR during qcrypto_random_bytes
  crypto: Use O_CLOEXEC in qcrypto_random_init
  crypto: Use getrandom for qcrypto_random_bytes
  crypto: Change the qcrypto_random_bytes buffer type to void*
  ui/vnc: Split out authentication_failed
  ui/vnc: Use gcrypto_random_bytes for start_auth_vnc
  util: Add qemu_guest_getrandom and associated routines
  cpus: Initialize pseudo-random seeds for all guest cpus
  linux-user: Initialize pseudo-random seeds for all guest cpus
  linux-user: Call qcrypto_init if not using -seed
  linux-user: Use qemu_guest_getrandom_nofail for AT_RANDOM
  linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys
  linux-user: Remove srand call
  aspeed/scu: Use qemu_guest_getrandom_nofail
  hw/misc/nrf51_rng: Use qemu_guest_getrandom_nofail
  hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail
  hw/misc/exynos4210_rng: Use qemu_guest_getrandom
  target/arm: Put all PAC keys into a structure
  target/arm: Implement ARMv8.5-RNG
  target/ppc: Use qemu_guest_getrandom for DARN
  target/i386: Implement CPUID_EXT_RDRAND

 Makefile|  12 ++--
 Makefile.objs   |   8 +--
 Makefile.target |   4 --
 include/crypto/random.h |   2 +-
 include/qemu/guest-random.h |  68 ++
 include/qom/cpu.h   |   1 +
 linux-user/aarch64/target_syscall.h |   2 -
 target/arm/cpu.h|  17 +++--
 target/i386/helper.h|   2 +
 cpus.c  |   9 +++
 crypto/random-gcrypt.c  |   2 +-
 crypto/random-gnutls.c  |   2 +-
 crypto/random-platform.c| 104 +---
 hw/misc/aspeed_scu.c|  10 +--
 hw/misc/bcm2835_rng.c   |  32 -
 hw/misc/exynos4210_rng.c|  11 ++-
 hw/misc/nrf51_rng.c |   4 +-
 linux-user/aarch64/cpu_loop.c   |  25 +--
 linux-user/elfload.c|   8 +--
 linux-user/main.c   |  34 +
 linux-user/syscall.c|  34 +++--
 target/arm/cpu64.c  |   1 +
 target/arm/helper.c |  64 ++---
 target/arm/pauth_helper.c   |  18 ++---
 target/i386/cpu.c   |   5 +-
 target/i386/int_helper.c|  21 ++
 target/i386/translate.c |  55 +++
 target/ppc/int_helper.c |  39 +++
 ui/vnc.c|  53 ++
 util/guest-random.c |  93 +
 vl.c|   4 ++
 configure   |  87 +++
 crypto/Makefile.objs|   5 +-
 qemu-options.hx |  10 +++
 util/Makefile.objs  |   1 +
 35 files changed, 586 insertions(+), 261 deletions(-)
 create mode 100644 include/qemu/guest-random.h
 create mode 100644 util/guest-random.c

-- 
2.17.1




[Qemu-devel] [PATCH v5 09/24] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc

2019-05-09 Thread Richard Henderson
Use a better interface for random numbers than rand().
Fail gracefully if for some reason we cannot use the crypto system.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Gerd Hoffmann 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Richard Henderson 
---
v2: Use qcrypto_random_bytes, not qemu_getrandom, as there is
no need for deterministic results for this interface.
v3: Fail gracefully in the event qcrypto_random_bytes fails.
---
 ui/vnc.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 785edf3af1..d83f4a6ff9 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -43,6 +43,7 @@
 #include "crypto/hash.h"
 #include "crypto/tlscredsanon.h"
 #include "crypto/tlscredsx509.h"
+#include "crypto/random.h"
 #include "qom/object_interfaces.h"
 #include "qemu/cutils.h"
 #include "io/dns-resolver.h"
@@ -2547,16 +2548,6 @@ static void authentication_failed(VncState *vs)
 vnc_client_error(vs);
 }
 
-static void make_challenge(VncState *vs)
-{
-int i;
-
-srand(time(NULL)+getpid()+getpid()*987654+rand());
-
-for (i = 0 ; i < sizeof(vs->challenge) ; i++)
-vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
 {
 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
@@ -2628,7 +2619,16 @@ reject:
 
 void start_auth_vnc(VncState *vs)
 {
-make_challenge(vs);
+Error *err = NULL;
+
+if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), )) {
+trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
+error_get_pretty(err));
+error_free(err);
+authentication_failed(vs);
+return;
+}
+
 /* Send client a 'random' challenge */
 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
 vnc_flush(vs);
-- 
2.17.1




Re: [Qemu-devel] [PATCH v3 2/2] docs: add Security chapter to the documentation

2019-05-09 Thread Li Qiang
Stefan Hajnoczi  于2019年5月9日周四 下午8:20写道:

> This new chapter in the QEMU documentation covers the security
> requirements that QEMU is designed to meet and principles for securely
> deploying QEMU.
>
> It is just a starting point that can be extended in the future with more
> information.
>
> Signed-off-by: Stefan Hajnoczi 
> Acked-by: Stefano Garzarella 
> Reviewed-by: Alex Bennée 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>


Reviewed-by: Li Qiang 




>  Makefile   |   2 +-
>  docs/security.texi | 131 +
>  qemu-doc.texi  |   3 ++
>  3 files changed, 135 insertions(+), 1 deletion(-)
>  create mode 100644 docs/security.texi
>
> diff --git a/Makefile b/Makefile
> index d372493042..e2bc9c8c9d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -973,7 +973,7 @@ qemu-doc.html qemu-doc.info qemu-doc.pdf
> qemu-doc.txt: \
> qemu-img.texi qemu-nbd.texi qemu-options.texi
> qemu-option-trace.texi \
> qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi
> qemu-ga.texi \
> qemu-monitor-info.texi docs/qemu-block-drivers.texi \
> -   docs/qemu-cpu-models.texi
> +   docs/qemu-cpu-models.texi docs/security.texi
>
>  docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
>  docs/interop/qemu-ga-ref.info docs/interop/qemu-ga-ref.pdf \
> diff --git a/docs/security.texi b/docs/security.texi
> new file mode 100644
> index 00..927764f1e6
> --- /dev/null
> +++ b/docs/security.texi
> @@ -0,0 +1,131 @@
> +@node Security
> +@chapter Security
> +
> +@section Overview
> +
> +This chapter explains the security requirements that QEMU is designed to
> meet
> +and principles for securely deploying QEMU.
> +
> +@section Security Requirements
> +
> +QEMU supports many different use cases, some of which have stricter
> security
> +requirements than others.  The community has agreed on the overall
> security
> +requirements that users may depend on.  These requirements define what is
> +considered supported from a security perspective.
> +
> +@subsection Virtualization Use Case
> +
> +The virtualization use case covers cloud and virtual private server (VPS)
> +hosting, as well as traditional data center and desktop virtualization.
> These
> +use cases rely on hardware virtualization extensions to execute guest code
> +safely on the physical CPU at close-to-native speed.
> +
> +The following entities are untrusted, meaning that they may be buggy or
> +malicious:
> +
> +@itemize
> +@item Guest
> +@item User-facing interfaces (e.g. VNC, SPICE, WebSocket)
> +@item Network protocols (e.g. NBD, live migration)
> +@item User-supplied files (e.g. disk images, kernels, device trees)
> +@item Passthrough devices (e.g. PCI, USB)
> +@end itemize
> +
> +Bugs affecting these entities are evaluated on whether they can cause
> damage in
> +real-world use cases and treated as security bugs if this is the case.
> +
> +@subsection Non-virtualization Use Case
> +
> +The non-virtualization use case covers emulation using the Tiny Code
> Generator
> +(TCG).  In principle the TCG and device emulation code used in
> conjunction with
> +the non-virtualization use case should meet the same security
> requirements as
> +the virtualization use case.  However, for historical reasons much of the
> +non-virtualization use case code was not written with these security
> +requirements in mind.
> +
> +Bugs affecting the non-virtualization use case are not considered security
> +bugs at this time.  Users with non-virtualization use cases must not rely
> on
> +QEMU to provide guest isolation or any security guarantees.
> +
> +@section Architecture
> +
> +This section describes the design principles that ensure the security
> +requirements are met.
> +
> +@subsection Guest Isolation
> +
> +Guest isolation is the confinement of guest code to the virtual machine.
> When
> +guest code gains control of execution on the host this is called escaping
> the
> +virtual machine.  Isolation also includes resource limits such as
> throttling of
> +CPU, memory, disk, or network.  Guests must be unable to exceed their
> resource
> +limits.
> +
> +QEMU presents an attack surface to the guest in the form of emulated
> devices.
> +The guest must not be able to gain control of QEMU.  Bugs in emulated
> devices
> +could allow malicious guests to gain code execution in QEMU.  At this
> point the
> +guest has escaped the virtual machine and is able to act in the context
> of the
> +QEMU process on the host.
> +
> +Guests often interact with other guests and share resources with them.  A
> +malicious guest must not gain control of other guests or access their
> data.
> +Disk image files and network traffic must be protected from other guests
> unless
> +explicitly shared between them by the user.
> +
> +@subsection Principle of Least Privilege
> +
> +The principle of least privilege states that each component only has
> access to
> +the privileges necessary for its function.  In the case of 

Re: [Qemu-devel] [PATCH v3 1/2] docs: add Secure Coding Practices to developer docs

2019-05-09 Thread Li Qiang
Stefan Hajnoczi  于2019年5月9日周四 下午8:20写道:

> At KVM Forum 2018 I gave a presentation on security in QEMU:
> https://www.youtube.com/watch?v=YAdRf_hwxU8 (video)
> https://vmsplice.net/~stefan/stefanha-kvm-forum-2018.pdf (slides)
>
> This patch adds a guide to secure coding practices.  This document
> covers things that developers should know about security in QEMU.  It is
> just a starting point that we can expand on later.  I hope it will be
> useful as a resource for new contributors and will save code reviewers
> from explaining the same concepts many times.
>
> Signed-off-by: Stefan Hajnoczi 
> Acked-by: Stefano Garzarella 
> Reviewed-by: Alex Bennée 
> Reviewed-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Li Qiang 




> ---
>  docs/devel/index.rst   |   1 +
>  docs/devel/secure-coding-practices.rst | 106 +
>  2 files changed, 107 insertions(+)
>  create mode 100644 docs/devel/secure-coding-practices.rst
>
> diff --git a/docs/devel/index.rst b/docs/devel/index.rst
> index ebbab636ce..2a4ddf40ad 100644
> --- a/docs/devel/index.rst
> +++ b/docs/devel/index.rst
> @@ -20,3 +20,4 @@ Contents:
> stable-process
> testing
> decodetree
> +   secure-coding-practices
> diff --git a/docs/devel/secure-coding-practices.rst
> b/docs/devel/secure-coding-practices.rst
> new file mode 100644
> index 00..cbfc8af67e
> --- /dev/null
> +++ b/docs/devel/secure-coding-practices.rst
> @@ -0,0 +1,106 @@
> +===
> +Secure Coding Practices
> +===
> +This document covers topics that both developers and security researchers
> must
> +be aware of so that they can develop safe code and audit existing code
> +properly.
> +
> +Reporting Security Bugs
> +---
> +For details on how to report security bugs or ask questions about
> potential
> +security bugs, see the `Security Process wiki page
> +`_.
> +
> +General Secure C Coding Practices
> +-
> +Most CVEs (security bugs) reported against QEMU are not specific to
> +virtualization or emulation.  They are simply C programming bugs.
> Therefore
> +it's critical to be aware of common classes of security bugs.
> +
> +There is a wide selection of resources available covering secure C
> coding.  For
> +example, the `CERT C Coding Standard
> + >`_
> +covers the most important classes of security bugs.
> +
> +Instead of describing them in detail here, only the names of the most
> important
> +classes of security bugs are mentioned:
> +
> +* Buffer overflows
> +* Use-after-free and double-free
> +* Integer overflows
> +* Format string vulnerabilities
> +
> +Some of these classes of bugs can be detected by analyzers.  Static
> analysis is
> +performed regularly by Coverity and the most obvious of these bugs are
> even
> +reported by compilers.  Dynamic analysis is possible with valgrind, tsan,
> and
> +asan.
> +
> +Input Validation
> +
> +Inputs from the guest or external sources (e.g. network, files) cannot be
> +trusted and may be invalid.  Inputs must be checked before using them in
> a way
> +that could crash the program, expose host memory to the guest, or
> otherwise be
> +exploitable by an attacker.
> +
> +The most sensitive attack surface is device emulation.  All hardware
> register
> +accesses and data read from guest memory must be validated.  A typical
> example
> +is a device that contains multiple units that are selectable by the guest
> via
> +an index register::
> +
> +  typedef struct {
> +  ProcessingUnit unit[2];
> +  ...
> +  } MyDeviceState;
> +
> +  static void mydev_writel(void *opaque, uint32_t addr, uint32_t val)
> +  {
> +  MyDeviceState *mydev = opaque;
> +  ProcessingUnit *unit;
> +
> +  switch (addr) {
> +  case MYDEV_SELECT_UNIT:
> +  unit = >unit[val];   <-- this input wasn't validated!
> +  ...
> +  }
> +  }
> +
> +If ``val`` is not in range [0, 1] then an out-of-bounds memory access
> will take
> +place when ``unit`` is dereferenced.  The code must check that ``val`` is
> 0 or
> +1 and handle the case where it is invalid.
> +
> +Unexpected Device Accesses
> +--
> +The guest may access device registers in unusual orders or at unexpected
> +moments.  Device emulation code must not assume that the guest follows the
> +typical "theory of operation" presented in driver writer manuals.  The
> guest
> +may make nonsense accesses to device registers such as starting operations
> +before the device has been fully initialized.
> +
> +A related issue is that device emulation code must be prepared for
> unexpected
> +device register accesses while asynchronous operations are in progress.  A
> +well-behaved guest might wait for a completion interrupt before accessing
> +certain device registers.  Device emulation code must handle the 

Re: [Qemu-devel] [PATCH v2 00/10] refactor cpu topo into machine properties

2019-05-09 Thread Like Xu

On 2019/5/6 16:33, Like Xu wrote:

This patch series make existing cores/threads/sockets into machine
properties and get rid of global smp_* variables they use currently.

The purpose of getting rid of globals is disentangle layer violations and
let's do it one step at a time by replacing the smp_foo with qdev_get_machine()
as few calls as possible and delay other related refactoring efforts.



It looks like the changelog is missing and here it is:

==changelog==

v2:
- pass MachineState via call chain with trivial fixups
- replace smp_cpus directly at places if it's only used once
- s/topo/smp/ and drop smp_ prefix inside CpuTopology structure
- add more commit messages to explaining what patch does
- fix Patchew build failure for xen usage
- use macs rather than ms in migration context for MigrationState
- cleanup unrelated and redundant changes
- spilt OpenRISC and RISC-V related patches

v1: https://patchwork.kernel.org/cover/10876667/


Like Xu (10):
   hw/boards: add struct CpuTopology to MachineState
   cpu/topology: related call chains refactoring to pass MachineState
   cpu/topology: replace global smp variables by MachineState in general path
   cpu/topology: add uncommon arch support for smp machine properties
   cpu/topology: add hw/ppc support for smp machine properties
   cpu/topology: add hw/riscv support for smp machine properties
   cpu/topology: add hw/s390x support for smp machine properties
   cpu/topology: add hw/i386 support for smp machine properties
   cpu/topology: add hw/arm support for smp machine properties
   cpu/topology: replace smp global variables with smp machine properties

  accel/kvm/kvm-all.c  |  4 ++--
  backends/hostmem.c   |  6 --
  cpus.c   |  6 --
  exec.c   |  3 ++-
  gdbstub.c|  4 
  hw/alpha/dp264.c |  1 +
  hw/arm/fsl-imx6.c|  6 +-
  hw/arm/fsl-imx6ul.c  |  6 +-
  hw/arm/fsl-imx7.c|  7 +--
  hw/arm/highbank.c|  1 +
  hw/arm/mcimx6ul-evk.c|  2 +-
  hw/arm/mcimx7d-sabre.c   |  2 +-
  hw/arm/raspi.c   |  4 ++--
  hw/arm/realview.c|  1 +
  hw/arm/sabrelite.c   |  2 +-
  hw/arm/vexpress.c| 16 --
  hw/arm/virt.c| 10 +++--
  hw/arm/xlnx-zynqmp.c | 16 --
  hw/cpu/core.c|  4 +++-
  hw/hppa/machine.c|  4 +++-
  hw/i386/acpi-build.c | 13 +++-
  hw/i386/kvmvapic.c   |  7 +--
  hw/i386/pc.c | 33 -
  hw/i386/xen/xen-hvm.c|  4 
  hw/mips/boston.c |  2 +-
  hw/mips/mips_malta.c | 23 +++-
  hw/openrisc/openrisc_sim.c   |  1 +
  hw/ppc/e500.c|  3 +++
  hw/ppc/mac_newworld.c|  3 ++-
  hw/ppc/mac_oldworld.c|  3 ++-
  hw/ppc/pnv.c |  9 
  hw/ppc/prep.c|  4 ++--
  hw/ppc/spapr.c   | 37 +++-
  hw/ppc/spapr_rtas.c  |  4 +++-
  hw/riscv/sifive_e.c  |  6 --
  hw/riscv/sifive_plic.c   |  3 +++
  hw/riscv/sifive_u.c  |  6 --
  hw/riscv/spike.c |  2 ++
  hw/riscv/virt.c  |  1 +
  hw/s390x/s390-virtio-ccw.c   |  9 
  hw/s390x/sclp.c  |  2 +-
  hw/smbios/smbios.c   | 26 +--
  hw/sparc/sun4m.c |  2 ++
  hw/sparc64/sun4u.c   |  4 ++--
  hw/xtensa/sim.c  |  2 +-
  hw/xtensa/xtfpga.c   |  1 +
  include/hw/boards.h  | 19 +++--
  include/hw/firmware/smbios.h |  5 +++--
  include/hw/i386/pc.h |  2 +-
  migration/postcopy-ram.c |  8 ++-
  numa.c   |  1 +
  qmp.c|  2 +-
  target/arm/cpu.c |  8 ++-
  target/i386/cpu.c|  4 +++-
  target/openrisc/sys_helper.c |  6 +-
  target/s390x/cpu.c   |  3 +++
  target/s390x/excp_helper.c   |  5 +
  tcg/tcg.c| 13 +++-
  vl.c | 50 
  59 files changed, 301 insertions(+), 140 deletions(-)






Re: [Qemu-devel] [PATCH v1 16/23] tests/qemu-iotests/005: Add a sanity check for large sparse file support

2019-05-09 Thread Richard Henderson
On 5/9/19 9:59 AM, Alex Bennée wrote:
> From: Thomas Huth 
> 
> "check -raw 005" fails when running on certain filesystems - these do not
> support such large sparse files. Use the same check as in test 220 to
> skip the test in this case.
> 
> Suggested-by: Eric Blake 
> Reviewed-by: Eric Blake 
> Signed-off-by: Thomas Huth 
> Message-Id: <20190502084506.8009-2-th...@redhat.com>
> Signed-off-by: Alex Bennée 
> ---
>  tests/qemu-iotests/005 | 9 +
>  1 file changed, 9 insertions(+)

Reviewed-by: Richard Henderson 


r~




Re: [Qemu-devel] [PATCH v1 12/23] .travis.yml: enable aarch64-softmmu and alpha-softmmu tcg tests

2019-05-09 Thread Richard Henderson
On 5/9/19 9:59 AM, Alex Bennée wrote:
> Signed-off-by: Alex Bennée 
> ---
>  .travis.yml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson 


r~



Re: [Qemu-devel] [PATCH v1 06/23] editorconfig: add settings for .s/.S files

2019-05-09 Thread Richard Henderson
On 5/9/19 9:58 AM, Alex Bennée wrote:
> We are starting to add assembler foe tests/tcg so lets make sure we
> get the mode right.
> 
> Signed-off-by: Alex Bennée 
> ---
>  .editorconfig | 5 +
>  1 file changed, 5 insertions(+)

Yay, thanks!

Reviewed-by: Richard Henderson 


r~



[Qemu-devel] [PATCH v3 20/27] target/sparc: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Artyom Tarasenko 
Cc: Mark Cave-Ayland 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only, sparc32, and sparc64 tlb_fill separate.
v3: Assert !probe for sparc32.
---
 target/sparc/cpu.h |  5 ++--
 target/sparc/cpu.c |  5 ++--
 target/sparc/ldst_helper.c | 11 +---
 target/sparc/mmu_helper.c  | 58 --
 4 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 85b9665ccc..f31e8535df 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -579,8 +579,9 @@ void cpu_raise_exception_ra(CPUSPARCState *, int, 
uintptr_t) QEMU_NORETURN;
 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 void sparc_cpu_list(void);
 /* mmu_helper.c */
-int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-   int mmu_idx);
+bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
 void dump_mmu(CPUSPARCState *env);
 
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 4654c2a6a0..f93ce72eb9 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -875,9 +875,8 @@ static void sparc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
 cc->gdb_read_register = sparc_cpu_gdb_read_register;
 cc->gdb_write_register = sparc_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = sparc_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = sparc_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unassigned_access = sparc_cpu_unassigned_access;
 cc->do_unaligned_access = sparc_cpu_do_unaligned_access;
 cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index a7fcb84ac0..2558c08a64 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1925,18 +1925,9 @@ void QEMU_NORETURN 
sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 cpu_raise_exception_ra(env, TT_UNALIGNED, retaddr);
 }
 
-/* try to fill the TLB and return an exception if error. If retaddr is
-   NULL, it means that the function was called in C code (i.e. not
-   from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
 void tlb_fill(CPUState *cs, target_ulong addr, int size,
   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
-int ret;
-
-ret = sparc_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-if (ret) {
-cpu_loop_exit_restore(cs, retaddr);
-}
+sparc_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 #endif
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index afcc5b617d..facc0c60e9 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -27,13 +27,14 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-   int mmu_idx)
+bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 SPARCCPU *cpu = SPARC_CPU(cs);
 CPUSPARCState *env = >env;
 
-if (rw & 2) {
+if (access_type == MMU_INST_FETCH) {
 cs->exception_index = TT_TFAULT;
 } else {
 cs->exception_index = TT_DFAULT;
@@ -43,7 +44,7 @@ int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size, int rw,
 env->mmuregs[4] = address;
 #endif
 }
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else
@@ -208,8 +209,9 @@ static int get_physical_address(CPUSPARCState *env, hwaddr 
*physical,
 }
 
 /* Perform address translation */
-int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-   int mmu_idx)
+bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 SPARCCPU *cpu = SPARC_CPU(cs);
 CPUSPARCState *env = >env;
@@ -218,16 +220,26 @@ int sparc_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size, int rw,
 target_ulong page_size;
 int error_code = 0, prot, access_index;
 
+/*
+ * TODO: If we ever need tlb_vaddr_to_host for this target,
+ * then we must figure out how to manipulate FSR and FAR
+ * when both MMU_NF and probe are set.  In the meantime,
+ * do not support this use case.
+ */
+assert(!probe);
+
 address &= TARGET_PAGE_MASK;
 error_code = get_physical_address(env, , , _index,
-  address, rw, mmu_idx, _size);
+  

[Qemu-devel] [PATCH v3 21/27] target/tilegx: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/tilegx/cpu.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index b9d37105fa..b209c55387 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -25,6 +25,7 @@
 #include "hw/qdev-properties.h"
 #include "linux-user/syscall_defs.h"
 #include "qemu/qemu-print.h"
+#include "exec/exec-all.h"
 
 static void tilegx_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
@@ -111,8 +112,9 @@ static void tilegx_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = -1;
 }
 
-static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
+static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 TileGXCPU *cpu = TILEGX_CPU(cs);
 
@@ -122,7 +124,7 @@ static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size,
 cpu->env.signo = TARGET_SIGSEGV;
 cpu->env.sigcode = 0;
 
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
@@ -152,7 +154,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
 cc->dump_state = tilegx_cpu_dump_state;
 cc->set_pc = tilegx_cpu_set_pc;
-cc->handle_mmu_fault = tilegx_cpu_handle_mmu_fault;
+cc->tlb_fill = tilegx_cpu_tlb_fill;
 cc->gdb_num_core_regs = 0;
 cc->tcg_initialize = tilegx_tcg_init;
 }
-- 
2.17.1




Re: [Qemu-devel] [PATCH v1 05/23] semihosting: enable chardev backed output

2019-05-09 Thread Richard Henderson
On 5/9/19 9:58 AM, Alex Bennée wrote:
> @@ -51,12 +51,18 @@ static inline const char *semihosting_get_cmdline(void)
>  {
>  return NULL;
>  }
> +
> +static inline Chardev *semihosting_get_chardev(void)
> +{
> +return NULL;
> +}

Isn't the point of this function to avoid...

> -return write(STDERR_FILENO, , 1);
> +#ifdef CONFIG_SOFTMMU
> +  Chardev *chardev = semihosting_get_chardev();
> +  if (chardev) {
> +  return qemu_chr_write_all(chardev, (uint8_t *) , 1);
> +  } else
> +#endif
> +  {
> +  return write(STDERR_FILENO, , 1);
> +  }

... this ifdef?

Better to change

- char c;
+ uint8_t c;

above to avoid the cast in the call to qemu_chr_write_all?
Or perhaps we should adjust qemu_chr_write_all to take void*?


r~



[Qemu-devel] [PATCH v3 18/27] target/s390x: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: qemu-s3...@nongnu.org
Cc: Cornelia Huck 
Reviewed-by: David Hildenbrand 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only and system tlb_fill separate.
---
 target/s390x/internal.h|  5 +--
 target/s390x/cpu.c |  5 ++-
 target/s390x/excp_helper.c | 73 ++
 target/s390x/mem_helper.c  | 16 -
 4 files changed, 55 insertions(+), 44 deletions(-)

diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 26575f2130..56534b38e0 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -263,8 +263,9 @@ ObjectClass *s390_cpu_class_by_name(const char *name);
 void s390x_cpu_debug_excp_handler(CPUState *cs);
 void s390_cpu_do_interrupt(CPUState *cpu);
 bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req);
-int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr);
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index b58ef0a8ef..e28939032b 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -478,9 +478,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 cc->set_pc = s390_cpu_set_pc;
 cc->gdb_read_register = s390_cpu_gdb_read_register;
 cc->gdb_write_register = s390_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = s390_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = s390_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
 cc->vmsd = _s390_cpu;
 cc->write_elf64_note = s390_cpu_write_elf64_note;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index f84bfb1284..a4e134bcab 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -74,8 +74,9 @@ void s390_cpu_do_interrupt(CPUState *cs)
 cs->exception_index = -1;
 }
 
-int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-  int rw, int mmu_idx)
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 S390CPU *cpu = S390_CPU(cs);
 
@@ -83,7 +84,7 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size,
 /* On real machines this value is dropped into LowMem.  Since this
is userland, simply put this someplace that cpu_loop can find it.  */
 cpu->env.__excp_addr = address;
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else /* !CONFIG_USER_ONLY */
@@ -102,19 +103,20 @@ static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
 }
 }
 
-int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
-  int rw, int mmu_idx)
+bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 S390CPU *cpu = S390_CPU(cs);
 CPUS390XState *env = >env;
 target_ulong vaddr, raddr;
 uint64_t asc;
-int prot;
+int prot, fail;
 
 qemu_log_mask(CPU_LOG_MMU, "%s: addr 0x%" VADDR_PRIx " rw %d mmu_idx %d\n",
-  __func__, orig_vaddr, rw, mmu_idx);
+  __func__, address, access_type, mmu_idx);
 
-vaddr = orig_vaddr;
+vaddr = address;
 
 if (mmu_idx < MMU_REAL_IDX) {
 asc = cpu_mmu_idx_to_asc(mmu_idx);
@@ -122,39 +124,64 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr 
orig_vaddr, int size,
 if (!(env->psw.mask & PSW_MASK_64)) {
 vaddr &= 0x7fff;
 }
-if (mmu_translate(env, vaddr, rw, asc, , , true)) {
-return 1;
-}
+fail = mmu_translate(env, vaddr, access_type, asc, , , 
true);
 } else if (mmu_idx == MMU_REAL_IDX) {
 /* 31-Bit mode */
 if (!(env->psw.mask & PSW_MASK_64)) {
 vaddr &= 0x7fff;
 }
-if (mmu_translate_real(env, vaddr, rw, , )) {
-return 1;
-}
+fail = mmu_translate_real(env, vaddr, access_type, , );
 } else {
-abort();
+g_assert_not_reached();
 }
 
 /* check out of RAM access */
-if (!address_space_access_valid(_space_memory, raddr,
-TARGET_PAGE_SIZE, rw,
+if (!fail &&
+!address_space_access_valid(_space_memory, raddr,
+TARGET_PAGE_SIZE, access_type,
 MEMTXATTRS_UNSPECIFIED)) {
 qemu_log_mask(CPU_LOG_MMU,
   "%s: raddr 

[Qemu-devel] [PATCH v3 16/27] target/ppc: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: qemu-...@nongnu.org
Cc: David Gibson 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/ppc/cpu.h|  7 +++
 target/ppc/mmu_helper.c | 22 +-
 target/ppc/translate_init.inc.c |  5 ++---
 target/ppc/user_only_helper.c   | 14 --
 4 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 5e7cf54b2f..d7f23ad5e0 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1311,10 +1311,9 @@ void ppc_translate_init(void);
  * is returned if the signal was handled by the virtual CPU.
  */
 int cpu_ppc_signal_handler(int host_signum, void *pinfo, void *puc);
-#if defined(CONFIG_USER_ONLY)
-int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
- int mmu_idx);
-#endif
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
 
 #if !defined(CONFIG_USER_ONLY)
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 1dbc9acb75..afcca50530 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -3057,15 +3057,9 @@ void helper_check_tlb_flush_global(CPUPPCState *env)
 
 /*/
 
-/*
- * try to fill the TLB and return an exception if error. If retaddr is
- * NULL, it means that the function was called in C code (i.e. not
- * from generated code or from helper.c)
- *
- * XXX: fix it to restore all registers
- */
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
@@ -3078,7 +3072,17 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
 ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx);
 }
 if (unlikely(ret != 0)) {
+if (probe) {
+return false;
+}
 raise_exception_err_ra(env, cs->exception_index, env->error_code,
retaddr);
 }
+return true;
+}
+
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+ppc_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 0394a9ddad..3f847de36c 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -10592,9 +10592,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->gdb_read_register = ppc_cpu_gdb_read_register;
 cc->gdb_write_register = ppc_cpu_gdb_write_register;
 cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = ppc_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
 cc->vmsd = _ppc_cpu;
 #endif
diff --git a/target/ppc/user_only_helper.c b/target/ppc/user_only_helper.c
index 2f1477f102..683c03390d 100644
--- a/target/ppc/user_only_helper.c
+++ b/target/ppc/user_only_helper.c
@@ -20,21 +20,24 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "exec/exec-all.h"
 
-int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
- int mmu_idx)
+
+bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr)
 {
 PowerPCCPU *cpu = POWERPC_CPU(cs);
 CPUPPCState *env = >env;
 int exception, error_code;
 
-if (rw == 2) {
+if (access_type == MMU_INST_FETCH) {
 exception = POWERPC_EXCP_ISI;
 error_code = 0x4000;
 } else {
 exception = POWERPC_EXCP_DSI;
 error_code = 0x4000;
-if (rw) {
+if (access_type == MMU_DATA_STORE) {
 error_code |= 0x0200;
 }
 env->spr[SPR_DAR] = address;
@@ -42,6 +45,5 @@ int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int 
size, int rw,
 }
 cs->exception_index = exception;
 env->error_code = error_code;
-
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
-- 
2.17.1




[Qemu-devel] [PATCH v3 09/27] target/microblaze: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only and system tlb_fill separate.
---
 target/microblaze/cpu.h   |   5 +-
 target/microblaze/cpu.c   |   5 +-
 target/microblaze/helper.c| 107 ++
 target/microblaze/op_helper.c |  19 --
 4 files changed, 62 insertions(+), 74 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index f20e796865..7a9fb8f4aa 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -374,8 +374,9 @@ static inline int cpu_mmu_index (CPUMBState *env, bool 
ifetch)
 return MMU_KERNEL_IDX;
 }
 
-int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-int mmu_idx);
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 
 #include "exec/cpu-all.h"
 
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 5596cd5485..0ea549910b 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -304,9 +304,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 cc->set_pc = mb_cpu_set_pc;
 cc->gdb_read_register = mb_cpu_gdb_read_register;
 cc->gdb_write_register = mb_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = mb_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = mb_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_transaction_failed = mb_cpu_transaction_failed;
 cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
 #endif
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index 9848e31d7f..a523c77959 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -38,73 +38,80 @@ void mb_cpu_do_interrupt(CPUState *cs)
 env->regs[14] = env->sregs[SR_PC];
 }
 
-int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-int mmu_idx)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
 {
 cs->exception_index = 0xaa;
-cpu_dump_state(cs, stderr, 0);
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else /* !CONFIG_USER_ONLY */
 
-int mb_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-int mmu_idx)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
 {
 MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 CPUMBState *env = >env;
+struct microblaze_mmu_lookup lu;
 unsigned int hit;
-int r = 1;
 int prot;
 
-/* Translate if the MMU is available and enabled.  */
-if (mmu_idx != MMU_NOMMU_IDX) {
-uint32_t vaddr, paddr;
-struct microblaze_mmu_lookup lu;
-
-hit = mmu_translate(>mmu, , address, rw, mmu_idx);
-if (hit) {
-vaddr = address & TARGET_PAGE_MASK;
-paddr = lu.paddr + vaddr - lu.vaddr;
-
-qemu_log_mask(CPU_LOG_MMU, "MMU map mmu=%d v=%x p=%x prot=%x\n",
-mmu_idx, vaddr, paddr, lu.prot);
-tlb_set_page(cs, vaddr, paddr, lu.prot, mmu_idx, TARGET_PAGE_SIZE);
-r = 0;
-} else {
-env->sregs[SR_EAR] = address;
-qemu_log_mask(CPU_LOG_MMU, "mmu=%d miss v=%" VADDR_PRIx "\n",
-mmu_idx, address);
-
-switch (lu.err) {
-case ERR_PROT:
-env->sregs[SR_ESR] = rw == 2 ? 17 : 16;
-env->sregs[SR_ESR] |= (rw == 1) << 10;
-break;
-case ERR_MISS:
-env->sregs[SR_ESR] = rw == 2 ? 19 : 18;
-env->sregs[SR_ESR] |= (rw == 1) << 10;
-break;
-default:
-abort();
-break;
-}
-
-if (cs->exception_index == EXCP_MMU) {
-cpu_abort(cs, "recursive faults\n");
-}
-
-/* TLB miss.  */
-cs->exception_index = EXCP_MMU;
-}
-} else {
+if (mmu_idx == MMU_NOMMU_IDX) {
 /* MMU disabled or not available.  */
 address &= TARGET_PAGE_MASK;
 prot = PAGE_BITS;
 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
-r = 0;
+return true;
 }
-return r;
+
+hit = mmu_translate(>mmu, , address, access_type, mmu_idx);
+if (likely(hit)) {
+uint32_t vaddr = address & TARGET_PAGE_MASK;
+uint32_t paddr = lu.paddr + vaddr - lu.vaddr;
+
+qemu_log_mask(CPU_LOG_MMU, "MMU map mmu=%d v=%x p=%x prot=%x\n",
+  mmu_idx, vaddr, paddr, lu.prot);
+

[Qemu-devel] [PATCH v3 25/27] tcg: Use CPUClass::tlb_fill in cputlb.c

2019-05-09 Thread Richard Henderson
We can now use the CPUClass hook instead of a named function.

Create a static tlb_fill function to avoid other changes within
cputlb.c.  This also isolates the asserts within.  Remove the
named tlb_fill function from all of the targets.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h|  9 -
 accel/tcg/cputlb.c | 19 +++
 target/alpha/helper.c  |  6 --
 target/arm/helper.c|  8 
 target/cris/helper.c   |  6 --
 target/hppa/mem_helper.c   |  6 --
 target/i386/excp_helper.c  |  8 
 target/lm32/helper.c   |  6 --
 target/m68k/helper.c   |  8 
 target/microblaze/helper.c |  6 --
 target/mips/helper.c   |  6 --
 target/moxie/helper.c  |  6 --
 target/nios2/helper.c  |  6 --
 target/openrisc/mmu.c  |  6 --
 target/ppc/mmu_helper.c|  6 --
 target/riscv/cpu_helper.c  |  6 --
 target/s390x/excp_helper.c |  6 --
 target/sh4/helper.c|  8 
 target/sparc/ldst_helper.c |  6 --
 target/tricore/helper.c|  6 --
 target/unicore32/softmmu.c |  6 --
 target/xtensa/helper.c |  6 --
 22 files changed, 19 insertions(+), 137 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 58e988b3b1..31f0ecc461 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -474,15 +474,6 @@ static inline void assert_no_pages_locked(void)
  */
 struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
  hwaddr index, MemTxAttrs attrs);
-
-/*
- * Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
- * caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
- * be discarded and looked up again (e.g. via tlb_entry()).
- */
-void tlb_fill(CPUState *cpu, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
-
 #endif
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index f2f618217d..dfcd9ae168 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -855,6 +855,25 @@ static inline ram_addr_t 
qemu_ram_addr_from_host_nofail(void *ptr)
 return ram_addr;
 }
 
+/*
+ * Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
+ * caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
+ * be discarded and looked up again (e.g. via tlb_entry()).
+ */
+static void tlb_fill(CPUState *cpu, target_ulong addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+CPUClass *cc = CPU_GET_CLASS(cpu);
+bool ok;
+
+/*
+ * This is not a probe, so only valid return is success; failure
+ * should result in exception + longjmp to the cpu loop.
+ */
+ok = cc->tlb_fill(cpu, addr, size, access_type, mmu_idx, false, retaddr);
+assert(ok);
+}
+
 static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
  int mmu_idx,
  target_ulong addr, uintptr_t retaddr,
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 929a217455..5fe9c87912 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -275,12 +275,6 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
  prot, mmu_idx, TARGET_PAGE_SIZE);
 return true;
 }
-
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-alpha_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
-}
 #endif /* USER_ONLY */
 
 void alpha_cpu_do_interrupt(CPUState *cs)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index f1a2b94ddb..e2d5c8e34f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -13127,14 +13127,6 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 #endif
 }
 
-#ifndef CONFIG_USER_ONLY
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-arm_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
-}
-#endif
-
 void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
 {
 /* Implement DC ZVA, which zeroes a fixed-length block of memory.
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 69464837c8..b5159b8357 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -123,12 +123,6 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 cpu_loop_exit(cs);
 }
 
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-cris_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
-}
-
 void crisv10_cpu_do_interrupt(CPUState *cs)
 {
 CRISCPU *cpu = CRIS_CPU(cs);
diff --git 

[Qemu-devel] [PATCH v3 23/27] target/unicore32: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Remove the user-only functions, as we no longer
have a user-only config.

Cc: Guan Xuetao 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/unicore32/cpu.h   |  5 +++--
 target/unicore32/cpu.c   |  5 +
 target/unicore32/helper.c| 23 ---
 target/unicore32/op_helper.c | 14 --
 target/unicore32/softmmu.c   | 19 +++
 5 files changed, 19 insertions(+), 47 deletions(-)

diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 24abe5e5c0..f052ee08bf 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -178,8 +178,9 @@ static inline void cpu_get_tb_cpu_state(CPUUniCore32State 
*env, target_ulong *pc
 }
 }
 
-int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 void uc32_translate_init(void);
 void switch_mode(CPUUniCore32State *, int);
 
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 2b49d1ca40..3f57c508a0 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -138,11 +138,8 @@ static void uc32_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
 cc->dump_state = uc32_cpu_dump_state;
 cc->set_pc = uc32_cpu_set_pc;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = uc32_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = uc32_cpu_tlb_fill;
 cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
-#endif
 cc->tcg_initialize = uc32_translate_init;
 dc->vmsd = _uc32_cpu;
 }
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index a5ff2ddb74..0d4914b48d 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -215,29 +215,6 @@ void helper_cp1_putc(target_ulong x)
 }
 #endif
 
-#ifdef CONFIG_USER_ONLY
-void switch_mode(CPUUniCore32State *env, int mode)
-{
-UniCore32CPU *cpu = uc32_env_get_cpu(env);
-
-if (mode != ASR_MODE_USER) {
-cpu_abort(CPU(cpu), "Tried to switch out of user mode\n");
-}
-}
-
-void uc32_cpu_do_interrupt(CPUState *cs)
-{
-cpu_abort(cs, "NO interrupt in user mode\n");
-}
-
-int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-  int access_type, int mmu_idx)
-{
-cpu_abort(cs, "NO mmu fault in user mode\n");
-return 1;
-}
-#endif
-
 bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
 if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/unicore32/op_helper.c b/target/unicore32/op_helper.c
index e0a15882d3..797ba60dc9 100644
--- a/target/unicore32/op_helper.c
+++ b/target/unicore32/op_helper.c
@@ -242,17 +242,3 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t 
x, uint32_t i)
 return ((uint32_t)x >> shift) | (x << (32 - shift));
 }
 }
-
-#ifndef CONFIG_USER_ONLY
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-int ret;
-
-ret = uc32_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-if (unlikely(ret)) {
-/* now we have a real cpu fault */
-cpu_loop_exit_restore(cs, retaddr);
-}
-}
-#endif
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
index 00c7e0d028..13678df4d7 100644
--- a/target/unicore32/softmmu.c
+++ b/target/unicore32/softmmu.c
@@ -215,8 +215,9 @@ do_fault:
 return code;
 }
 
-int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-  int access_type, int mmu_idx)
+bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 UniCore32CPU *cpu = UNICORE32_CPU(cs);
 CPUUniCore32State *env = >env;
@@ -257,7 +258,11 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size,
 phys_addr &= TARGET_PAGE_MASK;
 address &= TARGET_PAGE_MASK;
 tlb_set_page(cs, address, phys_addr, prot, mmu_idx, page_size);
-return 0;
+return true;
+}
+
+if (probe) {
+return false;
 }
 
 env->cp0.c3_faultstatus = ret;
@@ -267,7 +272,13 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size,
 } else {
 cs->exception_index = UC32_EXCP_DTRAP;
 }
-return ret;
+cpu_loop_exit_restore(cs, retaddr);
+}
+
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+uc32_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 
 hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-- 
2.17.1




[Qemu-devel] [PATCH v3 08/27] target/m68k: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Laurent Vivier 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/m68k/cpu.h   |  5 ++-
 target/m68k/cpu.c   |  2 +-
 target/m68k/helper.c| 87 ++---
 target/m68k/op_helper.c | 15 ---
 4 files changed, 50 insertions(+), 59 deletions(-)

diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index ad41608341..683d3e2f79 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -542,8 +542,9 @@ static inline int cpu_mmu_index (CPUM68KState *env, bool 
ifetch)
 return (env->sr & SR_S) == 0 ? 1 : 0;
 }
 
-int m68k_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 bool is_write, bool is_exec, int is_asi,
 unsigned size);
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 582e3a73b3..6f441bc973 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -269,7 +269,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 cc->set_pc = m68k_cpu_set_pc;
 cc->gdb_read_register = m68k_cpu_gdb_read_register;
 cc->gdb_write_register = m68k_cpu_gdb_write_register;
-cc->handle_mmu_fault = m68k_cpu_handle_mmu_fault;
+cc->tlb_fill = m68k_cpu_tlb_fill;
 #if defined(CONFIG_SOFTMMU)
 cc->do_unassigned_access = m68k_cpu_unassigned_access;
 cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index d958a34959..862f955f7b 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -353,20 +353,7 @@ void m68k_switch_sp(CPUM68KState *env)
 env->current_sp = new_sp;
 }
 
-#if defined(CONFIG_USER_ONLY)
-
-int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
-{
-M68kCPU *cpu = M68K_CPU(cs);
-
-cs->exception_index = EXCP_ACCESS;
-cpu->env.mmu.ar = address;
-return 1;
-}
-
-#else
-
+#if !defined(CONFIG_USER_ONLY)
 /* MMU: 68040 only */
 
 static void print_address_zone(uint32_t logical, uint32_t physical,
@@ -795,11 +782,36 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return phys_addr;
 }
 
-int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
+/*
+ * Notify CPU of a pending interrupt.  Prioritization and vectoring should
+ * be handled by the interrupt controller.  Real hardware only requests
+ * the vector when the interrupt is acknowledged by the CPU.  For
+ * simplicity we calculate it when the interrupt is signalled.
+ */
+void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
+{
+CPUState *cs = CPU(cpu);
+CPUM68KState *env = >env;
+
+env->pending_level = level;
+env->pending_vector = vector;
+if (level) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}
+}
+
+#endif
+
+bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType qemu_access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 M68kCPU *cpu = M68K_CPU(cs);
 CPUM68KState *env = >env;
+
+#ifndef CONFIG_USER_ONLY
 hwaddr physical;
 int prot;
 int access_type;
@@ -812,32 +824,35 @@ int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size, int rw,
  address & TARGET_PAGE_MASK,
  PAGE_READ | PAGE_WRITE | PAGE_EXEC,
  mmu_idx, TARGET_PAGE_SIZE);
-return 0;
+return true;
 }
 
-if (rw == 2) {
+if (qemu_access_type == MMU_INST_FETCH) {
 access_type = ACCESS_CODE;
-rw = 0;
 } else {
 access_type = ACCESS_DATA;
-if (rw) {
+if (qemu_access_type == MMU_DATA_STORE) {
 access_type |= ACCESS_STORE;
 }
 }
-
 if (mmu_idx != MMU_USER_IDX) {
 access_type |= ACCESS_SUPER;
 }
 
 ret = get_physical_address(>env, , ,
address, access_type, _size);
-if (ret == 0) {
+if (likely(ret == 0)) {
 address &= TARGET_PAGE_MASK;
 physical += address & (page_size - 1);
 tlb_set_page(cs, address, physical,
  prot, mmu_idx, TARGET_PAGE_SIZE);
-return 0;
+return true;
 }
+
+if (probe) {
+return false;
+}
+
 /* page fault */
 env->mmu.ssw = M68K_ATC_040;
 switch (size) {
@@ -862,29 +877,19 @@ int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size, int rw,
 if (!(access_type & ACCESS_STORE)) {
 env->mmu.ssw |= M68K_RW_040;
 }
-env->mmu.ar = address;

[Qemu-devel] [PATCH v3 27/27] tcg: Use tlb_fill probe from tlb_vaddr_to_host

2019-05-09 Thread Richard Henderson
Most of the existing users would continue around a loop which
would fault the tlb entry in via a normal load/store.

But for AArch64 SVE we have an existing emulation bug wherein we
would mark the first element of a no-fault vector load as faulted
(within the FFR, not via exception) just because we did not have
its address in the TLB.  Now we can properly only mark it as faulted
if there really is no valid, readable translation, while still not
raising an exception.  (Note that beyond the first element of the
vector, the hardware may report a fault for any reason whatsoever;
with at least one element loaded, forward progress is guaranteed.)

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v2: Update function docs comment.
---
 include/exec/cpu_ldst.h | 50 ++---
 accel/tcg/cputlb.c  | 69 -
 target/arm/sve_helper.c |  6 +---
 3 files changed, 72 insertions(+), 53 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index d78041d7a0..7b28a839d2 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -433,50 +433,20 @@ static inline CPUTLBEntry *tlb_entry(CPUArchState *env, 
uintptr_t mmu_idx,
  * @mmu_idx: MMU index to use for lookup
  *
  * Look up the specified guest virtual index in the TCG softmmu TLB.
- * If the TLB contains a host virtual address suitable for direct RAM
- * access, then return it. Otherwise (TLB miss, TLB entry is for an
- * I/O access, etc) return NULL.
- *
- * This is the equivalent of the initial fast-path code used by
- * TCG backends for guest load and store accesses.
+ * If we can translate a host virtual address suitable for direct RAM
+ * access, without causing a guest exception, then return it.
+ * Otherwise (TLB entry is for an I/O access, guest software
+ * TLB fill required, etc) return NULL.
  */
+#ifdef CONFIG_USER_ONLY
 static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
-  int access_type, int mmu_idx)
+  MMUAccessType access_type, int mmu_idx)
 {
-#if defined(CONFIG_USER_ONLY)
 return g2h(addr);
-#else
-CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
-abi_ptr tlb_addr;
-uintptr_t haddr;
-
-switch (access_type) {
-case 0:
-tlb_addr = tlbentry->addr_read;
-break;
-case 1:
-tlb_addr = tlb_addr_write(tlbentry);
-break;
-case 2:
-tlb_addr = tlbentry->addr_code;
-break;
-default:
-g_assert_not_reached();
-}
-
-if (!tlb_hit(tlb_addr, addr)) {
-/* TLB entry is for a different page */
-return NULL;
-}
-
-if (tlb_addr & ~TARGET_PAGE_MASK) {
-/* IO access */
-return NULL;
-}
-
-haddr = addr + tlbentry->addend;
-return (void *)haddr;
-#endif /* defined(CONFIG_USER_ONLY) */
 }
+#else
+void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
+MMUAccessType access_type, int mmu_idx);
+#endif
 
 #endif /* CPU_LDST_H */
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index dfcd9ae168..45a5c4e123 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1007,6 +1007,16 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 }
 }
 
+static inline target_ulong tlb_read_ofs(CPUTLBEntry *entry, size_t ofs)
+{
+#if TCG_OVERSIZED_GUEST
+return *(target_ulong *)((uintptr_t)entry + ofs);
+#else
+/* ofs might correspond to .addr_write, so use atomic_read */
+return atomic_read((target_ulong *)((uintptr_t)entry + ofs));
+#endif
+}
+
 /* Return true if ADDR is present in the victim tlb, and has been copied
back to the main tlb.  */
 static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
@@ -1017,14 +1027,7 @@ static bool victim_tlb_hit(CPUArchState *env, size_t 
mmu_idx, size_t index,
 assert_cpu_is_self(ENV_GET_CPU(env));
 for (vidx = 0; vidx < CPU_VTLB_SIZE; ++vidx) {
 CPUTLBEntry *vtlb = >tlb_v_table[mmu_idx][vidx];
-target_ulong cmp;
-
-/* elt_ofs might correspond to .addr_write, so use atomic_read */
-#if TCG_OVERSIZED_GUEST
-cmp = *(target_ulong *)((uintptr_t)vtlb + elt_ofs);
-#else
-cmp = atomic_read((target_ulong *)((uintptr_t)vtlb + elt_ofs));
-#endif
+target_ulong cmp = tlb_read_ofs(vtlb, elt_ofs);
 
 if (cmp == page) {
 /* Found entry in victim tlb, swap tlb and iotlb.  */
@@ -1108,6 +,56 @@ void probe_write(CPUArchState *env, target_ulong addr, 
int size, int mmu_idx,
 }
 }
 
+void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
+MMUAccessType access_type, int mmu_idx)
+{
+CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
+uintptr_t tlb_addr, page;
+size_t elt_ofs;
+
+switch (access_type) {
+case MMU_DATA_LOAD:
+elt_ofs = offsetof(CPUTLBEntry, 

[Qemu-devel] [PATCH v3 24/27] target/xtensa: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Max Filippov 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only and system tlb_fill separate.
---
 target/xtensa/cpu.h|  5 +++--
 target/xtensa/cpu.c|  5 ++---
 target/xtensa/helper.c | 39 ++-
 3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 5d23e1345b..68d89f8faf 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -552,8 +552,9 @@ static inline XtensaCPU *xtensa_env_get_cpu(const 
CPUXtensaState *env)
 #define ENV_OFFSET offsetof(XtensaCPU, env)
 
 
-int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int size,
-int mmu_idx);
+bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 void xtensa_cpu_do_interrupt(CPUState *cpu);
 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr 
addr,
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index a54dbe4260..da1236377e 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -181,9 +181,8 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->gdb_read_register = xtensa_cpu_gdb_read_register;
 cc->gdb_write_register = xtensa_cpu_gdb_write_register;
 cc->gdb_stop_before_watchpoint = true;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = xtensa_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = xtensa_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
 cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
 cc->do_transaction_failed = xtensa_cpu_do_transaction_failed;
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index 5f37f378a3..5c94f934dd 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -240,19 +240,21 @@ void xtensa_cpu_list(void)
 
 #ifdef CONFIG_USER_ONLY
 
-int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-int mmu_idx)
+bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
 {
 XtensaCPU *cpu = XTENSA_CPU(cs);
 CPUXtensaState *env = >env;
 
 qemu_log_mask(CPU_LOG_INT,
   "%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n",
-  __func__, rw, address, size);
+  __func__, access_type, address, size);
 env->sregs[EXCVADDR] = address;
-env->sregs[EXCCAUSE] = rw ? STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE;
+env->sregs[EXCCAUSE] = (access_type == MMU_DATA_STORE ?
+STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE);
 cs->exception_index = EXC_USER;
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else
@@ -273,31 +275,42 @@ void xtensa_cpu_do_unaligned_access(CPUState *cs,
 }
 }
 
-void tlb_fill(CPUState *cs, target_ulong vaddr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
 {
 XtensaCPU *cpu = XTENSA_CPU(cs);
 CPUXtensaState *env = >env;
 uint32_t paddr;
 uint32_t page_size;
 unsigned access;
-int ret = xtensa_get_physical_addr(env, true, vaddr, access_type, mmu_idx,
-   , _size, );
+int ret = xtensa_get_physical_addr(env, true, address, access_type,
+   mmu_idx, , _size, );
 
-qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
-  __func__, vaddr, access_type, mmu_idx, paddr, ret);
+qemu_log_mask(CPU_LOG_MMU, "%s(%08" VADDR_PRIx
+  ", %d, %d) -> %08x, ret = %d\n",
+  __func__, address, access_type, mmu_idx, paddr, ret);
 
 if (ret == 0) {
 tlb_set_page(cs,
- vaddr & TARGET_PAGE_MASK,
+ address & TARGET_PAGE_MASK,
  paddr & TARGET_PAGE_MASK,
  access, mmu_idx, page_size);
+return true;
+} else if (probe) {
+return false;
 } else {
 cpu_restore_state(cs, retaddr, true);
-HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr);
+HELPER(exception_cause_vaddr)(env, env->pc, ret, address);
 }
 }
 
+void tlb_fill(CPUState *cs, target_ulong vaddr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+xtensa_cpu_tlb_fill(cs, vaddr, size, access_type, mmu_idx, false, retaddr);
+}
+
 void xtensa_cpu_do_transaction_failed(CPUState 

[Qemu-devel] [PATCH v3 07/27] target/lm32: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Michael Walle 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/lm32/cpu.h   |  5 +++--
 target/lm32/cpu.c   |  5 ++---
 target/lm32/helper.c| 12 +---
 target/lm32/op_helper.c | 16 
 4 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index 9b1e6c2d58..d224d4426e 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -261,8 +261,9 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
 #define cpu_list lm32_cpu_list
 #define cpu_signal_handler cpu_lm32_signal_handler
 
-int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 
 #include "exec/cpu-all.h"
 
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 282da19994..57c50c1578 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -231,9 +231,8 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 cc->set_pc = lm32_cpu_set_pc;
 cc->gdb_read_register = lm32_cpu_gdb_read_register;
 cc->gdb_write_register = lm32_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = lm32_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = lm32_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
 cc->vmsd = _lm32_cpu;
 #endif
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
index a039a993ff..1db9a5562e 100644
--- a/target/lm32/helper.c
+++ b/target/lm32/helper.c
@@ -25,8 +25,9 @@
 #include "exec/semihost.h"
 #include "exec/log.h"
 
-int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
+bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 LM32CPU *cpu = LM32_CPU(cs);
 CPULM32State *env = >env;
@@ -40,8 +41,13 @@ int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size, int rw,
 } else {
 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
 }
+return true;
+}
 
-return 0;
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+lm32_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 
 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
diff --git a/target/lm32/op_helper.c b/target/lm32/op_helper.c
index 234d55e056..be12b11b02 100644
--- a/target/lm32/op_helper.c
+++ b/target/lm32/op_helper.c
@@ -143,21 +143,5 @@ uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
 {
 return lm32_juart_get_jrx(env->juart_state);
 }
-
-/* Try to fill the TLB and return an exception if error. If retaddr is
- * NULL, it means that the function was called in C code (i.e. not
- * from generated code or from helper.c)
- */
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-int ret;
-
-ret = lm32_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-if (unlikely(ret)) {
-/* now we have a real cpu fault */
-cpu_loop_exit_restore(cs, retaddr);
-}
-}
 #endif
 
-- 
2.17.1




[Qemu-devel] [PATCH v3 17/27] target/riscv: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Note that env->pc is removed from the qemu_log as that value is garbage.
The PC isn't recovered until cpu_restore_state, called from
cpu_loop_exit_restore, called from riscv_raise_exception.

Cc: qemu-ri...@nongnu.org
Cc: Palmer Dabbelt 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 target/riscv/cpu.h|  5 +++--
 target/riscv/cpu.c|  5 ++---
 target/riscv/cpu_helper.c | 46 ++-
 3 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7d9f48973f..c17184f4e4 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -261,8 +261,9 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr 
addr);
 void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 MMUAccessType access_type, int mmu_idx,
 uintptr_t retaddr);
-int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
-  int rw, int mmu_idx);
+bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(void);
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1bcf4eaeb8..34a54ef2ed 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -355,9 +355,8 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
 #endif
 cc->gdb_stop_before_watchpoint = true;
 cc->disas_set_info = riscv_cpu_disas_set_info;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = riscv_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = riscv_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
 cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
 #endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b17f169681..2535435260 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -379,53 +379,49 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 riscv_raise_exception(env, cs->exception_index, retaddr);
 }
 
-/* called by qemu's softmmu to fill the qemu tlb */
 void tlb_fill(CPUState *cs, target_ulong addr, int size,
 MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
-int ret;
-ret = riscv_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-if (ret == TRANSLATE_FAIL) {
-RISCVCPU *cpu = RISCV_CPU(cs);
-CPURISCVState *env = >env;
-riscv_raise_exception(env, cs->exception_index, retaddr);
-}
+riscv_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
-
 #endif
 
-int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-int rw, int mmu_idx)
+bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
+#ifndef CONFIG_USER_ONLY
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-#if !defined(CONFIG_USER_ONLY)
 hwaddr pa = 0;
 int prot;
-#endif
 int ret = TRANSLATE_FAIL;
 
-qemu_log_mask(CPU_LOG_MMU,
-"%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx \
- %d\n", __func__, env->pc, address, rw, mmu_idx);
+qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
+  __func__, address, access_type, mmu_idx);
+
+ret = get_physical_address(env, , , address, access_type, mmu_idx);
 
-#if !defined(CONFIG_USER_ONLY)
-ret = get_physical_address(env, , , address, rw, mmu_idx);
 qemu_log_mask(CPU_LOG_MMU,
-"%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
- " prot %d\n", __func__, address, ret, pa, prot);
+  "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
+  " prot %d\n", __func__, address, ret, pa, prot);
+
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
-!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << rw)) {
+!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type)) {
 ret = TRANSLATE_FAIL;
 }
 if (ret == TRANSLATE_SUCCESS) {
 tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
  prot, mmu_idx, TARGET_PAGE_SIZE);
-} else if (ret == TRANSLATE_FAIL) {
-raise_mmu_exception(env, address, rw);
+return true;
+} else if (probe) {
+return false;
+} else {
+raise_mmu_exception(env, address, access_type);
+riscv_raise_exception(env, cs->exception_index, retaddr);
 }
 #else
-switch (rw) {
+switch (access_type) {
 case MMU_INST_FETCH:
 cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
 break;
@@ -436,8 +432,8 @@ int 

[Qemu-devel] [PATCH v3 05/27] target/hppa: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/hppa/cpu.h|  8 
 target/hppa/cpu.c|  5 ++---
 target/hppa/mem_helper.c | 22 +-
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 923346adb6..c1e0215e66 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -360,10 +360,10 @@ int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t 
*buf, int reg);
 void hppa_cpu_do_interrupt(CPUState *cpu);
 bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
-#ifdef CONFIG_USER_ONLY
-int hppa_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
-  int rw, int midx);
-#else
+bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
+#ifndef CONFIG_USER_ONLY
 int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
   int type, hwaddr *pphys, int *pprot);
 extern const MemoryRegionOps hppa_io_eir_ops;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index e64f48581e..9717ea1798 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -163,9 +163,8 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
 cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
 cc->gdb_read_register = hppa_cpu_gdb_read_register;
 cc->gdb_write_register = hppa_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = hppa_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = hppa_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = hppa_cpu_get_phys_page_debug;
 dc->vmsd = _hppa_cpu;
 #endif
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 77fb544838..5cee0c19b1 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -25,8 +25,9 @@
 #include "trace.h"
 
 #ifdef CONFIG_USER_ONLY
-int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
-  int size, int rw, int mmu_idx)
+bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 HPPACPU *cpu = HPPA_CPU(cs);
 
@@ -34,7 +35,7 @@ int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
which would affect si_code.  */
 cs->exception_index = EXCP_DMP;
 cpu->env.cr[CR_IOR] = address;
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 #else
 static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
@@ -213,8 +214,9 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return excp == EXCP_DTLB_MISS ? -1 : phys;
 }
 
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType type, int mmu_idx, uintptr_t retaddr)
+bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+   MMUAccessType type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 HPPACPU *cpu = HPPA_CPU(cs);
 CPUHPPAState *env = >env;
@@ -236,6 +238,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
 excp = hppa_get_physical_address(env, addr, mmu_idx,
  a_prot, , );
 if (unlikely(excp >= 0)) {
+if (probe) {
+return false;
+}
 trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);
 /* Failure.  Raise the indicated exception.  */
 cs->exception_index = excp;
@@ -252,6 +257,13 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size,
 /* Success!  Store the translation into the QEMU TLB.  */
 tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
  prot, mmu_idx, TARGET_PAGE_SIZE);
+return true;
+}
+
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType type, int mmu_idx, uintptr_t retaddr)
+{
+hppa_cpu_tlb_fill(cs, addr, size, type, mmu_idx, false, retaddr);
 }
 
 /* Insert (Insn/Data) TLB Address.  Note this is PA 1.1 only.  */
-- 
2.17.1




[Qemu-devel] [PATCH v3 26/27] tcg: Remove CPUClass::handle_mmu_fault

2019-05-09 Thread Richard Henderson
This hook is now completely replaced by tlb_fill.

Reviewed-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/qom/cpu.h |  3 ---
 accel/tcg/user-exec.c | 13 +++--
 2 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index c1f267b4e0..32983f27c3 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -117,7 +117,6 @@ struct TranslationBlock;
  *   This always includes at least the program counter; some targets
  *   will need to do more. If this hook is not implemented then the
  *   default is to call @set_pc(tb->pc).
- * @handle_mmu_fault: Callback for handling an MMU fault.
  * @tlb_fill: Callback for handling a softmmu tlb miss or user-only
  *   address fault.  For system mode, if the access is valid, call
  *   tlb_set_page and return true; if the access is invalid, and
@@ -195,8 +194,6 @@ typedef struct CPUClass {
Error **errp);
 void (*set_pc)(CPUState *cpu, vaddr value);
 void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
-int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int size, int rw,
-int mmu_index);
 bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr);
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 199f88c826..8cfbeb1b56 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -63,7 +63,6 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
 {
 CPUState *cpu = current_cpu;
 CPUClass *cc;
-int ret;
 unsigned long address = (unsigned long)info->si_addr;
 MMUAccessType access_type;
 
@@ -156,15 +155,9 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
 helper_retaddr = 0;
 
 cc = CPU_GET_CLASS(cpu);
-if (cc->tlb_fill) {
-access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
-cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
-g_assert_not_reached();
-} else {
-ret = cc->handle_mmu_fault(cpu, address, 0, is_write, MMU_USER_IDX);
-g_assert(ret > 0);
-cpu_loop_exit_restore(cpu, pc);
-}
+access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
+cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
+g_assert_not_reached();
 }
 
 #if defined(__i386__)
-- 
2.17.1




[Qemu-devel] [PATCH v3 11/27] target/mips: Tidy control flow in mips_cpu_handle_mmu_fault

2019-05-09 Thread Richard Henderson
Since the only non-negative TLBRET_* value is TLBRET_MATCH,
the subsequent test for ret < 0 is useless.  Use early return
to allow subsequent blocks to be unindented.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/mips/helper.c | 54 
 1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index cc7be7703a..86e622efb8 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -915,41 +915,35 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size, int rw,
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
  physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
  mmu_idx, TARGET_PAGE_SIZE);
-ret = 0;
-} else if (ret < 0)
-#endif
-{
-#if !defined(CONFIG_USER_ONLY)
+return 0;
+}
 #if !defined(TARGET_MIPS64)
-if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) {
-/*
- * Memory reads during hardware page table walking are performed
- * as if they were kernel-mode load instructions.
- */
-int mode = (env->hflags & MIPS_HFLAG_KSU);
-bool ret_walker;
-env->hflags &= ~MIPS_HFLAG_KSU;
-ret_walker = page_table_walk_refill(env, address, rw, mmu_idx);
-env->hflags |= mode;
-if (ret_walker) {
-ret = get_physical_address(env, , ,
-   address, rw, access_type, mmu_idx);
-if (ret == TLBRET_MATCH) {
-tlb_set_page(cs, address & TARGET_PAGE_MASK,
-physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
-mmu_idx, TARGET_PAGE_SIZE);
-ret = 0;
-return ret;
-}
+if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) {
+/*
+ * Memory reads during hardware page table walking are performed
+ * as if they were kernel-mode load instructions.
+ */
+int mode = (env->hflags & MIPS_HFLAG_KSU);
+bool ret_walker;
+env->hflags &= ~MIPS_HFLAG_KSU;
+ret_walker = page_table_walk_refill(env, address, rw, mmu_idx);
+env->hflags |= mode;
+if (ret_walker) {
+ret = get_physical_address(env, , ,
+   address, rw, access_type, mmu_idx);
+if (ret == TLBRET_MATCH) {
+tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ mmu_idx, TARGET_PAGE_SIZE);
+return 0;
 }
 }
-#endif
-#endif
-raise_mmu_exception(env, address, rw, ret);
-ret = 1;
 }
+#endif
+#endif
 
-return ret;
+raise_mmu_exception(env, address, rw, ret);
+return 1;
 }
 
 #if !defined(CONFIG_USER_ONLY)
-- 
2.17.1




[Qemu-devel] [PATCH v3 14/27] target/nios2: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Remove the leftover debugging cpu_dump_state.

Cc: Chris Wulff 
Cc: Marek Vasut 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only and system tlb_fill separate.
---
 target/nios2/cpu.h|   5 +-
 target/nios2/cpu.c|   5 +-
 target/nios2/helper.c | 176 +-
 target/nios2/mmu.c|  12 ---
 4 files changed, 91 insertions(+), 107 deletions(-)

diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h
index 881e7d58c9..60a916b2e5 100644
--- a/target/nios2/cpu.h
+++ b/target/nios2/cpu.h
@@ -252,8 +252,9 @@ static inline int cpu_mmu_index(CPUNios2State *env, bool 
ifetch)
   MMU_SUPERVISOR_IDX;
 }
 
-int nios2_cpu_handle_mmu_fault(CPUState *env, vaddr address, int size,
-   int rw, int mmu_idx);
+bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 
 static inline int cpu_interrupts_enabled(CPUNios2State *env)
 {
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index fbfaa2ce26..186af4913d 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -200,9 +200,8 @@ static void nios2_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->dump_state = nios2_cpu_dump_state;
 cc->set_pc = nios2_cpu_set_pc;
 cc->disas_set_info = nios2_cpu_disas_set_info;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = nios2_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = nios2_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unaligned_access = nios2_cpu_do_unaligned_access;
 cc->get_phys_page_debug = nios2_cpu_get_phys_page_debug;
 #endif
diff --git a/target/nios2/helper.c b/target/nios2/helper.c
index e01fc1ff3e..eb2eed7ad3 100644
--- a/target/nios2/helper.c
+++ b/target/nios2/helper.c
@@ -38,15 +38,12 @@ void nios2_cpu_do_interrupt(CPUState *cs)
 env->regs[R_EA] = env->regs[R_PC] + 4;
 }
 
-int nios2_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
+bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 cs->exception_index = 0xaa;
-/* Page 0x1000 is kuser helper */
-if (address < 0x1000 || address >= 0x2000) {
-cpu_dump_state(cs, stderr, 0);
-}
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else /* !CONFIG_USER_ONLY */
@@ -203,89 +200,6 @@ void nios2_cpu_do_interrupt(CPUState *cs)
 }
 }
 
-static int cpu_nios2_handle_virtual_page(
-CPUState *cs, target_ulong address, int rw, int mmu_idx)
-{
-Nios2CPU *cpu = NIOS2_CPU(cs);
-CPUNios2State *env = >env;
-target_ulong vaddr, paddr;
-Nios2MMULookup lu;
-unsigned int hit;
-hit = mmu_translate(env, , address, rw, mmu_idx);
-if (hit) {
-vaddr = address & TARGET_PAGE_MASK;
-paddr = lu.paddr + vaddr - lu.vaddr;
-
-if (((rw == 0) && (lu.prot & PAGE_READ)) ||
-((rw == 1) && (lu.prot & PAGE_WRITE)) ||
-((rw == 2) && (lu.prot & PAGE_EXEC))) {
-
-tlb_set_page(cs, vaddr, paddr, lu.prot,
- mmu_idx, TARGET_PAGE_SIZE);
-return 0;
-} else {
-/* Permission violation */
-cs->exception_index = (rw == 0) ? EXCP_TLBR :
-   ((rw == 1) ? EXCP_TLBW :
-EXCP_TLBX);
-}
-} else {
-cs->exception_index = EXCP_TLBD;
-}
-
-if (rw == 2) {
-env->regs[CR_TLBMISC] &= ~CR_TLBMISC_D;
-} else {
-env->regs[CR_TLBMISC] |= CR_TLBMISC_D;
-}
-env->regs[CR_PTEADDR] &= CR_PTEADDR_PTBASE_MASK;
-env->regs[CR_PTEADDR] |= (address >> 10) & CR_PTEADDR_VPN_MASK;
-env->mmu.pteaddr_wr = env->regs[CR_PTEADDR];
-env->regs[CR_BADADDR] = address;
-return 1;
-}
-
-int nios2_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
-{
-Nios2CPU *cpu = NIOS2_CPU(cs);
-CPUNios2State *env = >env;
-
-if (cpu->mmu_present) {
-if (MMU_SUPERVISOR_IDX == mmu_idx) {
-if (address >= 0xC000) {
-/* Kernel physical page - TLB bypassed */
-address &= TARGET_PAGE_MASK;
-tlb_set_page(cs, address, address, PAGE_BITS,
- mmu_idx, TARGET_PAGE_SIZE);
-} else if (address >= 0x8000) {
-/* Kernel virtual page */
-return cpu_nios2_handle_virtual_page(cs, address, rw, mmu_idx);
-} else {
-/* User virtual page */
-return cpu_nios2_handle_virtual_page(cs, address, rw, mmu_idx);
-}
-} else {
-if (address >= 0x8000) {
-/* 

[Qemu-devel] [PATCH v3 19/27] target/sh4: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Aurelien Jarno 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/sh4/cpu.h   |   5 +-
 target/sh4/cpu.c   |   5 +-
 target/sh4/helper.c| 197 -
 target/sh4/op_helper.c |  12 ---
 4 files changed, 101 insertions(+), 118 deletions(-)

diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 1be36fe875..547194aac7 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -243,8 +243,9 @@ void superh_cpu_do_unaligned_access(CPUState *cpu, vaddr 
addr,
 void sh4_translate_init(void);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
void *puc);
-int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-int mmu_idx);
+bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 
 void sh4_cpu_list(void);
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index da2799082e..c4736a0a73 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -229,9 +229,8 @@ static void superh_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
 cc->gdb_read_register = superh_cpu_gdb_read_register;
 cc->gdb_write_register = superh_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = superh_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = superh_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unaligned_access = superh_cpu_do_unaligned_access;
 cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
 #endif
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index fa51269fb1..1517a6152f 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -27,43 +27,6 @@
 #include "hw/sh4/sh_intc.h"
 #endif
 
-#if defined(CONFIG_USER_ONLY)
-
-void superh_cpu_do_interrupt(CPUState *cs)
-{
-cs->exception_index = -1;
-}
-
-int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-int mmu_idx)
-{
-SuperHCPU *cpu = SUPERH_CPU(cs);
-CPUSH4State *env = >env;
-
-env->tea = address;
-cs->exception_index = -1;
-switch (rw) {
-case 0:
-cs->exception_index = 0x0a0;
-break;
-case 1:
-cs->exception_index = 0x0c0;
-break;
-case 2:
-cs->exception_index = 0x0a0;
-break;
-}
-return 1;
-}
-
-int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
-{
-/* For user mode, only U0 area is cacheable. */
-return !(addr & 0x8000);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
 #define MMU_OK   0
 #define MMU_ITLB_MISS(-1)
 #define MMU_ITLB_MULTIPLE(-2)
@@ -79,6 +42,21 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
 #define MMU_DADDR_ERROR_READ (-12)
 #define MMU_DADDR_ERROR_WRITE(-13)
 
+#if defined(CONFIG_USER_ONLY)
+
+void superh_cpu_do_interrupt(CPUState *cs)
+{
+cs->exception_index = -1;
+}
+
+int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
+{
+/* For user mode, only U0 area is cacheable. */
+return !(addr & 0x8000);
+}
+
+#else /* !CONFIG_USER_ONLY */
+
 void superh_cpu_do_interrupt(CPUState *cs)
 {
 SuperHCPU *cpu = SUPERH_CPU(cs);
@@ -458,69 +436,6 @@ static int get_physical_address(CPUSH4State * env, 
target_ulong * physical,
 return get_mmu_address(env, physical, prot, address, rw, access_type);
 }
 
-int superh_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-int mmu_idx)
-{
-SuperHCPU *cpu = SUPERH_CPU(cs);
-CPUSH4State *env = >env;
-target_ulong physical;
-int prot, ret, access_type;
-
-access_type = ACCESS_INT;
-ret =
-   get_physical_address(env, , , address, rw,
-access_type);
-
-if (ret != MMU_OK) {
-   env->tea = address;
-   if (ret != MMU_DTLB_MULTIPLE && ret != MMU_ITLB_MULTIPLE) {
-   env->pteh = (env->pteh & PTEH_ASID_MASK) |
-   (address & PTEH_VPN_MASK);
-   }
-   switch (ret) {
-   case MMU_ITLB_MISS:
-   case MMU_DTLB_MISS_READ:
-cs->exception_index = 0x040;
-   break;
-   case MMU_DTLB_MULTIPLE:
-   case MMU_ITLB_MULTIPLE:
-cs->exception_index = 0x140;
-   break;
-   case MMU_ITLB_VIOLATION:
-cs->exception_index = 0x0a0;
-   break;
-   case MMU_DTLB_MISS_WRITE:
-cs->exception_index = 0x060;
-   break;
-   case MMU_DTLB_INITIAL_WRITE:
-cs->exception_index = 0x080;
-   break;
-   case MMU_DTLB_VIOLATION_READ:
-cs->exception_index = 0x0a0;
-   break;
-   case MMU_DTLB_VIOLATION_WRITE:
-cs->exception_index = 0x0c0;
-   break;
-   case MMU_IADDR_ERROR:
-  

[Qemu-devel] [PATCH v3 15/27] target/openrisc: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: Stafford Horne 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/openrisc/cpu.h |  5 ++--
 target/openrisc/cpu.c |  5 ++--
 target/openrisc/mmu.c | 65 ++-
 3 files changed, 39 insertions(+), 36 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 88a8c70092..9473d94d0c 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -344,8 +344,9 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, 
vaddr addr);
 int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 void openrisc_translate_init(void);
-int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
-  int rw, int mmu_idx);
+bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
 int print_insn_or1k(bfd_vma addr, disassemble_info *info);
 
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index d125236977..3816baee70 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -149,9 +149,8 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->set_pc = openrisc_cpu_set_pc;
 cc->gdb_read_register = openrisc_cpu_gdb_read_register;
 cc->gdb_write_register = openrisc_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = openrisc_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = openrisc_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
 dc->vmsd = _openrisc_cpu;
 #endif
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 5dec68dcff..94c65a25fa 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -107,16 +107,42 @@ static void raise_mmu_exception(OpenRISCCPU *cpu, 
target_ulong address,
 cpu->env.lock_addr = -1;
 }
 
-int openrisc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-  int rw, int mmu_idx)
+bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
-#ifdef CONFIG_USER_ONLY
 OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-raise_mmu_exception(cpu, address, EXCP_DPF);
-return 1;
-#else
-g_assert_not_reached();
+int excp = EXCP_DPF;
+
+#ifndef CONFIG_USER_ONLY
+int prot;
+hwaddr phys_addr;
+
+if (mmu_idx == MMU_NOMMU_IDX) {
+/* The mmu is disabled; lookups never fail.  */
+get_phys_nommu(_addr, , addr);
+excp = 0;
+} else {
+bool super = mmu_idx == MMU_SUPERVISOR_IDX;
+int need = (access_type == MMU_INST_FETCH ? PAGE_EXEC
+: access_type == MMU_DATA_STORE ? PAGE_WRITE
+: PAGE_READ);
+excp = get_phys_mmu(cpu, _addr, , addr, need, super);
+}
+
+if (likely(excp == 0)) {
+tlb_set_page(cs, addr & TARGET_PAGE_MASK,
+ phys_addr & TARGET_PAGE_MASK, prot,
+ mmu_idx, TARGET_PAGE_SIZE);
+return true;
+}
+if (probe) {
+return false;
+}
 #endif
+
+raise_mmu_exception(cpu, addr, excp);
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -156,29 +182,6 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, 
vaddr addr)
 void tlb_fill(CPUState *cs, target_ulong addr, int size,
   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
-OpenRISCCPU *cpu = OPENRISC_CPU(cs);
-int prot, excp;
-hwaddr phys_addr;
-
-if (mmu_idx == MMU_NOMMU_IDX) {
-/* The mmu is disabled; lookups never fail.  */
-get_phys_nommu(_addr, , addr);
-excp = 0;
-} else {
-bool super = mmu_idx == MMU_SUPERVISOR_IDX;
-int need = (access_type == MMU_INST_FETCH ? PAGE_EXEC
-: access_type == MMU_DATA_STORE ? PAGE_WRITE
-: PAGE_READ);
-excp = get_phys_mmu(cpu, _addr, , addr, need, super);
-}
-
-if (unlikely(excp)) {
-raise_mmu_exception(cpu, addr, excp);
-cpu_loop_exit_restore(cs, retaddr);
-}
-
-tlb_set_page(cs, addr & TARGET_PAGE_MASK,
- phys_addr & TARGET_PAGE_MASK, prot,
- mmu_idx, TARGET_PAGE_SIZE);
+openrisc_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, 0, retaddr);
 }
 #endif
-- 
2.17.1




[Qemu-devel] [PATCH v3 12/27] target/mips: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Note that env->active_tc.PC is removed from the qemu_log as that value
is garbage.  The PC isn't recovered until cpu_restore_state, called from
cpu_loop_exit_restore, called from do_raise_exception_err.

Cc: Aleksandar Markovic 
Cc: Aleksandar Rikalo 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
v2: Split out other mips cleanups to simplify the diff
---
 target/mips/internal.h  |  5 +++--
 target/mips/cpu.c   |  5 ++---
 target/mips/helper.c| 45 ++---
 target/mips/op_helper.c | 15 --
 4 files changed, 29 insertions(+), 41 deletions(-)

diff --git a/target/mips/internal.h b/target/mips/internal.h
index 286e3888ab..b2b41a51ab 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -202,8 +202,9 @@ void cpu_mips_start_count(CPUMIPSState *env);
 void cpu_mips_stop_count(CPUMIPSState *env);
 
 /* helper.c */
-int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 
 /* op_helper.c */
 uint32_t float_class_s(uint32_t arg, float_status *fst);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index e217fb3e36..ebdb834b97 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -197,9 +197,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
 cc->gdb_read_register = mips_cpu_gdb_read_register;
 cc->gdb_write_register = mips_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = mips_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = mips_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_unassigned_access = mips_cpu_unassigned_access;
 cc->do_unaligned_access = mips_cpu_do_unaligned_access;
 cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
diff --git a/target/mips/helper.c b/target/mips/helper.c
index 86e622efb8..3a4917ce7b 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -874,31 +874,25 @@ refill:
 #endif
 #endif
 
-int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
+bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 MIPSCPU *cpu = MIPS_CPU(cs);
 CPUMIPSState *env = >env;
 #if !defined(CONFIG_USER_ONLY)
 hwaddr physical;
 int prot;
-int access_type;
+int mips_access_type;
 #endif
 int ret = TLBRET_BADADDR;
 
-#if 0
-log_cpu_state(cs, 0);
-#endif
-qemu_log_mask(CPU_LOG_MMU,
-  "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
-  __func__, env->active_tc.PC, address, rw, mmu_idx);
-
 /* data access */
 #if !defined(CONFIG_USER_ONLY)
 /* XXX: put correct access by using cpu_restore_state() correctly */
-access_type = ACCESS_INT;
-ret = get_physical_address(env, , ,
-   address, rw, access_type, mmu_idx);
+mips_access_type = ACCESS_INT;
+ret = get_physical_address(env, , , address,
+   access_type, mips_access_type, mmu_idx);
 switch (ret) {
 case TLBRET_MATCH:
 qemu_log_mask(CPU_LOG_MMU,
@@ -915,7 +909,7 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size, int rw,
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
  physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
  mmu_idx, TARGET_PAGE_SIZE);
-return 0;
+return true;
 }
 #if !defined(TARGET_MIPS64)
 if ((ret == TLBRET_NOMATCH) && (env->tlb->nb_tlb > 1)) {
@@ -926,27 +920,36 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr 
address, int size, int rw,
 int mode = (env->hflags & MIPS_HFLAG_KSU);
 bool ret_walker;
 env->hflags &= ~MIPS_HFLAG_KSU;
-ret_walker = page_table_walk_refill(env, address, rw, mmu_idx);
+ret_walker = page_table_walk_refill(env, address, access_type, 
mmu_idx);
 env->hflags |= mode;
 if (ret_walker) {
-ret = get_physical_address(env, , ,
-   address, rw, access_type, mmu_idx);
+ret = get_physical_address(env, , , address,
+   access_type, mips_access_type, mmu_idx);
 if (ret == TLBRET_MATCH) {
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
  physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
  mmu_idx, TARGET_PAGE_SIZE);
-return 0;
+return true;
 }
 }
 }
 #endif
+if (probe) {
+return false;
+}
 #endif
 
-

[Qemu-devel] [PATCH v3 22/27] target/tricore: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Acked-by: Bastian Koppelmann 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/tricore/cpu.h   |  6 +++---
 target/tricore/cpu.c   |  1 +
 target/tricore/helper.c| 27 +++
 target/tricore/op_helper.c | 26 --
 4 files changed, 23 insertions(+), 37 deletions(-)

diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h
index 64d1a9c75e..287f4328a3 100644
--- a/target/tricore/cpu.h
+++ b/target/tricore/cpu.h
@@ -417,8 +417,8 @@ static inline void cpu_get_tb_cpu_state(CPUTriCoreState 
*env, target_ulong *pc,
 #define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU
 
 /* helpers.c */
-int cpu_tricore_handle_mmu_fault(CPUState *cpu, target_ulong address,
- int rw, int mmu_idx);
-#define cpu_handle_mmu_fault cpu_tricore_handle_mmu_fault
+bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
 
 #endif /* TRICORE_CPU_H */
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index e8d37e4040..ea1199d27e 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -166,6 +166,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void 
*data)
 cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
 cc->get_phys_page_attrs_debug = tricore_cpu_get_phys_page_attrs_debug;
 cc->tcg_initialize = tricore_tcg_init;
+cc->tlb_fill = tricore_cpu_tlb_fill;
 }
 
 #define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
index 78ee87c9ea..ed184fee3a 100644
--- a/target/tricore/helper.c
+++ b/target/tricore/helper.c
@@ -50,8 +50,9 @@ static void raise_mmu_exception(CPUTriCoreState *env, 
target_ulong address,
 {
 }
 
-int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
- int rw, int mmu_idx)
+bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType rw, int mmu_idx,
+  bool probe, uintptr_t retaddr)
 {
 TriCoreCPU *cpu = TRICORE_CPU(cs);
 CPUTriCoreState *env = >env;
@@ -64,20 +65,30 @@ int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong 
address,
 access_type = ACCESS_INT;
 ret = get_physical_address(env, , ,
address, rw, access_type);
-qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical " 
TARGET_FMT_plx
-  " prot %d\n", __func__, address, ret, physical, prot);
+
+qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical "
+  TARGET_FMT_plx " prot %d\n",
+  __func__, (target_ulong)address, ret, physical, prot);
 
 if (ret == TLBRET_MATCH) {
 tlb_set_page(cs, address & TARGET_PAGE_MASK,
  physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
  mmu_idx, TARGET_PAGE_SIZE);
-ret = 0;
-} else if (ret < 0) {
+return true;
+} else {
+assert(ret < 0);
+if (probe) {
+return false;
+}
 raise_mmu_exception(env, address, rw, ret);
-ret = 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
+}
 
-return ret;
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+tricore_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 
 static void tricore_cpu_list_entry(gpointer data, gpointer user_data)
diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c
index ed9dc0c83e..601e92f92a 100644
--- a/target/tricore/op_helper.c
+++ b/target/tricore/op_helper.c
@@ -2793,29 +2793,3 @@ uint32_t helper_psw_read(CPUTriCoreState *env)
 {
 return psw_read(env);
 }
-
-
-static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
-uint32_t exception,
-int error_code,
-uintptr_t pc)
-{
-CPUState *cs = CPU(tricore_env_get_cpu(env));
-cs->exception_index = exception;
-env->error_code = error_code;
-/* now we have a real cpu fault */
-cpu_loop_exit_restore(cs, pc);
-}
-
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-int ret;
-ret = cpu_tricore_handle_mmu_fault(cs, addr, access_type, mmu_idx);
-if (ret) {
-TriCoreCPU *cpu = TRICORE_CPU(cs);
-CPUTriCoreState *env = >env;
-do_raise_exception_err(env, cs->exception_index,
-   env->error_code, retaddr);
-}
-}
-- 
2.17.1




[Qemu-devel] [PATCH v3 01/27] tcg: Add CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
This hook will replace the (user-only mode specific) handle_mmu_fault
hook, and the (system mode specific) tlb_fill function.

The handle_mmu_fault hook was written as if there was a valid
way to recover from an mmu fault, and had 3 possible return states.
In reality, the only valid action is to raise an exception,
return to the main loop, and deliver the SIGSEGV to the guest.

Note that all of the current implementations of handle_mmu_fault
for guests which support linux-user do in fact only ever return 1,
which is the signal to return to the main loop.

Using the hook for system mode requires that all targets be converted,
so for now the hook is (optionally) used only from user-only mode.

Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 include/qom/cpu.h |  9 +
 accel/tcg/user-exec.c | 39 ++-
 2 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 08abcbd3fe..c1f267b4e0 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -118,6 +118,12 @@ struct TranslationBlock;
  *   will need to do more. If this hook is not implemented then the
  *   default is to call @set_pc(tb->pc).
  * @handle_mmu_fault: Callback for handling an MMU fault.
+ * @tlb_fill: Callback for handling a softmmu tlb miss or user-only
+ *   address fault.  For system mode, if the access is valid, call
+ *   tlb_set_page and return true; if the access is invalid, and
+ *   probe is true, return false; otherwise raise an exception and
+ *   do not return.  For user-only mode, always raise an exception
+ *   and do not return.
  * @get_phys_page_debug: Callback for obtaining a physical address.
  * @get_phys_page_attrs_debug: Callback for obtaining a physical address and 
the
  *   associated memory transaction attributes to use for the access.
@@ -191,6 +197,9 @@ typedef struct CPUClass {
 void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
 int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int size, int rw,
 int mmu_index);
+bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
 hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
 hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr,
 MemTxAttrs *attrs);
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 0789984fe6..199f88c826 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -65,6 +65,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t 
*info,
 CPUClass *cc;
 int ret;
 unsigned long address = (unsigned long)info->si_addr;
+MMUAccessType access_type;
 
 /* We must handle PC addresses from two different sources:
  * a call return address and a signal frame address.
@@ -147,35 +148,23 @@ static inline int handle_cpu_signal(uintptr_t pc, 
siginfo_t *info,
are still valid segv ones */
 address = h2g_nocheck(address);
 
-cc = CPU_GET_CLASS(cpu);
-/* see if it is an MMU fault */
-g_assert(cc->handle_mmu_fault);
-ret = cc->handle_mmu_fault(cpu, address, 0, is_write, MMU_USER_IDX);
-
-if (ret == 0) {
-/* The MMU fault was handled without causing real CPU fault.
- *  Retain helper_retaddr for a possible second fault.
- */
-return 1;
-}
-
-/* All other paths lead to cpu_exit; clear helper_retaddr
- * for next execution.
+/*
+ * There is no way the target can handle this other than raising
+ * an exception.  Undo signal and retaddr state prior to longjmp.
  */
+sigprocmask(SIG_SETMASK, old_set, NULL);
 helper_retaddr = 0;
 
-if (ret < 0) {
-return 0; /* not an MMU fault */
+cc = CPU_GET_CLASS(cpu);
+if (cc->tlb_fill) {
+access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
+cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
+g_assert_not_reached();
+} else {
+ret = cc->handle_mmu_fault(cpu, address, 0, is_write, MMU_USER_IDX);
+g_assert(ret > 0);
+cpu_loop_exit_restore(cpu, pc);
 }
-
-/* Now we have a real cpu fault.  */
-cpu_restore_state(cpu, pc, true);
-
-sigprocmask(SIG_SETMASK, old_set, NULL);
-cpu_loop_exit(cpu);
-
-/* never comes here */
-return 1;
 }
 
 #if defined(__i386__)
-- 
2.17.1




[Qemu-devel] [PATCH v3 06/27] target/i386: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
We do not support probing, but we do not need it yet either.

Cc: Paolo Bonzini 
Cc: Eduardo Habkost 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/i386/cpu.h |  5 ++--
 target/i386/cpu.c |  5 ++--
 target/i386/excp_helper.c | 61 +--
 target/i386/mem_helper.c  | 21 --
 4 files changed, 44 insertions(+), 48 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 0128910661..fce6660bac 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1656,8 +1656,9 @@ void host_cpuid(uint32_t function, uint32_t count,
 void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
 
 /* helper.c */
-int x86_cpu_handle_mmu_fault(CPUState *cpu, vaddr addr, int size,
- int is_write, int mmu_idx);
+bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
 void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 722c5514d4..3c98869577 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5915,9 +5915,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 cc->gdb_write_register = x86_cpu_gdb_write_register;
 cc->get_arch_id = x86_cpu_get_arch_id;
 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = x86_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->asidx_from_attrs = x86_asidx_from_attrs;
 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
diff --git a/target/i386/excp_helper.c b/target/i386/excp_helper.c
index 49231f6b69..68bf8e3f7c 100644
--- a/target/i386/excp_helper.c
+++ b/target/i386/excp_helper.c
@@ -137,26 +137,7 @@ void raise_exception_ra(CPUX86State *env, int 
exception_index, uintptr_t retaddr
 raise_interrupt2(env, exception_index, 0, 0, 0, retaddr);
 }
 
-#if defined(CONFIG_USER_ONLY)
-int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int size,
- int is_write, int mmu_idx)
-{
-X86CPU *cpu = X86_CPU(cs);
-CPUX86State *env = >env;
-
-/* user mode only emulation */
-is_write &= 1;
-env->cr[2] = addr;
-env->error_code = (is_write << PG_ERROR_W_BIT);
-env->error_code |= PG_ERROR_U_MASK;
-cs->exception_index = EXCP0E_PAGE;
-env->exception_is_int = 0;
-env->exception_next_eip = -1;
-return 1;
-}
-
-#else
-
+#if !defined(CONFIG_USER_ONLY)
 static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type,
 int *prot)
 {
@@ -365,8 +346,8 @@ static hwaddr get_hphys(CPUState *cs, hwaddr gphys, 
MMUAccessType access_type,
  * 0  = nothing more to do
  * 1  = generate PF fault
  */
-int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int size,
- int is_write1, int mmu_idx)
+static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
+int is_write1, int mmu_idx)
 {
 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = >env;
@@ -691,3 +672,39 @@ do_check_protect_pse36:
 return 1;
 }
 #endif
+
+bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr)
+{
+X86CPU *cpu = X86_CPU(cs);
+CPUX86State *env = >env;
+
+#ifdef CONFIG_USER_ONLY
+/* user mode only emulation */
+env->cr[2] = addr;
+env->error_code = (access_type == MMU_DATA_STORE) << PG_ERROR_W_BIT;
+env->error_code |= PG_ERROR_U_MASK;
+cs->exception_index = EXCP0E_PAGE;
+env->exception_is_int = 0;
+env->exception_next_eip = -1;
+cpu_loop_exit_restore(cs, retaddr);
+#else
+env->retaddr = retaddr;
+if (handle_mmu_fault(cs, addr, size, access_type, mmu_idx)) {
+/* FIXME: On error in get_hphys we have already jumped out.  */
+g_assert(!probe);
+raise_exception_err_ra(env, cs->exception_index,
+   env->error_code, retaddr);
+}
+return true;
+#endif
+}
+
+#if !defined(CONFIG_USER_ONLY)
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+x86_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
+}
+#endif
diff --git a/target/i386/mem_helper.c b/target/i386/mem_helper.c
index 6cc53bcb40..1885df29d2 100644
--- a/target/i386/mem_helper.c
+++ b/target/i386/mem_helper.c
@@ -191,24 +191,3 @@ void helper_boundl(CPUX86State *env, target_ulong a0, int 
v)
 raise_exception_ra(env, EXCP05_BOUND, GETPC());
 }
 }
-
-#if !defined(CONFIG_USER_ONLY)
-/* try to fill the TLB and return an exception if error. If retaddr is
- * 

[Qemu-devel] [PATCH v3 04/27] target/cris: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Remove dumping of cpu state.  Remove logging of PC, as that
value is garbage until cpu_restore_state.

Cc: Edgar E. Iglesias 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/cris/cpu.h   |  5 +--
 target/cris/cpu.c   |  5 ++-
 target/cris/helper.c| 67 +++--
 target/cris/op_helper.c | 28 -
 4 files changed, 42 insertions(+), 63 deletions(-)

diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 0fbe771639..857de79e24 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -281,8 +281,9 @@ static inline int cpu_mmu_index (CPUCRISState *env, bool 
ifetch)
return !!(env->pregs[PR_CCS] & U_FLAG);
 }
 
-int cris_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-  int mmu_idx);
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr);
 
 /* Support function regs.  */
 #define SFR_RW_GC_CFG  0][0
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 75729bfdd5..4e5288ae80 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -269,9 +269,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 cc->set_pc = cris_cpu_set_pc;
 cc->gdb_read_register = cris_cpu_gdb_read_register;
 cc->gdb_write_register = cris_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = cris_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = cris_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
 dc->vmsd = _cris_cpu;
 #endif
diff --git a/target/cris/helper.c b/target/cris/helper.c
index 3939603c73..69464837c8 100644
--- a/target/cris/helper.c
+++ b/target/cris/helper.c
@@ -24,6 +24,7 @@
 #include "qemu/host-utils.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
 
 
 //#define CRIS_HELPER_DEBUG
@@ -53,15 +54,15 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
 cris_cpu_do_interrupt(cs);
 }
 
-int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 CRISCPU *cpu = CRIS_CPU(cs);
 
 cs->exception_index = 0xaa;
 cpu->env.pregs[PR_EDA] = address;
-cpu_dump_state(cs, stderr, 0);
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 #else /* !CONFIG_USER_ONLY */
@@ -76,33 +77,19 @@ static void cris_shift_ccs(CPUCRISState *env)
 env->pregs[PR_CCS] = ccs;
 }
 
-int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw,
-  int mmu_idx)
+bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+   MMUAccessType access_type, int mmu_idx,
+   bool probe, uintptr_t retaddr)
 {
 CRISCPU *cpu = CRIS_CPU(cs);
 CPUCRISState *env = >env;
 struct cris_mmu_result res;
 int prot, miss;
-int r = -1;
 target_ulong phy;
 
-qemu_log_mask(CPU_LOG_MMU, "%s addr=%" VADDR_PRIx " pc=%x rw=%x\n",
-__func__, address, env->pc, rw);
 miss = cris_mmu_translate(, env, address & TARGET_PAGE_MASK,
-  rw, mmu_idx, 0);
-if (miss) {
-if (cs->exception_index == EXCP_BUSFAULT) {
-cpu_abort(cs,
-  "CRIS: Illegal recursive bus fault."
-  "addr=%" VADDR_PRIx " rw=%d\n",
-  address, rw);
-}
-
-env->pregs[PR_EDA] = address;
-cs->exception_index = EXCP_BUSFAULT;
-env->fault_vector = res.bf_vec;
-r = 1;
-} else {
+  access_type, mmu_idx, 0);
+if (likely(!miss)) {
 /*
  * Mask off the cache selection bit. The ETRAX busses do not
  * see the top bit.
@@ -111,15 +98,35 @@ int cris_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size, int rw,
 prot = res.prot;
 tlb_set_page(cs, address & TARGET_PAGE_MASK, phy,
  prot, mmu_idx, TARGET_PAGE_SIZE);
-r = 0;
+return true;
 }
-if (r > 0) {
-qemu_log_mask(CPU_LOG_MMU,
-"%s returns %d irqreq=%x addr=%" VADDR_PRIx " phy=%x vec=%x"
-" pc=%x\n", __func__, r, cs->interrupt_request, address,
-res.phy, res.bf_vec, env->pc);
+
+if (probe) {
+return false;
 }
-return r;
+
+if (cs->exception_index == EXCP_BUSFAULT) {
+cpu_abort(cs, "CRIS: Illegal recursive bus fault."
+  "addr=%" VADDR_PRIx " access_type=%d\n",
+  address, access_type);
+}
+
+env->pregs[PR_EDA] = address;
+cs->exception_index = EXCP_BUSFAULT;
+

[Qemu-devel] [PATCH v3 02/27] target/alpha: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v2: Keep user-only and system tlb_fill separate.
---
 target/alpha/cpu.h|  5 +++--
 target/alpha/cpu.c|  5 ++---
 target/alpha/helper.c | 30 +-
 target/alpha/mem_helper.c | 16 
 4 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 63bf3618ff..cf09112b6a 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -475,8 +475,9 @@ void alpha_cpu_list(void);
is returned if the signal was handled by the virtual CPU.  */
 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
  void *puc);
-int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
-   int mmu_idx);
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index ad3588a44a..7c81be4111 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -225,9 +225,8 @@ static void alpha_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->set_pc = alpha_cpu_set_pc;
 cc->gdb_read_register = alpha_cpu_gdb_read_register;
 cc->gdb_write_register = alpha_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = alpha_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = alpha_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_transaction_failed = alpha_cpu_do_transaction_failed;
 cc->do_unaligned_access = alpha_cpu_do_unaligned_access;
 cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
diff --git a/target/alpha/helper.c b/target/alpha/helper.c
index 7201576aae..929a217455 100644
--- a/target/alpha/helper.c
+++ b/target/alpha/helper.c
@@ -104,14 +104,15 @@ void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, 
uint64_t val)
 }
 
 #if defined(CONFIG_USER_ONLY)
-int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 AlphaCPU *cpu = ALPHA_CPU(cs);
 
 cs->exception_index = EXCP_MMFAULT;
 cpu->env.trap_arg0 = address;
-return 1;
+cpu_loop_exit_restore(cs, retaddr);
 }
 #else
 /* Returns the OSF/1 entMM failure indication, or -1 on success.  */
@@ -248,26 +249,37 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 return (fail >= 0 ? -1 : phys);
 }
 
-int alpha_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, int size, int rw,
-   int mmu_idx)
+bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 AlphaCPU *cpu = ALPHA_CPU(cs);
 CPUAlphaState *env = >env;
 target_ulong phys;
 int prot, fail;
 
-fail = get_physical_address(env, addr, 1 << rw, mmu_idx, , );
+fail = get_physical_address(env, addr, 1 << access_type,
+mmu_idx, , );
 if (unlikely(fail >= 0)) {
+if (probe) {
+return false;
+}
 cs->exception_index = EXCP_MMFAULT;
 env->trap_arg0 = addr;
 env->trap_arg1 = fail;
-env->trap_arg2 = (rw == 2 ? -1 : rw);
-return 1;
+env->trap_arg2 = (access_type == MMU_INST_FETCH ? -1 : access_type);
+cpu_loop_exit_restore(cs, retaddr);
 }
 
 tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK,
  prot, mmu_idx, TARGET_PAGE_SIZE);
-return 0;
+return true;
+}
+
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
+{
+alpha_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 #endif /* USER_ONLY */
 
diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c
index 011bc73dca..934faa1d6f 100644
--- a/target/alpha/mem_helper.c
+++ b/target/alpha/mem_helper.c
@@ -62,20 +62,4 @@ void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 env->error_code = 0;
 cpu_loop_exit_restore(cs, retaddr);
 }
-
-/* try to fill the TLB and return an exception if error. If retaddr is
-   NULL, it means that the function was called in C code (i.e. not
-   from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, int size,
-  MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
-{
-  

[Qemu-devel] [PATCH v3 10/27] target/mips: Pass a valid error to raise_mmu_exception for user-only

2019-05-09 Thread Richard Henderson
At present we give ret = 0, or TLBRET_MATCH.  This gets matched
by the default case, which falls through to TLBRET_BADADDR.
However, it makes more sense to use a proper value.  All of the
tlb-related exceptions are handled identically in cpu_loop.c,
so TLBRET_BADADDR is as good as any other.  Retain it.

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

diff --git a/target/mips/helper.c b/target/mips/helper.c
index c44cdca3b5..cc7be7703a 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -884,7 +884,7 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size, int rw,
 int prot;
 int access_type;
 #endif
-int ret = 0;
+int ret = TLBRET_BADADDR;
 
 #if 0
 log_cpu_state(cs, 0);
-- 
2.17.1




[Qemu-devel] [PATCH v3 03/27] target/arm: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Cc: qemu-...@nongnu.org
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v2: Reword a comment to match the new interface.
---
 target/arm/internals.h | 10 +++--
 target/arm/cpu.c   | 22 +-
 target/arm/helper.c| 98 ++
 target/arm/op_helper.c | 29 ++---
 4 files changed, 73 insertions(+), 86 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 587a1ddf58..5a02f458f3 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -761,10 +761,12 @@ static inline bool arm_extabort_type(MemTxResult result)
 return result != MEMTX_DECODE_ERROR;
 }
 
-/* Do a page table walk and add page to TLB if possible */
-bool arm_tlb_fill(CPUState *cpu, vaddr address,
-  MMUAccessType access_type, int mmu_idx,
-  ARMMMUFaultInfo *fi);
+bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr);
+
+void arm_deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
+   int mmu_idx, ARMMMUFaultInfo *fi) QEMU_NORETURN;
 
 /* Return true if the stage 1 translation regime is using LPAE format page
  * tables */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a181fa8dc1..bb8e824c3e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2133,23 +2133,6 @@ static Property arm_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST()
 };
 
-#ifdef CONFIG_USER_ONLY
-static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-int rw, int mmu_idx)
-{
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-
-env->exception.vaddress = address;
-if (rw == 2) {
-cs->exception_index = EXCP_PREFETCH_ABORT;
-} else {
-cs->exception_index = EXCP_DATA_ABORT;
-}
-return 1;
-}
-#endif
-
 static gchar *arm_gdb_arch_name(CPUState *cs)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -2182,9 +2165,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
 cc->gdb_read_register = arm_cpu_gdb_read_register;
 cc->gdb_write_register = arm_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = arm_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->do_interrupt = arm_cpu_do_interrupt;
 cc->do_unaligned_access = arm_cpu_do_unaligned_access;
 cc->do_transaction_failed = arm_cpu_do_transaction_failed;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1e6eb0d0f3..f1a2b94ddb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12596,43 +12596,6 @@ static bool get_phys_addr(CPUARMState *env, 
target_ulong address,
 }
 }
 
-/* Walk the page table and (if the mapping exists) add the page
- * to the TLB. Return false on success, or true on failure. Populate
- * fsr with ARM DFSR/IFSR fault register format value on failure.
- */
-bool arm_tlb_fill(CPUState *cs, vaddr address,
-  MMUAccessType access_type, int mmu_idx,
-  ARMMMUFaultInfo *fi)
-{
-ARMCPU *cpu = ARM_CPU(cs);
-CPUARMState *env = >env;
-hwaddr phys_addr;
-target_ulong page_size;
-int prot;
-int ret;
-MemTxAttrs attrs = {};
-
-ret = get_phys_addr(env, address, access_type,
-core_to_arm_mmu_idx(env, mmu_idx), _addr,
-, , _size, fi, NULL);
-if (!ret) {
-/*
- * Map a single [sub]page. Regions smaller than our declared
- * target page size are handled specially, so for those we
- * pass in the exact addresses.
- */
-if (page_size >= TARGET_PAGE_SIZE) {
-phys_addr &= TARGET_PAGE_MASK;
-address &= TARGET_PAGE_MASK;
-}
-tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
-prot, mmu_idx, page_size);
-return 0;
-}
-
-return ret;
-}
-
 hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
  MemTxAttrs *attrs)
 {
@@ -13111,6 +13074,67 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t 
addr, uint32_t op)
 
 #endif
 
+bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+  MMUAccessType access_type, int mmu_idx,
+  bool probe, uintptr_t retaddr)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+
+#ifdef CONFIG_USER_ONLY
+cpu->env.exception.vaddress = address;
+if (access_type == MMU_INST_FETCH) {
+cs->exception_index = EXCP_PREFETCH_ABORT;
+} else {
+cs->exception_index = EXCP_DATA_ABORT;
+}
+cpu_loop_exit_restore(cs, retaddr);
+#else
+hwaddr phys_addr;
+target_ulong page_size;
+int prot, ret;
+MemTxAttrs attrs = {};
+ARMMMUFaultInfo fi = {};
+
+/*
+ * Walk the 

[Qemu-devel] [PATCH v3 13/27] target/moxie: Convert to CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Remove the user-only functions, as we don't have a user-only config.
Fix the unconditional call to tlb_set_page, even if the translation
failed.

Cc: Anthony Green 
Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/moxie/cpu.h|  5 ++--
 target/moxie/cpu.c|  5 ++--
 target/moxie/helper.c | 61 ++-
 3 files changed, 19 insertions(+), 52 deletions(-)

diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
index f3b6d83ae7..a63a96bc05 100644
--- a/target/moxie/cpu.h
+++ b/target/moxie/cpu.h
@@ -139,7 +139,8 @@ static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, 
target_ulong *pc,
 *flags = 0;
 }
 
-int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
-   int rw, int mmu_idx);
+bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr);
 
 #endif /* MOXIE_CPU_H */
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index 46434e65ba..02b2b47574 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -112,9 +112,8 @@ static void moxie_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->do_interrupt = moxie_cpu_do_interrupt;
 cc->dump_state = moxie_cpu_dump_state;
 cc->set_pc = moxie_cpu_set_pc;
-#ifdef CONFIG_USER_ONLY
-cc->handle_mmu_fault = moxie_cpu_handle_mmu_fault;
-#else
+cc->tlb_fill = moxie_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
 cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
 cc->vmsd = _moxie_cpu;
 #endif
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
index 287a45232c..216cef057e 100644
--- a/target/moxie/helper.c
+++ b/target/moxie/helper.c
@@ -26,18 +26,10 @@
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
 
-/* Try to fill the TLB and return an exception if error. If retaddr is
-   NULL, it means that the function was called in C code (i.e. not
-   from generated code or from helper.c) */
 void tlb_fill(CPUState *cs, target_ulong addr, int size,
   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
 {
-int ret;
-
-ret = moxie_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
-if (unlikely(ret)) {
-cpu_loop_exit_restore(cs, retaddr);
-}
+moxie_cpu_tlb_fill(cs, addr, size, access_type, mmu_idx, false, retaddr);
 }
 
 void helper_raise_exception(CPUMoxieState *env, int ex)
@@ -85,53 +77,29 @@ void helper_debug(CPUMoxieState *env)
 cpu_loop_exit(cs);
 }
 
-#if defined(CONFIG_USER_ONLY)
-
-void moxie_cpu_do_interrupt(CPUState *cs)
-{
-CPUState *cs = CPU(moxie_env_get_cpu(env));
-
-cs->exception_index = -1;
-}
-
-int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
-{
-MoxieCPU *cpu = MOXIE_CPU(cs);
-
-cs->exception_index = 0xaa;
-cpu->env.debug1 = address;
-cpu_dump_state(cs, stderr, 0);
-return 1;
-}
-
-#else /* !CONFIG_USER_ONLY */
-
-int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
-   int rw, int mmu_idx)
+bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+MMUAccessType access_type, int mmu_idx,
+bool probe, uintptr_t retaddr)
 {
 MoxieCPU *cpu = MOXIE_CPU(cs);
 CPUMoxieState *env = >env;
 MoxieMMUResult res;
 int prot, miss;
-target_ulong phy;
-int r = 1;
 
 address &= TARGET_PAGE_MASK;
 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-miss = moxie_mmu_translate(, env, address, rw, mmu_idx);
-if (miss) {
-/* handle the miss.  */
-phy = 0;
-cs->exception_index = MOXIE_EX_MMU_MISS;
-} else {
-phy = res.phy;
-r = 0;
+miss = moxie_mmu_translate(, env, address, access_type, mmu_idx);
+if (likely(!miss)) {
+tlb_set_page(cs, address, res.phy, prot, mmu_idx, TARGET_PAGE_SIZE);
+return true;
+}
+if (probe) {
+return false;
 }
-tlb_set_page(cs, address, phy, prot, mmu_idx, TARGET_PAGE_SIZE);
-return r;
-}
 
+cs->exception_index = MOXIE_EX_MMU_MISS;
+cpu_loop_exit_restore(cs, retaddr);
+}
 
 void moxie_cpu_do_interrupt(CPUState *cs)
 {
@@ -156,4 +124,3 @@ hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr 
addr)
 }
 return phy;
 }
-#endif
-- 
2.17.1




[Qemu-devel] [PATCH v3 00/27] tcg: Add CPUClass::tlb_fill

2019-05-09 Thread Richard Henderson
Changes from v2:
  * Re-remove the cpu_dump_state from nios-linux-user.
  * Assert !probe for sparc32, undoing other mmureg changes.
  * Better describe the SVE bug fixed by the final patch.

Patches without review:
0014-target-nios2-Convert-to-CPUClass-tlb_fill.patch
0020-target-sparc-Convert-to-CPUClass-tlb_fill.patch

Changes from v1:
  * Do not unify user-only and system tlb_fill functions
(alpha, microblaze, nios2, s390x, sparc, xtensa).
  * Split the mips patch into multiple.
  * Other random changes per review.

Blurb from v1:

There is currently a lot of confusion between foo_cpu_handle_mmu_fault
and tlb_fill.

In particular, foo_cpu_handle_mmu_fault was only defined for user-only,
and its only valid action was to set up the cpu for cpu_loop_exit so
that we can deliver a SIGSEGV to the guest.  And yet, we had code that
tried to return from the host SIGSEGV handler to retry the instruction.

We had, for some targets, a definition of foo_cpu_handle_mmu_fault
for softmmu.  Sometimes this was called from tlb_fill, sometimes not.

Finally, we have a use case for SVE that wants a non-faulting tlb_fill,
so while we're changing the interface, let's go ahead and include that.


r~


Richard Henderson (27):
  tcg: Add CPUClass::tlb_fill
  target/alpha: Convert to CPUClass::tlb_fill
  target/arm: Convert to CPUClass::tlb_fill
  target/cris: Convert to CPUClass::tlb_fill
  target/hppa: Convert to CPUClass::tlb_fill
  target/i386: Convert to CPUClass::tlb_fill
  target/lm32: Convert to CPUClass::tlb_fill
  target/m68k: Convert to CPUClass::tlb_fill
  target/microblaze: Convert to CPUClass::tlb_fill
  target/mips: Pass a valid error to raise_mmu_exception for user-only
  target/mips: Tidy control flow in mips_cpu_handle_mmu_fault
  target/mips: Convert to CPUClass::tlb_fill
  target/moxie: Convert to CPUClass::tlb_fill
  target/nios2: Convert to CPUClass::tlb_fill
  target/openrisc: Convert to CPUClass::tlb_fill
  target/ppc: Convert to CPUClass::tlb_fill
  target/riscv: Convert to CPUClass::tlb_fill
  target/s390x: Convert to CPUClass::tlb_fill
  target/sh4: Convert to CPUClass::tlb_fill
  target/sparc: Convert to CPUClass::tlb_fill
  target/tilegx: Convert to CPUClass::tlb_fill
  target/tricore: Convert to CPUClass::tlb_fill
  target/unicore32: Convert to CPUClass::tlb_fill
  target/xtensa: Convert to CPUClass::tlb_fill
  tcg: Use CPUClass::tlb_fill in cputlb.c
  tcg: Remove CPUClass::handle_mmu_fault
  tcg: Use tlb_fill probe from tlb_vaddr_to_host

 include/exec/cpu_ldst.h |  50 ++---
 include/exec/exec-all.h |   9 --
 include/qom/cpu.h   |  12 +-
 target/alpha/cpu.h  |   5 +-
 target/arm/internals.h  |  10 +-
 target/cris/cpu.h   |   5 +-
 target/hppa/cpu.h   |   8 +-
 target/i386/cpu.h   |   5 +-
 target/lm32/cpu.h   |   5 +-
 target/m68k/cpu.h   |   5 +-
 target/microblaze/cpu.h |   5 +-
 target/mips/internal.h  |   5 +-
 target/moxie/cpu.h  |   5 +-
 target/nios2/cpu.h  |   5 +-
 target/openrisc/cpu.h   |   5 +-
 target/ppc/cpu.h|   7 +-
 target/riscv/cpu.h  |   5 +-
 target/s390x/internal.h |   5 +-
 target/sh4/cpu.h|   5 +-
 target/sparc/cpu.h  |   5 +-
 target/tricore/cpu.h|   6 +-
 target/unicore32/cpu.h  |   5 +-
 target/xtensa/cpu.h |   5 +-
 accel/tcg/cputlb.c  |  88 +--
 accel/tcg/user-exec.c   |  36 ++
 target/alpha/cpu.c  |   5 +-
 target/alpha/helper.c   |  24 ++--
 target/alpha/mem_helper.c   |  16 ---
 target/arm/cpu.c|  22 +---
 target/arm/helper.c |  90 ---
 target/arm/op_helper.c  |  29 +
 target/arm/sve_helper.c |   6 +-
 target/cris/cpu.c   |   5 +-
 target/cris/helper.c|  61 ++-
 target/cris/op_helper.c |  28 -
 target/hppa/cpu.c   |   5 +-
 target/hppa/mem_helper.c|  16 ++-
 target/i386/cpu.c   |   5 +-
 target/i386/excp_helper.c   |  53 +
 target/i386/mem_helper.c|  21 
 target/lm32/cpu.c   |   5 +-
 target/lm32/helper.c|   8 +-
 target/lm32/op_helper.c |  16 ---
 target/m68k/cpu.c   |   2 +-
 target/m68k/helper.c|  89 ---
 target/m68k/op_helper.c |  15 ---
 target/microblaze/cpu.c |   5 +-
 target/microblaze/helper.c  | 101 -
 target/microblaze/op_helper.c   |  19 
 target/mips/cpu.c   |   5 +-
 target/mips/helper.c|  81 ++
 target/mips/op_helper.c |  15 ---
 target/moxie/cpu.c  |   5 +-
 target/moxie/helper.c   |  65 +++
 target/nios2/cpu.c  |   5 +-
 target/nios2/helper.c   | 170 ++--
 

Re: [Qemu-devel] [PATCH 26/26] tcg: Use tlb_fill probe from tlb_vaddr_to_host

2019-05-09 Thread Richard Henderson
On 5/9/19 1:56 AM, Peter Maydell wrote:
> On Thu, 9 May 2019 at 06:24, Richard Henderson
>  wrote:
>>
>> On 4/29/19 10:41 AM, Peter Maydell wrote:
>>> On Wed, 3 Apr 2019 at 05:05, Richard Henderson
>>>  wrote:

 Most of the existing users would continue around a loop which
 would fault the tlb entry in via a normal load/store.  But for
 SVE we have a true non-faulting case which requires the new
 probing form of tlb_fill.
>>>
>>> So am I right in thinking that this fixes a bug where we
>>> previously would mark a load as faulted if the memory happened
>>> not to be in the TLB, whereas now we will correctly pull in the
>>> TLB entry and do the load ?
>>
>> Yes.
>>
>>> (Since guest code ought to be handling the "non-first-load
>>> faulted" case by looping round or otherwise arranging to
>>> retry, nothing in practice would have noticed this bug, right?)
>>
>> Yes.
>>
>> The only case with changed behaviour is (expected to be) SVE no-fault, where
>> the loop you mention would have produced different incorrect results.
> 
> OK. If we're fixing a guest-visible bug it would be nice to
> describe that in the commit message.

The commit message now reads, in part,

But for AArch64 SVE we have an existing emulation bug wherein we
would mark the first element of a no-fault vector load as faulted
(within the FFR, not via exception) just because we did not have
its address in the TLB.  Now we can properly only mark it as faulted
if there really is no valid, readable translation, while still not
raising an exception.  (Note that beyond the first element of the
vector, the hardware may report a fault for any reason whatsoever;
with at least one element loaded, forward progress is guaranteed.)


r~



Re: [Qemu-devel] [Question] Memory hotplug clarification for Qemu ARM/virt

2019-05-09 Thread Laszlo Ersek
On 05/09/19 18:35, Igor Mammedov wrote:
> On Wed, 8 May 2019 22:26:12 +0200
> Laszlo Ersek  wrote:
> 
>> On 05/08/19 14:50, Robin Murphy wrote:
>>> Hi Shameer,
>>>
>>> On 08/05/2019 11:15, Shameerali Kolothum Thodi wrote:
 Hi,

 This series here[0] attempts to add support for PCDIMM in QEMU for
 ARM/Virt platform and has stumbled upon an issue as it is not clear(at
 least
 from Qemu/EDK2 point of view) how in physical world the hotpluggable
 memory is handled by kernel.

 The proposed implementation in Qemu, builds the SRAT and DSDT parts
 and uses GED device to trigger the hotplug. This works fine.

 But when we added the DT node corresponding to the PCDIMM(cold plug
 scenario), we noticed that Guest kernel see this memory during early boot
 even if we are booting with ACPI. Because of this, hotpluggable memory
 may end up in zone normal and make it non-hot-un-pluggable even if Guest
 boots with ACPI.

 Further discussions[1] revealed that, EDK2 UEFI has no means to
 interpret the
 ACPI content from Qemu(this is designed to do so) and uses DT info to
 build the GetMemoryMap(). To solve this, introduced "hotpluggable"
 property
 to DT memory node(patches #7 & #8 from [0]) so that UEFI can
 differentiate
 the nodes and exclude the hotpluggable ones from GetMemoryMap().

 But then Laszlo rightly pointed out that in order to accommodate the
 changes
 into UEFI we need to know how exactly Linux expects/handles all the
 hotpluggable memory scenarios. Please find the discussion here[2].

 For ease, I am just copying the relevant comment from Laszlo below,

 /**
 "Given patches #7 and #8, as I understand them, the firmware cannot
 distinguish
   hotpluggable & present, from hotpluggable & absent. The firmware can
 only
   skip both hotpluggable cases. That's fine in that the firmware will
 hog neither
   type -- but is that OK for the OS as well, for both ACPI boot and DT
 boot?

 Consider in particular the "hotpluggable & present, ACPI boot" case.
 Assuming
 we modify the firmware to skip "hotpluggable" altogether, the UEFI memmap
 will not include the range despite it being present at boot.
 Presumably, ACPI
 will refer to the range somehow, however. Will that not confuse the OS?

 When Igor raised this earlier, I suggested that
 hotpluggable-and-present should
 be added by the firmware, but also allocated immediately, as
 EfiBootServicesData
 type memory. This will prevent other drivers in the firmware from
 allocating AcpiNVS
 or Reserved chunks from the same memory range, the UEFI memmap will
 contain
 the range as EfiBootServicesData, and then the OS can release that
 allocation in
 one go early during boot.

 But this really has to be clarified from the Linux kernel's
 expectations. Please
 formalize all of the following cases:

 OS boot (DT/ACPI)  hotpluggable & ...  GetMemoryMap() should report
 as  DT/ACPI should report as
 -  -- 
 ---  
 DT present ?    ?
 DT absent  ?    ?
 ACPI   present ?    ?
 ACPI   absent  ?    ?

 Again, this table is dictated by Linux."

 **/

 Could you please take a look at this and let us know what is expected
 here from
 a Linux kernel view point.
>>>
>>> For arm64, so far we've not even been considering DT-based hotplug - as
>>> far as I'm aware there would still be a big open question there around
>>> notification mechanisms and how to describe them. The DT stuff so far
>>> has come from the PowerPC folks, so it's probably worth seeing what
>>> their ideas are.
>>>
>>> ACPI-wise I've always assumed/hoped that hotplug-related things should
>>> be sufficiently well-specified in UEFI that "do whatever x86/IA-64 do"
>>> would be enough for us.
>>
>> As far as I can see in UEFI v2.8 -- and I had checked the spec before
>> dumping the table with the many question marks on Shameer --, all the
>> hot-plug language in the spec refers to USB and PCI hot-plug in the
>> preboot environment. There is not a single word about hot-plug at OS
>> runtime (regarding any device or component type), nor about memory
>> hot-plug (at any time).
>>
>> Looking to x86 appears valid -- so what does the Linux kernel expect on
>> that architecture, in the "ACPI" rows of the table?
> 
> I could only answer from QEMU x86 perspective.
> QEMU for x86 guests currently doesn't add hot-pluggable RAM into E820
> because of different linux guests tend to cannibalize it, making it non
> 

Re: [Qemu-devel] [PATCH v3 18/39] target/mips: Use env_cpu, env_archcpu

2019-05-09 Thread Aleksandar Markovic
On May 8, 2019 11:53 PM, "Philippe Mathieu-Daudé"  wrote:
>
> Hi Richard, Aleksandar.
>
> On 5/8/19 4:32 PM, Richard Henderson wrote:
> > On 5/8/19 1:15 AM, Aleksandar Markovic wrote:
> >>
> >> On May 8, 2019 2:19 AM, "Richard Henderson" <
richard.hender...@linaro.org
> >> > wrote:
> >>>
> >>>
> >>>
> >>
> >> This commit message doesnˊt explain the reason for the change, and why
is this
> >> an improvement. The underlyng reason for distingishing between
env_cpu and
> >> env_archcpu cases is not explained too.
> >
> > It's certainly explained in the preceeding patches that introduce those
functions.
> >
> > Are you suggesting that it is beneficial to copy-and-paste a common
block
> > explanation into 21 commit messages for each of target/foo/?
>
>
> *) Richard:
>
> I tried to put myself in Aleksandar shoes. I believe Aleksandar is
> worried about his MIPS maintainer duty, wanting to Ack-by this patch.
>
> It is true that out of the context of the series, it is hard to see what
> is the problem you try to solve.
>
> You could copy/paste the explanation you used previously,
> with s/$arch/mips/:
>
> "Cleanup in the boilerplate that each target must define."
>
> "Combined uses of CPU(mips_env_get_cpu()) were failures to use
> the more proper, ENV_GET_CPU macro, now replaced by env_cpu."
>
> Now to clearly understand this patch we still need to look at the
> previous two arch-generic patches
> - "cpu: Replace ENV_GET_CPU with env_cpu" and
> - "cpu: Introduce env_archcpu".
>
> Also, it is tedious to copy/paste the same explanation, but thinking of
> forks or stable branch that cherry-pick not all but some commits of a
> series, it might be useful.
>
> Another guess is Aleksandar might have looked at the series cover, which
> is not well explained as your v2:
> https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg07635.html
> I think you mistakenly copied the v1 blurb instead of the v2 one.
>
> So at some point I can understand Aleksandar frustation.
>
>
> *) Aleksandar:
>
> This series fall under the "Overall Guest CPU cores (TCG)" section
> maintained by Richard and Paolo. I think you have to see this series as
> a whole to understand the benefits of it.
>
> With the same reasoning, I believe you shouldn't worry to not give your
> Ack if you don't feel comfortable.
>
> I think Richard sent this v3 to simply address comments raised by the
> previous reviewer during v1/v2, where there was some discussions: I took
> it as "this is the last round before getting merged" (unless someone
> object).
>
> It is hard to make everybody happy on a such big project, with so many
> areas, lines of code, people, culture, etc... I believe we all try to
> give our best, neither the commiters nor the reviewers are perfect, but
> slowly we help this project to improve :)
>
>
> Best regards,
>
> Phil.

Richard, Philippe,

A commit message along the line that Philippe put together would be OK.

I can talk about this commit only - if other submaintainers are fine with
empty commit messages in key files for their target, that is their
business. I am certainly opposed to any empty commit messages in MIPS
files, and please, Richard, include a decent commit message for this
commit. I don't think I am asking much.

Thanks,
Aleksandar


Re: [Qemu-devel] [PATCH v2 04/16] hw/arm/bcm2835: Use TYPE_PL011 instead of hardcoded string

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 9:41 AM Philippe Mathieu-Daudé  wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/arm/bcm2835_peripherals.c | 2 +-
>  include/hw/arm/bcm2835_peripherals.h | 1 +
>  2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
> index 6be7660e8cb..7ffb51b6927 100644
> --- a/hw/arm/bcm2835_peripherals.c
> +++ b/hw/arm/bcm2835_peripherals.c
> @@ -46,7 +46,7 @@ static void bcm2835_peripherals_init(Object *obj)
>  qdev_set_parent_bus(DEVICE(>ic), sysbus_get_default());
>
>  /* UART0 */
> -s->uart0 = SYS_BUS_DEVICE(object_new("pl011"));
> +s->uart0 = SYS_BUS_DEVICE(object_new(TYPE_PL011));
>  object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
>  qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
>
> diff --git a/include/hw/arm/bcm2835_peripherals.h 
> b/include/hw/arm/bcm2835_peripherals.h
> index f5b193f6707..959508d57dd 100644
> --- a/include/hw/arm/bcm2835_peripherals.h
> +++ b/include/hw/arm/bcm2835_peripherals.h
> @@ -13,6 +13,7 @@
>
>  #include "qemu-common.h"
>  #include "hw/sysbus.h"
> +#include "hw/char/pl011.h"
>  #include "hw/char/bcm2835_aux.h"
>  #include "hw/display/bcm2835_fb.h"
>  #include "hw/dma/bcm2835_dma.h"
> --
> 2.20.1
>
>



Re: [Qemu-devel] [PATCH v2 05/16] hw/arm/bcm2835: Use object_initialize() on PL011State

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 9:42 AM Philippe Mathieu-Daudé  wrote:
>
> To be coherent with the other peripherals contained in the
> BCM2835PeripheralState structure, directly allocate the PL011State
> (instead of using the pl011 uart as a pointer to a SysBusDevice).
>
> Initialize the PL011State with object_initialize() instead of
> object_new().
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/arm/bcm2835_peripherals.c | 14 +++---
>  include/hw/arm/bcm2835_peripherals.h |  2 +-
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
> index 7ffb51b6927..2931a82a25a 100644
> --- a/hw/arm/bcm2835_peripherals.c
> +++ b/hw/arm/bcm2835_peripherals.c
> @@ -46,9 +46,9 @@ static void bcm2835_peripherals_init(Object *obj)
>  qdev_set_parent_bus(DEVICE(>ic), sysbus_get_default());
>
>  /* UART0 */
> -s->uart0 = SYS_BUS_DEVICE(object_new(TYPE_PL011));
> -object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
> -qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
> +object_initialize(>uart0, sizeof(s->uart0), TYPE_PL011);
> +object_property_add_child(obj, "uart0", OBJECT(>uart0), NULL);
> +qdev_set_parent_bus(DEVICE(>uart0), sysbus_get_default());
>
>  /* AUX / UART1 */
>  object_initialize(>aux, sizeof(s->aux), TYPE_BCM2835_AUX);
> @@ -166,16 +166,16 @@ static void bcm2835_peripherals_realize(DeviceState 
> *dev, Error **errp)
>  sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(>ic));
>
>  /* UART0 */
> -qdev_prop_set_chr(DEVICE(s->uart0), "chardev", serial_hd(0));
> -object_property_set_bool(OBJECT(s->uart0), true, "realized", );
> +qdev_prop_set_chr(DEVICE(>uart0), "chardev", serial_hd(0));
> +object_property_set_bool(OBJECT(>uart0), true, "realized", );
>  if (err) {
>  error_propagate(errp, err);
>  return;
>  }
>
>  memory_region_add_subregion(>peri_mr, UART0_OFFSET,
> -sysbus_mmio_get_region(s->uart0, 0));
> -sysbus_connect_irq(s->uart0, 0,
> +sysbus_mmio_get_region(SYS_BUS_DEVICE(>uart0), 0));
> +sysbus_connect_irq(SYS_BUS_DEVICE(>uart0), 0,
>  qdev_get_gpio_in_named(DEVICE(>ic), BCM2835_IC_GPU_IRQ,
> INTERRUPT_UART));
>  /* AUX / UART1 */
> diff --git a/include/hw/arm/bcm2835_peripherals.h 
> b/include/hw/arm/bcm2835_peripherals.h
> index 959508d57dd..e79c21771fe 100644
> --- a/include/hw/arm/bcm2835_peripherals.h
> +++ b/include/hw/arm/bcm2835_peripherals.h
> @@ -38,7 +38,7 @@ typedef struct BCM2835PeripheralState {
>  MemoryRegion ram_alias[4];
>  qemu_irq irq, fiq;
>
> -SysBusDevice *uart0;
> +PL011State uart0;
>  BCM2835AuxState aux;
>  BCM2835FBState fb;
>  BCM2835DMAState dma;
> --
> 2.20.1
>
>



Re: [Qemu-devel] [PATCH v4] s390: diagnose 318 info reset and migration support

2019-05-09 Thread Collin Walling

On 5/9/19 5:58 AM, Christian Borntraeger wrote:



On 02.05.19 00:31, Collin Walling wrote:

DIAGNOSE 0x318 (diag318) is a privileged s390x instruction that must
be intercepted by SIE and handled via KVM. Let's introduce some
functions to communicate between QEMU and KVM via ioctls. These
will be used to get/set the diag318 related information (also known
as the "Control Program Code" or "CPC"), as well as check the system
if KVM supports handling this instruction.

The availability of this instruction is determined by byte 134, bit 0
of the Read Info block. This coincidentally expands into the space used
for CPU entries, which means VMs running with the diag318 capability
will have a reduced maximum CPU count. To alleviate this, let's calculate
the actual max CPU entry space by subtracting the size of Read Info from
the SCCB size then dividing that number by the size of a CPU entry. If
this value is less than the value denoted by S390_MAX_CPUS, then let's
reduce the max cpus for s390 from 248 to 240 in an effort to anticipate
this potentially happening again in the future.

In order to simplify the migration and system reset requirements of
the diag318 data, let's introduce it as a device class and include
a VMStateDescription.

Diag318 is reset on during modified clear and load normal.

Signed-off-by: Collin Walling 
---
  hw/s390x/Makefile.objs   |   1 +
  hw/s390x/diag318.c   | 100 +++
  hw/s390x/diag318.h   |  39 +
  hw/s390x/s390-virtio-ccw.c   |  23 ++
  hw/s390x/sclp.c  |   5 +++
  include/hw/s390x/sclp.h  |   2 +
  linux-headers/asm-s390/kvm.h |   4 ++
  target/s390x/kvm-stub.c  |  15 +++
  target/s390x/kvm.c   |  32 ++
  target/s390x/kvm_s390x.h |   3 ++
  10 files changed, 224 insertions(+)
  create mode 100644 hw/s390x/diag318.c
  create mode 100644 hw/s390x/diag318.h

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index e02ed80..93621dc 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -34,3 +34,4 @@ obj-$(CONFIG_KVM) += s390-stattrib-kvm.o
  obj-y += s390-ccw.o
  obj-y += ap-device.o
  obj-y += ap-bridge.o
+obj-y += diag318.o
diff --git a/hw/s390x/diag318.c b/hw/s390x/diag318.c
new file mode 100644
index 000..94b44da
--- /dev/null
+++ b/hw/s390x/diag318.c
@@ -0,0 +1,100 @@
+/*
+ * DIAGNOSE 0x318 functions for reset and migration
+ *
+ * Copyright IBM, Corp. 2019
+ *
+ * Authors:
+ *  Collin Walling 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version. See the COPYING file in the top-level directory.
+ */
+
+#include "hw/s390x/diag318.h"
+#include "qapi/error.h"
+#include "kvm_s390x.h"
+#include "sysemu/kvm.h"
+
+static int diag318_post_load(void *opaque, int version_id)
+{
+DIAG318State *d = opaque;
+
+kvm_s390_set_cpc(d->cpc);
+
+/* It is not necessary to retain a copy of the cpc after migration. */
+d->cpc = 0;


But we also do not need to zero it out? Can't you just drop these 2 lines?




Absolutely. I'll drop them.


+
+return 0;
+}
+
+static int diag318_pre_save(void *opaque)
+{
+DIAG318State *d = opaque;
+
+kvm_s390_get_cpc(>cpc);
+return 0;
+}
+
+static bool diag318_needed(void *opaque)
+{
+DIAG318State *d = opaque;
+
+return d->enabled;
+}


I would like to have a cpumodel entry that allows to disable that feature. And 
we should
then check for this.



Noted.


+
+const VMStateDescription vmstate_diag318 = {
+.name = "vmstate_diag318",
+.post_load = diag318_post_load,
+.pre_save = diag318_pre_save,
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = diag318_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64(cpc, DIAG318State),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void s390_diag318_realize(DeviceState *dev, Error **errp)
+{
+DIAG318State *d = DIAG318(dev);
+
+if (kvm_s390_has_diag318()) {
+d->enabled = true;
+}


same here -> cpumodel
Then we can get rid of the enabled bool.


Noted.

[...]
  
  static void s390_cpu_plug(HotplugHandler *hotplug_dev,

@@ -570,6 +585,7 @@ static void machine_set_loadparm(Object *obj, const char 
*val, Error **errp)
  ms->loadparm[i] = ' '; /* pad right with spaces */
  }
  }
+
  static inline void s390_machine_initfn(Object *obj)
  {
  object_property_add_bool(obj, "aes-key-wrap",
@@ -652,6 +668,13 @@ static void ccw_machine_4_0_instance_options(MachineState 
*machine)
  
  static void ccw_machine_4_0_class_options(MachineClass *mc)

  {
+/*
+ * Read Info might reveal more bytes used to detect facilities, thus
+ * reducing the number of CPU entries. Let's reduce the max CPUs by
+ * an arbitrary number in effort to anticipate future facility bytes.
+ */
+if ((SCCB_SIZE - sizeof(ReadInfo)) / sizeof(CPUEntry) < S390_MAX_CPUS)
+mc->max_cpus = S390_MAX_CPUS - 8;



Re: [Qemu-devel] [PATCH v1 22/23] tests/qemu-iotests: re-format output to for make check-block

2019-05-09 Thread Eric Blake
On 5/9/19 3:38 PM, Alex Bennée wrote:

>> Hm, this makes every iotest print two lines:
>>
>> $ ./check -T -qcow2
>> [...]
>> 001 [20:06:27] -> [20:06:27]
>> 001 0s (last 1s)
> 
> Yes - it was a compromise to ensure we printed a start and end
> timestamp but I guess we can fix it up with a bit more shell ugliness:
> 
> --8<---cut here---start->8---
> 
> Subject: [PATCH] fixup! tests/qemu-iotests: re-format output to for make
>  check-block
> 
> ---
>  tests/qemu-iotests/check | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
> index fb239967a32..9f083f06b46 100755
> --- a/tests/qemu-iotests/check
> +++ b/tests/qemu-iotests/check
> @@ -726,7 +726,11 @@ _report_test_result()
>  if $pretty; then
>  echo "  TESTiotest: $1 $2"
>  else
> -echo "$1 $2"
> +if $timestamp; then
> +echo " $2"
> +else
> +echo "$1 $2"
> +fi

Why not just make $1 '' in the case where you've already printed a
timestamp, so that this code is still unconditionally echo "$1 $2"?

>  fi
>  }
> 
> @@ -793,7 +797,7 @@ do
>  $run_command >$tmp.out 2>&1)
>  fi
>  sts=$?
> -$timestamp && echo " [$(date "+%T")]"
> +$timestamp && echo -n " [$(date "+%T")]"

'echo -n' is not portable (even in bash, since you can compile a
different default for shopt xpg_echo). Better is to use 'printf %s', as
is already done in _timestamp().

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v3 32/39] cpu: Introduce cpu_set_cpustate_pointers

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 5:37 PM Richard Henderson
 wrote:
>
> Consolidate some boilerplate from foo_cpu_initfn.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/exec/cpu-all.h  | 11 +++
>  target/alpha/cpu.c  |  3 +--
>  target/arm/cpu.c|  3 +--
>  target/cris/cpu.c   |  3 +--
>  target/hppa/cpu.c   |  2 +-
>  target/i386/cpu.c   |  3 +--
>  target/lm32/cpu.c   |  3 +--
>  target/m68k/cpu.c   |  4 +---
>  target/microblaze/cpu.c |  3 +--
>  target/mips/cpu.c   |  3 +--
>  target/moxie/cpu.c  |  3 +--
>  target/nios2/cpu.c  |  6 ++
>  target/openrisc/cpu.c   |  3 +--
>  target/ppc/translate_init.inc.c |  3 +--
>  target/riscv/cpu.c  |  3 +--
>  target/s390x/cpu.c  |  9 +
>  target/sh4/cpu.c|  3 +--
>  target/sparc/cpu.c  |  3 +--
>  target/tilegx/cpu.c |  4 +---
>  target/tricore/cpu.c|  4 +---
>  target/unicore32/cpu.c  |  3 +--
>  target/xtensa/cpu.c |  3 +--
>  22 files changed, 37 insertions(+), 48 deletions(-)
>
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index c62f07b354..71154070a7 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -371,6 +371,17 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>
>  int cpu_exec(CPUState *cpu);
>
> +/**
> + * cpu_set_cpustate_pointers(cpu)
> + * @cpu: The cpu object
> + *
> + * Set the generic pointers in CPUState into the outer object.
> + */
> +static inline void cpu_set_cpustate_pointers(ArchCPU *cpu)
> +{
> +cpu->parent_obj.env_ptr = >env;
> +}
> +
>  /**
>   * env_archcpu(env)
>   * @env: The architecture environment
> diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
> index ad3588a44a..b771b9f3fe 100644
> --- a/target/alpha/cpu.c
> +++ b/target/alpha/cpu.c
> @@ -191,11 +191,10 @@ static void ev67_cpu_initfn(Object *obj)
>
>  static void alpha_cpu_initfn(Object *obj)
>  {
> -CPUState *cs = CPU(obj);
>  AlphaCPU *cpu = ALPHA_CPU(obj);
>  CPUAlphaState *env = >env;
>
> -cs->env_ptr = env;
> +cpu_set_cpustate_pointers(cpu);
>
>  env->lock_addr = -1;
>  #if defined(CONFIG_USER_ONLY)
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index a181fa8dc1..79d5096270 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -698,10 +698,9 @@ static void cpreg_hashtable_data_destroy(gpointer data)
>
>  static void arm_cpu_initfn(Object *obj)
>  {
> -CPUState *cs = CPU(obj);
>  ARMCPU *cpu = ARM_CPU(obj);
>
> -cs->env_ptr = >env;
> +cpu_set_cpustate_pointers(cpu);
>  cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
>   g_free, 
> cpreg_hashtable_data_destroy);
>
> diff --git a/target/cris/cpu.c b/target/cris/cpu.c
> index 75729bfdd5..070f8be363 100644
> --- a/target/cris/cpu.c
> +++ b/target/cris/cpu.c
> @@ -172,12 +172,11 @@ static void cris_disas_set_info(CPUState *cpu, 
> disassemble_info *info)
>
>  static void cris_cpu_initfn(Object *obj)
>  {
> -CPUState *cs = CPU(obj);
>  CRISCPU *cpu = CRIS_CPU(obj);
>  CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
>  CPUCRISState *env = >env;
>
> -cs->env_ptr = env;
> +cpu_set_cpustate_pointers(cpu);
>
>  env->pregs[PR_VR] = ccc->vr;
>
> diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
> index e64f48581e..fdff057793 100644
> --- a/target/hppa/cpu.c
> +++ b/target/hppa/cpu.c
> @@ -134,7 +134,7 @@ static void hppa_cpu_initfn(Object *obj)
>  HPPACPU *cpu = HPPA_CPU(obj);
>  CPUHPPAState *env = >env;
>
> -cs->env_ptr = env;
> +cpu_set_cpustate_pointers(cpu);
>  cs->exception_index = -1;
>  cpu_hppa_loaded_fr0(env);
>  cpu_hppa_put_psw(env, PSW_W);
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 5b84629f91..7eff4c4dea 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -5588,13 +5588,12 @@ static void x86_cpu_get_crash_info_qom(Object *obj, 
> Visitor *v,
>
>  static void x86_cpu_initfn(Object *obj)
>  {
> -CPUState *cs = CPU(obj);
>  X86CPU *cpu = X86_CPU(obj);
>  X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
>  CPUX86State *env = >env;
>  FeatureWord w;
>
> -cs->env_ptr = env;
> +cpu_set_cpustate_pointers(cpu);
>
>  object_property_add(obj, "family", "int",
>  x86_cpuid_version_get_family,
> diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
> index 282da19994..ebcbd2faa8 100644
> --- a/target/lm32/cpu.c
> +++ b/target/lm32/cpu.c
> @@ -142,11 +142,10 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>
>  static void lm32_cpu_initfn(Object *obj)
>  {
> -CPUState *cs = CPU(obj);
>  LM32CPU *cpu = LM32_CPU(obj);
>  CPULM32State *env = >env;
>
> -cs->env_ptr = env;
> +

Re: [Qemu-devel] [PATCH v1 22/23] tests/qemu-iotests: re-format output to for make check-block

2019-05-09 Thread Alex Bennée


Max Reitz  writes:

> On 09.05.19 18:59, Alex Bennée wrote:
>> This attempts to clean-up the output to better match the output of the
>> rest of the QEMU check system. This includes:
>>
>>   - formatting as "  TESTiotest: nnn"
>>   - calculating time diff at the end
>>   - only dumping config on failure
>>
>> Signed-off-by: Alex Bennée 
>> Message-Id: <20190503143904.31211-1-alex.ben...@linaro.org>
>> ---
>>  tests/qemu-iotests/check | 101 +++
>>  1 file changed, 61 insertions(+), 40 deletions(-)
>
> Hm, this makes every iotest print two lines:
>
> $ ./check -T -qcow2
> [...]
> 001 [20:06:27] -> [20:06:27]
> 001 0s (last 1s)

Yes - it was a compromise to ensure we printed a start and end
timestamp but I guess we can fix it up with a bit more shell ugliness:

--8<---cut here---start->8---

Subject: [PATCH] fixup! tests/qemu-iotests: re-format output to for make
 check-block

---
 tests/qemu-iotests/check | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index fb239967a32..9f083f06b46 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -726,7 +726,11 @@ _report_test_result()
 if $pretty; then
 echo "  TESTiotest: $1 $2"
 else
-echo "$1 $2"
+if $timestamp; then
+echo " $2"
+else
+echo "$1 $2"
+fi
 fi
 }

@@ -793,7 +797,7 @@ do
 $run_command >$tmp.out 2>&1)
 fi
 sts=$?
-$timestamp && echo " [$(date "+%T")]"
+$timestamp && echo -n " [$(date "+%T")]"
 stop=$(_wallclock)

 if [ -f core ]
--8<---cut here---end--->8---

--
Alex Bennée



Re: [Qemu-devel] [PATCH v3 33/39] cpu: Introduce CPUNegativeOffsetState

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 5:26 PM Richard Henderson
 wrote:
>
> Nothing in there so far, but all of the plumbing done
> within the target ArchCPU state.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/exec/cpu-all.h  | 24 
>  include/exec/cpu-defs.h |  8 
>  target/alpha/cpu.h  |  1 +
>  target/arm/cpu.h|  1 +
>  target/cris/cpu.h   |  1 +
>  target/hppa/cpu.h   |  1 +
>  target/i386/cpu.h   |  1 +
>  target/lm32/cpu.h   |  1 +
>  target/m68k/cpu.h   |  1 +
>  target/microblaze/cpu.h |  5 +++--
>  target/mips/cpu.h   |  1 +
>  target/moxie/cpu.h  |  1 +
>  target/nios2/cpu.h  |  2 ++
>  target/openrisc/cpu.h   |  2 +-
>  target/ppc/cpu.h|  2 ++
>  target/riscv/cpu.h  |  1 +
>  target/s390x/cpu.h  |  1 +
>  target/sh4/cpu.h|  1 +
>  target/sparc/cpu.h  |  1 +
>  target/tilegx/cpu.h |  1 +
>  target/tricore/cpu.h|  1 +
>  target/unicore32/cpu.h  |  1 +
>  target/xtensa/cpu.h |  1 +
>  23 files changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 71154070a7..5ae83405c8 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -404,4 +404,28 @@ static inline CPUState *env_cpu(CPUArchState *env)
>  return _archcpu(env)->parent_obj;
>  }
>
> +/**
> + * env_neg(env)
> + * @env: The architecture environment
> + *
> + * Return the CPUNegativeOffsetState associated with the environment.
> + */
> +static inline CPUNegativeOffsetState *env_neg(CPUArchState *env)
> +{
> +ArchCPU *arch_cpu = container_of(env, ArchCPU, env);
> +return _cpu->neg;
> +}
> +
> +/**
> + * cpu_neg(cpu)
> + * @cpu: The generic CPUState
> + *
> + * Return the CPUNegativeOffsetState associated with the cpu.
> + */
> +static inline CPUNegativeOffsetState *cpu_neg(CPUState *cpu)
> +{
> +ArchCPU *arch_cpu = container_of(cpu, ArchCPU, parent_obj);
> +return _cpu->neg;
> +}
> +
>  #endif /* CPU_ALL_H */
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index fbe8945606..ad97991faf 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -227,4 +227,12 @@ typedef struct CPUTLB {
>
>  #endif  /* !CONFIG_USER_ONLY && CONFIG_TCG */
>
> +/*
> + * This structure must be placed in ArchCPU immedately
> + * before CPUArchState, as a field named "neg".
> + */
> +typedef struct CPUNegativeOffsetState {
> +/* Empty */
> +} CPUNegativeOffsetState;
> +
>  #endif
> diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
> index 66782cf5d4..f4bb67c101 100644
> --- a/target/alpha/cpu.h
> +++ b/target/alpha/cpu.h
> @@ -267,6 +267,7 @@ struct AlphaCPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUAlphaState env;
>
>  /* This alarm doesn't exist in real hardware; we wish it did.  */
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 23beb1de9a..909cb4604d 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -719,6 +719,7 @@ struct ARMCPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUARMState env;
>
>  /* Coprocessor information */
> diff --git a/target/cris/cpu.h b/target/cris/cpu.h
> index c19fdcec1e..eeab483dba 100644
> --- a/target/cris/cpu.h
> +++ b/target/cris/cpu.h
> @@ -180,6 +180,7 @@ struct CRISCPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUCRISState env;
>  };
>
> diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
> index 58b2bf2933..0661ff60c1 100644
> --- a/target/hppa/cpu.h
> +++ b/target/hppa/cpu.h
> @@ -218,6 +218,7 @@ struct HPPACPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUHPPAState env;
>  QEMUTimer *alarm_timer;
>  };
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index a9cfb42b22..43bb6ab841 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1368,6 +1368,7 @@ struct X86CPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUX86State env;
>
>  bool hyperv_vapic;
> diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
> index 4234a439a3..0ec898eb1d 100644
> --- a/target/lm32/cpu.h
> +++ b/target/lm32/cpu.h
> @@ -186,6 +186,7 @@ struct LM32CPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPULM32State env;
>
>  uint32_t revision;
> diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
> index 02fbff3625..096d1eb588 100644
> --- a/target/m68k/cpu.h
> +++ b/target/m68k/cpu.h
> @@ -160,6 +160,7 @@ struct M68kCPU {
>  CPUState parent_obj;
>  /*< public >*/
>
> +CPUNegativeOffsetState neg;
>  CPUM68KState env;
>  };
>
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index 1becb9270b..732653caed 100644
> --- a/target/microblaze/cpu.h
> +++ 

Re: [Qemu-devel] [PATCH v3 34/39] cpu: Move icount_decr to CPUNegativeOffsetState

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 5:35 PM Richard Henderson
 wrote:
>
> Amusingly, we had already ignored the comment to keep this value at the
> end of CPUState.  This restores the minimum negative offset from TCG_AREG0
> for code generation.
>
> For the couple of uses within qom/cpu.c, add a pointer from the CPUState
> object to the IcountDecr object within CPUNegativeOffsetState.
>
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/exec/cpu-all.h|  1 +
>  include/exec/cpu-defs.h   |  3 ++-
>  include/exec/gen-icount.h | 16 ++--
>  include/qom/cpu.h | 40 ++-
>  accel/tcg/cpu-exec.c  | 23 +++---
>  accel/tcg/tcg-all.c   |  6 ++
>  accel/tcg/translate-all.c |  8 
>  cpus.c|  9 +
>  qom/cpu.c |  4 ++--
>  9 files changed, 56 insertions(+), 54 deletions(-)
>
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 5ae83405c8..253dd1d9a5 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -380,6 +380,7 @@ int cpu_exec(CPUState *cpu);
>  static inline void cpu_set_cpustate_pointers(ArchCPU *cpu)
>  {
>  cpu->parent_obj.env_ptr = >env;
> +cpu->parent_obj.icount_decr_ptr = >neg.icount_decr;
>  }
>
>  /**
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index ad97991faf..3971910653 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -33,6 +33,7 @@
>  #include "exec/hwaddr.h"
>  #endif
>  #include "exec/memattrs.h"
> +#include "qom/cpu.h"
>
>  #include "cpu-param.h"
>
> @@ -232,7 +233,7 @@ typedef struct CPUTLB {
>   * before CPUArchState, as a field named "neg".
>   */
>  typedef struct CPUNegativeOffsetState {
> -/* Empty */
> +IcountDecr icount_decr;
>  } CPUNegativeOffsetState;
>
>  #endif
> diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
> index 9cfa6ccce5..f7669b6841 100644
> --- a/include/exec/gen-icount.h
> +++ b/include/exec/gen-icount.h
> @@ -5,8 +5,6 @@
>
>  /* Helpers for instruction counting code generation.  */
>
> -#define ENV_OFFSET   offsetof(ArchCPU, env)
> -
>  static TCGOp *icount_start_insn;
>
>  static inline void gen_tb_start(TranslationBlock *tb)
> @@ -21,7 +19,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
>  }
>
>  tcg_gen_ld_i32(count, cpu_env,
> -   -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
> +   offsetof(ArchCPU, neg.icount_decr.u32) -
> +   offsetof(ArchCPU, env));
>
>  if (tb_cflags(tb) & CF_USE_ICOUNT) {
>  imm = tcg_temp_new_i32();
> @@ -39,7 +38,8 @@ static inline void gen_tb_start(TranslationBlock *tb)
>
>  if (tb_cflags(tb) & CF_USE_ICOUNT) {
>  tcg_gen_st16_i32(count, cpu_env,
> - -ENV_OFFSET + offsetof(CPUState, 
> icount_decr.u16.low));
> + offsetof(ArchCPU, neg.icount_decr.u16.low) -
> + offsetof(ArchCPU, env));
>  }
>
>  tcg_temp_free_i32(count);
> @@ -60,14 +60,18 @@ static inline void gen_tb_end(TranslationBlock *tb, int 
> num_insns)
>  static inline void gen_io_start(void)
>  {
>  TCGv_i32 tmp = tcg_const_i32(1);
> -tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, 
> can_do_io));
> +tcg_gen_st_i32(tmp, cpu_env,
> +   offsetof(ArchCPU, parent_obj.can_do_io) -
> +   offsetof(ArchCPU, env));
>  tcg_temp_free_i32(tmp);
>  }
>
>  static inline void gen_io_end(void)
>  {
>  TCGv_i32 tmp = tcg_const_i32(0);
> -tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, 
> can_do_io));
> +tcg_gen_st_i32(tmp, cpu_env,
> +   offsetof(ArchCPU, parent_obj.can_do_io) -
> +   offsetof(ArchCPU, env));
>  tcg_temp_free_i32(tmp);
>  }
>
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 08abcbd3fe..0d8fc1caa6 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -226,17 +226,25 @@ typedef struct CPUClass {
>  bool gdb_stop_before_watchpoint;
>  } CPUClass;
>
> +/*
> + * Low 16 bits: number of cycles left, used only in icount mode.
> + * High 16 bits: Set to -1 to force TCG to stop executing linked TBs
> + * for this CPU and return to its top level loop (even in non-icount mode).
> + * This allows a single read-compare-cbranch-write sequence to test
> + * for both decrementer underflow and exceptions.
> + */
> +typedef union IcountDecr {
> +uint32_t u32;
> +struct {
>  #ifdef HOST_WORDS_BIGENDIAN
> -typedef struct icount_decr_u16 {
> -uint16_t high;
> -uint16_t low;
> -} icount_decr_u16;
> +uint16_t high;
> +uint16_t low;
>  #else
> -typedef struct icount_decr_u16 {
> -uint16_t low;
> -uint16_t high;
> -} icount_decr_u16;
> +uint16_t low;
> +uint16_t high;
>  #endif
> +} u16;
> +} IcountDecr;
>
>  typedef struct CPUBreakpoint {
>  

Re: [Qemu-devel] [PATCH v3 30/39] target/xtensa: Use env_cpu, env_archcpu

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 5:37 PM Richard Henderson
 wrote:
>
> Move cpu_get_tb_cpu_state below the include of "exec/cpu-all.h"
> so that the definition of env_cpu is available.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/xtensa/cpu.h  | 17 ++---
>  hw/xtensa/pic_cpu.c  |  2 +-
>  linux-user/xtensa/cpu_loop.c |  2 +-
>  target/xtensa/dbg_helper.c   |  4 ++--
>  target/xtensa/exc_helper.c   |  9 -
>  target/xtensa/helper.c   |  2 +-
>  target/xtensa/mmu_helper.c   | 11 ---
>  target/xtensa/xtensa-semi.c  |  2 +-
>  8 files changed, 20 insertions(+), 29 deletions(-)
>
> diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
> index a20541b5d6..86c88eae40 100644
> --- a/target/xtensa/cpu.h
> +++ b/target/xtensa/cpu.h
> @@ -529,11 +529,6 @@ struct XtensaCPU {
>  CPUXtensaState env;
>  };
>
> -static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
> -{
> -return container_of(env, XtensaCPU, env);
> -}
> -
>  #define ENV_OFFSET offsetof(XtensaCPU, env)
>
>
> @@ -711,10 +706,15 @@ static inline int cpu_mmu_index(CPUXtensaState *env, 
> bool ifetch)
>  #define XTENSA_CSBASE_LBEG_OFF_MASK 0x00ff
>  #define XTENSA_CSBASE_LBEG_OFF_SHIFT 16
>
> +typedef CPUXtensaState CPUArchState;
> +typedef XtensaCPU ArchCPU;
> +
> +#include "exec/cpu-all.h"
> +
>  static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong 
> *pc,
>  target_ulong *cs_base, uint32_t *flags)
>  {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>
>  *pc = env->pc;
>  *cs_base = 0;
> @@ -784,9 +784,4 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState 
> *env, target_ulong *pc,
>  }
>  }
>
> -typedef CPUXtensaState CPUArchState;
> -typedef XtensaCPU ArchCPU;
> -
> -#include "exec/cpu-all.h"
> -
>  #endif
> diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
> index a8939f5e58..df3acbb541 100644
> --- a/hw/xtensa/pic_cpu.c
> +++ b/hw/xtensa/pic_cpu.c
> @@ -33,7 +33,7 @@
>
>  void check_interrupts(CPUXtensaState *env)
>  {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>  int minlevel = xtensa_get_cintlevel(env);
>  uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
>  int level;
> diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
> index bee78edb8a..64831c9199 100644
> --- a/linux-user/xtensa/cpu_loop.c
> +++ b/linux-user/xtensa/cpu_loop.c
> @@ -123,7 +123,7 @@ static void xtensa_underflow12(CPUXtensaState *env)
>
>  void cpu_loop(CPUXtensaState *env)
>  {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>  target_siginfo_t info;
>  abi_ulong ret;
>  int trapnr;
> diff --git a/target/xtensa/dbg_helper.c b/target/xtensa/dbg_helper.c
> index cd8fbd653a..be1f81107b 100644
> --- a/target/xtensa/dbg_helper.c
> +++ b/target/xtensa/dbg_helper.c
> @@ -71,7 +71,7 @@ void HELPER(wsr_ibreaka)(CPUXtensaState *env, uint32_t i, 
> uint32_t v)
>  static void set_dbreak(CPUXtensaState *env, unsigned i, uint32_t dbreaka,
>  uint32_t dbreakc)
>  {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>  int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
>  uint32_t mask = dbreakc | ~DBREAKC_MASK;
>
> @@ -118,7 +118,7 @@ void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, 
> uint32_t v)
>  set_dbreak(env, i, env->sregs[DBREAKA + i], v);
>  } else {
>  if (env->cpu_watchpoint[i]) {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>
>  cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[i]);
>  env->cpu_watchpoint[i] = NULL;
> diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
> index 4a1f7aef5d..601341d13a 100644
> --- a/target/xtensa/exc_helper.c
> +++ b/target/xtensa/exc_helper.c
> @@ -34,7 +34,7 @@
>
>  void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
>  {
> -CPUState *cs = CPU(xtensa_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>
>  cs->exception_index = excp;
>  if (excp == EXCP_YIELD) {
> @@ -100,7 +100,7 @@ void HELPER(debug_exception)(CPUXtensaState *env, 
> uint32_t pc, uint32_t cause)
>
>  void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
>  {
> -CPUState *cpu;
> +CPUState *cpu = env_cpu(env);
>
>  env->pc = pc;
>  env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
> @@ -111,11 +111,10 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, 
> uint32_t intlevel)
>  qemu_mutex_unlock_iothread();
>
>  if (env->pending_irq_level) {
> -cpu_loop_exit(CPU(xtensa_env_get_cpu(env)));
> +cpu_loop_exit(cpu);
>  return;
>  }
>
> -cpu = CPU(xtensa_env_get_cpu(env));
>  cpu->halted = 1;
>  

Re: [Qemu-devel] [PATCH v3 29/39] target/unicore32: Use env_cpu, env_archcpu

2019-05-09 Thread Alistair Francis
On Tue, May 7, 2019 at 5:30 PM Richard Henderson
 wrote:
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/unicore32/cpu.h  |  5 -
>  hw/unicore32/puv3.c |  2 +-
>  target/unicore32/helper.c   |  8 ++--
>  target/unicore32/op_helper.c|  2 +-
>  target/unicore32/softmmu.c  | 11 ---
>  target/unicore32/translate.c| 26 ++
>  target/unicore32/ucf64_helper.c |  2 +-
>  7 files changed, 11 insertions(+), 45 deletions(-)
>
> diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
> index 22e22345dc..2dd1b34765 100644
> --- a/target/unicore32/cpu.h
> +++ b/target/unicore32/cpu.h
> @@ -76,11 +76,6 @@ struct UniCore32CPU {
>  CPUUniCore32State env;
>  };
>
> -static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
> -{
> -return container_of(env, UniCore32CPU, env);
> -}
> -
>  #define ENV_OFFSET offsetof(UniCore32CPU, env)
>
>  void uc32_cpu_do_interrupt(CPUState *cpu);
> diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
> index b42e600f74..132e6086ee 100644
> --- a/hw/unicore32/puv3.c
> +++ b/hw/unicore32/puv3.c
> @@ -56,7 +56,7 @@ static void puv3_soc_init(CPUUniCore32State *env)
>
>  /* Initialize interrupt controller */
>  cpu_intc = qemu_allocate_irq(puv3_intc_cpu_handler,
> - uc32_env_get_cpu(env), 0);
> + env_archcpu(env), 0);
>  dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, cpu_intc);
>  for (i = 0; i < PUV3_IRQS_NR; i++) {
>  irqs[i] = qdev_get_gpio_in(dev, i);
> diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
> index a5ff2ddb74..19ba865482 100644
> --- a/target/unicore32/helper.c
> +++ b/target/unicore32/helper.c
> @@ -31,8 +31,6 @@
>  void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
>  uint32_t cop)
>  {
> -UniCore32CPU *cpu = uc32_env_get_cpu(env);
> -
>  /*
>   * movc pp.nn, rn, #imm9
>   *  rn: UCOP_REG_D
> @@ -101,7 +99,7 @@ void helper_cp0_set(CPUUniCore32State *env, uint32_t val, 
> uint32_t creg,
>  case 6:
>  if ((cop <= 6) && (cop >= 2)) {
>  /* invalid all tlb */
> -tlb_flush(CPU(cpu));
> +tlb_flush(env_cpu(env));
>  return;
>  }
>  break;
> @@ -218,10 +216,8 @@ void helper_cp1_putc(target_ulong x)
>  #ifdef CONFIG_USER_ONLY
>  void switch_mode(CPUUniCore32State *env, int mode)
>  {
> -UniCore32CPU *cpu = uc32_env_get_cpu(env);
> -
>  if (mode != ASR_MODE_USER) {
> -cpu_abort(CPU(cpu), "Tried to switch out of user mode\n");
> +cpu_abort(env_cpu(env), "Tried to switch out of user mode\n");
>  }
>  }
>
> diff --git a/target/unicore32/op_helper.c b/target/unicore32/op_helper.c
> index e0a15882d3..44ff84420e 100644
> --- a/target/unicore32/op_helper.c
> +++ b/target/unicore32/op_helper.c
> @@ -19,7 +19,7 @@
>
>  void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
>  {
> -CPUState *cs = CPU(uc32_env_get_cpu(env));
> +CPUState *cs = env_cpu(env);
>
>  cs->exception_index = excp;
>  cpu_loop_exit(cs);
> diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
> index 00c7e0d028..2f31592faf 100644
> --- a/target/unicore32/softmmu.c
> +++ b/target/unicore32/softmmu.c
> @@ -36,8 +36,6 @@
>  /* Map CPU modes onto saved register banks.  */
>  static inline int bank_number(CPUUniCore32State *env, int mode)
>  {
> -UniCore32CPU *cpu = uc32_env_get_cpu(env);
> -
>  switch (mode) {
>  case ASR_MODE_USER:
>  case ASR_MODE_SUSR:
> @@ -51,7 +49,7 @@ static inline int bank_number(CPUUniCore32State *env, int 
> mode)
>  case ASR_MODE_INTR:
>  return 4;
>  }
> -cpu_abort(CPU(cpu), "Bad mode %x\n", mode);
> +cpu_abort(env_cpu(env), "Bad mode %x\n", mode);
>  return -1;
>  }
>
> @@ -126,8 +124,7 @@ static int get_phys_addr_ucv2(CPUUniCore32State *env, 
> uint32_t address,
>  int access_type, int is_user, uint32_t *phys_ptr, int *prot,
>  target_ulong *page_size)
>  {
> -UniCore32CPU *cpu = uc32_env_get_cpu(env);
> -CPUState *cs = CPU(cpu);
> +CPUState *cs = env_cpu(env);
>  int code;
>  uint32_t table;
>  uint32_t desc;
> @@ -174,11 +171,11 @@ static int get_phys_addr_ucv2(CPUUniCore32State *env, 
> uint32_t address,
>  *page_size = TARGET_PAGE_SIZE;
>  break;
>  default:
> -cpu_abort(CPU(cpu), "wrong page type!");
> +cpu_abort(cs, "wrong page type!");
>  }
>  break;
>  default:
> -cpu_abort(CPU(cpu), "wrong page type!");
> +cpu_abort(cs, "wrong page type!");
>  }
>
>  *phys_ptr = phys_addr;
> diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
> index 89b02d1c3c..d27451eed3 100644
> --- a/target/unicore32/translate.c
> +++ 

  1   2   3   4   >