Re: [PATCH v2] audio: add help option for -audio and -audiodev

2022-09-07 Thread Volker Rümelin

Am 07.09.22 um 19:30 schrieb Claudio Fontana:


add a simple help option for -audio and -audiodev
to show the list of available drivers, and document them.

Signed-off-by: Claudio Fontana 
---
  audio/audio.c   | 20 
  audio/audio.h   |  1 +
  qemu-options.hx | 10 ++
  softmmu/vl.c|  9 +++--
  4 files changed, 34 insertions(+), 6 deletions(-)

v1 -> v2: also extend the help to -audio.

  -audio help
  -audio driver=help
  -audiodev help

will all show the same results.

diff --git a/audio/audio.c b/audio/audio.c
index 4f4bb10cce..ffb09ec825 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -32,6 +32,7 @@
  #include "qapi/qapi-visit-audio.h"
  #include "qemu/cutils.h"
  #include "qemu/module.h"
+#include "qemu/help_option.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/replay.h"
  #include "sysemu/runstate.h"
@@ -2105,10 +2106,29 @@ static void audio_validate_opts(Audiodev *dev, Error 
**errp)
  }
  }
  
+void audio_help(void)

+{
+int i;
+
+printf("Available audio drivers:\n");
+printf("none\n");
+
+for (i = 0; audio_prio_list[i]; i++) {
+audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);


Hi Claudio,

there is no guarantee that the audio_prio_list contains all audio 
backend drivers. I would use this


+    for (i = 0; i < AUDIODEV_DRIVER__MAX; i++) {
+    const char *name = AudiodevDriver_str(i);
+    audio_driver *driver = audio_driver_lookup(name);

to enumerate all audio backend drivers.

With best regards,
Volker


+if (driver) {
+printf("%s\n", driver->name);
+}
+}
+}
+






Re: [PATCH 1/2] tpm_emulator: Use latest tpm_ioctl.h from swtpm project

2022-09-07 Thread Marc-André Lureau
On Thu, Sep 8, 2022 at 2:28 AM Stefan Berger  wrote:
>
> Use the latest tpm_ioctl.h from upstream swtpm project.
>
> Signed-off-by: Stefan Berger 

Reviewed-by: Marc-André Lureau 

> ---
>  backends/tpm/tpm_ioctl.h | 96 +++-
>  1 file changed, 76 insertions(+), 20 deletions(-)
>
> diff --git a/backends/tpm/tpm_ioctl.h b/backends/tpm/tpm_ioctl.h
> index d67bf0283b..e506ef5160 100644
> --- a/backends/tpm/tpm_ioctl.h
> +++ b/backends/tpm/tpm_ioctl.h
> @@ -5,10 +5,15 @@
>   *
>   * This file is licensed under the terms of the 3-clause BSD license
>   */
> +#ifndef _TPM_IOCTL_H_
> +#define _TPM_IOCTL_H_
>
> -#ifndef TPM_IOCTL_H
> -#define TPM_IOCTL_H
> +#if defined(__CYGWIN__)
> +# define __USE_LINUX_IOCTL_DEFS
> +#endif
>
> +#include 
> +#include 
>  #ifndef _WIN32
>  #include 
>  #include 
> @@ -196,6 +201,48 @@ struct ptm_setbuffersize {
>  } u;
>  };
>
> +#define PTM_GETINFO_SIZE (3 * 1024)
> +/*
> + * PTM_GET_INFO: Get info about the TPM implementation (from libtpms)
> + *
> + * This request allows to indirectly call TPMLIB_GetInfo(flags) and
> + * retrieve information from libtpms.
> + * Only one transaction is currently necessary for returning results
> + * to a client. Therefore, totlength and length will be the same if
> + * offset is 0.
> + */
> +struct ptm_getinfo {
> +union {
> +struct {
> +uint64_t flags;
> +uint32_t offset;  /* offset from where to read */
> +uint32_t pad; /* 32 bit arch */
> +} req; /* request */
> +struct {
> +ptm_res tpm_result;
> +uint32_t totlength;
> +uint32_t length;
> +char buffer[PTM_GETINFO_SIZE];
> +} resp; /* response */
> +} u;
> +};
> +
> +#define SWTPM_INFO_TPMSPECIFICATION ((uint64_t)1 << 0)
> +#define SWTPM_INFO_TPMATTRIBUTES((uint64_t)1 << 1)
> +
> +/*
> + * PTM_LOCK_STORAGE: Lock the storage and retry n times
> + */
> +struct ptm_lockstorage {
> +union {
> +struct {
> +uint32_t retries; /* number of retries */
> +} req; /* request */
> +struct {
> +ptm_res tpm_result;
> +} resp; /* reponse */
> +} u;
> +};
>
>  typedef uint64_t ptm_cap;
>  typedef struct ptm_est ptm_est;
> @@ -207,6 +254,8 @@ typedef struct ptm_getstate ptm_getstate;
>  typedef struct ptm_setstate ptm_setstate;
>  typedef struct ptm_getconfig ptm_getconfig;
>  typedef struct ptm_setbuffersize ptm_setbuffersize;
> +typedef struct ptm_getinfo ptm_getinfo;
> +typedef struct ptm_lockstorage ptm_lockstorage;
>
>  /* capability flags returned by PTM_GET_CAPABILITY */
>  #define PTM_CAP_INIT   (1)
> @@ -223,6 +272,9 @@ typedef struct ptm_setbuffersize ptm_setbuffersize;
>  #define PTM_CAP_GET_CONFIG (1 << 11)
>  #define PTM_CAP_SET_DATAFD (1 << 12)
>  #define PTM_CAP_SET_BUFFERSIZE (1 << 13)
> +#define PTM_CAP_GET_INFO   (1 << 14)
> +#define PTM_CAP_SEND_COMMAND_HEADER (1 << 15)
> +#define PTM_CAP_LOCK_STORAGE   (1 << 16)
>
>  #ifndef _WIN32
>  enum {
> @@ -243,6 +295,8 @@ enum {
>  PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
>  PTM_SET_DATAFD = _IOR('P', 15, ptm_res),
>  PTM_SET_BUFFERSIZE = _IOWR('P', 16, ptm_setbuffersize),
> +PTM_GET_INFO   = _IOWR('P', 17, ptm_getinfo),
> +PTM_LOCK_STORAGE   = _IOWR('P', 18, ptm_lockstorage),
>  };
>  #endif
>
> @@ -257,23 +311,25 @@ enum {
>   * and ptm_set_state:u.req.data) are 0x.
>   */
>  enum {
> -CMD_GET_CAPABILITY = 1,
> -CMD_INIT,
> -CMD_SHUTDOWN,
> -CMD_GET_TPMESTABLISHED,
> -CMD_SET_LOCALITY,
> -CMD_HASH_START,
> -CMD_HASH_DATA,
> -CMD_HASH_END,
> -CMD_CANCEL_TPM_CMD,
> -CMD_STORE_VOLATILE,
> -CMD_RESET_TPMESTABLISHED,
> -CMD_GET_STATEBLOB,
> -CMD_SET_STATEBLOB,
> -CMD_STOP,
> -CMD_GET_CONFIG,
> -CMD_SET_DATAFD,
> -CMD_SET_BUFFERSIZE,
> +CMD_GET_CAPABILITY = 1,   /* 0x01 */
> +CMD_INIT, /* 0x02 */
> +CMD_SHUTDOWN, /* 0x03 */
> +CMD_GET_TPMESTABLISHED,   /* 0x04 */
> +CMD_SET_LOCALITY, /* 0x05 */
> +CMD_HASH_START,   /* 0x06 */
> +CMD_HASH_DATA,/* 0x07 */
> +CMD_HASH_END, /* 0x08 */
> +CMD_CANCEL_TPM_CMD,   /* 0x09 */
> +CMD_STORE_VOLATILE,   /* 0x0a */
> +CMD_RESET_TPMESTABLISHED, /* 0x0b */
> +CMD_GET_STATEBLOB,/* 0x0c */
> +CMD_SET_STATEBLOB,/* 0x0d */
> +CMD_STOP, /* 0x0e */
> +CMD_GET_CONFIG,   /* 0x0f */
> +CMD_SET_DATAFD,   /* 0x10 */
> +CMD_SET_BUFFERSIZE,   /* 0x11 */
> +CMD_GET_INFO, /* 0x12 */
> +CMD_LOCK_STORAGE, /* 0x13 */
>  };
>
> -#endif /* TPM_IOCTL_H */
> +#endif /* _TPM_IOCTL_H_ */
> --
> 2.37.2
>




Re: [PATCH v5 0/2] block: add missed block_acct_setup with new block device init procedure

2022-09-07 Thread Markus Armbruster
"Denis V. Lunev"  writes:

> On 8/24/22 11:50, Denis V. Lunev wrote:
>> Commit 5f76a7aac156ca75680dad5df4a385fd0b58f6b1 is looking harmless from
>> the first glance, but it has changed things a lot. 'libvirt' uses it to
>> detect that it should follow new initialization way and this changes
>> things considerably. With this procedure followed, blockdev_init() is
>> not called anymore and thus block_acct_setup() helper is not called.
>>
>> This means in particular that defaults for block accounting statistics
>> are changed and account_invalid/account_failed are actually initialized
>> as false instead of true originally.
>>
>> This commit changes things to match original world. There are the following
>> constraints:
>> * new default value in block_acct_init() is set to true
>> * block_acct_setup() inside blockdev_init() is called before
>>blkconf_apply_backend_options()
>> * thus newly created option in block device properties has precedence if
>>specified
>>
>> Changes from v4:
>> * removed hunk to QAPI which was used to test old initialization path
>> * added R-b: Vladimir
>>
>> Changes from v3:
>> * fixed accidentally wrong submission. Contains changes which should be
>>sent as v3
>>
>> Changes from v2:
>> * called bool_from_onoffauto(account_..., true) in the first patch to
>>preserve original semantics before patch 2
>>
>> Changes from v1:
>> * set account_invalid/account_failed to true by default
>> * pass OnOffAuto to block_acct_init() to handle double initialization (patch 
>> 1)
>> * changed properties on BLK device to OnOffAuto
>>
>> Signed-off-by: Denis V. Lunev 
>> CC: Peter Krempa 
>> CC: Markus Armbruster 
>> CC: John Snow 
>> CC: Kevin Wolf 
>> CC: Hanna Reitz 
>> CC: Vladimir Sementsov-Ogievskiy 
>>
>>
> ping

Can't find this series anymore.  Care to resend?




Re: [PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread Markus Armbruster
Daniel P. Berrangé  writes:

> On Wed, Sep 07, 2022 at 05:06:36PM +0200, Markus Armbruster wrote:
>> Claudio Fontana  writes:
>> 
>> > add a simple help option for -audiodev, so users can do
>> >
>> > qemu -audiodev ?
>> 
>> The preferred form is actually '-audiodev help'.  The other one is
>> deprecated.  Recommend to stay away from it even in commit messages.
>
> We introduced 'help' many many years ago, but don't thing we
> ever formally deprecated '?'.

is_help_option()'s function comment says "'?' is deprecated".  Goes back
to

commit c8057f951d64de93bfd01569c0a725baa9f94372
Author: Peter Maydell 
Date:   Thu Aug 2 13:45:54 2012 +0100

Support 'help' as a synonym for '?' in command line options

For command line options which permit '?' meaning 'please list the
permitted values', add support for 'help' as a synonym, by abstracting
the check out into a helper function.

This change means that in some cases where we were being lazy in
our string parsing, "?junk" will now be rejected as an invalid option
rather than being (undocumentedly) treated the same way as "?".

Update the documentation to use 'help' rather than '?', since '?'
is a shell metacharacter and thus prone to fail confusingly if there
is a single character filename in the current working directory and
the '?' has not been escaped. It's therefore better to steer users
towards 'help', though '?' is retained for backwards compatibility.

We do not, however, update the output of the system emulator's -help
(or any documentation autogenerated from the qemu-options.hx which
is the source of the -help text) because libvirt parses our -help
output and will break. At a later date when QEMU provides a better
interface so libvirt can avoid having to do this, we can update the
-help text too.

Signed-off-by: Peter Maydell 
Signed-off-by: Anthony Liguori 

The more formal deprecation process we use today didn't exist in 2012.
Looks like we simply de-documented '?'.

Note that output of -help has been updated since.

>Should we do so and aim to
> remove it, or are we happy to keep '?' forever, despite it
> tripping up shell filename expansion with single char filenames.

I'm not sure a belated formal notice of deprecation would be useful.

Emitting a warning might be.  Would have to be done at roughly 20 call
sites, I guess.

I'm cool with removing a feature that has been undocumented for a
decade.  However, experience tells us that every feature on the chopping
block will find a champion, and I believe this one is still around
simply because it's not worth a fight.

[...]




Re: [PATCH v7 00/14] KVM: mm: fd-based approach for supporting KVM guest private memory

2022-09-07 Thread Kirill A. Shutemov
On Wed, Aug 31, 2022 at 05:24:39PM +0300, Kirill A . Shutemov wrote:
> On Sat, Aug 20, 2022 at 10:15:32PM -0700, Hugh Dickins wrote:
> > > I will try next week to rework it as shim to top of shmem. Does it work
> > > for you?
> > 
> > Yes, please do, thanks.  It's a compromise between us: the initial TDX
> > case has no justification to use shmem at all, but doing it that way
> > will help you with some of the infrastructure, and will probably be
> > easiest for KVM to extend to other more relaxed fd cases later.
> 
> Okay, below is my take on the shim approach.
> 
> I don't hate how it turned out. It is easier to understand without
> callback exchange thing.
> 
> The only caveat is I had to introduce external lock to protect against
> race between lookup and truncate. Otherwise, looks pretty reasonable to me.
> 
> I did very limited testing. And it lacks integration with KVM, but API
> changed not substantially, any it should be easy to adopt.
> 
> Any comments?

Updated version below. Nothing major. Some simplification and cleanups.

diff --git a/include/linux/memfd.h b/include/linux/memfd.h
index 4f1600413f91..334ddff08377 100644
--- a/include/linux/memfd.h
+++ b/include/linux/memfd.h
@@ -3,6 +3,7 @@
 #define __LINUX_MEMFD_H
 
 #include 
+#include 
 
 #ifdef CONFIG_MEMFD_CREATE
 extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned long 
arg);
@@ -13,4 +14,27 @@ static inline long memfd_fcntl(struct file *f, unsigned int 
c, unsigned long a)
 }
 #endif
 
+struct inaccessible_notifier;
+
+struct inaccessible_notifier_ops {
+   void (*invalidate)(struct inaccessible_notifier *notifier,
+  pgoff_t start, pgoff_t end);
+};
+
+struct inaccessible_notifier {
+   struct list_head list;
+   const struct inaccessible_notifier_ops *ops;
+};
+
+void inaccessible_register_notifier(struct file *file,
+   struct inaccessible_notifier *notifier);
+void inaccessible_unregister_notifier(struct file *file,
+ struct inaccessible_notifier *notifier);
+
+int inaccessible_get_pfn(struct file *file, pgoff_t offset, pfn_t *pfn,
+int *order);
+void inaccessible_put_pfn(struct file *file, pfn_t pfn);
+
+struct file *memfd_mkinaccessible(struct file *memfd);
+
 #endif /* __LINUX_MEMFD_H */
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 6325d1d0e90f..9d066be3d7e8 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -101,5 +101,6 @@
 #define DMA_BUF_MAGIC  0x444d4142  /* "DMAB" */
 #define DEVMEM_MAGIC   0x454d444d  /* "DMEM" */
 #define SECRETMEM_MAGIC0x5345434d  /* "SECM" */
+#define INACCESSIBLE_MAGIC 0x494e4143  /* "INAC" */
 
 #endif /* __LINUX_MAGIC_H__ */
diff --git a/include/uapi/linux/memfd.h b/include/uapi/linux/memfd.h
index 7a8a26751c23..48750474b904 100644
--- a/include/uapi/linux/memfd.h
+++ b/include/uapi/linux/memfd.h
@@ -8,6 +8,7 @@
 #define MFD_CLOEXEC0x0001U
 #define MFD_ALLOW_SEALING  0x0002U
 #define MFD_HUGETLB0x0004U
+#define MFD_INACCESSIBLE   0x0008U
 
 /*
  * Huge page size encoding when MFD_HUGETLB is specified, and a huge page
diff --git a/mm/Makefile b/mm/Makefile
index 9a564f836403..f82e5d4b4388 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -126,7 +126,7 @@ obj-$(CONFIG_HARDENED_USERCOPY) += usercopy.o
 obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o
 obj-$(CONFIG_ZONE_DEVICE) += memremap.o
 obj-$(CONFIG_HMM_MIRROR) += hmm.o
-obj-$(CONFIG_MEMFD_CREATE) += memfd.o
+obj-$(CONFIG_MEMFD_CREATE) += memfd.o memfd_inaccessible.o
 obj-$(CONFIG_MAPPING_DIRTY_HELPERS) += mapping_dirty_helpers.o
 obj-$(CONFIG_PTDUMP_CORE) += ptdump.o
 obj-$(CONFIG_PAGE_REPORTING) += page_reporting.o
diff --git a/mm/memfd.c b/mm/memfd.c
index 08f5f8304746..1853a90f49ff 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -261,7 +261,8 @@ long memfd_fcntl(struct file *file, unsigned int cmd, 
unsigned long arg)
 #define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1)
 #define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN)
 
-#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB)
+#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB | \
+  MFD_INACCESSIBLE)
 
 SYSCALL_DEFINE2(memfd_create,
const char __user *, uname,
@@ -283,6 +284,14 @@ SYSCALL_DEFINE2(memfd_create,
return -EINVAL;
}
 
+   /* Disallow sealing when MFD_INACCESSIBLE is set. */
+   if ((flags & MFD_INACCESSIBLE) && (flags & MFD_ALLOW_SEALING))
+   return -EINVAL;
+
+   /* TODO: add hugetlb support */
+   if ((flags & MFD_INACCESSIBLE) && (flags & MFD_HUGETLB))
+   return -EINVAL;
+
/* length includes terminating zero */
len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1);
if (len <= 0)
@@ -331,10 +340,24 @@ SYSCALL_DEFINE2(memfd_create,

RE: [PATCH] Hexagon (target/hexagon) implement mutability mask for GPRs

2022-09-07 Thread Brian Cain

> -Original Message-
> From: Qemu-devel 
> On Behalf Of Anton Johansson via
...
> Hi, Brian!
> 
> I've taken a look and most of this patch seems good, however I have a few
> comments/observations.

Anton, sorry I missed this message last week, only following up now.

> > Some registers are defined to have immutable bits, this commit
> > will implement that behavior.
> >
> > Signed-off-by: Brian Cain 
> > ---
> >   target/hexagon/gen_masked.c   |  44 
> >   target/hexagon/gen_masked.h   |  26 
> >   target/hexagon/genptr.c   |  33 -
> >   target/hexagon/hex_regs.h |   6 ++
> >   target/hexagon/meson.build|   1 +
> >   tests/tcg/hexagon/Makefile.target |   1 +
> >   tests/tcg/hexagon/reg_mut.c   | 107
> ++
> >   7 files changed, 217 insertions(+), 1 deletion(-)
> >   create mode 100644 target/hexagon/gen_masked.c
> >   create mode 100644 target/hexagon/gen_masked.h
> >   create mode 100644 tests/tcg/hexagon/reg_mut.c
> >
> > diff --git a/target/hexagon/gen_masked.c b/target/hexagon/gen_masked.c
> > new file mode 100644
> > index 00..faffee2e13
> > --- /dev/null
> > +++ b/target/hexagon/gen_masked.c
> > @@ -0,0 +1,44 @@
> > +/*
> > + *  Copyright(c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of the GNU General Public License as published by
> > + *  the Free Software Foundation; either version 2 of the License, or
> > + *  (at your option) any later version.
> > + *
> > + *  This program is distributed in the hope that it will be useful,
> > + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + *  GNU General Public License for more details.
> > + *
> > + *  You should have received a copy of the GNU General Public License
> > + *  along with this program; if not, see .
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "tcg/tcg-op.h"
> > +#include "gen_masked.h"
> > +
> > +void gen_masked_reg_write(TCGv cur_val, TCGv in_val, TCGv out_val,
> > +target_ulong reg_mask) {
> 
> Brace on new line per coding standard. Also I would line up the
> indentation with

Hmm - odd, I could have sworn checkpatch gave this a green light.  ☹  I will 
fix it.

> the rest of the arguments to match the rest of the hexagon frontend. I would
> suggest putting output arguments first to match other TCG ops, could become
> confusing otherwise, so
> 
>  void gen_masked_reg_write(TCGv out_val, TCGv in_val, TCGv cur_val,
>target_ulong reg_mask)
>  {
> 
> > +TCGv set_bits = tcg_temp_new();
> > +TCGv cleared_bits = tcg_temp_new();
> > +
> > +/*
> > + * set_bits = in_val & reg_mask
> > + * cleared_bits = (~in_val) & reg_mask
> > + */
> > +tcg_gen_andi_tl(set_bits, in_val, reg_mask);
> > +tcg_gen_not_tl(cleared_bits, in_val);
> > +tcg_gen_andi_tl(cleared_bits, cleared_bits, reg_mask);
> > +
> > +/*
> > + * result = (reg_cur | set_bits) & (~cleared_bits)
> > + */
> > +tcg_gen_not_tl(cleared_bits, cleared_bits);
> > +tcg_gen_or_tl(set_bits, set_bits, cur_val);
> > +tcg_gen_and_tl(out_val, set_bits, cleared_bits);
> > +
> > +tcg_temp_free(set_bits);
> > +tcg_temp_free(cleared_bits);
> > +}
> 
> You could cut down on a single not operation in this function since
> 
>  ~cleared_bits = ~((~in_val) & reg_mask)
>= in_val | (~reg_mask)
> 
> I looked at the output of qemu-hexagon -d op_opt and this operation
> is not performed by the TCG optimizer, so we would end up saving
> an instruction.

IIUC Richard's suggestion reduces it yet further, so I'll use that algorithm 
instead.

> > diff --git a/target/hexagon/gen_masked.h b/target/hexagon/gen_masked.h
> > new file mode 100644
> > index 00..71f4b2818b
> > --- /dev/null
> > +++ b/target/hexagon/gen_masked.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + *  Copyright(c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of the GNU General Public License as published by
> > + *  the Free Software Foundation; either version 2 of the License, or
> > + *  (at your option) any later version.
> > + *
> > + *  This program is distributed in the hope that it will be useful,
> > + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + *  GNU General Public License for more details.
> > + *
> > + *  You should have received a copy of the GNU General Public License
> > + *  along with this program; if not, see .
> > + */
> > +
> > +#ifndef GEN_MASKED_H
> > +#define GEN_MASKED_H
> > +
> > 

[PATCH 2/2] tpm_emulator: Have swtpm relock storage upon migration fall-back

2022-09-07 Thread Stefan Berger
Swtpm may release the lock once the last one of its state blobs has been
migrated out. In case of VM migration failure QEMU now needs to notify
swtpm that it should again take the lock, which it can otherwise only do
once it has received the first TPM command from the VM.

Only try to send the lock command if swtpm supports it. It will not have
released the lock (and support shared storage setups) if it doesn't
support the locking command since the functionality of releasing the lock
upon state blob reception and the lock command were added to swtpm
'together'.

If QEMU sends the lock command and the storage has already been locked
no error is reported.

If swtpm does not receive the lock command (from older version of QEMU),
it will lock the storage once the first TPM command has been received. So
sending the lock command is an optimization.

Signed-off-by: Stefan Berger 
---
 backends/tpm/tpm_emulator.c | 60 -
 backends/tpm/trace-events   |  2 ++
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 87d061e9bb..905ebfc8a9 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -34,6 +34,7 @@
 #include "io/channel-socket.h"
 #include "sysemu/tpm_backend.h"
 #include "sysemu/tpm_util.h"
+#include "sysemu/runstate.h"
 #include "tpm_int.h"
 #include "tpm_ioctl.h"
 #include "migration/blocker.h"
@@ -81,6 +82,9 @@ struct TPMEmulator {
 unsigned int established_flag_cached:1;
 
 TPMBlobBuffers state_blobs;
+
+bool relock_storage;
+VMChangeStateEntry *vmstate;
 };
 
 struct tpm_error {
@@ -302,6 +306,35 @@ static int tpm_emulator_stop_tpm(TPMBackend *tb)
 return 0;
 }
 
+static int tpm_emulator_lock_storage(TPMEmulator *tpm_emu)
+{
+ptm_lockstorage pls;
+
+if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, PTM_CAP_LOCK_STORAGE)) {
+trace_tpm_emulator_lock_storage_cmd_not_supt();
+return 0;
+}
+
+/* give failing side 100 * 10ms time to release lock */
+pls.u.req.retries = cpu_to_be32(100);
+if (tpm_emulator_ctrlcmd(tpm_emu, CMD_LOCK_STORAGE, ,
+ sizeof(pls.u.req), sizeof(pls.u.resp)) < 0) {
+error_report("tpm-emulator: Could not lock storage: %s",
+ strerror(errno));
+return -1;
+}
+
+pls.u.resp.tpm_result = be32_to_cpu(pls.u.resp.tpm_result);
+if (pls.u.resp.tpm_result != 0) {
+error_report("tpm-emulator: TPM result for CMD_LOCK_STORAGE: 0x%x %s",
+ pls.u.resp.tpm_result,
+ tpm_emulator_strerror(pls.u.resp.tpm_result));
+return -1;
+}
+
+return 0;
+}
+
 static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 size_t wanted_size,
 size_t *actual_size)
@@ -843,13 +876,34 @@ static int tpm_emulator_pre_save(void *opaque)
 {
 TPMBackend *tb = opaque;
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
+int ret;
 
 trace_tpm_emulator_pre_save();
 
 tpm_backend_finish_sync(tb);
 
 /* get the state blobs from the TPM */
-return tpm_emulator_get_state_blobs(tpm_emu);
+ret = tpm_emulator_get_state_blobs(tpm_emu);
+
+tpm_emu->relock_storage = ret == 0;
+
+return ret;
+}
+
+static void tpm_emulator_vm_state_change(void *opaque, bool running,
+ RunState state)
+{
+TPMBackend *tb = opaque;
+TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
+
+trace_tpm_emulator_vm_state_change(running, state);
+
+if (!running || state != RUN_STATE_RUNNING || !tpm_emu->relock_storage) {
+return;
+}
+
+/* lock storage after migration fall-back */
+tpm_emulator_lock_storage(tpm_emu);
 }
 
 /*
@@ -911,6 +965,9 @@ static void tpm_emulator_inst_init(Object *obj)
 tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
 tpm_emu->cur_locty_number = ~0;
 qemu_mutex_init(_emu->mutex);
+tpm_emu->vmstate =
+qemu_add_vm_change_state_handler(tpm_emulator_vm_state_change,
+ tpm_emu);
 
 vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
  _tpm_emulator, obj);
@@ -960,6 +1017,7 @@ static void tpm_emulator_inst_finalize(Object *obj)
 tpm_sized_buffer_reset(_blobs->savestate);
 
 qemu_mutex_destroy(_emu->mutex);
+qemu_del_vm_change_state_handler(tpm_emu->vmstate);
 
 vmstate_unregister(NULL, _tpm_emulator, obj);
 }
diff --git a/backends/tpm/trace-events b/backends/tpm/trace-events
index 3298766dd7..1ecef42a07 100644
--- a/backends/tpm/trace-events
+++ b/backends/tpm/trace-events
@@ -20,6 +20,8 @@ tpm_emulator_set_buffer_size(uint32_t buffersize, uint32_t 
minsize, uint32_t max
 tpm_emulator_startup_tpm_resume(bool is_resume, size_t buffersize) "is_resume: 
%d, buffer size: %zu"
 tpm_emulator_get_tpm_established_flag(uint8_t flag) "got established flag: %d"
 

[PATCH 0/2] tpm_emulator: Signal swtpm to again lock storage

2022-09-07 Thread Stefan Berger
Swtpm has been extended to release the lock on the storage where its state
is written to upon migration of the last one of its state blobs. Signal
swtpm to again lock the storage upon migration fallback. An explicit signal
helps swtpm to lock the storage earlier because otherwise it would have
to wait for the next TPM command from the VM.

Releasing the lock on the storage is necessary for setups where the storage
holding the TPM state is shared between hosts.

Regards,
   Stefan

Stefan Berger (2):
  tpm_emulator: Use latest tpm_ioctl.h from swtpm project
  tpm_emulator: Have swtpm relock storage upon migration fall-back

 backends/tpm/tpm_emulator.c | 60 ++-
 backends/tpm/tpm_ioctl.h| 96 +
 backends/tpm/trace-events   |  2 +
 3 files changed, 137 insertions(+), 21 deletions(-)

-- 
2.37.2




[PATCH 1/2] tpm_emulator: Use latest tpm_ioctl.h from swtpm project

2022-09-07 Thread Stefan Berger
Use the latest tpm_ioctl.h from upstream swtpm project.

Signed-off-by: Stefan Berger 
---
 backends/tpm/tpm_ioctl.h | 96 +++-
 1 file changed, 76 insertions(+), 20 deletions(-)

diff --git a/backends/tpm/tpm_ioctl.h b/backends/tpm/tpm_ioctl.h
index d67bf0283b..e506ef5160 100644
--- a/backends/tpm/tpm_ioctl.h
+++ b/backends/tpm/tpm_ioctl.h
@@ -5,10 +5,15 @@
  *
  * This file is licensed under the terms of the 3-clause BSD license
  */
+#ifndef _TPM_IOCTL_H_
+#define _TPM_IOCTL_H_
 
-#ifndef TPM_IOCTL_H
-#define TPM_IOCTL_H
+#if defined(__CYGWIN__)
+# define __USE_LINUX_IOCTL_DEFS
+#endif
 
+#include 
+#include 
 #ifndef _WIN32
 #include 
 #include 
@@ -196,6 +201,48 @@ struct ptm_setbuffersize {
 } u;
 };
 
