Re: vnc clipboard support

2021-01-28 Thread Christophe de Dinechin


Christophe
(Typos are from my iPhone)

> Le 28 janv. 2021 à 21:24, Marc-André Lureau  a 
> écrit :
> 
> 
> Hi
> 
>> On Thu, Jan 28, 2021 at 9:14 PM Gerd Hoffmann  wrote:
>>   Hi folks,
>> 
>> I'm looking for a good way to implement cut+paste support for vnc.
>> 
>> The vnc core protocol has support for text/plain cut+paste, and there
>> is an extension adding support for other formats.  That'll cover one
>> part of the problem, exchanging cut+paste data between vnc client and
>> qemu vnc server.
>> 
>> The tricky part is the second: the guest <=> qemu communication.
>> I see basically two possible approaches here:
>> 
>>   (1) Have some guest agent (spice does it that way).
>>   Advantage: more flexible, allows more features.
>>   Disadvantage: requires agent in the guest.
>> 
>>   (2) Send text as key events.
>>   Advantage: no guest agent needed.
>>   Disadvantage: is translated by guests keyboard map, so qemu
>>   needs to know the map for proper char -> key event translation.
>>   Only works for text/plain and only for chars you can easily
>>   type, anything needing input methods (emoji 😊 for example)
>>   isn't going to fly.
>> 
>> I think that (1) is clearly the better way.  Given that the agent
>> would need to run in user wayland/xorg session context the existing
>> qemu-guest-agent will not work.  Also linking against some UI library
>> like gtk3 for clipboard handling is not something we want for the
>> qemu-guest-agent.  So we need another one, I'll name it
>> qemu-clipboard-agent for the rest of this mail.  And we need a
>> communication channel.
>> 
>> I'd tend to model the qemu-clipboard-agent simliar to the
>> qemu-guest-agent, i.e. have some stream as communication path and run
>> some stream protocol over it.
>> 
>> Stream options I see are (in order of personal preference):
>> 
>>   (1) New virtio-serial port.  virtio-serial likely is there anyway
>>   for the qemu-guest-agent ...
>> 
>>   (2) Have qemu-clipboard-agent and qemu-guest-agent share the agent
>>   channel, i.e. qemu-clipboard-agent will proxy everything through
>>   qemu-guest-agent (spice does it that way).
>> 
>> Protocol options I see are (not sure yet which to prefer, need to have
>> a closer look at the candidates):
>> 
>>   (1) Add clipboard commands to QMP and use these.
>> 
>>   (2) Reuse the clipboard bits of the vnc protocol (forward
>>   VNC_MSG_CLIENT_CUT_TEXT messages to the guest agent)
>> 
>>   (3) Reuse the clipboard bits of the spice-agent protocol.
>> 
>>   (4) Reuse the clipboard bits of the wayland protocol.
>> 
>> Once we have sorted the qemu <-> guest communication path it should be
>> possible to also hook up other UIs (specifically gtk) without too much
>> effort.  Which probably makes (2) a rather poor choice.
>> 
>> Comments?
>> Suggestions?
>> Other ideas?
> 
> 
> 
> I also had recently some thoughts about how to implement clipboard sharing in 
> a more general way for QEMU.
> 
> I admit I like Christophe's suggestion ("it's somebody else problem"), but it 
> falls short to me as I don't know of a common open-source remoting solution 
> for various operating systems, and I don't see how it could integrate well 
> with our UI and remote protocols. Or look at reusing some VirtualBox code 
> perhaps?

Just to clarify, I did not think of my suggestion as “SEP” but more as a way to 
leverage existing knowledge regarding guest OS clipboard. More a “what should 
we steal” approach. 

> 
> Some things I keep in mind:
> - the spice protocol had a number of iterations to fix some races. It would 
> be great not to repeat the same mistakes, and I don't know if VNC have the 
> same flaws or not.
> - the spice agent design isn't great: the system agent proxies messages to 
> the active session. It would be nice if the new solution didn't have such a 
> middle-man.
> - with wayland, clipboard sharing isn't really possible. Or not in a seamless 
> way at least. Today it kinda works with some X11 compatibility extensions, 
> but this will eventually go away or change behaviour.
> - the GNOME desktop is working on remoting using RDP, and they are 
> implementing a DBus interface for it 
> (https://gitlab.gnome.org/jadahl/mutter/-/commits/wip/remote-desktop-clipboard)
> - it's not just about clipboard. We would also want to have some kind of drag 
> and drop (even if limited to files like Spice atm). We may want some 
> windowing integration. We may also want to have access to some desktop 
> services: apps, documents etc.. And what's not.
> 
> That leads me to think that virtio-serial is not very well suited, as it 
> doesn't allow various services / processes to come and go. I see vsock as a 
> much better alternative. (I also wonder if it handles control flow any better 
> btw)
> 
> I think we shoud work on getting the free desktops our best-class support. To 
> me, this means we need to speak the lingua franca, which is DBus. The great 
> thing is that DBus is a

Re: vnc clipboard support

2021-01-28 Thread Gerd Hoffmann
On Thu, Jan 28, 2021 at 05:35:04PM +, Daniel P. Berrangé wrote:
> On Thu, Jan 28, 2021 at 06:12:24PM +0100, Gerd Hoffmann wrote:
> >   Hi folks,
> > 
> > I'm looking for a good way to implement cut+paste support for vnc.
> > 
> > The vnc core protocol has support for text/plain cut+paste, and there
> > is an extension adding support for other formats.  That'll cover one
> > part of the problem, exchanging cut+paste data between vnc client and
> > qemu vnc server.
> 
> NB the VNC cut+paste impl is technically undefined  for non-7-bit ascii
> data. In reality though I'd assume most servers/clients and up sending
> UTF8. 

rfbspec says it is latin1 for classic cut_text messages and utf-8 with
the extension.  In reality I've seen tigervnc send utf-8 even in classic
cut_text messages.  Given running in utf-8 locale is sort-of standard
these days I'm not surprised.

> I've never looked at the spice-guest-agent code, but I wonder if there
> is any scope for re-using it with VNC, or is it too closely tangled
> up with SPICE ?  The advantage of reuse is that all existing guest
> OS with spice-guest-agent installed will "just work".

Neat idea.  Need to check.  spice tunnels alot of stuff through the
agent channel, but IIRC there is some kind of feature negotiation so
maybe it isn't that hard to cherry-pick cut+paste and say "not
supported" for everything else.

> The QEMU guest agent is a single system level agent. IIUC, with SPICE
> you have a single system level agent, and then zero or more session
> level agents - one per desktop login basically.

Ok, easy multi-session support is one advantage of the proxy model.

take care,
  Gerd




Re: [PATCH] target/rx: Fix compiler errors for build with sanitizers

2021-01-28 Thread Laurent Vivier
Le 28/01/2021 à 18:21, Stefan Weil a écrit :
> gcc (Debian 10.2.1-6) 10.2.1 20210110 aborts builds with enabled sanitizers:
> 
> ../../../target/rx/op_helper.c: In function ‘helper_scmpu’:
> ../../../target/rx/op_helper.c:213:24: error: ‘tmp1’ may be used 
> uninitialized in this function [-Werror=maybe-uninitialized]
>   213 | env->psw_c = (tmp0 >= tmp1);
>   |  ~~^~~~
> ../../../target/rx/op_helper.c:213:24: error: ‘tmp0’ may be used 
> uninitialized in this function [-Werror=maybe-uninitialized]
> ../../../target/rx/op_helper.c: In function ‘helper_suntil’:
> ../../../target/rx/op_helper.c:299:23: error: ‘tmp’ may be used uninitialized 
> in this function [-Werror=maybe-uninitialized]
>   299 | env->psw_c = (tmp <= env->regs[2]);
>   |  ~^~~~
> ../../../target/rx/op_helper.c: In function ‘helper_swhile’:
> ../../../target/rx/op_helper.c:318:23: error: ‘tmp’ may be used uninitialized 
> in this function [-Werror=maybe-uninitialized]
>   318 | env->psw_c = (tmp <= env->regs[2]);
>   |  ~^~~~
> 
> Rewriting the code fixes those errors.
> 
> Signed-off-by: Stefan Weil 
> ---
> 
> Those error are false positives, but simple code changes help the
> compiler (and perhaps reviewers) to understand it better.
> 
> Stefan
> 
> 
>  target/rx/op_helper.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
> index 59389f4992..4d315b4449 100644
> --- a/target/rx/op_helper.c
> +++ b/target/rx/op_helper.c
> @@ -201,14 +201,14 @@ void helper_scmpu(CPURXState *env)
>  if (env->regs[3] == 0) {
>  return;
>  }
> -while (env->regs[3] != 0) {
> +do {
>  tmp0 = cpu_ldub_data_ra(env, env->regs[1]++, GETPC());
>  tmp1 = cpu_ldub_data_ra(env, env->regs[2]++, GETPC());
>  env->regs[3]--;
>  if (tmp0 != tmp1 || tmp0 == '\0') {
>  break;
>  }
> -}
> +} while (env->regs[3] != 0);
>  env->psw_z = tmp0 - tmp1;
>  env->psw_c = (tmp0 >= tmp1);
>  }
> @@ -287,14 +287,14 @@ void helper_suntil(CPURXState *env, uint32_t sz)
>  if (env->regs[3] == 0) {
>  return ;
>  }
> -while (env->regs[3] != 0) {
> +do {
>  tmp = cpu_ldufn[sz](env, env->regs[1], GETPC());
>  env->regs[1] += 1 << sz;
>  env->regs[3]--;
>  if (tmp == env->regs[2]) {
>  break;
>  }
> -}
> +} while (env->regs[3] != 0);
>  env->psw_z = tmp - env->regs[2];
>  env->psw_c = (tmp <= env->regs[2]);
>  }
> @@ -306,14 +306,14 @@ void helper_swhile(CPURXState *env, uint32_t sz)
>  if (env->regs[3] == 0) {
>  return ;
>  }
> -while (env->regs[3] != 0) {
> +do {
>  tmp = cpu_ldufn[sz](env, env->regs[1], GETPC());
>  env->regs[1] += 1 << sz;
>  env->regs[3]--;
>  if (tmp != env->regs[2]) {
>  break;
>  }
> -}
> +} while (env->regs[3] != 0);
>  env->psw_z = env->regs[3];
>  env->psw_c = (tmp <= env->regs[2]);
>  }
> 

Applied to my trivial-patches branch.

Thanks,
Laurent




Re: [PATCH] vfio/migrate: Move switch of dirty tracking into vfio_memory_listener

2021-01-28 Thread Paolo Bonzini

On 28/01/21 21:02, Dr. David Alan Gilbert wrote:

* Paolo Bonzini (pbonz...@redhat.com) wrote:

On 11/01/21 08:34, Keqian Zhu wrote:

+static void vfio_listener_log_start(MemoryListener *listener,
+MemoryRegionSection *section,
+int old, int new)
+{
+VFIOContainer *container = container_of(listener, VFIOContainer, listener);
+
+vfio_set_dirty_page_tracking(container, true);
+}


This would enable dirty page tracking also just for having a framebuffer
(DIRTY_MEMORY_VGA).  Technically it would be correct, but it would also be
more heavyweight than expected.


Wouldn't that only happen on emulated video devices?


Yes, but still it's not impossible to have both an emulated VGA and an 
assigned GPU or vGPU.



In order to only cover live migration, you can use the log_global_start and
log_global_stop callbacks instead.

If you want to use log_start and log_stop, you need to add respectively

 if (old != 0) {
 return;
 }

and

 if (new != 0) {
 return;
 }


Why 0, wouldn't you be checking for DIRTY_LOG_MIGRATION somewhere?


Actually thinking more about it log_start/log_stop are just wrong, 
because they would be called many times, for each MemoryRegionSection.


Paolo




[PATCH v2 3/3] nbd: make nbd_read* return -EIO on error

2021-01-28 Thread Roman Kagan
NBD reconnect logic considers the error code from the functions that
read NBD messages to tell if reconnect should be attempted or not: it is
attempted on -EIO, otherwise the client transitions to NBD_CLIENT_QUIT
state (see nbd_channel_error).  This error code is propagated from the
primitives like nbd_read.

The problem, however, is that nbd_read itself turns every error into -1
rather than -EIO.  As a result, if the NBD server happens to die while
sending the message, the client in QEMU receives less data than it
expects, considers it as a fatal error, and wouldn't attempt
reestablishing the connection.

Fix it by turning every negative return from qio_channel_read_all into
-EIO returned from nbd_read.  Apparently that was the original behavior,
but got broken later.  Also adjust nbd_readXX to follow.

Fixes: e6798f06a6 ("nbd: generalize usage of nbd_read")
Signed-off-by: Roman Kagan 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 include/block/nbd.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4a52a43ef5..5f34d23bb0 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -364,7 +364,7 @@ static inline int nbd_read(QIOChannel *ioc, void *buffer, 
size_t size,
 if (desc) {
 error_prepend(errp, "Failed to read %s: ", desc);
 }
-return -1;
+return ret;
 }
 
 return 0;
@@ -375,8 +375,9 @@ static inline int nbd_read##bits(QIOChannel *ioc,   
\
  uint##bits##_t *val,   \
  const char *desc, Error **errp)\
 {   \
-if (nbd_read(ioc, val, sizeof(*val), desc, errp) < 0) { \
-return -1;  \
+int ret = nbd_read(ioc, val, sizeof(*val), desc, errp); \
+if (ret < 0) {  \
+return ret; \
 }   \
 *val = be##bits##_to_cpu(*val); \
 return 0;   \
-- 
2.29.2




[PATCH v2 2/3] block/nbd: only enter connection coroutine if it's present

2021-01-28 Thread Roman Kagan
When an NBD block driver state is moved from one aio_context to another
(e.g. when doing a drain in a migration thread),
nbd_client_attach_aio_context_bh is executed that enters the connection
coroutine.

However, the assumption that ->connection_co is always present here
appears incorrect: the connection may have encountered an error other
than -EIO in the underlying transport, and thus may have decided to quit
rather than keep trying to reconnect, and therefore it may have
terminated the connection coroutine.  As a result an attempt to reassign
the client in this state (NBD_CLIENT_QUIT) to a different aio_context
leads to a null pointer dereference:

  #0  qio_channel_detach_aio_context (ioc=0x0)
  at /build/qemu-gYtjVn/qemu-5.0.1/io/channel.c:452
  #1  0x562a242824b3 in bdrv_detach_aio_context (bs=0x562a268d6a00)
  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6151
  #2  bdrv_set_aio_context_ignore (bs=bs@entry=0x562a268d6a00,
  new_context=new_context@entry=0x562a260c9580,
  ignore=ignore@entry=0x7feeadc9b780)
  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6230
  #3  0x562a24282969 in bdrv_child_try_set_aio_context
  (bs=bs@entry=0x562a268d6a00, ctx=0x562a260c9580,
  ignore_child=, errp=)
  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6332
  #4  0x562a242bb7db in blk_do_set_aio_context (blk=0x562a2735d0d0,
  new_context=0x562a260c9580,
  update_root_node=update_root_node@entry=true, errp=errp@entry=0x0)
  at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:1989
  #5  0x562a242be0bd in blk_set_aio_context (blk=,
  new_context=, errp=errp@entry=0x0)
  at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:2010
  #6  0x562a23fbd953 in virtio_blk_data_plane_stop (vdev=)
  at /build/qemu-gYtjVn/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
  #7  0x562a241fc7bf in virtio_bus_stop_ioeventfd (bus=0x562a260dbf08)
  at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio-bus.c:245
  #8  0x562a23fefb2e in virtio_vmstate_change (opaque=0x562a260dbf90,
  running=0, state=)
  at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio.c:3220
  #9  0x562a2402ebfd in vm_state_notify (running=running@entry=0,
  state=state@entry=RUN_STATE_FINISH_MIGRATE)
  at /build/qemu-gYtjVn/qemu-5.0.1/softmmu/vl.c:1275
  #10 0x562a23f7bc02 in do_vm_stop (state=RUN_STATE_FINISH_MIGRATE,
  send_stop=)
  at /build/qemu-gYtjVn/qemu-5.0.1/cpus.c:1032
  #11 0x562a24209765 in migration_completion (s=0x562a260e83a0)
  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:2914
  #12 migration_iteration_run (s=0x562a260e83a0)
  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3275
  #13 migration_thread (opaque=opaque@entry=0x562a260e83a0)
  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3439
  #14 0x562a2435ca96 in qemu_thread_start (args=)
  at /build/qemu-gYtjVn/qemu-5.0.1/util/qemu-thread-posix.c:519
  #15 0x7feed31466ba in start_thread (arg=0x7feeadc9c700)
  at pthread_create.c:333
  #16 0x7feed2e7c41d in __GI___sysctl (name=0x0, nlen=608471908,
  oldval=0x562a2452b138, oldlenp=0x0, newval=0x562a2452c5e0
  <__func__.28102>, newlen=0)
  at ../sysdeps/unix/sysv/linux/sysctl.c:30
  #17 0x in ?? ()

Fix it by checking that the connection coroutine is non-null before
trying to enter it.  If it is null, no entering is needed, as the
connection is probably going down anyway.

Signed-off-by: Roman Kagan 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/nbd.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index bcd6641e90..b3cbbeb4b0 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -250,13 +250,15 @@ static void nbd_client_attach_aio_context_bh(void *opaque)
 BlockDriverState *bs = opaque;
 BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
 
-/*
- * The node is still drained, so we know the coroutine has yielded in
- * nbd_read_eof(), the only place where bs->in_flight can reach 0, or it is
- * entered for the first time. Both places are safe for entering the
- * coroutine.
- */
-qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+if (s->connection_co) {
+/*
+ * The node is still drained, so we know the coroutine has yielded in
+ * nbd_read_eof(), the only place where bs->in_flight can reach 0, or
+ * it is entered for the first time. Both places are safe for entering
+ * the coroutine.
+ */
+qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+}
 bdrv_dec_in_flight(bs);
 }
 
-- 
2.29.2




[PATCH v2 1/3] block/nbd: only detach existing iochannel from aio_context

2021-01-28 Thread Roman Kagan
When the reconnect in NBD client is in progress, the iochannel used for
NBD connection doesn't exist.  Therefore an attempt to detach it from
the aio_context of the parent BlockDriverState results in a NULL pointer
dereference.

The problem is triggerable, in particular, when an outgoing migration is
about to finish, and stopping the dataplane tries to move the
BlockDriverState from the iothread aio_context to the main loop.  If the
NBD connection is lost before this point, and the NBD client has entered
the reconnect procedure, QEMU crashes:

  #0  qemu_aio_coroutine_enter (ctx=0x5618056c7580, co=0x0)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-coroutine.c:109
  #1  0x5618034b1b68 in nbd_client_attach_aio_context_bh (
  opaque=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block/nbd.c:164
  #2  0x56180353116b in aio_wait_bh (opaque=0x7f60e1e63700)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:55
  #3  0x561803530633 in aio_bh_call (bh=0x7f60d40a7e80)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:136
  #4  aio_bh_poll (ctx=ctx@entry=0x5618056c7580)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:164
  #5  0x561803533e5a in aio_poll (ctx=ctx@entry=0x5618056c7580,
  blocking=blocking@entry=true)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-posix.c:650
  #6  0x56180353128d in aio_wait_bh_oneshot (ctx=0x5618056c7580,
  cb=, opaque=)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:71
  #7  0x56180345c50a in bdrv_attach_aio_context (new_context=0x5618056c7580,
  bs=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6172
  #8  bdrv_set_aio_context_ignore (bs=bs@entry=0x561805ed4c00,
  new_context=new_context@entry=0x5618056c7580,
  ignore=ignore@entry=0x7f60e1e63780)
  at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6237
  #9  0x56180345c969 in bdrv_child_try_set_aio_context (
  bs=bs@entry=0x561805ed4c00, ctx=0x5618056c7580,
  ignore_child=, errp=)
  at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6332
  #10 0x5618034957db in blk_do_set_aio_context (blk=0x56180695b3f0,
  new_context=0x5618056c7580, update_root_node=update_root_node@entry=true,
  errp=errp@entry=0x0)
  at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:1989
  #11 0x5618034980bd in blk_set_aio_context (blk=,
  new_context=, errp=errp@entry=0x0)
  at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:2010
  #12 0x561803197953 in virtio_blk_data_plane_stop (vdev=)
  at /build/qemu-6MF7tq/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
  #13 0x5618033d67bf in virtio_bus_stop_ioeventfd (bus=0x5618056d9f08)
  at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio-bus.c:245
  #14 0x5618031c9b2e in virtio_vmstate_change (opaque=0x5618056d9f90,
  running=0, state=)
  at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio.c:3220
  #15 0x561803208bfd in vm_state_notify (running=running@entry=0,
  state=state@entry=RUN_STATE_FINISH_MIGRATE)
  at /build/qemu-6MF7tq/qemu-5.0.1/softmmu/vl.c:1275
  #16 0x561803155c02 in do_vm_stop (state=RUN_STATE_FINISH_MIGRATE,
  send_stop=) at /build/qemu-6MF7tq/qemu-5.0.1/cpus.c:1032
  #17 0x5618033e3765 in migration_completion (s=0x5618056e6960)
  at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:2914
  #18 migration_iteration_run (s=0x5618056e6960)
  at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3275
  #19 migration_thread (opaque=opaque@entry=0x5618056e6960)
  at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3439
  #20 0x561803536ad6 in qemu_thread_start (args=)
  at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-thread-posix.c:519
  #21 0x7f61085d06ba in start_thread ()
 from /lib/x86_64-linux-gnu/libpthread.so.0
  #22 0x7f610830641d in sysctl () from /lib/x86_64-linux-gnu/libc.so.6
  #23 0x in ?? ()

Fix it by checking that the iochannel is non-null before trying to
detach it from the aio_context.  If it is null, no detaching is needed,
and it will get reattached in the proper aio_context once the connection
is reestablished.

Signed-off-by: Roman Kagan 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 block/nbd.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/block/nbd.c b/block/nbd.c
index 42e10c7c93..bcd6641e90 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -235,7 +235,14 @@ static void nbd_client_detach_aio_context(BlockDriverState 
*bs)
 
 /* Timer is deleted in nbd_client_co_drain_begin() */
 assert(!s->reconnect_delay_timer);
-qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+/*
+ * If reconnect is in progress we may have no ->ioc.  It will be
+ * re-instantiated in the proper aio context once the connection is
+ * reestablished.
+ */
+if (s->ioc) {
+qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+}
 }
 
 static void nbd_client_attach_aio_context_bh(void *opaque)
-- 
2.29.2




[PATCH v2 0/3] block/nbd: fix crashers in reconnect while migrating

2021-01-28 Thread Roman Kagan
During the final phase of migration the NBD reconnection logic may
encounter situations it doesn't expect during regular operation.

This series addresses some of them that make qemu crash.  They are
reproducible when a vm with a secondary drive attached via nbd with
non-zero "reconnect-delay" runs a stress load (fio with big queue depth)
in the guest on that drive and is migrated (e.g. to a file), while the
nbd server is SIGKILL-ed and restarted every second.

See the individual patches for specific crash conditions and more
detailed explanations.

v1 -> v2:
- fix corrupted backtraces in log messages
- add r-b by Vladimir

Roman Kagan (3):
  block/nbd: only detach existing iochannel from aio_context
  block/nbd: only enter connection coroutine if it's present
  nbd: make nbd_read* return -EIO on error

 include/block/nbd.h |  7 ---
 block/nbd.c | 25 +
 2 files changed, 21 insertions(+), 11 deletions(-)

-- 
2.29.2




Re: [PATCH 0/3] block/nbd: fix crashers in reconnect while migrating

2021-01-28 Thread Roman Kagan
On Fri, Jan 29, 2021 at 08:51:39AM +0300, Vladimir Sementsov-Ogievskiy wrote:
> 28.01.2021 23:14, Roman Kagan wrote:
> > During the final phase of migration the NBD reconnection logic may
> > encounter situations it doesn't expect during regular operation.
> > 
> > This series addresses some of them that make qemu crash.  They are
> > reproducible when a vm with a secondary drive attached via nbd with
> > non-zero "reconnect-delay" runs a stress load (fio with big queue depth)
> > in the guest on that drive and is migrated (e.g. to a file), while the
> > nbd server is SIGKILL-ed and restarted every second.
> > 
> > See the individual patches for specific crash conditions and more
> > detailed explanations.
> > 
> > Roman Kagan (3):
> >block/nbd: only detach existing iochannel from aio_context
> >block/nbd: only enter connection coroutine if it's present
> >nbd: make nbd_read* return -EIO on error
> > 
> >   include/block/nbd.h |  7 ---
> >   block/nbd.c | 25 +
> >   2 files changed, 21 insertions(+), 11 deletions(-)
> > 
> 
> Thanks a lot for fixing!
> 
> Do you have some reproducer scripts? Could you post them or may be add
> an iotest?

I don't have it scripted, just ad hoc command lines.  I'll look into
making up a test.  Can you perhaps suggest what existing test to base
on?

Thanks,
Roman.



Re: [PATCH] vhost-user: Check for iotlb callback in iotlb_miss

2021-01-28 Thread Jason Wang



On 2021/1/29 下午3:22, Eugenio Perez Martin wrote:

On Fri, Jan 29, 2021 at 4:29 AM Jason Wang  wrote:


On 2021/1/28 下午5:37, Eugenio Perez Martin wrote:

Hi Jason.

On Thu, Jan 28, 2021 at 3:32 AM Jason Wang  wrote:

On 2021/1/28 上午4:44, Eugenio Pérez wrote:

Not registering this can lead to vhost_backend_handle_iotlb_msg and
vhost_device_iotlb_miss if backend issue a miss after qemu vhost device
stop.

This causes a try to access dev->vdev->dma_as with vdev == NULL.

Hi Eugenio:

What condition can we get this? Did you mean we receive IOTLB_MISS
before vhost_dev_start()?


In the VM reboot case, yes, between vhost_dev_stop() and
vhost_dev_start(). But I can reproduce the bug in VM shutdown too,
with no vhost_dev_start expected.

I didn't try to send IOTLB_MISS before starting vhost_dev, but this
patch should solve that problem too.

I think we can get this with whatever malicious/buggy vhost-user
backend sending unexpected iotlb misses, but I didn't test so deeply.


I see.



If yes, it looks to me a bug somewhere else.

Where should I look for it?


So I winder whether or not we can simply ignore IOTLB message if vhost
device is not started.


Do you mean like an early return in vhost_device_iotlb_miss?



Yes or probably a little bit earlier in vhost_backend_handle_iotlb_msg() 
which somehow a warn there.


Anyhow it's meaningless to process IOTLB message in this case and we 
don't need to introduce a dedicated variable for this.


Thanks



That was
my first first option, but this seems cleaner to me. I'm ok with both
options.

Or do you mean not to return -EFAULT but 0 if !u->iotlb_enabled ?

Thanks!


Thanks



Thanks!


Thanks



Reproduced rebooting a guest with testpmd in txonly forward mode.
#0  0x55994394 in vhost_device_iotlb_miss (
dev=dev@entry=0x55a0012f6680, iova=10245279744, write=1)
at ../hw/virtio/vhost.c:1013
#1  0x5599ac31 in vhost_backend_handle_iotlb_msg (
imsg=0x7ffddcfd32c0, dev=0x55a0012f6680)
at ../hw/virtio/vhost-backend.c:411
#2  vhost_backend_handle_iotlb_msg (dev=dev@entry=0x55a0012f6680,
imsg=imsg@entry=0x7ffddcfd32c0)
at ../hw/virtio/vhost-backend.c:404
#3  0x559fffeded7b in slave_read (opaque=0x55a0012f6680)
at ../hw/virtio/vhost-user.c:1464
#4  0x55ac541b in aio_dispatch_handler (
ctx=ctx@entry=0x55a0010a2120, node=0x55a0012d9e00)
at ../util/aio-posix.c:329