+#define PTM_GETINFO_SIZE (3 * 1024)
+/*
+ * PTM_GET_INFO: Get info about the TPM implementation (from libtpms)
+ *
+ * This request allows to indirectly call TPMLIB_GetInfo(flags) and
+ * retrieve information from libtpms.
+ * Only one transaction is currently necessary for returning results
+ * to a client. Therefore, totlength and length will be the same if
+ * offset is 0.
+ */
+struct ptm_getinfo {
+union {
+struct {
+uint64_t flags;
+uint32_t offset;  /* offset from where to read */
+uint32_t pad; /* 32 bit arch */
+} req; /* request */
+struct {
+ptm_res tpm_result;
+uint32_t totlength;
+uint32_t length;
+char buffer[PTM_GETINFO_SIZE];
+} resp; /* response */
+} u;
+};
+
+#define SWTPM_INFO_TPMSPECIFICATION ((uint64_t)1 << 0)
+#define SWTPM_INFO_TPMATTRIBUTES((uint64_t)1 << 1)
+
+/*
+ * PTM_LOCK_STORAGE: Lock the storage and retry n times
+ */
+struct ptm_lockstorage {
+union {
+struct {
+uint32_t retries; /* number of retries */
+} req; /* request */
+struct {
+ptm_res tpm_result;
+} resp; /* reponse */
+} u;
+};
 
 typedef uint64_t ptm_cap;
 typedef struct ptm_est ptm_est;
@@ -207,6 +254,8 @@ typedef struct ptm_getstate ptm_getstate;
 typedef struct ptm_setstate ptm_setstate;
 typedef struct ptm_getconfig ptm_getconfig;
 typedef struct ptm_setbuffersize ptm_setbuffersize;
+typedef struct ptm_getinfo ptm_getinfo;
+typedef struct ptm_lockstorage ptm_lockstorage;
 
 /* capability flags returned by PTM_GET_CAPABILITY */
 #define PTM_CAP_INIT   (1)
@@ -223,6 +272,9 @@ typedef struct ptm_setbuffersize ptm_setbuffersize;
 #define PTM_CAP_GET_CONFIG (1 << 11)
 #define PTM_CAP_SET_DATAFD (1 << 12)
 #define PTM_CAP_SET_BUFFERSIZE (1 << 13)
+#define PTM_CAP_GET_INFO   (1 << 14)
+#define PTM_CAP_SEND_COMMAND_HEADER (1 << 15)
+#define PTM_CAP_LOCK_STORAGE   (1 << 16)
 
 #ifndef _WIN32
 enum {
@@ -243,6 +295,8 @@ enum {
 PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig),
 PTM_SET_DATAFD = _IOR('P', 15, ptm_res),
 PTM_SET_BUFFERSIZE = _IOWR('P', 16, ptm_setbuffersize),
+PTM_GET_INFO   = _IOWR('P', 17, ptm_getinfo),
+PTM_LOCK_STORAGE   = _IOWR('P', 18, ptm_lockstorage),
 };
 #endif
 
@@ -257,23 +311,25 @@ enum {
  * and ptm_set_state:u.req.data) are 0x.
  */
 enum {
-CMD_GET_CAPABILITY = 1,
-CMD_INIT,
-CMD_SHUTDOWN,
-CMD_GET_TPMESTABLISHED,
-CMD_SET_LOCALITY,
-CMD_HASH_START,
-CMD_HASH_DATA,
-CMD_HASH_END,
-CMD_CANCEL_TPM_CMD,
-CMD_STORE_VOLATILE,
-CMD_RESET_TPMESTABLISHED,
-CMD_GET_STATEBLOB,
-CMD_SET_STATEBLOB,
-CMD_STOP,
-CMD_GET_CONFIG,
-CMD_SET_DATAFD,
-CMD_SET_BUFFERSIZE,
+CMD_GET_CAPABILITY = 1,   /* 0x01 */
+CMD_INIT, /* 0x02 */
+CMD_SHUTDOWN, /* 0x03 */
+CMD_GET_TPMESTABLISHED,   /* 0x04 */
+CMD_SET_LOCALITY, /* 0x05 */
+CMD_HASH_START,   /* 0x06 */
+CMD_HASH_DATA,/* 0x07 */
+CMD_HASH_END, /* 0x08 */
+CMD_CANCEL_TPM_CMD,   /* 0x09 */
+CMD_STORE_VOLATILE,   /* 0x0a */
+CMD_RESET_TPMESTABLISHED, /* 0x0b */
+CMD_GET_STATEBLOB,/* 0x0c */
+CMD_SET_STATEBLOB,/* 0x0d */
+CMD_STOP, /* 0x0e */
+CMD_GET_CONFIG,   /* 0x0f */
+CMD_SET_DATAFD,   /* 0x10 */
+CMD_SET_BUFFERSIZE,   /* 0x11 */
+CMD_GET_INFO, /* 0x12 */
+CMD_LOCK_STORAGE, /* 0x13 */
 };
 
-#endif /* TPM_IOCTL_H */
+#endif /* _TPM_IOCTL_H_ */
-- 
2.37.2




Re: [PATCH] Hexagon (target/hexagon) implement mutability mask for GPRs

2022-09-07 Thread Richard Henderson