Fixes: 6dcdd06e3b ("spec/vhost-user spec: Add IOMMU support")
Signed-off-by: Eugenio Pérez 
---
hw/virtio/vhost-user.c | 10 --
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 2fdd5daf74..a49b2229fb 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -238,6 +238,7 @@ struct vhost_user {
/* Shared between vhost devs of the same virtio device */
VhostUserState *user;
int slave_fd;
+bool iotlb_enabled;
NotifierWithReturn postcopy_notifier;
struct PostCopyFD  postcopy_fd;
uint64_t   postcopy_client_bases[VHOST_USER_MAX_RAM_SLOTS];
@@ -1461,7 +1462,11 @@ static void slave_read(void *opaque)

switch (hdr.request) {
case VHOST_USER_SLAVE_IOTLB_MSG:
-ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
+if (likely(u->iotlb_enabled)) {
+ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
+} else {
+ret = -EFAULT;
+}
break;
case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
ret = vhost_user_slave_handle_config_change(dev);
@@ -2044,7 +2049,8 @@ static int vhost_user_send_device_iotlb_msg(struct 
vhost_dev *dev,

static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int 
enabled)
{
-/* No-op as the receive channel is not dedicated to IOTLB messages. */
+struct vhost_user *u = dev->opaque;
+u->iotlb_enabled = enabled;
}

static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,





Re: [PATCH] vhost-user: Check for iotlb callback in iotlb_miss

2021-01-28 Thread Eugenio Perez Martin
On Fri, Jan 29, 2021 at 4:29 AM Jason Wang  wrote:
>
>
> On 2021/1/28 下午5:37, Eugenio Perez Martin wrote:
> > Hi Jason.
> >
> > On Thu, Jan 28, 2021 at 3:32 AM Jason Wang  wrote:
> >>
> >> On 2021/1/28 上午4:44, Eugenio Pérez wrote:
> >>> Not registering this can lead to vhost_backend_handle_iotlb_msg and
> >>> vhost_device_iotlb_miss if backend issue a miss after qemu vhost device
> >>> stop.
> >>>
> >>> This causes a try to access dev->vdev->dma_as with vdev == NULL.
> >>
> >> Hi Eugenio:
> >>
> >> What condition can we get this? Did you mean we receive IOTLB_MISS
> >> before vhost_dev_start()?
> >>
> > In the VM reboot case, yes, between vhost_dev_stop() and
> > vhost_dev_start(). But I can reproduce the bug in VM shutdown too,
> > with no vhost_dev_start expected.
> >
> > I didn't try to send IOTLB_MISS before starting vhost_dev, but this
> > patch should solve that problem too.
> >
> > I think we can get this with whatever malicious/buggy vhost-user
> > backend sending unexpected iotlb misses, but I didn't test so deeply.
>
>
> I see.
>
>
> >
> >> If yes, it looks to me a bug somewhere else.
> > Where should I look for it?
>
>
> So I winder whether or not we can simply ignore IOTLB message if vhost
> device is not started.
>

Do you mean like an early return in vhost_device_iotlb_miss? That was
my first first option, but this seems cleaner to me. I'm ok with both
options.

Or do you mean not to return -EFAULT but 0 if !u->iotlb_enabled ?

Thanks!

> Thanks
>
>
> >
> > Thanks!
> >
> >> Thanks
> >>
> >>
> >>> Reproduced rebooting a guest with testpmd in txonly forward mode.
> >>>#0  0x55994394 in vhost_device_iotlb_miss (
> >>>dev=dev@entry=0x55a0012f6680, iova=10245279744, write=1)
> >>>at ../hw/virtio/vhost.c:1013
> >>>#1  0x5599ac31 in vhost_backend_handle_iotlb_msg (
> >>>imsg=0x7ffddcfd32c0, dev=0x55a0012f6680)
> >>>at ../hw/virtio/vhost-backend.c:411
> >>>#2  vhost_backend_handle_iotlb_msg (dev=dev@entry=0x55a0012f6680,
> >>>imsg=imsg@entry=0x7ffddcfd32c0)
> >>>at ../hw/virtio/vhost-backend.c:404
> >>>#3  0x559fffeded7b in slave_read (opaque=0x55a0012f6680)
> >>>at ../hw/virtio/vhost-user.c:1464
> >>>#4  0x55ac541b in aio_dispatch_handler (
> >>>ctx=ctx@entry=0x55a0010a2120, node=0x55a0012d9e00)
> >>>at ../util/aio-posix.c:329
> >>>
> >>> Fixes: 6dcdd06e3b ("spec/vhost-user spec: Add IOMMU support")
> >>> Signed-off-by: Eugenio Pérez 
> >>> ---
> >>>hw/virtio/vhost-user.c | 10 --
> >>>1 file changed, 8 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> >>> index 2fdd5daf74..a49b2229fb 100644
> >>> --- a/hw/virtio/vhost-user.c
> >>> +++ b/hw/virtio/vhost-user.c
> >>> @@ -238,6 +238,7 @@ struct vhost_user {
> >>>/* Shared between vhost devs of the same virtio device */
> >>>VhostUserState *user;
> >>>int slave_fd;
> >>> +bool iotlb_enabled;
> >>>NotifierWithReturn postcopy_notifier;
> >>>struct PostCopyFD  postcopy_fd;
> >>>uint64_t   postcopy_client_bases[VHOST_USER_MAX_RAM_SLOTS];
> >>> @@ -1461,7 +1462,11 @@ static void slave_read(void *opaque)
> >>>
> >>>switch (hdr.request) {
> >>>case VHOST_USER_SLAVE_IOTLB_MSG:
> >>> -ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
> >>> +if (likely(u->iotlb_enabled)) {
> >>> +ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
> >>> +} else {
> >>> +ret = -EFAULT;
> >>> +}
> >>>break;
> >>>case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
> >>>ret = vhost_user_slave_handle_config_change(dev);
> >>> @@ -2044,7 +2049,8 @@ static int vhost_user_send_device_iotlb_msg(struct 
> >>> vhost_dev *dev,
> >>>
> >>>static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int 
> >>> enabled)
> >>>{
> >>> -/* No-op as the receive channel is not dedicated to IOTLB messages. 
> >>> */
> >>> +struct vhost_user *u = dev->opaque;
> >>> +u->iotlb_enabled = enabled;
> >>>}
> >>>
> >>>static int vhost_user_get_config(struct vhost_dev *dev, uint8_t 
> >>> *config,
>




Re: [PATCH 1/3] block/nbd: only detach existing iochannel from aio_context

2021-01-28 Thread Roman Kagan
On Fri, Jan 29, 2021 at 08:37:13AM +0300, Vladimir Sementsov-Ogievskiy wrote:
> 28.01.2021 23:14, Roman Kagan wrote:
> > When the reconnect in NBD client is in progress, the iochannel used for
> > NBD connection doesn't exist.  Therefore an attempt to detach it from
> > the aio_context of the parent BlockDriverState results in a NULL pointer
> > dereference.
> > 
> > The problem is triggerable, in particular, when an outgoing migration is
> > about to finish, and stopping the dataplane tries to move the
> > BlockDriverState from the iothread aio_context to the main loop.  If the
> > NBD connection is lost before this point, and the NBD client has entered
> > the reconnect procedure, QEMU crashes:
> > 
> >  at /build/qemu-gYtjVn/qemu-5.0.1/io/channel.c:452
> >  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6151
> >  new_context=new_context@entry=0x562a260c9580,
> >  ignore=ignore@entry=0x7feeadc9b780)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6230
> >  (bs=bs@entry=0x562a268d6a00, ctx=0x562a260c9580,
> >  ignore_child=, errp=)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6332
> >  new_context=0x562a260c9580,
> >  update_root_node=update_root_node@entry=true, errp=errp@entry=0x0)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:1989
> >  new_context=, errp=errp@entry=0x0)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:2010
> >  out>)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
> >  at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio-bus.c:245
> >  running=0, state=)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio.c:3220
> >  state=state@entry=RUN_STATE_FINISH_MIGRATE)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/softmmu/vl.c:1275
> >  send_stop=)
> >  at /build/qemu-gYtjVn/qemu-5.0.1/cpus.c:1032
> >  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:2914
> >  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3275
> >  at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3439
> >  at /build/qemu-gYtjVn/qemu-5.0.1/util/qemu-thread-posix.c:519
> >  at pthread_create.c:333
> >  oldval=0x562a2452b138, oldlenp=0x0, newval=0x562a2452c5e0
> >  <__func__.28102>, newlen=0)
> >  at ../sysdeps/unix/sysv/linux/sysctl.c:30
> 
> function names are somehow lost :(

Oops.  Backtraces in gdb have frame numbers prefixed with a hash which
got interpreted as comments by git commit; I should have offset the
backtrace when pasting.

Will respin with fixed log messages, thanks.

Roman.



[Bug 1913505] Re: Windows XP slow on Apple M1

2021-01-28 Thread Thomas Huth
Did you compile QEMU on your own? If so, which parameters did you use
for the "configure" script?

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

Title:
  Windows XP slow on Apple M1

Status in QEMU:
  New

Bug description:
  Qemu installed by using brew install qemu -s on M1

  QEMU emulator version 5.2.0
  XP image from: https://archive.org/details/WinXPProSP3x86

  Commands run:
  $ qemu-img create -f qcow2 xpsp3.img 10G
  $ qemu-system-i386 -m 512 -hda xpsp3.img -cdrom 
WinXPProSP3x86/en_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-73974.iso
 -boot d

  It's taken 3 days now with qemu running at around 94% CPU and
  installation hasn't finished. The mouse pointer moves and occasionally
  changes between the pointer and hourglass so it doesn't seem to have
  frozen.

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



[PATCH] hw/block/nvme: refactor zone state check for read

2021-01-28 Thread Klaus Jensen
From: Gollu Appalanaidu 

Align with nvme_check_zone_write.

Remove unnecessary storing status value and return at the end of the
function, if error occurs return immediately if applicable.

Signed-off-by: Gollu Appalanaidu 
Reviewed-by: Klaus Jensen 
---
 hw/block/nvme.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 8ac997735041..1dbd6ec129ae 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1210,7 +1210,7 @@ static uint16_t nvme_check_zone_write(NvmeCtrl *n, 
NvmeNamespace *ns,
 
 static uint16_t nvme_check_zone_state_for_read(NvmeZone *zone)
 {
-uint16_t status;
+uint64_t zslba = zone->d.zslba;
 
 switch (nvme_get_zone_state(zone)) {
 case NVME_ZONE_STATE_EMPTY:
@@ -1219,16 +1219,13 @@ static uint16_t nvme_check_zone_state_for_read(NvmeZone 
*zone)
 case NVME_ZONE_STATE_FULL:
 case NVME_ZONE_STATE_CLOSED:
 case NVME_ZONE_STATE_READ_ONLY:
-status = NVME_SUCCESS;
-break;
+return NVME_SUCCESS;
 case NVME_ZONE_STATE_OFFLINE:
-status = NVME_ZONE_OFFLINE;
-break;
+trace_pci_nvme_err_zone_is_offline(zslba);
+return NVME_ZONE_OFFLINE;
 default:
 assert(false);
 }
-
-return status;
 }
 
 static uint16_t nvme_check_zone_read(NvmeNamespace *ns, uint64_t slba,
@@ -1241,10 +1238,10 @@ static uint16_t nvme_check_zone_read(NvmeNamespace *ns, 
uint64_t slba,
 
 status = nvme_check_zone_state_for_read(zone);
 if (status) {
-;
+return status;
 } else if (unlikely(end > bndry)) {
 if (!ns->params.cross_zone_read) {
-status = NVME_ZONE_BOUNDARY_ERROR;
+return NVME_ZONE_BOUNDARY_ERROR;
 } else {
 /*
  * Read across zone boundary - check that all subsequent
@@ -1254,7 +1251,7 @@ static uint16_t nvme_check_zone_read(NvmeNamespace *ns, 
uint64_t slba,
 zone++;
 status = nvme_check_zone_state_for_read(zone);
 if (status) {
-break;
+return status;
 }
 } while (end > nvme_zone_rd_boundary(ns, zone));
 }
-- 
2.30.0




Re: [PATCH] target/rx: Fix compiler errors for build with sanitizers

2021-01-28 Thread Thomas Huth

On 28/01/2021 18.21, Stefan Weil wrote:

gcc (Debian 10.2.1-6) 10.2.1 20210110 aborts builds with enabled sanitizers:

../../../target/rx/op_helper.c: In function ‘helper_scmpu’:
../../../target/rx/op_helper.c:213:24: error: ‘tmp1’ may be used uninitialized 
in this function [-Werror=maybe-uninitialized]
   213 | env->psw_c = (tmp0 >= tmp1);
   |  ~~^~~~
../../../target/rx/op_helper.c:213:24: error: ‘tmp0’ may be used uninitialized 
in this function [-Werror=maybe-uninitialized]
../../../target/rx/op_helper.c: In function ‘helper_suntil’:
../../../target/rx/op_helper.c:299:23: error: ‘tmp’ may be used uninitialized 
in this function [-Werror=maybe-uninitialized]
   299 | env->psw_c = (tmp <= env->regs[2]);
   |  ~^~~~
../../../target/rx/op_helper.c: In function ‘helper_swhile’:
../../../target/rx/op_helper.c:318:23: error: ‘tmp’ may be used uninitialized 
in this function [-Werror=maybe-uninitialized]
   318 | env->psw_c = (tmp <= env->regs[2]);
   |  ~^~~~

Rewriting the code fixes those errors.

Signed-off-by: Stefan Weil 
---

Those error are false positives, but simple code changes help the
compiler (and perhaps reviewers) to understand it better.

Stefan


Reviewed-by: Thomas Huth 




Re: [PATCH 0/3] block/nbd: fix crashers in reconnect while migrating

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 23:14, Roman Kagan wrote:

During the final phase of migration the NBD reconnection logic may
encounter situations it doesn't expect during regular operation.

This series addresses some of them that make qemu crash.  They are
reproducible when a vm with a secondary drive attached via nbd with
non-zero "reconnect-delay" runs a stress load (fio with big queue depth)
in the guest on that drive and is migrated (e.g. to a file), while the
nbd server is SIGKILL-ed and restarted every second.

See the individual patches for specific crash conditions and more
detailed explanations.

Roman Kagan (3):
   block/nbd: only detach existing iochannel from aio_context
   block/nbd: only enter connection coroutine if it's present
   nbd: make nbd_read* return -EIO on error

  include/block/nbd.h |  7 ---
  block/nbd.c | 25 +
  2 files changed, 21 insertions(+), 11 deletions(-)



Thanks a lot for fixing!

Do you have some reproducer scripts? Could you post them or may be add an 
iotest?

--
Best regards,
Vladimir



Re: [PATCH 3/3] nbd: make nbd_read* return -EIO on error

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 23:14, Roman Kagan wrote:

NBD reconnect logic considers the error code from the functions that
read NBD messages to tell if reconnect should be attempted or not: it is
attempted on -EIO, otherwise the client transitions to NBD_CLIENT_QUIT
state (see nbd_channel_error).  This error code is propagated from the
primitives like nbd_read.

The problem, however, is that nbd_read itself turns every error into -1
rather than -EIO.  As a result, if the NBD server happens to die while
sending the message, the client in QEMU receives less data than it
expects, considers it as a fatal error, and wouldn't attempt
reestablishing the connection.

Fix it by turning every negative return from qio_channel_read_all into
-EIO returned from nbd_read.  Apparently that was the original behavior,
but got broken later.  Also adjust nbd_readXX to follow.

Fixes: e6798f06a6 ("nbd: generalize usage of nbd_read")
Signed-off-by: Roman Kagan 


Reviewed-by: Vladimir Sementsov-Ogievskiy 

Really looks like a bug in e6798f06a6: it changes error code from -EIO to -1 
without any reasoning.


---
  include/block/nbd.h | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4a52a43ef5..5f34d23bb0 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -364,7 +364,7 @@ static inline int nbd_read(QIOChannel *ioc, void *buffer, 
size_t size,
  if (desc) {
  error_prepend(errp, "Failed to read %s: ", desc);
  }
-return -1;
+return ret;
  }
  
  return 0;

@@ -375,8 +375,9 @@ static inline int nbd_read##bits(QIOChannel *ioc,   
\
   uint##bits##_t *val,   \
   const char *desc, Error **errp)\
  {   \
-if (nbd_read(ioc, val, sizeof(*val), desc, errp) < 0) { \
-return -1;  \
+int ret = nbd_read(ioc, val, sizeof(*val), desc, errp); \
+if (ret < 0) {  \
+return ret; \
  }   \
  *val = be##bits##_to_cpu(*val); \
  return 0;   \




--
Best regards,
Vladimir



Re: [PATCH] tests/acceptance: Re-enable the microblaze test

2021-01-28 Thread Thomas Huth

On 28/01/2021 20.34, Wainer dos Santos Moschetta wrote:

Hi,

On 1/28/21 12:28 PM, Thomas Huth wrote:

The microblaze kernel sometimes gets stuck during boot (ca. 1 out of 200
times), so we disabled the corresponding acceptance tests some months
ago. However, it's likely better to check that the kernel is still
starting than to not testing it at all anymore. Move the test to
a separate file, enable it again and check for an earlier console
message that should always appear.

Signed-off-by: Thomas Huth 
---
  MAINTAINERS    |  1 +
  tests/acceptance/boot_linux_console.py |  9 ---
  tests/acceptance/machine_microblaze.py | 35 ++
  3 files changed, 36 insertions(+), 9 deletions(-)
  create mode 100644 tests/acceptance/machine_microblaze.py

diff --git a/MAINTAINERS b/MAINTAINERS
index 34359a99b8..157ad4f7ef 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1112,6 +1112,7 @@ M: Edgar E. Iglesias 
  S: Maintained
  F: hw/microblaze/petalogix_s3adsp1800_mmu.c
  F: include/hw/char/xilinx_uartlite.h
+F: tests/acceptance/machine_microblaze.py
  petalogix_ml605
  M: Edgar E. Iglesias 
diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py

index fb41bb7144..969fbf3952 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -1047,15 +1047,6 @@ class BootLinuxConsole(LinuxKernelTest):
  tar_hash = 'ac688fd00561a2b6ce1359f9ff6aa2b98c9a570c'
  self.do_test_advcal_2018('07', tar_hash, 'sanity-clause.elf')
-    @skip("Test currently broken") # Console stuck as of 5.2-rc1
-    def test_microblaze_s3adsp1800(self):
-    """
-    :avocado: tags=arch:microblaze
-    :avocado: tags=machine:petalogix-s3adsp1800
-    """
-    tar_hash = '08bf3e3bfb6b6c7ce1e54ab65d54e189f2caf13f'
-    self.do_test_advcal_2018('17', tar_hash, 'ballerina.bin')
-
  def test_or1k_sim(self):
  """
  :avocado: tags=arch:or1k
diff --git a/tests/acceptance/machine_microblaze.py 
b/tests/acceptance/machine_microblaze.py

new file mode 100644
index 00..7f6d18495d
--- /dev/null
+++ b/tests/acceptance/machine_microblaze.py
@@ -0,0 +1,35 @@
+# Functional test that boots a microblaze Linux kernel and checks the 
console

+#
+# Copyright (c) 2018, 2021 Red Hat, Inc.
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from avocado_qemu import Test
+from avocado_qemu import wait_for_console_pattern
+from avocado.utils import archive
+
+class MicroblazeMachine(Test):
+
+    timeout = 90
+
+    def test_microblaze_s3adsp1800(self):
+    """
+    :avocado: tags=arch:microblaze
+    :avocado: tags=machine:petalogix-s3adsp1800
+    """
+
+    tar_url = ('https://www.qemu-advent-calendar.org'
+   '/2018/download/day17.tar.xz')
+    tar_hash = '08bf3e3bfb6b6c7ce1e54ab65d54e189f2caf13f'
+    file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
+    archive.extract(file_path, self.workdir)
+    self.vm.set_console()
+    self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin')
+    self.vm.launch()
+    wait_for_console_pattern(self, 'This architecture does not have '
+   'kernel memory protection')
+    # Note:
+    # The kernel sometimes gets stuck after the "This architecture ..."
+    # message, that's why we don't test for a later string here. This
+    # needs some investigation by a microblaze wizard one day...



The change looks good to me.

Also I appreciate the note you left on code. In addition I suggest to put 
some tag to indicate it needs some investigation or that it is flaky 
(although that's not the case anymore), because it will ease the discovery 
and filtering of "problematic" tests. What do you think?


Sounds reasonable, but I'm not aware of any such tags in the "acceptance" 
code yet... what exactly do you have in mind?


 Thomas




Re: [PATCH 2/3] block/nbd: only enter connection coroutine if it's present

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 23:14, Roman Kagan wrote:

When an NBD block driver state is moved from one aio_context to another
(e.g. when doing a drain in a migration thread),
nbd_client_attach_aio_context_bh is executed that enters the connection
coroutine.

However, the assumption that ->connection_co is always present here
appears incorrect: the connection may have encountered an error other
than -EIO in the underlying transport, and thus may have decided to quit
rather than keep trying to reconnect, and therefore it may have
terminated the connection coroutine.  As a result an attempt to reassign
the client in this state (NBD_CLIENT_QUIT) to a different aio_context
leads to a null pointer dereference:

 at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-coroutine.c:109
 opaque=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block/nbd.c:164
 at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:55
 at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:136
 at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:164
 blocking=blocking@entry=true)
 at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-posix.c:650
 cb=, opaque=)
 at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:71
 bs=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6172
 new_context=new_context@entry=0x5618056c7580,
 ignore=ignore@entry=0x7f60e1e63780)
 at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6237
 bs=bs@entry=0x561805ed4c00, ctx=0x5618056c7580,
 ignore_child=, errp=)
 at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6332
 new_context=0x5618056c7580, update_root_node=update_root_node@entry=true,
 errp=errp@entry=0x0)
 at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:1989
 new_context=, errp=errp@entry=0x0)
 at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:2010
 at /build/qemu-6MF7tq/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
 at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio-bus.c:245
 running=0, state=)
 at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio.c:3220
 state=state@entry=RUN_STATE_FINISH_MIGRATE)
 at /build/qemu-6MF7tq/qemu-5.0.1/softmmu/vl.c:1275
 send_stop=) at /build/qemu-6MF7tq/qemu-5.0.1/cpus.c:1032
 at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:2914
 at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3275
 at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3439
 at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-thread-posix.c:519
from /lib/x86_64-linux-gnu/libpthread.so.0

Fix it by checking that the connection coroutine is non-null before
trying to enter it.  If it is null, no entering is needed, as the
connection is probably going down anyway.

Signed-off-by: Roman Kagan 


Reviewed-by: Vladimir Sementsov-Ogievskiy 


---
  block/nbd.c | 16 +---
  1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index bcd6641e90..b3cbbeb4b0 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -250,13 +250,15 @@ static void nbd_client_attach_aio_context_bh(void *opaque)
  BlockDriverState *bs = opaque;
  BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
  
-/*

- * The node is still drained, so we know the coroutine has yielded in
- * nbd_read_eof(), the only place where bs->in_flight can reach 0, or it is
- * entered for the first time. Both places are safe for entering the
- * coroutine.
- */
-qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+if (s->connection_co) {
+/*
+ * The node is still drained, so we know the coroutine has yielded in
+ * nbd_read_eof(), the only place where bs->in_flight can reach 0, or
+ * it is entered for the first time. Both places are safe for entering
+ * the coroutine.
+ */
+qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+}
  bdrv_dec_in_flight(bs);
  }
  




--
Best regards,
Vladimir



Re: [PATCH 1/3] block/nbd: only detach existing iochannel from aio_context

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 23:14, Roman Kagan wrote:

When the reconnect in NBD client is in progress, the iochannel used for
NBD connection doesn't exist.  Therefore an attempt to detach it from
the aio_context of the parent BlockDriverState results in a NULL pointer
dereference.

The problem is triggerable, in particular, when an outgoing migration is
about to finish, and stopping the dataplane tries to move the
BlockDriverState from the iothread aio_context to the main loop.  If the
NBD connection is lost before this point, and the NBD client has entered
the reconnect procedure, QEMU crashes:

 at /build/qemu-gYtjVn/qemu-5.0.1/io/channel.c:452
 at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6151
 new_context=new_context@entry=0x562a260c9580,
 ignore=ignore@entry=0x7feeadc9b780)
 at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6230
 (bs=bs@entry=0x562a268d6a00, ctx=0x562a260c9580,
 ignore_child=, errp=)
 at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6332
 new_context=0x562a260c9580,
 update_root_node=update_root_node@entry=true, errp=errp@entry=0x0)
 at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:1989
 new_context=, errp=errp@entry=0x0)
 at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:2010
 out>)
 at /build/qemu-gYtjVn/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
 at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio-bus.c:245
 running=0, state=)
 at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio.c:3220
 state=state@entry=RUN_STATE_FINISH_MIGRATE)
 at /build/qemu-gYtjVn/qemu-5.0.1/softmmu/vl.c:1275
 send_stop=)
 at /build/qemu-gYtjVn/qemu-5.0.1/cpus.c:1032
 at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:2914
 at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3275
 at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3439
 at /build/qemu-gYtjVn/qemu-5.0.1/util/qemu-thread-posix.c:519
 at pthread_create.c:333
 oldval=0x562a2452b138, oldlenp=0x0, newval=0x562a2452c5e0
 <__func__.28102>, newlen=0)
 at ../sysdeps/unix/sysv/linux/sysctl.c:30


function names are somehow lost :(



Fix it by checking that the iochannel is non-null before trying to
detach it from the aio_context.  If it is null, no detaching is needed,
and it will get reattached in the proper aio_context once the connection
is reestablished.

Signed-off-by: Roman Kagan 


Thanks!

Reviewed-by: Vladimir Sementsov-Ogievskiy 


---
  block/nbd.c | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/block/nbd.c b/block/nbd.c
index 42e10c7c93..bcd6641e90 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -235,7 +235,14 @@ static void nbd_client_detach_aio_context(BlockDriverState 
*bs)
  
  /* Timer is deleted in nbd_client_co_drain_begin() */

  assert(!s->reconnect_delay_timer);
-qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+/*
+ * If reconnect is in progress we may have no ->ioc.  It will be
+ * re-instantiated in the proper aio context once the connection is
+ * reestablished.
+ */
+if (s->ioc) {
+qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+}
  }
  
  static void nbd_client_attach_aio_context_bh(void *opaque)





--
Best regards,
Vladimir



Re: [PULL 14/53] block: apply COR-filter to block-stream jobs

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 21:38, Philippe Mathieu-Daudé wrote:

Hi Andrey,

On 1/26/21 3:19 PM, Max Reitz wrote:

From: Andrey Shinkevich 

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

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

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

Several iotests are slightly modified due to filter insertion.

Signed-off-by: Andrey Shinkevich 
Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20201216061703.70908-14-vsement...@virtuozzo.com>
Reviewed-by: Max Reitz 
Signed-off-by: Max Reitz 
---
  block/stream.c | 105 ++---
  tests/qemu-iotests/030 |   8 +--
  tests/qemu-iotests/141.out |   2 +-
  tests/qemu-iotests/245 |  20 ---
  4 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/block/stream.c b/block/stream.c

...

@@ -228,7 +211,9 @@ void stream_start(const char *job_id, BlockDriverState *bs,
  bool bs_read_only;
  int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
  BlockDriverState *base_overlay;
+BlockDriverState *cor_filter_bs = NULL;
  BlockDriverState *above_base;
+QDict *opts;
  
  assert(!(base && bottom));

  assert(!(backing_file_str && bottom));
@@ -266,30 +251,62 @@ void stream_start(const char *job_id, BlockDriverState 
*bs,
  }
  }
  
-if (bdrv_freeze_backing_chain(bs, above_base, errp) < 0) {

-return;
-}
-
  /* Make sure that the image is opened in read-write mode */
  bs_read_only = bdrv_is_read_only(bs);
  if (bs_read_only) {
-if (bdrv_reopen_set_read_only(bs, false, errp) != 0) {
-bs_read_only = false;
-goto fail;
+int ret;
+/* Hold the chain during reopen */
+if (bdrv_freeze_backing_chain(bs, above_base, errp) < 0) {
+return;
+}
+
+ret = bdrv_reopen_set_read_only(bs, false, errp);
+
+/* failure, or cor-filter will hold the chain */
+bdrv_unfreeze_backing_chain(bs, above_base);
+
+if (ret < 0) {
+return;
  }
  }
  
-/* Prevent concurrent jobs trying to modify the graph structure here, we

- * already have our own plans. Also don't allow resize as the image size is
- * queried only at the job start and then cached. */
-s = block_job_create(job_id, &stream_job_driver, NULL, bs,
- basic_flags | BLK_PERM_GRAPH_MOD,
+opts = qdict_new();


Coverity reported (CID 1445793) that this resource could be leaked...


+
+qdict_put_str(opts, "driver", "copy-on-read");
+qdict_put_str(opts, "file", bdrv_get_node_name(bs));
+/* Pass the base_overlay node name as 'bottom' to COR driver */
+qdict_put_str(opts, "bottom", base_overlay->node_name);
+if (filter_node_name) {
+qdict_put_str(opts, "node-name", filter_node_name);
+}
+
+cor_filter_bs = bdrv_insert_node(bs, opts, BDRV_O_RDWR, errp);
+if (!cor_filter_bs) {


... probably here.

Should we call g_free(opts) here?



Actually, not..

bdrv_insert_node() calls bdrv_open() which eats options even on failure.

I see, CID already marked false-positive?




+goto fail;
+}
+
+if (!filter_node_name) {
+cor_filter_bs->implicit = true;
+}
+
+s = block_job_create(job_id, &stream_job_driver, NULL, cor_filter_bs,
+ BLK_PERM_CONSISTENT_READ,
   basic_flags | BLK_PERM_WRITE,
   speed, creation_flags, NULL, NULL, errp);
  if (!s) {
  goto fail;
  }
  
+/*

+ * Prevent concurrent jobs trying to modify the graph structure here, we
+ * already have our own plans. Also don't allow resize as the image size is
+ * queried only at the job start and then cached.
+ */
+if (block_job_add_bdrv(&s->common, "active node", bs, 0,
+   basic_flags | BLK_PERM_WRITE, &error_abort)) {
+goto fail;
+}
+
  /* Block all intermediate nodes between bs and base, because they will
   * disappear from the chain after this operation. The streaming job reads
   * every block only once, assuming that it doesn't change, so forbid 
writes
@@ -310,9 +327,9 @@ void stream_start(const char *job_id, BlockDriverState *bs,
  s->base_overlay = base_overlay;
  s->above_base = above_base;
  s->backing_file_str = g_strdup(backing_file_str);
+s->cor_filter_bs = cor_filter_bs;
  s->target_bs = bs;
  s->bs_read_only = bs_read_only;
-s->chain_frozen = true;
  
  s->on_error = on_error;

  trace_stream_start(bs, base, s);
@@ -320,8 +337,10 @@ void stream_start(const char *job_id, Block

[PATCH] tests/Makefile.include: export PYTHON for check-block.sh

2021-01-28 Thread Vladimir Sementsov-Ogievskiy
check-block.sh called by make check-block rely on PYTHON variable being
set.

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

Hi! As Peter reported, build fails on platforms where python3 is not
/usr/bin/python3.. This patch should help. At least it works for me if
I move /usr/bin/python3 to another location and configure it with
--python=. And doesn't work without the patch.
Don't know how the thing seemed to work for me before :\

 tests/Makefile.include | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3a0524ce74..ceaf3f0d6e 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -138,6 +138,7 @@ check:
 ifeq ($(CONFIG_TOOLS)$(CONFIG_POSIX),yy)
 QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = 
tests/qemu-iotests/socket_scm_helper$(EXESUF)
 check: check-block
+export PYTHON
 check-block: $(SRC_PATH)/tests/check-block.sh qemu-img$(EXESUF) \
qemu-io$(EXESUF) qemu-nbd$(EXESUF) $(QEMU_IOTESTS_HELPERS-y) \
$(filter qemu-system-%, $(ninja-targets))
-- 
2.29.2




Re: [PATCH v7 09/13] confidential guest support: Update documentation

2021-01-28 Thread David Gibson
On Fri, Jan 15, 2021 at 04:36:46PM +0100, Cornelia Huck wrote:
> On Thu, 14 Jan 2021 10:58:07 +1100
> David Gibson  wrote:
> 
> > Now that we've implemented a generic machine option for configuring various
> > confidential guest support mechanisms:
> >   1. Update docs/amd-memory-encryption.txt to reference this rather than
> >  the earlier SEV specific option
> >   2. Add a docs/confidential-guest-support.txt to cover the generalities of
> >  the confidential guest support scheme
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  docs/amd-memory-encryption.txt  |  2 +-
> >  docs/confidential-guest-support.txt | 43 +
> >  2 files changed, 44 insertions(+), 1 deletion(-)
> >  create mode 100644 docs/confidential-guest-support.txt
> > 
> > diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
> > index 80b8eb00e9..145896aec7 100644
> > --- a/docs/amd-memory-encryption.txt
> > +++ b/docs/amd-memory-encryption.txt
> > @@ -73,7 +73,7 @@ complete flow chart.
> >  To launch a SEV guest
> >  
> >  # ${QEMU} \
> > --machine ...,memory-encryption=sev0 \
> > +-machine ...,confidential-guest-support=sev0 \
> >  -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
> >  
> >  Debugging
> > diff --git a/docs/confidential-guest-support.txt 
> > b/docs/confidential-guest-support.txt
> > new file mode 100644
> > index 00..2790425b38
> > --- /dev/null
> > +++ b/docs/confidential-guest-support.txt
> 
> Maybe make this a proper .rst from the start and hook this up into the
> system guide? It is already almost there.

Hrm.  I considered it, but didn't really want to spend the time
integrating it into the overall structure of the system guide.  I kind
of want to get this dang thing wrapped up.

> 
> > @@ -0,0 +1,43 @@
> > +Confidential Guest Support
> > +==
> > +
> > +Traditionally, hypervisors such as qemu have complete access to a
> 
> s/qemu/QEMU/ ?

Fixed.

> 
> > +guest's memory and other state, meaning that a compromised hypervisor
> > +can compromise any of its guests.  A number of platforms have added
> > +mechanisms in hardware and/or firmware which give guests at least some
> > +protection from a compromised hypervisor.  This is obviously
> > +especially desirable for public cloud environments.
> > +
> > +These mechanisms have different names and different modes of
> > +operation, but are often referred to as Secure Guests or Confidential
> > +Guests.  We use the term "Confidential Guest Support" to distinguish
> > +this from other aspects of guest security (such as security against
> > +attacks from other guests, or from network sources).
> > +
> > +Running a Confidential Guest
> > +
> > +
> > +To run a confidential guest you need to add two command line parameters:
> > +
> > +1. Use "-object" to create a "confidential guest support" object.  The
> > +   type and parameters will vary with the specific mechanism to be
> > +   used
> > +2. Set the "confidential-guest-support" machine parameter to the ID of
> > +   the object from (1).
> > +
> > +Example (for AMD SEV)::
> > +
> > +qemu-system-x86_64 \
> > + \
> > +-machine ...,confidential-guest-support=sev0 \
> > +-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
> > +
> > +Supported mechanisms
> > +
> > +
> > +Currently supported confidential guest mechanisms are:
> > +
> > +AMD Secure Encrypted Virtualization (SEV)
> > +docs/amd-memory-encryption.txt
> > +
> > +Other mechanisms may be supported in future.
> 
> LGTM.
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v7 02/13] confidential guest support: Introduce new confidential guest support class

2021-01-28 Thread David Gibson
On Thu, Jan 21, 2021 at 09:08:07AM +, Dr. David Alan Gilbert wrote:
> * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > On Mon, Jan 18, 2021 at 06:51:24PM +, Dr. David Alan Gilbert wrote:
> > > * David Gibson (da...@gibson.dropbear.id.au) wrote:
> > > > Several architectures have mechanisms which are designed to protect 
> > > > guest
> > > > memory from interference or eavesdropping by a compromised hypervisor.  
> > > > AMD
> > > > SEV does this with in-chip memory encryption and Intel's MKTME can do
> > >^
> > > (and below) My understanding is that it's Intel TDX that's the VM
> > > equivalent.
> > 
> > I thought MKTME could already do memory encryption and TDX extended
> > that to... more?  I'll adjust the comment to say TDX anyway, since
> > that seems to be the newer name.
> 
> My understanding was MKTME does the memory encryption, but doesn't
> explicitly wire that into VMs or attestation of VMs or anything like
> that.  TDX wires that encryption to VMs and provides all the other glue
> that goes with attestation and the like.

Ok.

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


signature.asc
Description: PGP signature


Re: [PATCH v7 10/13] spapr: Add PEF based confidential guest support

2021-01-28 Thread David Gibson
On Fri, Jan 15, 2021 at 04:41:51PM +0100, Cornelia Huck wrote:
> On Thu, 14 Jan 2021 10:58:08 +1100
> David Gibson  wrote:
> 
> > Some upcoming POWER machines have a system called PEF (Protected
> > Execution Facility) which uses a small ultravisor to allow guests to
> > run in a way that they can't be eavesdropped by the hypervisor.  The
> > effect is roughly similar to AMD SEV, although the mechanisms are
> > quite different.
> > 
> > Most of the work of this is done between the guest, KVM and the
> > ultravisor, with little need for involvement by qemu.  However qemu
> > does need to tell KVM to allow secure VMs.
> > 
> > Because the availability of secure mode is a guest visible difference
> > which depends on having the right hardware and firmware, we don't
> > enable this by default.  In order to run a secure guest you need to
> > create a "pef-guest" object and set the confidential-guest-support
> > property to point to it.
> > 
> > Note that this just *allows* secure guests, the architecture of PEF is
> > such that the guest still needs to talk to the ultravisor to enter
> > secure mode.  Qemu has no directl way of knowing if the guest is in
> > secure mode, and certainly can't know until well after machine
> > creation time.
> > 
> > To start a PEF-capable guest, use the command line options:
> > -object pef-guest,id=pef0 -machine confidential-guest-support=pef0
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  docs/confidential-guest-support.txt |   3 +
> >  docs/papr-pef.txt   |  30 +++
> >  hw/ppc/meson.build  |   1 +
> >  hw/ppc/pef.c| 119 
> >  hw/ppc/spapr.c  |   6 ++
> >  include/hw/ppc/pef.h|  25 ++
> >  target/ppc/kvm.c|  18 -
> >  target/ppc/kvm_ppc.h|   6 --
> >  8 files changed, 184 insertions(+), 24 deletions(-)
> >  create mode 100644 docs/papr-pef.txt
> >  create mode 100644 hw/ppc/pef.c
> >  create mode 100644 include/hw/ppc/pef.h
> > 
> > diff --git a/docs/confidential-guest-support.txt 
> > b/docs/confidential-guest-support.txt
> > index 2790425b38..f0801814ff 100644
> > --- a/docs/confidential-guest-support.txt
> > +++ b/docs/confidential-guest-support.txt
> > @@ -40,4 +40,7 @@ Currently supported confidential guest mechanisms are:
> >  AMD Secure Encrypted Virtualization (SEV)
> >  docs/amd-memory-encryption.txt
> >  
> > +POWER Protected Execution Facility (PEF)
> > +docs/papr-pef.txt
> > +
> >  Other mechanisms may be supported in future.
> > diff --git a/docs/papr-pef.txt b/docs/papr-pef.txt
> > new file mode 100644
> > index 00..6419e995cf
> > --- /dev/null
> > +++ b/docs/papr-pef.txt
> 
> Same here, make this .rst and add it to the system guide?

Again, I feel like I'm sufficiently bogged down in bikeshedding the
technical details to feel inclined to block it on a nice-to-have like
this.

> > @@ -0,0 +1,30 @@
> > +POWER (PAPR) Protected Execution Facility (PEF)
> > +===
> > +
> > +Protected Execution Facility (PEF), also known as Secure Guest support
> > +is a feature found on IBM POWER9 and POWER10 processors.
> > +
> > +If a suitable firmware including an Ultravisor is installed, it adds
> > +an extra memory protection mode to the CPU.  The ultravisor manages a
> > +pool of secure memory which cannot be accessed by the hypervisor.
> > +
> > +When this feature is enabled in qemu, a guest can use ultracalls to
> 
> s/qemu/QEMU/

Fixed.

> > +enter "secure mode".  This transfers most of its memory to secure
> > +memory, where it cannot be eavesdropped by a compromised hypervisor.
> > +
> > +Launching
> > +-
> > +
> > +To launch a guest which will be permitted to enter PEF secure mode:
> > +
> > +# ${QEMU} \
> > +-object pef-guest,id=pef0 \
> > +-machine confidential-guest-support=pef0 \
> > +...
> > +
> > +Live Migration
> > +
> > +
> > +Live migration is not yet implemented for PEF guests.  For
> > +consistency, we currently prevent migration if the PEF feature is
> > +enabled, whether or not the guest has actually entered secure mode.
> > diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
> > index ffa2ec37fa..218631c883 100644
> > --- a/hw/ppc/meson.build
> > +++ b/hw/ppc/meson.build
> > @@ -27,6 +27,7 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
> >'spapr_nvdimm.c',
> >'spapr_rtas_ddw.c',
> >'spapr_numa.c',
> > +  'pef.c',
> >  ))
> >  ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c'))
> >  ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_LINUX'], if_true: files(
> > diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c
> > new file mode 100644
> > index 00..02b9b3b460
> > --- /dev/null
> > +++ b/hw/ppc/pef.c
> > @@ -0,0 +1,119 @@
> > +/*
> > + * PEF (Protected Execution Facility) for POWER support
> > + *
> > + * Copyright David Gibson, Redhat Inc. 2020
> 
> 2021?

So, it hap

Re: [PATCH v7 08/13] confidential guest support: Move SEV initialization into arch specific code

2021-01-28 Thread David Gibson
On Mon, Jan 18, 2021 at 09:03:36AM +0100, Cornelia Huck wrote:
> On Mon, 18 Jan 2021 14:03:08 +1100
> David Gibson  wrote:
> 
> > On Fri, Jan 15, 2021 at 02:24:25PM +0100, Cornelia Huck wrote:
> > > On Thu, 14 Jan 2021 10:58:06 +1100
> > > David Gibson  wrote:
> > >   
> > > > While we've abstracted some (potential) differences between mechanisms 
> > > > for
> > > > securing guest memory, the initialization is still specific to SEV.  
> > > > Given
> > > > that, move it into x86's kvm_arch_init() code, rather than the generic
> > > > kvm_init() code.
> > > > 
> > > > Signed-off-by: David Gibson 
> > > > ---
> > > >  accel/kvm/kvm-all.c   | 14 --
> > > >  accel/kvm/sev-stub.c  |  4 ++--
> > > >  target/i386/kvm/kvm.c | 12 
> > > >  target/i386/sev.c |  7 ++-
> > > >  4 files changed, 20 insertions(+), 17 deletions(-)
> > > >   
> > > 
> > > (...)
> > >   
> > > > @@ -2135,6 +2136,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
> > > >  uint64_t shadow_mem;
> > > >  int ret;
> > > >  struct utsname utsname;
> > > > +Error *local_err = NULL;
> > > > +
> > > > +/*
> > > > + * if memory encryption object is specified then initialize the
> > > > + * memory encryption context (no-op otherwise)
> > > > + */
> > > > +ret = sev_kvm_init(ms->cgs, &local_err);  
> > > 
> > > Maybe still leave a comment here, as the code will still need to be
> > > modified to handle non-SEV x86 mechanisms?  
> > 
> > Uh.. I'm confused.. this hunk is adding a comment, not removing one..
> 
> Yes, but there was a "TODO: handle non-SEV" comment before. This will
> probably need some massaging if we add Intel mechanisms?

Technically, not exactly.  New mechanisms would have their own
initialization, which might go adjacent to this, or could be somewhere
else - the sev_kvm_init() is a no-op if a non-SEV mechanism is
selected (currently impossible).

The distinction is pretty subtle, though, so I've altered the comment
here in a way I hope explains it.

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


signature.asc
Description: PGP signature


Re: [PATCH] vhost-user: Check for iotlb callback in iotlb_miss

2021-01-28 Thread Jason Wang



On 2021/1/28 下午5:37, Eugenio Perez Martin wrote:

Hi Jason.

On Thu, Jan 28, 2021 at 3:32 AM Jason Wang  wrote:


On 2021/1/28 上午4:44, Eugenio Pérez wrote:

Not registering this can lead to vhost_backend_handle_iotlb_msg and
vhost_device_iotlb_miss if backend issue a miss after qemu vhost device
stop.

This causes a try to access dev->vdev->dma_as with vdev == NULL.


Hi Eugenio:

What condition can we get this? Did you mean we receive IOTLB_MISS
before vhost_dev_start()?


In the VM reboot case, yes, between vhost_dev_stop() and
vhost_dev_start(). But I can reproduce the bug in VM shutdown too,
with no vhost_dev_start expected.

I didn't try to send IOTLB_MISS before starting vhost_dev, but this
patch should solve that problem too.

I think we can get this with whatever malicious/buggy vhost-user
backend sending unexpected iotlb misses, but I didn't test so deeply.



I see.





If yes, it looks to me a bug somewhere else.

Where should I look for it?



So I winder whether or not we can simply ignore IOTLB message if vhost 
device is not started.


Thanks




Thanks!


Thanks



Reproduced rebooting a guest with testpmd in txonly forward mode.
   #0  0x55994394 in vhost_device_iotlb_miss (
   dev=dev@entry=0x55a0012f6680, iova=10245279744, write=1)
   at ../hw/virtio/vhost.c:1013
   #1  0x5599ac31 in vhost_backend_handle_iotlb_msg (
   imsg=0x7ffddcfd32c0, dev=0x55a0012f6680)
   at ../hw/virtio/vhost-backend.c:411
   #2  vhost_backend_handle_iotlb_msg (dev=dev@entry=0x55a0012f6680,
   imsg=imsg@entry=0x7ffddcfd32c0)
   at ../hw/virtio/vhost-backend.c:404
   #3  0x559fffeded7b in slave_read (opaque=0x55a0012f6680)
   at ../hw/virtio/vhost-user.c:1464
   #4  0x55ac541b in aio_dispatch_handler (
   ctx=ctx@entry=0x55a0010a2120, node=0x55a0012d9e00)
   at ../util/aio-posix.c:329