On 9/6/22 23:26, Taylor Simpson wrote:

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
8a334ba07b..21385f556e 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
  static inline void gen_log_reg_write(int rnum, TCGv val)  {
-tcg_gen_mov_tl(hex_new_value[rnum], val);
+const hexagon_mut_entry entry = gpr_mut_masks[rnum];
+if (entry.present) {
+gen_masked_reg_write(hex_gpr[rnum], val, hex_new_value[rnum],


You can't write to hex_gpr here.  You have to wait to make sure the packet will 
commit.  Put this result back into val and do the mov to hex_new_value 
unconditionally.


The feedback, then, is that the operands are confusingly ordered -- the output is to 
hex_new_value.  Brian, tcg functions generally list outputs first.



r~



Re: [PATCH] hw/intc: Handle software disabling of APIC correctly

2022-09-07 Thread Jay Khandkar
Have sent in v2.

On Wed, Aug 17, 2022 at 4:20 PM Michael S. Tsirkin  wrote:

> On Fri, Jul 29, 2022 at 11:04:47PM +0530, Jay Khandkar wrote:
> > On Fri, Jul 29, 2022 at 06:09:01PM +0100, Peter Maydell wrote:
> > > On Tue, 12 Jul 2022 at 19:38, Jay Khandkar 
> wrote:
> > > >
> > > > When the local APIC is in a software disabled state, all local
> interrupt
> > > > sources must be masked and all attempts to unmask them should be
> > > > ignored. Currently, we don't do either. Fix this by handling it
> > > > correctly in apic_mem_write().
> > > >
> > > > Signed-off-by: Jay Khandkar 
> > > > ---
> > > >  hw/intc/apic.c | 16 +---
> > > >  1 file changed, 13 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/hw/intc/apic.c b/hw/intc/apic.c
> > > > index 3df11c34d6..493c70af62 100644
> > > > --- a/hw/intc/apic.c
> > > > +++ b/hw/intc/apic.c
> > > > @@ -792,9 +792,16 @@ static void apic_mem_write(void *opaque, hwaddr
> addr, uint64_t val,
> > > >  s->dest_mode = val >> 28;
> > > >  break;
> > > >  case 0x0f:
> > > > -s->spurious_vec = val & 0x1ff;
> > > > -apic_update_irq(s);
> > > > -break;
> > > > +{
> > > > +s->spurious_vec = val & 0x1ff;
> > > > +if (!(val & APIC_SPURIO_ENABLED)) {
> > > > +for (int i = 0; i < APIC_LVT_NB; i++) {
> > > > +s->lvt[i] |= APIC_LVT_MASKED;
> > > > +}
> > > > +}
> > > > +apic_update_irq(s);
> > > > +break;
> > > > +}
> > >
> > > What are the braces for here ? There's no local variable declaration...
> > >
> > > thanks
> > > -- PMM
> > You are right, the braces are unnecessary for that part. I just put them
> in to
> > create a neat visually separate block. Can get rid of them.
> >
> > Thanks,
> > Jay
>
> Did you intend to send v2 of this?
>
> --
> MST
>
>


[PATCH V2] hw/intc: Handle software disabling of APIC correctly

2022-09-07 Thread Jay Khandkar
When the local APIC is in a software disabled state, all local interrupt
sources must be masked and all attempts to unmask them should be
ignored. Currently, we don't do either. Fix this by handling it
correctly in apic_mem_write().

Signed-off-by: Jay Khandkar 
---
 hw/intc/apic.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 3df11c34d6..be26b5c913 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -793,6 +793,11 @@ static void apic_mem_write(void *opaque, hwaddr addr, 
uint64_t val,
 break;
 case 0x0f:
 s->spurious_vec = val & 0x1ff;
+if (!(val & APIC_SPURIO_ENABLED)) {
+for (int i = 0; i < APIC_LVT_NB; i++) {
+s->lvt[i] |= APIC_LVT_MASKED;
+}
+}
 apic_update_irq(s);
 break;
 case 0x10 ... 0x17:
@@ -812,6 +817,9 @@ static void apic_mem_write(void *opaque, hwaddr addr, 
uint64_t val,
 case 0x32 ... 0x37:
 {
 int n = index - 0x32;
+if (!(s->spurious_vec & APIC_SPURIO_ENABLED)) {
+val |= APIC_LVT_MASKED;
+}
 s->lvt[n] = val;
 if (n == APIC_LVT_TIMER) {
 apic_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-- 
2.37.3




Re: Seeing qtest assertion failure with 7.1

2022-09-07 Thread Peter Maydell
On Wed, 7 Sept 2022 at 16:39, Patrick Venture  wrote:
>
> # Start of nvme tests
> # Start of pci-device tests
> # Start of pci-device-tests tests
> # starting QEMU: exec ./qemu-system-aarch64 -qtest unix:/tmp/qtest-1431.sock 
> -qtest-log /dev/null -chardev socket,path=/tmp/qtest-1431.qmp,id=char0 -mon 
> chardev=char0,mode=control -display none -M virt, -cpu max -drive 
> id=drv0,if=none,file=null-co://,file.read-zeroes=on,format=raw -object 
> memory-backend-ram,id=pmr0,share=on,size=8 -device 
> nvme,addr=04.0,drive=drv0,serial=foo -accel qtest
>
> # 
> ERROR:../../src/qemu/tests/qtest/libqtest.c:338:qtest_init_without_qmp_handshake:
>  assertion failed: (s->fd >= 0 && s->qmp_fd >= 0)
> stderr:
> double free or corruption (out)
> socket_accept failed: Resource temporarily unavailable
> **
> ERROR:../../src/qemu/tests/qtest/libqtest.c:338:qtest_init_without_qmp_handshake:
>  assertion failed: (s->fd >= 0 && s->qmp_fd >= 0)
> ../../src/qemu/tests/qtest/libqtest.c:165: kill_qemu() detected QEMU death 
> from signal 6 (Aborted) (core dumped)
>
> I'm not seeing this reliably, and we haven't done a lot of digging yet, such 
> as enabling sanitizers, so I'll reply back to this thread with details as I 
> have them.
>
> Has anyone seen this before or something like it?

Have a look in the source at what exactly the assertion
failure in libqtest.c is checking for -- IIRC it's a pretty
basic "did we open a socket fd" one. I think sometimes I
used to see something like this if there's an old stale socket
lying around in the test directory and the randomly generated
socket filename happens to clash with it.

Everything after that is probably follow-on errors from the
tests not being terribly clean about error handling.

Are you running 'make check' with a -j option for parallel?
(This is supposed to work, and it's the standard way I run
'make check', so if it's flaky we need to fix it, but it
would be interesting to know if the issue repros at -j1.)

-- PMM



[PATCH v2] audio: add help option for -audio and -audiodev

2022-09-07 Thread Claudio Fontana
add a simple help option for -audio and -audiodev
to show the list of available drivers, and document them.

Signed-off-by: Claudio Fontana 
---
 audio/audio.c   | 20 
 audio/audio.h   |  1 +
 qemu-options.hx | 10 ++
 softmmu/vl.c|  9 +++--
 4 files changed, 34 insertions(+), 6 deletions(-)

v1 -> v2: also extend the help to -audio.

 -audio help
 -audio driver=help
 -audiodev help

will all show the same results.

diff --git a/audio/audio.c b/audio/audio.c
index 4f4bb10cce..ffb09ec825 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -32,6 +32,7 @@
 #include "qapi/qapi-visit-audio.h"
 #include "qemu/cutils.h"
 #include "qemu/module.h"
+#include "qemu/help_option.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/replay.h"
 #include "sysemu/runstate.h"
@@ -2105,10 +2106,29 @@ static void audio_validate_opts(Audiodev *dev, Error 
**errp)
 }
 }
 
+void audio_help(void)
+{
+int i;
+
+printf("Available audio drivers:\n");
+printf("none\n");
+
+for (i = 0; audio_prio_list[i]; i++) {
+audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);
+if (driver) {
+printf("%s\n", driver->name);
+}
+}
+}
+
 void audio_parse_option(const char *opt)
 {
 Audiodev *dev = NULL;
 
+if (is_help_option(opt)) {
+audio_help();
+exit(EXIT_SUCCESS);
+}
 Visitor *v = qobject_input_visitor_new_str(opt, "driver", _fatal);
 visit_type_Audiodev(v, NULL, , _fatal);
 visit_free(v);
diff --git a/audio/audio.h b/audio/audio.h
index 27e67079a0..01bdc567fb 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -171,6 +171,7 @@ void audio_sample_from_uint64(void *samples, int pos,
 void audio_define(Audiodev *audio);
 void audio_parse_option(const char *opt);
 bool audio_init_audiodevs(void);
+void audio_help(void);
 void audio_legacy_help(void);
 
 AudioState *audio_state_by_name(const char *name);
diff --git a/qemu-options.hx b/qemu-options.hx
index 31c04f7eea..04cd4dacfc 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -704,10 +704,11 @@ SRST
 ``-audio [driver=]driver,model=value[,prop[=value][,...]]``
 This option is a shortcut for configuring both the guest audio
 hardware and the host audio backend in one go.
-The host backend options are the same as with the corresponding
-``-audiodev`` options below. The guest hardware model can be set with
-``model=modelname``. Use ``model=help`` to list the available device
-types.
+The driver option is the same as with the corresponding ``-audiodev`` 
option below.
+The guest hardware model can be set with ``model=modelname``.
+
+Use ``driver=help`` to list the available drivers,
+and ``model=help`` to list the available device types.
 
 The following two example do exactly the same, to show how ``-audio``
 can be used to shorten the command line length:
@@ -721,6 +722,7 @@ ERST
 DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
 "-audiodev [driver=]driver,id=id[,prop[=value][,...]]\n"
 "specifies the audio backend to use\n"
+"Use ``-audiodev help`` to list the available drivers\n"
 "id= identifier of the backend\n"
 "timer-period= timer period in microseconds\n"
 "in|out.mixing-engine= use mixing engine to mix streams 
inside QEMU\n"
diff --git a/softmmu/vl.c b/softmmu/vl.c
index dea4005e47..2f8eecf5c1 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2842,11 +2842,16 @@ void qemu_init(int argc, char **argv, char **envp)
 audio_parse_option(optarg);
 break;
 case QEMU_OPTION_audio: {
-QDict *dict = keyval_parse(optarg, "driver", NULL, 
_fatal);
+bool help;
 char *model;
 Audiodev *dev = NULL;
 Visitor *v;
-
+QDict *dict = keyval_parse(optarg, "driver", , 
_fatal);
+if (help || (qdict_haskey(dict, "driver") &&
+ is_help_option(qdict_get_str(dict, "driver" {
+audio_help();
+exit(EXIT_SUCCESS);
+}
 if (!qdict_haskey(dict, "id")) {
 qdict_put_str(dict, "id", "audiodev0");
 }
-- 
2.26.2




Re: [PATCH v5 0/2] block: add missed block_acct_setup with new block device init procedure

2022-09-07 Thread Denis V. Lunev

On 8/24/22 11:50, Denis V. Lunev wrote:

Commit 5f76a7aac156ca75680dad5df4a385fd0b58f6b1 is looking harmless from
the first glance, but it has changed things a lot. 'libvirt' uses it to
detect that it should follow new initialization way and this changes
things considerably. With this procedure followed, blockdev_init() is
not called anymore and thus block_acct_setup() helper is not called.

This means in particular that defaults for block accounting statistics
are changed and account_invalid/account_failed are actually initialized
as false instead of true originally.

This commit changes things to match original world. There are the following
constraints:
* new default value in block_acct_init() is set to true
* block_acct_setup() inside blockdev_init() is called before
   blkconf_apply_backend_options()
* thus newly created option in block device properties has precedence if
   specified

Changes from v4:
* removed hunk to QAPI which was used to test old initialization path
* added R-b: Vladimir

Changes from v3:
* fixed accidentally wrong submission. Contains changes which should be
   sent as v3

Changes from v2:
* called bool_from_onoffauto(account_..., true) in the first patch to
   preserve original semantics before patch 2

Changes from v1:
* set account_invalid/account_failed to true by default
* pass OnOffAuto to block_acct_init() to handle double initialization (patch 1)
* changed properties on BLK device to OnOffAuto

Signed-off-by: Denis V. Lunev 
CC: Peter Krempa 
CC: Markus Armbruster 
CC: John Snow 
CC: Kevin Wolf 
CC: Hanna Reitz 
CC: Vladimir Sementsov-Ogievskiy 



ping



Re: [PATCH for 7.2] minor fixups in block code

2022-09-07 Thread Denis V. Lunev

On 8/17/22 10:37, Denis V. Lunev wrote:

These 2 patches are just minor improvements to make code a bit better.

Signed-off-by: Denis V. Lunev 
CC: Kevin Wolf 
CC: Hanna Reitz 
CC: Stefan Hajnoczi 
CC: Fam Zheng 
CC: Ronnie Sahlberg 
CC: Paolo Bonzini 
CC: Peter Lieven 
CC: Vladimir Sementsov-Ogievskiy 



ping v2



Re: [PATCH 3/8] scripts/ci/setup: Fix libxen requirements

2022-09-07 Thread Alex Bennée


"Lucas Mateus Castro(alqotel)"  writes:

> XEN hypervisor is only available in ARM and x86, but the yaml only
> checked if the architecture is different from s390x, changed it to
> a more accurate test.
> Tested this change on a Ubuntu 20.04 ppc64le.
>
> Signed-off-by: Lucas Mateus Castro(alqotel)
> 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée



Re: [PATCH v2 16/20] disas/nanomips: Replace exception handling

2022-09-07 Thread Milica Lazarevic

On 9/5/22 10:55, Milica Lazarevic wrote:
> Since there's no support for exception handling in C, the try-catch
> blocks have been deleted, and throw clauses are replaced. When a runtime
> error happens, we're printing out the error message. Disassembling of
> the current instruction interrupts. This behavior is achieved by adding
> sigsetjmp() to discard further disassembling after the error message
> prints and by adding the siglongjmp() function to imitate throwing an
> error. The goal was to maintain the same output as it was.
>
> Signed-off-by: Milica Lazarevic 
> ---
>   disas/nanomips.cpp | 126 ++---
>   1 file changed, 61 insertions(+), 65 deletions(-)
>
> diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
> index 5142f307fc..a8295ebfa8 100644
> --- a/disas/nanomips.cpp
> +++ b/disas/nanomips.cpp
> @@ -31,7 +31,6 @@

> +disassembly_function dis_fn = table[i].disassembly;
> +if (dis_fn == 0) {
> +strcpy(dis,
> +"disassembler failure - bad table entry");
> +return -6;
> +}
> +type = table[i].type;
> +g_autofree char *dis_str = dis_fn(op_code, info);
> +strcpy(dis, dis_str);
> +return table[i].instructions_size;
> +} else {
> +strcpy(dis, "reserved instruction");
> +return -2;

Ought these errors use the same error path?


r~

I'm not sure if I understood the question correctly. The difference between 
these errors and the errors covered by the patch is that, in the case of the 
latter, the disassembling of one part of the instruction has already happened. 
For example, if we have an irregular GPR register index, the output of the 
assembler will look something like this:
...
0x80200622:  86ad 9018  Invalid GPR register index 33
...
On the other hand, if we have some error like "disassembler failure - bad table 
entry" - that string would be the only output regarding the instruction we're 
trying to disassemble. The disassembling process, in this case, hasn't begun, 
so there's no need for an interruption like in the previous example.

But yes, in both cases after printing the error message, the disassembling of 
the particular instruction is not continuing.


Re: [PATCH] crypto/block-luks: always set splitkeylen to 0

2022-09-07 Thread Patrick Venture
On Wed, Sep 7, 2022 at 9:34 AM Daniel P. Berrangé 
wrote:

> On Wed, Sep 07, 2022 at 09:21:25AM -0700, Patrick Venture wrote:
> > This was caught by a sanitized build, that was perhaps oversensitive.
> >
> > Signed-off-by: Patrick Venture 
> > ---
> >  crypto/block-luks.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> > index f62be6836b..8633fb7e9f 100644
> > --- a/crypto/block-luks.c
> > +++ b/crypto/block-luks.c
> > @@ -729,7 +729,7 @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
> >  QCryptoBlockLUKS *luks = block->opaque;
> >  QCryptoBlockLUKSKeySlot *slot;
> >  g_autofree uint8_t *splitkey = NULL;
> > -size_t splitkeylen;
> > +size_t splitkeylen = 0;
> >  g_autofree uint8_t *slotkey = NULL;
> >  g_autoptr(QCryptoCipher) cipher = NULL;
> >  g_autoptr(QCryptoIVGen) ivgen = NULL;
> > @@ -901,7 +901,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
> >  QCryptoBlockLUKS *luks = block->opaque;
> >  const QCryptoBlockLUKSKeySlot *slot;
> >  g_autofree uint8_t *splitkey = NULL;
> > -size_t splitkeylen;
> > +size_t splitkeylen = 0;
> >  g_autofree uint8_t *possiblekey = NULL;
> >  int rv;
> >  g_autoptr(QCryptoCipher) cipher = NULL;
> > @@ -1147,7 +1147,7 @@ qcrypto_block_luks_erase_key(QCryptoBlock *block,
> >  QCryptoBlockLUKS *luks = block->opaque;
> >  QCryptoBlockLUKSKeySlot *slot;
> >  g_autofree uint8_t *garbagesplitkey = NULL;
> > -size_t splitkeylen;
> > +size_t splitkeylen = 0;
> >  size_t i;
> >  Error *local_err = NULL;
> >  int ret;
>
> In all three cases, splitkeylen is initialized a few lines later.
>
> In qcrypto_block_luks_store_key there is a 'goto cleanup' before
> the initialization. The 'cleanup' code can use 'splitkeylen', but
> only if 'splitkey != NULL' & this isn't possible if splitkeylen is
> uninitialized.
>
> The other two methods have no code path where splitkeylen can be
> used uninitialized.
>
> The tool is reporting non-existant problems AFAICT
>

I'm 100% certain it is. I just needed to make the changes to get a
sanitized build of Qemu to build.  Presumably if someone else tries
building qemu with `--enable-sanitizers` they'll have to make the same
non-sense adjustment.


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


Re: [PATCH] crypto/block-luks: always set splitkeylen to 0

2022-09-07 Thread Daniel P . Berrangé
On Wed, Sep 07, 2022 at 09:21:25AM -0700, Patrick Venture wrote:
> This was caught by a sanitized build, that was perhaps oversensitive.
> 
> Signed-off-by: Patrick Venture 
> ---
>  crypto/block-luks.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index f62be6836b..8633fb7e9f 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -729,7 +729,7 @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
>  QCryptoBlockLUKS *luks = block->opaque;
>  QCryptoBlockLUKSKeySlot *slot;
>  g_autofree uint8_t *splitkey = NULL;
> -size_t splitkeylen;
> +size_t splitkeylen = 0;
>  g_autofree uint8_t *slotkey = NULL;
>  g_autoptr(QCryptoCipher) cipher = NULL;
>  g_autoptr(QCryptoIVGen) ivgen = NULL;
> @@ -901,7 +901,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
>  QCryptoBlockLUKS *luks = block->opaque;
>  const QCryptoBlockLUKSKeySlot *slot;
>  g_autofree uint8_t *splitkey = NULL;
> -size_t splitkeylen;
> +size_t splitkeylen = 0;
>  g_autofree uint8_t *possiblekey = NULL;
>  int rv;
>  g_autoptr(QCryptoCipher) cipher = NULL;
> @@ -1147,7 +1147,7 @@ qcrypto_block_luks_erase_key(QCryptoBlock *block,
>  QCryptoBlockLUKS *luks = block->opaque;
>  QCryptoBlockLUKSKeySlot *slot;
>  g_autofree uint8_t *garbagesplitkey = NULL;
> -size_t splitkeylen;
> +size_t splitkeylen = 0;
>  size_t i;
>  Error *local_err = NULL;
>  int ret;

In all three cases, splitkeylen is initialized a few lines later.

In qcrypto_block_luks_store_key there is a 'goto cleanup' before
the initialization. The 'cleanup' code can use 'splitkeylen', but
only if 'splitkey != NULL' & this isn't possible if splitkeylen is
uninitialized.

The other two methods have no code path where splitkeylen can be
used uninitialized.

The tool is reporting non-existant problems AFAICT

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




Re: [PATCH 0/6] parallels: Add duplication check, repair at open, fix bugs

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

This patchset is based on
git: https://src.openvz.org/~den/qemu.git parallels

Fix incorrect data end calculation in parallels_open().

Add parallels_handle_leak() and highest_offset() helpers.

Add checking and repairing duplicate offsets in BAT.

Deduplicate highest offset calculation.

Replace fprintf() by qemu_log().

Add check and repair to parallels_open().


Alexander Ivanov (6):
   parallels: Incorrect data end calculation in parallels_open()
   parallels: Create parallels_handle_leak() to truncate excess clusters
   parallels: Add checking and repairing duplicate offsets in BAT
   parallels: Use highest_offset() helper in leak check
   parallels: Replace fprintf by qemu_log
   parallels: Image repairing in parallels_open()

  block/parallels.c | 297 +-
  1 file changed, 241 insertions(+), 56 deletions(-)


common note - please fix formatting in the patch descriptions.
74 characters on a line, empty line between paragraphs.

Den



Re: [PATCH v7 05/14] mm/memfd: Introduce MFD_INACCESSIBLE flag

2022-09-07 Thread Kirill A. Shutemov
On Fri, Aug 05, 2022 at 03:28:50PM +0200, David Hildenbrand wrote:
> On 06.07.22 10:20, Chao Peng wrote:
> > Introduce a new memfd_create() flag indicating the content of the
> > created memfd is inaccessible from userspace through ordinary MMU
> > access (e.g., read/write/mmap). However, the file content can be
> > accessed via a different mechanism (e.g. KVM MMU) indirectly.
> > 
> > It provides semantics required for KVM guest private memory support
> > that a file descriptor with this flag set is going to be used as the
> > source of guest memory in confidential computing environments such
> > as Intel TDX/AMD SEV but may not be accessible from host userspace.
> > 
> > The flag can not coexist with MFD_ALLOW_SEALING, future sealing is
> > also impossible for a memfd created with this flag.
> 
> It's kind of weird to have it that way. Why should the user have to
> care? It's the notifier requirement to have that, no?
> 
> Why can't we handle that when register a notifier? If anything is
> already mapped, fail registering the notifier if the notifier has these
> demands. If registering succeeds, block it internally.
> 
> Or what am I missing? We might not need the memfile set flag semantics
> eventually and would not have to expose such a flag to user space.

Well, with the new shim-based[1] implementation the approach without uAPI
does not work.

We now have two struct file, one is a normal accessible memfd and the
other one is wrapper around that hides the memfd from userspace and
filters allowed operations. If we first create an accessible memfd that
userspace see it would be hard to hide it as by the time userspace may
have multiple fds in different processes that point to the same struct
file.

[1] 
https://lore.kernel.org/all/20220831142439.65q2gi4g2d2z4...@box.shutemov.name

-- 
  Kiryl Shutsemau / Kirill A. Shutemov



[PATCH] crypto/block-luks: always set splitkeylen to 0

2022-09-07 Thread Patrick Venture
This was caught by a sanitized build, that was perhaps oversensitive.

Signed-off-by: Patrick Venture 
---
 crypto/block-luks.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index f62be6836b..8633fb7e9f 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -729,7 +729,7 @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
 QCryptoBlockLUKS *luks = block->opaque;
 QCryptoBlockLUKSKeySlot *slot;
 g_autofree uint8_t *splitkey = NULL;
-size_t splitkeylen;
+size_t splitkeylen = 0;
 g_autofree uint8_t *slotkey = NULL;
 g_autoptr(QCryptoCipher) cipher = NULL;
 g_autoptr(QCryptoIVGen) ivgen = NULL;
@@ -901,7 +901,7 @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
 QCryptoBlockLUKS *luks = block->opaque;
 const QCryptoBlockLUKSKeySlot *slot;
 g_autofree uint8_t *splitkey = NULL;
-size_t splitkeylen;
+size_t splitkeylen = 0;
 g_autofree uint8_t *possiblekey = NULL;
 int rv;
 g_autoptr(QCryptoCipher) cipher = NULL;
@@ -1147,7 +1147,7 @@ qcrypto_block_luks_erase_key(QCryptoBlock *block,
 QCryptoBlockLUKS *luks = block->opaque;
 QCryptoBlockLUKSKeySlot *slot;
 g_autofree uint8_t *garbagesplitkey = NULL;
-size_t splitkeylen;
+size_t splitkeylen = 0;
 size_t i;
 Error *local_err = NULL;
 int ret;
-- 
2.37.2.789.g6183377224-goog




Re: [PATCH 2/6] parallels: Create parallels_handle_leak() to truncate excess clusters

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

This helper will be reused in the next patch for duplications check.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 65 +++
  1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 7b4e997ebd..dbcaf5d310 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -475,37 +475,23 @@ static int parallels_check_outside_image(BlockDriverState 
*bs,
  return 0;
  }
  
-static int parallels_check_leak(BlockDriverState *bs,

-BdrvCheckResult *res,
-BdrvCheckMode fix)
+static int64_t parallels_handle_leak(BlockDriverState *bs,
+ BdrvCheckResult *res,
+ int64_t high_off,
+ bool fix)
  {
  BDRVParallelsState *s = bs->opaque;
-int64_t size, off, high_off, count;
-uint32_t i;
+int64_t size;
  int ret;
  
  size = bdrv_getlength(bs->file->bs);

  if (size < 0) {
-res->check_errors++;
  return size;
  }
  
-high_off = 0;

-for (i = 0; i < s->bat_size; i++) {
-off = bat2sect(s, i) << BDRV_SECTOR_BITS;
-if (off > high_off) {
-high_off = off;
-}
-}
-
  res->image_end_offset = high_off + s->cluster_size;
  if (size > res->image_end_offset) {
-count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size);
-fprintf(stderr, "%s space leaked at the end of the image %" PRId64 
"\n",
-fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
-size - res->image_end_offset);
-res->leaks += count;
-if (fix & BDRV_FIX_LEAKS) {
+if (fix) {
  Error *local_err = NULL;
  
  /*

@@ -516,13 +502,48 @@ static int parallels_check_leak(BlockDriverState *bs,
  PREALLOC_MODE_OFF, 0, _err);
  if (ret < 0) {
  error_report_err(local_err);
-res->check_errors++;
  return ret;
  }
-res->leaks_fixed += count;
  }
  }
  
+return size - res->image_end_offset;

+}
+
+static int parallels_check_leak(BlockDriverState *bs,
+BdrvCheckResult *res,
+BdrvCheckMode fix)
+{
+BDRVParallelsState *s = bs->opaque;
+int64_t off, high_off, count, cut_out;
+uint32_t i;
+
+high_off = 0;
+for (i = 0; i < s->bat_size; i++) {
+off = bat2sect(s, i) << BDRV_SECTOR_BITS;
+if (off > high_off) {
+high_off = off;
+}
+}
+
+cut_out = parallels_handle_leak(bs, res, high_off, fix & BDRV_FIX_LEAKS);
+if (cut_out < 0) {
+res->check_errors++;
+return cut_out;
+}
+if (cut_out == 0) {
+return 0;
+}
+
+count = DIV_ROUND_UP(cut_out, s->cluster_size);
+fprintf(stderr, "%s space leaked at the end of the image %" PRId64 "\n",
+fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR", cut_out);
+
+res->leaks += count;
+if (fix & BDRV_FIX_LEAKS) {
+res->leaks_fixed += count;
+}
+
  return 0;
  }
  

I do not think that we need this helper. See the note to the next patch



Re: [PATCH 3/6] parallels: Add checking and repairing duplicate offsets in BAT

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

Cluster offsets must be unique among all BAT entries.
Find duplicate offsets in the BAT.

If a duplicated offset is found fix it by copying the content
of the relevant cluster to a new allocated cluster and
set the new cluster offset to the duplicated entry.

Add host_cluster_index() helper to deduplicate the code.
Add highest_offset() helper. It will be used for code deduplication
in the next patch.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 136 ++
  1 file changed, 136 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index dbcaf5d310..339ce45634 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -136,6 +136,26 @@ static int cluster_remainder(BDRVParallelsState *s, 
int64_t sector_num,
  return MIN(nb_sectors, ret);
  }
  
+static uint32_t host_cluster_index(BDRVParallelsState *s, int64_t off)

+{
+off -= s->header->data_off << BDRV_SECTOR_BITS;
+return off / s->cluster_size;

not properly aligned cluster is a problem by itself
This is possible for older image format and I believe that
we should run "leak check" even for it and note that
in "not aligned" case one should call 'qemu-img convert"
and copy what can be saved. The error is really hard to
recover.


+}
+
+static int64_t highest_offset(BDRVParallelsState *s)
+{
+int64_t off, high_off = 0;
+int i;
+
+for (i = 0; i < s->bat_size; i++) {
+off = bat2sect(s, i) << BDRV_SECTOR_BITS;
+if (off > high_off) {
+high_off = off;
+}
+}
+return high_off;
+}
+
  static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
  int nb_sectors, int *pnum)
  {
@@ -547,6 +567,114 @@ static int parallels_check_leak(BlockDriverState *bs,
  return 0;
  }
  
+static int parallels_check_duplicate(BlockDriverState *bs,

+ BdrvCheckResult *res,
+ BdrvCheckMode fix)
+{
+BDRVParallelsState *s = bs->opaque;
+QEMUIOVector qiov;
+int64_t off, high_off, sector;
+unsigned long *bitmap;
+uint32_t i, bitmap_size, cluster_index;
+int n, ret = 0;
+uint64_t *buf = NULL;
+bool new_allocations = false;
+
+high_off = highest_offset(s);
+if (high_off == 0) {
+return 0;
+}
+
+/*
+ * Create a bitmap of used clusters.
+ * If a bit is set, there is a BAT entry pointing to this cluster.
+ * Loop through the BAT entrues, check bits relevant to an entry offset.

s/entrues/entries/

+ * If bit is set, this entry is duplicated. Otherwise set the bit.
+ */
+bitmap_size = host_cluster_index(s, high_off) + 1;
+bitmap = bitmap_new(bitmap_size);

this is wrong de-facto. once you deduplicate, you will have clusters
outside the bitmap. We should use MAX(high_off, virtual_size(bds))
OK, may be this is correct, see my note below, but that's needs
a comment.


+
+buf = g_malloc(s->cluster_size);

nope-nope. you should use memalign as you could have
O_DIRECT IO later on with this buffer


+qemu_iovec_init(, 0);
+qemu_iovec_add(, buf, s->cluster_size);
+
+for (i = 0; i < s->bat_size; i++) {
+off = bat2sect(s, i) << BDRV_SECTOR_BITS;
+if (off == 0) {
+continue;
+}
+
+cluster_index = host_cluster_index(s, off);
+if (test_bit(cluster_index, bitmap)) {
+/* this cluster duplicates another one */
+fprintf(stderr,
+"%s duplicate offset in BAT entry %u\n",
+fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
+
+res->corruptions++;
+
+if (fix & BDRV_FIX_ERRORS) {
+/*
+ * Reset the entry and allocate a new cluster
+ * for the relevant guest offset. In this way we let
+ * the lower layer to place the new cluster properly.
+ * Copy the original cluster to the allocated one.
+ */
+parallels_set_bat_entry(s, i, 0);
+
+ret = bdrv_pread(bs->file, off, s->cluster_size, buf, 0);

I believe that we are for sure in co-routine context thus
bdrv_co_pread would be better



+if (ret < 0) {
+res->check_errors++;
+goto out;
+}
+
+sector = (i * s->cluster_size) >> BDRV_SECTOR_BITS;
+off = allocate_clusters(bs, sector, s->tracks, );

no way. Please do not keep bytes and sectors in the same variable
That makes code unreadable


+if (off < 0) {
+res->check_errors++;
+ret = off;
+goto out;
+}
+off <<= BDRV_SECTOR_BITS;
+if (off > high_off) {
+high_off = off;
+}
+
+ret = bdrv_co_pwritev(bs->file, off, 

Re: [PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Daniel P. Berrangé wrote:

On Wed, Sep 07, 2022 at 05:06:36PM +0200, Markus Armbruster wrote:

Claudio Fontana  writes:


add a simple help option for -audiodev, so users can do

qemu -audiodev ?


The preferred form is actually '-audiodev help'.  The other one is
deprecated.  Recommend to stay away from it even in commit messages.


We introduced 'help' many many years ago, but don't thing we
ever formally deprecated '?'.  Should we do so and aim to
remove it, or are we happy to keep '?' forever, despite it
tripping up shell filename expansion with single char filenames.


Had this conversation before and I think we agreed to keep ? as a 
convenient shorthand even if help is preferred so it should not be 
deprecated but you can keep it from appearing in docs to advertise help as 
the preferred option. (\? is still shorter to type than help if you're 
worried about shell expansion which is rarely a problem in practice)


Regards,
BALATON Zoltan


(tangential to this patch, NOT a request to fix something in v2)



to get the list of drivers available.

Signed-off-by: Claudio Fontana 
---
 audio/audio.c | 20 
 1 file changed, 20 insertions(+)


Update qemu-options.hx ?


With regards,
Daniel


Re: [PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread Claudio Fontana
On 9/7/22 17:06, Markus Armbruster wrote:
> Claudio Fontana  writes:
> 
>> add a simple help option for -audiodev, so users can do
>>
>> qemu -audiodev ?
> 
> The preferred form is actually '-audiodev help'.  The other one is
> deprecated.  Recommend to stay away from it even in commit messages.

I have no problem mentioning "help" instead of "?" in the commit message (or 
both).

The function used (is_help_option) checks for both, which seems the best way to 
me.

Ciao

C

> 
>>
>> to get the list of drivers available.
>>
>> Signed-off-by: Claudio Fontana 
>> ---
>>  audio/audio.c | 20 
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/audio/audio.c b/audio/audio.c
>> index 4f4bb10cce..bd8c18c3cd 100644
>> --- a/audio/audio.c
>> +++ b/audio/audio.c
>> @@ -32,6 +32,7 @@
>>  #include "qapi/qapi-visit-audio.h"
>>  #include "qemu/cutils.h"
>>  #include "qemu/module.h"
>> +#include "qemu/help_option.h"
>>  #include "sysemu/sysemu.h"
>>  #include "sysemu/replay.h"
>>  #include "sysemu/runstate.h"
>> @@ -2105,10 +2106,29 @@ static void audio_validate_opts(Audiodev *dev, Error 
>> **errp)
>>  }
>>  }
>>  
>> +static void audio_help(void)
>> +{
>> +int i;
>> +
>> +printf("Available audiodev types:\n");
>> +printf("none\n");
>> +
>> +for (i = 0; audio_prio_list[i]; i++) {
>> +audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);
>> +if (driver) {
>> +printf("%s\n", driver->name);
>> +}
>> +}
>> +}
>> +
>>  void audio_parse_option(const char *opt)
>>  {
>>  Audiodev *dev = NULL;
>>  
>> +if (is_help_option(opt)) {
>> +audio_help();
>> +exit(0);
>> +}
>>  Visitor *v = qobject_input_visitor_new_str(opt, "driver", _fatal);
>>  visit_type_Audiodev(v, NULL, , _fatal);
>>  visit_free(v);
> 




Re: [PATCH 6/6] parallels: Image repairing in parallels_open()

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:53, Alexander Ivanov wrote:

Repair an image at opening if the image is unclean or
out-of-image corruption was detected.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 95 ---
  1 file changed, 65 insertions(+), 30 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 08526196da..a7c3af4ef2 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -735,6 +735,18 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,
  return ret;
  }
  
+typedef struct ParallelsOpenCheckCo {

+BlockDriverState *bs;
+BdrvCheckResult *res;
+BdrvCheckMode fix;
+int ret;
+} ParallelsOpenCheckCo;
+
+static void coroutine_fn parallels_co_open_check(void *opaque)
+{
+ParallelsOpenCheckCo *poc = opaque;
+poc->ret = parallels_co_check(poc->bs, poc->res, poc->fix);
+}
  
  static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,

  Error **errp)
@@ -947,8 +959,8 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  {
  BDRVParallelsState *s = bs->opaque;
  ParallelsHeader ph;
-int ret, size, i;
-int64_t file_size;
+int ret, size;
+int64_t file_size, high_off;
  QemuOpts *opts = NULL;
  Error *local_err = NULL;
  char *buf;
@@ -1027,34 +1039,6 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  }
  s->bat_bitmap = (uint32_t *)(s->header + 1);
  
-for (i = 0; i < s->bat_size; i++) {

-int64_t off = bat2sect(s, i);
-if (off >= file_size) {
-if (flags & BDRV_O_CHECK) {
-continue;
-}
-error_setg(errp, "parallels: Offset %" PRIi64 " in BAT[%d] entry "
-   "is larger than file size (%" PRIi64 ")",
-   off, i, file_size);
-ret = -EINVAL;
-goto fail;
-}
-if (off >= s->data_end) {
-s->data_end = off + s->tracks;
-}
-}
-
-if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
-/* Image was not closed correctly. The check is mandatory */
-s->header_unclean = true;
-if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
-error_setg(errp, "parallels: Image was not closed correctly; "
-   "cannot be opened read/write");
-ret = -EACCES;
-goto fail;
-}
-}
-
  opts = qemu_opts_create(_runtime_opts, NULL, 0, errp);
  if (!opts) {
  goto fail_options;
@@ -1116,7 +1100,58 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  error_free(s->migration_blocker);
  goto fail;
  }
+
  qemu_co_mutex_init(>lock);
+
+if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
+s->header_unclean = true;
+}
+
+high_off = highest_offset(s) >> BDRV_SECTOR_BITS;
+if (high_off >= s->data_end) {
+s->data_end = high_off + s->tracks;
+}
+
+/*
+ * We don't repair the image here if it is opened for checks.
+ * Also let to work with images in RO mode.

My silly $0.02.
Also let *us allow* to with in read-only more.


+ */
+if ((flags & BDRV_O_CHECK) || !(flags & BDRV_O_RDWR)) {
+return 0;
+}

not enough, We are not allowed to make changes with O_INACTIVE.
The check in this case should be postponed till O_INACTIVE clearance.

Very specific note. header_unclean is allowed in O_INACTIVE.
The image could be opened at the moment on the other
host!

This should be clarified.


+
+/*
+ * Repair the image if it's dirty or
+ * out-of-image corruption was detected.
+ */
+if (s->data_end > file_size ||
+le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {

I dislike this. There are detection conditions above
and I think we should respect them adding the flag
'need_check' which should be kept in the BDS to
respect O_INACTIVE.


+BdrvCheckResult res = {0};

such assignments are weird (not portable for older compilers).


+Coroutine *co;
+ParallelsOpenCheckCo poc = {
+.bs = bs,
+.res = ,

This is strange, why not to put BdrvCheckResult as
a whole to the ParallelsOpenCheckCo

+.fix = BDRV_FIX_ERRORS | BDRV_FIX_LEAKS,
+.ret = -EINPROGRESS

pls add comma on the line above, This is common convention
as in the case of addition one more initializing field you will
not change that line.

+};
+
+if (qemu_in_coroutine()) {
+/* From bdrv_co_create.  */
+parallels_co_open_check();
+} else {
+assert(qemu_get_current_aio_context() == qemu_get_aio_context());
+co = qemu_coroutine_create(parallels_co_open_check, );
+qemu_coroutine_enter(co);
+BDRV_POLL_WHILE(bs, poc.ret == -EINPROGRESS);
+}
+
+if (poc.ret < 0) {
+

Re: [PATCH 5/6] parallels: Replace fprintf by qemu_log

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

Use a standard QEMU function for logging.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 688aa081e2..08526196da 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -42,6 +42,7 @@
  #include "qemu/bswap.h"
  #include "qemu/bitmap.h"
  #include "qemu/memalign.h"
+#include "qemu/log-for-trace.h"
  #include "migration/blocker.h"
  #include "parallels.h"
  
@@ -448,7 +449,7 @@ static void parallels_check_unclean(BlockDriverState *bs,

  return;
  }
  
-fprintf(stderr, "%s image was not closed correctly\n",

+qemu_log("%s image was not closed correctly\n",
  fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
  res->corruptions++;
  if (fix & BDRV_FIX_ERRORS) {
@@ -476,7 +477,7 @@ static int parallels_check_outside_image(BlockDriverState 
*bs,
  for (i = 0; i < s->bat_size; i++) {
  off = bat2sect(s, i) << BDRV_SECTOR_BITS;
  if (off >= size) {
-fprintf(stderr, "%s cluster %u is outside image\n",
+qemu_log("%s cluster %u is outside image\n",
  fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
  res->corruptions++;
  if (fix & BDRV_FIX_ERRORS) {
@@ -549,7 +550,7 @@ static int parallels_check_leak(BlockDriverState *bs,
  }
  
  count = DIV_ROUND_UP(cut_out, s->cluster_size);

-fprintf(stderr, "%s space leaked at the end of the image %" PRId64 "\n",
+qemu_log("%s space leaked at the end of the image %" PRId64 "\n",
  fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR", cut_out);
  
  res->leaks += count;

@@ -600,8 +601,7 @@ static int parallels_check_duplicate(BlockDriverState *bs,
  cluster_index = host_cluster_index(s, off);
  if (test_bit(cluster_index, bitmap)) {
  /* this cluster duplicates another one */
-fprintf(stderr,
-"%s duplicate offset in BAT entry %u\n",
+qemu_log("%s duplicate offset in BAT entry %u\n",
  fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
  
  res->corruptions++;
formatting is broken. next line after qemu_log should be indented with 
one more space.


I would be happy to get more detailed motivation, which should say that 
once the check
will be called during normal work, tracking of the check MUST be present 
in VM log

to have some clues if something will go wrong with customer's data.

Den



Re: [PATCH 4/6] parallels: Use highest_offset() helper in leak check

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

Deduplicate code by using highest_offset() helper.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 11 ++-
  1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 339ce45634..688aa081e2 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -535,16 +535,9 @@ static int parallels_check_leak(BlockDriverState *bs,
  BdrvCheckMode fix)
  {
  BDRVParallelsState *s = bs->opaque;
-int64_t off, high_off, count, cut_out;
-uint32_t i;
+int64_t high_off, count, cut_out;
  
-high_off = 0;

-for (i = 0; i < s->bat_size; i++) {
-off = bat2sect(s, i) << BDRV_SECTOR_BITS;
-if (off > high_off) {
-high_off = off;
-}
-}
+high_off = highest_offset(s);
  
  cut_out = parallels_handle_leak(bs, res, high_off, fix & BDRV_FIX_LEAKS);

  if (cut_out < 0) {

Here I kinda disagree. This change and the introduction of the
helper should be done exactly in the same patch as in the other
case it is not possible to say whether this replacement is
correct or not.

Den



Seeing qtest assertion failure with 7.1

2022-09-07 Thread Patrick Venture
# Start of nvme tests
# Start of pci-device tests
# Start of pci-device-tests tests
# starting QEMU: exec ./qemu-system-aarch64 -qtest
unix:/tmp/qtest-1431.sock -qtest-log /dev/null -chardev
socket,path=/tmp/qtest-1431.qmp,id=char0 -mon chardev=char0,mode=control
-display none -M virt, -cpu max -drive
id=drv0,if=none,file=null-co://,file.read-zeroes=on,format=raw -object
memory-backend-ram,id=pmr0,share=on,size=8 -device
nvme,addr=04.0,drive=drv0,serial=foo -accel qtest

#
ERROR:../../src/qemu/tests/qtest/libqtest.c:338:qtest_init_without_qmp_handshake:
assertion failed: (s->fd >= 0 && s->qmp_fd >= 0)
stderr:
double free or corruption (out)
socket_accept failed: Resource temporarily unavailable
**
ERROR:../../src/qemu/tests/qtest/libqtest.c:338:qtest_init_without_qmp_handshake:
assertion failed: (s->fd >= 0 && s->qmp_fd >= 0)
../../src/qemu/tests/qtest/libqtest.c:165: kill_qemu() detected QEMU death
from signal 6 (Aborted) (core dumped)

I'm not seeing this reliably, and we haven't done a lot of digging yet,
such as enabling sanitizers, so I'll reply back to this thread with details
as I have them.

Has anyone seen this before or something like it?

Patrick


Re: [PATCH 1/6] parallels: Incorrect data end calculation in parallels_open()

2022-09-07 Thread Denis V. Lunev

On 9/2/22 10:52, Alexander Ivanov wrote:

The BDRVParallelsState structure contains data_end field that
is measured in sectors.
In parallels_open() initially this field is set by data_off field from
parallels image header.

According to the parallels format documentation,
data_off field contains an offset, in sectors, from the start of the file
to the start of the data area.
For "WithoutFreeSpace" images: if data_off is zero,
the offset is calculated as the end of the BAT table
plus some padding to ensure sector size alignment.

The parallels_open() function has code for handling zero value
in data_off, but in the result data_end contains the offset in bytes.

Replace the alignment to sector size by division by sector size
and fix the comparision with s->header_size.

Signed-off-by: Alexander Ivanov 
---
  block/parallels.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index e6e8b9e369..7b4e997ebd 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -863,9 +863,9 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  }
  s->data_end = le32_to_cpu(ph.data_off);
  if (s->data_end == 0) {
-s->data_end = ROUND_UP(bat_entry_off(s->bat_size), BDRV_SECTOR_SIZE);
+s->data_end = DIV_ROUND_UP(size, BDRV_SECTOR_SIZE);
  }
-if (s->data_end < s->header_size) {
+if (s->data_end < (s->header_size >> BDRV_SECTOR_BITS)) {
  /* there is not enough unused space to fit to block align between BAT
 and actual data. We can't avoid read-modify-write... */
  s->header_size = size;

Reviewed-by: Denis V. Lunev 

Sidenote: if the image is truncated for more than BAT size and there is 
no data inside
the image, we would get memory corruption during BAT access. That should 
be addressed

separately.



Re: [PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread Daniel P . Berrangé
On Wed, Sep 07, 2022 at 05:06:36PM +0200, Markus Armbruster wrote:
> Claudio Fontana  writes:
> 
> > add a simple help option for -audiodev, so users can do
> >
> > qemu -audiodev ?
> 
> The preferred form is actually '-audiodev help'.  The other one is
> deprecated.  Recommend to stay away from it even in commit messages.

We introduced 'help' many many years ago, but don't thing we
ever formally deprecated '?'.  Should we do so and aim to
remove it, or are we happy to keep '?' forever, despite it
tripping up shell filename expansion with single char filenames.

(tangential to this patch, NOT a request to fix something in v2)

> >
> > to get the list of drivers available.
> >
> > Signed-off-by: Claudio Fontana 
> > ---
> >  audio/audio.c | 20 
> >  1 file changed, 20 insertions(+)

Update qemu-options.hx ?


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




Re: [PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread Markus Armbruster
Claudio Fontana  writes:

> add a simple help option for -audiodev, so users can do
>
> qemu -audiodev ?

The preferred form is actually '-audiodev help'.  The other one is
deprecated.  Recommend to stay away from it even in commit messages.

>
> to get the list of drivers available.
>
> Signed-off-by: Claudio Fontana 
> ---
>  audio/audio.c | 20 
>  1 file changed, 20 insertions(+)
>
> diff --git a/audio/audio.c b/audio/audio.c
> index 4f4bb10cce..bd8c18c3cd 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -32,6 +32,7 @@
>  #include "qapi/qapi-visit-audio.h"
>  #include "qemu/cutils.h"
>  #include "qemu/module.h"
> +#include "qemu/help_option.h"
>  #include "sysemu/sysemu.h"
>  #include "sysemu/replay.h"
>  #include "sysemu/runstate.h"
> @@ -2105,10 +2106,29 @@ static void audio_validate_opts(Audiodev *dev, Error 
> **errp)
>  }
>  }
>  
> +static void audio_help(void)
> +{
> +int i;
> +
> +printf("Available audiodev types:\n");
> +printf("none\n");
> +
> +for (i = 0; audio_prio_list[i]; i++) {
> +audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);
> +if (driver) {
> +printf("%s\n", driver->name);
> +}
> +}
> +}
> +
>  void audio_parse_option(const char *opt)
>  {
>  Audiodev *dev = NULL;
>  
> +if (is_help_option(opt)) {
> +audio_help();
> +exit(0);
> +}
>  Visitor *v = qobject_input_visitor_new_str(opt, "driver", _fatal);
>  visit_type_Audiodev(v, NULL, , _fatal);
>  visit_free(v);




[PULL 04/10] qapi: fix example of BLOCK_JOB_READY event

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output is missing ',' delimiter. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-5-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/block-core.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 2173e7734a..882b266532 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5252,7 +5252,7 @@
 #
 # <- { "event": "BLOCK_JOB_READY",
 #  "data": { "device": "drive0", "type": "mirror", "speed": 0,
-#"len": 2097152, "offset": 2097152 }
+#"len": 2097152, "offset": 2097152 },
 #  "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
 #
 ##
-- 
2.37.2




[PULL 10/10] qapi: fix examples of events missing timestamp

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

I've used real timestamp and changing them one by one so they would
not be all equal.

Problem was noticed when using the example as a test case for Go
bindings.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-11-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/migration.json | 27 +++
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/qapi/migration.json b/qapi/migration.json
index 81185d4311..88ecf86ac8 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1995,16 +1995,23 @@
 #}
 # <- { "return": { } }
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1432121972, "microseconds": 744001},
 # "data": {"status": "created", "id": "snapsave0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1432122172, "microseconds": 744001},
 # "data": {"status": "running", "id": "snapsave0"}}
-# <- {"event": "STOP"}
-# <- {"event": "RESUME"}
+# <- {"event": "STOP",
+# "timestamp": {"seconds": 1432122372, "microseconds": 744001} }
+# <- {"event": "RESUME",
+# "timestamp": {"seconds": 1432122572, "microseconds": 744001} }
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1432122772, "microseconds": 744001},
 # "data": {"status": "waiting", "id": "snapsave0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1432122972, "microseconds": 744001},
 # "data": {"status": "pending", "id": "snapsave0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1432123172, "microseconds": 744001},
 # "data": {"status": "concluded", "id": "snapsave0"}}
 # -> {"execute": "query-jobs"}
 # <- {"return": [{"current-progress": 1,
@@ -2056,16 +2063,23 @@
 #}
 # <- { "return": { } }
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1472124172, "microseconds": 744001},
 # "data": {"status": "created", "id": "snapload0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1472125172, "microseconds": 744001},
 # "data": {"status": "running", "id": "snapload0"}}
-# <- {"event": "STOP"}
-# <- {"event": "RESUME"}
+# <- {"event": "STOP",
+# "timestamp": {"seconds": 1472125472, "microseconds": 744001} }
+# <- {"event": "RESUME",
+# "timestamp": {"seconds": 1472125872, "microseconds": 744001} }
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1472126172, "microseconds": 744001},
 # "data": {"status": "waiting", "id": "snapload0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1472127172, "microseconds": 744001},
 # "data": {"status": "pending", "id": "snapload0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1472128172, "microseconds": 744001},
 # "data": {"status": "concluded", "id": "snapload0"}}
 # -> {"execute": "query-jobs"}
 # <- {"return": [{"current-progress": 1,
@@ -2108,14 +2122,19 @@
 #}
 # <- { "return": { } }
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1442124172, "microseconds": 744001},
 # "data": {"status": "created", "id": "snapdelete0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1442125172, "microseconds": 744001},
 # "data": {"status": "running", "id": "snapdelete0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1442126172, "microseconds": 744001},
 # "data": {"status": "waiting", "id": "snapdelete0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1442127172, "microseconds": 744001},
 # "data": {"status": "pending", "id": "snapdelete0"}}
 # <- {"event": "JOB_STATUS_CHANGE",
+# "timestamp": {"seconds": 1442128172, "microseconds": 744001},
 # "data": {"status": "concluded", "id": "snapdelete0"}}
 # -> {"execute": "query-jobs"}
 # <- {"return": [{"current-progress": 1,
-- 
2.37.2




[PULL 03/10] qapi: fix example of query-dump-guest-memory-capability command

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output is missing closing curly brackets. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-4-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/dump.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/dump.json b/qapi/dump.json
index 90859c5483..6fc215dd47 100644
--- a/qapi/dump.json
+++ b/qapi/dump.json
@@ -195,7 +195,7 @@
 #
 # -> { "execute": "query-dump-guest-memory-capability" }
 # <- { "return": { "formats":
-#  ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
+#  ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] } }
 #
 ##
 { 'command': 'query-dump-guest-memory-capability',
-- 
2.37.2




[PULL 01/10] qapi: fix example of query-ballon command

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output has an extra ',' delimiter. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-2-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/machine.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 6afd1936b0..5f1f50d3ed 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1074,7 +1074,7 @@
 #
 # -> { "execute": "query-balloon" }
 # <- { "return": {
-#  "actual": 1073741824,
+#  "actual": 1073741824
 #   }
 #}
 #
-- 
2.37.2




[PULL 07/10] qapi: fix example of MEM_UNPLUG_ERROR event

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output was missing ',' delimiter. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-8-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/machine.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 5f1f50d3ed..4782eea2c3 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1416,7 +1416,7 @@
 #
 # Example:
 #
-# <- { "event": "MEM_UNPLUG_ERROR"
+# <- { "event": "MEM_UNPLUG_ERROR",
 #  "data": { "device": "dimm1",
 #"msg": "acpi: device unplug for unsupported device"
 #  },
-- 
2.37.2




[PULL 02/10] qapi: fix example of query-vnc command

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output has an extra ',' delimiter in member "websocket" and it
lacks it in "family" member. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-3-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/ui.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/ui.json b/qapi/ui.json
index cf58ab4283..286c5731d1 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -667,8 +667,8 @@
 # {
 #"host":"127.0.0.1",
 #"service":"50401",
-#"family":"ipv4"
-#"websocket":false,
+#"family":"ipv4",
+#"websocket":false
 # }
 #  ]
 #   }
-- 
2.37.2




[PULL 08/10] qapi: fix examples of blockdev-add with qcow2

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

The examples use "qcow2" driver with the wrong member name for
BlockdevRef alternate type. This patch changes all wrong member names
from "file" to "data-file" which is the correct member name in
BlockdevOptionsQcow2 for the BlockdevRef field.

Problem was noticed when using the example as a test case for Go
bindings.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-9-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/block-core.json | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 882b266532..f21fa235f2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1541,8 +1541,8 @@
 # -> { "execute": "blockdev-add",
 #  "arguments": { "driver": "qcow2",
 # "node-name": "node1534",
-# "file": { "driver": "file",
-#   "filename": "hd1.qcow2" },
+# "data-file": { "driver": "file",
+#"filename": "hd1.qcow2" },
 # "backing": null } }
 #
 # <- { "return": {} }
@@ -4378,7 +4378,7 @@
 #  "arguments": {
 #   "driver": "qcow2",
 #   "node-name": "test1",
-#   "file": {
+#   "data-file": {
 #   "driver": "file",
 #   "filename": "test.qcow2"
 #}
@@ -4395,7 +4395,7 @@
 #   "cache": {
 #  "direct": true
 #},
-#"file": {
+#   "data-file": {
 #  "driver": "file",
 #  "filename": "/tmp/test.qcow2"
 #},
@@ -4477,7 +4477,7 @@
 #  "arguments": {
 #   "driver": "qcow2",
 #   "node-name": "node0",
-#   "file": {
+#   "data-file": {
 #   "driver": "file",
 #   "filename": "test.qcow2"
 #   }
-- 
2.37.2




[PULL 05/10] qapi: fix example of NIC_RX_FILTER_CHANGED event

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output has an extra ending curly bracket. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-6-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/net.json | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qapi/net.json b/qapi/net.json
index 75ba2cb989..dd088c09c5 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -757,7 +757,6 @@
 #  "data": { "name": "vnet0",
 #"path": "/machine/peripheral/vnet0/virtio-backend" },
 #  "timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
-#}
 #
 ##
 { 'event': 'NIC_RX_FILTER_CHANGED',
-- 
2.37.2




[PULL 09/10] qapi: fix example of query-hotpluggable-cpus command

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

The example return type has the wrong member name. Fix it.

Problem was noticed when using the example as a test case for Go
bindings.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-10-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/machine.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 4782eea2c3..abb2f48808 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -958,9 +958,9 @@
 #
 # -> { "execute": "query-hotpluggable-cpus" }
 # <- {"return": [
-#  { "props": { "core": 8 }, "type": "POWER8-spapr-cpu-core",
+#  { "props": { "core-id": 8 }, "type": "POWER8-spapr-cpu-core",
 #"vcpus-count": 1 },
-#  { "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core",
+#  { "props": { "core-id": 0 }, "type": "POWER8-spapr-cpu-core",
 #"vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"}
 #]}'
 #
-- 
2.37.2




[PULL 00/10] QAPI patches patches for 2022-09-07

2022-09-07 Thread Markus Armbruster
The following changes since commit 946e9bccf12f2bcc3ca471b820738fb22d14fc80:

  Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into 
staging (2022-09-06 08:31:24 -0400)

are available in the Git repository at:

  git://repo.or.cz/qemu/armbru.git tags/pull-qapi-2022-09-07

for you to fetch changes up to 6e7a37ffc230d06852f1a8893097331d39df77c9:

  qapi: fix examples of events missing timestamp (2022-09-07 15:10:13 +0200)


QAPI patches patches for 2022-09-07


Victor Toso (10):
  qapi: fix example of query-ballon command
  qapi: fix example of query-vnc command
  qapi: fix example of query-dump-guest-memory-capability command
  qapi: fix example of BLOCK_JOB_READY event
  qapi: fix example of NIC_RX_FILTER_CHANGED event
  qapi: fix example of DEVICE_UNPLUG_GUEST_ERROR event
  qapi: fix example of MEM_UNPLUG_ERROR event
  qapi: fix examples of blockdev-add with qcow2
  qapi: fix example of query-hotpluggable-cpus command
  qapi: fix examples of events missing timestamp

 qapi/block-core.json | 12 ++--
 qapi/dump.json   |  2 +-
 qapi/machine.json|  8 
 qapi/migration.json  | 27 +++
 qapi/net.json|  1 -
 qapi/qdev.json   |  3 +--
 qapi/ui.json |  4 ++--
 7 files changed, 37 insertions(+), 20 deletions(-)

-- 
2.37.2




[PULL 06/10] qapi: fix example of DEVICE_UNPLUG_GUEST_ERROR event

2022-09-07 Thread Markus Armbruster
From: Victor Toso 

Example output is missing a ',' delimiter and it has an extra ending
curly bracket. Fix it.

Problem was noticed when trying to load the example into python's json
library.

Signed-off-by: Victor Toso 
Message-Id: <20220901085840.22520-7-victort...@redhat.com>
Signed-off-by: Markus Armbruster 
---
 qapi/qdev.json | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/qapi/qdev.json b/qapi/qdev.json
index 26cd10106b..2708fb4e99 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -150,10 +150,9 @@
 #
 # Example:
 #
-# <- { "event": "DEVICE_UNPLUG_GUEST_ERROR"
+# <- { "event": "DEVICE_UNPLUG_GUEST_ERROR",
 #  "data": { "device": "core1",
 #"path": "/machine/peripheral/core1" },
-#  },
 #  "timestamp": { "seconds": 1615570772, "microseconds": 202844 } }
 #
 ##
-- 
2.37.2




Re: [PATCH 06/20] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

Instead of checking if memory size is valid in board code move this
check to ppc4xx_sdram_init() as this is a restriction imposed by the
SDRAM controller.

Signed-off-by: BALATON Zoltan 


It looks like a good clean up. At some point, I think we will need to
pass "MemoryRegion *sysmem" to the SDRAM model.  Let's start with this
change and see how it evolves.


Not sure what you mean here, this and the QOM'ify patches later in the 
series change it to pass the memory region from board to the dram property 
of the SDRAM controller model. This allows the board to set any memory 
region or alias as the SoC memory area.



One small comment below
Reviewed-by: Cédric Le Goater 

Thanks,


C.


---
  hw/ppc/ppc405.h |  2 --
  hw/ppc/ppc405_boards.c  | 10 --
  hw/ppc/ppc405_uc.c  | 11 ++-
  hw/ppc/ppc440_bamboo.c  | 10 +-
  hw/ppc/ppc4xx_devs.c| 14 ++
  include/hw/ppc/ppc4xx.h |  2 +-
  6 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ca0972b88b..ad54dff542 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
/* Public */
-Ppc4xxSdramBank ram_banks[2];
  MemoryRegion *dram_mr;
-hwaddr ram_size;
PowerPCCPU cpu;
  PPCUIC uic;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 0a29ad97c7..a82b6c5c83 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -278,21 +278,11 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)

  static void ppc405_init(MachineState *machine)
  {
  Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(machine);
  const char *kernel_filename = machine->kernel_filename;
  MemoryRegion *sysmem = get_system_memory();
  -if (machine->ram_size != mc->default_ram_size) {
-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM size, should be %s", sz);
-g_free(sz);
-exit(EXIT_FAILURE);
-}
-
  object_initialize_child(OBJECT(machine), "soc", >soc,
  TYPE_PPC405_SOC);
-object_property_set_uint(OBJECT(>soc), "ram-size",
- machine->ram_size, _fatal);
  object_property_set_link(OBJECT(>soc), "dram",
   OBJECT(machine->ram), _abort);
  object_property_set_uint(OBJECT(>soc), "sys-clk", ,
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 461d18c8a5..4049fb98dc 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1070,15 +1070,9 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)
 qdev_get_gpio_in(DEVICE(>cpu), 
PPC40x_INPUT_CINT));

/* SDRAM controller */
-/* XXX 405EP has no ECC interrupt */
-s->ram_banks[0].base = 0;
-s->ram_banks[0].size = s->ram_size;
-memory_region_init_alias(>ram_banks[0].ram, OBJECT(s),
- "ppc405.sdram0", s->dram_mr,
- s->ram_banks[0].base, s->ram_banks[0].size);
-
+/* XXX 405EP has no ECC interrupt */
  ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(>uic), 17), 1,
-  s->ram_banks);
+  s->dram_mr);
/* External bus controller */
  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>ebc), >cpu, errp)) {
@@ -1156,7 +1150,6 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)

  static Property ppc405_soc_properties[] = {
  DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
   MemoryRegion *),
-DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
  DEFINE_PROP_END_OF_LIST(),
  };
  diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 2bd5e41140..9b456f1819 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -50,10 +50,6 @@
#define PPC440EP_SDRAM_NR_BANKS 4
  -static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {
-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 
0

-};
-
  static hwaddr entry;
static int bamboo_load_device_tree(hwaddr addr,
@@ -168,8 +164,6 @@ static void bamboo_init(MachineState *machine)
  unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
-PPC440EP_SDRAM_NR_BANKS);
  PCIBus *pcibus;
  PowerPCCPU *cpu;
  CPUPPCState *env;
@@ -204,11 +198,9 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
/* SDRAM controller */
-ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_banks,
- 

Re: [PATCH v1 0/8] migration: introduce dirtylimit capability

2022-09-07 Thread Hyman




在 2022/9/7 4:46, Peter Xu 写道:

On Fri, Sep 02, 2022 at 01:22:28AM +0800, huang...@chinatelecom.cn wrote:

From: Hyman Huang(黄勇) 

v1:
- make parameter vcpu-dirty-limit experimental
- switch dirty limit off when cancel migrate
- add cancel logic in migration test

Please review, thanks,

Yong

Abstract


This series added a new migration capability called "dirtylimit".  It can
be enabled when dirty ring is enabled, and it'll improve the vCPU performance
during the process of migration. It is based on the previous patchset:
https://lore.kernel.org/qemu-devel/cover.1656177590.git.huang...@chinatelecom.cn/

As mentioned in patchset "support dirty restraint on vCPU", dirtylimit way of
migration can make the read-process not be penalized. This series wires up the
vcpu dirty limit and wrappers as dirtylimit capability of migration. I introduce
two parameters vcpu-dirtylimit-period and vcpu-dirtylimit to implement the setup
of dirtylimit during live migration.

To validate the implementation, i tested a 32 vCPU vm live migration with such
model:
Only dirty vcpu0, vcpu1 with heavy memory workoad and leave the rest vcpus
untouched, running unixbench on the vpcu8-vcpu15 by setup the cpu affinity as
the following command:
taskset -c 8-15 ./Run -i 2 -c 8 {unixbench test item}

The following are results:

host cpu: Intel(R) Xeon(R) Platinum 8378A
host interface speed: 1000Mb/s
   |-+++---|
   | UnixBench test item | Normal | Dirtylimit | Auto-converge |
   |-+++---|
   | dhry2reg| 32800  | 32786  | 25292 |
   | whetstone-double| 10326  | 10315  | 9847  |
   | pipe| 15442  | 15271  | 14506 |
   | context1| 7260   | 6235   | 4514  |
   | spawn   | 3663   | 3317   | 3249  |
   | syscall | 4669   | 4667   | 3841  |
   |-+++---|
 From the data above we can draw a conclusion that vcpus that do not dirty 
memory
in vm are almost unaffected during the dirtylimit migration, but the auto 
converge
way does.

I also tested the total time of dirtylimit migration with variable dirty memory
size in vm.

senario 1:
host cpu: Intel(R) Xeon(R) Platinum 8378A
host interface speed: 1000Mb/s
   |---++---|
   | dirty memory size(MB) | Dirtylimit(ms) | Auto-converge(ms) |
   |---++---|
   | 60| 2014   | 2131  |
   | 70| 5381   | 12590 |
   | 90| 6037   | 33545 |
   | 110   | 7660   | [*]   |
   |---++---|
   [*]: This case means migration is not convergent.

senario 2:
host cpu: Intel(R) Xeon(R) CPU E5-2650
host interface speed: 1Mb/s
   |---++---|
   | dirty memory size(MB) | Dirtylimit(ms) | Auto-converge(ms) |
   |---++---|
   | 1600  | 15842  | 27548 |
   | 2000  | 19026  | 38447 |
   | 2400  | 19897  | 46381 |
   | 2800  | 22338  | 57149 |
   |---++---|
Above data shows that dirtylimit way of migration can also reduce the total
time of migration and it achieves convergence more easily in some case.

In addition to implement dirtylimit capability itself, this series
add 3 tests for migration, aiming at playing around for developer simply:
  1. qtest for dirty limit migration
  2. support dirty ring way of migration for guestperf tool
  3. support dirty limit migration for guestperf tool


Yong,

I should have asked even earlier - just curious whether you have started
using this in production systems?  It's definitely not required for any
patchset to be merged, but it'll be very useful (and supportive)
information to have if there's proper testing beds applied already.

Actually no when i posted the cover letter above, the qemu version in 
our production is much lower than upstream, and the patchset is 
different from here, i built test mode and did the test on my own in the 
first time. But this feature is in the process of test conducted by 
another professional test team, so once report is ready, i'll post it. :)

Thanks,





Re: [PATCH 14/20] ppc440_sdram: Move RAM size check to ppc440_sdram_init

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

Move the check for valid memory sizes from board to sdram contrller


controller


init. Board now only checks for additinal restrictions imposed by


additional


Thanks for finding these spelling mistakes, looks like I was in a hurry...


firmware then sdram init checks for valid sizes for SoC.

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440.h|  4 ++--
  hw/ppc/ppc440_uc.c | 15 +++
  hw/ppc/sam460ex.c  | 32 +---
  3 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 7bd5cca1ab..29f6f14ed7 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,13 +11,13 @@
  #ifndef PPC440_H
  #define PPC440_H
  -#include "hw/ppc/ppc4xx.h"
+#include "hw/ppc/ppc.h"
void ppc4xx_l2sram_init(CPUPPCState *env);
  void ppc4xx_cpr_init(CPUPPCState *env);
  void ppc4xx_sdr_init(CPUPPCState *env);
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank ram_banks[]);
+   MemoryRegion *ram);
  void ppc4xx_ahb_init(CPUPPCState *env);
  void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
  void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index b39c6dbbd2..e77d56225d 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -486,7 +486,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  typedef struct ppc440_sdram_t {
  uint32_t addr;
  uint32_t mcopt2;
-int nbanks;
+int nbanks; /* Banks to use from the 4, e.g. when board has less slots 
*/

  Ppc4xxSdramBank bank[4];
  } ppc440_sdram_t;
  @@ -728,18 +728,17 @@ static void sdram_ddr2_reset(void *opaque)
  }
void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank ram_banks[])
+   MemoryRegion *ram)
  {
  ppc440_sdram_t *s;
-int i;
+const ram_addr_t valid_bank_sizes[] = {
+4 * GiB, 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * 
MiB,

+32 * MiB, 16 * MiB, 8 * MiB, 0
+};
s = g_malloc0(sizeof(*s));
  s->nbanks = nbanks;
-for (i = 0; i < nbanks; i++) {
-s->bank[i].ram = ram_banks[i].ram;
-s->bank[i].base = ram_banks[i].base;
-s->bank[i].size = ram_banks[i].size;
-}
+ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
  qemu_register_reset(_ddr2_reset, s);
  ppc_dcr_register(env, SDRAM0_CFGADDR,
   s, _ddr2_dcr_read, _ddr2_dcr_write);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index dac329d482..9b850808a3 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -74,13 +74,6 @@
  #define EBC_FREQ 11500
  #define UART_FREQ 11059200
  -/* The SoC could also handle 4 GiB but firmware does not work with that. 
*/

-/* Maybe it overflows a signed 32 bit number somewhere? */
-static const ram_addr_t ppc460ex_sdram_bank_sizes[] = {
-2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
-32 * MiB, 0
-};
-
  struct boot_info {
  uint32_t dt_base;
  uint32_t dt_size;
@@ -273,7 +266,6 @@ static void sam460ex_init(MachineState *machine)
  {
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank, 1);
  MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1);
  DeviceState *uic[4];
  int i;
@@ -340,12 +332,22 @@ static void sam460ex_init(MachineState *machine)
  }
/* SDRAM controller */
-/* put all RAM on first bank because board has one slot
- * and firmware only checks that */
-ppc4xx_sdram_banks(machine->ram, 1, ram_banks, 
ppc460ex_sdram_bank_sizes);

-
+/* The SoC could also handle 4 GiB but firmware does not work with 
that. */

+if (machine->ram_size > 2 * GiB) {
+error_report("Memory over 2 GiB is not supported");
+exit(1);
+}
+/* Firmware needs at least 64 MiB */
+if (machine->ram_size < 64 * MiB) {
+error_report("Memory below 64 MiB is not supported");
+exit(1);
+}



These checks on the RAM size should be done by the SDRAM model.

May be it is addressed later in the patchset ?


No, these are really board specific as the commenst say, they are imposed 
by board firmware (as firmware fails with other valid RAM sizes for the 
SoC) that's why these are here and the SoC size limits are checked in the 
SDRAM controller model.


Regards,
BALATON Zoltan


C.




+/*
+ * Put all RAM on first bank because board has one slot
+ * and firmware only checks that
+ */
+ppc440_sdram_init(env, 1, machine->ram);
  /* FIXME: does 460EX have ECC interrupts? */
-ppc440_sdram_init(env, 1, ram_banks);
  /* Enable SDRAM memory regions as we may boot without firmware */
  if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21) ||
  

Re: [PATCH 13/20] ppc4xx_sdram: Rename functions to prevent name clashes

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

Rename functions to avoid name clashes when moving the DDR2 controller
model currently called ppc440_sdram to ppc4xx_devs. This also more
clearly shows which function belongs to which model.


Shouldn't we introduce class handlers instead  ?


What do you mean? Could you please explain more?

Regards,
BALATON Zoltan


Thanks,

C.




Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c   | 69 ++--
  hw/ppc/ppc4xx_devs.c | 44 ++--
  2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 72eb75d3d2..b39c6dbbd2 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -502,7 +502,7 @@ enum {
  SDRAM_PLBADDUHB = 0x50,
  };
  -static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
+static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
  {
  uint32_t bcr;
  @@ -547,12 +547,12 @@ static uint32_t sdram_bcr(hwaddr ram_base, hwaddr 
ram_size)

  return bcr;
  }
  -static inline hwaddr sdram_base(uint32_t bcr)
+static inline hwaddr sdram_ddr2_base(uint32_t bcr)
  {
  return (bcr & 0xffe0) << 2;
  }
  -static uint64_t sdram_size(uint32_t bcr)
+static uint64_t sdram_ddr2_size(uint32_t bcr)
  {
  uint64_t size;
  int sh;
@@ -578,50 +578,51 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
  object_unparent(OBJECT(>container));
  }
  -static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
-  uint32_t bcr, int enabled)
+static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
+   uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
- sdram_size(sdram->bank[i].bcr));
+trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
+ sdram_ddr2_size(sdram->bank[i].bcr));
  sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
-sdram->bank[i].base = sdram_base(bcr);
-sdram->bank[i].size = sdram_size(bcr);
+sdram->bank[i].base = sdram_ddr2_base(bcr);
+sdram->bank[i].size = sdram_ddr2_size(bcr);
  if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
+trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), 
sdram_ddr2_size(bcr));

  sdram_bank_map(>bank[i]);
  }
  }
  -static void sdram_map_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
  {
  int i;
for (i = 0; i < sdram->nbanks; i++) {
  if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
+sdram_ddr2_set_bcr(sdram, i,
+   sdram_ddr2_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
-sdram_set_bcr(sdram, i, 0, 0);
+sdram_ddr2_set_bcr(sdram, i, 0, 0);
  }
  }
  }
  -static void sdram_unmap_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
  {
  int i;
for (i = 0; i < sdram->nbanks; i++) {
  if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
  }
  }
  }
  -static uint32_t dcr_read_sdram(void *opaque, int dcrn)
+static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
  {
  ppc440_sdram_t *sdram = opaque;
  uint32_t ret = 0;
@@ -632,8 +633,8 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  case SDRAM_R2BAS:
  case SDRAM_R3BAS:
  if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
-ret = sdram_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
-sdram->bank[dcrn - SDRAM_R0BAS].size);
+ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
+ sdram->bank[dcrn - SDRAM_R0BAS].size);
  }
  break;
  case SDRAM_CONF1HB:
@@ -674,7 +675,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  return ret;
  }
  -static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
+static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
  {
  ppc440_sdram_t *sdram = opaque;
  @@ -700,12 +701,12 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)

  if (!(sdram->mcopt2 & 0x0800) && (val & 0x0800)) {
  trace_ppc4xx_sdram_enable("enable");
  /* validate all RAM mappings */
-sdram_map_bcr(sdram);
+sdram_ddr2_map_bcr(sdram);
  sdram->mcopt2 |= 0x0800;
  } else if ((sdram->mcopt2 & 0x0800) 

Re: [PATCH 10/20] ppc440_sdram: Implement enable bit in the DDR2 SDRAM controller

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

To allow removing the do_init hack we need to improve the DDR2 SDRAM
controller model to handle the enable/disable bit that it ignored so
far.

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 34 --
  1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index c33f91e134..7c1513ff69 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -23,6 +23,7 @@
  #include "sysemu/reset.h"
  #include "ppc440.h"
  #include "qom/object.h"
+#include "trace.h"

/*/
  /* L2 Cache as SRAM */
@@ -484,6 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  /* SDRAM controller */
  typedef struct ppc440_sdram_t {
  uint32_t addr;
+uint32_t mcopt2;
  int nbanks;
  Ppc4xxSdramBank bank[4];
  } ppc440_sdram_t;
@@ -581,12 +583,15 @@ static void sdram_set_bcr(ppc440_sdram_t *sdram, int 
i,

  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
+ sdram_size(sdram->bank[i].bcr));
  sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
  sdram->bank[i].base = sdram_base(bcr);
  sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
+trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
  sdram_bank_map(>bank[i]);
  }
  }
@@ -596,7 +601,7 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  int i;
for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->bank[i].size != 0) {
+if (sdram->bank[i].size) {
  sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
@@ -605,6 +610,17 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  }
  }
  +static void sdram_unmap_bcr(ppc440_sdram_t *sdram)
+{
+int i;
+
+for (i = 0; i < sdram->nbanks; i++) {
+if (sdram->bank[i].size) {
+sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+}
+}
+}
+
  static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  {
  ppc440_sdram_t *sdram = opaque;
@@ -636,7 +652,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  ret = 0x8000;
  break;
  case 0x21: /* SDRAM_MCOPT2 */
-ret = 0x0800;
+ret = sdram->mcopt2;
  break;
  case 0x40: /* SDRAM_MB0CF */
  ret = 0x8001;
@@ -680,6 +696,19 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)

  switch (sdram->addr) {
  case 0x00: /* B0CR */
  break;
+case 0x21: /* SDRAM_MCOPT2 */
+if (!(sdram->mcopt2 & 0x0800) && (val & 0x0800)) {
+trace_ppc4xx_sdram_enable("enable");
+/* validate all RAM mappings */
+sdram_map_bcr(sdram);
+sdram->mcopt2 |= 0x0800;
+} else if ((sdram->mcopt2 & 0x0800) && !(val & 
0x0800)) {

+trace_ppc4xx_sdram_enable("disable");
+/* invalidate all RAM mappings */
+sdram_unmap_bcr(sdram);
+sdram->mcopt2 &= ~0x0800;
+}
+break;
  default:
  break;
  }
@@ -694,6 +723,7 @@ static void sdram_reset(void *opaque)
  ppc440_sdram_t *sdram = opaque;
sdram->addr = 0;
+sdram->mcopt2 = 0x0800;


Introducing a define for the 0x0800 value would make the code easier
to read.


How about BIT(27) instead of a new define just for this one? Adding e 
define would probably lead to a long name which results in split lines and 
less redable code in the end.


Regards,
BALATON Zoltan


Thanks,

C.


  }
void ppc440_sdram_init(CPUPPCState *env, int nbanks,





Re: [PATCH 09/20] ppc440_sdram: Split off map/unmap of sdram banks for later reuse

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 31 +++
  1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 3507c35b63..c33f91e134 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -561,26 +561,33 @@ static uint64_t sdram_size(uint32_t bcr)
  return size;
  }
  +static void sdram_bank_map(Ppc4xxSdramBank *bank)
+{
+memory_region_init(>container, NULL, "sdram-container", 
bank->size);


I don't think we need to init the ->container memory region each time.
This could be done once and for all in the realize handler.


+memory_region_add_subregion(>container, 0, >ram);
+memory_region_add_subregion(get_system_memory(), bank->base,
+>container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+memory_region_del_subregion(get_system_memory(), >container);
+memory_region_del_subregion(>container, >ram);
+object_unparent(OBJECT(>container));


object_unparent could be dropped if the memory_region_init was called in
realize.

Also, memory_region_set_enabled() might be a better alternative.


I think these could be considered as a follow up later, I don't want to 
change it now to avoid breaking it more as I've already managed to break 
ref405ep as you found (this will be fixed in v2) so I'd not try to change 
this in this series.


Regards,
BALATON Zoltan


Thanks,

C.



+}
+
  static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-memory_region_del_subregion(get_system_memory(),
->bank[i].container);
-memory_region_del_subregion(>bank[i].container,
->bank[i].ram);
-object_unparent(OBJECT(>bank[i].container));
+sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
+sdram->bank[i].base = sdram_base(bcr);
+sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
-memory_region_init(>bank[i].container, NULL, 
"sdram-container",

-   sdram_size(bcr));
-memory_region_add_subregion(>bank[i].container, 0,
->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_base(bcr),
->bank[i].container);
+sdram_bank_map(>bank[i]);
  }
  }






Re: [PATCH 08/20] ppc4xx_sdram: Drop extra zeros for readability

2022-09-07 Thread BALATON Zoltan

On Wed, 7 Sep 2022, Cédric Le Goater wrote:

On 8/19/22 18:55, BALATON Zoltan wrote:

Constants that are written zero padded for no good reason are hard to
read, it's easier to see what is meant if it's just 0 or 1 instead.


I would keep the 0x prefix though.


I'm not a fan of 0x0 or 0x prefix for numbers below 0xa as it's more 
confusing than just having the simple number since these are the same in 
decimal and hex so I always think it might be 0xC or something not just 0 
when I see a prefix and have to double check. So unless there's a good 
reaon to write them in hex it's simpler to only use the 0x when really 
needed. Maybe if you really want the 0x I could keep it in the switch 
below just for consistency with other cases there but wouldn't have them 
elsewhere. Is it really not acceptable for you as in this patch?


Regards,
BALATON Zoltan


Thanks,

C.




Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc4xx_devs.c | 40 
  1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 375834a52b..bfe7b2d3a6 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -49,31 +49,31 @@ static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr 
ram_size)

switch (ram_size) {
  case 4 * MiB:
-bcr = 0x;
+bcr = 0;
  break;
  case 8 * MiB:
-bcr = 0x0002;
+bcr = 0x2;
  break;
  case 16 * MiB:
-bcr = 0x0004;
+bcr = 0x4;
  break;
  case 32 * MiB:
-bcr = 0x0006;
+bcr = 0x6;
  break;
  case 64 * MiB:
-bcr = 0x0008;
+bcr = 0x8;
  break;
  case 128 * MiB:
-bcr = 0x000A;
+bcr = 0xA;
  break;
  case 256 * MiB:
-bcr = 0x000C;
+bcr = 0xC;
  break;
  default:
  qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid RAM size 0x%" HWADDR_PRIx "\n", 
__func__,

ram_size);
-return 0x;
+return 0;
  }
  bcr |= ram_base & 0xFF80;
  bcr |= 1;
@@ -104,7 +104,7 @@ static target_ulong sdram_size(uint32_t bcr)
  static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
uint32_t bcr, int enabled)
  {
-if (sdram->bank[i].bcr & 0x0001) {
+if (sdram->bank[i].bcr & 1) {
  /* Unmap RAM */
  trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
   sdram_size(sdram->bank[i].bcr));
@@ -115,7 +115,7 @@ static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, 
int i,

  object_unparent(OBJECT(>bank[i].container));
  }
  sdram->bank[i].bcr = bcr & 0xFFDEE001;
-if (enabled && (bcr & 0x0001)) {
+if (enabled && (bcr & 1)) {
  trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
  memory_region_init(>bank[i].container, NULL, 
"sdram-container",

 sdram_size(bcr));
@@ -136,7 +136,7 @@ static void sdram_map_bcr(Ppc4xxSdramDdrState *sdram)
  sdram_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
sdram->bank[i].size), 
1);

  } else {
-sdram_set_bcr(sdram, i, 0x, 0);
+sdram_set_bcr(sdram, i, 0, 0);
  }
  }
  }
@@ -213,7 +213,7 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int 
dcrn)

  break;
  default:
  /* Avoid gcc warning */
-ret = 0x;
+ret = 0;
  break;
  }
  @@ -306,18 +306,18 @@ static void ppc4xx_sdram_ddr_reset(DeviceState 
*dev)

  {
  Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
  -sdram->addr = 0x;
-sdram->bear = 0x;
-sdram->besr0 = 0x; /* No error */
-sdram->besr1 = 0x; /* No error */
-sdram->cfg = 0x;
-sdram->ecccfg = 0x; /* No ECC */
-sdram->eccesr = 0x; /* No error */
+sdram->addr = 0;
+sdram->bear = 0;
+sdram->besr0 = 0; /* No error */
+sdram->besr1 = 0; /* No error */
+sdram->cfg = 0;
+sdram->ecccfg = 0; /* No ECC */
+sdram->eccesr = 0; /* No error */
  sdram->pmit = 0x07C0;
  sdram->rtr = 0x05F0;
  sdram->tr = 0x00854009;
  /* We pre-initialize RAM banks */
-sdram->status = 0x;
+sdram->status = 0;
  sdram->cfg = 0x0080;
  }