Fixes: 6dcdd06e3b ("spec/vhost-user spec: Add IOMMU support")
Signed-off-by: Eugenio Pérez 
---
   hw/virtio/vhost-user.c | 10 --
   1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 2fdd5daf74..a49b2229fb 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -238,6 +238,7 @@ struct vhost_user {
   /* Shared between vhost devs of the same virtio device */
   VhostUserState *user;
   int slave_fd;
+bool iotlb_enabled;
   NotifierWithReturn postcopy_notifier;
   struct PostCopyFD  postcopy_fd;
   uint64_t   postcopy_client_bases[VHOST_USER_MAX_RAM_SLOTS];
@@ -1461,7 +1462,11 @@ static void slave_read(void *opaque)

   switch (hdr.request) {
   case VHOST_USER_SLAVE_IOTLB_MSG:
-ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
+if (likely(u->iotlb_enabled)) {
+ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
+} else {
+ret = -EFAULT;
+}
   break;
   case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
   ret = vhost_user_slave_handle_config_change(dev);
@@ -2044,7 +2049,8 @@ static int vhost_user_send_device_iotlb_msg(struct 
vhost_dev *dev,

   static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int enabled)
   {
-/* No-op as the receive channel is not dedicated to IOTLB messages. */
+struct vhost_user *u = dev->opaque;
+u->iotlb_enabled = enabled;
   }

   static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,





RE: [PATCH 02/10] Fix the qemu crash when guest shutdown during checkpoint

2021-01-28 Thread Rao, Lei
The state will be set RUN_STATE_COLO in colo_do_checkpoint_transaction(). If 
the guest executes power off or shutdown at this time and the QEMU main thread 
will call vm_shutdown(), it will set the state to RUN_STATE_SHUTDOWN.
The state switch from RUN_STATE_COLO to RUN_STATE_SHUTDOWN is not defined in 
runstate_transitions_def. this will cause QEMU crash. Although this is small 
probability, it may still happen. By the way. Do you have any comments about 
other patches?

Thanks,
Lei.

-Original Message-
From: Lukas Straub  
Sent: Thursday, January 28, 2021 2:24 AM
To: Rao, Lei 
Cc: Zhang, Chen ; lizhij...@cn.fujitsu.com; 
jasow...@redhat.com; zhang.zhanghaili...@huawei.com; quint...@redhat.com; 
dgilb...@redhat.com; qemu-devel@nongnu.org
Subject: Re: [PATCH 02/10] Fix the qemu crash when guest shutdown during 
checkpoint

On Thu, 21 Jan 2021 01:48:31 +
"Rao, Lei"  wrote:

> The Primary VM can be shut down when it is in COLO state, which may trigger 
> this bug.

Do you have a backtrace for this bug?

> About 'shutdown' -> 'colo' -> 'running', I think you are right, I did have 
> the problems you said. For 'shutdown'->'colo', The fixed 
> patch(5647051f432b7c9b57525470b0a79a31339062d2) have been merged.
> Recently, I found another bug as follows in the test.
>   qemu-system-x86_64: invalid runstate transition: 'shutdown' -> 'running'
>   Aborted (core dumped)
> The gdb bt as following:
> #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
> #1  0x7faa3d613859 in __GI_abort () at abort.c:79
> #2  0x55c5a21268fd in runstate_set (new_state=RUN_STATE_RUNNING) at 
> vl.c:723
> #3  0x55c5a1f8cae4 in vm_prepare_start () at 
> /home/workspace/colo-qemu/cpus.c:2206
> #4  0x55c5a1f8cb1b in vm_start () at 
> /home/workspace/colo-qemu/cpus.c:2213
> #5  0x55c5a2332bba in migration_iteration_finish (s=0x55c5a4658810) 
> at migration/migration.c:3376
> #6  0x55c5a2332f3b in migration_thread (opaque=0x55c5a4658810) at 
> migration/migration.c:3527
> #7  0x55c5a251d68a in qemu_thread_start (args=0x55c5a5491a70) at 
> util/qemu-thread-posix.c:519
> #8  0x7faa3d7e9609 in start_thread (arg=) at 
> pthread_create.c:477
> #9  0x7faa3d710293 in clone () at 
> ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
> 
> For the bug, I made the following changes:
>   @@ -3379,7 +3379,9 @@ static void 
> migration_iteration_finish(MigrationState *s)
>  case MIGRATION_STATUS_CANCELLED:
>  case MIGRATION_STATUS_CANCELLING:
>  if (s->vm_was_running) {
> -vm_start();
> +if (!runstate_check(RUN_STATE_SHUTDOWN)) {
> +vm_start();
> +}
>  } else {
>  if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
>  runstate_set(RUN_STATE_POSTMIGRATE);
>
> I will send the patch to community after more test.
> 
> Thanks,
> Lei.
> 
> -Original Message-
> From: Lukas Straub 
> Sent: Thursday, January 21, 2021 3:13 AM
> To: Rao, Lei 
> Cc: Zhang, Chen ; lizhij...@cn.fujitsu.com; 
> jasow...@redhat.com; zhang.zhanghaili...@huawei.com; 
> quint...@redhat.com; dgilb...@redhat.com; qemu-devel@nongnu.org
> Subject: Re: [PATCH 02/10] Fix the qemu crash when guest shutdown 
> during checkpoint
> 
> On Wed, 13 Jan 2021 10:46:27 +0800
> leirao  wrote:
> 
> > From: "Rao, Lei" 
> > 
> > This patch fixes the following:
> > qemu-system-x86_64: invalid runstate transition: 'colo' ->'shutdown'
> > Aborted (core dumped)
> > 
> > Signed-off-by: Lei Rao 
> 
> I wonder how that is possible, since the VM is stopped during 'colo' state.
> 
> Unrelated to this patch, I think this area needs some work since the 
> following unintended runstate transition is possible:
> 'shutdown' -> 'colo' -> 'running'.
> 
> > ---
> >  softmmu/runstate.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 
> > 636aab0..455ad0d 100644
> > --- a/softmmu/runstate.c
> > +++ b/softmmu/runstate.c
> > @@ -125,6 +125,7 @@ static const RunStateTransition 
> > runstate_transitions_def[] = {
> >  { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
> >  
> >  { RUN_STATE_COLO, RUN_STATE_RUNNING },
> > +{ RUN_STATE_COLO, RUN_STATE_SHUTDOWN},
> >  
> >  { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
> >  { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
> 
> 
> 



-- 




[Bug 1913667] [NEW] FPE in npcm7xx_clk_update_pll

2021-01-28 Thread Alexander Bulekov
Public bug reported:

I've been working on integrating the generic-fuzzer with ARM machines on
OSS-Fuzz so we can fuzz devices on architectures beyond i386 devices.
Since I saw that there is some active development for the Nuvoton
machines, I thought it might be useful to fuzz the NPCM750 machine

Reproducer:
cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
-accel qtest -qtest stdio
write 0xf080100c 0x4 0x00
write 0xf080100c 0x4 0x00
EOF

Trace:
../hw/misc/npcm7xx_clk.c:131:14: runtime error: division by zero
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/misc/npcm7xx_clk.c:131:14 in
AddressSanitizer:DEADLYSIGNAL
=
==717855==ERROR: AddressSanitizer: FPE on unknown address 0x5619201fcd8c (pc 
0x5619201fcd8c bp 0x7ffc94214e50 sp 0x7ffc94214e30 T0)
#0 0x5619201fcd8c in npcm7xx_clk_update_pll /hw/misc/npcm7xx_clk.c:131:14
#1 0x5619201ff5dc in npcm7xx_clk_write /hw/misc/npcm7xx_clk.c:799:13
#2 0x5619214781fe in memory_region_write_accessor /softmmu/memory.c:491:5
#3 0x561921477bfb in access_with_adjusted_size /softmmu/memory.c:552:18
#4 0x561921477467 in memory_region_dispatch_write /softmmu/memory.c
#5 0x561921807ffb in flatview_write_continue /softmmu/physmem.c:2759:23
#6 0x5619217fd71b in flatview_write /softmmu/physmem.c:2799:14
#7 0x5619217fd71b in address_space_write /softmmu/physmem.c:2891:18
#8 0x561921465eee in qtest_process_command /softmmu/qtest.c:539:13
#9 0x561921462b97 in qtest_process_inbuf /softmmu/qtest.c:797:9
#10 0x561921cb3286 in fd_chr_read /chardev/char-fd.c:68:9
#11 0x7f4ad283baae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
#12 0x56192230e363 in glib_pollfds_poll /util/main-loop.c:232:9
#13 0x56192230e363 in os_host_main_loop_wait /util/main-loop.c:255:5
#14 0x56192230e363 in main_loop_wait /util/main-loop.c:531:11
#15 0x5619213c9599 in qemu_main_loop /softmmu/runstate.c:721:9
#16 0x56191f6561fd in main /softmmu/main.c:50:5
#17 0x7f4ad22e0cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
#18 0x56191f5a9bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: fuzzer

** Tags added: fuzzer

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

Title:
  FPE in npcm7xx_clk_update_pll

Status in QEMU:
  New

Bug description:
  I've been working on integrating the generic-fuzzer with ARM machines
  on OSS-Fuzz so we can fuzz devices on architectures beyond i386
  devices. Since I saw that there is some active development for the
  Nuvoton machines, I thought it might be useful to fuzz the NPCM750
  machine

  Reproducer:
  cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
  -accel qtest -qtest stdio
  write 0xf080100c 0x4 0x00
  write 0xf080100c 0x4 0x00
  EOF

  Trace:
  ../hw/misc/npcm7xx_clk.c:131:14: runtime error: division by zero
  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/misc/npcm7xx_clk.c:131:14 in
  AddressSanitizer:DEADLYSIGNAL
  =
  ==717855==ERROR: AddressSanitizer: FPE on unknown address 0x5619201fcd8c (pc 
0x5619201fcd8c bp 0x7ffc94214e50 sp 0x7ffc94214e30 T0)
  #0 0x5619201fcd8c in npcm7xx_clk_update_pll /hw/misc/npcm7xx_clk.c:131:14
  #1 0x5619201ff5dc in npcm7xx_clk_write /hw/misc/npcm7xx_clk.c:799:13
  #2 0x5619214781fe in memory_region_write_accessor /softmmu/memory.c:491:5
  #3 0x561921477bfb in access_with_adjusted_size /softmmu/memory.c:552:18
  #4 0x561921477467 in memory_region_dispatch_write /softmmu/memory.c
  #5 0x561921807ffb in flatview_write_continue /softmmu/physmem.c:2759:23
  #6 0x5619217fd71b in flatview_write /softmmu/physmem.c:2799:14
  #7 0x5619217fd71b in address_space_write /softmmu/physmem.c:2891:18
  #8 0x561921465eee in qtest_process_command /softmmu/qtest.c:539:13
  #9 0x561921462b97 in qtest_process_inbuf /softmmu/qtest.c:797:9
  #10 0x561921cb3286 in fd_chr_read /chardev/char-fd.c:68:9
  #11 0x7f4ad283baae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
  #12 0x56192230e363 in glib_pollfds_poll /util/main-loop.c:232:9
  #13 0x56192230e363 in os_host_main_loop_wait /util/main-loop.c:255:5
  #14 0x56192230e363 in main_loop_wait /util/main-loop.c:531:11
  #15 0x5619213c9599 in qemu_main_loop /softmmu/runstate.c:721:9
  #16 0x56191f6561fd in main /softmmu/main.c:50:5
  #17 0x7f4ad22e0cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
  #18 0x56191f5a9bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

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



[Bug 1913668] [NEW] FPE in npcm7xx_pwm_calculate_freq

2021-01-28 Thread Alexander Bulekov
Public bug reported:

Reproducer:
cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
-accel qtest -qtest stdio
write 0xf0103008 0x4 0x0900
write 0xf010300c 0x4 0x
EOF

Trace:
../hw/misc/npcm7xx_pwm.c:94:17: runtime error: division by zero
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/misc/npcm7xx_pwm.c:94:17 in
AddressSanitizer:DEADLYSIGNAL
=
==717868==ERROR: AddressSanitizer: FPE on unknown address 0x5597c7190150 (pc 
0x5597c7190150 bp 0x7fffcb17c5d0 sp 0x7fffcb17c4e0 T0)
#0 0x5597c7190150 in npcm7xx_pwm_calculate_freq /hw/misc/npcm7xx_pwm.c:94:17
#1 0x5597c7190150 in npcm7xx_pwm_update_freq /hw/misc/npcm7xx_pwm.c:122:21
#2 0x5597c718f06d in npcm7xx_pwm_write /hw/misc/npcm7xx_pwm.c
#3 0x5597c8d241fe in memory_region_write_accessor /softmmu/memory.c:491:5
#4 0x5597c8d23bfb in access_with_adjusted_size /softmmu/memory.c:552:18
#5 0x5597c8d23467 in memory_region_dispatch_write /softmmu/memory.c
#6 0x5597c90b3ffb in flatview_write_continue /softmmu/physmem.c:2759:23
#7 0x5597c90a971b in flatview_write /softmmu/physmem.c:2799:14
#8 0x5597c90a971b in address_space_write /softmmu/physmem.c:2891:18
#9 0x5597c8d11eee in qtest_process_command /softmmu/qtest.c:539:13
#10 0x5597c8d0eb97 in qtest_process_inbuf /softmmu/qtest.c:797:9
#11 0x5597c955f286 in fd_chr_read /chardev/char-fd.c:68:9
#12 0x7f994c124aae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
#13 0x5597c9bba363 in glib_pollfds_poll /util/main-loop.c:232:9
#14 0x5597c9bba363 in os_host_main_loop_wait /util/main-loop.c:255:5
#15 0x5597c9bba363 in main_loop_wait /util/main-loop.c:531:11
#16 0x5597c8c75599 in qemu_main_loop /softmmu/runstate.c:721:9
#17 0x5597c6f021fd in main /softmmu/main.c:50:5
#18 0x7f994bbc9cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
#19 0x5597c6e55bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: fuzzer

** Tags added: fuzzer

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

Title:
  FPE in npcm7xx_pwm_calculate_freq

Status in QEMU:
  New

Bug description:
  Reproducer:
  cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
  -accel qtest -qtest stdio
  write 0xf0103008 0x4 0x0900
  write 0xf010300c 0x4 0x
  EOF

  Trace:
  ../hw/misc/npcm7xx_pwm.c:94:17: runtime error: division by zero
  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/misc/npcm7xx_pwm.c:94:17 in
  AddressSanitizer:DEADLYSIGNAL
  =
  ==717868==ERROR: AddressSanitizer: FPE on unknown address 0x5597c7190150 (pc 
0x5597c7190150 bp 0x7fffcb17c5d0 sp 0x7fffcb17c4e0 T0)
  #0 0x5597c7190150 in npcm7xx_pwm_calculate_freq /hw/misc/npcm7xx_pwm.c:94:17
  #1 0x5597c7190150 in npcm7xx_pwm_update_freq /hw/misc/npcm7xx_pwm.c:122:21
  #2 0x5597c718f06d in npcm7xx_pwm_write /hw/misc/npcm7xx_pwm.c
  #3 0x5597c8d241fe in memory_region_write_accessor /softmmu/memory.c:491:5
  #4 0x5597c8d23bfb in access_with_adjusted_size /softmmu/memory.c:552:18
  #5 0x5597c8d23467 in memory_region_dispatch_write /softmmu/memory.c
  #6 0x5597c90b3ffb in flatview_write_continue /softmmu/physmem.c:2759:23
  #7 0x5597c90a971b in flatview_write /softmmu/physmem.c:2799:14
  #8 0x5597c90a971b in address_space_write /softmmu/physmem.c:2891:18
  #9 0x5597c8d11eee in qtest_process_command /softmmu/qtest.c:539:13
  #10 0x5597c8d0eb97 in qtest_process_inbuf /softmmu/qtest.c:797:9
  #11 0x5597c955f286 in fd_chr_read /chardev/char-fd.c:68:9
  #12 0x7f994c124aae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
  #13 0x5597c9bba363 in glib_pollfds_poll /util/main-loop.c:232:9
  #14 0x5597c9bba363 in os_host_main_loop_wait /util/main-loop.c:255:5
  #15 0x5597c9bba363 in main_loop_wait /util/main-loop.c:531:11
  #16 0x5597c8c75599 in qemu_main_loop /softmmu/runstate.c:721:9
  #17 0x5597c6f021fd in main /softmmu/main.c:50:5
  #18 0x7f994bbc9cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
  #19 0x5597c6e55bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

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



[Bug 1913669] [NEW] FPE in npcm7xx_adc_convert

2021-01-28 Thread Alexander Bulekov
Public bug reported:

Reproducer:
cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
-accel qtest -qtest stdio
write 0xf000c000 0x4 0x02400200
clock_step
EOF

Trace:
../hw/adc/npcm7xx_adc.c:60:51: runtime error: division by zero
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/adc/npcm7xx_adc.c:60:51 in
AddressSanitizer:DEADLYSIGNAL
=
==717962==ERROR: AddressSanitizer: FPE on unknown address 0x55901aa6e67a (pc 
0x55901aa6e67a bp 0x7fff0ac087e0 sp 0x7fff0ac087a0 T0)
#0 0x55901aa6e67a in npcm7xx_adc_convert /hw/adc/npcm7xx_adc.c:60:51
#1 0x55901aa6e67a in npcm7xx_adc_convert_done /hw/adc/npcm7xx_adc.c:106:15
#2 0x55901ceb847e in timerlist_run_timers /util/qemu-timer.c:574:9
#3 0x55901c05d804 in qtest_clock_warp /softmmu/qtest.c:356:9
#4 0x55901c059781 in qtest_process_command /softmmu/qtest.c:752:9
#5 0x55901c051b97 in qtest_process_inbuf /softmmu/qtest.c:797:9
#6 0x55901c8a2286 in fd_chr_read /chardev/char-fd.c:68:9
#7 0x7fa5c43f1aae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
#8 0x55901cefd363 in glib_pollfds_poll /util/main-loop.c:232:9
#9 0x55901cefd363 in os_host_main_loop_wait /util/main-loop.c:255:5
#10 0x55901cefd363 in main_loop_wait /util/main-loop.c:531:11
#11 0x55901bfb8599 in qemu_main_loop /softmmu/runstate.c:721:9
#12 0x55901a2451fd in main /softmmu/main.c:50:5
#13 0x7fa5c3e96cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
#14 0x55901a198bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /hw/adc/npcm7xx_adc.c:60:51 in 
npcm7xx_adc_convert

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: fuzzer

** Tags added: fuzzer

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

Title:
  FPE in npcm7xx_adc_convert

Status in QEMU:
  New

Bug description:
  Reproducer:
  cat << EOF | ./qemu-system-aarch64 -M npcm750-evb \
  -accel qtest -qtest stdio
  write 0xf000c000 0x4 0x02400200
  clock_step
  EOF

  Trace:
  ../hw/adc/npcm7xx_adc.c:60:51: runtime error: division by zero
  SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 
../hw/adc/npcm7xx_adc.c:60:51 in
  AddressSanitizer:DEADLYSIGNAL
  =
  ==717962==ERROR: AddressSanitizer: FPE on unknown address 0x55901aa6e67a (pc 
0x55901aa6e67a bp 0x7fff0ac087e0 sp 0x7fff0ac087a0 T0)
  #0 0x55901aa6e67a in npcm7xx_adc_convert /hw/adc/npcm7xx_adc.c:60:51
  #1 0x55901aa6e67a in npcm7xx_adc_convert_done /hw/adc/npcm7xx_adc.c:106:15
  #2 0x55901ceb847e in timerlist_run_timers /util/qemu-timer.c:574:9
  #3 0x55901c05d804 in qtest_clock_warp /softmmu/qtest.c:356:9
  #4 0x55901c059781 in qtest_process_command /softmmu/qtest.c:752:9
  #5 0x55901c051b97 in qtest_process_inbuf /softmmu/qtest.c:797:9
  #6 0x55901c8a2286 in fd_chr_read /chardev/char-fd.c:68:9
  #7 0x7fa5c43f1aae in g_main_context_dispatch 
(/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51aae)
  #8 0x55901cefd363 in glib_pollfds_poll /util/main-loop.c:232:9
  #9 0x55901cefd363 in os_host_main_loop_wait /util/main-loop.c:255:5
  #10 0x55901cefd363 in main_loop_wait /util/main-loop.c:531:11
  #11 0x55901bfb8599 in qemu_main_loop /softmmu/runstate.c:721:9
  #12 0x55901a2451fd in main /softmmu/main.c:50:5
  #13 0x7fa5c3e96cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
  #14 0x55901a198bc9 in _start 
(/home/alxndr/Development/qemu/build/qemu-system-aarch64+0x3350bc9)

  AddressSanitizer can not provide additional info.
  SUMMARY: AddressSanitizer: FPE /hw/adc/npcm7xx_adc.c:60:51 in 
npcm7xx_adc_convert

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



Re: [Bug 1909418] Re: QEMU: Heap Overflow vulnerability in SDHCI Component

2021-01-28 Thread Alexander Bulekov
This was found by OSS-Fuzz as well. Yankable reproducer:

+CC Phil. I know you mentioned you don't have time to fix many of the
sdhci bugs, but this one seems like a large heap write, and the original
reporter provided some analysis.

On 210107 0307, Muhammad Ramdhan wrote:
> ** Information type changed from Private Security to Public Security
> 
> -- 
> You received this bug notification because you are a member of qemu-
> devel-ml, which is subscribed to QEMU.
> https://bugs.launchpad.net/bugs/1909418
> 
> Title:
>   QEMU: Heap Overflow vulnerability in SDHCI Component
> 
> Status in QEMU:
>   New
> 
> Bug description:
>   Hello, i want to report qemu vulnerability in SDHCI component, this is
>   integer overflow bug leads to oob read/write in the heap, that can
>   happens in sdhci_do_adma or sdhci_sdma_transfer_multi_blocks.
> 
>   This is caused when in the middle of unfinished transfer, blksize can
>   change, but the data_count still have the last offset of fifo_buffer
>   from the last transfer. We change blksize to zero, then in the next
>   transfer dma_memory_read/dma_memory_write in the first loop calculate
>   length as blksize-data_count, this leads to integer overflow, because
>   blksize is zero, and data_count can be more than zero.
> 
>   This bug is recorded in CVE-2020-25085, but the fix is not complete
>   and not fix the root cause of the bug.
>   Reproducer:

Changing this so it is yankable:

cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest \
-m 512M -nodefaults -device sdhci-pci,sd-spec-version=3 \
-device sd-card,drive=mydrive \
-drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \
-nographic -qtest stdio
outl 0xcf8 0x80001010
outl 0xcfc 0xd7055dba
outl 0xcf8 0x80001003
outl 0xcfc 0x86b1d733
write 0x00 0x1 0x29
write 0x02 0x1 0x10
write 0x08 0x1 0x39
writeb 0xd7055d2b 0x5e
writel 0xd7055d2c 0xed7d735
writew 0xd7055d30 0x126e
writeb 0xd7055d32 0x84
writel 0xd7055d24 0xd7346e01
writew 0xd7055d28 0x3bd7
writeb 0xd7055d2a 0x1
writeb 0xd7055d05 0x2c
writew 0xd7055d06 0x5c4
writeb 0xd7055d0c 0x21
writew 0xd7055d0e 0x846e
writel 0xd7055d04 0x26
writew 0xd7055d08 0x0
writeb 0xd7055d0a 0x6d
writeb 0xd7055d0c 0x31
clock_step
EOF

-Alex

> 
>   ➜  x86_64-softmmu git:(master) ✗ ./qemu-system-x86_64 -m 4G -nodefaults 
> -trace 'sdhci*' -device sdhci-pci,sd-spec-version=3 -device 
> sd-card,drive=mydrive -drive 
> if=sd,index=0,file=null-co://,format=raw,id=mydrive -nographic -qtest stdio 
> -accel qtest
>   ==410717==WARNING: ASan doesn't fully support makecontext/swapcontext 
> functions and may produce false positives in some cases!
>   [I 1609122395.789698] OPENED
>   qemu-system-x86_64: -drive 
> if=sd,index=0,file=null-co://,format=raw,id=mydrive: warning: bogus if=sd is 
> deprecated, use if=none
>   [R +0.037381] outl 0xcf8 0x80001010
>   [S +0.037436] OK
>   OK
>   [R +0.037470] outl 0xcfc 0xd7055dba
>   [S +0.037510] OK
>   OK
>   [R +0.037531] outl 0xcf8 0x80001003
>   [S +0.037549] OK
>   OK
>   [R +0.037571] outl 0xcfc 0x86b1d733
>   [S +0.039830] OK
>   OK
>   [R +0.039882] write 0x00 0x1 0x29
>   [S +0.040364] OK
>   OK
>   [R +0.040401] write 0x02 0x1 0x10
>   [S +0.040428] OK
>   OK
>   [R +0.040449] write 0x08 0x1 0x39
>   [S +0.040472] OK
>   OK
>   [R +0.040491] writeb 0xd7055d2b 0x5e
>   [S +0.040530] OK
>   OK
>   [R +0.040550] writel 0xd7055d2c 0xed7d735
>   [S +0.040575] OK
>   OK
>   [R +0.040594] writew 0xd7055d30 0x126e
>   [S +0.040620] OK
>   OK
>   [R +0.040638] writeb 0xd7055d32 0x84
>   [S +0.040658] OK
>   OK
>   [R +0.040676] writel 0xd7055d24 0xd7346e01
>   [S +0.040697] OK
>   OK
>   [R +0.040715] writew 0xd7055d28 0x3bd7
>   [S +0.040738] OK
>   OK
>   [R +0.040756] writeb 0xd7055d2a 0x1
>   [S +0.040779] OK
>   OK
>   [R +0.040797] writeb 0xd7055d05 0x2c
>   [S +0.040819] OK
>   OK
>   [R +0.040840] writew 0xd7055d06 0x5c4
>   [S +0.040862] OK
>   OK
>   [R +0.040882] writeb 0xd7055d0c 0x21
>   [S +0.040907] OK
>   OK
>   [R +0.040927] writew 0xd7055d0e 0x846e
>   [S +0.041026] OK
>   OK
>   [R +0.041054] writel 0xd7055d04 0x26
>   [S +0.041115] OK
>   OK
>   [R +0.041139] writew 0xd7055d08 0x0
>   =
>   ==410717==ERROR: AddressSanitizer: heap-buffer-overflow on address 
> 0x61524180 at pc 0x7fe40cb7457d bp 0x7fffa1a7b800 sp 0x7fffa1a7afa8
>   WRITE of size 786432 at 0x61524180 thread T0
>   #0 0x7fe40cb7457c  (/lib/x86_64-linux-gnu/libasan.so.5+0x9b57c)
>   #1 0x55f804942120 in flatview_read_continue ../../softmmu/physmem.c:2829
>   #2 0x55f8049423dd in flatview_read ../../softmmu/physmem.c:2862
>   #3 0x55f804942581 in address_space_read_full 
> ../../softmmu/physmem.c:2875
>   #4 0x55f804942800 in address_space_rw ../../softmmu/physmem.c:2903
>   #5 0x55f8038d6a92 in dma_memory_rw_relaxed 
> /home/n0p/belajar/qemu/source/qemu/include/sysemu/dma.h:88
>   #6 0x55f8038d6adf in dma_memory_rw 
> /home/n0p/belajar/qemu/source/qemu

[PATCH v2 5/6] hw/i2c: Add a QTest for NPCM7XX SMBus Device

2021-01-28 Thread wuhaotsh--- via
This patch adds a QTest for NPCM7XX SMBus's single byte mode. It sends a
byte to a device in the evaluation board, and verify the retrieved value
is equivalent to the sent value.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_smbus-test.c | 352 +++
 2 files changed, 353 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_smbus-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 16d04625b8..aa62d59817 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -138,6 +138,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test']
 qtests_arm = \
diff --git a/tests/qtest/npcm7xx_smbus-test.c b/tests/qtest/npcm7xx_smbus-test.c
new file mode 100644
index 00..4594b107df
--- /dev/null
+++ b/tests/qtest/npcm7xx_smbus-test.c
@@ -0,0 +1,352 @@
+/*
+ * QTests for Nuvoton NPCM7xx SMBus Modules.
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "libqos/i2c.h"
+#include "libqos/libqtest.h"
+#include "hw/misc/tmp105_regs.h"
+
+#define NR_SMBUS_DEVICES16
+#define SMBUS_ADDR(x)   (0xf008 + 0x1000 * (x))
+#define SMBUS_IRQ(x)(64 + (x))
+
+#define EVB_DEVICE_ADDR 0x48
+#define INVALID_DEVICE_ADDR 0x01
+
+const int evb_bus_list[] = {0, 1, 2, 6};
+
+/* Offsets */
+enum CommonRegister {
+OFFSET_SDA = 0x0,
+OFFSET_ST  = 0x2,
+OFFSET_CST = 0x4,
+OFFSET_CTL1= 0x6,
+OFFSET_ADDR1   = 0x8,
+OFFSET_CTL2= 0xa,
+OFFSET_ADDR2   = 0xc,
+OFFSET_CTL3= 0xe,
+OFFSET_CST2= 0x18,
+OFFSET_CST3= 0x19,
+};
+
+enum NPCM7xxSMBusBank0Register {
+OFFSET_ADDR3   = 0x10,
+OFFSET_ADDR7   = 0x11,
+OFFSET_ADDR4   = 0x12,
+OFFSET_ADDR8   = 0x13,
+OFFSET_ADDR5   = 0x14,
+OFFSET_ADDR9   = 0x15,
+OFFSET_ADDR6   = 0x16,
+OFFSET_ADDR10  = 0x17,
+OFFSET_CTL4= 0x1a,
+OFFSET_CTL5= 0x1b,
+OFFSET_SCLLT   = 0x1c,
+OFFSET_FIF_CTL = 0x1d,
+OFFSET_SCLHT   = 0x1e,
+};
+
+enum NPCM7xxSMBusBank1Register {
+OFFSET_FIF_CTS  = 0x10,
+OFFSET_FAIR_PER = 0x11,
+OFFSET_TXF_CTL  = 0x12,
+OFFSET_T_OUT= 0x14,
+OFFSET_TXF_STS  = 0x1a,
+OFFSET_RXF_STS  = 0x1c,
+OFFSET_RXF_CTL  = 0x1e,
+};
+
+/* ST fields */
+#define ST_STP  BIT(7)
+#define ST_SDASTBIT(6)
+#define ST_BER  BIT(5)
+#define ST_NEGACK   BIT(4)
+#define ST_STASTR   BIT(3)
+#define ST_NMATCH   BIT(2)
+#define ST_MODE BIT(1)
+#define ST_XMIT BIT(0)
+
+/* CST fields */
+#define CST_ARPMATCHBIT(7)
+#define CST_MATCHAF BIT(6)
+#define CST_TGSCL   BIT(5)
+#define CST_TSDABIT(4)
+#define CST_GCMATCH BIT(3)
+#define CST_MATCH   BIT(2)
+#define CST_BB  BIT(1)
+#define CST_BUSYBIT(0)
+
+/* CST2 fields */
+#define CST2_INSTTS BIT(7)
+#define CST2_MATCH7FBIT(6)
+#define CST2_MATCH6FBIT(5)
+#define CST2_MATCH5FBIT(4)
+#define CST2_MATCH4FBIT(3)
+#define CST2_MATCH3FBIT(2)
+#define CST2_MATCH2FBIT(1)
+#define CST2_MATCH1FBIT(0)
+
+/* CST3 fields */
+#define CST3_EO_BUSYBIT(7)
+#define CST3_MATCH10F   BIT(2)
+#define CST3_MATCH9FBIT(1)
+#define CST3_MATCH8FBIT(0)
+
+/* CTL1 fields */
+#define CTL1_STASTREBIT(7)
+#define CTL1_NMINTE BIT(6)
+#define CTL1_GCMEN  BIT(5)
+#define CTL1_ACKBIT(4)
+#define CTL1_EOBINTEBIT(3)
+#define CTL1_INTEN  BIT(2)
+#define CTL1_STOP   BIT(1)
+#define CTL1_START  BIT(0)
+
+/* CTL2 fields */
+#define CTL2_SCLFRQ(rv) extract8((rv), 1, 6)
+#define CTL2_ENABLE BIT(0)
+
+/* CTL3 fields */
+#define CTL3_SCL_LVLBIT(7)
+#define CTL3_SDA_LVLBIT(6)
+#define CTL3_BNK_SELBIT(5)
+#define CTL3_400K_MODE  BIT(4)
+#define CTL3_IDL_START  BIT(3)
+#define CTL3_ARPMEN BIT(2)
+#define CTL3_SCLFRQ(rv) extract8((rv), 0, 2)
+
+/* ADDR fields */
+#define ADDR_EN BIT(7)
+#define ADDR_A(rv)  extract8((rv), 0, 6)
+
+
+static void check_running(QTestState *qts, uint64_t base_addr)
+{
+g_assert_true(qtest_readb(qts, base_

[PATCH v2 6/6] hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode

2021-01-28 Thread wuhaotsh--- via
This patch implements the FIFO mode of the SMBus module. In FIFO, the
user transmits or receives at most 16 bytes at a time. The FIFO mode
allows the module to transmit large amount of data faster than single
byte mode.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
Reviewed-by: Corey Minyard 
Ack-by: Corey Minyard 
---
 hw/i2c/npcm7xx_smbus.c   | 342 +--
 hw/i2c/trace-events  |   1 +
 include/hw/i2c/npcm7xx_smbus.h   |  25 +++
 tests/qtest/npcm7xx_smbus-test.c | 149 +-
 4 files changed, 501 insertions(+), 16 deletions(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index c72b6e446f..be3253d251 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -27,7 +27,7 @@
 #include "trace.h"
 
 #define NPCM7XX_SMBUS_VERSION 1
-#define NPCM7XX_SMBUS_FIFO_EN 0
+#define NPCM7XX_SMBUS_FIFO_EN 1
 
 enum NPCM7xxSMBusCommonRegister {
 NPCM7XX_SMB_SDA = 0x0,
@@ -132,10 +132,41 @@ enum NPCM7xxSMBusBank1Register {
 #define NPCM7XX_ADDR_EN BIT(7)
 #define NPCM7XX_ADDR_A(rv)  extract8((rv), 0, 6)
 
+/* FIFO Mode Register Fields */
+/* FIF_CTL fields */
+#define NPCM7XX_SMBFIF_CTL_FIFO_EN  BIT(4)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE  BIT(2)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY BIT(1)
+#define NPCM7XX_SMBFIF_CTL_FAIR_BUSYBIT(0)
+/* FIF_CTS fields */
+#define NPCM7XX_SMBFIF_CTS_STR  BIT(7)
+#define NPCM7XX_SMBFIF_CTS_CLR_FIFO BIT(6)
+#define NPCM7XX_SMBFIF_CTS_RFTE_IE  BIT(3)
+#define NPCM7XX_SMBFIF_CTS_RXF_TXE  BIT(1)
+/* TXF_CTL fields */
+#define NPCM7XX_SMBTXF_CTL_THR_TXIE BIT(6)
+#define NPCM7XX_SMBTXF_CTL_TX_THR(rv)   extract8((rv), 0, 5)
+/* T_OUT fields */
+#define NPCM7XX_SMBT_OUT_ST BIT(7)
+#define NPCM7XX_SMBT_OUT_IE BIT(6)
+#define NPCM7XX_SMBT_OUT_CLKDIV(rv) extract8((rv), 0, 6)
+/* TXF_STS fields */
+#define NPCM7XX_SMBTXF_STS_TX_THST  BIT(6)
+#define NPCM7XX_SMBTXF_STS_TX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_STS fields */
+#define NPCM7XX_SMBRXF_STS_RX_THST  BIT(6)
+#define NPCM7XX_SMBRXF_STS_RX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_CTL fields */
+#define NPCM7XX_SMBRXF_CTL_THR_RXIE BIT(6)
+#define NPCM7XX_SMBRXF_CTL_LAST BIT(5)
+#define NPCM7XX_SMBRXF_CTL_RX_THR(rv)   extract8((rv), 0, 5)
+
 #define KEEP_OLD_BIT(o, n, b)   (((n) & (~(b))) | ((o) & (b)))
 #define WRITE_ONE_CLEAR(o, n, b)((n) & (b) ? (o) & (~(b)) : (o))
 
 #define NPCM7XX_SMBUS_ENABLED(s)((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
+#define NPCM7XX_SMBUS_FIFO_ENABLED(s) (NPCM7XX_SMBUS_FIFO_EN && \
+(s)->fif_ctl & NPCM7XX_SMBFIF_CTL_FIFO_EN)
 
 /* Reset values */
 #define NPCM7XX_SMB_ST_INIT_VAL 0x00
@@ -150,6 +181,14 @@ enum NPCM7xxSMBusBank1Register {
 #define NPCM7XX_SMB_ADDR_INIT_VAL   0x00
 #define NPCM7XX_SMB_SCLLT_INIT_VAL  0x00
 #define NPCM7XX_SMB_SCLHT_INIT_VAL  0x00
+#define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
+#define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
+#define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
+#define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
 
 static uint8_t npcm7xx_smbus_get_version(void)
 {
@@ -169,7 +208,13 @@ static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
(s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
 s->st & NPCM7XX_SMBST_SDAST) ||
(s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
-s->cst3 & NPCM7XX_SMBCST3_EO_BUSY));
+s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
+   (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
+s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
+   (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
+s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
+   (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
+s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
 
 if (level) {
 s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
@@ -187,6 +232,13 @@ static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
 s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
 }
 
+static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
+{
+s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
+s->txf_sts = 0;
+s->rxf_sts = 0;
+}
+
 static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
 {
 int rv = i2c_send(s->bus, value);
@@ -195,6 +247,15 @@ static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, 
uint8_t value)
 npcm7xx_smbus_nack(s);
 } else {
 s->st |= NPCM7XX_SMBST_SDAST;
+if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
+if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
+NPCM7XX

[PATCH v2 4/6] hw/arm: Add I2C sensors and EEPROM for GSJ machine

2021-01-28 Thread wuhaotsh--- via
Add AT24 EEPROM and temperature sensors for GSJ machine.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 default-configs/devices/arm-softmmu.mak |  1 +
 hw/arm/npcm7xx_boards.c | 27 +
 2 files changed, 28 insertions(+)

diff --git a/default-configs/devices/arm-softmmu.mak 
b/default-configs/devices/arm-softmmu.mak
index 0500156a0c..d9805dd539 100644
--- a/default-configs/devices/arm-softmmu.mak
+++ b/default-configs/devices/arm-softmmu.mak
@@ -7,6 +7,7 @@ CONFIG_ARM_V7M=y
 # CONFIG_TEST_DEVICES=n
 
 CONFIG_ARM_VIRT=y
+CONFIG_AT24C=y
 CONFIG_CUBIEBOARD=y
 CONFIG_EXYNOS4=y
 CONFIG_HIGHBANK=y
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 47a215bd01..2d757b4013 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -19,6 +19,7 @@
 #include "exec/address-spaces.h"
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
+#include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -104,6 +105,17 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
 }
 
+static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
+  uint32_t rsize)
+{
+I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
+I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rsize);
+i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
+}
+
 static void npcm750_evb_i2c_init(NPCM7xxState *soc)
 {
 /* lm75 temperature sensor on SVB, tmp105 is compatible */
@@ -116,6 +128,20 @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
 }
 
+static void quanta_gsj_i2c_init(NPCM7xxState *soc)
+{
+/* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. 
*/
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x5c);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x5c);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
+
+at24c_eeprom_init(soc, 9, 0x55, 8192);
+at24c_eeprom_init(soc, 10, 0x55, 8192);
+
+/* TODO: Add addtional i2c devices. */
+}
+
 static void npcm750_evb_init(MachineState *machine)
 {
 NPCM7xxState *soc;
@@ -141,6 +167,7 @@ static void quanta_gsj_init(MachineState *machine)
 npcm7xx_load_bootrom(machine, soc);
 npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
   drive_get(IF_MTD, 0, 0));
+quanta_gsj_i2c_init(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.30.0.365.g02bc693789-goog




[PATCH v2 1/6] hw/arm: Remove GPIO from unimplemented NPCM7XX

2021-01-28 Thread wuhaotsh--- via
NPCM7XX GPIO devices have been implemented in hw/gpio/npcm7xx-gpio.c. So
we removed them from the unimplemented devices list.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu
---
 hw/arm/npcm7xx.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 72040d4079..d1fe9bd1df 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -576,14 +576,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
 create_unimplemented_device("npcm7xx.kcs",  0xf0007000,   4 * KiB);
 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[0]",  0xf001,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[1]",  0xf0011000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[2]",  0xf0012000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[3]",  0xf0013000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[4]",  0xf0014000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[5]",  0xf0015000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[6]",  0xf0016000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[7]",  0xf0017000,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[0]", 0xf008,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000,   4 * KiB);
-- 
2.30.0.365.g02bc693789-goog




[PATCH v2 2/6] hw/i2c: Implement NPCM7XX SMBus Module Single Mode

2021-01-28 Thread wuhaotsh--- via
This commit implements the single-byte mode of the SMBus.

Each Nuvoton SoC has 16 System Management Bus (SMBus). These buses
compliant with SMBus and I2C protocol.

This patch implements the single-byte mode of the SMBus. In this mode,
the user sends or receives a byte each time. The SMBus device transmits
it to the underlying i2c device and sends an interrupt back to the QEMU
guest.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
Reviewed-by: Corey Minyard 
Ack-by: Corey Minyard 
---
 docs/system/arm/nuvoton.rst|   2 +-
 hw/arm/npcm7xx.c   |  68 ++-
 hw/i2c/meson.build |   1 +
 hw/i2c/npcm7xx_smbus.c | 781 +
 hw/i2c/trace-events|  11 +
 include/hw/arm/npcm7xx.h   |   2 +
 include/hw/i2c/npcm7xx_smbus.h |  88 
 7 files changed, 936 insertions(+), 17 deletions(-)
 create mode 100644 hw/i2c/npcm7xx_smbus.c
 create mode 100644 include/hw/i2c/npcm7xx_smbus.h

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index a1786342e2..34fc799b2d 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -43,6 +43,7 @@ Supported devices
  * GPIO controller
  * Analog to Digital Converter (ADC)
  * Pulse Width Modulation (PWM)
+ * SMBus controller (SMBF)
 
 Missing devices
 ---
@@ -58,7 +59,6 @@ Missing devices
 
  * Ethernet controllers (GMAC and EMC)
  * USB device (USBD)
- * SMBus controller (SMBF)
  * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d1fe9bd1df..f8950f9470 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -102,6 +102,22 @@ enum NPCM7xxInterrupt {
 NPCM7XX_WDG2_IRQ,   /* Timer Module 2 Watchdog */
 NPCM7XX_EHCI_IRQ= 61,
 NPCM7XX_OHCI_IRQ= 62,
+NPCM7XX_SMBUS0_IRQ  = 64,
+NPCM7XX_SMBUS1_IRQ,
+NPCM7XX_SMBUS2_IRQ,
+NPCM7XX_SMBUS3_IRQ,
+NPCM7XX_SMBUS4_IRQ,
+NPCM7XX_SMBUS5_IRQ,
+NPCM7XX_SMBUS6_IRQ,
+NPCM7XX_SMBUS7_IRQ,
+NPCM7XX_SMBUS8_IRQ,
+NPCM7XX_SMBUS9_IRQ,
+NPCM7XX_SMBUS10_IRQ,
+NPCM7XX_SMBUS11_IRQ,
+NPCM7XX_SMBUS12_IRQ,
+NPCM7XX_SMBUS13_IRQ,
+NPCM7XX_SMBUS14_IRQ,
+NPCM7XX_SMBUS15_IRQ,
 NPCM7XX_PWM0_IRQ= 93,   /* PWM module 0 */
 NPCM7XX_PWM1_IRQ,   /* PWM module 1 */
 NPCM7XX_GPIO0_IRQ   = 116,
@@ -152,6 +168,26 @@ static const hwaddr npcm7xx_pwm_addr[] = {
 0xf0104000,
 };
 
+/* Direct memory-mapped access to each SMBus Module. */
+static const hwaddr npcm7xx_smbus_addr[] = {
+0xf008,
+0xf0081000,
+0xf0082000,
+0xf0083000,
+0xf0084000,
+0xf0085000,
+0xf0086000,
+0xf0087000,
+0xf0088000,
+0xf0089000,
+0xf008a000,
+0xf008b000,
+0xf008c000,
+0xf008d000,
+0xf008e000,
+0xf008f000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -353,6 +389,11 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "gpio[*]", &s->gpio[i], 
TYPE_NPCM7XX_GPIO);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+object_initialize_child(obj, "smbus[*]", &s->smbus[i],
+TYPE_NPCM7XX_SMBUS);
+}
+
 object_initialize_child(obj, "ehci", &s->ehci, TYPE_NPCM7XX_EHCI);
 object_initialize_child(obj, "ohci", &s->ohci, TYPE_SYSBUS_OHCI);
 
@@ -509,6 +550,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
 }
 
+/* SMBus modules. Cannot fail. */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus));
+for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+Object *obj = OBJECT(&s->smbus[i]);
+
+sysbus_realize(SYS_BUS_DEVICE(obj), &error_abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
+   npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
+}
+
 /* USB Host */
 object_property_set_bool(OBJECT(&s->ehci), "companion-enable", true,
  &error_abort);
@@ -576,22 +628,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
 create_unimplemented_device("npcm7xx.kcs",  0xf0007000,   4 * KiB);
 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[0]", 0xf008,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[3]", 0xf0083000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[4]", 0xf0084000,   4 * KiB);
-create_unimplemente

[PATCH v2 0/6] hw/i2c: Add NPCM7XX SMBus Device

2021-01-28 Thread wuhaotsh--- via
This patch set implements the System manager bus (SMBus) module in NPCM7XX
SoC. Basically, it emulates the data transactions of the module, not the
SDA/SCL levels. We have also added a QTest which contains read and write
operations for both single-byte and FIFO mode, and added basic I2C devices
for npcm750-evb and quanta-gsj boards.

We also cleaned up the unimplemented GPIO devices in npcm7xx.c since they
are already implemented.

Changes since v1:
- Fix errors for i2c device addresses for temperature sensors in GSJ machine
- Use at24c device to emulate GSJ EEPROM. It supports more than 256 bytes.
- Fill in VMState in npcm7xx_smbus.c
- Change commit message in patch 3 and 4
- Fix order in npcm7xx.c IRQ list
- Add a few extra comments to make things clearer

Hao Wu (6):
  hw/arm: Remove GPIO from unimplemented NPCM7XX
  hw/i2c: Implement NPCM7XX SMBus Module Single Mode
  hw/arm: Add I2C sensors for NPCM750 eval board
  hw/arm: Add I2C sensors and EEPROM for GSJ machine
  hw/i2c: Add a QTest for NPCM7XX SMBus Device
  hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode

 default-configs/devices/arm-softmmu.mak |1 +
 docs/system/arm/nuvoton.rst |2 +-
 hw/arm/npcm7xx.c|   76 +-
 hw/arm/npcm7xx_boards.c |   46 +
 hw/i2c/meson.build  |1 +
 hw/i2c/npcm7xx_smbus.c  | 1097 +++
 hw/i2c/trace-events |   12 +
 include/hw/arm/npcm7xx.h|2 +
 include/hw/i2c/npcm7xx_smbus.h  |  113 +++
 tests/qtest/meson.build |1 +
 tests/qtest/npcm7xx_smbus-test.c|  495 ++
 11 files changed, 1821 insertions(+), 25 deletions(-)
 create mode 100644 hw/i2c/npcm7xx_smbus.c
 create mode 100644 include/hw/i2c/npcm7xx_smbus.h
 create mode 100644 tests/qtest/npcm7xx_smbus-test.c

-- 
2.30.0.365.g02bc693789-goog




[PATCH v2 3/6] hw/arm: Add I2C sensors for NPCM750 eval board

2021-01-28 Thread wuhaotsh--- via
Add I2C temperature sensors for NPCM750 eval board.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 3fdd5cab01..47a215bd01 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -98,6 +98,24 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState 
*machine,
 return NPCM7XX(obj);
 }
 
+static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num)
+{
+g_assert(num < ARRAY_SIZE(soc->smbus));
+return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
+}
+
+static void npcm750_evb_i2c_init(NPCM7xxState *soc)
+{
+/* lm75 temperature sensor on SVB, tmp105 is compatible */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), "tmp105", 0x48);
+/* lm75 temperature sensor on EB, tmp105 is compatible */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
+/* tmp100 temperature sensor on EB, tmp105 is compatible */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
+/* tmp100 temperature sensor on SVB, tmp105 is compatible */
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
+}
+
 static void npcm750_evb_init(MachineState *machine)
 {
 NPCM7xxState *soc;
@@ -108,6 +126,7 @@ static void npcm750_evb_init(MachineState *machine)
 
 npcm7xx_load_bootrom(machine, soc);
 npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
+npcm750_evb_i2c_init(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.30.0.365.g02bc693789-goog




Re: [PATCH 4/7] ppc/pnv: Simplify pnv_bmc_create()

2021-01-28 Thread David Gibson
On Thu, Jan 28, 2021 at 08:46:01AM +0100, Cédric Le Goater wrote:
> On 1/28/21 1:46 AM, Joel Stanley wrote:
> > On Tue, 26 Jan 2021 at 17:14, Cédric Le Goater  wrote:
> >>
> >> and reuse pnv_bmc_set_pnor() to share the setting of the PNOR.
> >>
> >> Signed-off-by: Cédric Le Goater 
> >> ---
> >>  hw/ppc/pnv_bmc.c | 7 +--
> >>  1 file changed, 1 insertion(+), 6 deletions(-)
> >>
> >> diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
> >> index 67ebb16c4d5f..86d16b493539 100644
> >> --- a/hw/ppc/pnv_bmc.c
> >> +++ b/hw/ppc/pnv_bmc.c
> >> @@ -260,13 +260,8 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
> >>  Object *obj;
> >>
> >>  obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
> >> -object_ref(OBJECT(pnor));
> >> -object_property_add_const_link(obj, "pnor", OBJECT(pnor));
> > 
> > I assume it's ok to move the link set to after the realise of the BMC 
> > object?
>  
> 
> When 2 objects need to be linked, one has to be realized first. 
> I suppose this is why it is allowed but I am not expert in that area. 
> 
> Greg  ?
> 
> That was the case already when defining a "ipmi-bmc-sim" device on the 
> command line.

Well, the other thing here is that the IPMI_BMC_SIMULATOR isn't a
POWER specific object, and doesn't actually know anything about pnor,
so it never looks at that property.  Do we even need it?

> 
> C. 
> 
> 
> >>  qdev_realize(DEVICE(obj), NULL, &error_fatal);
> >> -
> >> -/* Install the HIOMAP protocol handlers to access the PNOR */
> >> -ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(obj), IPMI_NETFN_OEM,
> >> -&hiomap_netfn);
> >> +pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);
> >>
> >>  return IPMI_BMC(obj);
> >>  }
> >>
> >>
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v2 3/3] spapr_numa.c: fix ibm,max-associativity-domains calculation

2021-01-28 Thread David Gibson

On Thu, Jan 28, 2021 at 02:42:13PM -0300, Daniel Henrique Barboza wrote:
> The current logic for calculating 'maxdomain' making it a sum of
> numa_state->num_nodes with spapr->gpu_numa_id. spapr->gpu_numa_id is
> used as a index to determine the next available NUMA id that a
> given NVGPU can use.
> 
> The problem is that the initial value of gpu_numa_id, for any topology
> that has more than one NUMA node, is equal to numa_state->num_nodes.
> This means that our maxdomain will always be, at least, twice the
> amount of existing NUMA nodes. This means that a guest with 4 NUMA
> nodes will end up with the following max-associativity-domains:
> 
> rtas/ibm,max-associativity-domains
>  0004 0008 0008 0008 0008
> 
> This overtuning of maxdomains doesn't go unnoticed in the guest, being
> detected in SLUB during boot:
> 
>  dmesg | grep SLUB
> [0.00] SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=4, Nodes=8
> 
> SLUB is detecting 8 total nodes, with 4 nodes being online.
> 
> This patch fixes ibm,max-associativity-domains by considering the amount
> of NVGPUs NUMA nodes presented in the guest, instead of just
> spapr->gpu_numa_id.
> 
> Reported-by: Cédric Le Goater 
> Tested-by: Cédric Le Goater 
> Signed-off-by: Daniel Henrique Barboza 

Applied, thanks.

> ---
>  hw/ppc/spapr_numa.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
> index a757dd88b8..779f18b994 100644
> --- a/hw/ppc/spapr_numa.c
> +++ b/hw/ppc/spapr_numa.c
> @@ -311,6 +311,8 @@ void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, 
> void *fdt, int rtas)
>  {
>  MachineState *ms = MACHINE(spapr);
>  SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +uint32_t number_nvgpus_nodes = spapr->gpu_numa_id -
> +   spapr_numa_initial_nvgpu_numa_id(ms);
>  uint32_t refpoints[] = {
>  cpu_to_be32(0x4),
>  cpu_to_be32(0x3),
> @@ -318,7 +320,7 @@ void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, 
> void *fdt, int rtas)
>  cpu_to_be32(0x1),
>  };
>  uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
> -uint32_t maxdomain = ms->numa_state->num_nodes + spapr->gpu_numa_id;
> +uint32_t maxdomain = ms->numa_state->num_nodes + number_nvgpus_nodes;
>  uint32_t maxdomains[] = {
>  cpu_to_be32(4),
>  cpu_to_be32(maxdomain),

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


signature.asc
Description: PGP signature


Re: [PATCH] target/ppc: Fix truncation of env->hflags

2021-01-28 Thread David Gibson
On Sun, Jan 24, 2021 at 09:38:04AM -1000, Richard Henderson wrote:
> On 1/23/21 6:46 PM, David Gibson wrote:
> > On Sat, Jan 23, 2021 at 05:24:22PM -1000, Richard Henderson wrote:
> >> Use the cs_base field, because it happens to be the same
> >> size as hflags (and MSR, from which hflags is derived).
> >>
> >> In translate, extract most bits from a local hflags variable.
> >> Mark several cases where code generation is *not* derived from
> >> data stored within the hashed elements of the TranslationBlock.
> > 
> > My knowledge of TCG isn't great, so I'm pretty much prepared to accept
> > this is correct on your say so.
> > 
> > But that commit message feels like it's following on from a
> > conversation that's not here, nor linked.  It'd be great if it
> > explained how said hflags truncation is happening, because it's
> > certainly not obvious to someone with only a fair to middling
> > understanding of TCG.
> 
> Mm, fair.
> 
> How about:
> 
> The assignment from env->hflags to tb->flags truncates
> target_ulong to uint32_t.  This loses important bits from
> the top of hflags, which results in incorrect tb selection.
> 
> Use the cs_base field instead, because it happens to be the
> same size as hflags (and MSR fom which hflags is derived).
> 
> In translate, extract most bits from a local hflags variable.
> All of the checks vs env->flags are redundant with env->msr_mask
> in that msr bits cannot be set when the feature is not available.
> Mark several cases where code generation is *not* derived from
> data stored within hashed elements of the tb.

Thanks, I've applied the patch with the updated description.

> 
> 
> r~
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v2 2/3] spapr_numa.c: create spapr_numa_initial_nvgpu_numa_id() helper

2021-01-28 Thread David Gibson
On Thu, Jan 28, 2021 at 02:42:12PM -0300, Daniel Henrique Barboza wrote:
> We'll need to check the initial value given to spapr->gpu_numa_id when
> building the rtas DT, so put it in a helper for easier access and to
> avoid repetition.
> 
> Tested-by: Cédric Le Goater 
> Reviewed-by: Greg Kurz 
> Signed-off-by: Daniel Henrique Barboza 

Applied to ppc-for-6.0, thanks.

> ---
>  hw/ppc/spapr.c  | 11 +--
>  hw/ppc/spapr_numa.c | 14 ++
>  include/hw/ppc/spapr_numa.h |  1 +
>  3 files changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 2d60c6f594..bc3fa276ff 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2765,16 +2765,7 @@ static void spapr_machine_init(MachineState *machine)
>  
>  }
>  
> -/*
> - * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
> - * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
> - * called from vPHB reset handler so we initialize the counter here.
> - * If no NUMA is configured from the QEMU side, we start from 1 as GPU 
> RAM
> - * must be equally distant from any other node.
> - * The final value of spapr->gpu_numa_id is going to be written to
> - * max-associativity-domains in spapr_build_fdt().
> - */
> -spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
> +spapr->gpu_numa_id = spapr_numa_initial_nvgpu_numa_id(machine);
>  
>  /* Init numa_assoc_array */
>  spapr_numa_associativity_init(spapr, machine);
> diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
> index 261810525b..a757dd88b8 100644
> --- a/hw/ppc/spapr_numa.c
> +++ b/hw/ppc/spapr_numa.c
> @@ -46,6 +46,20 @@ static bool spapr_numa_is_symmetrical(MachineState *ms)
>  return true;
>  }
>  
> +/*
> + * NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
> + * We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
> + * called from vPHB reset handler so we initialize the counter here.
> + * If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
> + * must be equally distant from any other node.
> + * The final value of spapr->gpu_numa_id is going to be written to
> + * max-associativity-domains in spapr_build_fdt().
> + */
> +unsigned int spapr_numa_initial_nvgpu_numa_id(MachineState *machine)
> +{
> +return MAX(1, machine->numa_state->num_nodes);
> +}
> +
>  /*
>   * This function will translate the user distances into
>   * what the kernel understand as possible values: 10
> diff --git a/include/hw/ppc/spapr_numa.h b/include/hw/ppc/spapr_numa.h
> index b3fd950634..6f9f02d3de 100644
> --- a/include/hw/ppc/spapr_numa.h
> +++ b/include/hw/ppc/spapr_numa.h
> @@ -31,5 +31,6 @@ int spapr_numa_fixup_cpu_dt(SpaprMachineState *spapr, void 
> *fdt,
>  int offset, PowerPCCPU *cpu);
>  int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
>   int offset);
> +unsigned int spapr_numa_initial_nvgpu_numa_id(MachineState *machine);
>  
>  #endif /* HW_SPAPR_NUMA_H */

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