[PATCH] audio: add help option (?) for -audiodev

2022-09-07 Thread Claudio Fontana
add a simple help option for -audiodev, so users can do

qemu -audiodev ?

to get the list of drivers available.

Signed-off-by: Claudio Fontana 
---
 audio/audio.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/audio/audio.c b/audio/audio.c
index 4f4bb10cce..bd8c18c3cd 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -32,6 +32,7 @@
 #include "qapi/qapi-visit-audio.h"
 #include "qemu/cutils.h"
 #include "qemu/module.h"
+#include "qemu/help_option.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/replay.h"
 #include "sysemu/runstate.h"
@@ -2105,10 +2106,29 @@ static void audio_validate_opts(Audiodev *dev, Error 
**errp)
 }
 }
 
+static void audio_help(void)
+{
+int i;
+
+printf("Available audiodev types:\n");
+printf("none\n");
+
+for (i = 0; audio_prio_list[i]; i++) {
+audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);
+if (driver) {
+printf("%s\n", driver->name);
+}
+}
+}
+
 void audio_parse_option(const char *opt)
 {
 Audiodev *dev = NULL;
 
+if (is_help_option(opt)) {
+audio_help();
+exit(0);
+}
 Visitor *v = qobject_input_visitor_new_str(opt, "driver", _fatal);
 visit_type_Audiodev(v, NULL, , _fatal);
 visit_free(v);
-- 
2.26.2




Re: [PULL 00/11] OpenRISC updates for 7.2.0

2022-09-07 Thread Stefan Hajnoczi
On Sun, 4 Sept 2022 at 03:27, Stafford Horne  wrote:
>
> The following changes since commit 61fd710b8da8aedcea9b4f197283dc38638e4b60:
>
>   Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging 
> (2022-09-02 13:24:28 -0400)
>
> are available in the Git repository at:
>
>   g...@github.com:stffrdhrn/qemu.git tags/pull-or1k-20220904

Hi Stafford,
Please update .git/config to separate the push URL from the fetch URL:

[remote "github"]
url = https://github.com/stffrdhrn/qemu.git
pushUrl = g...@gitlab.com:stffrdhrn/qemu.git

That way future pull requests will include an https URL that allows
fetches without ssh or a GitHub account. Thanks!

Stefan



Re: [PULL 00/44] riscv-to-apply queue

2022-09-07 Thread Stefan Hajnoczi
On Wed, 7 Sept 2022 at 04:32, Alistair Francis via
 wrote:
>
> The following changes since commit 946e9bccf12f2bcc3ca471b820738fb22d14fc80:
>
>   Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu 
> into staging (2022-09-06 08:31:24 -0400)
>
> are available in the Git repository at:
>
>   g...@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220907

Hi Alistair,
Please update .git/config to separate the push URL from the fetch URL:

[remote "github"]
url = https://github.com/alistair23/qemu.git
pushUrl = g...@gitlab.com:alistair23/qemu.git

That way future pull requests will include an https URL that allows
fetches without ssh or a GitHub account. Thanks!

Stefan



Re: [PULL 00/44] riscv-to-apply queue

2022-09-07 Thread Stefan Hajnoczi
Applied, thanks.

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


signature.asc
Description: PGP signature


Re: [PATCH 14/20] ppc440_sdram: Move RAM size check to ppc440_sdram_init

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Move the check for valid memory sizes from board to sdram contrller


controller


init. Board now only checks for additinal restrictions imposed by


additional


firmware then sdram init checks for valid sizes for SoC.

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440.h|  4 ++--
  hw/ppc/ppc440_uc.c | 15 +++
  hw/ppc/sam460ex.c  | 32 +---
  3 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 7bd5cca1ab..29f6f14ed7 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,13 +11,13 @@
  #ifndef PPC440_H
  #define PPC440_H
  
-#include "hw/ppc/ppc4xx.h"

+#include "hw/ppc/ppc.h"
  
  void ppc4xx_l2sram_init(CPUPPCState *env);

  void ppc4xx_cpr_init(CPUPPCState *env);
  void ppc4xx_sdr_init(CPUPPCState *env);
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank ram_banks[]);
+   MemoryRegion *ram);
  void ppc4xx_ahb_init(CPUPPCState *env);
  void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
  void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index b39c6dbbd2..e77d56225d 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -486,7 +486,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  typedef struct ppc440_sdram_t {
  uint32_t addr;
  uint32_t mcopt2;
-int nbanks;
+int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
  Ppc4xxSdramBank bank[4];
  } ppc440_sdram_t;
  
@@ -728,18 +728,17 @@ static void sdram_ddr2_reset(void *opaque)

  }
  
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,

-   Ppc4xxSdramBank ram_banks[])
+   MemoryRegion *ram)
  {
  ppc440_sdram_t *s;
-int i;
+const ram_addr_t valid_bank_sizes[] = {
+4 * GiB, 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
+32 * MiB, 16 * MiB, 8 * MiB, 0
+};
  
  s = g_malloc0(sizeof(*s));

  s->nbanks = nbanks;
-for (i = 0; i < nbanks; i++) {
-s->bank[i].ram = ram_banks[i].ram;
-s->bank[i].base = ram_banks[i].base;
-s->bank[i].size = ram_banks[i].size;
-}
+ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
  qemu_register_reset(_ddr2_reset, s);
  ppc_dcr_register(env, SDRAM0_CFGADDR,
   s, _ddr2_dcr_read, _ddr2_dcr_write);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index dac329d482..9b850808a3 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -74,13 +74,6 @@
  #define EBC_FREQ 11500
  #define UART_FREQ 11059200
  
-/* The SoC could also handle 4 GiB but firmware does not work with that. */

-/* Maybe it overflows a signed 32 bit number somewhere? */
-static const ram_addr_t ppc460ex_sdram_bank_sizes[] = {
-2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
-32 * MiB, 0
-};
-
  struct boot_info {
  uint32_t dt_base;
  uint32_t dt_size;
@@ -273,7 +266,6 @@ static void sam460ex_init(MachineState *machine)
  {
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank, 1);
  MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1);
  DeviceState *uic[4];
  int i;
@@ -340,12 +332,22 @@ static void sam460ex_init(MachineState *machine)
  }
  
  /* SDRAM controller */

-/* put all RAM on first bank because board has one slot
- * and firmware only checks that */
-ppc4xx_sdram_banks(machine->ram, 1, ram_banks, ppc460ex_sdram_bank_sizes);
-
+/* The SoC could also handle 4 GiB but firmware does not work with that. */
+if (machine->ram_size > 2 * GiB) {
+error_report("Memory over 2 GiB is not supported");
+exit(1);
+}
+/* Firmware needs at least 64 MiB */
+if (machine->ram_size < 64 * MiB) {
+error_report("Memory below 64 MiB is not supported");
+exit(1);
+}



These checks on the RAM size should be done by the SDRAM model.

May be it is addressed later in the patchset ?

C.




+/*
+ * Put all RAM on first bank because board has one slot
+ * and firmware only checks that
+ */
+ppc440_sdram_init(env, 1, machine->ram);
  /* FIXME: does 460EX have ECC interrupts? */
-ppc440_sdram_init(env, 1, ram_banks);
  /* Enable SDRAM memory regions as we may boot without firmware */
  if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21) ||
  ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x0800)) {
@@ -358,8 +360,8 @@ static void sam460ex_init(MachineState *machine)
 qdev_get_gpio_in(uic[0], 2));
  i2c = PPC4xx_I2C(dev)->bus;
  /* SPD EEPROM on RAM module */
-spd_data = spd_data_generate(ram_banks->size < 128 * MiB ? DDR : DDR2,
- ram_banks->size);
+spd_data = 

Re: [PATCH 15/20] ppc440_sdram: QOM'ify

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Change the ppc440_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr2. This is mostly
modelling the DDR2 SDRAM controller found in the 460EX (used on the
sam460ex board). Newer SoCs (regardless of their PPC core, e.g. 405EX)
may have this controller but we only emulate enough of it for the
sam460ex u-boot firmware.

Signed-off-by: BALATON Zoltan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ppc/ppc440.h |   2 -
  hw/ppc/ppc440_uc.c  | 115 +---
  hw/ppc/sam460ex.c   |   7 ++-
  include/hw/ppc/ppc4xx.h |  14 +
  4 files changed, 91 insertions(+), 47 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 29f6f14ed7..7c24db8504 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -16,8 +16,6 @@
  void ppc4xx_l2sram_init(CPUPPCState *env);
  void ppc4xx_cpr_init(CPUPPCState *env);
  void ppc4xx_sdr_init(CPUPPCState *env);
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram);
  void ppc4xx_ahb_init(CPUPPCState *env);
  void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
  void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index e77d56225d..a75a1748bd 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -483,13 +483,6 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  
  /*/

  /* SDRAM controller */
-typedef struct ppc440_sdram_t {
-uint32_t addr;
-uint32_t mcopt2;
-int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
-Ppc4xxSdramBank bank[4];
-} ppc440_sdram_t;
-
  enum {
  SDRAM_R0BAS = 0x40,
  SDRAM_R1BAS,
@@ -578,7 +571,7 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
  object_unparent(OBJECT(>container));
  }
  
-static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,

+static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
 uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
@@ -596,7 +589,7 @@ static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
  }
  }
  
-static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)

+static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
  {
  int i;
  
@@ -611,7 +604,7 @@ static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)

  }
  }
  
-static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)

+static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
  {
  int i;
  
@@ -624,7 +617,7 @@ static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
  
  static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)

  {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = opaque;
  uint32_t ret = 0;
  
  switch (dcrn) {

@@ -677,7 +670,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
  
  static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)

  {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = opaque;
  
  switch (dcrn) {

  case SDRAM_R0BAS:
@@ -719,52 +712,86 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, 
uint32_t val)
  }
  }
  
-static void sdram_ddr2_reset(void *opaque)

+static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
  {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev);
  
  sdram->addr = 0;

  sdram->mcopt2 = 0;
  }
  
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,

-   MemoryRegion *ram)
+static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
  {
-ppc440_sdram_t *s;
+Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
+Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
  const ram_addr_t valid_bank_sizes[] = {
  4 * GiB, 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
  32 * MiB, 16 * MiB, 8 * MiB, 0
  };
  
-s = g_malloc0(sizeof(*s));

-s->nbanks = nbanks;
-ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
-qemu_register_reset(_ddr2_reset, s);
-ppc_dcr_register(env, SDRAM0_CFGADDR,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM0_CFGDATA,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-
-ppc_dcr_register(env, SDRAM_R0BAS,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R1BAS,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R2BAS,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R3BAS,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_CONF1HB,
- s, _ddr2_dcr_read, _ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_PLBADDULL,
- s, 

Re: [PATCH 13/20] ppc4xx_sdram: Rename functions to prevent name clashes

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Rename functions to avoid name clashes when moving the DDR2 controller
model currently called ppc440_sdram to ppc4xx_devs. This also more
clearly shows which function belongs to which model.


Shouldn't we introduce class handlers instead  ?

Thanks,

C.




Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c   | 69 ++--
  hw/ppc/ppc4xx_devs.c | 44 ++--
  2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 72eb75d3d2..b39c6dbbd2 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -502,7 +502,7 @@ enum {
  SDRAM_PLBADDUHB = 0x50,
  };
  
-static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)

+static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
  {
  uint32_t bcr;
  
@@ -547,12 +547,12 @@ static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)

  return bcr;
  }
  
-static inline hwaddr sdram_base(uint32_t bcr)

+static inline hwaddr sdram_ddr2_base(uint32_t bcr)
  {
  return (bcr & 0xffe0) << 2;
  }
  
-static uint64_t sdram_size(uint32_t bcr)

+static uint64_t sdram_ddr2_size(uint32_t bcr)
  {
  uint64_t size;
  int sh;
@@ -578,50 +578,51 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
  object_unparent(OBJECT(>container));
  }
  
-static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,

-  uint32_t bcr, int enabled)
+static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
+   uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
- sdram_size(sdram->bank[i].bcr));
+trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
+ sdram_ddr2_size(sdram->bank[i].bcr));
  sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
-sdram->bank[i].base = sdram_base(bcr);
-sdram->bank[i].size = sdram_size(bcr);
+sdram->bank[i].base = sdram_ddr2_base(bcr);
+sdram->bank[i].size = sdram_ddr2_size(bcr);
  if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
+trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
  sdram_bank_map(>bank[i]);
  }
  }
  
-static void sdram_map_bcr(ppc440_sdram_t *sdram)

+static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
  {
  int i;
  
  for (i = 0; i < sdram->nbanks; i++) {

  if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
+sdram_ddr2_set_bcr(sdram, i,
+   sdram_ddr2_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
-sdram_set_bcr(sdram, i, 0, 0);
+sdram_ddr2_set_bcr(sdram, i, 0, 0);
  }
  }
  }
  
-static void sdram_unmap_bcr(ppc440_sdram_t *sdram)

+static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
  {
  int i;
  
  for (i = 0; i < sdram->nbanks; i++) {

  if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
  }
  }
  }
  
-static uint32_t dcr_read_sdram(void *opaque, int dcrn)

+static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
  {
  ppc440_sdram_t *sdram = opaque;
  uint32_t ret = 0;
@@ -632,8 +633,8 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  case SDRAM_R2BAS:
  case SDRAM_R3BAS:
  if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
-ret = sdram_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
-sdram->bank[dcrn - SDRAM_R0BAS].size);
+ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
+ sdram->bank[dcrn - SDRAM_R0BAS].size);
  }
  break;
  case SDRAM_CONF1HB:
@@ -674,7 +675,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  return ret;
  }
  
-static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)

+static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
  {
  ppc440_sdram_t *sdram = opaque;
  
@@ -700,12 +701,12 @@ static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)

  if (!(sdram->mcopt2 & 0x0800) && (val & 0x0800)) {
  trace_ppc4xx_sdram_enable("enable");
  /* validate all RAM mappings */
-sdram_map_bcr(sdram);
+sdram_ddr2_map_bcr(sdram);
  sdram->mcopt2 |= 0x0800;
  } else if ((sdram->mcopt2 & 0x0800) && !(val & 0x0800)) {
  trace_ppc4xx_sdram_enable("disable");
  /* 

Re: [PATCH 12/20] ppc440_sdram: Rename local variable for readibility

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Rename local sdram variable in ppc440_sdram_init to s for readibility.


readability



Signed-off-by: BALATON Zoltan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.


---
  hw/ppc/ppc440_uc.c | 36 ++--
  1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index bd3d60f278..72eb75d3d2 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -729,40 +729,40 @@ static void sdram_reset(void *opaque)
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,
 Ppc4xxSdramBank ram_banks[])
  {
-ppc440_sdram_t *sdram;
+ppc440_sdram_t *s;
  int i;
  
-sdram = g_malloc0(sizeof(*sdram));

-sdram->nbanks = nbanks;
+s = g_malloc0(sizeof(*s));
+s->nbanks = nbanks;
  for (i = 0; i < nbanks; i++) {
-sdram->bank[i].ram = ram_banks[i].ram;
-sdram->bank[i].base = ram_banks[i].base;
-sdram->bank[i].size = ram_banks[i].size;
+s->bank[i].ram = ram_banks[i].ram;
+s->bank[i].base = ram_banks[i].base;
+s->bank[i].size = ram_banks[i].size;
  }
-qemu_register_reset(_reset, sdram);
+qemu_register_reset(_reset, s);
  ppc_dcr_register(env, SDRAM0_CFGADDR,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM0_CFGDATA,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  
  ppc_dcr_register(env, SDRAM_R0BAS,

- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_R1BAS,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_R2BAS,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_R3BAS,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_CONF1HB,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_PLBADDULL,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_CONF1LL,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_CONFPATHB,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  ppc_dcr_register(env, SDRAM_PLBADDUHB,
- sdram, _read_sdram, _write_sdram);
+ s, _read_sdram, _write_sdram);
  }
  
  /*/





Re: [PATCH 10/20] ppc440_sdram: Implement enable bit in the DDR2 SDRAM controller

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

To allow removing the do_init hack we need to improve the DDR2 SDRAM
controller model to handle the enable/disable bit that it ignored so
far.

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 34 --
  1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index c33f91e134..7c1513ff69 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -23,6 +23,7 @@
  #include "sysemu/reset.h"
  #include "ppc440.h"
  #include "qom/object.h"
+#include "trace.h"
  
  /*/

  /* L2 Cache as SRAM */
@@ -484,6 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  /* SDRAM controller */
  typedef struct ppc440_sdram_t {
  uint32_t addr;
+uint32_t mcopt2;
  int nbanks;
  Ppc4xxSdramBank bank[4];
  } ppc440_sdram_t;
@@ -581,12 +583,15 @@ static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
+ sdram_size(sdram->bank[i].bcr));
  sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
  sdram->bank[i].base = sdram_base(bcr);
  sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
+trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
  sdram_bank_map(>bank[i]);
  }
  }
@@ -596,7 +601,7 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  int i;
  
  for (i = 0; i < sdram->nbanks; i++) {

-if (sdram->bank[i].size != 0) {
+if (sdram->bank[i].size) {
  sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
@@ -605,6 +610,17 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  }
  }
  
+static void sdram_unmap_bcr(ppc440_sdram_t *sdram)

+{
+int i;
+
+for (i = 0; i < sdram->nbanks; i++) {
+if (sdram->bank[i].size) {
+sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+}
+}
+}
+
  static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  {
  ppc440_sdram_t *sdram = opaque;
@@ -636,7 +652,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  ret = 0x8000;
  break;
  case 0x21: /* SDRAM_MCOPT2 */
-ret = 0x0800;
+ret = sdram->mcopt2;
  break;
  case 0x40: /* SDRAM_MB0CF */
  ret = 0x8001;
@@ -680,6 +696,19 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)
  switch (sdram->addr) {
  case 0x00: /* B0CR */
  break;
+case 0x21: /* SDRAM_MCOPT2 */
+if (!(sdram->mcopt2 & 0x0800) && (val & 0x0800)) {
+trace_ppc4xx_sdram_enable("enable");
+/* validate all RAM mappings */
+sdram_map_bcr(sdram);
+sdram->mcopt2 |= 0x0800;
+} else if ((sdram->mcopt2 & 0x0800) && !(val & 0x0800)) {
+trace_ppc4xx_sdram_enable("disable");
+/* invalidate all RAM mappings */
+sdram_unmap_bcr(sdram);
+sdram->mcopt2 &= ~0x0800;
+}
+break;
  default:
  break;
  }
@@ -694,6 +723,7 @@ static void sdram_reset(void *opaque)
  ppc440_sdram_t *sdram = opaque;
  
  sdram->addr = 0;

+sdram->mcopt2 = 0x0800;


Introducing a define for the 0x0800 value would make the code easier
to read.

Thanks,

C.


  }
  
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,





Re: PING: Re: [PATCH v4 1/1] monitor: Support specified vCPU registers

2022-09-07 Thread Dr. David Alan Gilbert
* zhenwei pi (pizhen...@bytedance.com) wrote:
> PING!

It's OK, I've got it lined up for a pull I'll do in a few days time.

Dave

> On 8/15/22 20:00, Dr. David Alan Gilbert wrote:
> > * zhenwei pi (pizhen...@bytedance.com) wrote:
> > > Originally we have to get all the vCPU registers and parse the
> > > specified one. To improve the performance of this usage, allow user
> > > specified vCPU id to query registers.
> > > 
> > > Run a VM with 16 vCPU, use bcc tool to track the latency of
> > > 'hmp_info_registers':
> > > 'info registers -a' uses about 3ms;
> > > 'info registers 12' uses about 150us.
> > > 
> > > Cc: Darren Kenny 
> > > Reviewed-by: Markus Armbruster 
> > > Signed-off-by: zhenwei pi 
> > 
> > Reviewed-by: Dr. David Alan Gilbert 
> > 
> > > ---
> > >   hmp-commands-info.hx |  8 +---
> > >   monitor/misc.c   | 10 --
> > >   2 files changed, 13 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> > > index 188d9ece3b..e012035541 100644
> > > --- a/hmp-commands-info.hx
> > > +++ b/hmp-commands-info.hx
> > > @@ -100,9 +100,11 @@ ERST
> > >   {
> > >   .name   = "registers",
> > > -.args_type  = "cpustate_all:-a",
> > > -.params = "[-a]",
> > > -.help   = "show the cpu registers (-a: all - show register 
> > > info for all cpus)",
> > > +.args_type  = "cpustate_all:-a,vcpu:i?",
> > > +.params = "[-a|vcpu]",
> > > +.help   = "show the cpu registers (-a: show register info 
> > > for all cpus;"
> > > +  " vcpu: specific vCPU to query; show the current 
> > > CPU's registers if"
> > > +  " no argument is specified)",
> > >   .cmd= hmp_info_registers,
> > >   },
> > > diff --git a/monitor/misc.c b/monitor/misc.c
> > > index 3d2312ba8d..6436a8786b 100644
> > > --- a/monitor/misc.c
> > > +++ b/monitor/misc.c
> > > @@ -307,6 +307,7 @@ int monitor_get_cpu_index(Monitor *mon)
> > >   static void hmp_info_registers(Monitor *mon, const QDict *qdict)
> > >   {
> > >   bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
> > > +int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
> > >   CPUState *cs;
> > >   if (all_cpus) {
> > > @@ -315,13 +316,18 @@ static void hmp_info_registers(Monitor *mon, const 
> > > QDict *qdict)
> > >   cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
> > >   }
> > >   } else {
> > > -cs = mon_get_cpu(mon);
> > > +cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
> > >   if (!cs) {
> > > -monitor_printf(mon, "No CPU available\n");
> > > +if (vcpu >= 0) {
> > > +monitor_printf(mon, "CPU#%d not available\n", vcpu);
> > > +} else {
> > > +monitor_printf(mon, "No CPU available\n");
> > > +}
> > >   return;
> > >   }
> > > +monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
> > >   cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
> > >   }
> > >   }
> > > -- 
> > > 2.20.1
> > > 
> 
> -- 
> zhenwei pi
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH 09/20] ppc440_sdram: Split off map/unmap of sdram banks for later reuse

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 31 +++
  1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 3507c35b63..c33f91e134 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -561,26 +561,33 @@ static uint64_t sdram_size(uint32_t bcr)
  return size;
  }
  
+static void sdram_bank_map(Ppc4xxSdramBank *bank)

+{
+memory_region_init(>container, NULL, "sdram-container", bank->size);


I don't think we need to init the ->container memory region each time.
This could be done once and for all in the realize handler.


+memory_region_add_subregion(>container, 0, >ram);
+memory_region_add_subregion(get_system_memory(), bank->base,
+>container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+memory_region_del_subregion(get_system_memory(), >container);
+memory_region_del_subregion(>container, >ram);
+object_unparent(OBJECT(>container));


object_unparent could be dropped if the memory_region_init was called in
realize.

Also, memory_region_set_enabled() might be a better alternative.

Thanks,

C.



+}
+
  static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-memory_region_del_subregion(get_system_memory(),
->bank[i].container);
-memory_region_del_subregion(>bank[i].container,
->bank[i].ram);
-object_unparent(OBJECT(>bank[i].container));
+sdram_bank_unmap(>bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
+sdram->bank[i].base = sdram_base(bcr);
+sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
-memory_region_init(>bank[i].container, NULL, "sdram-container",
-   sdram_size(bcr));
-memory_region_add_subregion(>bank[i].container, 0,
->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_base(bcr),
->bank[i].container);
+sdram_bank_map(>bank[i]);
  }
  }
  





Re: [PATCH 08/20] ppc4xx_sdram: Drop extra zeros for readability

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Constants that are written zero padded for no good reason are hard to
read, it's easier to see what is meant if it's just 0 or 1 instead.


I would keep the 0x prefix though.

Thanks,

C.




Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc4xx_devs.c | 40 
  1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 375834a52b..bfe7b2d3a6 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -49,31 +49,31 @@ static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr 
ram_size)
  
  switch (ram_size) {

  case 4 * MiB:
-bcr = 0x;
+bcr = 0;
  break;
  case 8 * MiB:
-bcr = 0x0002;
+bcr = 0x2;
  break;
  case 16 * MiB:
-bcr = 0x0004;
+bcr = 0x4;
  break;
  case 32 * MiB:
-bcr = 0x0006;
+bcr = 0x6;
  break;
  case 64 * MiB:
-bcr = 0x0008;
+bcr = 0x8;
  break;
  case 128 * MiB:
-bcr = 0x000A;
+bcr = 0xA;
  break;
  case 256 * MiB:
-bcr = 0x000C;
+bcr = 0xC;
  break;
  default:
  qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
ram_size);
-return 0x;
+return 0;
  }
  bcr |= ram_base & 0xFF80;
  bcr |= 1;
@@ -104,7 +104,7 @@ static target_ulong sdram_size(uint32_t bcr)
  static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
uint32_t bcr, int enabled)
  {
-if (sdram->bank[i].bcr & 0x0001) {
+if (sdram->bank[i].bcr & 1) {
  /* Unmap RAM */
  trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
   sdram_size(sdram->bank[i].bcr));
@@ -115,7 +115,7 @@ static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
  object_unparent(OBJECT(>bank[i].container));
  }
  sdram->bank[i].bcr = bcr & 0xFFDEE001;
-if (enabled && (bcr & 0x0001)) {
+if (enabled && (bcr & 1)) {
  trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
  memory_region_init(>bank[i].container, NULL, "sdram-container",
 sdram_size(bcr));
@@ -136,7 +136,7 @@ static void sdram_map_bcr(Ppc4xxSdramDdrState *sdram)
  sdram_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
-sdram_set_bcr(sdram, i, 0x, 0);
+sdram_set_bcr(sdram, i, 0, 0);
  }
  }
  }
@@ -213,7 +213,7 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
  break;
  default:
  /* Avoid gcc warning */
-ret = 0x;
+ret = 0;
  break;
  }
  
@@ -306,18 +306,18 @@ static void ppc4xx_sdram_ddr_reset(DeviceState *dev)

  {
  Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
  
-sdram->addr = 0x;

-sdram->bear = 0x;
-sdram->besr0 = 0x; /* No error */
-sdram->besr1 = 0x; /* No error */
-sdram->cfg = 0x;
-sdram->ecccfg = 0x; /* No ECC */
-sdram->eccesr = 0x; /* No error */
+sdram->addr = 0;
+sdram->bear = 0;
+sdram->besr0 = 0; /* No error */
+sdram->besr1 = 0; /* No error */
+sdram->cfg = 0;
+sdram->ecccfg = 0; /* No ECC */
+sdram->eccesr = 0; /* No error */
  sdram->pmit = 0x07C0;
  sdram->rtr = 0x05F0;
  sdram->tr = 0x00854009;
  /* We pre-initialize RAM banks */
-sdram->status = 0x;
+sdram->status = 0;
  sdram->cfg = 0x0080;
  }
  





Re: [PATCH 07/20] ppc4xx_sdram: QOM'ify

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Change the ppc4xx_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr. This is mostly
modelling the DDR SDRAM controller found in the 440EP (used on the
bamboo board) but also backward compatible with the older DDR
controllers on some 405 SoCs so we also use it for those now. This
likely does not cause problems for guests we run as the new features
are just not accessed but to model 405 SoC accurately some features
may have to be disabled or the model split between 440 and older.

Newer SoCs (regardless of their PPC core, e.g. 405EX) may have an
updated DDR2 SDRAM controller implemented by the ppc440_sdram model
(only partially, enough for the 460EX on the sam460ex) that is not yet
QOM'ified in this patch. That is intended to become ppc4xx-sdram-ddr2
when QOM'ified later.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ppc/ppc405.h |  3 +-
  hw/ppc/ppc405_uc.c  | 22 +
  hw/ppc/ppc440_bamboo.c  | 10 +++--
  hw/ppc/ppc4xx_devs.c| 99 ++---
  include/hw/ppc/ppc4xx.h | 27 +--
  5 files changed, 98 insertions(+), 63 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ad54dff542..9a4312691e 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,8 +167,6 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
  
  /* Public */

-MemoryRegion *dram_mr;
-
  PowerPCCPU cpu;
  PPCUIC uic;
  Ppc405CpcState cpc;
@@ -182,6 +180,7 @@ struct Ppc405SoCState {
  Ppc405PobState pob;
  Ppc4xxPlbState plb;
  Ppc4xxMalState mal;
+Ppc4xxSdramDdrState sdram;
  };
  
  #endif /* PPC405_H */

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 4049fb98dc..9c266a21ad 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1013,6 +1013,9 @@ static void ppc405_soc_instance_init(Object *obj)
  object_initialize_child(obj, "plb", >plb, TYPE_PPC4xx_PLB);
  
  object_initialize_child(obj, "mal", >mal, TYPE_PPC4xx_MAL);

+
+object_initialize_child(obj, "sdram", >sdram, TYPE_PPC4xx_SDRAM_DDR);
+object_property_add_alias(obj, "dram", OBJECT(>sdram), "dram");
  }
  
  static void ppc405_reset(void *opaque)

@@ -1070,9 +1073,17 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 qdev_get_gpio_in(DEVICE(>cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

+/*
+ * We use the 440 DDR SDRAM controller which has more regs and features
+ * but it's compatible enough for now
+ */
+object_property_set_int(OBJECT(>sdram), "nbanks", 2, _abort);
+if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>sdram), >cpu, errp)) {
+return;
+}
  /* XXX 405EP has no ECC interrupt */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(>uic), 17), 1,
-  s->dram_mr);
+sysbus_connect_irq(SYS_BUS_DEVICE(>sdram), 0,
+   qdev_get_gpio_in(DEVICE(>uic), 17));
  
  /* External bus controller */

  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>ebc), >cpu, errp)) {
@@ -1147,12 +1158,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  /* Uses UIC IRQs 9, 15, 17 */
  }
  
-static Property ppc405_soc_properties[] = {

-DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
- MemoryRegion *),
-DEFINE_PROP_END_OF_LIST(),
-};
-
  static void ppc405_soc_class_init(ObjectClass *oc, void *data)
  {
  DeviceClass *dc = DEVICE_CLASS(oc);
@@ -1160,7 +1165,6 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
  dc->realize = ppc405_soc_realize;
  /* Reason: only works as part of a ppc405 board/machine */
  dc->user_creatable = false;
-device_class_set_props(dc, ppc405_soc_properties);
  }
  
  static const TypeInfo ppc405_types[] = {

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 9b456f1819..6052d3a2e0 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -48,8 +48,6 @@
  #define PPC440EP_PCI_IO 0xe800
  #define PPC440EP_PCI_IOLEN  0x0001
  
-#define PPC440EP_SDRAM_NR_BANKS 4

-
  static hwaddr entry;
  
  static int bamboo_load_device_tree(hwaddr addr,

@@ -198,9 +196,13 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

+dev = qdev_new(TYPE_PPC4xx_SDRAM_DDR);
+object_property_set_link(OBJECT(dev), "dram", OBJECT(machine->ram),
+ _abort);
+ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(dev), cpu, _fatal);
+object_unref(OBJECT(dev));
  /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, machine->ram);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(uicdev, 

[PATCH v3] audio: Add sndio backend

2022-09-07 Thread Alexandre Ratchov
sndio is the native API used by OpenBSD, although it has been ported to
other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).

Signed-off-by: Brad Smith 
Signed-off-by: Alexandre Ratchov 
---

References to the previous patch versions and related discussions are
here:

https://marc.info/?l=qemu-devel=163973393011543   (v2)
https://marc.info/?l=qemu-devel=163626248712444   (initial patch)

Here are the changes between v2 and v3 of this patch:

- fixed of typos in file-names in MAINTAINERS
- added Gerd Hoffmann to the M: entry in MAINTAINERS
- added missin S: entry in MAINTAINERS
- removed unused #include "qemu-common.h"
- bumped "Since:" version to 7.2 in qapi/audio.json
- regenerated scripts/meson-buildoptions.sh
- implement buffer_get_free() method, introduced by
  commit 9833438ef624155de879d4ed57ecfcd3464a0bbe

  audio: restore mixing-engine playback buffer size