signature.asc
Description: PGP signature


Re: [PATCH 1/3] spapr: move spapr_machine_using_legacy_numa() to spapr_numa.c

2021-01-28 Thread David Gibson
On Thu, Jan 28, 2021 at 12:17:29PM -0300, Daniel Henrique Barboza wrote:
> This function is used only in spapr_numa.c.
> 
> Signed-off-by: Daniel Henrique Barboza 

Applied to ppc-for-6.0, thanks.

> ---
>  hw/ppc/spapr.c | 9 -
>  hw/ppc/spapr_numa.c| 9 +
>  include/hw/ppc/spapr.h | 1 -
>  3 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 6c47466fc2..2d60c6f594 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -295,15 +295,6 @@ static hwaddr spapr_node0_size(MachineState *machine)
>  return machine->ram_size;
>  }
>  
> -bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr)
> -{
> -MachineState *machine = MACHINE(spapr);
> -SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
> -
> -return smc->pre_5_2_numa_associativity ||
> -   machine->numa_state->num_nodes <= 1;
> -}
> -
>  static void add_str(GString *s, const gchar *s1)
>  {
>  g_string_append_len(s, s1, strlen(s1) + 1);
> diff --git a/hw/ppc/spapr_numa.c b/hw/ppc/spapr_numa.c
> index b50796bbe3..261810525b 100644
> --- a/hw/ppc/spapr_numa.c
> +++ b/hw/ppc/spapr_numa.c
> @@ -19,6 +19,15 @@
>  /* Moved from hw/ppc/spapr_pci_nvlink2.c */
>  #define SPAPR_GPU_NUMA_ID   (cpu_to_be32(1))
>  
> +static bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr)
> +{
> +MachineState *machine = MACHINE(spapr);
> +SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
> +
> +return smc->pre_5_2_numa_associativity ||
> +   machine->numa_state->num_nodes <= 1;
> +}
> +
>  static bool spapr_numa_is_symmetrical(MachineState *ms)
>  {
>  int src, dst;
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index c27c7ce515..ccbeeca1de 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -851,7 +851,6 @@ int spapr_max_server_number(SpaprMachineState *spapr);
>  void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
>uint64_t pte0, uint64_t pte1);
>  void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered);
> -bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr);
>  
>  /* DRC callbacks. */
>  void spapr_core_release(DeviceState *dev);

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


signature.asc
Description: PGP signature


Re: [PATCH 3/7] ppc/pnv: Use skiboot addresses to load kernel and ramfs

2021-01-28 Thread David Gibson
On Thu, Jan 28, 2021 at 08:02:41AM +0100, Cédric Le Goater wrote:
> On 1/28/21 1:45 AM, Joel Stanley wrote:
> > On Tue, 26 Jan 2021 at 17:11, Cédric Le Goater  wrote:
> >>
> >> The current settings are useful to load large kernels (with debug) but
> >> it moves the initrd image in a memory region not protected by
> >> skiboot. If skiboot is compiled with DEBUG=1, memory poisoning will
> >> corrupt the initrd.
> >>
> >> Cc: Murilo Opsfelder Araujo 
> >> Signed-off-by: Cédric Le Goater 
> > 
> > Reviewed-by: Joel Stanley 
> > 
> > Note that the machine's default ram size will change with this patch:
> > 
> >  mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
> 
> Ah yes. I missed that.
> 
> > So we will go from 1.75GB to 768MB. Does anything break when the
> > machine has less than 1GB of ram?
> 
> There is a warning if the machine has less than 1GB but we should
> also change the default RAM size to 1G to be on the safe side.

I've merged the patch, but I'm happy to replace it with an updated
version, or fold in a change, if that helps.

> 
> Thanks,
> 
> C. 
> 
> > 
> >> ---
> >>
> >>  If we want to increase the kernel size limit as commit b45b56baeecd
> >>  ("ppc/pnv: increase kernel size limit to 256MiB") intented to do, I
> >>  think we should add a machine option.
> >>
> >>  hw/ppc/pnv.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> >> index 14fc9758a973..e500c2e2437e 100644
> >> --- a/hw/ppc/pnv.c
> >> +++ b/hw/ppc/pnv.c
> >> @@ -65,9 +65,9 @@
> >>  #define FW_MAX_SIZE (16 * MiB)
> >>
> >>  #define KERNEL_LOAD_ADDR0x2000
> >> -#define KERNEL_MAX_SIZE (256 * MiB)
> >> -#define INITRD_LOAD_ADDR0x6000
> >> -#define INITRD_MAX_SIZE (256 * MiB)
> >> +#define KERNEL_MAX_SIZE (128 * MiB)
> >> +#define INITRD_LOAD_ADDR0x2800
> >> +#define INITRD_MAX_SIZE (128 * MiB)
> >>
> >>  static const char *pnv_chip_core_typename(const PnvChip *o)
> >>  {
> >>
> >>
> 

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


signature.asc
Description: PGP signature


Re: [PATCH 4/7] ppc/pnv: Simplify pnv_bmc_create()

2021-01-28 Thread David Gibson
On Thu, Jan 28, 2021 at 01:04:28PM +0100, Greg Kurz wrote:
> On Thu, 28 Jan 2021 08:46:01 +0100
> Cédric Le Goater  wrote:
> 
> > On 1/28/21 1:46 AM, Joel Stanley wrote:
> > > On Tue, 26 Jan 2021 at 17:14, Cédric Le Goater  wrote:
> > >>
> > >> and reuse pnv_bmc_set_pnor() to share the setting of the PNOR.
> > >>
> > >> Signed-off-by: Cédric Le Goater 
> > >> ---
> > >>  hw/ppc/pnv_bmc.c | 7 +--
> > >>  1 file changed, 1 insertion(+), 6 deletions(-)
> > >>
> > >> diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
> > >> index 67ebb16c4d5f..86d16b493539 100644
> > >> --- a/hw/ppc/pnv_bmc.c
> > >> +++ b/hw/ppc/pnv_bmc.c
> > >> @@ -260,13 +260,8 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
> > >>  Object *obj;
> > >>
> > >>  obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
> > >> -object_ref(OBJECT(pnor));
> > >> -object_property_add_const_link(obj, "pnor", OBJECT(pnor));
> > > 
> > > I assume it's ok to move the link set to after the realise of the BMC 
> > > object?
> >  
> > 
> > When 2 objects need to be linked, one has to be realized first. 
> 
> Realize isn't a QOM concept in the first place...
> 
> > I suppose this is why it is allowed but I am not expert in that area. 
> > 
> 
> ... so no surprise object_property_add_const_link() doesn't care
> about it.
> 
> > Greg  ?
> > 
> 
> What is important though is that a property with a given name
> can only be added *once* to an object during its lifetime.
> Doing the contrary is a bug and QEMU aborts. So, with this
> in mind, it seems to me that adding QOM properties to a
> device object should only be done from some init path
> that is only called once.
> 
> > That was the case already when defining a "ipmi-bmc-sim" device on the 
> > command line. 
> > 
> 
> Yeah and the property is added during machine reset... which
> is typically a path that can be taken several times during
> the machine lifetime. The potential crash is avoided because
> pnv_reset() doesn't call pnv_bmc_set_pnor() if pnv->bmc is
> already set, but this is a fragile workaround...

Oof, yeah.  In general we should avoid creating or realizing objects
at machine reset time.  There might be a few exceptions, but they're
rare.

> A QOM link doesn't look like the correct way to model the BMC
> accesses to the PNOR. Since the only user is hiomap_cmd(),
> it seems you could reach the same result with a pointer to
> the PNOR object being passed to ipmi_sim_register_netfn()
> and later passed to hiomap_cmd().
> 
> > C. 
> > 
> > 
> > >>  qdev_realize(DEVICE(obj), NULL, &error_fatal);
> > >> -
> > >> -/* Install the HIOMAP protocol handlers to access the PNOR */
> > >> -ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(obj), IPMI_NETFN_OEM,
> > >> -&hiomap_netfn);
> > >> +pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);
> > >>
> > >>  return IPMI_BMC(obj);
> > >>  }
> > >>
> > >>
> > 
> 

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


signature.asc
Description: PGP signature


Re: [PATCH v14 15/22] cpu: tcg_ops: move to tcg-cpu-ops.h, keep a pointer in CPUClass

2021-01-28 Thread Richard Henderson
On 1/27/21 11:28 PM, Claudio Fontana wrote:
> +/*
> + * NB: this should be covered by CONFIG_TCG, but it is unsafe to do it 
> here,
> + * as this header is included by both ss_specific and ss_common code,
> + * leading to potential differences in the data structure between 
> modules.
> + * We could always keep it last, but it seems safer to just leave this
> + * pointer NULL for non-TCG.
> + */
> +struct TCGCPUOps *tcg_ops;

Sorry, I'm going to unqueue the patch set.

I first thought this was fixing up something done already, fixing an existing 
bug.

But it's something done in patch 1, and therefore the patch set needs to be
re-worked to use this pointer to begin, for the exact reasons detailed above.
Otherwise it would appear this breaks bisection.


r~



Re: [PATCH v14 00/22] i386 cleanup PART 2

2021-01-28 Thread Richard Henderson
On 1/27/21 11:27 PM, Claudio Fontana wrote:
> Claudio Fontana (17):
>   target/riscv: remove CONFIG_TCG, as it is always TCG
>   accel/tcg: split TCG-only code from cpu_exec_realizefn
>   target/arm: do not use cc->do_interrupt for KVM directly
>   cpu: move cc->do_interrupt to tcg_ops
>   cpu: move cc->transaction_failed to tcg_ops
>   cpu: move do_unaligned_access to tcg_ops
>   physmem: make watchpoint checking code TCG-only
>   cpu: move adjust_watchpoint_address to tcg_ops
>   cpu: move debug_check_watchpoint to tcg_ops
>   cpu: tcg_ops: move to tcg-cpu-ops.h, keep a pointer in CPUClass
>   accel: extend AccelState and AccelClass to user-mode
>   accel: replace struct CpusAccel with AccelOpsClass
>   accel: introduce AccelCPUClass extending CPUClass
>   i386: split cpu accelerators from cpu.c, using AccelCPUClass
>   cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn
>   hw/core/cpu: call qemu_init_vcpu in cpu_common_realizefn
>   accel: introduce new accessor functions
> 
> Eduardo Habkost (5):
>   cpu: Introduce TCGCpuOperations struct
>   cpu: Move synchronize_from_tb() to tcg_ops
>   cpu: Move cpu_exec_* to tcg_ops
>   cpu: Move tlb_fill to tcg_ops
>   cpu: Move debug_excp_handler to tcg_ops

I'm going to queue the first 18 patches to tcg-next.

With the exception of the minor target/arm do_interrupt change, they clearly
fall into the tcg bucket.

Patch 19, split i386 accelerators, needs more i386 review, and on a host
accelerator I can't test.  If I drop that, then patch 20 doesn't apply, so I'll
let the rest of the series go.  But at least it'll reduce the size of your
patch load.


r~



Re: [PATCH v14 18/22] accel: introduce AccelCPUClass extending CPUClass

2021-01-28 Thread Richard Henderson
On 1/28/21 6:29 AM, Philippe Mathieu-Daudé wrote:
> On 1/28/21 5:08 PM, Alex Bennée wrote:
>>
>> Claudio Fontana  writes:
>>
>>> On 1/28/21 2:03 PM, Philippe Mathieu-Daudé wrote:
 On 1/28/21 10:28 AM, Claudio Fontana wrote:
>> 
> +
> +#define TYPE_ACCEL_CPU "accel-" CPU_RESOLVING_TYPE
> +#define ACCEL_CPU_NAME(name) (name "-" TYPE_ACCEL_CPU)
> +typedef struct AccelCPUClass AccelCPUClass;
> +DECLARE_CLASS_CHECKERS(AccelCPUClass, ACCEL_CPU, TYPE_ACCEL_CPU)
> +
> +typedef struct AccelCPUClass {
> +/*< private >*/
> +ObjectClass parent_class;
> +/*< public >*/
> +
> +void (*cpu_class_init)(CPUClass *cc);
> +void (*cpu_instance_init)(CPUState *cpu);
> +void (*cpu_realizefn)(CPUState *cpu, Error **errp);

 If we want callers to check errp, better have the prototype return
 a boolean.
>>>
>>> Good point, the whole errp thing is worth revisiting in the series,
>>> there are many cases (which are basically reproduced in the refactoring 
>>> from existing code),
>>> where errp is passed but is really unused.
>>>
>>> I am constantly internally debating whether to remove the parameter 
>>> altogether, or to keep it in there.
>>>
>>> What would you suggest?
>>
>> I think it really depends on if we can expect the realizefn to usefully
>> return an error message that can be read and understood by the user. I
>> guess this comes down to how much user config is going to be checked at
>> the point we realize the CPU?
> 
> cpu_realize() is were various feature checks are, isn't it?
> 
>   -cpu mycpu,feat1=on,feat2=off
>   CPU 'mycpu' can not disable feature 'feat2' because of REASON.

Yes.  And while changing the return type of realize is probably a good idea, it
should be a separate patch.


r~



Re: [PATCH v4 00/23] target-arm: Implement ARMv8.5-MemTag, user mode

2021-01-28 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20210128224141.638790-1-richard.hender...@linaro.org/



Hi,

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

Type: series
Message-id: 20210128224141.638790-1-richard.hender...@linaro.org
Subject: [PATCH v4 00/23] target-arm: Implement ARMv8.5-MemTag, user mode

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/20210128224141.638790-1-richard.hender...@linaro.org -> 
patchew/20210128224141.638790-1-richard.hender...@linaro.org
Switched to a new branch 'test'
6c36cfa tests/tcg/aarch64: Add mte smoke tests
93868dc target/arm: Enable MTE for user-only
89c67bb target/arm: Add allocation tag storage for user mode
9e55bce linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
662f309 linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
405c8bc linux-user/aarch64: Pass syndrome to EXC_*_ABORT
852c847 target/arm: Split out syndrome.h from internals.h
aaea091 linux-user/aarch64: Implement PROT_MTE
40b5989 linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
ffe7c9e target/arm: Use the proper TBI settings for linux-user
749b207 target/arm: Improve gen_top_byte_ignore
4b25f7f linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
d905335 exec: Add support for TARGET_TAGGED_ADDRESSES
0757b19 linux-user: Fix guest_addr_valid vs reserved_va
f2294c5 linux-user: Do not use guest_addr_valid for h2g_valid
67730ef bsd-user: Tidy VERIFY_READ/VERIFY_WRITE
f4cd54c linux-user: Tidy VERIFY_READ/VERIFY_WRITE
6cf3801 linux-user: Check for overflow in access_ok
ce479f6 exec: Improve types for guest_addr_valid
99a6c83 exec: Use uintptr_t in cpu_ldst.h
b43639c exec: Use uintptr_t for guest_base
2c72fdf linux-user: Introduce PAGE_ANON
28506f41 tcg: Introduce target-specific page data for user-only

=== OUTPUT BEGIN ===
1/23 Checking commit 28506f418a43 (tcg: Introduce target-specific page data for 
user-only)
2/23 Checking commit 2c72fdf28de9 (linux-user: Introduce PAGE_ANON)
3/23 Checking commit b43639c7a6f9 (exec: Use uintptr_t for guest_base)
4/23 Checking commit 99a6c8388583 (exec: Use uintptr_t in cpu_ldst.h)
5/23 Checking commit ce479f673a66 (exec: Improve types for guest_addr_valid)
6/23 Checking commit 6cf38016de1c (linux-user: Check for overflow in access_ok)
7/23 Checking commit f4cd54ce0606 (linux-user: Tidy VERIFY_READ/VERIFY_WRITE)
8/23 Checking commit 67730ef0214d (bsd-user: Tidy VERIFY_READ/VERIFY_WRITE)
9/23 Checking commit f2294c5aeb95 (linux-user: Do not use guest_addr_valid for 
h2g_valid)
10/23 Checking commit 0757b19036b7 (linux-user: Fix guest_addr_valid vs 
reserved_va)
11/23 Checking commit d905335fb7aa (exec: Add support for 
TARGET_TAGGED_ADDRESSES)
12/23 Checking commit 4b25f7f499e3 (linux-user/aarch64: Implement 
PR_TAGGED_ADDR_ENABLE)
13/23 Checking commit 749b207a98e2 (target/arm: Improve gen_top_byte_ignore)
14/23 Checking commit ffe7c9e590c3 (target/arm: Use the proper TBI settings for 
linux-user)
15/23 Checking commit 40b598970ac8 (linux-user/aarch64: Implement PR_MTE_TCF 
and PR_MTE_TAG)
16/23 Checking commit aaea091c2349 (linux-user/aarch64: Implement PROT_MTE)
17/23 Checking commit 852c84714792 (target/arm: Split out syndrome.h from 
internals.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#281: 
new file mode 100644

total: 0 errors, 1 warnings, 530 lines checked

Patch 17/23 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
18/23 Checking commit 405c8bc94002 (linux-user/aarch64: Pass syndrome to 
EXC_*_ABORT)
19/23 Checking commit 662f30915b17 (linux-user/aarch64: Signal SEGV_MTESERR for 
sync tag check fault)
20/23 Checking commit 9e55bcec5069 (linux-user/aarch64: Signal SEGV_MTEAERR for 
async tag check error)
21/23 Checking commit 89c67bb0643e (target/arm: Add allocation tag storage for 
user mode)
22/23 Checking commit 93868dc63114 (target/arm: Enable MTE for user-only)
23/23 Checking commit 6c36cfabbd96 (tests/tcg/aarch64: Add mte smoke tests)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#37: 
new file mode 100644

ERROR: trailing statements should be on next line
#176: FILE: tests/tcg/aarch64/mte-3.c:50:
+while (1);

ERROR: braces {} are necessary for all arms of this statement
#176: FILE: tests/tcg/aarch64/mte-3.c:50:
+while (1);
[...]

ERROR: use qemu_real_host_page_size instead of getpagesize()
#214: FILE: tests/tcg/aarch64/mte-4.c:31:
+size_t size = getpagesize() * 4;

total: 3 errors, 1 warnings, 251 lines checked

Patch 23/23 has style problems, please review.  If any of these errors
are

Re: [PATCH v14 04/22] cpu: Move synchronize_from_tb() to tcg_ops

2021-01-28 Thread Richard Henderson
On 1/28/21 8:58 AM, Alex Bennée wrote:
> Looking at the function here I wonder if we should be worried about the
> thumb state? Peter?
> 
> static void arm_cpu_set_pc(CPUState *cs, vaddr value)
> {
> ARMCPU *cpu = ARM_CPU(cs);
> CPUARMState *env = &cpu->env;
> 
> if (is_a64(env)) {
> env->pc = value;
> env->thumb = 0;
> } else {
> env->regs[15] = value & ~1;
> env->thumb = value & 1;
> }
> }

Plausible.  You could possibly test this via gdbstub, as there are not many
other users.  I think it would be of the form:

(gdb) call foo()

where foo is a thumb function.

> #ifdef CONFIG_TCG
> void arm_cpu_synchronize_from_tb(CPUState *cs,
>  const TranslationBlock *tb)
> {
> ARMCPU *cpu = ARM_CPU(cs);
> CPUARMState *env = &cpu->env;
> 
> /*
>  * It's OK to look at env for the current mode here, because it's
>  * never possible for an AArch64 TB to chain to an AArch32 TB.
>  */
> if (is_a64(env)) {
> env->pc = tb->pc;
> } else {
> env->regs[15] = tb->pc;
> }
> }
> #endif /* CONFIG_TCG */

This function need only handle any state that is "deferred" across goto_tb.
This is almost always simply the pc, e.g.

if (use_goto_tb(s, dest)) {
tcg_gen_goto_tb(n);
gen_set_pc_im(s, dest);
tcg_gen_exit_tb(s->base.tb, n);

A few targets do a bit more than that, especially vs delayed branches, but ARM
does not.

But there should be no thumb state that ought to be updated here.


r~



[PATCH v4 22/23] target/arm: Enable MTE for user-only

2021-01-28 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index db81a12418..43933550c3 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -204,6 +204,21 @@ static void arm_cpu_reset(DeviceState *dev)
  * Note that this must match useronly_clean_ptr.
  */
 env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
+
+/* Enable MTE */
+if (cpu_isar_feature(aa64_mte, cpu)) {
+/* Enable tag access, but leave TCF0 as No Effect (0). */
+env->cp15.sctlr_el[1] |= SCTLR_ATA0;
+/*
+ * Exclude all tags, so that tag 0 is always used.
+ * This corresponds to Linux current->thread.gcr_incl = 0.
+ *
+ * Set RRND, so that helper_irg() will generate a seed later.
+ * Here in cpu_reset(), the crypto subsystem has not yet been
+ * initialized.
+ */
+env->cp15.gcr_el1 = 0x1;
+}
 #else
 /* Reset into the highest available EL */
 if (arm_feature(env, ARM_FEATURE_EL3)) {
-- 
2.25.1




[PATCH v4 20/23] linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error

2021-01-28 Thread Richard Henderson
The real kernel collects _TIF_MTE_ASYNC_FAULT into the current thread's
state on any kernel entry (interrupt, exception etc), and then delivers
the signal in advance of resuming the thread.

This means that while the signal won't be delivered immediately, it will
not be delayed forever -- at minimum it will be delivered after the next
clock interrupt.

We don't have a clock interrupt in linux-user, so we issue a cpu_kick
to signal a return to the main loop at the end of the current TB.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_signal.h |  1 +
 linux-user/aarch64/cpu_loop.c  | 11 +++
 target/arm/mte_helper.c| 10 ++
 3 files changed, 22 insertions(+)

diff --git a/linux-user/aarch64/target_signal.h 
b/linux-user/aarch64/target_signal.h
index 777fb667fe..18013e1b23 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -21,6 +21,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_SEGV_MTEAERR  8  /* Asynchronous ARM MTE error */
 #define TARGET_SEGV_MTESERR  9  /* Synchronous ARM MTE exception */
 
 #define TARGET_ARCH_HAS_SETUP_FRAME
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index b6a2e65593..7c42f65706 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -164,6 +164,17 @@ void cpu_loop(CPUARMState *env)
 EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", 
trapnr);
 abort();
 }
+
+/* Check for MTE asynchronous faults */
+if (unlikely(env->cp15.tfsr_el[0])) {
+env->cp15.tfsr_el[0] = 0;
+info.si_signo = TARGET_SIGSEGV;
+info.si_errno = 0;
+info._sifields._sigfault._addr = 0;
+info.si_code = TARGET_SEGV_MTEAERR;
+queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+}
+
 process_pending_signals(env);
 /* Exception return on AArch64 always clears the exclusive monitor,
  * so any return to running guest code implies this.
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 153bd1e9df..d55f8d1e1e 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -565,6 +565,16 @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
 select = 0;
 }
 env->cp15.tfsr_el[el] |= 1 << select;
+#ifdef CONFIG_USER_ONLY
+/*
+ * Stand in for a timer irq, setting _TIF_MTE_ASYNC_FAULT,
+ * which then sends a SIGSEGV when the thread is next scheduled.
+ * This cpu will return to the main loop at the end of the TB,
+ * which is rather sooner than "normal".  But the alternative
+ * is waiting until the next syscall.
+ */
+qemu_cpu_kick(env_cpu(env));
+#endif
 break;
 
 default:
-- 
2.25.1




[PATCH v4 23/23] tests/tcg/aarch64: Add mte smoke tests

2021-01-28 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tests/tcg/aarch64/mte.h   | 60 +++
 tests/tcg/aarch64/mte-1.c | 28 +++
 tests/tcg/aarch64/mte-2.c | 45 +++
 tests/tcg/aarch64/mte-3.c | 51 ++
 tests/tcg/aarch64/mte-4.c | 45 +++
 tests/tcg/aarch64/Makefile.target |  6 
 tests/tcg/configure.sh|  4 +++
 7 files changed, 239 insertions(+)
 create mode 100644 tests/tcg/aarch64/mte.h
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c
 create mode 100644 tests/tcg/aarch64/mte-3.c
 create mode 100644 tests/tcg/aarch64/mte-4.c

diff --git a/tests/tcg/aarch64/mte.h b/tests/tcg/aarch64/mte.h
new file mode 100644
index 00..141cef522c
--- /dev/null
+++ b/tests/tcg/aarch64/mte.h
@@ -0,0 +1,60 @@
+/*
+ * Linux kernel fallback API definitions for MTE and test helpers.
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef PR_SET_TAGGED_ADDR_CTRL
+# define PR_SET_TAGGED_ADDR_CTRL  55
+#endif
+#ifndef PR_TAGGED_ADDR_ENABLE
+# define PR_TAGGED_ADDR_ENABLE(1UL << 0)
+#endif
+#ifndef PR_MTE_TCF_SHIFT
+# define PR_MTE_TCF_SHIFT 1
+# define PR_MTE_TCF_NONE  (0UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_SYNC  (1UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
+# define PR_MTE_TAG_SHIFT 3
+#endif
+
+#ifndef PROT_MTE
+# define PROT_MTE 0x20
+#endif
+
+#ifndef SEGV_MTEAERR
+# define SEGV_MTEAERR8
+# define SEGV_MTESERR9
+#endif
+
+static void enable_mte(int tcf)
+{
+int r = prctl(PR_SET_TAGGED_ADDR_CTRL,
+  PR_TAGGED_ADDR_ENABLE | tcf | (0xfffe << PR_MTE_TAG_SHIFT),
+  0, 0, 0);
+if (r < 0) {
+perror("PR_SET_TAGGED_ADDR_CTRL");
+exit(2);
+}
+}
+
+static void *alloc_mte_mem(size_t size)
+{
+void *p = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_MTE,
+   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+if (p == MAP_FAILED) {
+perror("mmap PROT_MTE");
+exit(2);
+}
+return p;
+}
diff --git a/tests/tcg/aarch64/mte-1.c b/tests/tcg/aarch64/mte-1.c
new file mode 100644
index 00..88dcd617ad
--- /dev/null
+++ b/tests/tcg/aarch64/mte-1.c
@@ -0,0 +1,28 @@
+/*
+ * Memory tagging, basic pass cases.
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "mte.h"
+
+int main(int ac, char **av)
+{
+int *p0, *p1, *p2;
+long c;
+
+enable_mte(PR_MTE_TCF_NONE);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(1));
+assert(p1 != p0);
+asm("subp %0,%1,%2" : "=r"(c) : "r"(p0), "r"(p1));
+assert(c == 0);
+
+asm("stg %0, [%0]" : : "r"(p1));
+asm("ldg %0, [%1]" : "=r"(p2) : "r"(p0), "0"(p0));
+assert(p1 == p2);
+
+return 0;
+}
diff --git a/tests/tcg/aarch64/mte-2.c b/tests/tcg/aarch64/mte-2.c
new file mode 100644
index 00..a62278276a
--- /dev/null
+++ b/tests/tcg/aarch64/mte-2.c
@@ -0,0 +1,45 @@
+/*
+ * Memory tagging, basic fail cases, synchronous signals.
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "mte.h"
+
+void pass(int sig, siginfo_t *info, void *uc)
+{
+assert(info->si_code == SEGV_MTESERR);
+exit(0);
+}
+
+int main(int ac, char **av)
+{
+struct sigaction sa;
+int *p0, *p1, *p2;
+long excl = 1;
+
+enable_mte(PR_MTE_TCF_SYNC);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+/* Create two differently tagged pointers.  */
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
+asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
+assert(excl != 1);
+asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
+assert(p1 != p2);
+
+/* Store the tag from the first pointer.  */
+asm("stg %0, [%0]" : : "r"(p1));
+
+*p1 = 0;
+
+memset(&sa, 0, sizeof(sa));
+sa.sa_sigaction = pass;
+sa.sa_flags = SA_SIGINFO;
+sigaction(SIGSEGV, &sa, NULL);
+
+*p2 = 0;
+
+abort();
+}
diff --git a/tests/tcg/aarch64/mte-3.c b/tests/tcg/aarch64/mte-3.c
new file mode 100644
index 00..424ea685c2
--- /dev/null
+++ b/tests/tcg/aarch64/mte-3.c
@@ -0,0 +1,51 @@
+/*
+ * Memory tagging, basic fail cases, asynchronous signals.
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "mte.h"
+
+void pass(int sig, siginfo_t *info, void *uc)
+{
+assert(info->si_code == SEGV_MTEAERR);
+exit(0);
+}
+
+int main(int ac, char **av)
+{
+struct sigaction sa;
+long *p0, *p1, *p2;
+long excl = 1;
+
+enable_mte(PR_MTE_TCF_ASYNC);
+p0 = alloc_mte_mem(sizeof(*p0));
+
+/* Create two differently tagged pointers.  */
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(exc

[PATCH v4 11/23] exec: Add support for TARGET_TAGGED_ADDRESSES

2021-01-28 Thread Richard Henderson
The AArch64 Linux ABI has always enabled TBI, but has historically
required that pointer tags be removed before a syscall.  This has
changed in the lead-up to ARMv8.5-MTE, in a way that affects the
ABI generically and not specifically to MTE.

This patch allows the target to indicate that (1) there are tags
and (2) whether or not they should be taken into account at the
syscall level.

Adjust g2h, guest_addr_valid, and guest_range_valid to ignore
pointer tags, similar to how TIF_TAGGED_ADDR alters __range_ok
in the arm64 kernel source.

The prctl syscall is not not yet updated, so this change by itself
has no visible effect.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index e62f4fba00..1df9b93e59 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -69,17 +69,31 @@ typedef uint64_t abi_ptr;
 #define TARGET_ABI_FMT_ptr "%"PRIx64
 #endif
 
+static inline abi_ptr untagged_addr(abi_ptr x)
+{
+#ifdef TARGET_TAGGED_ADDRESSES
+if (current_cpu) {
+return cpu_untagged_addr(current_cpu, x);
+}
+#endif
+return x;
+}
+
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
-#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
+static inline void *g2h(abi_ulong x)
+{
+return (void *)((uintptr_t)untagged_addr(x) + guest_base);
+}
 
 static inline bool guest_addr_valid(abi_ulong x)
 {
-return x <= GUEST_ADDR_MAX;
+return untagged_addr(x) <= GUEST_ADDR_MAX;
 }
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
-return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
+return len - 1 <= GUEST_ADDR_MAX &&
+   untagged_addr(start) <= GUEST_ADDR_MAX - len + 1;
 }
 
 #define h2g_valid(x) \
-- 
2.25.1




[PATCH v4 18/23] linux-user/aarch64: Pass syndrome to EXC_*_ABORT

2021-01-28 Thread Richard Henderson
A proper syndrome is required to fill in the proper si_code.
Use page_get_flags to determine permission vs translation for user-only.

Signed-off-by: Richard Henderson 
---
v3: Use syndrome.h, arm_deliver_fault.
---
 linux-user/aarch64/cpu_loop.c | 24 +---
 target/arm/tlb_helper.c   | 15 +--
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 42b9c15f53..4e43906e66 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -23,6 +23,7 @@
 #include "cpu_loop-common.h"
 #include "qemu/guest-random.h"
 #include "hw/semihosting/common-semi.h"
+#include "target/arm/syndrome.h"
 
 #define get_user_code_u32(x, gaddr, env)\
 ({ abi_long __r = get_user_u32((x), (gaddr));   \
@@ -76,7 +77,7 @@
 void cpu_loop(CPUARMState *env)
 {
 CPUState *cs = env_cpu(env);
-int trapnr;
+int trapnr, ec, fsc;
 abi_long ret;
 target_siginfo_t info;
 
@@ -117,9 +118,26 @@ void cpu_loop(CPUARMState *env)
 case EXCP_DATA_ABORT:
 info.si_signo = TARGET_SIGSEGV;
 info.si_errno = 0;
-/* XXX: check env->error_code */
-info.si_code = TARGET_SEGV_MAPERR;
 info._sifields._sigfault._addr = env->exception.vaddress;
+
+/* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
+ec = syn_get_ec(env->exception.syndrome);
+assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
+
+/* Both EC have the same format for FSC, or close enough. */
+fsc = extract32(env->exception.syndrome, 0, 6);
+switch (fsc) {
+case 0x04 ... 0x07: /* Translation fault, level {0-3} */
+info.si_code = TARGET_SEGV_MAPERR;
+break;
+case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
+case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
+info.si_code = TARGET_SEGV_ACCERR;
+break;
+default:
+g_assert_not_reached();
+}
+
 queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 break;
 case EXCP_DEBUG:
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
index df85079d9f..9609333cbd 100644
--- a/target/arm/tlb_helper.c
+++ b/target/arm/tlb_helper.c
@@ -154,21 +154,24 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
   bool probe, uintptr_t retaddr)
 {
 ARMCPU *cpu = ARM_CPU(cs);
+ARMMMUFaultInfo fi = {};
 
 #ifdef CONFIG_USER_ONLY
-cpu->env.exception.vaddress = address;
-if (access_type == MMU_INST_FETCH) {
-cs->exception_index = EXCP_PREFETCH_ABORT;
+int flags = page_get_flags(useronly_clean_ptr(address));
+if (flags & PAGE_VALID) {
+fi.type = ARMFault_Permission;
 } else {
-cs->exception_index = EXCP_DATA_ABORT;
+fi.type = ARMFault_Translation;
 }
-cpu_loop_exit_restore(cs, retaddr);
+
+/* now we have a real cpu fault */
+cpu_restore_state(cs, retaddr, true);
+arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
 #else
 hwaddr phys_addr;
 target_ulong page_size;
 int prot, ret;
 MemTxAttrs attrs = {};
-ARMMMUFaultInfo fi = {};
 ARMCacheAttrs cacheattrs = {};
 
 /*
-- 
2.25.1




[PATCH v4 19/23] linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault

2021-01-28 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_signal.h | 2 ++
 linux-user/aarch64/cpu_loop.c  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/linux-user/aarch64/target_signal.h 
b/linux-user/aarch64/target_signal.h
index ddd73169f0..777fb667fe 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -21,5 +21,7 @@ typedef struct target_sigaltstack {
 
 #include "../generic/signal.h"
 
+#define TARGET_SEGV_MTESERR  9  /* Synchronous ARM MTE exception */
+
 #define TARGET_ARCH_HAS_SETUP_FRAME
 #endif /* AARCH64_TARGET_SIGNAL_H */
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 4e43906e66..b6a2e65593 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -134,6 +134,9 @@ void cpu_loop(CPUARMState *env)
 case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
 info.si_code = TARGET_SEGV_ACCERR;
 break;
+case 0x11: /* Synchronous Tag Check Fault */
+info.si_code = TARGET_SEGV_MTESERR;
+break;
 default:
 g_assert_not_reached();
 }
-- 
2.25.1




[PATCH v4 17/23] target/arm: Split out syndrome.h from internals.h

2021-01-28 Thread Richard Henderson
Move everything related to syndromes to a new file,
which can be shared with linux-user.

Signed-off-by: Richard Henderson 
---
 target/arm/internals.h | 245 +---
 target/arm/syndrome.h  | 273 +
 2 files changed, 274 insertions(+), 244 deletions(-)
 create mode 100644 target/arm/syndrome.h

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6efe0c303e..5a4a742eba 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -26,6 +26,7 @@
 #define TARGET_ARM_INTERNALS_H
 
 #include "hw/registerfields.h"
+#include "syndrome.h"
 
 /* register banks for CPU modes */
 #define BANK_USRSYS 0
@@ -256,250 +257,6 @@ static inline bool extended_addresses_enabled(CPUARMState 
*env)
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE));
 }
 
-/* Valid Syndrome Register EC field values */
-enum arm_exception_class {
-EC_UNCATEGORIZED  = 0x00,
-EC_WFX_TRAP   = 0x01,
-EC_CP15RTTRAP = 0x03,
-EC_CP15RRTTRAP= 0x04,
-EC_CP14RTTRAP = 0x05,
-EC_CP14DTTRAP = 0x06,
-EC_ADVSIMDFPACCESSTRAP= 0x07,
-EC_FPIDTRAP   = 0x08,
-EC_PACTRAP= 0x09,
-EC_CP14RRTTRAP= 0x0c,
-EC_BTITRAP= 0x0d,
-EC_ILLEGALSTATE   = 0x0e,
-EC_AA32_SVC   = 0x11,
-EC_AA32_HVC   = 0x12,
-EC_AA32_SMC   = 0x13,
-EC_AA64_SVC   = 0x15,
-EC_AA64_HVC   = 0x16,
-EC_AA64_SMC   = 0x17,
-EC_SYSTEMREGISTERTRAP = 0x18,
-EC_SVEACCESSTRAP  = 0x19,
-EC_INSNABORT  = 0x20,
-EC_INSNABORT_SAME_EL  = 0x21,
-EC_PCALIGNMENT= 0x22,
-EC_DATAABORT  = 0x24,
-EC_DATAABORT_SAME_EL  = 0x25,
-EC_SPALIGNMENT= 0x26,
-EC_AA32_FPTRAP= 0x28,
-EC_AA64_FPTRAP= 0x2c,
-EC_SERROR = 0x2f,
-EC_BREAKPOINT = 0x30,
-EC_BREAKPOINT_SAME_EL = 0x31,
-EC_SOFTWARESTEP   = 0x32,
-EC_SOFTWARESTEP_SAME_EL   = 0x33,
-EC_WATCHPOINT = 0x34,
-EC_WATCHPOINT_SAME_EL = 0x35,
-EC_AA32_BKPT  = 0x38,
-EC_VECTORCATCH= 0x3a,
-EC_AA64_BKPT  = 0x3c,
-};
-
-#define ARM_EL_EC_SHIFT 26
-#define ARM_EL_IL_SHIFT 25
-#define ARM_EL_ISV_SHIFT 24
-#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
-#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
-
-static inline uint32_t syn_get_ec(uint32_t syn)
-{
-return syn >> ARM_EL_EC_SHIFT;
-}
-
-/* Utility functions for constructing various kinds of syndrome value.
- * Note that in general we follow the AArch64 syndrome values; in a
- * few cases the value in HSR for exceptions taken to AArch32 Hyp
- * mode differs slightly, and we fix this up when populating HSR in
- * arm_cpu_do_interrupt_aarch32_hyp().
- * The exception is FP/SIMD access traps -- these report extra information
- * when taking an exception to AArch32. For those we include the extra coproc
- * and TA fields, and mask them out when taking the exception to AArch64.
- */
-static inline uint32_t syn_uncategorized(void)
-{
-return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
-}
-
-static inline uint32_t syn_aa64_svc(uint32_t imm16)
-{
-return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa64_hvc(uint32_t imm16)
-{
-return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa64_smc(uint32_t imm16)
-{
-return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
-{
-return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0x)
-| (is_16bit ? 0 : ARM_EL_IL);
-}
-
-static inline uint32_t syn_aa32_hvc(uint32_t imm16)
-{
-return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_smc(void)
-{
-return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
-}
-
-static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
-{
-return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0x);
-}
-
-static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
-{
-return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0x)
-| (is_16bit ? 0 : ARM_EL_IL);
-}
-
-static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
-   int crn, int crm, int rt,
-   int isread)
-{
-return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
-| (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
-| (crm << 1) | isread;
-}
-
-static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
-  

[PATCH v4 06/23] linux-user: Check for overflow in access_ok

2021-01-28 Thread Richard Henderson
Verify that addr + size - 1 does not wrap around.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 17aa992165..441ba6a78b 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -491,12 +491,19 @@ extern unsigned long guest_stack_size;
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1 /* implies read access */
 
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
-return guest_addr_valid(addr) &&
-   (size == 0 || guest_addr_valid(addr + size - 1)) &&
-   page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | 
PAGE_WRITE)) == 0;
+if (!guest_addr_valid(addr)) {
+return false;
+}
+if (size != 0 &&
+(addr + size - 1 < addr ||
+ !guest_addr_valid(addr + size - 1))) {
+return false;
+}
+return page_check_range((target_ulong)addr, size,
+(type == VERIFY_READ) ? PAGE_READ :
+(PAGE_READ | PAGE_WRITE)) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access.
-- 
2.25.1