Running "make update-buildoptions" triggered unrelated changes of
scripts/meson-buildoptions.sh, that I removed from the commit as they
are not related to sndio.

Tested on OpenBSD, still works as expected :-)

Regards,
Alexandre

 MAINTAINERS   |   7 +
 audio/audio.c |   1 +
 audio/audio_template.h|   2 +
 audio/meson.build |   1 +
 audio/sndioaudio.c| 565 ++
 meson.build   |   9 +-
 meson_options.txt |   4 +-
 qapi/audio.json   |  25 +-
 qemu-options.hx   |  16 +
 scripts/meson-buildoptions.sh |   7 +-
 10 files changed, 632 insertions(+), 5 deletions(-)
 create mode 100644 audio/sndioaudio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1729c0901c..2064efc856 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2438,6 +2438,7 @@ X: audio/jackaudio.c
 X: audio/ossaudio.c
 X: audio/paaudio.c
 X: audio/sdlaudio.c
+X: audio/sndioaudio.c
 X: audio/spiceaudio.c
 F: qapi/audio.json
 
@@ -2482,6 +2483,12 @@ R: Thomas Huth 
 S: Odd Fixes
 F: audio/sdlaudio.c
 
+Sndio Audio backend
+M: Gerd Hoffmann 
+R: Alexandre Ratchov 
+S: Odd Fixes
+F: audio/sndioaudio.c
+
 Block layer core
 M: Kevin Wolf 
 M: Hanna Reitz 
diff --git a/audio/audio.c b/audio/audio.c
index 76b8735b44..d3a768007e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2029,6 +2029,7 @@ void audio_create_pdos(Audiodev *dev)
 CASE(OSS, oss, Oss);
 CASE(PA, pa, Pa);
 CASE(SDL, sdl, Sdl);
+CASE(SNDIO, sndio, );
 CASE(SPICE, spice, );
 CASE(WAV, wav, );
 
diff --git a/audio/audio_template.h b/audio/audio_template.h
index 7192b19e73..81860cea62 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -336,6 +336,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, 
TYPE)(Audiodev *dev)
 return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
 case AUDIODEV_DRIVER_SDL:
 return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
+case AUDIODEV_DRIVER_SNDIO:
+return dev->u.sndio.TYPE;
 case AUDIODEV_DRIVER_SPICE:
 return dev->u.spice.TYPE;
 case AUDIODEV_DRIVER_WAV:
diff --git a/audio/meson.build b/audio/meson.build
index 3abee90860..34aed78342 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -17,6 +17,7 @@ foreach m : [
   ['pa', pulse, files('paaudio.c')],
   ['sdl', sdl, files('sdlaudio.c')],
   ['jack', jack, files('jackaudio.c')],
+  ['sndio', sndio, files('sndioaudio.c')],
   ['spice', spice, files('spiceaudio.c')]
 ]
   if m[1].found()
diff --git a/audio/sndioaudio.c b/audio/sndioaudio.c
new file mode 100644
index 00..7c45276d36
--- /dev/null
+++ b/audio/sndioaudio.c
@@ -0,0 +1,565 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2019 Alexandre Ratchov 
+ */
+
+/*
+ * TODO :
+ *
+ * Use a single device and open it in full-duplex rather than
+ * opening it twice (once for playback once for recording).
+ *
+ * This is the only way to ensure that playback doesn't drift with respect
+ * to recording, which is what guest systems expect.
+ */
+
+#include 
+#include 
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "audio.h"
+#include "trace.h"
+
+#define AUDIO_CAP "sndio"
+#include "audio_int.h"
+
+/* default latency in microseconds if no option is set */
+#define SNDIO_LATENCY_US   5
+
+typedef struct SndioVoice {
+union {
+HWVoiceOut out;
+HWVoiceIn in;
+} hw;
+struct sio_par par;
+struct sio_hdl *hdl;
+struct pollfd *pfds;
+struct pollindex {
+struct SndioVoice *self;
+int index;
+} *pindexes;
+unsigned char *buf;
+size_t buf_size;
+size_t sndio_pos;
+size_t qemu_pos;
+unsigned int mode;
+unsigned int nfds;
+bool enabled;
+} SndioVoice;
+
+typedef struct SndioConf {
+const char *devname;
+unsigned int latency;
+} SndioConf;
+
+/* needed for forward reference */
+static void sndio_poll_in(void *arg);
+static void sndio_poll_out(void *arg);
+
+/*
+ * stop polling 

Re: [PATCH 06/20] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Instead of checking if memory size is valid in board code move this
check to ppc4xx_sdram_init() as this is a restriction imposed by the
SDRAM controller.

Signed-off-by: BALATON Zoltan 


It looks like a good clean up. At some point, I think we will need to
pass "MemoryRegion *sysmem" to the SDRAM model.  Let's start with this
change and see how it evolves.

One small comment below
 
Reviewed-by: Cédric Le Goater 


Thanks,


C.


---
  hw/ppc/ppc405.h |  2 --
  hw/ppc/ppc405_boards.c  | 10 --
  hw/ppc/ppc405_uc.c  | 11 ++-
  hw/ppc/ppc440_bamboo.c  | 10 +-
  hw/ppc/ppc4xx_devs.c| 14 ++
  include/hw/ppc/ppc4xx.h |  2 +-
  6 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ca0972b88b..ad54dff542 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
  
  /* Public */

-Ppc4xxSdramBank ram_banks[2];
  MemoryRegion *dram_mr;
-hwaddr ram_size;
  
  PowerPCCPU cpu;

  PPCUIC uic;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 0a29ad97c7..a82b6c5c83 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -278,21 +278,11 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)
  static void ppc405_init(MachineState *machine)
  {
  Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(machine);
  const char *kernel_filename = machine->kernel_filename;
  MemoryRegion *sysmem = get_system_memory();
  
-if (machine->ram_size != mc->default_ram_size) {

-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM size, should be %s", sz);
-g_free(sz);
-exit(EXIT_FAILURE);
-}
-
  object_initialize_child(OBJECT(machine), "soc", >soc,
  TYPE_PPC405_SOC);
-object_property_set_uint(OBJECT(>soc), "ram-size",
- machine->ram_size, _fatal);
  object_property_set_link(OBJECT(>soc), "dram",
   OBJECT(machine->ram), _abort);
  object_property_set_uint(OBJECT(>soc), "sys-clk", ,
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 461d18c8a5..4049fb98dc 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1070,15 +1070,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 qdev_get_gpio_in(DEVICE(>cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

-/* XXX 405EP has no ECC interrupt */
-s->ram_banks[0].base = 0;
-s->ram_banks[0].size = s->ram_size;
-memory_region_init_alias(>ram_banks[0].ram, OBJECT(s),
- "ppc405.sdram0", s->dram_mr,
- s->ram_banks[0].base, s->ram_banks[0].size);
-
+/* XXX 405EP has no ECC interrupt */
  ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(>uic), 17), 1,
-  s->ram_banks);
+  s->dram_mr);
  
  /* External bus controller */

  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>ebc), >cpu, errp)) {
@@ -1156,7 +1150,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  static Property ppc405_soc_properties[] = {
  DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
   MemoryRegion *),
-DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c

index 2bd5e41140..9b456f1819 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -50,10 +50,6 @@
  
  #define PPC440EP_SDRAM_NR_BANKS 4
  
-static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {

-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
-};
-
  static hwaddr entry;
  
  static int bamboo_load_device_tree(hwaddr addr,

@@ -168,8 +164,6 @@ static void bamboo_init(MachineState *machine)
  unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
-PPC440EP_SDRAM_NR_BANKS);
  PCIBus *pcibus;
  PowerPCCPU *cpu;
  CPUPPCState *env;
@@ -204,11 +198,9 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

-ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_banks,
-   ppc440ep_sdram_bank_sizes);
  /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
  ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, ram_banks);
+  

Re: [PATCH 05/20] ppc440_bamboo: Add missing 4 MiB valid memory size

2022-09-07 Thread Cédric Le Goater

On 8/19/22 18:55, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ppc/ppc440_bamboo.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 2aac8a3fe9..2bd5e41140 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -51,7 +51,7 @@
  #define PPC440EP_SDRAM_NR_BANKS 4
  
  static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {

-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
+256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
  };
  
  static hwaddr entry;





Re: [PATCH] migration/multifd: Remove redundant copy of page offsets during send

2022-09-07 Thread Nikolay Borisov




On 10.08.22 г. 13:39 ч., Nikolay Borisov wrote:

All pages which are going to be migrated are first added to
MultiFDSendParams::MultiFDPages_t::offset array by the main migration
thread and are subsequently copied to MultiFDSendParams::normal by the
multifd thread. This is really unnecessary as the MultiFDPages_t is
guaranteed to be stable since its mutex is being held. Additionally,
this somewhat simplifies the code as the migration pages are now kept
in only 1 place during send, also the name 'offset' coupled with the
context it's being used - usually added to the host pages makes it
obvious that this is an offset.

With this change normal/normal_num are no longer used in the multifd
send path.

Signed-off-by: Nikolay Borisov 



Ping



Re: [PATCH REPOST] hw/i386/e820: remove legacy reserved entries for e820

2022-09-07 Thread Ani Sinha
On Wed, Aug 31, 2022 at 10:23 AM Ani Sinha  wrote:
>
> e820 reserved entries were used before the dynamic entries with fw config 
> files
> were intoduced. Please see the following change:
> 7d67110f2d9a6("pc: add etc/e820 fw_cfg file")
>
> Identical support was introduced into seabios as well with the following 
> commit:
> ce39bd4031820 ("Add support for etc/e820 fw_cfg file")
>
> Both the above commits are now quite old. QEMU machines 1.7 and newer no 
> longer
> use the reserved entries. Seabios uses fw config files and
> dynamic e820 entries by default and only falls back to using reserved entries
> when it has to work with old qemu (versions earlier than 1.7). Please see
> functions qemu_cfg_e820() and qemu_early_e820(). It is safe to remove legacy
> FW_CFG_E820_TABLE and associated code now as QEMU 7.0 has deprecated i440fx
> machines 1.7 and older. It would be incredibly rare to run the latest qemu
> version with a very old version of seabios that did not support fw config 
> files
> for e820.
>
> As far as I could see, edk2/ovfm never supported reserved entries and uses fw
> config files from the beginning. So there should be no incompatibilities with
> ovfm as well.
>
> CC: Gerd Hoffmann 
> Signed-off-by: Ani Sinha 
> Acked-by: Gerd Hoffmann 

michael, please pick this one as well for the next pull. thanks.

> ---
>  hw/i386/e820_memory_layout.c | 20 +---
>  hw/i386/e820_memory_layout.h |  8 
>  hw/i386/fw_cfg.c |  3 ---
>  hw/i386/fw_cfg.h |  1 -
>  hw/i386/microvm.c|  2 --
>  5 files changed, 1 insertion(+), 33 deletions(-)
>
> Please see:
> https://patchwork.ozlabs.org/project/qemu-devel/patch/20220420043904.1225153-1-...@anisinha.ca/
> for the previous post. Now that we are in 7.2 devel cycle, time to push
> this patch.
>
> diff --git a/hw/i386/e820_memory_layout.c b/hw/i386/e820_memory_layout.c
> index bcf9eaf837..06970ac44a 100644
> --- a/hw/i386/e820_memory_layout.c
> +++ b/hw/i386/e820_memory_layout.c
> @@ -11,29 +11,11 @@
>  #include "e820_memory_layout.h"
>
>  static size_t e820_entries;
> -struct e820_table e820_reserve;
>  struct e820_entry *e820_table;
>
>  int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
>  {
> -int index = le32_to_cpu(e820_reserve.count);
> -struct e820_entry *entry;
> -
> -if (type != E820_RAM) {
> -/* old FW_CFG_E820_TABLE entry -- reservations only */
> -if (index >= E820_NR_ENTRIES) {
> -return -EBUSY;
> -}
> -entry = _reserve.entry[index++];
> -
> -entry->address = cpu_to_le64(address);
> -entry->length = cpu_to_le64(length);
> -entry->type = cpu_to_le32(type);
> -
> -e820_reserve.count = cpu_to_le32(index);
> -}
> -
> -/* new "etc/e820" file -- include ram too */
> +/* new "etc/e820" file -- include ram and reserved entries */
>  e820_table = g_renew(struct e820_entry, e820_table, e820_entries + 1);
>  e820_table[e820_entries].address = cpu_to_le64(address);
>  e820_table[e820_entries].length = cpu_to_le64(length);
> diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h
> index 04f93780f9..7c239aa033 100644
> --- a/hw/i386/e820_memory_layout.h
> +++ b/hw/i386/e820_memory_layout.h
> @@ -16,20 +16,12 @@
>  #define E820_NVS4
>  #define E820_UNUSABLE   5
>
> -#define E820_NR_ENTRIES 16
> -
>  struct e820_entry {
>  uint64_t address;
>  uint64_t length;
>  uint32_t type;
>  } QEMU_PACKED __attribute((__aligned__(4)));
>
> -struct e820_table {
> -uint32_t count;
> -struct e820_entry entry[E820_NR_ENTRIES];
> -} QEMU_PACKED __attribute((__aligned__(4)));
> -
> -extern struct e820_table e820_reserve;
>  extern struct e820_entry *e820_table;
>
>  int e820_add_entry(uint64_t address, uint64_t length, uint32_t type);
> diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
> index a283785a8d..72a42f3c66 100644
> --- a/hw/i386/fw_cfg.c
> +++ b/hw/i386/fw_cfg.c
> @@ -36,7 +36,6 @@ const char *fw_cfg_arch_key_name(uint16_t key)
>  {FW_CFG_ACPI_TABLES, "acpi_tables"},
>  {FW_CFG_SMBIOS_ENTRIES, "smbios_entries"},
>  {FW_CFG_IRQ0_OVERRIDE, "irq0_override"},
> -{FW_CFG_E820_TABLE, "e820_table"},
>  {FW_CFG_HPET, "hpet"},
>  };
>
> @@ -127,8 +126,6 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms,
>  #endif
>  fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, 1);
>
> -fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
> - _reserve, sizeof(e820_reserve));
>  fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
>  sizeof(struct e820_entry) * e820_get_num_entries());
>
> diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h
> index 275f15c1c5..86ca7c1c0c 100644
> --- a/hw/i386/fw_cfg.h
> +++ b/hw/i386/fw_cfg.h
> @@ -17,7 +17,6 @@
>  #define FW_CFG_ACPI_TABLES  (FW_CFG_ARCH_LOCAL + 0)
>  #define FW_CFG_SMBIOS_ENTRIES   (FW_CFG_ARCH_LOCAL + 1)
>  #define 

Re: Maximum QMP reply size

2022-09-07 Thread Markus Armbruster
John Snow  writes:

> Hi, I suspect I have asked this before, but I didn't write it down in
> a comment, so I forget my justification...
>
> In the QMP lib, we need to set a buffering limit for how big a QMP
> message can be -- In practice, I found that the largest possible
> response was the QAPI schema reply, and I set the code to this:
>
> # Maximum allowable size of read buffer
> _limit = (64 * 1024)
>
> However, I didn't document if this was a reasonable limit or just a
> "worksforme" one. I assume that there's no hard limit for the protocol
> or the implementation thereof in QEMU. Is there any kind of value here
> that would be more sensible than another?
>
> I'm worried that if replies get bigger in the future (possibly in some
> degenerate case I am presently unaware of) that the library default
> will become nonsensical.
>
> Any pointers/tips?

Peter and Daniel already provided some.  I can add a bit of insight into
how QMP output works in QEMU, which may or may not help you.

QEMU executes one command after the other.  A command's response
(success or failure) is a QDict.  Which is then formatted as JSON and
appended to the monitor's output buffer.

Events work similarly.

The conversion to JSON does not limit the resulting string's size.  If
it runs out of memory, QEMU dies.

The output buffer is also unbounded.  It drains into the monitor's
character device.

If the QMP client sends enough commands without reading their responses,
QEMU can run out of memory and die.

Now I'm ready to go back to your question, which is about a *single*
message (QMP command response or event): nothing in QEMU limits the size
of the QMP output message text.

Weak consolation: I guess QEMU is somewhat likely to run out of memory
and die before your client software does.  That's because QDict is a
pig: an empty one eats 4120 Bytes on my system.  Compares unfavourable
to its text representation "{}".




[PATCH v2 3/3] accel: abort if we fail to load the accelerator plugin

2022-09-07 Thread Claudio Fontana
if QEMU is configured with modules enabled, it is possible that the
load of an accelerator module will fail.
Abort in this case, relying on module_object_class_by_name to report
the specific load error if any.

Signed-off-by: Claudio Fontana 
---
 accel/accel-softmmu.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/accel/accel-softmmu.c b/accel/accel-softmmu.c
index 67276e4f52..9fa4849f2c 100644
--- a/accel/accel-softmmu.c
+++ b/accel/accel-softmmu.c
@@ -66,6 +66,7 @@ void accel_init_ops_interfaces(AccelClass *ac)
 {
 const char *ac_name;
 char *ops_name;
+ObjectClass *oc;
 AccelOpsClass *ops;
 
 ac_name = object_class_get_name(OBJECT_CLASS(ac));
@@ -73,8 +74,13 @@ void accel_init_ops_interfaces(AccelClass *ac)
 
 ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name);
 ops = ACCEL_OPS_CLASS(module_object_class_by_name(ops_name));
+oc = module_object_class_by_name(ops_name);
+if (!oc) {
+error_report("fatal: could not load module for type '%s'", ops_name);
+abort();
+}
 g_free(ops_name);
-
+ops = ACCEL_OPS_CLASS(oc);
 /*
  * all accelerators need to define ops, providing at least a mandatory
  * non-NULL create_vcpu_thread operation.
-- 
2.26.2




[PATCH v2 0/3] improve error handling for module load

2022-09-07 Thread Claudio Fontana
while investigating a permission issue in accel, where accel-tcg-x86_64.so
was not accessible, I noticed that no errors were produced regarding the
module load failure.

This series attempts to improve module_load_one and module_load_qom_one
to handle the error cases better and produce some errors.

Patch 1 is already reviewed and is about removing an unused existing
argument "mayfail" from the call stack.

Patch 2 is the real meat, and that one I would say is RFC.
Will follow up with comments on the specific questions I have.

Patch 3 finally adds a simple check in accel/, aborting if a module
is not found, but relying on the existing error report from
module_load_qom_one.

v1 -> v2:

* do not treat the display help text any differently and do report
  module load _errors_. If the module does not exist (ENOENT, ENOTDIR),
  no error will be produced.

Claudio Fontana (3):
  module: removed unused function argument "mayfail"
  module: add Error arguments to module_load_one and module_load_qom_one
  accel: abort if we fail to load the accelerator plugin

 accel/accel-softmmu.c |   8 ++-
 audio/audio.c |   6 +-
 block.c   |  12 +++-
 block/dmg.c   |  10 ++-
 hw/core/qdev.c|  10 ++-
 include/qemu/module.h |  10 +--
 qom/object.c  |  15 +++-
 softmmu/qtest.c   |   6 +-
 ui/console.c  |  18 -
 util/module.c | 157 ++
 10 files changed, 188 insertions(+), 64 deletions(-)

-- 
2.26.2




[PATCH v2 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-07 Thread Claudio Fontana
improve error handling during module load, by changing:

bool module_load_one(const char *prefix, const char *lib_name);
void module_load_qom_one(const char *type);

to:

bool module_load_one(const char *prefix, const char *name, Error **errp);
bool module_load_qom_one(const char *type, Error **errp);

module_load_qom_one has been introduced in:

commit 28457744c345 ("module: qom module support"), which built on top of
module_load_one, but discarded the bool return value. Restore it.

Adapt all callers to emit errors, or ignore them, or fail hard,
as appropriate in each context.

Signed-off-by: Claudio Fontana 
---
 audio/audio.c |   6 +-
 block.c   |  12 +++-
 block/dmg.c   |  10 ++-
 hw/core/qdev.c|  10 ++-
 include/qemu/module.h |  10 +--
 qom/object.c  |  15 +++-
 softmmu/qtest.c   |   6 +-
 ui/console.c  |  18 -
 util/module.c | 155 ++
 9 files changed, 181 insertions(+), 61 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 76b8735b44..4f4bb10cce 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -72,6 +72,7 @@ void audio_driver_register(audio_driver *drv)
 audio_driver *audio_driver_lookup(const char *name)
 {
 struct audio_driver *d;
+Error *local_err = NULL;
 
 QLIST_FOREACH(d, _drivers, next) {
 if (strcmp(name, d->name) == 0) {
@@ -79,7 +80,10 @@ audio_driver *audio_driver_lookup(const char *name)
 }
 }
 
-audio_module_load_one(name);
+if (!audio_module_load_one(name, _err) && local_err) {
+error_report_err(local_err);
+}
+
 QLIST_FOREACH(d, _drivers, next) {
 if (strcmp(name, d->name) == 0) {
 return d;
diff --git a/block.c b/block.c
index bc85f46eed..85c3742d7a 100644
--- a/block.c
+++ b/block.c
@@ -464,7 +464,11 @@ BlockDriver *bdrv_find_format(const char *format_name)
 /* The driver isn't registered, maybe we need to load a module */
 for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
 if (!strcmp(block_driver_modules[i].format_name, format_name)) {
-block_module_load_one(block_driver_modules[i].library_name);
+Error *local_err = NULL;
+if (!block_module_load_one(block_driver_modules[i].library_name,
+   _err) && local_err) {
+error_report_err(local_err);
+}
 break;
 }
 }
@@ -976,7 +980,11 @@ BlockDriver *bdrv_find_protocol(const char *filename,
 for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
 if (block_driver_modules[i].protocol_name &&
 !strcmp(block_driver_modules[i].protocol_name, protocol)) {
-block_module_load_one(block_driver_modules[i].library_name);
+Error *local_err = NULL;
+if (!block_module_load_one(block_driver_modules[i].library_name,
+   _err) && local_err) {
+error_report_err(local_err);
+}
 break;
 }
 }
diff --git a/block/dmg.c b/block/dmg.c
index 98db18d82a..349b05d20b 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -434,6 +434,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, 
int flags,
 uint64_t plist_xml_offset, plist_xml_length;
 int64_t offset;
 int ret;
+Error *local_err = NULL;
 
 ret = bdrv_apply_auto_read_only(bs, NULL, errp);
 if (ret < 0) {
@@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict *options, 
int flags,
 return -EINVAL;
 }
 
-block_module_load_one("dmg-bz2");
-block_module_load_one("dmg-lzfse");
+if (!block_module_load_one("dmg-bz2", _err) && local_err) {
+error_report_err(local_err);
+}
+local_err = NULL;
+if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
+error_report_err(local_err);
+}
 
 s->n_chunks = 0;
 s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 0806d8fcaa..5902c59c94 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -148,7 +148,15 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, 
Error **errp)
 DeviceState *qdev_new(const char *name)
 {
 if (!object_class_by_name(name)) {
-module_load_qom_one(name);
+Error *local_err = NULL;
+if (!module_load_qom_one(name, _err)) {
+if (local_err) {
+error_report_err(local_err);
+} else {
+error_report("could not find a module for type '%s'", name);
+}
+abort();
+}
 }
 return DEVICE(object_new(name));
 }
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 8c012bbe03..7893922aba 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -61,16 +61,16 @@ typedef enum {
 #define fuzz_target_init(function) module_init(function, \
 

[PATCH v2 1/3] module: removed unused function argument "mayfail"

2022-09-07 Thread Claudio Fontana
mayfail is always passed as false for every invocation throughout the program.
It controls whether to printf or not to printf an error on
g_module_open failure.

Remove this unused argument.

Signed-off-by: Claudio Fontana 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/qemu/module.h |  8 
 softmmu/qtest.c   |  2 +-
 util/module.c | 20 +---
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/include/qemu/module.h b/include/qemu/module.h
index bd73607104..8c012bbe03 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -61,15 +61,15 @@ typedef enum {
 #define fuzz_target_init(function) module_init(function, \
MODULE_INIT_FUZZ_TARGET)
 #define migration_init(function) module_init(function, MODULE_INIT_MIGRATION)
-#define block_module_load_one(lib) module_load_one("block-", lib, false)
-#define ui_module_load_one(lib) module_load_one("ui-", lib, false)
-#define audio_module_load_one(lib) module_load_one("audio-", lib, false)
+#define block_module_load_one(lib) module_load_one("block-", lib)
+#define ui_module_load_one(lib) module_load_one("ui-", lib)
+#define audio_module_load_one(lib) module_load_one("audio-", lib)
 
 void register_module_init(void (*fn)(void), module_init_type type);
 void register_dso_module_init(void (*fn)(void), module_init_type type);
 
 void module_call_init(module_init_type type);
-bool module_load_one(const char *prefix, const char *lib_name, bool mayfail);
+bool module_load_one(const char *prefix, const char *lib_name);
 void module_load_qom_one(const char *type);
 void module_load_qom_all(void);
 void module_allow_arch(const char *arch);
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
index f8acef2628..76eb7bac56 100644
--- a/softmmu/qtest.c
+++ b/softmmu/qtest.c
@@ -756,7 +756,7 @@ static void qtest_process_command(CharBackend *chr, gchar 
**words)
 g_assert(words[1] && words[2]);
 
 qtest_send_prefix(chr);
-if (module_load_one(words[1], words[2], false)) {
+if (module_load_one(words[1], words[2])) {
 qtest_sendf(chr, "OK\n");
 } else {
 qtest_sendf(chr, "FAIL\n");
diff --git a/util/module.c b/util/module.c
index 8ddb0e18f5..8563edd626 100644
--- a/util/module.c
+++ b/util/module.c
@@ -144,7 +144,7 @@ static bool module_check_arch(const QemuModinfo *modinfo)
 return true;
 }
 
-static int module_load_file(const char *fname, bool mayfail, bool 
export_symbols)
+static int module_load_file(const char *fname, bool export_symbols)
 {
 GModule *g_module;
 void (*sym)(void);
@@ -172,10 +172,8 @@ static int module_load_file(const char *fname, bool 
mayfail, bool export_symbols
 }
 g_module = g_module_open(fname, flags);
 if (!g_module) {
-if (!mayfail) {
-fprintf(stderr, "Failed to open module: %s\n",
-g_module_error());
-}
+fprintf(stderr, "Failed to open module: %s\n",
+g_module_error());
 ret = -EINVAL;
 goto out;
 }
@@ -208,7 +206,7 @@ out:
 }
 #endif
 
-bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
+bool module_load_one(const char *prefix, const char *lib_name)
 {
 bool success = false;
 
@@ -256,7 +254,7 @@ bool module_load_one(const char *prefix, const char 
*lib_name, bool mayfail)
 if (strcmp(modinfo->name, module_name) == 0) {
 /* we depend on other module(s) */
 for (sl = modinfo->deps; *sl != NULL; sl++) {
-module_load_one("", *sl, false);
+module_load_one("", *sl);
 }
 } else {
 for (sl = modinfo->deps; *sl != NULL; sl++) {
@@ -287,7 +285,7 @@ bool module_load_one(const char *prefix, const char 
*lib_name, bool mayfail)
 for (i = 0; i < n_dirs; i++) {
 fname = g_strdup_printf("%s/%s%s",
 dirs[i], module_name, CONFIG_HOST_DSOSUF);
-ret = module_load_file(fname, mayfail, export_symbols);
+ret = module_load_file(fname, export_symbols);
 g_free(fname);
 fname = NULL;
 /* Try loading until loaded a module file */
@@ -333,7 +331,7 @@ void module_load_qom_one(const char *type)
 }
 for (sl = modinfo->objs; *sl != NULL; sl++) {
 if (strcmp(type, *sl) == 0) {
-module_load_one("", modinfo->name, false);
+module_load_one("", modinfo->name);
 }
 }
 }
@@ -354,7 +352,7 @@ void module_load_qom_all(void)
 if (!module_check_arch(modinfo)) {
 continue;
 }
-module_load_one("", modinfo->name, false);
+module_load_one("", modinfo->name);
 }
 module_loaded_qom_all = true;
 }
@@ -370,7 +368,7 @@ void qemu_load_module_for_opts(const char *group)
 }
 for (sl = modinfo->opts; *sl != NULL; sl++) {
   

Re: [PATCH v9 05/10] s390x/cpu: reporting drawers and books topology to the guest

2022-09-07 Thread Janis Schoetterl-Glausch
On Fri, 2022-09-02 at 09:55 +0200, Pierre Morel wrote:
> The guest can ask for a topology report on drawer's or book's
> level.
> Let's implement the STSI instruction's handling for the corresponding
> selector values.
> 
> Signed-off-by: Pierre Morel 
> ---
>  hw/s390x/cpu-topology.c | 19 +++---
>  hw/s390x/s390-virtio-ccw.c  |  2 ++
>  include/hw/s390x/cpu-topology.h |  7 +++-
>  target/s390x/cpu_topology.c | 64 +++--
>  4 files changed, 76 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c
> index e2fd5c7e44..bb9ae63483 100644
> --- a/hw/s390x/cpu-topology.c
> +++ b/hw/s390x/cpu-topology.c
> 
[...]

> @@ -99,13 +103,20 @@ static void s390_topology_realize(DeviceState *dev, 
> Error **errp)
>  S390Topology *topo = S390_CPU_TOPOLOGY(dev);
>  int n;
>  
> +topo->drawers = ms->smp.drawers;
> +topo->books = ms->smp.books;
> +topo->total_books = topo->books * topo->drawers;
>  topo->sockets = ms->smp.sockets;
> +topo->total_sockets = topo->sockets * topo->books * topo->drawers;
>  topo->cores = ms->smp.cores;
> -topo->tles = ms->smp.max_cpus;
>  
> -n = topo->sockets;
> +n = topo->drawers;
> +topo->drawer = g_malloc0(n * sizeof(S390TopoContainer));
> +n *= topo->books;
> +topo->book = g_malloc0(n * sizeof(S390TopoContainer));
> +n *= topo->sockets;
>  topo->socket = g_malloc0(n * sizeof(S390TopoContainer));
> -topo->tle = g_malloc0(topo->tles * sizeof(S390TopoTLE));
> +topo->tle = g_malloc0(n * sizeof(S390TopoTLE));

Same question here about using g_new0.
>  
>  qemu_mutex_init(>topo_mutex);
>  }
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 15cefd104b..3f28e28d47 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -626,6 +626,8 @@ static void ccw_machine_class_init(ObjectClass *oc, void 
> *data)
>  hc->unplug_request = s390_machine_device_unplug_request;
>  nc->nmi_monitor_handler = s390_nmi;
>  mc->default_ram_id = "s390.ram";
> +mc->smp_props.books_supported = true;
> +mc->smp_props.drawers_supported = true;
>  }
>  
>  static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
> diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h
> index 0b7f3d10b2..4f8ac39ca0 100644
> --- a/include/hw/s390x/cpu-topology.h
> +++ b/include/hw/s390x/cpu-topology.h
> @@ -29,9 +29,14 @@ typedef struct S390TopoTLE {
>  
>  struct S390Topology {
>  SysBusDevice parent_obj;
> +int total_books;
> +int total_sockets;

What are these used for? I'm not seeing anything.

> +int drawers;
> +int books;
>  int sockets;
>  int cores;
> -int tles;

You remove this in this patch and you didn't really need it before.
As far as I can tell it was just used for calculating the number of
tles to allocate and you could use a local variable instead.
So I would get rid of it in the patch that introduced it.

> +S390TopoContainer *drawer;
> +S390TopoContainer *book;
>  S390TopoContainer *socket;
>  S390TopoTLE *tle;
>  QemuMutex topo_mutex;
> diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
> index 56865dafc6..305fbb9734 100644
> --- a/target/s390x/cpu_topology.c
> +++ b/target/s390x/cpu_topology.c
> @@ -37,19 +37,18 @@ static char *fill_tle_cpu(char *p, uint64_t mask, int 
> origin)
>  return p + sizeof(*tle);
>  }
>  
> -static char *s390_top_set_level2(S390Topology *topo, char *p)
> +static char *s390_top_set_level2(S390Topology *topo, char *p, int fs, int ns)
>  {

I wouldn't hate more verbose names for fs and ns. start_socket,
num_socket maybe? Same for fb, nb, but it is your call, it's not really
hard to understand the code.

> -int i, origin;
> +int socket, origin;
> +uint64_t mask;
>  
> -for (i = 0; i < topo->sockets; i++) {
> -if (!topo->socket[i].active_count) {
> +for (socket = fs; socket < fs + ns; socket++) {
> +if (!topo->socket[socket].active_count) {
>  continue;
>  }
> -p = fill_container(p, 1, i);
> +p = fill_container(p, 1, socket);

Have you considered using an enum for the level constants?

>  for (origin = 0; origin < S390_TOPOLOGY_MAX_ORIGIN; origin++) {
> -uint64_t mask = 0L;
> -
> -mask = be64_to_cpu(topo->tle[i].mask[origin]);
> +mask = be64_to_cpu(topo->tle[socket].mask[origin]);
>  if (mask) {
>  p = fill_tle_cpu(p, mask, origin);
>  }
> @@ -58,19 +57,63 @@ static char *s390_top_set_level2(S390Topology *topo, char 
> *p)
>  return p;
>  }
>  
> +static char *s390_top_set_level3(S390Topology *topo, char *p, int fb, int nb)
> +{
> +int book, fs = 0;
> +
> +for (book = fb; book < fb + nb; book++, fs += topo->sockets) {
> +if (!topo->book[book].active_count) {
> +continue;

Re: [PATCH v9 03/10] s390x/cpu topology: reporting the CPU topology to the guest

2022-09-07 Thread Janis Schoetterl-Glausch
On Fri, 2022-09-02 at 09:55 +0200, Pierre Morel wrote:
> The guest can use the STSI instruction to get a buffer filled
> with the CPU topology description.
> 
> Let us implement the STSI instruction for the basis CPU topology
> level, level 2.
> 
> Signed-off-by: Pierre Morel 
> ---
>  hw/s390x/cpu-topology.c |   4 ++
>  include/hw/s390x/cpu-topology.h |   5 ++
>  target/s390x/cpu.h  |  49 +++
>  target/s390x/cpu_topology.c | 108 
>  target/s390x/kvm/kvm.c  |   6 +-
>  target/s390x/meson.build|   1 +
>  6 files changed, 172 insertions(+), 1 deletion(-)
>  create mode 100644 target/s390x/cpu_topology.c
> 
[...]

> diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c

[...]

> +static char *fill_tle_cpu(char *p, uint64_t mask, int origin)
> +{
> +SysIBTl_cpu *tle = (SysIBTl_cpu *)p;
> +
> +tle->nl = 0;
> +tle->dedicated = 1;
> +tle->polarity = S390_TOPOLOGY_POLARITY_H;
> +tle->type = S390_TOPOLOGY_CPU_TYPE;
> +tle->origin = origin * 64;

origin is a multibyte field too, so needs a conversion too.

> +tle->mask = be64_to_cpu(mask);
> +return p + sizeof(*tle);
> +}
> +
[...]



Re: [PATCH 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-07 Thread Claudio Fontana
On 9/7/22 09:36, Gerd Hoffmann wrote:
>   Hi,
>  
>> For this module_load_qom_all() maybe Gerd has a bit more context on
>> was should be the error reporting here?
> 
> Use case for module_load_qom_all() is someone enumerating the qom
> objects available.  So we load all modules known to have all object
> types registered and can return a complete list.
> 
> It could be that some of the known modules are not there.  Consider a
> distro packaging modules which depend on shared libraries into optional
> sub-rpms, to reduce the dependency chain of core qemu.  So, with core
> qemu installed and (some of) the sub-rpms not installed
> module_load_qom_all() will obviously fail to load some modules.
> 
> But I don't think those errors should be reported.  The object types
> implemented by the missing modules will also be missing from the object
> type list ...
> 
> Example: hw-usb-host.so is not installed.
> 
>   => 'qemu -device help' should IMHO not report the module load error
>  and just not list the 'usb-host' device.
>   => 'qemu -device usb-host' should report the module load error.
> 
> take care,
>   Gerd
> 

Hi Gerd,

the thing is, we can distinguish between a module not being present (ENOENT, 
ENOTDIR),
from a module being present, but failing to load.

So the "module not there" thing does not need to be treated separately, because 
no warning/error will be emitted if the module is not there.

It is up to the user/caller to decide what to do with the condition "module not 
there", error out and quit, continue on, etc.

Thanks this helped,

Claudio



Re: [PATCH 2/3] module: add Error arguments to module_load_one and module_load_qom_one

2022-09-07 Thread Claudio Fontana
On 9/6/22 13:55, Claudio Fontana wrote:
> improve error handling during module load, by changing:
> 
> bool module_load_one(const char *prefix, const char *lib_name);
> void module_load_qom_one(const char *type);
> 
> to:
> 
> bool module_load_one(const char *prefix, const char *name, Error **errp);
> bool module_load_qom_one(const char *type, Error **errp);
> 
> module_load_qom_one has been introduced in:
> 
> commit 28457744c345 ("module: qom module support"), which built on top of
> module_load_one, but discarded the bool return value. Restore it.
> 
> Adapt all callers to emit errors, or ignore them, or fail hard,
> as appropriate in each context.
> 
> Signed-off-by: Claudio Fontana 
> ---
>  audio/audio.c |   6 +-
>  block.c   |  12 +++-
>  block/dmg.c   |  10 ++-
>  hw/core/qdev.c|  10 ++-
>  include/qemu/module.h |  10 +--
>  qom/object.c  |  15 +++-
>  softmmu/qtest.c   |   6 +-
>  ui/console.c  |  19 +-
>  util/module.c | 155 ++
>  9 files changed, 182 insertions(+), 61 deletions(-)
> 
> diff --git a/audio/audio.c b/audio/audio.c
> index 76b8735b44..4f4bb10cce 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -72,6 +72,7 @@ void audio_driver_register(audio_driver *drv)
>  audio_driver *audio_driver_lookup(const char *name)
>  {
>  struct audio_driver *d;
> +Error *local_err = NULL;
>  
>  QLIST_FOREACH(d, _drivers, next) {
>  if (strcmp(name, d->name) == 0) {
> @@ -79,7 +80,10 @@ audio_driver *audio_driver_lookup(const char *name)
>  }
>  }
>  
> -audio_module_load_one(name);
> +if (!audio_module_load_one(name, _err) && local_err) {
> +error_report_err(local_err);
> +}
> +
>  QLIST_FOREACH(d, _drivers, next) {
>  if (strcmp(name, d->name) == 0) {
>  return d;
> diff --git a/block.c b/block.c
> index bc85f46eed..85c3742d7a 100644
> --- a/block.c
> +++ b/block.c
> @@ -464,7 +464,11 @@ BlockDriver *bdrv_find_format(const char *format_name)
>  /* The driver isn't registered, maybe we need to load a module */
>  for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
>  if (!strcmp(block_driver_modules[i].format_name, format_name)) {
> -block_module_load_one(block_driver_modules[i].library_name);
> +Error *local_err = NULL;
> +if (!block_module_load_one(block_driver_modules[i].library_name,
> +   _err) && local_err) {
> +error_report_err(local_err);
> +}
>  break;
>  }
>  }
> @@ -976,7 +980,11 @@ BlockDriver *bdrv_find_protocol(const char *filename,
>  for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
>  if (block_driver_modules[i].protocol_name &&
>  !strcmp(block_driver_modules[i].protocol_name, protocol)) {
> -block_module_load_one(block_driver_modules[i].library_name);
> +Error *local_err = NULL;
> +if (!block_module_load_one(block_driver_modules[i].library_name,
> +   _err) && local_err) {
> +error_report_err(local_err);
> +}
>  break;
>  }
>  }
> diff --git a/block/dmg.c b/block/dmg.c
> index 98db18d82a..349b05d20b 100644
> --- a/block/dmg.c
> +++ b/block/dmg.c
> @@ -434,6 +434,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, 
> int flags,
>  uint64_t plist_xml_offset, plist_xml_length;
>  int64_t offset;
>  int ret;
> +Error *local_err = NULL;
>  
>  ret = bdrv_apply_auto_read_only(bs, NULL, errp);
>  if (ret < 0) {
> @@ -446,8 +447,13 @@ static int dmg_open(BlockDriverState *bs, QDict 
> *options, int flags,
>  return -EINVAL;
>  }
>  
> -block_module_load_one("dmg-bz2");
> -block_module_load_one("dmg-lzfse");
> +if (!block_module_load_one("dmg-bz2", _err) && local_err) {
> +error_report_err(local_err);
> +}
> +local_err = NULL;
> +if (!block_module_load_one("dmg-lzfse", _err) && local_err) {
> +error_report_err(local_err);
> +}
>  
>  s->n_chunks = 0;
>  s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 0806d8fcaa..5902c59c94 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -148,7 +148,15 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState 
> *bus, Error **errp)
>  DeviceState *qdev_new(const char *name)
>  {
>  if (!object_class_by_name(name)) {
> -module_load_qom_one(name);
> +Error *local_err = NULL;
> +if (!module_load_qom_one(name, _err)) {
> +if (local_err) {
> +error_report_err(local_err);
> +} else {
> +error_report("could not find a module for type '%s'", name);
> +}
> +abort();
> +}
>  }
>  

Re: [PATCH v6 09/14] hw/ppc: set machine->fdt in pnv_reset()

2022-09-07 Thread Frederic Barrat




On 05/09/2022 01:34, Daniel Henrique Barboza wrote:

This will enable support for the 'dumpdtb' QMP/HMP command for
all powernv machines.

Cc: Cédric Le Goater 
Cc: Frederic Barrat 
Signed-off-by: Daniel Henrique Barboza 
---



LGTM
Reviewed-by: Frederic Barrat 

  Fred



  hw/ppc/pnv.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 354aa289d1..6a20c4811f 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -678,7 +678,13 @@ static void pnv_reset(MachineState *machine)
  qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
  cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
  
-g_free(fdt);

+/*
+ * Set machine->fdt for 'dumpdtb' QMP/HMP command. Free
+ * the existing machine->fdt to avoid leaking it during
+ * a reset.
+ */
+g_free(machine->fdt);
+machine->fdt = fdt;
  }
  
  static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)




[PULL 44/44] target/riscv: Update the privilege field for sscofpmf CSRs

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

The sscofpmf extension was ratified as a part of priv spec v1.12.
Mark the csr_ops accordingly.

Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Message-Id: <20220824221701.41932-6-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 90 ++
 1 file changed, 60 insertions(+), 30 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 2151e280a8..b96db1b62b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -4067,63 +4067,92 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
  write_mhpmevent   },
 
 [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT4H]= { "mhpmevent4h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT5H]= { "mhpmevent5h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT6H]= { "mhpmevent6h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT7H]= { "mhpmevent7h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT8H]= { "mhpmevent8h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT9H]= { "mhpmevent9h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT10H]   = { "mhpmevent10h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT11H]   = { "mhpmevent11h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT12H]   = { "mhpmevent12h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT13H]   = { "mhpmevent13h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT14H]   = { "mhpmevent14h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT15H]   = { "mhpmevent15h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT16H]   = { "mhpmevent16h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT17H]   = { "mhpmevent17h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh   },
+ write_mhpmeventh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_MHPMEVENT18H]   = { "mhpmevent18h",sscofpmf,  read_mhpmeventh,
- write_mhpmeventh 

Re: [PATCH] fw_cfg: Don't set callback_opaque NULL in fw_cfg_modify_bytes_read()

2022-09-07 Thread Gerd Hoffmann
> > QEMU_EFI reports the below error:
> > ProcessCmdAddPointer: invalid pointer value in "etc/acpi/tables"
> > OnRootBridgesConnected: InstallAcpiTables: Protocol Error
> > 
> > Debugging shows that on first reboot(after hot-adding NVDIMM),
> > Qemu updates the etc/table-loader len,
> > 
> > qemu_ram_resize()
> >   fw_cfg_modify_file()
> >      fw_cfg_modify_bytes_read()
> > 
> > And in fw_cfg_modify_bytes_read() we set the "callback_opaque" for
> > the "key" entry to NULL. Because of this, on the second reboot,
> > virt_acpi_build_update() is called with a NULL "build_state" and
> > returns without updating the ACPI tables. This seems to be 
> > upsetting the firmware.
> > 
> > To fix this, don't change the callback_opaque in fw_cfg_modify_bytes_read().
> 
> Fixes: bdbb5b1706d165 ("fw_cfg: add fw_cfg_machine_reset function")
> Acked-by: Igor Mammedov 
> 
> CCing Gerd to have a second set of eyes on it

Hmm.  Original patch clears both 'callback_opaque' and 'callback' (where
'callback' used to be what 'select_cb' is today I think).  Not fully
sure what the motivation was for that.  Maybe because using both
fw_cfg_modify*() calls and a callback for update-on-read for a given
entry looks pointless.  Should that be the case there are better ways to
catch that, like having fw_cfg_modify_bytes_read() throw an error in
case select_cb is not NULL instead of silently clearing the callback.

In any case clearing callback_opaque only is obviously wrong, so
Acked-by: Gerd Hoffmann 

take care,
  Gerd




Re: [PATCH v3 3/5] acpi/nvdimm: define macro for NVDIMM Device _DSM

2022-09-07 Thread Igor Mammedov
On Thu,  1 Sep 2022 11:27:19 +0800
Robert Hoo  wrote:

> Since it will be heavily used in next patch, define macro
> NVDIMM_DEVICE_DSM_UUID for "4309AC30-0D11-11E4-9191-0800200C9A66", which is
> NVDIMM device specific method uuid defined in NVDIMM _DSM interface spec,
> Section 3. [1]
> 
> No functional changes in this patch.
> 
> [1] https://pmem.io/documents/IntelOptanePMem_DSM_Interface-V2.0.pdf
> 
> Signed-off-by: Robert Hoo 
> Reviewed-by: Jingqi Liu 

Reviewed-by: Igor Mammedov 

> ---
>  hw/acpi/nvdimm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
> index 201317c611..afff911c1e 100644
> --- a/hw/acpi/nvdimm.c
> +++ b/hw/acpi/nvdimm.c
> @@ -922,6 +922,7 @@ void nvdimm_init_acpi_state(NVDIMMState *state, 
> MemoryRegion *io,
>  #define NVDIMM_DSM_RFIT_STATUS  "RSTA"
>  
>  #define NVDIMM_QEMU_RSVD_UUID   "648B9CF2-CDA1-4312-8AD9-49C4AF32BD62"
> +#define NVDIMM_DEVICE_DSM_UUID  "4309AC30-0D11-11E4-9191-0800200C9A66"
>  
>  static void nvdimm_build_common_dsm(Aml *dev,
>  NVDIMMState *nvdimm_state)
> @@ -1029,8 +1030,7 @@ static void nvdimm_build_common_dsm(Aml *dev,
> /* UUID for QEMU internal use */), expected_uuid));
>  aml_append(elsectx, ifctx);
>  elsectx2 = aml_else();
> -aml_append(elsectx2, aml_store(
> -   aml_touuid("4309AC30-0D11-11E4-9191-0800200C9A66")
> +aml_append(elsectx2, aml_store(aml_touuid(NVDIMM_DEVICE_DSM_UUID)
> /* UUID for NVDIMM Devices */, expected_uuid));
>  aml_append(elsectx, elsectx2);
>  aml_append(method, elsectx);




[PULL 43/44] hw/riscv: virt: Add PMU DT node to the device tree

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

Qemu virt machine can support few cache events and cycle/instret counters.
It also supports counter overflow for these events.

Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
capabilities. There are some dummy nodes added for testing as well.

Acked-by: Alistair Francis 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
Message-Id: <20220824221701.41932-5-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmu.h |  1 +
 hw/riscv/virt.c| 16 +
 target/riscv/pmu.c | 57 ++
 3 files changed, 74 insertions(+)

diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 036653627f..3004ce37b6 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -31,5 +31,6 @@ int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
 int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
uint32_t ctr_idx);
 int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
+void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char *pmu_name);
 int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
   uint32_t ctr_idx);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index ff8c0df5cd..befa9d2c26 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -30,6 +30,7 @@
 #include "hw/char/serial.h"
 #include "target/riscv/cpu.h"
 #include "hw/core/sysbus-fdt.h"
+#include "target/riscv/pmu.h"
 #include "hw/riscv/riscv_hart.h"
 #include "hw/riscv/virt.h"
 #include "hw/riscv/boot.h"
@@ -708,6 +709,20 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
 aplic_phandles[socket] = aplic_s_phandle;
 }
 
+static void create_fdt_pmu(RISCVVirtState *s)
+{
+char *pmu_name;
+MachineState *mc = MACHINE(s);
+RISCVCPU hart = s->soc[0].harts[0];
+
+pmu_name = g_strdup_printf("/soc/pmu");
+qemu_fdt_add_subnode(mc->fdt, pmu_name);
+qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
+riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
+
+g_free(pmu_name);
+}
+
 static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
bool is_32_bit, uint32_t *phandle,
uint32_t *irq_mmio_phandle,
@@ -1036,6 +1051,7 @@ static void create_fdt(RISCVVirtState *s, const 
MemMapEntry *memmap,
 
 create_fdt_flash(s, memmap);
 create_fdt_fw_cfg(s, memmap);
+create_fdt_pmu(s);
 
 update_bootargs:
 if (cmdline && *cmdline) {
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index a5f504e53c..b8e56d2b7b 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -20,11 +20,68 @@
 #include "cpu.h"
 #include "pmu.h"
 #include "sysemu/cpu-timers.h"
+#include "sysemu/device_tree.h"
 
 #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
 #define MAKE_32BIT_MASK(shift, length) \
 (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
 
+/*
+ * To keep it simple, any event can be mapped to any programmable counters in
+ * QEMU. The generic cycle & instruction count events can also be monitored
+ * using programmable counters. In that case, mcycle & minstret must continue
+ * to provide the correct value as well. Heterogeneous PMU per hart is not
+ * supported yet. Thus, number of counters are same across all harts.
+ */
+void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
+{
+uint32_t fdt_event_ctr_map[20] = {};
+uint32_t cmask;
+
+/* All the programmable counters can map to any event */
+cmask = MAKE_32BIT_MASK(3, num_ctrs);
+
+   /*
+* The event encoding is specified in the SBI specification
+* Event idx is a 20bits wide number encoded as follows:
+* event_idx[19:16] = type
+* event_idx[15:0] = code
+* The code field in cache events are encoded as follows:
+* event_idx.code[15:3] = cache_id
+* event_idx.code[2:1] = op_id
+* event_idx.code[0:0] = result_id
+*/
+
+   /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
+   fdt_event_ctr_map[0] = cpu_to_be32(0x0001);
+   fdt_event_ctr_map[1] = cpu_to_be32(0x0001);
+   fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
+
+   /* SBI_PMU_HW_INSTRUCTIONS: 0x02 : type(0x00) */
+   fdt_event_ctr_map[3] = cpu_to_be32(0x0002);
+   fdt_event_ctr_map[4] = cpu_to_be32(0x0002);
+   fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2);
+
+   /* SBI_PMU_HW_CACHE_DTLB : 0x03 READ : 0x00 MISS : 0x00 type(0x01) */
+   fdt_event_ctr_map[6] = cpu_to_be32(0x00010019);
+   fdt_event_ctr_map[7] = cpu_to_be32(0x00010019);
+   fdt_event_ctr_map[8] = cpu_to_be32(cmask);
+
+   /* SBI_PMU_HW_CACHE_DTLB : 0x03 WRITE : 0x01 MISS : 0x00 type(0x01) */
+   fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B);
+   fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B);
+   fdt_event_ctr_map[11] = cpu_to_be32(cmask);
+
+   /* SBI_PMU_HW_CACHE_ITLB : 0x04 READ : 0x00 MISS : 0x00 type(0x01) */
+   

Re: [PATCH] fw_cfg: Don't set callback_opaque NULL in fw_cfg_modify_bytes_read()

2022-09-07 Thread Igor Mammedov
On Thu, 25 Aug 2022 17:18:42 +0100
Shameer Kolothum  wrote:

> Hi
> 
> On arm/virt platform, Chen Xiang reported a Guest crash while
> attempting the below steps,
> 
> 1. Launch the Guest with nvdimm=on
> 2. Hot-add a NVDIMM dev
> 3. Reboot
> 4. Guest boots fine.
> 5. Reboot again.
> 6. Guest boot fails.
> 
> QEMU_EFI reports the below error:
> ProcessCmdAddPointer: invalid pointer value in "etc/acpi/tables"
> OnRootBridgesConnected: InstallAcpiTables: Protocol Error
> 
> Debugging shows that on first reboot(after hot-adding NVDIMM),
> Qemu updates the etc/table-loader len,
> 
> qemu_ram_resize()
>   fw_cfg_modify_file()
>      fw_cfg_modify_bytes_read()
> 
> And in fw_cfg_modify_bytes_read() we set the "callback_opaque" for
> the "key" entry to NULL. Because of this, on the second reboot,
> virt_acpi_build_update() is called with a NULL "build_state" and
> returns without updating the ACPI tables. This seems to be 
> upsetting the firmware.
> 
> To fix this, don't change the callback_opaque in fw_cfg_modify_bytes_read().

Fixes: bdbb5b1706d165 ("fw_cfg: add fw_cfg_machine_reset function")
Acked-by: Igor Mammedov 

CCing Gerd to have a second set of eyes on it

> Reported-by: chenxiang 
> Signed-off-by: Shameer Kolothum 
> ---
> I am still not very convinced this is the root cause of the issue.
> Though it looks like setting callback_opaque to NULL while updating
> the file size is wrong, what puzzles me is that on the second reboot
> we don't have any ACPI table size changes and ideally firmware should
> see the updated tables from the first reboot itself.
> 
> Please take a look and let me know.
> 
> Thanks,
> Shameer
> 
> ---
>  hw/nvram/fw_cfg.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
> index d605f3f45a..dfe8404c01 100644
> --- a/hw/nvram/fw_cfg.c
> +++ b/hw/nvram/fw_cfg.c
> @@ -728,7 +728,6 @@ static void *fw_cfg_modify_bytes_read(FWCfgState *s, 
> uint16_t key,
>  ptr = s->entries[arch][key].data;
>  s->entries[arch][key].data = data;
>  s->entries[arch][key].len = len;
> -s->entries[arch][key].callback_opaque = NULL;

>  s->entries[arch][key].allow_write = false;

As Christian have mentioned, this also looks bogus.
perhaps another patch to fix that as well.

>  return ptr;




[PULL 41/44] target/riscv: Simplify counter predicate function

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
as a unified counter. Thus, the predicate function doesn't need handle each
case separately.

Simplify the predicate function so that we just handle things differently
between RV32/RV64 and S/HS mode.

Reviewed-by: Bin Meng 
Acked-by: Alistair Francis 
Signed-off-by: Atish Patra 
Message-Id: <20220824221701.41932-3-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 110 -
 1 file changed, 9 insertions(+), 101 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 888ddfc4dd..2151e280a8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -75,6 +75,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
 int ctr_index;
+target_ulong ctr_mask;
 int base_csrno = CSR_CYCLE;
 bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
 
@@ -83,122 +84,29 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 base_csrno += 0x80;
 }
 ctr_index = csrno - base_csrno;
+ctr_mask = BIT(ctr_index);
 
 if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
 (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
 goto skip_ext_pmu_check;
 }
 
-if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index {
+if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
 /* No counter is enabled in PMU or the counter is out of range */
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
 skip_ext_pmu_check:
 
-if (env->priv == PRV_S) {
-switch (csrno) {
-case CSR_CYCLE:
-if (!get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_TIME:
-if (!get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_INSTRET:
-if (!get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-if (!get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-}
-if (rv32) {
-switch (csrno) {
-case CSR_CYCLEH:
-if (!get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_TIMEH:
-if (!get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_INSTRETH:
-if (!get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
-if (!get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-break;
-}
-}
+if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
+((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask {
+return RISCV_EXCP_ILLEGAL_INST;
 }
 
 if (riscv_cpu_virt_enabled(env)) {
-switch (csrno) {
-case CSR_CYCLE:
-if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_TIME:
-if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-get_field(env->mcounteren, COUNTEREN_TM)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_INSTRET:
-if (!get_field(env->hcounteren, COUNTEREN_IR) &&
-get_field(env->mcounteren, COUNTEREN_IR)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
-if (!get_field(env->hcounteren, 1 << ctr_index) &&
- get_field(env->mcounteren, 1 << ctr_index)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-}
-if (rv32) {
-switch (csrno) {
-case CSR_CYCLEH:
-if (!get_field(env->hcounteren, COUNTEREN_CY) &&
-get_field(env->mcounteren, COUNTEREN_CY)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-break;
-case CSR_TIMEH:
-if (!get_field(env->hcounteren, COUNTEREN_TM) &&
-   

[PULL 31/44] hw/riscv: virt: fix uart node name

2022-09-07 Thread Alistair Francis via
From: Conor Dooley 

"uart" is not a node name that complies with the dt-schema.
Change the node name to "serial" to ix warnings seen during
dt-validate on a dtbdump of the virt machine such as:
/stuff/qemu/qemu.dtb: uart@1000: $nodename:0: 'uart@1000' does not 
match '^serial(@.*)?$'
From schema: 
/stuff/linux/Documentation/devicetree/bindings/serial/8250.yaml

Reported-by: Rob Herring 
Reviewed-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-id: 20220810184612.157317-2-m...@conchuod.ie
Link: 
https://lore.kernel.org/linux-riscv/20220803170552.ga2250266-r...@kernel.org/
Fixes: 04331d0b56 ("RISC-V VirtIO Machine")
Signed-off-by: Conor Dooley 
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index c1e8e0fcaf..9d36133b74 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -918,7 +918,7 @@ static void create_fdt_uart(RISCVVirtState *s, const 
MemMapEntry *memmap,
 char *name;
 MachineState *mc = MACHINE(s);
 
-name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base);
+name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base);
 qemu_fdt_add_subnode(mc->fdt, name);
 qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a");
 qemu_fdt_setprop_cells(mc->fdt, name, "reg",
-- 
2.37.2




[PULL 42/44] target/riscv: Add few cache related PMU events

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

Qemu can monitor the following cache related PMU events through
tlb_fill functions.

1. DTLB load/store miss
3. ITLB prefetch miss

Increment the PMU counter in tlb_fill function.

Reviewed-by: Alistair Francis 
Tested-by: Heiko Stuebner 
Signed-off-by: Atish Patra 
Signed-off-by: Atish Patra 
Message-Id: <20220824221701.41932-4-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 719c5d5d02..67e4c0efd2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,11 +21,13 @@
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "cpu.h"
+#include "pmu.h"
 #include "exec/exec-all.h"
 #include "instmap.h"
 #include "tcg/tcg-op.h"
 #include "trace.h"
 #include "semihosting/common-semi.h"
+#include "cpu_bits.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -1189,6 +1191,28 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 cpu_loop_exit_restore(cs, retaddr);
 }
 
+
+static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType access_type)
+{
+enum riscv_pmu_event_idx pmu_event_type;
+
+switch (access_type) {
+case MMU_INST_FETCH:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS;
+break;
+case MMU_DATA_LOAD:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS;
+break;
+case MMU_DATA_STORE:
+pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS;
+break;
+default:
+return;
+}
+
+riscv_pmu_incr_ctr(cpu, pmu_event_type);
+}
+
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr)
@@ -1287,6 +1311,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 } else {
+pmu_tlb_fill_incr_ctr(cpu, access_type);
 /* Single stage lookup */
 ret = get_physical_address(env, , , address, NULL,
access_type, mmu_idx, true, false, false);
-- 
2.37.2




[PULL 39/44] target/riscv: Add vstimecmp support

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

vstimecmp CSR allows the guest OS or to program the next guest timer
interrupt directly. Thus, hypervisor no longer need to inject the
timer interrupt to the guest if vstimecmp is used. This was ratified
as a part of the Sstc extension.

Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Message-Id: <20220824221357.41070-4-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  4 ++
 target/riscv/cpu_bits.h|  4 ++
 target/riscv/cpu_helper.c  | 11 +++--
 target/riscv/csr.c | 88 --
 target/riscv/machine.c |  1 +
 target/riscv/time_helper.c | 16 +++
 6 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d2529b757a..d895a0af2c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -311,6 +311,8 @@ struct CPUArchState {
 /* Sstc CSRs */
 uint64_t stimecmp;
 
+uint64_t vstimecmp;
+
 /* physical memory protection */
 pmp_table_t pmp_state;
 target_ulong mseccfg;
@@ -365,6 +367,8 @@ struct CPUArchState {
 
 /* Fields from here on are preserved across CPU reset. */
 QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
+QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
+bool vstime_irq;
 
 hwaddr kernel_addr;
 hwaddr fdt_addr;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index ac17cf1515..095dab19f5 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -257,6 +257,10 @@
 #define CSR_VSIP0x244
 #define CSR_VSATP   0x280
 
+/* Sstc virtual CSRs */
+#define CSR_VSTIMECMP   0x24D
+#define CSR_VSTIMECMPH  0x25D
+
 #define CSR_MTINST  0x34a
 #define CSR_MTVAL2  0x34b
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 05c0c8d777..719c5d5d02 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -346,8 +346,9 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
 {
 uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
 uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
+uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
 
-return (env->mip | vsgein) & env->mie;
+return (env->mip | vsgein | vstip) & env->mie;
 }
 
 int riscv_cpu_mirq_pending(CPURISCVState *env)
@@ -606,7 +607,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, 
uint64_t value)
 {
 CPURISCVState *env = >env;
 CPUState *cs = CPU(cpu);
-uint64_t gein, vsgein = 0, old = env->mip;
+uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
 bool locked = false;
 
 if (riscv_cpu_virt_enabled(env)) {
@@ -614,6 +615,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
mask, uint64_t value)
 vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
 }
 
+/* No need to update mip for VSTIP */
+mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
+vstip = env->vstime_irq ? MIP_VSTIP : 0;
+
 if (!qemu_mutex_iothread_locked()) {
 locked = true;
 qemu_mutex_lock_iothread();
@@ -621,7 +626,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, 
uint64_t value)
 
 env->mip = (env->mip & ~mask) | (value & mask);
 
-if (env->mip | vsgein) {
+if (env->mip | vsgein | vstip) {
 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 } else {
 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 04b06a2389..1a35ac48cc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -820,6 +820,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 {
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
+bool hmode_check = false;
 
 if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -838,7 +839,18 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-return smode(env, csrno);
+if (riscv_cpu_virt_enabled(env)) {
+if (!(get_field(env->hcounteren, COUNTEREN_TM) &
+  get_field(env->henvcfg, HENVCFG_STCE))) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
+hmode_check = true;
+}
+
+return hmode_check ? hmode(env, csrno) : smode(env, csrno);
 }
 
 static RISCVException sstc_32(CPURISCVState *env, int csrno)
@@ -850,17 +862,72 @@ static RISCVException sstc_32(CPURISCVState *env, int 
csrno)
 return sstc(env, csrno);
 }
 
+static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->vstimecmp;
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->vstimecmp 

[PULL 29/44] hw/riscv: microchip_pfsoc: fix kernel panics due to missing peripherals

2022-09-07 Thread Alistair Francis via
From: Conor Dooley 

Booting using "Direct Kernel Boot" for PolarFire SoC & skipping u-boot
entirely is probably not advisable, but it does at least show signs of
life. Recent Linux kernel versions make use of peripherals that are
missing definitions in QEMU and lead to kernel panics. These issues
almost certain rear their head for other methods of booting, but I was
unable to figure out a suitable HSS version that is recent enough to
support these peripherals & works with QEMU.

With these peripherals added, booting a kernel with the following hangs
hangs waiting for the system controller's hwrng, but the kernel no
longer panics. With the Linux driver for hwrng disabled, it boots to
console.

qemu-system-riscv64 -M microchip-icicle-kit \
-m 2G -smp 5 \
-kernel $(vmlinux_bin) \
-dtb  $(dtb)\
-initrd $(initramfs) \
-display none -serial null \
-serial stdio

More peripherals are added than strictly required to fix the panics in
the hopes of avoiding a replication of this problem in the future.
Some of the peripherals which are in the device tree for recent kernels
are implemented in the FPGA fabric. The eMMC/SD mux, which exists as
an unimplemented device is replaced by a wider entry. This updated
entry covers both the mux & the remainder of the FPGA fabric connected
to the MSS using Fabric Interrconnect (FIC) 3.

Link: 
https://github.com/polarfire-soc/icicle-kit-reference-design#fabric-memory-map
Link: 
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/SupportingCollateral/V1_4_Register_Map.zip
Signed-off-by: Conor Dooley 
Reviewed-by: Alistair Francis 
Message-Id: <20220813135127.2971754-1-m...@conchuod.ie>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h | 14 ++-
 hw/riscv/microchip_pfsoc.c | 67 +++---
 2 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index a0673f5f59..a757b240e0 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -88,8 +88,11 @@ enum {
 MICROCHIP_PFSOC_L2LIM,
 MICROCHIP_PFSOC_PLIC,
 MICROCHIP_PFSOC_MMUART0,
+MICROCHIP_PFSOC_WDOG0,
 MICROCHIP_PFSOC_SYSREG,
+MICROCHIP_PFSOC_AXISW,
 MICROCHIP_PFSOC_MPUCFG,
+MICROCHIP_PFSOC_FMETER,
 MICROCHIP_PFSOC_DDR_SGMII_PHY,
 MICROCHIP_PFSOC_EMMC_SD,
 MICROCHIP_PFSOC_DDR_CFG,
@@ -97,19 +100,28 @@ enum {
 MICROCHIP_PFSOC_MMUART2,
 MICROCHIP_PFSOC_MMUART3,
 MICROCHIP_PFSOC_MMUART4,
+MICROCHIP_PFSOC_WDOG1,
+MICROCHIP_PFSOC_WDOG2,
+MICROCHIP_PFSOC_WDOG3,
+MICROCHIP_PFSOC_WDOG4,
 MICROCHIP_PFSOC_SPI0,
 MICROCHIP_PFSOC_SPI1,
+MICROCHIP_PFSOC_I2C0,
 MICROCHIP_PFSOC_I2C1,
+MICROCHIP_PFSOC_CAN0,
+MICROCHIP_PFSOC_CAN1,
 MICROCHIP_PFSOC_GEM0,
 MICROCHIP_PFSOC_GEM1,
 MICROCHIP_PFSOC_GPIO0,
 MICROCHIP_PFSOC_GPIO1,
 MICROCHIP_PFSOC_GPIO2,
+MICROCHIP_PFSOC_RTC,
 MICROCHIP_PFSOC_ENVM_CFG,
 MICROCHIP_PFSOC_ENVM_DATA,
+MICROCHIP_PFSOC_USB,
 MICROCHIP_PFSOC_QSPI_XIP,
 MICROCHIP_PFSOC_IOSCB,
-MICROCHIP_PFSOC_EMMC_SD_MUX,
+MICROCHIP_PFSOC_FABRIC_FIC3,
 MICROCHIP_PFSOC_DRAM_LO,
 MICROCHIP_PFSOC_DRAM_LO_ALIAS,
 MICROCHIP_PFSOC_DRAM_HI,
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 7313153606..a821263d4f 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -100,8 +100,11 @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
 [MICROCHIP_PFSOC_L2LIM] =   {  0x800,  0x200 },
 [MICROCHIP_PFSOC_PLIC] ={  0xc00,  0x400 },
 [MICROCHIP_PFSOC_MMUART0] = { 0x2000, 0x1000 },
+[MICROCHIP_PFSOC_WDOG0] =   { 0x20001000, 0x1000 },
 [MICROCHIP_PFSOC_SYSREG] =  { 0x20002000, 0x2000 },
+[MICROCHIP_PFSOC_AXISW] =   { 0x20004000, 0x1000 },
 [MICROCHIP_PFSOC_MPUCFG] =  { 0x20005000, 0x1000 },
+[MICROCHIP_PFSOC_FMETER] =  { 0x20006000, 0x1000 },
 [MICROCHIP_PFSOC_DDR_SGMII_PHY] =   { 0x20007000, 0x1000 },
 [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
 [MICROCHIP_PFSOC_DDR_CFG] = { 0x2008,0x4 },
@@ -109,19 +112,28 @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
 [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
 [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
 [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
+[MICROCHIP_PFSOC_WDOG1] =   { 0x20101000, 0x1000 },
+[MICROCHIP_PFSOC_WDOG2] =   { 0x20103000, 0x1000 },
+[MICROCHIP_PFSOC_WDOG3] =   { 0x20105000, 0x1000 },
+[MICROCHIP_PFSOC_WDOG4] =   { 0x20106000, 0x1000 },
 [MICROCHIP_PFSOC_SPI0] ={ 0x20108000, 0x1000 },
 

[PULL 38/44] target/riscv: Add stimecmp support

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

stimecmp allows the supervisor mode to update stimecmp CSR directly
to program the next timer interrupt. This CSR is part of the Sstc
extension which was ratified recently.

Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Message-Id: <20220824221357.41070-3-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  5 ++
 target/riscv/cpu_bits.h|  4 ++
 target/riscv/time_helper.h | 30 
 target/riscv/cpu.c |  9 
 target/riscv/csr.c | 86 +
 target/riscv/machine.c |  1 +
 target/riscv/time_helper.c | 98 ++
 target/riscv/meson.build   |  3 +-
 8 files changed, 235 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/time_helper.h
 create mode 100644 target/riscv/time_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 53335def23..d2529b757a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -308,6 +308,9 @@ struct CPUArchState {
 uint64_t mfromhost;
 uint64_t mtohost;
 
+/* Sstc CSRs */
+uint64_t stimecmp;
+
 /* physical memory protection */
 pmp_table_t pmp_state;
 target_ulong mseccfg;
@@ -361,6 +364,7 @@ struct CPUArchState {
 float_status fp_status;
 
 /* Fields from here on are preserved across CPU reset. */
+QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
 
 hwaddr kernel_addr;
 hwaddr fdt_addr;
@@ -424,6 +428,7 @@ struct RISCVCPUConfig {
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zihintpause;
+bool ext_sstc;
 bool ext_svinval;
 bool ext_svnapot;
 bool ext_svpbmt;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 6be5a9e9f0..ac17cf1515 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -206,6 +206,10 @@
 #define CSR_STVAL   0x143
 #define CSR_SIP 0x144
 
+/* Sstc supervisor CSRs */
+#define CSR_STIMECMP0x14D
+#define CSR_STIMECMPH   0x15D
+
 /* Supervisor Protection and Translation */
 #define CSR_SPTBR   0x180
 #define CSR_SATP0x180
diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h
new file mode 100644
index 00..7b3cdcc350
--- /dev/null
+++ b/target/riscv/time_helper.h
@@ -0,0 +1,30 @@
+/*
+ * RISC-V timer header file.
+ *
+ * Copyright (c) 2022 Rivos Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RISCV_TIME_HELPER_H
+#define RISCV_TIME_HELPER_H
+
+#include "cpu.h"
+#include "qemu/timer.h"
+
+void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
+   uint64_t timecmp, uint64_t delta,
+   uint32_t timer_irq);
+void riscv_timer_init(RISCVCPU *cpu);
+
+#endif
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 26d44df446..8ab36e82e1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -23,6 +23,7 @@
 #include "qemu/log.h"
 #include "cpu.h"
 #include "internals.h"
+#include "time_helper.h"
 #include "exec/exec-all.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -101,6 +102,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
 ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
 ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
+ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
 ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
 ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
@@ -674,6 +676,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 
 set_resetvec(env, cpu->cfg.resetvec);
 
+#ifndef CONFIG_USER_ONLY
+if (cpu->cfg.ext_sstc) {
+riscv_timer_init(cpu);
+}
+#endif /* CONFIG_USER_ONLY */
+
 /* Validate that MISA_MXL is set properly. */
 switch (env->misa_mxl_max) {
 #ifdef TARGET_RISCV64
@@ -994,6 +1002,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, 

[PULL 34/44] hw/core: fix platform bus node name

2022-09-07 Thread Alistair Francis via
From: Conor Dooley 

"platform" is not a valid name for a bus node in dt-schema, so warnings
can be see in dt-validate on a dump of the riscv virt dtb:

/stuff/qemu/qemu.dtb: platform@400: $nodename:0: 'platform@400' does 
not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
From schema: 
/home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
"platform-bus" is a valid name, so use that instead.

CC: Rob Herring 
Fixes: 11d306b9df ("hw/arm/sysbus-fdt: helpers for platform bus nodes addition")
Reviewed-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-id: 20220810184612.157317-5-m...@conchuod.ie
Signed-off-by: Alistair Francis 
---
 hw/core/sysbus-fdt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
index 19d22cbe73..edb0c49b19 100644
--- a/hw/core/sysbus-fdt.c
+++ b/hw/core/sysbus-fdt.c
@@ -539,7 +539,7 @@ void platform_bus_add_all_fdt_nodes(void *fdt, const char 
*intc, hwaddr addr,
 
 assert(fdt);
 
-node = g_strdup_printf("/platform@%"PRIx64, addr);
+node = g_strdup_printf("/platform-bus@%"PRIx64, addr);
 
 /* Create a /platform node that we can put all devices into */
 qemu_fdt_add_subnode(fdt, node);
-- 
2.37.2




[PULL 28/44] hw/riscv: opentitan: bump opentitan version

2022-09-07 Thread Alistair Francis via
From: Wilfred Mallawa 

The following patch updates opentitan to match the new configuration,
as per, lowRISC/opentitan@217a0168ba118503c166a9587819e3811eeb0c0c

Note: with this patch we now skip the usage of the opentitan
`boot_rom`. The Opentitan boot rom contains hw verification
for devies which we are currently not supporting in qemu. As of now,
the `boot_rom` has no major significance, however, would be good to
support in the future.

Tested by running utests from the latest tock [1]
(that supports this version of OT).

[1] https://github.com/tock/tock/pull/3056

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20220812005229.358850-1-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 11 ++-
 hw/riscv/opentitan.c | 12 
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 68892cd8e5..26d960f288 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -74,6 +74,7 @@ enum {
 IBEX_DEV_TIMER,
 IBEX_DEV_SENSOR_CTRL,
 IBEX_DEV_OTP_CTRL,
+IBEX_DEV_LC_CTRL,
 IBEX_DEV_PWRMGR,
 IBEX_DEV_RSTMGR,
 IBEX_DEV_CLKMGR,
@@ -105,11 +106,11 @@ enum {
 IBEX_UART0_RX_BREAK_ERR_IRQ   = 6,
 IBEX_UART0_RX_TIMEOUT_IRQ = 7,
 IBEX_UART0_RX_PARITY_ERR_IRQ  = 8,
-IBEX_TIMER_TIMEREXPIRED0_0= 126,
-IBEX_SPI_HOST0_ERR_IRQ= 150,
-IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 151,
-IBEX_SPI_HOST1_ERR_IRQ= 152,
-IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 153,
+IBEX_TIMER_TIMEREXPIRED0_0= 127,
+IBEX_SPI_HOST0_ERR_IRQ= 151,
+IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 152,
+IBEX_SPI_HOST1_ERR_IRQ= 153,
+IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 154,
 };
 
 #endif
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 4495a2c039..af13dbe3b1 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -29,9 +29,9 @@
 #include "sysemu/sysemu.h"
 
 static const MemMapEntry ibex_memmap[] = {
-[IBEX_DEV_ROM] ={  0x8000, 16 * KiB },
-[IBEX_DEV_RAM] ={  0x1000,  0x1 },
-[IBEX_DEV_FLASH] =  {  0x2000,  0x8 },
+[IBEX_DEV_ROM] ={  0x8000,   0x8000 },
+[IBEX_DEV_RAM] ={  0x1000,  0x2 },
+[IBEX_DEV_FLASH] =  {  0x2000,  0x10 },
 [IBEX_DEV_UART] =   {  0x4000,  0x1000  },
 [IBEX_DEV_GPIO] =   {  0x4004,  0x1000  },
 [IBEX_DEV_SPI_DEVICE] = {  0x4005,  0x1000  },
@@ -40,6 +40,7 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_TIMER] =  {  0x4010,  0x1000  },
 [IBEX_DEV_SENSOR_CTRL] ={  0x4011,  0x1000  },
 [IBEX_DEV_OTP_CTRL] =   {  0x4013,  0x4000  },
+[IBEX_DEV_LC_CTRL] ={  0x4014,  0x1000  },
 [IBEX_DEV_USBDEV] = {  0x4015,  0x1000  },
 [IBEX_DEV_SPI_HOST0] =  {  0x4030,  0x1000  },
 [IBEX_DEV_SPI_HOST1] =  {  0x4031,  0x1000  },
@@ -141,7 +142,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 _abort);
 object_property_set_int(OBJECT(>cpus), "num-harts", ms->smp.cpus,
 _abort);
-object_property_set_int(OBJECT(>cpus), "resetvec", 0x8080, 
_abort);
+object_property_set_int(OBJECT(>cpus), "resetvec", 0x2490,
+_abort);
 sysbus_realize(SYS_BUS_DEVICE(>cpus), _fatal);
 
 /* Boot ROM */
@@ -253,6 +255,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
 create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
 memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size);
+create_unimplemented_device("riscv.lowrisc.ibex.lc_ctrl",
+memmap[IBEX_DEV_LC_CTRL].base, memmap[IBEX_DEV_LC_CTRL].size);
 create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
 memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size);
 create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
-- 
2.37.2




Re: sphinx-build is really slow, any way to improve that?

2022-09-07 Thread Markus Armbruster
Peter Maydell  writes:

> On Tue, 6 Sept 2022 at 08:55, Daniel P. Berrangé  wrote:
>>
>> On Mon, Sep 05, 2022 at 10:21:55PM +0100, Peter Maydell wrote:
>> > On Mon, 5 Sept 2022 at 20:51, Claudio Fontana  wrote:
>> > > when I build qemu, there is a lot of time spent at the end of the build 
>> > > where one cpu goes 100% on sphinx-build.
>> > >
>> > > Is there some way to parallelize that? It seems it is the current 
>> > > bottleneck for rebuilds for me..
>> >
>> > It's a big fat python program, so I suspect not, but
>> > maybe I'm wrong.
>>
>> It annoys me too and I've had a look at what it is doing in the past and
>> failed to find an obvious way to improve it. I fear this could be an
>> inherant limitation of the way we use sphinx to build the docs as a
>> complete manual, as compared to say treating each docs source file as
>> a distinct standalone web page.
>
> IIRC sphinx really really wants to process the whole document tree
> in one go. You can see this in the way that for example the
> HTML build process creates HTML files for the top-level rst
> files that are supposed to be only for the manpage -- it will
> suck in and process everything, not just the files reachable
> via whatever top level file you point it at.

How do other projects deal with the resulting slowness?

Could we avoid rerunning sphinx-build when documentation hasn't changed?




[PULL 35/44] target/riscv: Add xicondops in ISA entry

2022-09-07 Thread Alistair Francis via
From: Rahul Pathak 

XVentanaCondOps is Ventana custom extension. Add
its extension entry in the ISA Ext array

Signed-off-by: Rahul Pathak 
Reviewed-by: Alistair Francis 
Message-id: 20220816045408.1231135-1-rpat...@ventanamicro.com
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d4635c7df4..e0d5941230 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -102,6 +102,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
 ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
+ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 };
 
 static bool isa_ext_is_enabled(RISCVCPU *cpu,
-- 
2.37.2




[PULL 36/44] target/riscv: Use official extension names for AIA CSRs

2022-09-07 Thread Alistair Francis via
From: Anup Patel 

The arch review of AIA spec is completed and we now have official
extension names for AIA: Smaia (M-mode AIA CSRs) and Ssaia (S-mode
AIA CSRs).

Refer, section 1.6 of the latest AIA v0.3.1 stable specification at
https://github.com/riscv/riscv-aia/releases/download/0.3.1-draft.32/riscv-interrupts-032.pdf)

Based on above, we update QEMU RISC-V to:
1) Have separate config options for Smaia and Ssaia extensions
   which replace RISCV_FEATURE_AIA in CPU features
2) Not generate AIA INTC compatible string in virt machine

Signed-off-by: Anup Patel 
Reviewed-by: Andrew Jones 
Reviewed-by: Alistair Francis 
Message-id: 20220820042958.377018-1-apa...@ventanamicro.com
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  4 ++--
 hw/intc/riscv_imsic.c |  4 +++-
 hw/riscv/virt.c   | 13 ++---
 target/riscv/cpu.c|  9 -
 target/riscv/cpu_helper.c |  3 ++-
 target/riscv/csr.c| 24 ++--
 6 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4be4b82a83..081cd05544 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -85,7 +85,6 @@ enum {
 RISCV_FEATURE_PMP,
 RISCV_FEATURE_EPMP,
 RISCV_FEATURE_MISA,
-RISCV_FEATURE_AIA,
 RISCV_FEATURE_DEBUG
 };
 
@@ -439,6 +438,8 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool ext_zmmul;
+bool ext_smaia;
+bool ext_ssaia;
 bool rvv_ta_all_1s;
 bool rvv_ma_all_1s;
 
@@ -459,7 +460,6 @@ struct RISCVCPUConfig {
 bool mmu;
 bool pmp;
 bool epmp;
-bool aia;
 bool debug;
 uint64_t resetvec;
 
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
index 8615e4cc1d..4d4d5b50ca 100644
--- a/hw/intc/riscv_imsic.c
+++ b/hw/intc/riscv_imsic.c
@@ -344,9 +344,11 @@ static void riscv_imsic_realize(DeviceState *dev, Error 
**errp)
 
 /* Force select AIA feature and setup CSR read-modify-write callback */
 if (env) {
-riscv_set_feature(env, RISCV_FEATURE_AIA);
 if (!imsic->mmode) {
+rcpu->cfg.ext_ssaia = true;
 riscv_cpu_set_geilen(env, imsic->num_pages - 1);
+} else {
+rcpu->cfg.ext_smaia = true;
 }
 riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S,
   riscv_imsic_rmw, imsic);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 686341a0e2..ff8c0df5cd 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -260,17 +260,8 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int 
socket,
 qemu_fdt_add_subnode(mc->fdt, intc_name);
 qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
 intc_phandles[cpu]);
-if (riscv_feature(>soc[socket].harts[cpu].env,
-  RISCV_FEATURE_AIA)) {
-static const char * const compat[2] = {
-"riscv,cpu-intc-aia", "riscv,cpu-intc"
-};
-qemu_fdt_setprop_string_array(mc->fdt, intc_name, "compatible",
-  (char **), ARRAY_SIZE(compat));
-} else {
-qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
-"riscv,cpu-intc");
-}
+qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
+"riscv,cpu-intc");
 qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0);
 qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e0d5941230..26d44df446 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -99,6 +99,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
 ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
 ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin),
+ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia),
+ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia),
 ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
 ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
@@ -666,10 +668,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
-if (cpu->cfg.aia) {
-riscv_set_feature(env, RISCV_FEATURE_AIA);
-}
-
 if (cpu->cfg.debug) {
 riscv_set_feature(env, RISCV_FEATURE_DEBUG);
 }
@@ -1038,7 +1036,8 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
+DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
+DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
 

[PULL 33/44] hw/riscv: virt: fix syscon subnode paths

2022-09-07 Thread Alistair Francis via
From: Conor Dooley 

The reset and poweroff features of the syscon were originally added to
top level, which is a valid path for a syscon subnode. Subsequently a
reorganisation was carried out while implementing NUMA in which the
subnodes were moved into the /soc node. As /soc is a "simple-bus", this
path is invalid, and so dt-validate produces the following warnings:

/stuff/qemu/qemu.dtb: soc: poweroff: {'value': [[21845]], 'offset': [[0]], 
'regmap': [[4]], 'compatible': ['syscon-poweroff']} should not be valid under 
{'type': 'object'}
From schema: 
/home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml
/stuff/qemu/qemu.dtb: soc: reboot: {'value': [[30583]], 'offset': [[0]], 
'regmap': [[4]], 'compatible': ['syscon-reboot']} should not be valid under 
{'type': 'object'}
From schema: 
/home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml

Move the syscon subnodes back to the top level and silence the warnings.

Reported-by: Rob Herring 
Signed-off-by: Conor Dooley 
Reviewed-by: Alistair Francis 
Message-id: 20220810184612.157317-4-m...@conchuod.ie
Link: 
https://lore.kernel.org/linux-riscv/20220803170552.ga2250266-r...@kernel.org/
Fixes: 18df0b4695 ("hw/riscv: virt: Allow creating multiple NUMA sockets")
Signed-off-by: Conor Dooley 
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index f19758e1df..686341a0e2 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -897,7 +897,7 @@ static void create_fdt_reset(RISCVVirtState *s, const 
MemMapEntry *memmap,
 test_phandle = qemu_fdt_get_phandle(mc->fdt, name);
 g_free(name);
 
-name = g_strdup_printf("/soc/reboot");
+name = g_strdup_printf("/reboot");
 qemu_fdt_add_subnode(mc->fdt, name);
 qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot");
 qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
@@ -905,7 +905,7 @@ static void create_fdt_reset(RISCVVirtState *s, const 
MemMapEntry *memmap,
 qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET);
 g_free(name);
 
-name = g_strdup_printf("/soc/poweroff");
+name = g_strdup_printf("/poweroff");
 qemu_fdt_add_subnode(mc->fdt, name);
 qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff");
 qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
-- 
2.37.2




[PULL 21/44] target/riscv: rvv: Add mask agnostic for vector floating-point instructions

2022-09-07 Thread Alistair Francis via
From: "Yueh-Ting (eop) Chen" 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
Message-Id: <165570784143.17634.3509581658457369...@git.sr.ht>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c| 26 +
 target/riscv/insn_trans/trans_rvv.c.inc | 12 
 2 files changed, 38 insertions(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 597fa9c752..315742c6b8 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3051,10 +3051,14 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,
  \
 uint32_t total_elems =\
 vext_get_total_elems(env, desc, ESZ); \
 uint32_t vta = vext_vta(desc);\
+uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+vext_set_elems_1s(vd, vma, i * ESZ,   \
+  (i + 1) * ESZ); \
 continue; \
 } \
 do_##NAME(vd, vs1, vs2, i, env);  \
@@ -3090,10 +3094,14 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1,  
  \
 uint32_t total_elems =\
 vext_get_total_elems(env, desc, ESZ);  \
 uint32_t vta = vext_vta(desc);\
+uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+vext_set_elems_1s(vd, vma, i * ESZ,   \
+  (i + 1) * ESZ); \
 continue; \
 } \
 do_##NAME(vd, s1, vs2, i, env);   \
@@ -3665,6 +3673,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
 uint32_t total_elems = \
 vext_get_total_elems(env, desc, ESZ);  \
 uint32_t vta = vext_vta(desc); \
+uint32_t vma = vext_vma(desc); \
 uint32_t i;\
\
 if (vl == 0) { \
@@ -3672,6 +3681,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
 }  \
 for (i = env->vstart; i < vl; i++) {   \
 if (!vm && !vext_elem_mask(v0, i)) {   \
+/* set masked-off elements to 1s */\
+vext_set_elems_1s(vd, vma, i * ESZ,\
+  (i + 1) * ESZ);  \
 continue;  \
 }  \
 do_##NAME(vd, vs2, i, env);\
@@ -4182,12 +4194,17 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 uint32_t vl = env->vl;\
 uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
 uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
+uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
 ETYPE s1 = *((ETYPE *)vs1 + H(i));\
 ETYPE s2 = *((ETYPE *)vs2 + H(i));\
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+if (vma) {\
+vext_set_elem_mask(vd, i, 1); \
+} \
 continue; \
 } \
 vext_set_elem_mask(vd, i, \
@@ -4215,11 +4232,16 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 uint32_t vl = env->vl;  \
 uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
 uint32_t 

[PULL 30/44] target/riscv: Remove additional priv version check for mcountinhibit

2022-09-07 Thread Alistair Francis via
From: Atish Patra 

With .min_priv_version, additiona priv version check is uncessary
for mcountinhibit read/write functions.

Reviewed-by: Heiko Stuebner 
Tested-by: Heiko Stuebner 
Reviewed-by: Alistair Francis 
Signed-off-by: Atish Patra 
Message-Id: <20220816232321.558250-7-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d81f466c80..4a7078f7d1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1494,10 +1494,6 @@ static RISCVException write_mtvec(CPURISCVState *env, 
int csrno,
 static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
-if (env->priv_ver < PRIV_VERSION_1_11_0) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
 *val = env->mcountinhibit;
 return RISCV_EXCP_NONE;
 }
@@ -1508,10 +1504,6 @@ static RISCVException write_mcountinhibit(CPURISCVState 
*env, int csrno,
 int cidx;
 PMUCTRState *counter;
 
-if (env->priv_ver < PRIV_VERSION_1_11_0) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
 env->mcountinhibit = val;
 
 /* Check if any other counter is also monitoring cycles/instructions */
-- 
2.37.2




[PULL 27/44] target/riscv: Fix priority of csr related check in riscv_csrrw_check

2022-09-07 Thread Alistair Francis via
From: Weiwei Li 

Normally, riscv_csrrw_check is called when executing Zicsr instructions.
And we can only do access control for existed CSRs. So the priority of
CSR related check, from highest to lowest, should be as follows:
1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not
2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not
3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_
INSTRUCTION_FAULT if not allowed

The predicates contain parts of function of both 2) and 3), So they need
to be placed in the middle of riscv_csrrw_check

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20220803123652.3700-1-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 44 +---
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0fb042b2fd..d81f466c80 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3270,6 +3270,30 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
 int read_only = get_field(csrno, 0xC00) == 3;
 int csr_min_priv = csr_ops[csrno].min_priv_ver;
+
+/* ensure the CSR extension is enabled. */
+if (!cpu->cfg.ext_icsr) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (env->priv_ver < csr_min_priv) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+/* check predicate */
+if (!csr_ops[csrno].predicate) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (write_mask && read_only) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+RISCVException ret = csr_ops[csrno].predicate(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 int csr_priv, effective_priv = env->priv;
 
@@ -3290,25 +3314,7 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 #endif
-if (write_mask && read_only) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-/* ensure the CSR extension is enabled. */
-if (!cpu->cfg.ext_icsr) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-/* check predicate */
-if (!csr_ops[csrno].predicate) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (env->priv_ver < csr_min_priv) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-return csr_ops[csrno].predicate(env, csrno);
+return RISCV_EXCP_NONE;
 }
 
 static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
-- 
2.37.2




  1   2   >