[PATCH v4 14/23] target/arm: Use the proper TBI settings for linux-user

2021-01-28 Thread Richard Henderson
We were fudging TBI1 enabled to speed up the generated code.
Now that we've improved the code generation, remove this.
Also, tidy the comment to reflect the current code.

The pauth test was testing a kernel address (-1) and making
incorrect assumptions about TBI1; stick to userland addresses.

Signed-off-by: Richard Henderson 
---
 target/arm/internals.h  |  4 ++--
 target/arm/cpu.c| 10 +++---
 tests/tcg/aarch64/pauth-2.c |  1 -
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 853fa88fd6..6efe0c303e 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1413,9 +1413,9 @@ static inline bool tcma_check(uint32_t desc, int bit55, 
int ptr_tag)
  */
 static inline uint64_t useronly_clean_ptr(uint64_t ptr)
 {
-/* TBI is known to be enabled. */
 #ifdef CONFIG_USER_ONLY
-ptr = sextract64(ptr, 0, 56);
+/* TBI0 is known to be enabled, while TBI1 is disabled. */
+ptr &= sextract64(ptr, 0, 56);
 #endif
 return ptr;
 }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 40142ac141..db81a12418 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -200,14 +200,10 @@ static void arm_cpu_reset(DeviceState *dev)
 env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
 }
 /*
- * Enable TBI0 and TBI1.  While the real kernel only enables TBI0,
- * turning on both here will produce smaller code and otherwise
- * make no difference to the user-level emulation.
- *
- * In sve_probe_page, we assume that this is set.
- * Do not modify this without other changes.
+ * Enable TBI0 but not TBI1.
+ * Note that this must match useronly_clean_ptr.
  */
-env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
+env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
 #else
 /* Reset into the highest available EL */
 if (arm_feature(env, ARM_FEATURE_EL3)) {
diff --git a/tests/tcg/aarch64/pauth-2.c b/tests/tcg/aarch64/pauth-2.c
index 9bba0beb63..978652ede3 100644
--- a/tests/tcg/aarch64/pauth-2.c
+++ b/tests/tcg/aarch64/pauth-2.c
@@ -53,7 +53,6 @@ void do_test(uint64_t value)
 int main()
 {
 do_test(0);
-do_test(-1);
 do_test(0xda004acedeadbeefull);
 return 0;
 }
-- 
2.25.1




[PATCH v4 05/23] exec: Improve types for guest_addr_valid

2021-01-28 Thread Richard Henderson
Return bool not int; pass abi_ulong not 'unsigned long'.
All callers use abi_ulong already, so the change in type
has no effect.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 3f9063aade..5e8878ee9b 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -79,7 +79,7 @@ typedef uint64_t abi_ptr;
 #endif
 #define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
-static inline int guest_range_valid(unsigned long start, unsigned long len)
+static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
 }
-- 
2.25.1




[PATCH v4 13/23] target/arm: Improve gen_top_byte_ignore

2021-01-28 Thread Richard Henderson
Use simple arithmetic instead of a conditional
move when tbi0 != tbi1.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index ffc060e5d7..3ec0dc17d8 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -183,17 +183,20 @@ static void gen_top_byte_ignore(DisasContext *s, TCGv_i64 
dst,
 /* Sign-extend from bit 55.  */
 tcg_gen_sextract_i64(dst, src, 0, 56);
 
-if (tbi != 3) {
-TCGv_i64 tcg_zero = tcg_const_i64(0);
-
-/*
- * The two TBI bits differ.
- * If tbi0, then !tbi1: only use the extension if positive.
- * if !tbi0, then tbi1: only use the extension if negative.
- */
-tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
-dst, dst, tcg_zero, dst, src);
-tcg_temp_free_i64(tcg_zero);
+switch (tbi) {
+case 1:
+/* tbi0 but !tbi1: only use the extension if positive */
+tcg_gen_and_i64(dst, dst, src);
+break;
+case 2:
+/* !tbi0 but tbi1: only use the extension if negative */
+tcg_gen_or_i64(dst, dst, src);
+break;
+case 3:
+/* tbi0 and tbi1: always use the extension */
+break;
+default:
+g_assert_not_reached();
 }
 }
 }
-- 
2.25.1




[PATCH v4 15/23] linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG

2021-01-28 Thread Richard Henderson
These prctl fields are required for the function of MTE.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  9 ++
 linux-user/syscall.c| 43 +
 2 files changed, 52 insertions(+)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index 820601dfcc..76f6c3391d 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -33,5 +33,14 @@ struct target_pt_regs {
 #define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
 #define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
 # define TARGET_PR_TAGGED_ADDR_ENABLE  (1UL << 0)
+/* MTE tag check fault modes */
+# define TARGET_PR_MTE_TCF_SHIFT   1
+# define TARGET_PR_MTE_TCF_NONE(0UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_SYNC(1UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_ASYNC   (2UL << TARGET_PR_MTE_TCF_SHIFT)
+# define TARGET_PR_MTE_TCF_MASK(3UL << TARGET_PR_MTE_TCF_SHIFT)
+/* MTE tag inclusion mask */
+# define TARGET_PR_MTE_TAG_SHIFT   3
+# define TARGET_PR_MTE_TAG_MASK(0xUL << TARGET_PR_MTE_TAG_SHIFT)
 
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 46526f50b0..d645eb8f44 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10967,17 +10967,53 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 {
 abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
 CPUARMState *env = cpu_env;
+ARMCPU *cpu = env_archcpu(env);
+
+if (cpu_isar_feature(aa64_mte, cpu)) {
+valid_mask |= TARGET_PR_MTE_TCF_MASK;
+valid_mask |= TARGET_PR_MTE_TAG_MASK;
+}
 
 if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
 return -TARGET_EINVAL;
 }
 env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
+
+if (cpu_isar_feature(aa64_mte, cpu)) {
+switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
+case TARGET_PR_MTE_TCF_NONE:
+case TARGET_PR_MTE_TCF_SYNC:
+case TARGET_PR_MTE_TCF_ASYNC:
+break;
+default:
+return -EINVAL;
+}
+
+/*
+ * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
+ * Note that the syscall values are consistent with hw.
+ */
+env->cp15.sctlr_el[1] =
+deposit64(env->cp15.sctlr_el[1], 38, 2,
+  arg2 >> TARGET_PR_MTE_TCF_SHIFT);
+
+/*
+ * Write PR_MTE_TAG to GCR_EL1[Exclude].
+ * Note that the syscall uses an include mask,
+ * and hardware uses an exclude mask -- invert.
+ */
+env->cp15.gcr_el1 =
+deposit64(env->cp15.gcr_el1, 0, 16,
+  ~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
+arm_rebuild_hflags(env);
+}
 return 0;
 }
 case TARGET_PR_GET_TAGGED_ADDR_CTRL:
 {
 abi_long ret = 0;
 CPUARMState *env = cpu_env;
+ARMCPU *cpu = env_archcpu(env);
 
 if (arg2 || arg3 || arg4 || arg5) {
 return -TARGET_EINVAL;
@@ -10985,6 +11021,13 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 if (env->tagged_addr_enable) {
 ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
 }
+if (cpu_isar_feature(aa64_mte, cpu)) {
+/* See above. */
+ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
+<< TARGET_PR_MTE_TCF_SHIFT);
+ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
+~env->cp15.gcr_el1);
+}
 return ret;
 }
 #endif /* AARCH64 */
-- 
2.25.1




[PATCH v4 21/23] target/arm: Add allocation tag storage for user mode

2021-01-28 Thread Richard Henderson
Use the now-saved PAGE_ANON and PAGE_MTE bits,
and the per-page saved data.

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

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index d55f8d1e1e..1c569336ea 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -78,8 +78,33 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int 
ptr_mmu_idx,
int tag_size, uintptr_t ra)
 {
 #ifdef CONFIG_USER_ONLY
-/* Tag storage not implemented.  */
-return NULL;
+uint64_t clean_ptr = useronly_clean_ptr(ptr);
+int flags = page_get_flags(clean_ptr);
+uint8_t *tags;
+uintptr_t index;
+
+if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE : PAGE_READ))) {
+/* SIGSEGV */
+arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access,
+ ptr_mmu_idx, false, ra);
+g_assert_not_reached();
+}
+
+/* Require both MAP_ANON and PROT_MTE for the page. */
+if (!(flags & PAGE_ANON) || !(flags & PAGE_MTE)) {
+return NULL;
+}
+
+tags = page_get_target_data(clean_ptr);
+if (tags == NULL) {
+size_t alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1);
+tags = page_alloc_target_data(clean_ptr, alloc_size);
+assert(tags != NULL);
+}
+
+index = extract32(ptr, LOG2_TAG_GRANULE + 1,
+  TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
+return tags + index;
 #else
 uintptr_t index;
 CPUIOTLBEntry *iotlbentry;
-- 
2.25.1




[PATCH v4 07/23] linux-user: Tidy VERIFY_READ/VERIFY_WRITE

2021-01-28 Thread Richard Henderson
These constants are only ever used with access_ok, and friends.
Rather than translating them to PAGE_* bits, let them equal
the PAGE_* bits to begin.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 441ba6a78b..9251337daf 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -488,8 +488,8 @@ extern unsigned long guest_stack_size;
 
 /* user access */
 
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
+#define VERIFY_READ  PAGE_READ
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
 
 static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
@@ -501,9 +501,7 @@ static inline bool access_ok(int type, abi_ulong addr, 
abi_ulong size)
  !guest_addr_valid(addr + size - 1))) {
 return false;
 }
-return page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ :
-(PAGE_READ | PAGE_WRITE)) == 0;
+return page_check_range((target_ulong)addr, size, type) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access.
-- 
2.25.1




[PATCH v4 08/23] bsd-user: Tidy VERIFY_READ/VERIFY_WRITE

2021-01-28 Thread Richard Henderson
These constants are only ever used with access_ok, and friends.
Rather than translating them to PAGE_* bits, let them equal
the PAGE_* bits to begin.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 bsd-user/qemu.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index f8bb1e5459..4076adabd0 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -218,13 +218,12 @@ extern unsigned long x86_stack_size;
 
 /* user access */
 
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
+#define VERIFY_READ  PAGE_READ
+#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
 
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
 {
-return page_check_range((target_ulong)addr, size,
-(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | 
PAGE_WRITE)) == 0;
+return page_check_range((target_ulong)addr, size, type) == 0;
 }
 
 /* NOTE __get_user and __put_user use host pointers and don't check access. */
-- 
2.25.1




[PATCH v4 12/23] linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE

2021-01-28 Thread Richard Henderson
This is the prctl bit that controls whether syscalls accept tagged
addresses.  See Documentation/arm64/tagged-address-abi.rst in the
linux kernel.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_syscall.h |  4 
 target/arm/cpu-param.h  |  3 +++
 target/arm/cpu.h| 31 +
 linux-user/syscall.c| 24 ++
 4 files changed, 62 insertions(+)

diff --git a/linux-user/aarch64/target_syscall.h 
b/linux-user/aarch64/target_syscall.h
index 3194e6b009..820601dfcc 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -30,4 +30,8 @@ struct target_pt_regs {
 # define TARGET_PR_PAC_APDBKEY   (1 << 3)
 # define TARGET_PR_PAC_APGAKEY   (1 << 4)
 
+#define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
+#define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
+# define TARGET_PR_TAGGED_ADDR_ENABLE  (1UL << 0)
+
 #endif /* AARCH64_TARGET_SYSCALL_H */
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 00e7d9e937..7f38d33b8e 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -20,6 +20,9 @@
 
 #ifdef CONFIG_USER_ONLY
 #define TARGET_PAGE_BITS 12
+# ifdef TARGET_AARCH64
+#  define TARGET_TAGGED_ADDRESSES
+# endif
 #else
 /*
  * ARMv7 and later CPUs have 4K pages minimum, but ARMv5 and v6
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index df0d677833..0db6e65467 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -721,6 +721,11 @@ typedef struct CPUARMState {
 const struct arm_boot_info *boot_info;
 /* Store GICv3CPUState to access from this struct */
 void *gicv3state;
+
+#ifdef TARGET_TAGGED_ADDRESSES
+/* Linux syscall tagged address support */
+bool tagged_addr_enable;
+#endif
 } CPUARMState;
 
 static inline void set_feature(CPUARMState *env, int feature)
@@ -3601,6 +3606,32 @@ static inline MemTxAttrs 
*typecheck_memtxattrs(MemTxAttrs *x)
  */
 #define PAGE_BTI  PAGE_TARGET_1
 
+#ifdef TARGET_TAGGED_ADDRESSES
+/**
+ * cpu_untagged_addr:
+ * @cs: CPU context
+ * @x: tagged address
+ *
+ * Remove any address tag from @x.  This is explicitly related to the
+ * linux syscall TIF_TAGGED_ADDR setting, not TBI in general.
+ *
+ * There should be a better place to put this, but we need this in
+ * include/exec/cpu_ldst.h, and not some place linux-user specific.
+ */
+static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+if (cpu->env.tagged_addr_enable) {
+/*
+ * TBI is enabled for userspace but not kernelspace addresses.
+ * Only clear the tag if bit 55 is clear.
+ */
+x &= sextract64(x, 0, 56);
+}
+return x;
+}
+#endif
+
 /*
  * Naming convention for isar_feature functions:
  * Functions which test 32-bit ID registers should have _aa32_ in
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6001022e96..46526f50b0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10963,6 +10963,30 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 }
 return -TARGET_EINVAL;
+case TARGET_PR_SET_TAGGED_ADDR_CTRL:
+{
+abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
+CPUARMState *env = cpu_env;
+
+if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
+return -TARGET_EINVAL;
+}
+env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
+return 0;
+}
+case TARGET_PR_GET_TAGGED_ADDR_CTRL:
+{
+abi_long ret = 0;
+CPUARMState *env = cpu_env;
+
+if (arg2 || arg3 || arg4 || arg5) {
+return -TARGET_EINVAL;
+}
+if (env->tagged_addr_enable) {
+ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
+}
+return ret;
+}
 #endif /* AARCH64 */
 case PR_GET_SECCOMP:
 case PR_SET_SECCOMP:
-- 
2.25.1




[PATCH v4 16/23] linux-user/aarch64: Implement PROT_MTE

2021-01-28 Thread Richard Henderson
Remember the PROT_MTE bit as PAGE_MTE/PAGE_TARGET_2.
Otherwise this does not yet have effect.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
v3: Do not overlap PAGE_TARGET_2 with PAGE_RESERVED.
---
 include/exec/cpu-all.h|  1 +
 linux-user/syscall_defs.h |  1 +
 target/arm/cpu.h  |  1 +
 linux-user/mmap.c | 22 ++
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c52180e8e6..b2a72f70ec 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -284,6 +284,7 @@ extern intptr_t qemu_host_page_mask;
 #endif
 /* Target-specific bits that will be used via page_get_flags().  */
 #define PAGE_TARGET_1  0x0080
+#define PAGE_TARGET_2  0x0200
 
 #if defined(CONFIG_USER_ONLY)
 void page_dump(FILE *f);
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index f98c1c1c8d..46a960fccb 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1311,6 +1311,7 @@ struct target_winsize {
 
 #ifdef TARGET_AARCH64
 #define TARGET_PROT_BTI 0x10
+#define TARGET_PROT_MTE 0x20
 #endif
 
 /* Common */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0db6e65467..7a79dde6f6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3605,6 +3605,7 @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs 
*x)
  * AArch64 usage of the PAGE_TARGET_* bits for linux-user.
  */
 #define PAGE_BTI  PAGE_TARGET_1
+#define PAGE_MTE  PAGE_TARGET_2
 
 #ifdef TARGET_TAGGED_ADDRESSES
 /**
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 7fb4c628e1..34bd114f97 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -84,18 +84,24 @@ static int validate_prot_to_pageflags(int *host_prot, int 
prot)
| (prot & PROT_EXEC ? PROT_READ : 0);
 
 #ifdef TARGET_AARCH64
-/*
- * The PROT_BTI bit is only accepted if the cpu supports the feature.
- * Since this is the unusual case, don't bother checking unless
- * the bit has been requested.  If set and valid, record the bit
- * within QEMU's page_flags.
- */
-if (prot & TARGET_PROT_BTI) {
+{
 ARMCPU *cpu = ARM_CPU(thread_cpu);
-if (cpu_isar_feature(aa64_bti, cpu)) {
+
+/*
+ * The PROT_BTI bit is only accepted if the cpu supports the feature.
+ * Since this is the unusual case, don't bother checking unless
+ * the bit has been requested.  If set and valid, record the bit
+ * within QEMU's page_flags.
+ */
+if ((prot & TARGET_PROT_BTI) && cpu_isar_feature(aa64_bti, cpu)) {
 valid |= TARGET_PROT_BTI;
 page_flags |= PAGE_BTI;
 }
+/* Similarly for the PROT_MTE bit. */
+if ((prot & TARGET_PROT_MTE) && cpu_isar_feature(aa64_mte, cpu)) {
+valid |= TARGET_PROT_MTE;
+page_flags |= PAGE_MTE;
+}
 }
 #endif
 
-- 
2.25.1




[PATCH v4 03/23] exec: Use uintptr_t for guest_base

2021-01-28 Thread Richard Henderson
This is more descriptive than 'unsigned long'.
No functional change, since these match on all linux+bsd hosts.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h | 2 +-
 bsd-user/main.c| 4 ++--
 linux-user/elfload.c   | 4 ++--
 linux-user/main.c  | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index c23c77589b..c52180e8e6 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -158,7 +158,7 @@ static inline void tswap64s(uint64_t *s)
 /* On some host systems the guest address space is reserved on the host.
  * This allows the guest address space to be offset to a convenient location.
  */
-extern unsigned long guest_base;
+extern uintptr_t guest_base;
 extern bool have_guest_base;
 extern unsigned long reserved_va;
 
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 65163e1396..c09d74d788 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -41,7 +41,7 @@
 
 int singlestep;
 unsigned long mmap_min_addr;
-unsigned long guest_base;
+uintptr_t guest_base;
 bool have_guest_base;
 unsigned long reserved_va;
 
@@ -965,7 +965,7 @@ int main(int argc, char **argv)
 g_free(target_environ);
 
 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
-qemu_log("guest_base  0x%lx\n", guest_base);
+qemu_log("guest_base  %p\n", (void *)guest_base);
 log_page_dump("binary load");
 
 qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a64050713f..29f07bb234 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2135,9 +2135,9 @@ static void pgb_have_guest_base(const char *image_name, 
abi_ulong guest_loaddr,
 void *addr, *test;
 
 if (!QEMU_IS_ALIGNED(guest_base, align)) {
-fprintf(stderr, "Requested guest base 0x%lx does not satisfy "
+fprintf(stderr, "Requested guest base %p does not satisfy "
 "host minimum alignment (0x%lx)\n",
-guest_base, align);
+(void *)guest_base, align);
 exit(EXIT_FAILURE);
 }
 
diff --git a/linux-user/main.c b/linux-user/main.c
index bb4e55e8fc..55aac56d70 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -58,7 +58,7 @@ static const char *cpu_model;
 static const char *cpu_type;
 static const char *seed_optarg;
 unsigned long mmap_min_addr;
-unsigned long guest_base;
+uintptr_t guest_base;
 bool have_guest_base;
 
 /*
@@ -819,7 +819,7 @@ int main(int argc, char **argv, char **envp)
 g_free(target_environ);
 
 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
-qemu_log("guest_base  0x%lx\n", guest_base);
+qemu_log("guest_base  %p\n", (void *)guest_base);
 log_page_dump("binary load");
 
 qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
-- 
2.25.1




[PATCH v4 09/23] linux-user: Do not use guest_addr_valid for h2g_valid

2021-01-28 Thread Richard Henderson
This is the only use of guest_addr_valid that does not begin
with a guest address, but a host address being transformed to
a guest address.

We will shortly adjust guest_addr_valid to handle guest memory
tags, and the host address should not be subjected to that.

Move h2g_valid adjacent to the other h2g macros.

Signed-off-by: Richard Henderson 
---
v3: Ditch type changes; retain true for HLB <= GAM (pmm).
---
 include/exec/cpu_ldst.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 5e8878ee9b..4e6ef3d542 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -77,13 +77,16 @@ typedef uint64_t abi_ptr;
 #else
 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
 #endif
-#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
 }
 
+#define h2g_valid(x) \
+(HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
+ (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
+
 #define h2g_nocheck(x) ({ \
 uintptr_t __ret = (uintptr_t)(x) - guest_base; \
 (abi_ptr)__ret; \
-- 
2.25.1




[PATCH v4 04/23] exec: Use uintptr_t in cpu_ldst.h

2021-01-28 Thread Richard Henderson
This is more descriptive than 'unsigned long'.
No functional change, since these match on all linux+bsd hosts.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index ef54cb7e1f..3f9063aade 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -70,14 +70,14 @@ typedef uint64_t abi_ptr;
 #endif
 
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
-#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
+#define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
 
 #if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
 #define guest_addr_valid(x) (1)
 #else
 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
 #endif
-#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
+#define h2g_valid(x) guest_addr_valid((uintptr_t)(x) - guest_base)
 
 static inline int guest_range_valid(unsigned long start, unsigned long len)
 {
@@ -85,7 +85,7 @@ static inline int guest_range_valid(unsigned long start, 
unsigned long len)
 }
 
 #define h2g_nocheck(x) ({ \
-unsigned long __ret = (unsigned long)(x) - guest_base; \
+uintptr_t __ret = (uintptr_t)(x) - guest_base; \
 (abi_ptr)__ret; \
 })
 
-- 
2.25.1




[PATCH v4 10/23] linux-user: Fix guest_addr_valid vs reserved_va

2021-01-28 Thread Richard Henderson
We must always use GUEST_ADDR_MAX, because even 32-bit hosts can
use -R  to restrict the memory address of the guest.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu_ldst.h | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
index 4e6ef3d542..e62f4fba00 100644
--- a/include/exec/cpu_ldst.h
+++ b/include/exec/cpu_ldst.h
@@ -72,11 +72,10 @@ typedef uint64_t abi_ptr;
 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
 #define g2h(x) ((void *)((uintptr_t)(abi_ptr)(x) + guest_base))
 
-#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
-#define guest_addr_valid(x) (1)
-#else
-#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
-#endif
+static inline bool guest_addr_valid(abi_ulong x)
+{
+return x <= GUEST_ADDR_MAX;
+}
 
 static inline bool guest_range_valid(abi_ulong start, abi_ulong len)
 {
-- 
2.25.1




[PATCH v4 00/23] target-arm: Implement ARMv8.5-MemTag, user mode

2021-01-28 Thread Richard Henderson
The kernel abi was finally merged into 5.10.

Changes for v4:
  * Revamp "Add support for TARGET_TAGGED_ADDRESSES".  There are now two
sets of functions in include/exec/, one for tagged and one for
untagged addresses.  The former takes a CPUState, and does not
assume current_cpu is a thing.  So much for the generic bits...
However, use of current_cpu remains, pushed down to lock_user.
Changing everything that touches that, or get/put_user, is daunting.
  * Fix tbi0 vs tbi1 for linux-user.
This had a number of cascading effects.
  * Adjust when async errors are noticed.

Changes for v3:
  * Split out type changes to separate patches.
  * Add doc comments; tweak alloc so that the !PAGE_VALID case is clear.
  * Do not overlap PAGE_TARGET_2 with PAGE_RESERVED.
  * Use syndrome.h, arm_deliver_fault.


r~


Richard Henderson (23):
  tcg: Introduce target-specific page data for user-only
  linux-user: Introduce PAGE_ANON
  exec: Use uintptr_t for guest_base
  exec: Use uintptr_t in cpu_ldst.h
  exec: Improve types for guest_addr_valid
  linux-user: Check for overflow in access_ok
  linux-user: Tidy VERIFY_READ/VERIFY_WRITE
  bsd-user: Tidy VERIFY_READ/VERIFY_WRITE
  linux-user: Do not use guest_addr_valid for h2g_valid
  linux-user: Fix guest_addr_valid vs reserved_va
  exec: Add support for TARGET_TAGGED_ADDRESSES
  linux-user/aarch64: Implement PR_TAGGED_ADDR_ENABLE
  target/arm: Improve gen_top_byte_ignore
  target/arm: Use the proper TBI settings for linux-user
  linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
  linux-user/aarch64: Implement PROT_MTE
  target/arm: Split out syndrome.h from internals.h
  linux-user/aarch64: Pass syndrome to EXC_*_ABORT
  linux-user/aarch64: Signal SEGV_MTESERR for sync tag check fault
  linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error
  target/arm: Add allocation tag storage for user mode
  target/arm: Enable MTE for user-only
  tests/tcg/aarch64: Add mte smoke tests

 bsd-user/qemu.h |   9 +-
 include/exec/cpu-all.h  |  47 -
 include/exec/cpu_ldst.h |  42 +++--
 linux-user/aarch64/target_signal.h  |   3 +
 linux-user/aarch64/target_syscall.h |  13 ++
 linux-user/qemu.h   |  19 +-
 linux-user/syscall_defs.h   |   1 +
 target/arm/cpu-param.h  |   3 +
 target/arm/cpu.h|  32 
 target/arm/internals.h  | 249 +
 target/arm/syndrome.h   | 273 
 tests/tcg/aarch64/mte.h |  60 ++
 accel/tcg/translate-all.c   |  28 +++
 bsd-user/main.c |   4 +-
 linux-user/aarch64/cpu_loop.c   |  38 +++-
 linux-user/elfload.c|   4 +-
 linux-user/main.c   |   4 +-
 linux-user/mmap.c   |  29 ++-
 linux-user/syscall.c|  71 +++-
 target/arm/cpu.c|  25 ++-
 target/arm/mte_helper.c |  39 +++-
 target/arm/tlb_helper.c |  15 +-
 target/arm/translate-a64.c  |  25 +--
 tests/tcg/aarch64/mte-1.c   |  28 +++
 tests/tcg/aarch64/mte-2.c   |  45 +
 tests/tcg/aarch64/mte-3.c   |  51 ++
 tests/tcg/aarch64/mte-4.c   |  45 +
 tests/tcg/aarch64/pauth-2.c |   1 -
 tests/tcg/aarch64/Makefile.target   |   6 +
 tests/tcg/configure.sh  |   4 +
 30 files changed, 888 insertions(+), 325 deletions(-)
 create mode 100644 target/arm/syndrome.h
 create mode 100644 tests/tcg/aarch64/mte.h
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c
 create mode 100644 tests/tcg/aarch64/mte-3.c
 create mode 100644 tests/tcg/aarch64/mte-4.c

-- 
2.25.1




[PATCH v4 01/23] tcg: Introduce target-specific page data for user-only

2021-01-28 Thread Richard Henderson
This data can be allocated by page_alloc_target_data() and
released by page_set_flags(start, end, prot | PAGE_RESET).

This data will be used to hold tag memory for AArch64 MTE.

Signed-off-by: Richard Henderson 
---
v3: Add doc comments; tweak alloc so that the !PAGE_VALID case is clear.
---
 include/exec/cpu-all.h| 42 +--
 accel/tcg/translate-all.c | 28 ++
 linux-user/mmap.c |  4 +++-
 linux-user/syscall.c  |  4 ++--
 4 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 4b5408c341..99a09ee137 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -264,15 +264,21 @@ extern intptr_t qemu_host_page_mask;
 #define PAGE_EXEC  0x0004
 #define PAGE_BITS  (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
 #define PAGE_VALID 0x0008
-/* original state of the write flag (used when tracking self-modifying
-   code */
+/*
+ * Original state of the write flag (used when tracking self-modifying code)
+ */
 #define PAGE_WRITE_ORG 0x0010
-/* Invalidate the TLB entry immediately, helpful for s390x
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs() */
-#define PAGE_WRITE_INV 0x0040
+/*
+ * Invalidate the TLB entry immediately, helpful for s390x
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
+ */
+#define PAGE_WRITE_INV 0x0020
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
+#define PAGE_RESET 0x0040
+
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
-#define PAGE_RESERVED  0x0020
+#define PAGE_RESERVED  0x0100
 #endif
 /* Target-specific bits that will be used via page_get_flags().  */
 #define PAGE_TARGET_1  0x0080
@@ -287,6 +293,30 @@ int walk_memory_regions(void *, walk_memory_regions_fn);
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 int page_check_range(target_ulong start, target_ulong len, int flags);
+
+/**
+ * page_alloc_target_data(address, size)
+ * @address: guest virtual address
+ * @size: size of data to allocate
+ *
+ * Allocate @size bytes of out-of-band data to associate with the
+ * guest page at @address.  If the page is not mapped, NULL will
+ * be returned.  If there is existing data associated with @address,
+ * no new memory will be allocated.
+ *
+ * The memory will be freed when the guest page is deallocated,
+ * e.g. with the munmap system call.
+ */
+void *page_alloc_target_data(target_ulong address, size_t size);
+
+/**
+ * page_get_target_data(address)
+ * @address: guest virtual address
+ *
+ * Return any out-of-bound memory assocated with the guest page
+ * at @address, as per page_alloc_target_data.
+ */
+void *page_get_target_data(target_ulong address);
 #endif
 
 CPUArchState *cpu_copy(CPUArchState *env);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 81d4c83f22..bba9c8e0b3 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -114,6 +114,7 @@ typedef struct PageDesc {
 unsigned int code_write_count;
 #else
 unsigned long flags;
+void *target_data;
 #endif
 #ifndef CONFIG_USER_ONLY
 QemuSpin lock;
@@ -2740,6 +2741,7 @@ int page_get_flags(target_ulong address)
 void page_set_flags(target_ulong start, target_ulong end, int flags)
 {
 target_ulong addr, len;
+bool reset_target_data;
 
 /* This function should never be called with addresses outside the
guest address space.  If this assert fires, it probably indicates
@@ -2754,6 +2756,8 @@ void page_set_flags(target_ulong start, target_ulong end, 
int flags)
 if (flags & PAGE_WRITE) {
 flags |= PAGE_WRITE_ORG;
 }
+reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
+flags &= ~PAGE_RESET;
 
 for (addr = start, len = end - start;
  len != 0;
@@ -2767,10 +2771,34 @@ void page_set_flags(target_ulong start, target_ulong 
end, int flags)
 p->first_tb) {
 tb_invalidate_phys_page(addr, 0);
 }
+if (reset_target_data && p->target_data) {
+g_free(p->target_data);
+p->target_data = NULL;
+}
 p->flags = flags;
 }
 }
 
+void *page_get_target_data(target_ulong address)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+return p ? p->target_data : NULL;
+}
+
+void *page_alloc_target_data(target_ulong address, size_t size)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+void *ret = NULL;
+
+if (p->flags & PAGE_VALID) {
+ret = p->target_data;
+if (!ret) {
+p->target_data = ret = g_malloc0(size);
+}
+}
+return ret;
+}
+
 int page_check_range(target_ulong start, target_ulong len, int flags)
 {
 PageDesc *p;
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 810653c503..c6935

[PATCH v4 02/23] linux-user: Introduce PAGE_ANON

2021-01-28 Thread Richard Henderson
Record whether the backing page is anonymous, or if it has file
backing.  This will allow us to get close to the Linux AArch64
ABI for MTE, which allows tag memory only on ram-backed VMAs.

The real ABI allows tag memory on files, when those files are
on ram-backed filesystems, such as tmpfs.  We will not be able
to implement that in QEMU linux-user.

Thankfully, anonymous memory for malloc arenas is the primary
consumer of this feature, so this restricted version should
still be of use.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h | 2 ++
 linux-user/mmap.c  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 99a09ee137..c23c77589b 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -275,6 +275,8 @@ extern intptr_t qemu_host_page_mask;
 #define PAGE_WRITE_INV 0x0020
 /* For use with page_set_flags: page is being replaced; target_data cleared. */
 #define PAGE_RESET 0x0040
+/* For linux-user, indicates that the page is MAP_ANON. */
+#define PAGE_ANON  0x0080
 
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c693505b60..7fb4c628e1 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -599,6 +599,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
target_prot,
 }
 }
  the_end1:
+if (flags & MAP_ANONYMOUS) {
+page_flags |= PAGE_ANON;
+}
 page_flags |= PAGE_RESET;
 page_set_flags(start, start + len, page_flags);
  the_end:
-- 
2.25.1




Re: [PATCH 2/2] utils/fifo8: add VMSTATE_FIFO8_TEST macro

2021-01-28 Thread Peter Maydell
On Thu, 28 Jan 2021 at 22:17, Mark Cave-Ayland
 wrote:
>
> Rewrite the existing VMSTATE_FIFO8 macro to use VMSTATE_FIFO8_TEST as per the
> standard pattern in include/migration/vmstate.h.
>
> Signed-off-by: Mark Cave-Ayland 
> ---
>  include/qemu/fifo8.h | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH 2/2] utils/fifo8: add VMSTATE_FIFO8_TEST macro

2021-01-28 Thread Mark Cave-Ayland
Rewrite the existing VMSTATE_FIFO8 macro to use VMSTATE_FIFO8_TEST as per the
standard pattern in include/migration/vmstate.h.

Signed-off-by: Mark Cave-Ayland 
---
 include/qemu/fifo8.h | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
index 489c354291..28bf2cee57 100644
--- a/include/qemu/fifo8.h
+++ b/include/qemu/fifo8.h
@@ -148,12 +148,16 @@ uint32_t fifo8_num_used(Fifo8 *fifo);
 
 extern const VMStateDescription vmstate_fifo8;
 
-#define VMSTATE_FIFO8(_field, _state) {  \
-.name   = (stringify(_field)),   \
-.size   = sizeof(Fifo8), \
-.vmsd   = &vmstate_fifo8,\
-.flags  = VMS_STRUCT,\
-.offset = vmstate_offset_value(_state, _field, Fifo8),   \
+#define VMSTATE_FIFO8_TEST(_field, _state, _test) {  \
+.name = (stringify(_field)), \
+.field_exists = (_test), \
+.size = sizeof(Fifo8),   \
+.vmsd = &vmstate_fifo8,  \
+.flags= VMS_STRUCT,  \
+.offset   = vmstate_offset_value(_state, _field, Fifo8), \
 }
 
+#define VMSTATE_FIFO8(_field, _state)\
+VMSTATE_FIFO8_TEST(_field, _state, NULL)
+
 #endif /* QEMU_FIFO8_H */
-- 
2.20.1




[PATCH 1/2] utils/fifo8: change fatal errors from abort() to assert()

2021-01-28 Thread Mark Cave-Ayland
Developer errors are better represented with assert() rather than abort(). Also
improve the strictness of the checks by using range checks within the assert()
rather than converting the existing equality checks to inequality checks.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Claudio Fontana 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20210121102518.20112-1-mark.cave-ayl...@ilande.co.uk>
---
 util/fifo8.c | 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/util/fifo8.c b/util/fifo8.c
index a5dd789ce5..d4d1c135e0 100644
--- a/util/fifo8.c
+++ b/util/fifo8.c
@@ -31,9 +31,7 @@ void fifo8_destroy(Fifo8 *fifo)
 
 void fifo8_push(Fifo8 *fifo, uint8_t data)
 {
-if (fifo->num == fifo->capacity) {
-abort();
-}
+assert(fifo->num < fifo->capacity);
 fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
 fifo->num++;
 }
@@ -42,9 +40,7 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, 
uint32_t num)
 {
 uint32_t start, avail;
 
-if (fifo->num + num > fifo->capacity) {
-abort();
-}
+assert(fifo->num + num <= fifo->capacity);
 
 start = (fifo->head + fifo->num) % fifo->capacity;
 
@@ -63,9 +59,7 @@ uint8_t fifo8_pop(Fifo8 *fifo)
 {
 uint8_t ret;
 
-if (fifo->num == 0) {
-abort();
-}
+assert(fifo->num > 0);
 ret = fifo->data[fifo->head++];
 fifo->head %= fifo->capacity;
 fifo->num--;
@@ -76,9 +70,7 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, 
uint32_t *num)
 {
 uint8_t *ret;
 
-if (max == 0 || max > fifo->num) {
-abort();
-}
+assert(max > 0 && max <= fifo->num);
 *num = MIN(fifo->capacity - fifo->head, max);
 ret = &fifo->data[fifo->head];
 fifo->head += *num;
-- 
2.20.1




[PATCH 0/2] utils/fifo8: minor updates

2021-01-28 Thread Mark Cave-Ayland
This patchset contains a couple of minor updates to QEMU's Fifo8 implementation
conceived whilst working on the next revision of the ESP series.

Patch 1 has already been reviewed on-list whilst patch 2 adds a new
VMSTATE_FIFO8_TEST macro which is required to allow the updated ESP series
to handle incoming migrations from previous QEMU versions.

Signed-off-by: Mark Cave-Ayland 


Mark Cave-Ayland (2):
  utils/fifo8: change fatal errors from abort() to assert()
  utils/fifo8: add VMSTATE_FIFO8_TEST macro

 include/qemu/fifo8.h | 16 ++--
 util/fifo8.c | 16 
 2 files changed, 14 insertions(+), 18 deletions(-)

-- 
2.20.1




Re: [PATCH] Add support for building on ARM Macs

2021-01-28 Thread Peter Maydell
On Thu, 28 Jan 2021 at 21:14, John Arbuckle  wrote:
>
> Adds support for building QEMU on ARM-based Macintoshes.
> This patch has been tested on an M1 Mac running Mac OS 11.1
> and on a 64-bit x86 Mac running Mac OS 10.12.
>
> Signed-off-by: John Arbuckle 

There are already patches on-list working on adding support
for building on Apple Silicon:
 https://patchew.org/QEMU/20210126012457.39046-...@getutm.app/
and also on hvf support for it:
https://patchew.org/QEMU/2021012022.71840-1-ag...@csgraf.de/

thanks
-- PMM



Re: [PATCH 0/1] tests/acceptance/boot_linux: Switch to Fedora 32

2021-01-28 Thread Daniele Buono

On 1/28/2021 3:19 PM, Wainer dos Santos Moschetta wrote:

Hi,

On 1/26/21 10:09 PM, Daniele Buono wrote:

Local acceptance tests run with "make check-acceptance" are now
showing some cases canceled like the following:

(01/39) 
tests/acceptance/boot_linux.py:BootLinuxX8664.test_pc_i440fx_tcg: 
CANCEL: Failed to download/prepare boot image (0.25 s)


Turns out, every full-vm test in boot_linux.py is trying to use a
Fedora 31 cloud image and is failing, with Avocado refusing to download
it, presumably because Fedora 31 is EOL.

This patch moves to Fedora 32, which is still supported. And seem to
work fine


While ago it was discussed about updating the Fedora version which, in 
my opinion, ended up without a conclusion. Please see the complete 
thread in:


https://www.mail-archive.com/qemu-devel@nongnu.org/msg763986.html


Oops, didn't notice the previous thread. Apologies for the duplicate!



I'm CC'ing Daniel Berrrangé so that, perhaps, we could resume the 
discussion.


Thanks!

- Wainer



The script has the image checksums hardcoded. I downloaded and verified
the checksums with the Fedora 32 GPG key, but I would feel more
confident if someone else wants to verify it too.

The checksum files are here:
https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/ppc64le/images/Fedora-Cloud-32-1.6-ppc64le-CHECKSUM 

https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/s390x/images/Fedora-Cloud-32-1.6-s390x-CHECKSUM 

https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/aarch64/images/Fedora-Cloud-32-1.6-aarch64-CHECKSUM 

https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/x86_64/images/Fedora-Cloud-32-1.6-x86_64-CHECKSUM 


and the GPG keys are available here:
https://getfedora.org/en/security/

NOTE: I tried moving to Fedora 33, but the aarch64 VM cannot boot
properly. May be worth investigating but I have no experience with ARM
so I'll leave that to someone else, if interested.

Daniele Buono (1):
   tests/acceptance/boot_linux: Switch to Fedora 32

  tests/acceptance/boot_linux.py | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)







Re: [PATCH] hw/arm/smmuv3: Fix addr_mask for range-based invalidation

2021-01-28 Thread Auger Eric
Hi Zenghui,

On 1/28/21 9:25 AM, Auger Eric wrote:
> Hi Zenghui,
> 
> On 12/25/20 10:50 AM, Zenghui Yu wrote:
>> When performing range-based IOTLB invalidation, we should decode the TG
>> field into the corresponding translation granule size so that we can pass
>> the correct invalidation range to backend. Set @granule to (tg * 2 + 10) to
>> properly emulate the architecture.
>>
>> Fixes: d52915616c05 ("hw/arm/smmuv3: Get prepared for range invalidation")
>> Signed-off-by: Zenghui Yu 
> 
> Good catch! I tested with older guest kernels though. I wonder how I did
> not face the bug?
Please ignore this wrong comment as this corresponds to recent kernels
instead. Still puzzled anyway ;-)

Eric
> 
> 
>> ---
>>  hw/arm/smmuv3.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
>> index bbca0e9f20..65231c7d52 100644
>> --- a/hw/arm/smmuv3.c
>> +++ b/hw/arm/smmuv3.c
>> @@ -801,7 +801,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
>>  {
>>  SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
>>  IOMMUTLBEvent event;
>> -uint8_t granule = tg;
>> +uint8_t granule;
>>  
>>  if (!tg) {
>>  SMMUEventInfo event = {.inval_ste_allowed = true};
>> @@ -821,6 +821,8 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
>>  return;
>>  }
>>  granule = tt->granule_sz;
>> +} else {
>> +guanule = tg * 2 + 10;
> maybe just init granule to this value above while fixing the typo.
> 
> Thanks
> 
> Eric
>>  }
>>  
>>  event.type = IOMMU_NOTIFIER_UNMAP;
>>




Re: [PATCH v6 67/72] target/riscv: rvv-1.0: set mstatus.SD bit when writing vector CSRs

2021-01-28 Thread Alistair Francis
On Tue, Jan 12, 2021 at 2:30 AM  wrote:
>
> From: Frank Chang 
>
> Signed-off-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 28c1ce7928a..176010674e8 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -301,7 +301,7 @@ static int write_vxrm(CPURISCVState *env, int csrno, 
> target_ulong val)
>  if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
>  return -1;
>  }
> -env->mstatus |= MSTATUS_VS;
> +env->mstatus |= MSTATUS_VS | MSTATUS_SD;
>  #endif
>
>  env->vxrm = val;
> @@ -320,7 +320,7 @@ static int write_vxsat(CPURISCVState *env, int csrno, 
> target_ulong val)
>  if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
>  return -1;
>  }
> -env->mstatus |= MSTATUS_VS;
> +env->mstatus |= MSTATUS_VS | MSTATUS_SD;
>  #endif
>
>  env->vxsat = val;
> @@ -339,7 +339,7 @@ static int write_vstart(CPURISCVState *env, int csrno, 
> target_ulong val)
>  if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
>  return -1;
>  }
> -env->mstatus |= MSTATUS_VS;
> +env->mstatus |= MSTATUS_VS | MSTATUS_SD;
>  #endif
>
>  /*
> @@ -362,7 +362,7 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
> target_ulong val)
>  if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
>  return -1;
>  }
> -env->mstatus |= MSTATUS_VS;
> +env->mstatus |= MSTATUS_VS | MSTATUS_SD;
>  #endif
>
>  env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
> --
> 2.17.1
>
>



Re: [PATCH] gdbstub: Fix handle_query_xfer_auxv

2021-01-28 Thread Alex Bennée


Richard Henderson  writes:

> The main problem was that we were treating a guest address
> as a host address with a mere cast.
>
> Use the correct interface for accessing guest memory.  Do not
> allow offset == auxv_len, which would result in an empty packet.
>
> Fixes: 51c623b0de1 ("gdbstub: add support to Xfer:auxv:read: packet")
> Signed-off-by: Richard Henderson 
> ---
>
> Fixes a number of check-tcg failures, which are transformed from
> proper failures to "SKIP: PC not set" by the test harness (bug?).
> But the qemu executable has in fact crashed.

I wonder if I can tighten that up to detect the failed remote end in the
scripts.

Anyway snarfed into my queue. Thanks!

>
> I'm embarrased to note that I reviewed the original patch, and
> should have noticed this.
>
>
> r~
>
> ---
>  gdbstub.c | 17 -
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/gdbstub.c b/gdbstub.c
> index c7ca7e9f88..759bb00bcf 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2245,7 +2245,6 @@ static void handle_query_xfer_auxv(GdbCmdContext 
> *gdb_ctx, void *user_ctx)
>  {
>  TaskState *ts;
>  unsigned long offset, len, saved_auxv, auxv_len;
> -const char *mem;
>  
>  if (gdb_ctx->num_params < 2) {
>  put_packet("E22");
> @@ -2257,8 +2256,8 @@ static void handle_query_xfer_auxv(GdbCmdContext 
> *gdb_ctx, void *user_ctx)
>  ts = gdbserver_state.c_cpu->opaque;
>  saved_auxv = ts->info->saved_auxv;
>  auxv_len = ts->info->auxv_len;
> -mem = (const char *)(saved_auxv + offset);
> -if (offset > auxv_len) {
> +
> +if (offset >= auxv_len) {
>  put_packet("E00");
>  return;
>  }
> @@ -2269,12 +2268,20 @@ static void handle_query_xfer_auxv(GdbCmdContext 
> *gdb_ctx, void *user_ctx)
>  
>  if (len < auxv_len - offset) {
>  g_string_assign(gdbserver_state.str_buf, "m");
> -memtox(gdbserver_state.str_buf, mem, len);
>  } else {
>  g_string_assign(gdbserver_state.str_buf, "l");
> -memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
> +len = auxv_len - offset;
>  }
>  
> +g_byte_array_set_size(gdbserver_state.mem_buf, len);
> +if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
> +   gdbserver_state.mem_buf->data, len, false)) {
> +put_packet("E14");
> +return;
> +}
> +
> +memtox(gdbserver_state.str_buf,
> +   (const char *)gdbserver_state.mem_buf->data, len);
>  put_packet_binary(gdbserver_state.str_buf->str,
>gdbserver_state.str_buf->len, true);
>  }


-- 
Alex Bennée



Re: [PATCH v6 36/72] target/riscv: rvv-1.0: floating-point move instruction

2021-01-28 Thread Alistair Francis
On Tue, Jan 12, 2021 at 2:16 AM  wrote:
>
> From: Frank Chang 
>
> NaN-boxed the scalar floating-point register based on RVV 1.0's rules.
>
> Signed-off-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 1839fc0a56b..7ac7d6a2b92 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2691,9 +2691,15 @@ static bool trans_vfmv_v_f(DisasContext *s, 
> arg_vfmv_v_f *a)
>  require_rvf(s) &&
>  vext_check_isa_ill(s) &&
>  require_align(a->rd, s->lmul)) {
> +TCGv_i64 t1;
> +
>  if (s->vl_eq_vlmax) {
> +t1 = tcg_temp_new_i64();
> +/* NaN-box f[rs1] */
> +do_nanbox(s, t1, cpu_fpr[a->rs1]);
> +
>  tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
> - MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]);
> + MAXSZ(s), MAXSZ(s), t1);
>  mark_vs_dirty(s);
>  } else {
>  TCGv_ptr dest;
> @@ -2707,16 +2713,22 @@ static bool trans_vfmv_v_f(DisasContext *s, 
> arg_vfmv_v_f *a)
>  TCGLabel *over = gen_new_label();
>  tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
> +t1 = tcg_temp_new_i64();
> +/* NaN-box f[rs1] */
> +do_nanbox(s, t1, cpu_fpr[a->rs1]);
> +
>  dest = tcg_temp_new_ptr();
>  desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
>  tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
> -fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
> +
> +fns[s->sew - 1](dest, t1, cpu_env, desc);
>
>  tcg_temp_free_ptr(dest);
>  tcg_temp_free_i32(desc);
>  mark_vs_dirty(s);
>  gen_set_label(over);
>  }
> +tcg_temp_free_i64(t1);
>  return true;
>  }
>  return false;
> --
> 2.17.1
>
>



Re: [PATCH v6 34/72] target/riscv: rvv-1.0: register gather instructions

2021-01-28 Thread Alistair Francis
On Tue, Jan 12, 2021 at 2:10 AM  wrote:
>
> From: Frank Chang 
>
> * Add vrgatherei16.vv instruction.
>
> Signed-off-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/helper.h   |  4 
>  target/riscv/insn32.decode  |  1 +
>  target/riscv/insn_trans/trans_rvv.c.inc | 27 ++---
>  target/riscv/vector_helper.c| 23 -
>  4 files changed, 43 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index abf08dbc710..ea6c39b49a8 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1100,6 +1100,10 @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, 
> env, i32)
>  DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
>  DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
>  DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
>  DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32)
>  DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
>  DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index a593938e5c8..85cb3c81be0 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -620,6 +620,7 @@ vslidedown_vx   00 . . . 100 . 1010111 
> @r_vm
>  vslidedown_vi   00 . . . 011 . 1010111 @r_vm
>  vslide1down_vx  00 . . . 110 . 1010111 @r_vm
>  vrgather_vv 001100 . . . 000 . 1010111 @r_vm
> +vrgatherei16_vv 001110 . . . 000 . 1010111 @r_vm
>  vrgather_vx 001100 . . . 100 . 1010111 @r_vm
>  vrgather_vi 001100 . . . 011 . 1010111 @r_vm
>  vcompress_vm010111 - . . 010 . 1010111 @r
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 7d73e0e..bc780912b2b 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -3323,7 +3323,25 @@ static bool vrgather_vv_check(DisasContext *s, 
> arg_rmrr *a)
> require_vm(a->vm, a->rd);
>  }
>
> +static bool vrgatherei16_vv_check(DisasContext *s, arg_rmrr *a)
> +{
> +int8_t emul = MO_16 - s->sew + s->lmul;
> +return require_rvv(s) &&
> +   vext_check_isa_ill(s) &&
> +   (emul >= -3 && emul <= 3) &&
> +   require_align(a->rd, s->lmul) &&
> +   require_align(a->rs1, emul) &&
> +   require_align(a->rs2, s->lmul) &&
> +   (a->rd != a->rs2 && a->rd != a->rs1) &&
> +   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
> +  a->rs1, 1 << MAX(emul, 0)) &&
> +   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
> +  a->rs2, 1 << MAX(s->lmul, 0)) &&
> +   require_vm(a->vm, a->rd);
> +}
> +
>  GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check)
> +GEN_OPIVV_TRANS(vrgatherei16_vv, vrgatherei16_vv_check)
>
>  static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a)
>  {
> @@ -3343,7 +3361,8 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
> *a)
>  }
>
>  if (a->vm && s->vl_eq_vlmax) {
> -int vlmax = s->vlen;
> +int scale = s->lmul - (s->sew + 3);
> +int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
>  TCGv_i64 dest = tcg_temp_new_i64();
>
>  if (a->rs1 == 0) {
> @@ -3374,8 +3393,10 @@ static bool trans_vrgather_vi(DisasContext *s, 
> arg_rmrr *a)
>  }
>
>  if (a->vm && s->vl_eq_vlmax) {
> -if (a->rs1 >= s->vlen) {
> -tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd),
> +int scale = s->lmul - (s->sew + 3);
> +int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
> +if (a->rs1 >= vlmax) {
> +tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
>   MAXSZ(s), MAXSZ(s), 0);
>  } else {
>  tcg_gen_gvec_dup_mem(s->sew, vreg_ofs(s, a->rd),
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 8ccf538141c..782fe086f3e 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4666,11 +4666,11 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, 
> H4)
>  GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8)
>
>  /* Vector Register Gather Instruction */
> -#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H)  \
> +#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2)\
>  void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
>

Re: [PATCH v6 14/72] target/riscv: rvv-1.0: update check functions

2021-01-28 Thread Alistair Francis
On Tue, Jan 12, 2021 at 1:54 AM  wrote:
>
> From: Frank Chang 
>
> Update check functions with RVV 1.0 rules.
>
> Signed-off-by: Frank Chang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 732 
>  1 file changed, 499 insertions(+), 233 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 46e18a62b59..5967ba42b6d 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -19,11 +19,124 @@
>  #include "tcg/tcg-gvec-desc.h"
>  #include "internals.h"
>
> +static inline bool is_overlapped(const int8_t astart, int8_t asize,
> + const int8_t bstart, int8_t bsize)
> +{
> +const int8_t aend = astart + asize;
> +const int8_t bend = bstart + bsize;
> +
> +return MAX(aend, bend) - MIN(astart, bstart) < asize + bsize;
> +}
> +
> +static bool require_rvv(DisasContext *s)
> +{
> +return s->mstatus_vs != 0;
> +}
> +
> +static bool require_rvf(DisasContext *s)
> +{
> +if (s->mstatus_fs == 0) {
> +return false;
> +}
> +
> +switch (s->sew) {
> +case MO_16:
> +case MO_32:
> +return has_ext(s, RVF);
> +case MO_64:
> +return has_ext(s, RVD);
> +default:
> +return false;
> +}
> +}
> +
> +static bool require_scale_rvf(DisasContext *s)
> +{
> +if (s->mstatus_fs == 0) {
> +return false;
> +}
> +
> +switch (s->sew) {
> +case MO_8:
> +case MO_16:
> +return has_ext(s, RVF);
> +case MO_32:
> +return has_ext(s, RVD);
> +default:
> +return false;
> +}
> +}
> +
> +/* Destination vector register group cannot overlap source mask register. */
> +static bool require_vm(int vm, int vd)
> +{
> +return (vm != 0 || vd != 0);
> +}
> +
> +static bool require_nf(int vd, int nf, int lmul)
> +{
> +int size = nf << MAX(lmul, 0);
> +return size <= 8 && vd + size <= 32;
> +}
> +
> +/*
> + * Vector register should aligned with the passed-in LMUL (EMUL).
> + * If LMUL < 0, i.e. fractional LMUL, any vector register is allowed.
> + */
> +static bool require_align(const int8_t val, const int8_t lmul)
> +{
> +return lmul <= 0 || extract32(val, 0, lmul) == 0;
> +}
> +
> +/*
> + * A destination vector register group can overlap a source vector
> + * register group only if one of the following holds:
> + *  1. The destination EEW equals the source EEW.
> + *  2. The destination EEW is smaller than the source EEW and the overlap
> + * is in the lowest-numbered part of the source register group.
> + *  3. The destination EEW is greater than the source EEW, the source EMUL
> + * is at least 1, and the overlap is in the highest-numbered part of
> + * the destination register group.
> + * (Section 5.2)
> + *
> + * This function returns true if one of the following holds:
> + *  * Destination vector register group does not overlap a source vector
> + *register group.
> + *  * Rule 3 met.
> + * For rule 1, overlap is allowed so this function doesn't need to be called.
> + * For rule 2, (vd == vs). Caller has to check whether: (vd != vs) before
> + * calling this function.
> + */
> +static bool require_noover(const int8_t dst, const int8_t dst_lmul,
> +   const int8_t src, const int8_t src_lmul)
> +{
> +int8_t dst_size = dst_lmul <= 0 ? 1 : 1 << dst_lmul;
> +int8_t src_size = src_lmul <= 0 ? 1 : 1 << src_lmul;
> +
> +/* Destination EEW is greater than the source EEW, check rule 3. */
> +if (dst_size > src_size) {
> +if (dst < src &&
> +src_lmul >= 0 &&
> +is_overlapped(dst, dst_size, src, src_size) &&
> +!is_overlapped(dst, dst_size, src + src_size, src_size)) {
> +return true;
> +}
> +}
> +
> +return !is_overlapped(dst, dst_size, src, src_size);
> +}
> +
> +static bool require_noover_seg(const int8_t dst, const int8_t nf,
> +   const int8_t src)
> +{
> +return !is_overlapped(dst, nf, src, 1);
> +}
> +
>  static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>  {
>  TCGv s1, s2, dst;
>
> -if (!has_ext(ctx, RVV)) {
> +if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
>  return false;
>  }
>
> @@ -56,7 +169,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli 
> *a)
>  {
>  TCGv s1, s2, dst;
>
> -if (!has_ext(ctx, RVV)) {
> +if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
>  return false;
>  }
>
> @@ -100,54 +213,246 @@ static bool vext_check_isa_ill(DisasContext *s)
>  return !s->vill;
>  }
>
> +static bool vext_check_ss(DisasContext *s, int vd, int vs, int vm)
> +{
> +return require_vm(vm, vd) &&
> +require_align(vd, s->lmul) &&
> +require_align(vs, s->lmul);
> +}
> +
>  /*
> - * There are two rules check here.
> + * Check function for vector instruction with

[PATCH] Add support for building on ARM Macs

2021-01-28 Thread John Arbuckle
Adds support for building QEMU on ARM-based Macintoshes. 
This patch has been tested on an M1 Mac running Mac OS 11.1
and on a 64-bit x86 Mac running Mac OS 10.12.

Signed-off-by: John Arbuckle 
---
 configure | 49 +++--
 1 file changed, 39 insertions(+), 10 deletions(-)

diff --git a/configure b/configure
index dcc5ea7d63..f6bcd0ecac 100755
--- a/configure
+++ b/configure
@@ -622,13 +622,40 @@ fi
 # the correct CPU with the --cpu option.
 case $targetos in
 Darwin)
-  # on Leopard most of the system is 32-bit, so we have to ask the kernel if 
we can
-  # run 64-bit userspace code.
-  # If the user didn't specify a CPU explicitly and the kernel says this is
-  # 64 bit hw, then assume x86_64. Otherwise fall through to the usual 
detection code.
-  if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
-cpu="x86_64"
-  fi
+# user specified the target cpu with --cpu
+if test ! -z "$cpu"; then
+echo "Using user-specified cpu target $cpu"
+
+# detect the host cpu
+else
+raw_value=`sysctl -n hw.cputype`
+cpu_arch=$((raw_value & 0xff))
+
+if [[ $"cpu_arch" -eq 12 ]]; then# if ARM
+is_64bit=$((raw_value & 0x0100))
+if [[ "$is_64bit" -gt 1 ]]; then # if 64-bit
+cpu="aarch64"
+else
+cpu="arm"
+fi
+
+elif [[ $"cpu_arch" -eq 7 ]]; then   # if x86
+is_64bit=`sysctl -n hw.cpu64bit_capable`
+if [[ "$is_64bit" -eq 1 ]]; then # if 64-bit
+cpu="x86_64"
+else
+cpu="x86"
+fi
+
+elif [[ $"cpu_arch" -eq 18 ]]; then  # if PowerPC
+# Not sure know how to detect 64-bit PowerPC a.k.a. G5
+cpu="ppc"
+
+else
+echo "Unknown target cpu error"
+fi
+fi
+
   HOST_DSOSUF=".dylib"
   ;;
 SunOS)
@@ -772,10 +799,12 @@ OpenBSD)
 Darwin)
   bsd="yes"
   darwin="yes"
-  if [ "$cpu" = "x86_64" ] ; then
-QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
-QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
+  cpu_arch="$cpu"
+  if [ $cpu == "aarch64" ]; then   # Apple's clang prefers arm64
+cpu_arch="arm64"
   fi
+  QEMU_CFLAGS="-arch $cpu_arch $QEMU_CFLAGS"
+  QEMU_LDFLAGS="-arch $cpu_arch $QEMU_LDFLAGS"
   audio_drv_list="coreaudio try-sdl"
   audio_possible_drivers="coreaudio sdl"
   QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
-- 
2.24.3 (Apple Git-128)




Re: [PATCH v3 1/9] hw/block: m25p80: Add ISSI SPI flash support

2021-01-28 Thread Alistair Francis
On Mon, Jan 25, 2021 at 10:01 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds the ISSI SPI flash support. The number of dummy cycles in
> fast read, fast read dual output and fast read quad output commands
> is currently using the default 8. Likewise, the same default value
> is used for fast read dual/quad I/O command. Per the datasheet [1],
> the number of dummy cycles is configurable, but this is not modeled
> at present.
>
> For flash whose size is larger than 16 MiB, the sequence of 3-byte
> address along with EXTADD bit in the bank address register (BAR) is
> not supported. We assume that guest software always uses op codes
> with 4-byte address sequence. Fortunately, this is the case for both
> U-Boot and Linux spi-nor drivers.
>
> QPI (Quad Peripheral Interface) that supports 2-cycle instruction
> has different default values for dummy cycles of fast read family
> commands, and is unsupported at the time being.
>
> [1] http://www.issi.com/WW/pdf/25LP-WP256.pdf
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Mention QPI (Quad Peripheral Interface) mode is not supported
>
>  hw/block/m25p80.c | 44 +++-
>  1 file changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index b744a58d1c..217c130f56 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -412,6 +412,7 @@ typedef enum {
>  MAN_NUMONYX,
>  MAN_WINBOND,
>  MAN_SST,
> +MAN_ISSI,
>  MAN_GENERIC,
>  } Manufacturer;
>
> @@ -487,6 +488,8 @@ static inline Manufacturer get_man(Flash *s)
>  return MAN_MACRONIX;
>  case 0xBF:
>  return MAN_SST;
> +case 0x9D:
> +return MAN_ISSI;
>  default:
>  return MAN_GENERIC;
>  }
> @@ -706,6 +709,9 @@ static void complete_collecting_data(Flash *s)
>  case MAN_SPANSION:
>  s->quad_enable = !!(s->data[1] & 0x02);
>  break;
> +case MAN_ISSI:
> +s->quad_enable = extract32(s->data[0], 6, 1);
> +break;
>  case MAN_MACRONIX:
>  s->quad_enable = extract32(s->data[0], 6, 1);
>  if (s->len > 1) {
> @@ -895,6 +901,19 @@ static void decode_fast_read_cmd(Flash *s)
>  SPANSION_DUMMY_CLK_LEN
>  );
>  break;
> +case MAN_ISSI:
> +/*
> + * The Fast Read instruction code is followed by address bytes and
> + * dummy cycles, transmitted via the SI line.
> + *
> + * The number of dummy cycles is configurable but this is currently
> + * unmodeled, hence the default value 8 is used.
> + *
> + * QPI (Quad Peripheral Interface) mode has different default value
> + * of dummy cycles, but this is unsupported at the time being.
> + */
> +s->needed_bytes += 1;
> +break;
>  default:
>  break;
>  }
> @@ -934,6 +953,16 @@ static void decode_dio_read_cmd(Flash *s)
>  break;
>  }
>  break;
> +case MAN_ISSI:
> +/*
> + * The Fast Read Dual I/O instruction code is followed by address 
> bytes
> + * and dummy cycles, transmitted via the IO1 and IO0 line.
> + *
> + * The number of dummy cycles is configurable but this is currently
> + * unmodeled, hence the default value 4 is used.
> + */
> +s->needed_bytes += 1;
> +break;
>  default:
>  break;
>  }
> @@ -974,6 +1003,19 @@ static void decode_qio_read_cmd(Flash *s)
>  break;
>  }
>  break;
> +case MAN_ISSI:
> +/*
> + * The Fast Read Quad I/O instruction code is followed by address 
> bytes
> + * and dummy cycles, transmitted via the IO3, IO2, IO1 and IO0 line.
> + *
> + * The number of dummy cycles is configurable but this is currently
> + * unmodeled, hence the default value 6 is used.
> + *
> + * QPI (Quad Peripheral Interface) mode has different default value
> + * of dummy cycles, but this is unsupported at the time being.
> + */
> +s->needed_bytes += 3;
> +break;
>  default:
>  break;
>  }
> @@ -1132,7 +1174,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
>
>  case RDSR:
>  s->data[0] = (!!s->write_enable) << 1;
> -if (get_man(s) == MAN_MACRONIX) {
> +if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
>  s->data[0] |= (!!s->quad_enable) << 6;
>  }
>  if (get_man(s) == MAN_SST) {
> --
> 2.25.1
>
>



Re: vnc clipboard support

2021-01-28 Thread BALATON Zoltan

On Fri, 29 Jan 2021, Marc-André Lureau wrote:

I also had recently some thoughts about how to implement clipboard sharing
in a more general way for QEMU.

I admit I like Christophe's suggestion ("it's somebody else problem"), but
it falls short to me as I don't know of a common open-source remoting
solution for various operating systems, and I don't see how it could
integrate well with our UI and remote protocols. Or look at reusing some
VirtualBox code perhaps?


I also thought about VirtualBox may worth a look at as that supports 
clipboard sharing and there's also Synergy 
[https://en.wikipedia.org/wiki/Synergy_(software)] that I don't know much 
but it's cross platform and may support clipboard sharing. It seems to 
have an open source fork called Barrier: 
https://github.com/debauchee/barrier


Regards,
BALATON Zoltan


Some things I keep in mind:
- the spice protocol had a number of iterations to fix some races. It would
be great not to repeat the same mistakes, and I don't know if VNC have the
same flaws or not.
- the spice agent design isn't great: the system agent proxies messages to
the active session. It would be nice if the new solution didn't have such a
middle-man.
- with wayland, clipboard sharing isn't really possible. Or not in a
seamless way at least. Today it kinda works with some X11 compatibility
extensions, but this will eventually go away or change behaviour.
- the GNOME desktop is working on remoting using RDP, and they are
implementing a DBus interface for it (
https://gitlab.gnome.org/jadahl/mutter/-/commits/wip/remote-desktop-clipboard
)
- it's not just about clipboard. We would also want to have some kind of
drag and drop (even if limited to files like Spice atm). We may want some
windowing integration. We may also want to have access to some desktop
services: apps, documents etc.. And what's not.

That leads me to think that virtio-serial is not very well suited, as it
doesn't allow various services / processes to come and go. I see vsock as a
much better alternative. (I also wonder if it handles control flow any
better btw)

I think we shoud work on getting the free desktops our best-class support.
To me, this means we need to speak the lingua franca, which is DBus. The
great thing is that DBus is also equipped to handle services that come and
go, handling discovery, introspection etc. Various services are already
available. As mentioned earlier, that's what the GNOME desktop will offer
for clipboard sharing. There are good chances other desktops will follow if
that design works, as it should be easy for them to implement the same
service. That means good reuse of existing desktop code. Speaking DBus on
Windows, MacOS or Android isn't an issue. However, vsock support may be a
bit tricky atm.

Fwiw, DBus doesn't yet officially support vsock connections:
https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/200. This a minor
detail, as once you give it a fd for transport, it doesn't really care (I
also took care of glib!1892 and Rust zbus)

Oh and of course, since this is a new daemon, it would be really a shame
not to write it in a modern language (hint! ;-).

Hope that helps,



Re: [PATCH v9 04/11] slirp: feature detection for smbd

2021-01-28 Thread Joelle van Dyne
On Mon, Jan 25, 2021 at 11:30 PM Philippe Mathieu-Daudé
 wrote:
>
> On 1/26/21 2:24 AM, Joelle van Dyne wrote:
> > Replace Windows specific macro with a more generic feature detection
> > macro. Allows slirp smb feature to be disabled manually as well.
> >
> > Signed-off-by: Joelle van Dyne 
> > ---
> >  configure   | 22 +-
> >  meson.build |  2 +-
> >  net/slirp.c | 16 
> >  3 files changed, 30 insertions(+), 10 deletions(-)
> >
> > diff --git a/configure b/configure
> > index 8d8a4733d7..d72ab22da5 100755
> > --- a/configure
> > +++ b/configure
> > @@ -464,6 +464,7 @@ fuse="auto"
> >  fuse_lseek="auto"
> >
> >  malloc_trim="auto"
> > +slirp_smbd="auto"
> >
> >  # parse CC options second
> >  for opt do
> > @@ -845,7 +846,18 @@ do
> >  fi
> >  done
> >
> > +# Check for smbd dupport
> >  : ${smbd=${SMBD-/usr/sbin/smbd}}
> > +if test "$slirp_smbd" != "no" ; then
>
> Here slirp_smbd is always "auto".
>
> > +  if test "$mingw32" = "yes" ; then
> > +if test "$slirp_smbd" = "yes" ; then
> > +  error_exit "Host smbd not supported on this platform."
> > +fi
> > +slirp_smbd=no
> > +  else
> > +slirp_smbd=yes
> > +  fi
> > +fi
>
> So this check ...
>
> >
> >  # Default objcc to clang if available, otherwise use CC
> >  if has clang; then
> > @@ -1560,6 +1572,10 @@ for opt do
> >;;
> >--disable-fuse-lseek) fuse_lseek="disabled"
> >;;
> > +  --enable-slirp-smbd) slirp_smbd=yes
> > +  ;;
> > +  --disable-slirp-smbd) slirp_smbd=no
> > +  ;;
> >*)
>
> ... should be placed after the cmdline options processing,
> isn't it?

That's right, good catch.
>



Re: vnc clipboard support

2021-01-28 Thread Marc-André Lureau
Hi

On Thu, Jan 28, 2021 at 9:14 PM Gerd Hoffmann  wrote:

>   Hi folks,
>
> I'm looking for a good way to implement cut+paste support for vnc.
>
> The vnc core protocol has support for text/plain cut+paste, and there
> is an extension adding support for other formats.  That'll cover one
> part of the problem, exchanging cut+paste data between vnc client and
> qemu vnc server.
>
> The tricky part is the second: the guest <=> qemu communication.
> I see basically two possible approaches here:
>
>   (1) Have some guest agent (spice does it that way).
>   Advantage: more flexible, allows more features.
>   Disadvantage: requires agent in the guest.
>
>   (2) Send text as key events.
>   Advantage: no guest agent needed.
>   Disadvantage: is translated by guests keyboard map, so qemu
>   needs to know the map for proper char -> key event translation.
>   Only works for text/plain and only for chars you can easily
>   type, anything needing input methods (emoji 😊 for example)
>   isn't going to fly.
>
> I think that (1) is clearly the better way.  Given that the agent
> would need to run in user wayland/xorg session context the existing
> qemu-guest-agent will not work.  Also linking against some UI library
> like gtk3 for clipboard handling is not something we want for the
> qemu-guest-agent.  So we need another one, I'll name it
> qemu-clipboard-agent for the rest of this mail.  And we need a
> communication channel.
>
> I'd tend to model the qemu-clipboard-agent simliar to the
> qemu-guest-agent, i.e. have some stream as communication path and run
> some stream protocol over it.
>
> Stream options I see are (in order of personal preference):
>
>   (1) New virtio-serial port.  virtio-serial likely is there anyway
>   for the qemu-guest-agent ...
>
>   (2) Have qemu-clipboard-agent and qemu-guest-agent share the agent
>   channel, i.e. qemu-clipboard-agent will proxy everything through
>   qemu-guest-agent (spice does it that way).
>
> Protocol options I see are (not sure yet which to prefer, need to have
> a closer look at the candidates):
>
>   (1) Add clipboard commands to QMP and use these.
>
>   (2) Reuse the clipboard bits of the vnc protocol (forward
>   VNC_MSG_CLIENT_CUT_TEXT messages to the guest agent)
>
>   (3) Reuse the clipboard bits of the spice-agent protocol.
>
>   (4) Reuse the clipboard bits of the wayland protocol.
>
> Once we have sorted the qemu <-> guest communication path it should be
> possible to also hook up other UIs (specifically gtk) without too much
> effort.  Which probably makes (2) a rather poor choice.
>
> Comments?
> Suggestions?
> Other ideas?
>


I also had recently some thoughts about how to implement clipboard sharing
in a more general way for QEMU.

I admit I like Christophe's suggestion ("it's somebody else problem"), but
it falls short to me as I don't know of a common open-source remoting
solution for various operating systems, and I don't see how it could
integrate well with our UI and remote protocols. Or look at reusing some
VirtualBox code perhaps?

Some things I keep in mind:
- the spice protocol had a number of iterations to fix some races. It would
be great not to repeat the same mistakes, and I don't know if VNC have the
same flaws or not.
- the spice agent design isn't great: the system agent proxies messages to
the active session. It would be nice if the new solution didn't have such a
middle-man.
- with wayland, clipboard sharing isn't really possible. Or not in a
seamless way at least. Today it kinda works with some X11 compatibility
extensions, but this will eventually go away or change behaviour.
- the GNOME desktop is working on remoting using RDP, and they are
implementing a DBus interface for it (
https://gitlab.gnome.org/jadahl/mutter/-/commits/wip/remote-desktop-clipboard
)
- it's not just about clipboard. We would also want to have some kind of
drag and drop (even if limited to files like Spice atm). We may want some
windowing integration. We may also want to have access to some desktop
services: apps, documents etc.. And what's not.

That leads me to think that virtio-serial is not very well suited, as it
doesn't allow various services / processes to come and go. I see vsock as a
much better alternative. (I also wonder if it handles control flow any
better btw)

I think we shoud work on getting the free desktops our best-class support.
To me, this means we need to speak the lingua franca, which is DBus. The
great thing is that DBus is also equipped to handle services that come and
go, handling discovery, introspection etc. Various services are already
available. As mentioned earlier, that's what the GNOME desktop will offer
for clipboard sharing. There are good chances other desktops will follow if
that design works, as it should be easy for them to implement the same
service. That means good reuse of existing desktop code. Speaking DBus on
Windows, MacOS or Android isn't an issue. However, vsock su

Re: [PATCH 0/1] tests/acceptance/boot_linux: Switch to Fedora 32

2021-01-28 Thread Wainer dos Santos Moschetta

Hi,

On 1/26/21 10:09 PM, Daniele Buono wrote:

Local acceptance tests run with "make check-acceptance" are now
showing some cases canceled like the following:

(01/39) tests/acceptance/boot_linux.py:BootLinuxX8664.test_pc_i440fx_tcg: 
CANCEL: Failed to download/prepare boot image (0.25 s)

Turns out, every full-vm test in boot_linux.py is trying to use a
Fedora 31 cloud image and is failing, with Avocado refusing to download
it, presumably because Fedora 31 is EOL.

This patch moves to Fedora 32, which is still supported. And seem to
work fine


While ago it was discussed about updating the Fedora version which, in 
my opinion, ended up without a conclusion. Please see the complete 
thread in:


https://www.mail-archive.com/qemu-devel@nongnu.org/msg763986.html

I'm CC'ing Daniel Berrrangé so that, perhaps, we could resume the 
discussion.


Thanks!

- Wainer



The script has the image checksums hardcoded. I downloaded and verified
the checksums with the Fedora 32 GPG key, but I would feel more
confident if someone else wants to verify it too.

The checksum files are here:
https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/ppc64le/images/Fedora-Cloud-32-1.6-ppc64le-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/s390x/images/Fedora-Cloud-32-1.6-s390x-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/aarch64/images/Fedora-Cloud-32-1.6-aarch64-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/x86_64/images/Fedora-Cloud-32-1.6-x86_64-CHECKSUM
and the GPG keys are available here:
https://getfedora.org/en/security/

NOTE: I tried moving to Fedora 33, but the aarch64 VM cannot boot
properly. May be worth investigating but I have no experience with ARM
so I'll leave that to someone else, if interested.

Daniele Buono (1):
   tests/acceptance/boot_linux: Switch to Fedora 32

  tests/acceptance/boot_linux.py | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)






[PATCH] gdbstub: Fix handle_query_xfer_auxv

2021-01-28 Thread Richard Henderson
The main problem was that we were treating a guest address
as a host address with a mere cast.

Use the correct interface for accessing guest memory.  Do not
allow offset == auxv_len, which would result in an empty packet.

Fixes: 51c623b0de1 ("gdbstub: add support to Xfer:auxv:read: packet")
Signed-off-by: Richard Henderson 
---

Fixes a number of check-tcg failures, which are transformed from
proper failures to "SKIP: PC not set" by the test harness (bug?).
But the qemu executable has in fact crashed.

I'm embarrased to note that I reviewed the original patch, and
should have noticed this.


r~

---
 gdbstub.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index c7ca7e9f88..759bb00bcf 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2245,7 +2245,6 @@ static void handle_query_xfer_auxv(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 {
 TaskState *ts;
 unsigned long offset, len, saved_auxv, auxv_len;
-const char *mem;
 
 if (gdb_ctx->num_params < 2) {
 put_packet("E22");
@@ -2257,8 +2256,8 @@ static void handle_query_xfer_auxv(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 ts = gdbserver_state.c_cpu->opaque;
 saved_auxv = ts->info->saved_auxv;
 auxv_len = ts->info->auxv_len;
-mem = (const char *)(saved_auxv + offset);
-if (offset > auxv_len) {
+
+if (offset >= auxv_len) {
 put_packet("E00");
 return;
 }
@@ -2269,12 +2268,20 @@ static void handle_query_xfer_auxv(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 
 if (len < auxv_len - offset) {
 g_string_assign(gdbserver_state.str_buf, "m");
-memtox(gdbserver_state.str_buf, mem, len);
 } else {
 g_string_assign(gdbserver_state.str_buf, "l");
-memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
+len = auxv_len - offset;
 }
 
+g_byte_array_set_size(gdbserver_state.mem_buf, len);
+if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
+   gdbserver_state.mem_buf->data, len, false)) {
+put_packet("E14");
+return;
+}
+
+memtox(gdbserver_state.str_buf,
+   (const char *)gdbserver_state.mem_buf->data, len);
 put_packet_binary(gdbserver_state.str_buf->str,
   gdbserver_state.str_buf->len, true);
 }
-- 
2.25.1




[PATCH 1/3] block/nbd: only detach existing iochannel from aio_context

2021-01-28 Thread Roman Kagan
When the reconnect in NBD client is in progress, the iochannel used for
NBD connection doesn't exist.  Therefore an attempt to detach it from
the aio_context of the parent BlockDriverState results in a NULL pointer
dereference.

The problem is triggerable, in particular, when an outgoing migration is
about to finish, and stopping the dataplane tries to move the
BlockDriverState from the iothread aio_context to the main loop.  If the
NBD connection is lost before this point, and the NBD client has entered
the reconnect procedure, QEMU crashes:

at /build/qemu-gYtjVn/qemu-5.0.1/io/channel.c:452
at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6151
new_context=new_context@entry=0x562a260c9580,
ignore=ignore@entry=0x7feeadc9b780)
at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6230
(bs=bs@entry=0x562a268d6a00, ctx=0x562a260c9580,
ignore_child=, errp=)
at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6332
new_context=0x562a260c9580,
update_root_node=update_root_node@entry=true, errp=errp@entry=0x0)
at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:1989
new_context=, errp=errp@entry=0x0)
at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:2010
out>)
at /build/qemu-gYtjVn/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio-bus.c:245
running=0, state=)
at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio.c:3220
state=state@entry=RUN_STATE_FINISH_MIGRATE)
at /build/qemu-gYtjVn/qemu-5.0.1/softmmu/vl.c:1275
send_stop=)
at /build/qemu-gYtjVn/qemu-5.0.1/cpus.c:1032
at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:2914
at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3275
at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3439
at /build/qemu-gYtjVn/qemu-5.0.1/util/qemu-thread-posix.c:519
at pthread_create.c:333
oldval=0x562a2452b138, oldlenp=0x0, newval=0x562a2452c5e0
<__func__.28102>, newlen=0)
at ../sysdeps/unix/sysv/linux/sysctl.c:30

Fix it by checking that the iochannel is non-null before trying to
detach it from the aio_context.  If it is null, no detaching is needed,
and it will get reattached in the proper aio_context once the connection
is reestablished.

Signed-off-by: Roman Kagan 
---
 block/nbd.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/block/nbd.c b/block/nbd.c
index 42e10c7c93..bcd6641e90 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -235,7 +235,14 @@ static void nbd_client_detach_aio_context(BlockDriverState 
*bs)
 
 /* Timer is deleted in nbd_client_co_drain_begin() */
 assert(!s->reconnect_delay_timer);
-qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+/*
+ * If reconnect is in progress we may have no ->ioc.  It will be
+ * re-instantiated in the proper aio context once the connection is
+ * reestablished.
+ */
+if (s->ioc) {
+qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc));
+}
 }
 
 static void nbd_client_attach_aio_context_bh(void *opaque)
-- 
2.29.2




[PATCH 3/3] nbd: make nbd_read* return -EIO on error

2021-01-28 Thread Roman Kagan
NBD reconnect logic considers the error code from the functions that
read NBD messages to tell if reconnect should be attempted or not: it is
attempted on -EIO, otherwise the client transitions to NBD_CLIENT_QUIT
state (see nbd_channel_error).  This error code is propagated from the
primitives like nbd_read.

The problem, however, is that nbd_read itself turns every error into -1
rather than -EIO.  As a result, if the NBD server happens to die while
sending the message, the client in QEMU receives less data than it
expects, considers it as a fatal error, and wouldn't attempt
reestablishing the connection.

Fix it by turning every negative return from qio_channel_read_all into
-EIO returned from nbd_read.  Apparently that was the original behavior,
but got broken later.  Also adjust nbd_readXX to follow.

Fixes: e6798f06a6 ("nbd: generalize usage of nbd_read")
Signed-off-by: Roman Kagan 
---
 include/block/nbd.h | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4a52a43ef5..5f34d23bb0 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -364,7 +364,7 @@ static inline int nbd_read(QIOChannel *ioc, void *buffer, 
size_t size,
 if (desc) {
 error_prepend(errp, "Failed to read %s: ", desc);
 }
-return -1;
+return ret;
 }
 
 return 0;
@@ -375,8 +375,9 @@ static inline int nbd_read##bits(QIOChannel *ioc,   
\
  uint##bits##_t *val,   \
  const char *desc, Error **errp)\
 {   \
-if (nbd_read(ioc, val, sizeof(*val), desc, errp) < 0) { \
-return -1;  \
+int ret = nbd_read(ioc, val, sizeof(*val), desc, errp); \
+if (ret < 0) {  \
+return ret; \
 }   \
 *val = be##bits##_to_cpu(*val); \
 return 0;   \
-- 
2.29.2




[PATCH 0/3] block/nbd: fix crashers in reconnect while migrating

2021-01-28 Thread Roman Kagan
During the final phase of migration the NBD reconnection logic may
encounter situations it doesn't expect during regular operation.

This series addresses some of them that make qemu crash.  They are
reproducible when a vm with a secondary drive attached via nbd with
non-zero "reconnect-delay" runs a stress load (fio with big queue depth)
in the guest on that drive and is migrated (e.g. to a file), while the
nbd server is SIGKILL-ed and restarted every second.

See the individual patches for specific crash conditions and more
detailed explanations.

Roman Kagan (3):
  block/nbd: only detach existing iochannel from aio_context
  block/nbd: only enter connection coroutine if it's present
  nbd: make nbd_read* return -EIO on error

 include/block/nbd.h |  7 ---
 block/nbd.c | 25 +
 2 files changed, 21 insertions(+), 11 deletions(-)

-- 
2.29.2




[PATCH 2/3] block/nbd: only enter connection coroutine if it's present

2021-01-28 Thread Roman Kagan
When an NBD block driver state is moved from one aio_context to another
(e.g. when doing a drain in a migration thread),
nbd_client_attach_aio_context_bh is executed that enters the connection
coroutine.

However, the assumption that ->connection_co is always present here
appears incorrect: the connection may have encountered an error other
than -EIO in the underlying transport, and thus may have decided to quit
rather than keep trying to reconnect, and therefore it may have
terminated the connection coroutine.  As a result an attempt to reassign
the client in this state (NBD_CLIENT_QUIT) to a different aio_context
leads to a null pointer dereference:

at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-coroutine.c:109
opaque=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block/nbd.c:164
at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:55
at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:136
at /build/qemu-6MF7tq/qemu-5.0.1/util/async.c:164
blocking=blocking@entry=true)
at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-posix.c:650
cb=, opaque=)
at /build/qemu-6MF7tq/qemu-5.0.1/util/aio-wait.c:71
bs=0x561805ed4c00) at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6172
new_context=new_context@entry=0x5618056c7580,
ignore=ignore@entry=0x7f60e1e63780)
at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6237
bs=bs@entry=0x561805ed4c00, ctx=0x5618056c7580,
ignore_child=, errp=)
at /build/qemu-6MF7tq/qemu-5.0.1/block.c:6332
new_context=0x5618056c7580, update_root_node=update_root_node@entry=true,
errp=errp@entry=0x0)
at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:1989
new_context=, errp=errp@entry=0x0)
at /build/qemu-6MF7tq/qemu-5.0.1/block/block-backend.c:2010
at /build/qemu-6MF7tq/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292
at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio-bus.c:245
running=0, state=)
at /build/qemu-6MF7tq/qemu-5.0.1/hw/virtio/virtio.c:3220
state=state@entry=RUN_STATE_FINISH_MIGRATE)
at /build/qemu-6MF7tq/qemu-5.0.1/softmmu/vl.c:1275
send_stop=) at /build/qemu-6MF7tq/qemu-5.0.1/cpus.c:1032
at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:2914
at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3275
at /build/qemu-6MF7tq/qemu-5.0.1/migration/migration.c:3439
at /build/qemu-6MF7tq/qemu-5.0.1/util/qemu-thread-posix.c:519
   from /lib/x86_64-linux-gnu/libpthread.so.0

Fix it by checking that the connection coroutine is non-null before
trying to enter it.  If it is null, no entering is needed, as the
connection is probably going down anyway.

Signed-off-by: Roman Kagan 
---
 block/nbd.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index bcd6641e90..b3cbbeb4b0 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -250,13 +250,15 @@ static void nbd_client_attach_aio_context_bh(void *opaque)
 BlockDriverState *bs = opaque;
 BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
 
-/*
- * The node is still drained, so we know the coroutine has yielded in
- * nbd_read_eof(), the only place where bs->in_flight can reach 0, or it is
- * entered for the first time. Both places are safe for entering the
- * coroutine.
- */
-qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+if (s->connection_co) {
+/*
+ * The node is still drained, so we know the coroutine has yielded in
+ * nbd_read_eof(), the only place where bs->in_flight can reach 0, or
+ * it is entered for the first time. Both places are safe for entering
+ * the coroutine.
+ */
+qemu_aio_coroutine_enter(bs->aio_context, s->connection_co);
+}
 bdrv_dec_in_flight(bs);
 }
 
-- 
2.29.2




Re: [PULL 0/8] Block layer patches

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 21:19, Peter Maydell wrote:

On Wed, 27 Jan 2021 at 19:58, Kevin Wolf  wrote:


The following changes since commit bf159f0bdc7b8e7aa8342dedb3829ca744c1b612:

   Merge remote-tracking branch 
'remotes/edgar/tags/edgar/xilinx-next-2021-01-27.for-upstream' into staging 
(2021-01-27 17:40:25 +)

are available in the Git repository at:

   git://repo.or.cz/qemu/kevin.git tags/for-upstream

for you to fetch changes up to a44be0334beae3a9affb4a3a92cc6852993d7a84:

   iotests: rename and move 169 and 199 tests (2021-01-27 20:53:14 +0100)


Block layer patches:

- Fix crash on write to read-only devices
- iotests: Rewrite 'check' in Python, get rid of 'groups' and allow
   non-numeric test case names




I somehow failed to notice before applying this, but this
breaks 'make check' on the netbsd and freebsd VMs.

As usual the build log is pretty opaque, but this looks like the
probable culprit:

env: python3: No such file or directory
gmake: *** [/home/qemu/qemu-test.nU2bcG/src/tests/Makefile.include:144:
check-block] Error 1

The python in the netbsd VM is /usr/pkg/bin/python3.7. Something
seems to be ignoring the --python= passed into our configure
and assuming that "python3" is always a valid executable.



Seems, that's shows that the fact that "PYTHON" variable in check-block.sh 
works for me doesn't mean that it works everywhere.. My fault, I look closer tomorrow.

--
Best regards,
Vladimir



Re: [PATCH] iotests/297: pylint: ignore too many statements

2021-01-28 Thread Vladimir Sementsov-Ogievskiy

28.01.2021 23:04, Vladimir Sementsov-Ogievskiy wrote:

Ignore two complains, which now lead to 297 failure on testenv.py and
testrunner.py.

Fixes: 2e5a2f57db481f18fcf70be2a36b1417370b8476
Fixes: d74c754c924ca34e90b7c96ce2f5609d82c0e628
Signed-off-by: Vladimir Sementsov-Ogievskiy 
---


Forget to note:

I don't add exclusions to pylintrc intentionally, as I think these warnings are 
reasonable, and it's good that vim ALE show them.. Still, adding them to 
pylintrc works too if you prefer.


  tests/qemu-iotests/297 | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index a37910b42d..3e3e0e34aa 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -73,7 +73,9 @@ def run_linters():
  env['PYTHONPATH'] += os.pathsep + qemu_module_path
  except KeyError:
  env['PYTHONPATH'] = qemu_module_path
-subprocess.run(('pylint-3', '--score=n', '--notes=FIXME,XXX', *files),
+subprocess.run(('pylint-3', '--score=n', '--notes=FIXME,XXX',
+'--disable=too-many-return-statements',
+'--disable=too-many-statements', *files),
 env=env, check=False)
  
  print('=== mypy ===')





--
Best regards,
Vladimir



  1   2   3   4   >