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

2022-08-17 Thread Michael Roth
On Tue, Aug 16, 2022 at 03:38:08PM +, Sean Christopherson wrote:
> On Tue, Aug 16, 2022, Gupta, Pankaj wrote:
> > 
> > > > > Actually the current version allows you to delay the allocation to a
> > > > > later time (e.g. page fault time) if you don't call fallocate() on the
> > > > > private fd. fallocate() is necessary in previous versions because we
> > > > > treat the existense in the fd as 'private' but in this version we 
> > > > > track
> > > > > private/shared info in KVM so we don't rely on that fact from memory
> > > > > backstores.
> > > > 
> > > > Does this also mean reservation of guest physical memory with secure
> > > > processor (both for SEV-SNP & TDX) will also happen at page fault time?
> > > > 
> > > > Do we plan to keep it this way?
> > > 
> > > If you are talking about accepting memory by the guest, it is initiated by
> > > the guest and has nothing to do with page fault time vs fallocate()
> > > allocation of host memory. I mean acceptance happens after host memory
> > > allocation but they are not in lockstep, acceptance can happen much later.
> > 
> > No, I meant reserving guest physical memory range from hypervisor e.g with
> > RMPUpdate for SEV-SNP or equivalent at TDX side (PAMTs?).
> 
> As proposed, RMP/PAMT updates will occur in the fault path, i.e. there is no 
> way
> for userspace to pre-map guest memory.

Hi Sean,

Currently I have the rmpupdate hook in KVM_MEMORY_ENCRYPT_{REG,UNREG}_REGION
ioctls, so that when the pages actually get faulted in they are already
in the expected state. I have userspace set up to call
KVM_MEMORY_ENCRYPT_* in response to explicit page state changes issued by
the guest, as well as in response to MEMORY_FAULT exits for implicit page
state changes.

Initially the private backing store may or may not be pre-fallocate()'d
depending on how userspace wants to handle it. If it's not
pre-fallocate()'d, then the pages don't get faulted in until the guest
does explicit page state changes (currently SNP guests will do this for all
memory at boot time, but with unaccepted memory patches for guest/ovmf
this will happen during guest run-time, would still allow us to make
efficient use of lazy-pinning support for shorter boot times).

If userspaces wants to pre-allocate, it can issue the fallocate() for
all the ranges up-front so it doesn't incur the cost during run-time.

Is that compatible with the proposed design?

Of course, for the initial encrypted payload, we would need to to issue
the KVM_MEMORY_ENCRYPT_{REG,UNREG}_REGION up-front. I'm doing that in
conjunction with the hack to allow pwrite() to memfd to pre-populate the
private pages before the in-place encryption that occurs when
SNP_LAUNCH_UPDATE is issued...

In the past you and Vishal suggested doing the copy from within
SNP_LAUNCH_UPDATE, which seems like a workable solution and something
we've been meaning to implement...

> 
> I think the best approach is to turn KVM_TDX_INIT_MEM_REGION into a generic
> vCPU-scoped ioctl() that allows userspace to pre-map guest memory.  Supporting
> initializing guest private memory with a source page can be implemented via a
> flag.  That also gives KVM line of sight to in-place "conversion", e.g. 
> another
> flag could be added to say that the dest is also the source.

So is this proposed ioctl only intended to handle the initial encrypted
payload, and the KVM_MEMORY_ENCRYPT_{REG,UNREG}_REGION ioctls would
still be used for conversions post-boot?

If so, that seems reasonable, but I thought there was some consensus that
just handling it per-platform in, e.g., SNP_LAUNCH_UPDATE, was
sufficient for now until some additional need arose for a new interface.
Has something changed in the regard? Just want to understand the
motivations so we can plan accordingly.

Thanks!

-Mike

> 
> The TDX and SNP restrictions would then become addition restrictions on when
> initializing with a source is allowed (and VMs that don't have guest private
> memory wouldn't allow the flag at all).



[ANNOUNCE] QEMU 7.1.0-rc3 is now available

2022-08-17 Thread Michael Roth
Hello,

On behalf of the QEMU Team, I'd like to announce the availability of the
fourth release candidate for the QEMU 7.1 release. This release is meant
for testing purposes and should not be used in a production environment.

  http://download.qemu-project.org/qemu-7.1.0-rc3.tar.xz
  http://download.qemu-project.org/qemu-7.1.0-rc3.tar.xz.sig

You can help improve the quality of the QEMU 7.1 release by testing this
release and reporting bugs using our GitLab issue tracker:

  https://gitlab.com/qemu-project/qemu/-/issues

The release plan, as well a documented known issues for release
candidates, are available at:

  http://wiki.qemu.org/Planning/7.1

Please add entries to the ChangeLog for the 7.1 release below:

  http://wiki.qemu.org/ChangeLog/7.1

Thank you to everyone involved!

Changes since rc2:

c7208a6e0d: Update version for v7.1.0-rc3 release (Richard Henderson)
effaf5a240: hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() 
(CVE-2020-14394) (Thomas Huth)
9c23d71934: tests/qtest: misc tweaks to readconfig (Daniel P. Berrangé)
65711f9a87: tests/avocado: apply a band aid to aspeed-evb login (Alex Bennée)
b1ceae2f5b: tests/avocado: add timeout to the aspeed tests (Alex Bennée)
52f0c16076: linux-user: un-parent OBJECT(cpu) when closing thread (Alex Bennée)
1f90ce64fc: docs/system/loongarch: Update the LoongArch document (Xiaojuan Yang)
4311682ea8: cutils: Add missing dyld(3) include on macOS (Philippe 
Mathieu-Daudé)
e1f045780b: hw/arm/virt-acpi-build: Present the GICR structure properly for 
GICv4 (Zenghui Yu)
6a54ac2a97: tests/unit: fix a -Wformat-truncation warning (Marc-André Lureau)
120f765e03: Fix some typos in documentation (most of them found by codespell) 
(Stefan Weil)
2daf518dd1: target/arm: Don't report Statistical Profiling Extension in ID 
registers (Peter Maydell)
dbbf89751b: linux-user/aarch64: Reset target data on MADV_DONTNEED (Vitaly Buka)
3cd3df2a95: linux-user: fix compat with glibc >= 2.36 sys/mount.h (Daniel P. 
Berrangé)



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

2022-08-17 Thread Hugh Dickins
On Wed, 6 Jul 2022, Chao Peng wrote:
> This is the v7 of this series which tries to implement the fd-based KVM
> guest private memory.

Here at last are my reluctant thoughts on this patchset.

fd-based approach for supporting KVM guest private memory: fine.

Use or abuse of memfd and shmem.c: mistaken.

memfd_create() was an excellent way to put together the initial prototype.

But since then, TDX in particular has forced an effort into preventing
(by flags, seals, notifiers) almost everything that makes it shmem/tmpfs.

Are any of the shmem.c mods useful to existing users of shmem.c? No.
Is MFD_INACCESSIBLE useful or comprehensible to memfd_create() users? No.

What use do you have for a filesystem here?  Almost none.
IIUC, what you want is an fd through which QEMU can allocate kernel
memory, selectively free that memory, and communicate fd+offset+length
to KVM.  And perhaps an interface to initialize a little of that memory
from a template (presumably copied from a real file on disk somewhere).

You don't need shmem.c or a filesystem for that!

If your memory could be swapped, that would be enough of a good reason
to make use of shmem.c: but it cannot be swapped; and although there
are some references in the mailthreads to it perhaps being swappable
in future, I get the impression that will not happen soon if ever.

If your memory could be migrated, that would be some reason to use
filesystem page cache (because page migration happens to understand
that type of memory): but it cannot be migrated.

Some of these impressions may come from earlier iterations of the
patchset (v7 looks better in several ways than v5).  I am probably
underestimating the extent to which you have taken on board other
usages beyond TDX and SEV private memory, and rightly want to serve
them all with similar interfaces: perhaps there is enough justification
for shmem there, but I don't see it.  There was mention of userfaultfd
in one link: does that provide the justification for using shmem?

I'm afraid of the special demands you may make of memory allocation
later on - surprised that huge pages are not mentioned already;
gigantic contiguous extents? secretmem removed from direct map?

Here's what I would prefer, and imagine much easier for you to maintain;
but I'm no system designer, and may be misunderstanding throughout.

QEMU gets fd from opening /dev/kvm_something, uses ioctls (or perhaps
the fallocate syscall interface itself) to allocate and free the memory,
ioctl for initializing some of it too.  KVM in control of whether that
fd can be read or written or mmap'ed or whatever, no need to prevent it
in shmem.c, no need for flags, seals, notifications to and fro because
KVM is already in control and knows the history.  If shmem actually has
value, call into it underneath - somewhat like SysV SHM, and /dev/zero
mmap, and i915/gem make use of it underneath.  If shmem has nothing to
add, just allocate and free kernel memory directly, recorded in your
own xarray.

With that /dev/kvm_something subject to access controls and LSMs -
which I cannot find for memfd_create().  Full marks for including the
MFD_INACCESSIBLE manpage update, and for Cc'ing linux-api: but I'd
have expected some doubts from that direction already.

Hugh



Re: [PATCH for-7.1 3/4] target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"

2022-08-17 Thread maobibo



在 2022/8/18 10:31, WANG Xuerui 写道:
> On 2022/8/17 21:26, Richard Henderson wrote:
>> On 8/17/22 04:10, WANG Xuerui wrote:
>>>  From my own experiences, different use cases care about different aspects 
>>> of the CPU, and that IMO is an argument in favor of providing both 
>>> (high-fidelity models named after actual product model names, and virtual 
>>> models named after ISA levels). But before we have truly high-fidelity 
>>> models I think we should start with the virtual ones first. And don't 
>>> pretend the currently implemented model is LA464 -- the kernel change I've 
>>> linked to [1] implies the opposite.
>>
>> No, it simply pointed to a bug in qemu that could have been fixed.
>>
>> The trouble with inventing virtual models is that no one knows what they 
>> mean.  Targeting real hardware is better, because we have a documented 
>> standard.
>>
> Hmm, I've looked up more context and it is indeed reasonable to generally 
> name the QEMU models after real existing models. But in this case we could 
> face a problem with Loongson's nomenclature: all of Loongson 3A5000, 3C5000 
> and 3C5000L are LA464, yet they should be distinguishable software-side by 
> checking the model name CSR. But with only one CPU model that is LA464, 
> currently this CSR is hard-coded to read "3A5000", and this can hurt IMO. And 
> when we finally add LA264 and LA364 they would be identical ISA-level-wise, 
> again the only differentiator is the model name CSR.
We will add LA264 later, there are some small different features with LA464, 
such as virtual/physical address width, unaligned address access, vector fpu 
width etc.
 

> And by "not high-fidelity", I mean some of the features present on real HW 
> might never get implemented, or actually implementable, like the DVFS 
> mechanism needed by cpufreq. And I believe Bibo wouldn't have to change the 
> kernel if it's not needed after all to run the unmodified upstream kernel on 
> top of qemu-system-loongarch64. (I would of course accept, and learn 
> something along the way, if this turns out not to be the case though.)
qemu does not emulation actual voltage/freq function,  cpu freq 2000MHZ in qemu 
is not real freq, it is only function emulation rather than timing emulation.

regards
bibo,mao 

> Lastly, the "ISA level" I proposed is not arbitrarily made up; it's direct 
> reference to the ISA manual revision. Each time the ISA gets some 
> addition/revision the ISA manual has to be updated, and currently the 
> manual's revision is the only reliable source of said information. (Loongson 
> has a history of naming cores badly, like with the MIPS 3B1500 and 3A4000, 
> both were "GS464V"; and 3A5000 was originally GS464V too, even though the 
> insn encodings and some semantics have been entirely different.)
> 
> In conclusion, I'd accept the micro-architecture naming if the model CSR 
> behavior could be sorted out, otherwise I'd personally prefer real model 
> names if ISA level naming is not going to fly. This is not a strong objection 
> to the current way of doing things though, more like some minor but anyway 
> needed discussion that happened a bit late. Sorry for not chiming in earlier 
> during the review process.




Re: [PATCH 7/7] target/riscv: Honour -semihosting-config userspace=on and enable=on

2022-08-17 Thread Alistair Francis
On Tue, Aug 16, 2022 at 5:11 AM Peter Maydell  wrote:
>
> The riscv target incorrectly enabled semihosting always, whether the
> user asked for it or not.  Call semihosting_enabled() passing the
> correct value to the is_userspace argument, which fixes this and also
> handles the userspace=on argument.
>
> Note that this is a behaviour change: we used to default to
> semihosting being enabled, and now the user must pass
> "-semihosting-config enable=on" if they want it.
>
> Signed-off-by: Peter Maydell 

I agree with Richard that a check in translate would be better, but
this is also an improvement on the broken implementation we have now

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 59b3680b1b2..49c4ea98ac9 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -24,6 +24,7 @@
>  #include "exec/exec-all.h"
>  #include "tcg/tcg-op.h"
>  #include "trace.h"
> +#include "semihosting/semihost.h"
>  #include "semihosting/common-semi.h"
>
>  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> @@ -1342,7 +1343,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
>  target_ulong mtval2 = 0;
>
>  if  (cause == RISCV_EXCP_SEMIHOST) {
> -if (env->priv >= PRV_S) {
> +if (semihosting_enabled(env->priv < PRV_S)) {
>  do_common_semihosting(cs);
>  env->pc += 4;
>  return;
> --
> 2.25.1
>
>



Re: [PATCH 1/7] semihosting: Allow optional use of semihosting from userspace

2022-08-17 Thread Alistair Francis
On Tue, Aug 16, 2022 at 5:03 AM Peter Maydell  wrote:
>
> Currently our semihosting implementations generally prohibit use of
> semihosting calls in system emulation from the guest userspace.  This
> is a very long standing behaviour justified originally "to provide
> some semblance of security" (since code with access to the
> semihosting ABI can do things like read and write arbitrary files on
> the host system).  However, it is sometimes useful to be able to run
> trusted guest code which performs semihosting calls from guest
> userspace, notably for test code.  Add a command line suboption to
> the existing semihosting-config option group so that you can
> explicitly opt in to semihosting from guest userspace with
>  -semihosting-config userspace=on
>
> (There is no equivalent option for the user-mode emulator, because
> there by definition all code runs in userspace and has access to
> semihosting already.)
>
> This commit adds the infrastructure for the command line option and
> adds a bool 'is_user' parameter to the function
> semihosting_userspace_enabled() that target code can use to check
> whether it should be permitting the semihosting call for userspace.
> It mechanically makes all the callsites pass 'false', so they
> continue checking "is semihosting enabled in general".  Subsequent
> commits will make each target that implements semihosting honour the
> userspace=on option by passing the correct value and removing
> whatever "don't do this for userspace" checking they were doing by
> hand.
>
> Signed-off-by: Peter Maydell 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/semihosting/semihost.h | 10 --
>  semihosting/config.c   | 10 --
>  softmmu/vl.c   |  2 +-
>  stubs/semihost.c   |  2 +-
>  target/arm/translate-a64.c |  2 +-
>  target/arm/translate.c |  6 +++---
>  target/m68k/op_helper.c|  2 +-
>  target/nios2/translate.c   |  2 +-
>  target/xtensa/translate.c  |  6 +++---
>  qemu-options.hx| 11 +--
>  10 files changed, 36 insertions(+), 17 deletions(-)
>
> diff --git a/include/semihosting/semihost.h b/include/semihosting/semihost.h
> index 93a3c21b44d..efd2efa25ae 100644
> --- a/include/semihosting/semihost.h
> +++ b/include/semihosting/semihost.h
> @@ -27,7 +27,7 @@ typedef enum SemihostingTarget {
>  } SemihostingTarget;
>
>  #ifdef CONFIG_USER_ONLY
> -static inline bool semihosting_enabled(void)
> +static inline bool semihosting_enabled(bool is_user)
>  {
>  return true;
>  }
> @@ -52,7 +52,13 @@ static inline const char *semihosting_get_cmdline(void)
>  return NULL;
>  }
>  #else /* !CONFIG_USER_ONLY */
> -bool semihosting_enabled(void);
> +/**
> + * semihosting_enabled:
> + * @is_user: true if guest code is in usermode (i.e. not privileged)
> + *
> + * Return true if guest code is allowed to make semihosting calls.
> + */
> +bool semihosting_enabled(bool is_user);
>  SemihostingTarget semihosting_get_target(void);
>  const char *semihosting_get_arg(int i);
>  int semihosting_get_argc(void);
> diff --git a/semihosting/config.c b/semihosting/config.c
> index e171d4d6bc3..89a17596879 100644
> --- a/semihosting/config.c
> +++ b/semihosting/config.c
> @@ -34,6 +34,9 @@ QemuOptsList qemu_semihosting_config_opts = {
>  {
>  .name = "enable",
>  .type = QEMU_OPT_BOOL,
> +}, {
> +.name = "userspace",
> +.type = QEMU_OPT_BOOL,
>  }, {
>  .name = "target",
>  .type = QEMU_OPT_STRING,
> @@ -50,6 +53,7 @@ QemuOptsList qemu_semihosting_config_opts = {
>
>  typedef struct SemihostingConfig {
>  bool enabled;
> +bool userspace_enabled;
>  SemihostingTarget target;
>  char **argv;
>  int argc;
> @@ -59,9 +63,9 @@ typedef struct SemihostingConfig {
>  static SemihostingConfig semihosting;
>  static const char *semihost_chardev;
>
> -bool semihosting_enabled(void)
> +bool semihosting_enabled(bool is_user)
>  {
> -return semihosting.enabled;
> +return semihosting.enabled && (!is_user || 
> semihosting.userspace_enabled);
>  }
>
>  SemihostingTarget semihosting_get_target(void)
> @@ -137,6 +141,8 @@ int qemu_semihosting_config_options(const char *optarg)
>  if (opts != NULL) {
>  semihosting.enabled = qemu_opt_get_bool(opts, "enable",
>  true);
> +semihosting.userspace_enabled = qemu_opt_get_bool(opts, "userspace",
> +  false);
>  const char *target = qemu_opt_get(opts, "target");
>  /* setup of chardev is deferred until they are initialised */
>  semihost_chardev = qemu_opt_get(opts, "chardev");
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 706bd7cff79..3593f1d7821 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1822,7 +1822,7 @@ static void qemu_apply_machine_options(QDict *qdict)
>  {
>  

Re: [PATCH v1] target/riscv: Add xicondops in ISA entry

2022-08-17 Thread Alistair Francis
On Tue, Aug 16, 2022 at 2:54 PM Rahul Pathak  wrote:
>
> XVentanaCondOps is Ventana custom extension. Add
> its extension entry in the ISA Ext array
>
> Signed-off-by: Rahul Pathak 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
> This patch is based on branch riscv-to-apply.next (Alistair qemu tree)
> Based on top commit: f2a91d8b78
>
>  target/riscv/cpu.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 2498b93105..27d10bd6a6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -104,6 +104,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.34.1
>
>



Re: [PATCH for-7.1 3/4] target/loongarch: rename the TCG CPU "la464" to "qemu64-v1.00"

2022-08-17 Thread WANG Xuerui

On 2022/8/17 21:26, Richard Henderson wrote:

On 8/17/22 04:10, WANG Xuerui wrote:
 From my own experiences, different use cases care about different 
aspects of the CPU, and that IMO is an argument in favor of providing 
both (high-fidelity models named after actual product model names, 
and virtual models named after ISA levels). But before we have truly 
high-fidelity models I think we should start with the virtual ones 
first. And don't pretend the currently implemented model is LA464 -- 
the kernel change I've linked to [1] implies the opposite.


No, it simply pointed to a bug in qemu that could have been fixed.

The trouble with inventing virtual models is that no one knows what 
they mean.  Targeting real hardware is better, because we have a 
documented standard.


Hmm, I've looked up more context and it is indeed reasonable to 
generally name the QEMU models after real existing models. But in this 
case we could face a problem with Loongson's nomenclature: all of 
Loongson 3A5000, 3C5000 and 3C5000L are LA464, yet they should be 
distinguishable software-side by checking the model name CSR. But with 
only one CPU model that is LA464, currently this CSR is hard-coded to 
read "3A5000", and this can hurt IMO. And when we finally add LA264 and 
LA364 they would be identical ISA-level-wise, again the only 
differentiator is the model name CSR.


And by "not high-fidelity", I mean some of the features present on real 
HW might never get implemented, or actually implementable, like the DVFS 
mechanism needed by cpufreq. And I believe Bibo wouldn't have to change 
the kernel if it's not needed after all to run the unmodified upstream 
kernel on top of qemu-system-loongarch64. (I would of course accept, and 
learn something along the way, if this turns out not to be the case though.)


Lastly, the "ISA level" I proposed is not arbitrarily made up; it's 
direct reference to the ISA manual revision. Each time the ISA gets some 
addition/revision the ISA manual has to be updated, and currently the 
manual's revision is the only reliable source of said information. 
(Loongson has a history of naming cores badly, like with the MIPS 3B1500 
and 3A4000, both were "GS464V"; and 3A5000 was originally GS464V too, 
even though the insn encodings and some semantics have been entirely 
different.)


In conclusion, I'd accept the micro-architecture naming if the model CSR 
behavior could be sorted out, otherwise I'd personally prefer real model 
names if ISA level naming is not going to fly. This is not a strong 
objection to the current way of doing things though, more like some 
minor but anyway needed discussion that happened a bit late. Sorry for 
not chiming in earlier during the review process.




Re: [PATCH v7 01/14] mm: Add F_SEAL_AUTO_ALLOCATE seal to memfd

2022-08-17 Thread Kirill A. Shutemov
On Fri, Aug 05, 2022 at 07:55:38PM +0200, Paolo Bonzini wrote:
> On 7/21/22 11:44, David Hildenbrand wrote:
> > 
> > Also, I*think*  you can place pages via userfaultfd into shmem. Not
> > sure if that would count "auto alloc", but it would certainly bypass
> > fallocate().
> 
> Yeah, userfaultfd_register would probably have to forbid this for
> F_SEAL_AUTO_ALLOCATE vmas.  Maybe the memfile_node can be reused for this,
> adding a new MEMFILE_F_NO_AUTO_ALLOCATE flags?  Then userfault_register
> would do something like memfile_node_get_flags(vma->vm_file) and check the
> result.

I donno, memory allocation with userfaultfd looks pretty intentional to
me. Why would F_SEAL_AUTO_ALLOCATE prevent it?

Maybe we would need it in the future for post-copy migration or something?

Or existing practises around userfaultfd touch memory randomly and
therefore incompatible with F_SEAL_AUTO_ALLOCATE intent?

Note, that userfaultfd is only relevant for shared memory as it requires
VMA which we don't have for MFD_INACCESSIBLE.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov



Re: [PATCH 4/8] migration: Implement dirty-limit convergence algo

2022-08-17 Thread Peter Xu
On Sat, Jul 23, 2022 at 03:49:16PM +0800, huang...@chinatelecom.cn wrote:
> From: Hyman Huang(黄勇) 
> 
> Implement dirty-limit convergence algo for live migration,
> which is kind of like auto-converge algo but using dirty-limit
> instead of cpu throttle to make migration convergent.
> 
> Signed-off-by: Hyman Huang(黄勇) 
> ---
>  migration/ram.c| 53 
> +-
>  migration/trace-events |  1 +
>  2 files changed, 41 insertions(+), 13 deletions(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index b94669b..2a5cd23 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -45,6 +45,7 @@
>  #include "qapi/error.h"
>  #include "qapi/qapi-types-migration.h"
>  #include "qapi/qapi-events-migration.h"
> +#include "qapi/qapi-commands-migration.h"
>  #include "qapi/qmp/qerror.h"
>  #include "trace.h"
>  #include "exec/ram_addr.h"
> @@ -57,6 +58,8 @@
>  #include "qemu/iov.h"
>  #include "multifd.h"
>  #include "sysemu/runstate.h"
> +#include "sysemu/dirtylimit.h"
> +#include "sysemu/kvm.h"
>  
>  #include "hw/boards.h" /* for machine_dump_guest_core() */
>  
> @@ -1139,6 +1142,21 @@ static void migration_update_rates(RAMState *rs, 
> int64_t end_time)
>  }
>  }
>  
> +/*
> + * Enable dirty-limit to throttle down the guest
> + */
> +static void migration_dirty_limit_guest(void)
> +{
> +if (!dirtylimit_in_service()) {
> +MigrationState *s = migrate_get_current();
> +int64_t quota_dirtyrate = s->parameters.vcpu_dirty_limit;
> +
> +/* Set quota dirtyrate if dirty limit not in service */
> +qmp_set_vcpu_dirty_limit(false, -1, quota_dirtyrate, NULL);
> +trace_migration_dirty_limit_guest(quota_dirtyrate);
> +}
> +}

What if migration is cancelled?  Do we have logic to stop the dirty limit,
or should we?

-- 
Peter Xu




Re: [PATCH 2/8] qapi/migration: Introduce vcpu-dirty-limit parameters

2022-08-17 Thread Peter Xu
On Sat, Jul 23, 2022 at 03:49:14PM +0800, huang...@chinatelecom.cn wrote:
> From: Hyman Huang(黄勇) 
> 
> Introduce "vcpu-dirty-limit" migration parameter used
> to limit dirty page rate during live migration.
> 
> "vcpu-dirty-limit" and "x-vcpu-dirty-limit-period" are
> two dirty-limit-related migration parameters, which can
> be set before and during live migration by qmp
> migrate-set-parameters.
> 
> This two parameters are used to help implement the dirty
> page rate limit algo of migration.
> 
> Signed-off-by: Hyman Huang(黄勇) 
> ---
>  migration/migration.c | 14 ++
>  monitor/hmp-cmds.c|  8 
>  qapi/migration.json   | 18 +++---
>  3 files changed, 37 insertions(+), 3 deletions(-)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index 7b19f85..ed1a47b 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -117,6 +117,7 @@
>  #define DEFAULT_MIGRATE_ANNOUNCE_STEP100
>  
>  #define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD 500 /* ms */
> +#define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT1   /* MB/s */

This default value also looks a bit weird.. why 1MB/s?  Thanks,

-- 
Peter Xu




Re: [PATCH 1/8] qapi/migration: Introduce x-vcpu-dirty-limit-period parameter

2022-08-17 Thread Peter Xu
On Sat, Jul 23, 2022 at 03:49:13PM +0800, huang...@chinatelecom.cn wrote:
> From: Hyman Huang(黄勇) 
> 
> Introduce "x-vcpu-dirty-limit-period" migration experimental
> parameter, which is used to make dirtyrate calculation period
> configurable.
> 
> Signed-off-by: Hyman Huang(黄勇) 
> ---
>  migration/migration.c | 16 
>  monitor/hmp-cmds.c|  8 
>  qapi/migration.json   | 31 ---
>  3 files changed, 48 insertions(+), 7 deletions(-)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index e03f698..7b19f85 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -116,6 +116,8 @@
>  #define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS5
>  #define DEFAULT_MIGRATE_ANNOUNCE_STEP100
>  
> +#define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD 500 /* ms */

Why 500 but not DIRTYLIMIT_CALC_TIME_MS?

Is it intended to make this parameter experimental, but the other one not?

Thanks,

-- 
Peter Xu




Re: [PATCH v3 8/8] parallels: Replace qemu_co_mutex_lock by WITH_QEMU_LOCK_GUARD

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

Replace the way we use mutex in parallels_co_check() for simplier
and less error prone code.

Signed-off-by: Alexander Ivanov 
---
v2: Fix an incorrect usage of WITH_QEMU_LOCK_GUARD.
v3: Fix commit message.

  block/parallels.c | 26 --
  1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index d0364182bb..e124a8bb7d 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -553,24 +553,22 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,
  BDRVParallelsState *s = bs->opaque;
  int ret;
  
-qemu_co_mutex_lock(>lock);

+WITH_QEMU_LOCK_GUARD(>lock) {
+parallels_check_unclean(bs, res, fix);
  
-parallels_check_unclean(bs, res, fix);

+ret = parallels_check_outside_image(bs, res, fix);
+if (ret < 0) {
+return ret;
+}
  
-ret = parallels_check_outside_image(bs, res, fix);

-if (ret < 0) {
-goto out;
-}
-
-ret = parallels_check_leak(bs, res, fix);
-if (ret < 0) {
-goto out;
-}
+ret = parallels_check_leak(bs, res, fix);
+if (ret < 0) {
+return ret;
+}
  
-parallels_collect_statistics(bs, res, fix);

+parallels_collect_statistics(bs, res, fix);
  
-out:

-qemu_co_mutex_unlock(>lock);
+}
  
  ret = bdrv_co_flush(bs);

  if (ret < 0) {


Aha, and here you silently fix the problem I noted in patch 3. Still, all 
patches should be correct, so this should be rebased onto fixed patch 3.

The final look of parallels_co_check is good.


--
Best regards,
Vladimir



Re: [PATCH v3 7/8] parallels: Move statistic collection to a separate function

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

We will add more and more checks so we need a better code structure
in parallels_co_check. Let each check performs in a separate loop
in a separate helper.

Signed-off-by: Alexander Ivanov


Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



Re: [PATCH v3 6/8] parallels: Move check of leaks to a separate function

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

We will add more and more checks so we need a better code structure
in parallels_co_check. Let each check performs in a separate loop
in a separate helper.

Signed-off-by: Alexander Ivanov 
---
v2: No change.
v3: Fix commit message.

  block/parallels.c | 85 +--
  1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 12104ba5ad..8737eadfb4 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -469,14 +469,13 @@ static int parallels_check_outside_image(BlockDriverState 
*bs,
  return 0;
  }
  
-static int coroutine_fn parallels_co_check(BlockDriverState *bs,

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


'i' should be kept to be uint32_t, as pre-patch.

With it fixed:

Reviewed-by: Vladimir Sementsov-Ogievskiy 



--
Best regards,
Vladimir



Re: [RFC v3 5/8] block: add BlockRAMRegistrar

2022-08-17 Thread Stefan Hajnoczi
On Thu, Jul 14, 2022 at 11:30:11AM +0200, Hanna Reitz wrote:
> On 08.07.22 06:17, Stefan Hajnoczi wrote:
> > Emulated devices and other BlockBackend users wishing to take advantage
> > of blk_register_buf() all have the same repetitive job: register
> > RAMBlocks with the BlockBackend using RAMBlockNotifier.
> > 
> > Add a BlockRAMRegistrar API to do this. A later commit will use this
> > from hw/block/virtio-blk.c.
> > 
> > Signed-off-by: Stefan Hajnoczi 
> > ---
> >   MAINTAINERS  |  1 +
> >   include/sysemu/block-ram-registrar.h | 30 +
> >   block/block-ram-registrar.c  | 39 
> >   block/meson.build|  1 +
> >   4 files changed, 71 insertions(+)
> >   create mode 100644 include/sysemu/block-ram-registrar.h
> >   create mode 100644 block/block-ram-registrar.c
> 
> What memory is handled in ram_list?  Is it everything?  If so, won’t devices
> have trouble registering all those buffer, especially if they happen to be
> fragmented in physical memory? (nvme_register_buf() seems to say it can run
> out of slots quite easily.)

I replied to this in another sub-thread. You are right, there is a
possibility of running out of mappings and there's no smart resource
management at the moment.

> 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 50f340d9ee..d16189449f 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2490,6 +2490,7 @@ F: block*
> >   F: block/
> >   F: hw/block/
> >   F: include/block/
> > +F: include/sysemu/block-*.h
> >   F: qemu-img*
> >   F: docs/tools/qemu-img.rst
> >   F: qemu-io*
> 
> Sneaky. ;)
> 
> > diff --git a/include/sysemu/block-ram-registrar.h 
> > b/include/sysemu/block-ram-registrar.h
> > new file mode 100644
> > index 00..09d63f64b2
> > --- /dev/null
> > +++ b/include/sysemu/block-ram-registrar.h
> > @@ -0,0 +1,30 @@
> > +/*
> > + * BlockBackend RAM Registrar
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#ifndef BLOCK_RAM_REGISTRAR_H
> > +#define BLOCK_RAM_REGISTRAR_H
> > +
> > +#include "exec/ramlist.h"
> > +
> > +/**
> > + * struct BlockRAMRegistrar:
> > + *
> > + * Keeps RAMBlock memory registered with a BlockBackend using
> > + * blk_register_buf() including hotplugged memory.
> > + *
> > + * Emulated devices or other BlockBackend users initialize a 
> > BlockRAMRegistrar
> > + * with blk_ram_registrar_init() before submitting I/O requests with the
> > + * BLK_REQ_REGISTERED_BUF flag set.
> 
> s/BLK/BDRV/, right?

Thanks, fixed!

Stefan


signature.asc
Description: PGP signature


Re: [RFC v3 4/8] block: add BDRV_REQ_REGISTERED_BUF request flag

2022-08-17 Thread Stefan Hajnoczi
On Thu, Jul 14, 2022 at 10:54:12AM +0200, Hanna Reitz wrote:
> On 08.07.22 06:17, Stefan Hajnoczi wrote:
> > Block drivers may optimize I/O requests accessing buffers previously
> > registered with bdrv_register_buf(). Checking whether all elements of a
> > request's QEMUIOVector are within previously registered buffers is
> > expensive, so we need a hint from the user to avoid costly checks.
> > 
> > Add a BDRV_REQ_REGISTERED_BUF request flag to indicate that all
> > QEMUIOVector elements in an I/O request are known to be within
> > previously registered buffers.
> > 
> > bdrv_aligned_preadv() is strict in validating supported read flags and
> > its assertions fail when it sees BDRV_REQ_REGISTERED_BUF. There is no
> > harm in passing BDRV_REQ_REGISTERED_BUF to block drivers that do not
> > support it, so update the assertions to ignore BDRV_REQ_REGISTERED_BUF.
> > 
> > Care must be taken to clear the flag when the block layer or filter
> > drivers replace QEMUIOVector elements with bounce buffers since these
> > have not been registered with bdrv_register_buf(). A lot of the changes
> > in this commit deal with clearing the flag in those cases.
> > 
> > Ensuring that the flag is cleared properly is somewhat invasive to
> > implement across the block layer and it's hard to spot when future code
> > changes accidentally break it. Another option might be to add a flag to
> > QEMUIOVector itself and clear it in qemu_iovec_*() functions that modify
> > elements. That is more robust but somewhat of a layering violation, so I
> > haven't attempted that.
> 
> Yeah...  I will say that most read code already looks quite reasonable in
> that it’ll pass @flags to lower layers basically only if it’s an unmodified
> request, so it seems like in the past most people have already adhered to
> “don’t pass on any flags if you’re reading to a local bounce buffer”.
> 
> > Signed-off-by: Stefan Hajnoczi
> > ---
> >   include/block/block-common.h |  9 +
> >   block/blkverify.c|  4 ++--
> >   block/crypto.c   |  2 ++
> >   block/io.c   | 30 +++---
> >   block/mirror.c   |  2 ++
> >   block/raw-format.c   |  2 ++
> >   6 files changed, 40 insertions(+), 9 deletions(-)
> 
> Some things not covered here that look a bit wrong:
> 
> While bdrv_driver_preadv() asserts that the flags don’t contain anything the
> driver couldn’t handle (and this new flag is made exempt from that assertion
> here in this patch), bdrv_driver_pwritev() just hides those flags from
> drivers silently. I think just like we exempt the new flag from the
> assertion in bdrv_driver_preadv(), we should have bdrv_driver_pwritev()
> always pass it to drivers.
> 
> The following driver read/write functions assert that @flags is 0, which is
> probably no longer ideal:
> - bdrv_qed_co_writev()
> - block_crypto_co_preadv()
> - nbd_client_co_preadv()
> - parallels_co_writev()
> - qcow_co_preadv()
> - qcow_co_pwritev()
> - qemu_gluster_co_writev()
> - raw_co_pwritev() (block/file-posix.c)
> - replication_co_writev()
> - ssh_co_writev()
> - vhdx_co_writev()
> 
> snapshot_access_co_preadv_part() returns an error when any flags are set,
> but should probably ignore BDRV_REQ_REGISTERED_BUF for this check.

The assert(!flags) checks can be removed without losing much safety
since bdrv_driver_preadv/pwritev() prepare the flags bits appropriately
and calls from other locations are rare.

> 
> 
> While looking around, I spotted a couple of places that look like they could
> pass the flag on but currently don’t (just FYI, not asking for anything
> here):
> 
> bdrv_co_do_copy_on_readv() never passes the flags through to its calls, but
> I think it could pass this flag on in the one bdrv_driver_preadv() call
> where it doesn’t use a bounce buffer (“Read directly into the destination”).
> 
> qcow2’s qcow2_co_preadv_task() and qcow2_co_pwritev_task() (besides the
> encryption part) also look like they should pass this flag on, but, well,
> the functions themselves currently don’t get the flag, so they can’t.
> 
> qcow1’s qcow_co_preadv() and qcow_co_pwritev() are so-so, sometimes using a
> bounce buffer, and sometimes not, but those function could use optimization
> in general if anyone cared.
> 
> vpc_co_preadv()’s and vpc_co_pwritev()’s first
> bdrv_co_preadv()/bdrv_co_pwritev() invocations look straightforward, but as
> with qcow1, not sure if anyone cares.
> 
> I’m too lazy to thoroughly check what’s going on with qed_aio_write_main(). 
> Passing 0 is safe, and it doesn’t get the original request flags, so I guess
> doing anything about this would be difficult.
> 
> quorum’s read_fifo_child() probably could pass acb->flags. Probably. 
> Perhaps not.  Difficult to say it is.
> 
> block/replication.c also looks like a candidate for passing flags, but
> personally, I’d like to refrain from touching it.  (Well, besides the fact
> that replication_co_writev() asserts that @flags is 0.)
> 
> 
> 

Re: [PATCH v3 5/8] parallels: Move check of cluster outside image to a separate function

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

We will add more and more checks so we need a better code structure
in parallels_co_check. Let each check performs in a separate loop
in a separate helper.

Signed-off-by: Alexander Ivanov



Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



Re: [PATCH v3 4/8] parallels: Move check of unclean image to a separate function

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

We will add more and more checks so we need a better code structure
in parallels_co_check. Let each check performs in a separate loop
in a separate helper.

Signed-off-by: Alexander Ivanov


Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



[PULL 12/12] virtio-pci: don't touch pci on virtio reset

2022-08-17 Thread Michael S. Tsirkin
virtio level reset should not affect pci express
registers such as PM, error or link.

Fixes: 27ce0f3afc ("hw/virtio: fix Power Management Control Register for PCI 
Express virtio devices")
Fixes: d584f1b9ca ("hw/virtio: fix Link Control Register for PCI Express virtio 
devices")
Fixes: c2cabb3422 ("hw/virtio: fix error enabling flags in Device Control 
register")
Cc: "Marcel Apfelbaum" 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 5ce61f9b45..a50c5a57d7 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1947,7 +1947,6 @@ static void virtio_pci_reset(DeviceState *qdev)
 {
 VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
 VirtioBusState *bus = VIRTIO_BUS(>bus);
-PCIDevice *dev = PCI_DEVICE(qdev);
 int i;
 
 virtio_bus_reset(bus);
@@ -1960,6 +1959,13 @@ static void virtio_pci_reset(DeviceState *qdev)
 proxy->vqs[i].avail[0] = proxy->vqs[i].avail[1] = 0;
 proxy->vqs[i].used[0] = proxy->vqs[i].used[1] = 0;
 }
+}
+
+static void virtio_pci_bus_reset(DeviceState *qdev)
+{
+PCIDevice *dev = PCI_DEVICE(qdev);
+
+virtio_pci_reset(qdev);
 
 if (pci_is_express(dev)) {
 pcie_cap_deverr_reset(dev);
@@ -2027,7 +2033,7 @@ static void virtio_pci_class_init(ObjectClass *klass, 
void *data)
 k->class_id = PCI_CLASS_OTHERS;
 device_class_set_parent_realize(dc, virtio_pci_dc_realize,
 >parent_dc_realize);
-dc->reset = virtio_pci_reset;
+dc->reset = virtio_pci_bus_reset;
 }
 
 static const TypeInfo virtio_pci_info = {
-- 
MST




[PULL 11/12] tests: acpi: silence applesmc warning about invalid key

2022-08-17 Thread Michael S. Tsirkin
From: Igor Mammedov 

OSK value is irrelevant for ACPI test case.
Supply fake OSK explicitly to prevent QEMU complaining about
invalid key when it fallbacks to default_osk.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Igor Mammedov 
Message-Id: <20220728133713.1369596-1-imamm...@redhat.com>
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/qtest/bios-tables-test.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 359916c228..7c5f736b51 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1632,7 +1632,9 @@ static void test_acpi_q35_applesmc(void)
 .variant = ".applesmc",
 };
 
-test_acpi_one("-device isa-applesmc", );
+/* supply fake 64-byte OSK to silence missing key warning */
+test_acpi_one("-device isa-applesmc,osk=any64characterfakeoskisenough"
+  "topreventinvalidkeywarningsonstderr", );
 free_test_data();
 }
 
-- 
MST




[PULL 06/12] hw/cxl: Fix memory leak in error paths

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

Use g_autofree to free the CXLFixedWindow structure if an
error occurs in configuration before we have added to
the list (via g_steal_pointer())

Fix Coverity CID: 1488872

Reported-by: Peter Maydell 
Signed-off-by: Jonathan Cameron 
Message-Id: <20220808122051.14822-2-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-host.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index 483d8eb13f..faa68ef038 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -26,7 +26,7 @@ static void cxl_fixed_memory_window_config(CXLState 
*cxl_state,
CXLFixedMemoryWindowOptions *object,
Error **errp)
 {
-CXLFixedWindow *fw = g_malloc0(sizeof(*fw));
+g_autofree CXLFixedWindow *fw = g_malloc0(sizeof(*fw));
 strList *target;
 int i;
 
@@ -64,7 +64,8 @@ static void cxl_fixed_memory_window_config(CXLState 
*cxl_state,
 fw->enc_int_gran = 0;
 }
 
-cxl_state->fixed_windows = g_list_append(cxl_state->fixed_windows, fw);
+cxl_state->fixed_windows = g_list_append(cxl_state->fixed_windows,
+ g_steal_pointer());
 
 return;
 }
-- 
MST




[PULL 10/12] hw/cxl: Correctly handle variable sized mailbox input payloads.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

A placeholder of ~0 is used to indicate variable payload size.
Whilst the checks for output payload correctly took this into
account, those for input payload did not.

This results in failure of the Set LSA command.

Fixes: 464e14ac43 ("hw/cxl/device: Implement basic mailbox (8.2.8.4)")
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-4-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-mailbox-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 3cea8b17a8..bc1bb18844 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -425,7 +425,7 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
 cxl_cmd = _cmd_set[set][cmd];
 h = cxl_cmd->handler;
 if (h) {
-if (len == cxl_cmd->in) {
+if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
 cxl_cmd->payload = cxl_dstate->mbox_reg_state +
 A_CXL_DEV_CMD_PAYLOAD;
 ret = (*h)(cxl_cmd, cxl_dstate, );
-- 
MST




[PULL 07/12] hw/cxl: Fix wrong query of target ports

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

Two issues were present in this code:
1) Check on which register to look in was inverted.
2) Both branches use the _LO register.

Whilst here moved to extract32() rather than hand rolling
the field extraction as simpler and hopefully less error prone.

Fixes Coverity CID: 1488873

Reported-by: Peter Maydell 
Signed-off-by: Jonathan Cameron 
Message-Id: <20220808122051.14822-3-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-host.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index faa68ef038..1adf61231a 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -104,7 +104,6 @@ static bool cxl_hdm_find_target(uint32_t *cache_mem, hwaddr 
addr,
 uint32_t ctrl;
 uint32_t ig_enc;
 uint32_t iw_enc;
-uint32_t target_reg;
 uint32_t target_idx;
 
 ctrl = cache_mem[R_CXL_HDM_DECODER0_CTRL];
@@ -116,14 +115,13 @@ static bool cxl_hdm_find_target(uint32_t *cache_mem, 
hwaddr addr,
 iw_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IW);
 target_idx = (addr / cxl_decode_ig(ig_enc)) % (1 << iw_enc);
 
-if (target_idx > 4) {
-target_reg = cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_LO];
-target_reg >>= target_idx * 8;
+if (target_idx < 4) {
+*target = extract32(cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_LO],
+target_idx * 8, 8);
 } else {
-target_reg = cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_LO];
-target_reg >>= (target_idx - 4) * 8;
+*target = extract32(cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_HI],
+(target_idx - 4) * 8, 8);
 }
-*target = target_reg & 0xff;
 
 return true;
 }
-- 
MST




[PULL 05/12] x86: disable rng seeding via setup_data

2022-08-17 Thread Michael S. Tsirkin
From: Gerd Hoffmann 

Causes regressions when doing direct kernel boots with OVMF.

At this point in the release cycle the only sensible action
is to just disable this for 7.1 and sort it properly in the
7.2 devel cycle.

Cc: Jason A. Donenfeld 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Laurent Vivier 
Signed-off-by: Gerd Hoffmann 
Message-Id: <20220817083940.3174933-1-kra...@redhat.com>
Cc: Jason A. Donenfeld 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Laurent Vivier 
Signed-off-by: Gerd Hoffmann 
---
 hw/i386/microvm.c | 2 +-
 hw/i386/pc_piix.c | 2 +-
 hw/i386/pc_q35.c  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 7fe8cce03e..52cafa003d 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -332,7 +332,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
 rom_set_fw(fw_cfg);
 
 if (machine->kernel_filename != NULL) {
-x86_load_linux(x86ms, fw_cfg, 0, true, false);
+x86_load_linux(x86ms, fw_cfg, 0, true, true);
 }
 
 if (mms->option_roms) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a5c65c1c35..20962c34e7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -439,6 +439,7 @@ static void pc_i440fx_7_1_machine_options(MachineClass *m)
 m->alias = "pc";
 m->is_default = true;
 pcmc->default_cpu_version = 1;
+pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL,
@@ -450,7 +451,6 @@ static void pc_i440fx_7_0_machine_options(MachineClass *m)
 pc_i440fx_7_1_machine_options(m);
 m->alias = NULL;
 m->is_default = false;
-pcmc->legacy_no_rng_seed = true;
 pcmc->enforce_amd_1tb_hole = false;
 compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
 compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 3a35193ff7..2e5dae9a89 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -376,6 +376,7 @@ static void pc_q35_7_1_machine_options(MachineClass *m)
 pc_q35_machine_options(m);
 m->alias = "q35";
 pcmc->default_cpu_version = 1;
+pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_Q35_MACHINE(v7_1, "pc-q35-7.1", NULL,
@@ -386,7 +387,6 @@ static void pc_q35_7_0_machine_options(MachineClass *m)
 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_q35_7_1_machine_options(m);
 m->alias = NULL;
-pcmc->legacy_no_rng_seed = true;
 pcmc->enforce_amd_1tb_hole = false;
 compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
 compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
-- 
MST




[PULL 04/12] hw/virtio: fix vhost_user_read tracepoint

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

As reads happen in the callback we were never seeing them. We only
really care about the header so move the tracepoint to when the header
is complete.

Fixes: 6ca6d8ee9d (hw/virtio: add vhost_user_[read|write] trace points)
Signed-off-by: Alex Bennée 
Acked-by: Jason Wang 
Message-Id: <20220728135503.1060062-5-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost-user.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 75b8df21a4..bd24741be8 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -295,6 +295,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, 
VhostUserMsg *msg)
 return -EPROTO;
 }
 
+trace_vhost_user_read(msg->hdr.request, msg->hdr.flags);
+
 return 0;
 }
 
@@ -544,8 +546,6 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, 
uint64_t base,
 }
 }
 
-trace_vhost_user_read(msg.hdr.request, msg.hdr.flags);
-
 return 0;
 }
 
-- 
MST




[PULL 09/12] hw/cxl: Fix Get LSA input payload size which should be 8 bytes.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

Get LSA needs 4 byte offset and 4 byte length arguments.
CXL rev 2.0 Table 178.

Fixes: 3ebe676a34 ("hw/cxl/device: Implement get/set Label Storage Area (LSA)")
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-3-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-mailbox-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index bb66c765a5..3cea8b17a8 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -406,7 +406,7 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
 cmd_identify_memory_device, 0, 0 },
 [CCLS][GET_PARTITION_INFO] = { "CCLS_GET_PARTITION_INFO",
 cmd_ccls_get_partition_info, 0, 0 },
-[CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 0, 0 },
+[CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 },
 [CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa,
 ~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
 };
-- 
MST




[PULL 01/12] virtio-scsi: fix race in virtio_scsi_dataplane_start()

2022-08-17 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

As soon as virtio_scsi_data_plane_start() attaches host notifiers the
IOThread may start virtqueue processing. There is a race between
IOThread virtqueue processing and virtio_scsi_data_plane_start() because
it only assigns s->dataplane_started after attaching host notifiers.

When a virtqueue handler function in the IOThread calls
virtio_scsi_defer_to_dataplane() it may see !s->dataplane_started and
attempt to start dataplane even though we're already in the IOThread:

  #0  0x7f67b360857c __pthread_kill_implementation (libc.so.6 + 0xa257c)
  #1  0x7f67b35bbd56 raise (libc.so.6 + 0x55d56)
  #2  0x7f67b358e833 abort (libc.so.6 + 0x28833)
  #3  0x7f67b358e75b __assert_fail_base.cold (libc.so.6 + 0x2875b)
  #4  0x7f67b35b4cd6 __assert_fail (libc.so.6 + 0x4ecd6)
  #5  0x55ca87fd411b memory_region_transaction_commit (qemu-kvm + 0x67511b)
  #6  0x55ca87e17811 virtio_pci_ioeventfd_assign (qemu-kvm + 0x4b8811)
  #7  0x55ca87e14836 virtio_bus_set_host_notifier (qemu-kvm + 0x4b5836)
  #8  0x55ca87f8e14e virtio_scsi_set_host_notifier (qemu-kvm + 0x62f14e)
  #9  0x55ca87f8dd62 virtio_scsi_dataplane_start (qemu-kvm + 0x62ed62)
  #10 0x55ca87e14610 virtio_bus_start_ioeventfd (qemu-kvm + 0x4b5610)
  #11 0x55ca87f8c29a virtio_scsi_handle_ctrl (qemu-kvm + 0x62d29a)
  #12 0x55ca87fa5902 virtio_queue_host_notifier_read (qemu-kvm + 0x646902)
  #13 0x55ca882c099e aio_dispatch_handler (qemu-kvm + 0x96199e)
  #14 0x55ca882c1761 aio_poll (qemu-kvm + 0x962761)
  #15 0x55ca880e1052 iothread_run (qemu-kvm + 0x782052)
  #16 0x55ca882c562a qemu_thread_start (qemu-kvm + 0x96662a)

This patch assigns s->dataplane_started before attaching host notifiers
so that virtqueue handler functions that run in the IOThread before
virtio_scsi_data_plane_start() returns correctly identify that dataplane
does not need to be started. This fix is taken from the virtio-blk
dataplane code and it's worth adding a comment in virtio-blk as well to
explain why it works.

Note that s->dataplane_started does not need the AioContext lock because
it is set before attaching host notifiers and cleared after detaching
host notifiers. In other words, the IOThread always sees the value true
and the main loop thread does not modify it while the IOThread is
active.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2099541
Reported-by: Qing Wang 
Signed-off-by: Stefan Hajnoczi 
Message-Id: <20220808162134.240405-1-stefa...@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/dataplane/virtio-blk.c |  5 +
 hw/scsi/virtio-scsi-dataplane.c | 11 ---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 49276e46f2..26f965cabc 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -219,6 +219,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
 
 memory_region_transaction_commit();
 
+/*
+ * These fields are visible to the IOThread so we rely on implicit barriers
+ * in aio_context_acquire() on the write side and aio_notify_accept() on
+ * the read side.
+ */
 s->starting = false;
 vblk->dataplane_started = true;
 trace_virtio_blk_data_plane_start(s);
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 8bb6e6acfc..20bb91766e 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -136,6 +136,14 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
 
 memory_region_transaction_commit();
 
+/*
+ * These fields are visible to the IOThread so we rely on implicit barriers
+ * in aio_context_acquire() on the write side and aio_notify_accept() on
+ * the read side.
+ */
+s->dataplane_starting = false;
+s->dataplane_started = true;
+
 aio_context_acquire(s->ctx);
 virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx);
 virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx);
@@ -143,9 +151,6 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
 for (i = 0; i < vs->conf.num_queues; i++) {
 virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx);
 }
-
-s->dataplane_starting = false;
-s->dataplane_started = true;
 aio_context_release(s->ctx);
 return 0;
 
-- 
MST




[PULL 08/12] hw/cxl: Add stub write function for RO MemoryRegionOps entries.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

There is no checking on the availability of a write callback.
Hence QEMU crashes if a write does occur to one of these regions.

Discovered whilst chasing a Linux kernel bug that incorrectly
wrote into one of these regions.

Fixes: 6364adacdf ("hw/cxl/device: Implement the CAP array (8.2.8.1-2)")
Reported-by: Bobo WL 
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-2-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-device-utils.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 687759b301..83ce7a8270 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -141,9 +141,15 @@ static uint64_t mdev_reg_read(void *opaque, hwaddr offset, 
unsigned size)
 return retval;
 }
 
+static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
+   unsigned size)
+{
+/* Many register sets are read only */
+}
+
 static const MemoryRegionOps mdev_ops = {
 .read = mdev_reg_read,
-.write = NULL, /* memory device register is read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
@@ -173,7 +179,7 @@ static const MemoryRegionOps mailbox_ops = {
 
 static const MemoryRegionOps dev_ops = {
 .read = dev_reg_read,
-.write = NULL, /* status register is read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
@@ -188,7 +194,7 @@ static const MemoryRegionOps dev_ops = {
 
 static const MemoryRegionOps caps_ops = {
 .read = caps_reg_read,
-.write = NULL, /* caps registers are read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
-- 
MST




[PULL 02/12] hw/virtio: gracefully handle unset vhost_dev vdev

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

I've noticed asserts firing because we query the status of vdev after
a vhost connection is closed down. Rather than faulting on the NULL
indirect just quietly reply false.

Signed-off-by: Alex Bennée 
Message-Id: <20220728135503.1060062-3-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 0827d631c0..f758f177bb 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -306,7 +306,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev 
*dev, uint64_t size)
 dev->log_size = size;
 }
 
-static int vhost_dev_has_iommu(struct vhost_dev *dev)
+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
 {
 VirtIODevice *vdev = dev->vdev;
 
@@ -316,8 +316,12 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
  * does not have IOMMU, there's no need to enable this feature
  * which may cause unnecessary IOTLB miss/update transactions.
  */
-return virtio_bus_device_iommu_enabled(vdev) &&
-   virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+if (vdev) {
+return virtio_bus_device_iommu_enabled(vdev) &&
+virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+} else {
+return false;
+}
 }
 
 static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
-- 
MST




[PULL 00/12] pc,virtio: fixes

2022-08-17 Thread Michael S. Tsirkin
The following changes since commit c7208a6e0d049f9e8af15df908168a79b1f99685:

  Update version for v7.1.0-rc3 release (2022-08-16 20:45:19 -0500)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 9afb4177d66ac1eee858aba07fa2fc729b274eb4:

  virtio-pci: don't touch pci on virtio reset (2022-08-17 13:08:11 -0400)


pc,virtio: fixes

Several bugfixes, they all look very safe to me. Revert
seed support since we aren't any closer to a proper fix.

Signed-off-by: Michael S. Tsirkin 


Alex Bennée (3):
  hw/virtio: gracefully handle unset vhost_dev vdev
  hw/virtio: handle un-configured shutdown in virtio-pci
  hw/virtio: fix vhost_user_read tracepoint

Gerd Hoffmann (1):
  x86: disable rng seeding via setup_data

Igor Mammedov (1):
  tests: acpi: silence applesmc warning about invalid key

Jonathan Cameron (5):
  hw/cxl: Fix memory leak in error paths
  hw/cxl: Fix wrong query of target ports
  hw/cxl: Add stub write function for RO MemoryRegionOps entries.
  hw/cxl: Fix Get LSA input payload size which should be 8 bytes.
  hw/cxl: Correctly handle variable sized mailbox input payloads.

Michael S. Tsirkin (1):
  virtio-pci: don't touch pci on virtio reset

Stefan Hajnoczi (1):
  virtio-scsi: fix race in virtio_scsi_dataplane_start()

 hw/block/dataplane/virtio-blk.c |  5 +
 hw/cxl/cxl-device-utils.c   | 12 +---
 hw/cxl/cxl-host.c   | 17 -
 hw/cxl/cxl-mailbox-utils.c  |  4 ++--
 hw/i386/microvm.c   |  2 +-
 hw/i386/pc_piix.c   |  2 +-
 hw/i386/pc_q35.c|  2 +-
 hw/scsi/virtio-scsi-dataplane.c | 11 ---
 hw/virtio/vhost-user.c  |  4 ++--
 hw/virtio/vhost.c   | 10 +++---
 hw/virtio/virtio-pci.c  | 19 +++
 tests/qtest/bios-tables-test.c  |  4 +++-
 12 files changed, 62 insertions(+), 30 deletions(-)




[PULL 03/12] hw/virtio: handle un-configured shutdown in virtio-pci

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

The assert() protecting against leakage is a little aggressive and
causes needless crashes if a device is shutdown without having been
configured. In this case no descriptors are lost because none have
been assigned.

Signed-off-by: Alex Bennée 
Message-Id: <20220728135503.1060062-4-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 45327f0b31..5ce61f9b45 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -996,9 +996,14 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, 
int nvqs, bool assign)
 
 nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
 
-/* When deassigning, pass a consistent nvqs value
- * to avoid leaking notifiers.
+/*
+ * When deassigning, pass a consistent nvqs value to avoid leaking
+ * notifiers. But first check we've actually been configured, exit
+ * early if we haven't.
  */
+if (!assign && !proxy->nvqs_with_notifiers) {
+return 0;
+}
 assert(assign || nvqs == proxy->nvqs_with_notifiers);
 
 proxy->nvqs_with_notifiers = nvqs;
-- 
MST




Re: [PATCH v3 3/8] parallels: Use generic infrastructure for BAT writing in parallels_co_check()

2022-08-17 Thread Denis V. Lunev

On 17.08.2022 21:48, Vladimir Sementsov-Ogievskiy wrote:

On 8/15/22 12:02, Alexander Ivanov wrote:

BAT is written in the context of conventional operations over
the image inside bdrv_co_flush() when it calls
parallels_co_flush_to_os() callback. Thus we should not
modify BAT array directly, but call parallels_set_bat_entry()
helper and bdrv_co_flush() further on. After that there is no
need to manually write BAT and track its modification.

This makes code more generic and allows to split
parallels_set_bat_entry() for independent pieces.

Signed-off-by: Alexander Ivanov 
---
v2: Patch order was changed so the replacement is done in 
parallels_co_check.

 Now we use a helper to set BAT entry and mark the block dirty.
v3: Fix commit message.

  block/parallels.c | 19 +++
  1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 7f68f3cbc9..6879ea4597 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -428,7 +428,6 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,

  int64_t size, prev_off, high_off;
  int ret;
  uint32_t i;
-    bool flush_bat = false;
    size = bdrv_getlength(bs->file->bs);
  if (size < 0) {
@@ -467,9 +466,8 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,

  res->corruptions++;
  if (fix & BDRV_FIX_ERRORS) {
  prev_off = 0;
-    s->bat_bitmap[i] = 0;
+    parallels_set_bat_entry(s, i, 0);
  res->corruptions_fixed++;
-    flush_bat = true;
  continue;
  }
  }
@@ -485,15 +483,6 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,

  prev_off = off;
  }
  -    ret = 0;
-    if (flush_bat) {
-    ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size, 
s->header, 0);

-    if (ret < 0) {
-    res->check_errors++;
-    goto out;
-    }
-    }
-
  res->image_end_offset = high_off + s->cluster_size;
  if (size > res->image_end_offset) {
  int64_t count;
@@ -522,6 +511,12 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,

    out:
  qemu_co_mutex_unlock(>lock);
+
+    ret = bdrv_co_flush(bs);


Oops that's wrong. Here we probably rewrite previous error of 
bdrv_truncate stored in ret variable.




You absolutely right, we have missed this point.

Good catch!


+    if (ret < 0) {
+    res->check_errors++;
+    }
+
  return ret;
  }








Re: [PATCH v3 1/8] parallels: Out of image offset in BAT leads to image inflation

2022-08-17 Thread Denis V. Lunev

On 17.08.2022 21:43, Vladimir Sementsov-Ogievskiy wrote:

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

On 17.08.2022 21:13, Vladimir Sementsov-Ogievskiy wrote:

On 8/15/22 12:02, Alexander Ivanov wrote:
data_end field in BDRVParallelsState is set to the biggest offset 
present
in BAT. If this offset is outside of the image, any further write 
will create

the cluster at this offset and/or the image will be truncated to this
offset on close. This is definitely not correct and should be fixed.

Signed-off-by: Alexander Ivanov 
---
v2: No change.
v3: Fix commit message.

  block/parallels.c | 17 +
  1 file changed, 17 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index a229c06f25..a76cf9d993 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -732,6 +732,7 @@ static int parallels_open(BlockDriverState *bs, 
QDict *options, int flags,

  BDRVParallelsState *s = bs->opaque;
  ParallelsHeader ph;
  int ret, size, i;
+    int64_t file_size;
  QemuOpts *opts = NULL;
  Error *local_err = NULL;
  char *buf;
@@ -811,6 +812,22 @@ static int parallels_open(BlockDriverState 
*bs, QDict *options, int flags,

  }
  }
  +    file_size = bdrv_getlength(bs->file->bs);
+    if (file_size < 0) {
+    goto fail;
+    }
+
+    file_size >>= BDRV_SECTOR_BITS;
+    if (s->data_end > file_size) {
+    if (flags & BDRV_O_CHECK) {
+    s->data_end = file_size;


Hm. but with this, any further allocation may lead to twice-allocted 
clusters, as you just modify s->data_end, but havn't yet fixed the 
BAT entry.. It seems unsafe. Or what I miss?


if O_CHECK is specified, we are going to execute parallels_co_check 
which

will correctly handle this. In the other case (normal open) we will
face the error, which is pretty much correct under this logic.


Sounds like "s->data_end = file_size" is part of this handling and 
should be in parallels_co_check()..


Looking at it, seems more correct to recalculate s->data_end exactly 
after for-loop, which fixes out-of-image clusters. Also it would work 
better in case when we have leaked clusters at the end of file.


Otherwise, ideally, you should have comment at top of 
parallels_co_check(), that we must first fix out-of-image clusters, 
before doing any kind of allocation, because data_end is already tweaked.


I agree that patch should work as is.



but that will change the game rules.

Ideally we should call parallels_co_check if we face a error
on open and assume that the error is recoverable like
is done in QCOW2, but IMHO this is not the time within
this patchset.

This patch is needed here as we would have tests broken
immediately once we start checking duplicated cluster
management.

That is why I am happy with this code but in general this
would need further rework. This is a question of the
chicken and egg and we can not do all at once :(




+    } else {
+    error_setg(errp, "parallels: Offset in BAT is out of 
image");

+    ret = -EINVAL;
+    goto fail;
+    }
+    }
+
  if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
  /* Image was not closed correctly. The check is mandatory */
  s->header_unclean = true;













Re: [PATCH v3 3/8] parallels: Use generic infrastructure for BAT writing in parallels_co_check()

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

BAT is written in the context of conventional operations over
the image inside bdrv_co_flush() when it calls
parallels_co_flush_to_os() callback. Thus we should not
modify BAT array directly, but call parallels_set_bat_entry()
helper and bdrv_co_flush() further on. After that there is no
need to manually write BAT and track its modification.

This makes code more generic and allows to split
parallels_set_bat_entry() for independent pieces.

Signed-off-by: Alexander Ivanov 
---
v2: Patch order was changed so the replacement is done in parallels_co_check.
 Now we use a helper to set BAT entry and mark the block dirty.
v3: Fix commit message.

  block/parallels.c | 19 +++
  1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 7f68f3cbc9..6879ea4597 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -428,7 +428,6 @@ static int coroutine_fn parallels_co_check(BlockDriverState 
*bs,
  int64_t size, prev_off, high_off;
  int ret;
  uint32_t i;
-bool flush_bat = false;
  
  size = bdrv_getlength(bs->file->bs);

  if (size < 0) {
@@ -467,9 +466,8 @@ static int coroutine_fn parallels_co_check(BlockDriverState 
*bs,
  res->corruptions++;
  if (fix & BDRV_FIX_ERRORS) {
  prev_off = 0;
-s->bat_bitmap[i] = 0;
+parallels_set_bat_entry(s, i, 0);
  res->corruptions_fixed++;
-flush_bat = true;
  continue;
  }
  }
@@ -485,15 +483,6 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,
  prev_off = off;
  }
  
-ret = 0;

-if (flush_bat) {
-ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size, s->header, 0);
-if (ret < 0) {
-res->check_errors++;
-goto out;
-}
-}
-
  res->image_end_offset = high_off + s->cluster_size;
  if (size > res->image_end_offset) {
  int64_t count;
@@ -522,6 +511,12 @@ static int coroutine_fn 
parallels_co_check(BlockDriverState *bs,
  
  out:

  qemu_co_mutex_unlock(>lock);
+
+ret = bdrv_co_flush(bs);


Oops that's wrong. Here we probably rewrite previous error of bdrv_truncate 
stored in ret variable.


+if (ret < 0) {
+res->check_errors++;
+}
+
  return ret;
  }
  



--
Best regards,
Vladimir



Re: [PATCH v3 1/8] parallels: Out of image offset in BAT leads to image inflation

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

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

On 17.08.2022 21:13, Vladimir Sementsov-Ogievskiy wrote:

On 8/15/22 12:02, Alexander Ivanov wrote:

data_end field in BDRVParallelsState is set to the biggest offset present
in BAT. If this offset is outside of the image, any further write will create
the cluster at this offset and/or the image will be truncated to this
offset on close. This is definitely not correct and should be fixed.

Signed-off-by: Alexander Ivanov 
---
v2: No change.
v3: Fix commit message.

  block/parallels.c | 17 +
  1 file changed, 17 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index a229c06f25..a76cf9d993 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -732,6 +732,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  BDRVParallelsState *s = bs->opaque;
  ParallelsHeader ph;
  int ret, size, i;
+    int64_t file_size;
  QemuOpts *opts = NULL;
  Error *local_err = NULL;
  char *buf;
@@ -811,6 +812,22 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  }
  }
  +    file_size = bdrv_getlength(bs->file->bs);
+    if (file_size < 0) {
+    goto fail;
+    }
+
+    file_size >>= BDRV_SECTOR_BITS;
+    if (s->data_end > file_size) {
+    if (flags & BDRV_O_CHECK) {
+    s->data_end = file_size;


Hm. but with this, any further allocation may lead to twice-allocted clusters, as 
you just modify s->data_end, but havn't yet fixed the BAT entry.. It seems 
unsafe. Or what I miss?


if O_CHECK is specified, we are going to execute parallels_co_check which
will correctly handle this. In the other case (normal open) we will
face the error, which is pretty much correct under this logic.


Sounds like "s->data_end = file_size" is part of this handling and should be in 
parallels_co_check()..

Looking at it, seems more correct to recalculate s->data_end exactly after 
for-loop, which fixes out-of-image clusters. Also it would work better in case 
when we have leaked clusters at the end of file.

Otherwise, ideally, you should have comment at top of parallels_co_check(), 
that we must first fix out-of-image clusters, before doing any kind of 
allocation, because data_end is already tweaked.

I agree that patch should work as is.




+    } else {
+    error_setg(errp, "parallels: Offset in BAT is out of image");
+    ret = -EINVAL;
+    goto fail;
+    }
+    }
+
  if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
  /* Image was not closed correctly. The check is mandatory */
  s->header_unclean = true;








--
Best regards,
Vladimir



Re: [PATCH v3 1/8] parallels: Out of image offset in BAT leads to image inflation

2022-08-17 Thread Denis V. Lunev

On 17.08.2022 21:13, Vladimir Sementsov-Ogievskiy wrote:

On 8/15/22 12:02, Alexander Ivanov wrote:
data_end field in BDRVParallelsState is set to the biggest offset 
present
in BAT. If this offset is outside of the image, any further write 
will create

the cluster at this offset and/or the image will be truncated to this
offset on close. This is definitely not correct and should be fixed.

Signed-off-by: Alexander Ivanov 
---
v2: No change.
v3: Fix commit message.

  block/parallels.c | 17 +
  1 file changed, 17 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index a229c06f25..a76cf9d993 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -732,6 +732,7 @@ static int parallels_open(BlockDriverState *bs, 
QDict *options, int flags,

  BDRVParallelsState *s = bs->opaque;
  ParallelsHeader ph;
  int ret, size, i;
+    int64_t file_size;
  QemuOpts *opts = NULL;
  Error *local_err = NULL;
  char *buf;
@@ -811,6 +812,22 @@ static int parallels_open(BlockDriverState *bs, 
QDict *options, int flags,

  }
  }
  +    file_size = bdrv_getlength(bs->file->bs);
+    if (file_size < 0) {
+    goto fail;
+    }
+
+    file_size >>= BDRV_SECTOR_BITS;
+    if (s->data_end > file_size) {
+    if (flags & BDRV_O_CHECK) {
+    s->data_end = file_size;


Hm. but with this, any further allocation may lead to twice-allocted 
clusters, as you just modify s->data_end, but havn't yet fixed the BAT 
entry.. It seems unsafe. Or what I miss?



if O_CHECK is specified, we are going to execute parallels_co_check which
will correctly handle this. In the other case (normal open) we will
face the error, which is pretty much correct under this logic.


+    } else {
+    error_setg(errp, "parallels: Offset in BAT is out of 
image");

+    ret = -EINVAL;
+    goto fail;
+    }
+    }
+
  if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
  /* Image was not closed correctly. The check is mandatory */
  s->header_unclean = true;








Re: [PATCH v3 2/8] parallels: create parallels_set_bat_entry_helper() to assign BAT value

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

This helper will be reused in next patches during parallels_co_check
rework to simplify its code.

Signed-off-by: Alexander Ivanov 


Reviewed-by: Vladimir Sementsov-Ogievskiy 


---
v2: A new patch - a part of a splitted patch.
v3: Fix commit message.

  block/parallels.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index a76cf9d993..7f68f3cbc9 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -165,6 +165,13 @@ static int64_t block_status(BDRVParallelsState *s, int64_t 
sector_num,
  return start_off;
  }
  
+static void parallels_set_bat_entry(BDRVParallelsState *s,

+uint32_t index, uint32_t offset)


Rather unobvious that offset should be passed already converted to LE. Worth a 
comment? Or may be do convertion inside function (depends on further usages of 
the helper)


+{
+s->bat_bitmap[index] = offset;
+bitmap_set(s->bat_dirty_bmap, bat_entry_off(index) / s->bat_dirty_block, 
1);
+}
+
  static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
   int nb_sectors, int *pnum)
  {
@@ -250,10 +257,9 @@ static int64_t allocate_clusters(BlockDriverState *bs, 
int64_t sector_num,
  }
  
  for (i = 0; i < to_allocate; i++) {

-s->bat_bitmap[idx + i] = cpu_to_le32(s->data_end / s->off_multiplier);
+parallels_set_bat_entry(s, idx + i,
+cpu_to_le32(s->data_end / s->off_multiplier));
  s->data_end += s->tracks;
-bitmap_set(s->bat_dirty_bmap,
-   bat_entry_off(idx + i) / s->bat_dirty_block, 1);
  }
  
  return bat2sect(s, idx) + sector_num % s->tracks;



--
Best regards,
Vladimir



Re: [PATCH v3 1/8] parallels: Out of image offset in BAT leads to image inflation

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/15/22 12:02, Alexander Ivanov wrote:

data_end field in BDRVParallelsState is set to the biggest offset present
in BAT. If this offset is outside of the image, any further write will create
the cluster at this offset and/or the image will be truncated to this
offset on close. This is definitely not correct and should be fixed.

Signed-off-by: Alexander Ivanov 
---
v2: No change.
v3: Fix commit message.

  block/parallels.c | 17 +
  1 file changed, 17 insertions(+)

diff --git a/block/parallels.c b/block/parallels.c
index a229c06f25..a76cf9d993 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -732,6 +732,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  BDRVParallelsState *s = bs->opaque;
  ParallelsHeader ph;
  int ret, size, i;
+int64_t file_size;
  QemuOpts *opts = NULL;
  Error *local_err = NULL;
  char *buf;
@@ -811,6 +812,22 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
  }
  }
  
+file_size = bdrv_getlength(bs->file->bs);

+if (file_size < 0) {
+goto fail;
+}
+
+file_size >>= BDRV_SECTOR_BITS;
+if (s->data_end > file_size) {
+if (flags & BDRV_O_CHECK) {
+s->data_end = file_size;


Hm. but with this, any further allocation may lead to twice-allocted clusters, as 
you just modify s->data_end, but havn't yet fixed the BAT entry.. It seems 
unsafe. Or what I miss?


+} else {
+error_setg(errp, "parallels: Offset in BAT is out of image");
+ret = -EINVAL;
+goto fail;
+}
+}
+
  if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
  /* Image was not closed correctly. The check is mandatory */
  s->header_unclean = true;



--
Best regards,
Vladimir



Re: [PATCH v2 00/31] QOMify PPC4xx devices and minor clean ups

2022-08-17 Thread BALATON Zoltan

On Wed, 17 Aug 2022, BALATON Zoltan wrote:

Hello,

This is based on gitlab.com/danielhb/qemu/tree/ppc-7.2

This series contains the rest of Cédric's OOM'ify patches modified
according my review comments and some other clean ups I've noticed
along the way.

v2 now also includes the sdram changes after some clean up to simplify
it. This should now be the same state as Cédric's series. I shall
continue with the ppc440_sdram DDR2 controller model used by the
sam460ex but that needs a bit more chnages. But it is independent of
this series so this can be merged now and I can follow up later in a
separate series.


I've resent fixed v3 patches for patch 21 and 31, hopefully there are no 
more missing pieces. Let me know if you want the whole series resent 
instead.


Regards,
BALATON Zoltan

[PATCH v3 21/31] hw/ppc/sam3460ex: Remove PPC405 dependency from sam460ex

2022-08-17 Thread BALATON Zoltan
Now that shared PPC4xx devices are separated from PPC405 ones we can
drop this depencency.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
v3: Also remove now unneeded #include

 hw/ppc/Kconfig| 1 -
 hw/ppc/sam460ex.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 400511c6b7..205f9f98d7 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -58,7 +58,6 @@ config PPC4XX
 
 config SAM460EX
 bool
-select PPC405
 select PFLASH_CFI01
 select IDE_SII3112
 select M41T80
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 348ed27211..850bb3b817 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -25,7 +25,6 @@
 #include "elf.h"
 #include "exec/memory.h"
 #include "ppc440.h"
-#include "ppc405.h"
 #include "hw/block/flash.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/reset.h"
-- 
2.30.4




Re: [PATCH v10 18/21] job.c: enable job lock/unlock and remove Aiocontext locks

2022-08-17 Thread Vladimir Sementsov-Ogievskiy

On 8/16/22 15:52, Emanuele Giuseppe Esposito wrote:

   }
@@ -501,8 +481,12 @@ void job_unref_locked(Job *job)>
assert(!job->txn);
     if (job->driver->free) {
+    AioContext *aio_context = job->aio_context;
   job_unlock();
+    /* FIXME: aiocontext lock is required because cb calls
blk_unref */
+    aio_context_acquire(aio_context);
   job->driver->free(job);
+    aio_context_release(aio_context);

So, job_unref_locked() must be called with aio_context not locked,
otherwise we dead-lock here? That should be documented in function
declaration comment.

For example in qemu-img.c in run_block_job() we do exactly that: call
job_unref_locked()  inside aio-context lock critical seaction..

No, job_unref_locked has also status and refcnt and all the other fields
that need to be protectd. Only free must be called without job lock held.



I mean, don't we try here to acquire aio_context twice, when we call 
job_unref_locked() with aio_context _already_ acquired?

--
Best regards,
Vladimir



Re: [PATCH v4] target/ppc: Fix host PVR matching for KVM

2022-08-17 Thread Daniel Henrique Barboza




On 7/30/22 22:33, Nicholas Piggin wrote:

ppc_cpu_compare_class_pvr_mask() should match the best CPU class in the
family, because it is used by the KVM subsystem to find the host CPU
class. Since commit 03ae4133ab8 ("target-ppc: Add pvr_match()
callback"), it matches any class in the family (the first one in the
comparison list).

Since commit f30c843ced5 ("ppc/pnv: Introduce PowerNV machines with
fixed CPU models"), pnv has relied on pnv_match having these new
semantics to check machine compatibility with a CPU family.

Resolve this by adding a parameter to the pvr_match function to select
the best or any match, and restore the old behaviour for the KVM case.

Prior to this fix, e.g., a POWER9 DD2.3 KVM host matches to the
power9_v1.0 class (because that happens to be the first POWER9 family
CPU compared). After the patch, it matches the power9_v2.0 class.

This approach requires pnv_match contain knowledge of the CPU classes
implemented in the same family, which feels ugly. But pushing the 'best'
match down to the class would still require they know about one another
which is not obviously much better. For now this gets things working.

Fixes: 03ae4133ab8 ("target-ppc: Add pvr_match() callback")
Signed-off-by: Nicholas Piggin 
---


Reviewed-by: Daniel Henrique Barboza 

And queued in gitlab.com/danielhb/qemu/tree/ppc-7.2.


Daniel



This is extracted from patch 1 in the series here:

https://lists.gnu.org/archive/html/qemu-ppc/2022-03/msg00226.html

I finally went back and worked out what the issue was, which is the
new usage of pvr_match that pnv has. That should now be fixed.

Thanks,
Nick

  hw/ppc/pnv.c  |  2 +-
  target/ppc/cpu-qom.h  |  6 ++-
  target/ppc/cpu_init.c | 91 +--
  target/ppc/machine.c  |  2 +-
  4 files changed, 77 insertions(+), 24 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d3f77c8367..a4cb4cf10b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -714,7 +714,7 @@ static bool pnv_match_cpu(const char *default_type, const 
char *cpu_type)
  PowerPCCPUClass *ppc =
  POWERPC_CPU_CLASS(object_class_by_name(cpu_type));
  
-return ppc_default->pvr_match(ppc_default, ppc->pvr);

+return ppc_default->pvr_match(ppc_default, ppc->pvr, false);
  }
  
  static void pnv_ipmi_bt_init(ISABus *bus, IPMIBmc *bmc, uint32_t irq)

diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index ad7e3c3db9..89ff88f28c 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -158,7 +158,11 @@ struct PowerPCCPUClass {
  void (*parent_parse_features)(const char *type, char *str, Error **errp);
  
  uint32_t pvr;

-bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr);
+/*
+ * If @best is false, match if pcc is in the family of pvr
+ * Else match only if pcc is the best match for pvr in this family.
+ */
+bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr, bool best);
  uint64_t pcr_mask;  /* Available bits in PCR register */
  uint64_t pcr_supported; /* Bits for supported PowerISA versions */
  uint32_t svr;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index d1493a660c..899c4a586e 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5912,15 +5912,25 @@ static void init_proc_POWER7(CPUPPCState *env)
  ppcPOWER7_irq_init(env_archcpu(env));
  }
  
-static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)

+static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr, bool best)
  {
-if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
-return true;
+uint32_t base = pvr & CPU_POWERPC_POWER_SERVER_MASK;
+uint32_t pcc_base = pcc->pvr & CPU_POWERPC_POWER_SERVER_MASK;
+
+if (!best) {
+if (base == CPU_POWERPC_POWER7_BASE) {
+return true;
+}
+if (base == CPU_POWERPC_POWER7P_BASE) {
+return true;
+}
  }
-if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
-return true;
+
+if (base != pcc_base) {
+return false;
  }
-return false;
+
+return true;
  }
  
  static bool cpu_has_work_POWER7(CPUState *cs)

@@ -6073,18 +6083,27 @@ static void init_proc_POWER8(CPUPPCState *env)
  ppcPOWER7_irq_init(env_archcpu(env));
  }
  
-static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)

+static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best)
  {
-if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
-return true;
-}
-if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
-return true;
+uint32_t base = pvr & CPU_POWERPC_POWER_SERVER_MASK;
+uint32_t pcc_base = pcc->pvr & CPU_POWERPC_POWER_SERVER_MASK;
+
+if (!best) {
+if (base == CPU_POWERPC_POWER8_BASE) {
+return true;
+}
+if (base == CPU_POWERPC_POWER8E_BASE) 

Re: [PATCH v5 0/4] linux-user: Fix siginfo_t contents when jumping to non-readable pages

2022-08-17 Thread Ilya Leoshkevich
On Wed, 2022-08-17 at 11:23 -0500, Richard Henderson wrote:
> On 8/17/22 10:05, Ilya Leoshkevich wrote:
> > Hi,
> > 
> > I noticed that when we get a SEGV due to jumping to non-readable
> > memory, sometimes si_addr and program counter in siginfo_t are
> > slightly
> > off. I tracked this down to the assumption that translators stop
> > before
> > the end of a page, while in reality they may stop right after it.
> > 
> > Patch 1 fixes an invalidation issue, which may prevent SEGV from
> > happening altogether.
> > Patches 2-3 fix the main issue on x86_64 and s390x. Many other
> > architectures have fixed-size instructions and are not affected.
> > Patch 4 adds tests.
> > 
> > Note: this series depends on [1].
> 
> Hah.  I was just thinking that I should queue your patch set to tcg-
> next-7.2, and then 
> rebase my stuff off of that.  It would ensure that I have your test
> cases in tree so that 
> I don't keep regressing them on you.  :-)
> 
> I'll cherry pick the one patch you're depending on.
> 
> 
> r~

I just checked and cherry-picking [1] and [2] before this series
should be enough.

[1] https://lists.gnu.org/archive/html/qemu-devel/2022-08/msg02462.html
[2] https://lists.gnu.org/archive/html/qemu-devel/2022-08/msg02461.html



[PATCH v3 31/31] ppc4xx_sdram: QOM'ify

2022-08-17 Thread BALATON Zoltan
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 
---
v3: Missed removing the prototype of ppc4xx_sdram_init
rest of series is unchanged so only resent this patch

 hw/ppc/ppc405.h |  3 +-
 hw/ppc/ppc405_uc.c  | 22 +-
 hw/ppc/ppc440_bamboo.c  | 10 +++--
 hw/ppc/ppc4xx_devs.c| 89 +++--
 include/hw/ppc/ppc4xx.h | 27 +++--
 5 files changed, 93 insertions(+), 58 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, 14));
 /* Enable SDRAM memory 

Re: [PULL 0/9] pc,virtio: fixes

2022-08-17 Thread Michael S. Tsirkin
On Wed, Aug 17, 2022 at 12:12:03PM -0400, Michael S. Tsirkin wrote:
> The following changes since commit c7208a6e0d049f9e8af15df908168a79b1f99685:
> 
>   Update version for v7.1.0-rc3 release (2022-08-16 20:45:19 -0500)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> 
> for you to fetch changes up to ae1f6ccc9dd42981fb26ac3839751d450a85a838:
> 
>   tests: acpi: silence applesmc warning about invalid key (2022-08-17 
> 12:11:05 -0400)


Oops fat fingers. Sorry. Will send a fixed v2 asap.

> 
> pc,virtio: fixes
> 
> Several bugfixes, they all look very safe to me. Revert
> seed support since we aren't any closer to a proper fix.
> 
> Signed-off-by: Michael S. Tsirkin 
> 
> 
> Alex Bennée (3):
>   hw/virtio: gracefully handle unset vhost_dev vdev
>   hw/virtio: handle un-configured shutdown in virtio-pci
>   hw/virtio: fix vhost_user_read tracepoint
> 
> Gerd Hoffmann (1):
>   x86: disable rng seeding via setup_data
> 
> Igor Mammedov (1):
>   tests: acpi: silence applesmc warning about invalid key
> 
> Jonathan Cameron (3):
>   hw/cxl: Add stub write function for RO MemoryRegionOps entries.
>   hw/cxl: Fix Get LSA input payload size which should be 8 bytes.
>   hw/cxl: Correctly handle variable sized mailbox input payloads.
> 
> Stefan Hajnoczi (1):
>   virtio-scsi: fix race in virtio_scsi_dataplane_start()
> 
>  hw/block/dataplane/virtio-blk.c |  5 +
>  hw/cxl/cxl-device-utils.c   | 12 +---
>  hw/cxl/cxl-mailbox-utils.c  |  4 ++--
>  hw/i386/microvm.c   |  2 +-
>  hw/i386/pc_piix.c   |  2 +-
>  hw/i386/pc_q35.c|  2 +-
>  hw/scsi/virtio-scsi-dataplane.c | 11 ---
>  hw/virtio/vhost-user.c  |  4 ++--
>  hw/virtio/vhost.c   | 10 +++---
>  hw/virtio/virtio-pci.c  |  9 +++--
>  tests/qtest/bios-tables-test.c  |  4 +++-
>  11 files changed, 46 insertions(+), 19 deletions(-)




[PATCH 2/2] tests/tcg/ppc64le: Added an underflow with UE=1 test

2022-08-17 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

Added a test to see if the adjustment is being made correctly when an
underflow occurs and UE is set.

Signed-off-by: Lucas Mateus Castro (alqotel) 
---
This patch will also fail without the underflow with UE set bugfix
Message-Id:<20220805141522.412864-3-lucas.ara...@eldorado.org.br>
---
 tests/tcg/ppc64/Makefile.target   |  1 +
 tests/tcg/ppc64le/Makefile.target |  1 +
 tests/tcg/ppc64le/ue_excp.c   | 54 +++
 3 files changed, 56 insertions(+)
 create mode 100644 tests/tcg/ppc64le/ue_excp.c

diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target
index 43958ad87b..583677031b 100644
--- a/tests/tcg/ppc64/Makefile.target
+++ b/tests/tcg/ppc64/Makefile.target
@@ -30,5 +30,6 @@ run-plugin-sha512-vector-with-%: QEMU_OPTS+=-cpu POWER10
 PPC64_TESTS += signal_save_restore_xer
 PPC64_TESTS += xxspltw
 PPC64_TESTS += oe_excp
+PPC64_TESTS += ue_excp
 
 TESTS += $(PPC64_TESTS)
diff --git a/tests/tcg/ppc64le/Makefile.target 
b/tests/tcg/ppc64le/Makefile.target
index 8d11ac731d..b9e689c582 100644
--- a/tests/tcg/ppc64le/Makefile.target
+++ b/tests/tcg/ppc64le/Makefile.target
@@ -28,5 +28,6 @@ PPC64LE_TESTS += mffsce
 PPC64LE_TESTS += signal_save_restore_xer
 PPC64LE_TESTS += xxspltw
 PPC64LE_TESTS += oe_excp
+PPC64LE_TESTS += ue_excp
 
 TESTS += $(PPC64LE_TESTS)
diff --git a/tests/tcg/ppc64le/ue_excp.c b/tests/tcg/ppc64le/ue_excp.c
new file mode 100644
index 00..b25ba1f803
--- /dev/null
+++ b/tests/tcg/ppc64le/ue_excp.c
@@ -0,0 +1,54 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define FP_UE (1ull << 5)
+#define MTFSF(FLM, FRB) asm volatile ("mtfsf %0, %1" :: "i" (FLM), "f" (FRB))
+
+void sigfpe_handler(int sig, siginfo_t *si, void *ucontext)
+{
+uint64_t t;
+uint64_t ch = 0x1b64f1c1b000ull;
+asm (
+"stfd 2, %0\n\t"
+: "=m"(t)
+:
+: "memory", "fr2"
+);
+if (t == ch) {
+exit(0);
+}
+fprintf(stderr, "expected result: %lx\n result: %lx\n", ch, t);
+exit(1);
+}
+
+int main()
+{
+uint64_t fpscr;
+uint64_t a = 0x5ca8ull;
+uint64_t b = 0x1cefull;
+
+struct sigaction sa = {
+.sa_sigaction = sigfpe_handler,
+.sa_flags = SA_SIGINFO
+};
+
+prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE);
+sigaction(SIGFPE, , NULL);
+
+fpscr = FP_UE;
+MTFSF(0b, fpscr);
+
+asm (
+"lfd 0, %0\n\t"
+"lfd 1, %1\n\t"
+"fmul 2, 0, 1\n\t"
+:
+: "m"(a), "m"(b)
+: "memory", "fr0", "fr1", "fr2"
+);
+
+return -1;
+}
-- 
2.31.1




[PATCH 1/2] tests/tcg/ppc64le: Added an overflow with OE=1 test

2022-08-17 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

Added a test to see if the adjustment is being made correctly when an
overflow occurs and OE is set.

Signed-off-by: Lucas Mateus Castro (alqotel) 
---
The prctl patch is not ready yet, so this patch does as Richard
Henderson suggested and check the fp register in the signal handler

This patch will fail without the overflow with OE set bugfix
Message-Id:<20220805141522.412864-3-lucas.ara...@eldorado.org.br>
---
 tests/tcg/ppc64/Makefile.target   |  1 +
 tests/tcg/ppc64le/Makefile.target |  1 +
 tests/tcg/ppc64le/oe_excp.c   | 54 +++
 3 files changed, 56 insertions(+)
 create mode 100644 tests/tcg/ppc64le/oe_excp.c

diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target
index 331fae628e..43958ad87b 100644
--- a/tests/tcg/ppc64/Makefile.target
+++ b/tests/tcg/ppc64/Makefile.target
@@ -29,5 +29,6 @@ run-plugin-sha512-vector-with-%: QEMU_OPTS+=-cpu POWER10
 
 PPC64_TESTS += signal_save_restore_xer
 PPC64_TESTS += xxspltw
+PPC64_TESTS += oe_excp
 
 TESTS += $(PPC64_TESTS)
diff --git a/tests/tcg/ppc64le/Makefile.target 
b/tests/tcg/ppc64le/Makefile.target
index 6ca3003f02..8d11ac731d 100644
--- a/tests/tcg/ppc64le/Makefile.target
+++ b/tests/tcg/ppc64le/Makefile.target
@@ -27,5 +27,6 @@ PPC64LE_TESTS += mtfsf
 PPC64LE_TESTS += mffsce
 PPC64LE_TESTS += signal_save_restore_xer
 PPC64LE_TESTS += xxspltw
+PPC64LE_TESTS += oe_excp
 
 TESTS += $(PPC64LE_TESTS)
diff --git a/tests/tcg/ppc64le/oe_excp.c b/tests/tcg/ppc64le/oe_excp.c
new file mode 100644
index 00..cfc364f5ed
--- /dev/null
+++ b/tests/tcg/ppc64le/oe_excp.c
@@ -0,0 +1,54 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define FP_OE (1ull << 6)
+#define MTFSF(FLM, FRB) asm volatile ("mtfsf %0, %1" :: "i" (FLM), "f" (FRB))
+
+void sigfpe_handler(int sig, siginfo_t *si, void *ucontext)
+{
+uint64_t t;
+uint64_t ch = 0x5fcfffe4965a17e0ull;
+asm (
+"stfd 2, %0\n\t"
+: "=m"(t)
+:
+: "memory", "fr2"
+);
+if (t == ch) {
+exit(0);
+}
+fprintf(stderr, "expected result: %lx\n result: %lx\n", ch, t);
+exit(1);
+}
+
+int main()
+{
+uint64_t fpscr;
+uint64_t a = 0x7fdfffe816d77b00ull;
+uint64_t b = 0x7fdfffFC7F7FFF00ull;
+
+struct sigaction sa = {
+.sa_sigaction = sigfpe_handler,
+.sa_flags = SA_SIGINFO
+};
+
+prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE);
+sigaction(SIGFPE, , NULL);
+
+fpscr = FP_OE;
+MTFSF(0b, fpscr);
+
+asm (
+"lfd 0, %0\n\t"
+"lfd 1, %1\n\t"
+"fmul 2, 0, 1\n\t"
+:
+: "m"(a), "m"(b)
+: "memory", "fr0", "fr1", "fr2"
+);
+
+return -1;
+}
-- 
2.31.1




Re: [RFC PATCH v2 4/8] qapi: golang: Generate qapi's union types in Go

2022-08-17 Thread Victor Toso
On Wed, Jul 06, 2022 at 10:48:06AM +0100, Daniel P. Berrangé wrote:
> On Wed, Jul 06, 2022 at 10:37:54AM +0100, Daniel P. Berrangé wrote:
> > On Wed, Jul 06, 2022 at 04:28:16AM -0500, Andrea Bolognani wrote:
> > > You're right, that is undesirable. What about something like this?
> > >
> > >   type GuestPanicInformation struct {
> > >   HyperV *GuestPanicInformationHyperV
> > >   S390   *GuestPanicInformationS390
> > >   }
> > >
> > >   type jsonGuestPanicInformation struct {
> > >   Discriminator string   `json:"type"`
> > >   HyperV*GuestPanicInformationHyperV `json:"hyper-v"`
> > >   S390  *GuestPanicInformationS390   `json:"s390"`
> > >   }
> >
> > It can possibly be even simpler with just embedding the real
> > struct
> >
> >type jsonGuestPanicInformation struct {
> >Discriminator string
> >GuestPanicInformation
> >}

Similar to what I said in previous email (same thread) to Andrea,
this would not work because the end result does not match with
QAPI spec, where HyperV or S390 fields should be at the same
level as 'type'.

If we embed either HyperV or S390, then it should work, like:

tmp := struct {
GuestPanicInformationHyperV
Discriminator string "type"
}{}

But I intend to try the json.RawMessage too as with description
it seems like we can avoid looking the whole json data twice.

> > >   func (s GuestPanicInformation) MarshalJSON() ([]byte, error) {
> > >   if (s.HyperV != nil && s.S390 != nil) ||
> > >   (s.HyperV == nil && s.S390 == nil) {
> > >   // client hasn't filled in the struct properly
> > >   return nil, errors.New("...")
> > >   }
> > > 
> > >   tmp := jsonGuestPanicInformation{}
> > > 
> > >   if s.HyperV != nil {
> > >   tmp.Discriminator = "hyper-v"
> > >   tmp.HyperV = s.HyperV
> > >   } else if s.S390 != nil {
> > >   tmp.Discriminator = "s390"
> > >   tmp.S390 = s.S390
> > >   }
> > > 
> > >   return json.Marshal(tmp)
> > >   }
> > 
> > And...
> > 
> >var discriminator string
> >if s.HyperV != nil {
> >discriminator = "hyper-v"
> >} else if s.S390 != nil {
> >discriminator = "s390"
> >}
> > 
> >tmp := jsonGuestPanicInformation{ discriminator, s}
> >return json.Marshal(tmp)
> > 
> > > 
> > >   func (s *GuestPanicInformation) UnmarshalJSON(data []byte) error {
> > >   tmp := jsonGuestPanicInformation{}
> > > 
> > >   err := json.Unmarshal(data, )
> > >   if err != nil {
> > >   return err
> > >   }
> > > 
> > >   switch tmp.Discriminator {
> > >   case "hyper-v":
> > >   if tmp.HyperV == nil {
> > >   return errors.New("...")
> > >   }
> > >   s.HyperV = tmp.HyperV
> > >   case "s390":
> > >   if tmp.S390 == nil {
> > >   return errors.New("...")
> > >   }
> > >   s.S390 = tmp.S390
> > >   }
> >
> > I'm not actually sure this works, because the first json.Unmarshal
> > call won't know which branch to try unmarhsalling. So it might be
> > unavoidable to parse twice.  With the XML parser this wouldn't be
> > a problem as it has separated the parse phase and then fills the
> > struct after.
> 
> Right afer sending, I remember how this is supposed to be done. It
> involves use of 'json.RawMessage' eg examples at:
> 
>   https://pkg.go.dev/encoding/json#example-RawMessage-Unmarshal
> 
> So it would look like:
> 
>type GuestPanicInformation struct {
>HyperV *GuestPanicInformationHyperV
>S390   *GuestPanicInformationS390
>}
>  
>type jsonGuestPanicInformation struct {
>Discriminator string   `json:"type"`
>Payload *json.RawMessage
>}
> 
> 
> func (s GuestPanicInformation) MarshalJSON() ([]byte, error) {
> var p *json.RawMesage
> var err error
> if s.HyperV != nil {
> d = "hyper-v"
> p, err = json.Marshal(s.HyperV)
> } else if s.S390 != nil {
> d = "s390"
> p, err = json.Marshal(s.S390)
> } else {
>   err = fmt.Errorf("No payload defined")
>   }
> if err != nil {
> return []byte{}, err
> }
>   
> return json.Marshal(jsonGuestPanicInformation{d, p}), nil
> }
> 
> 
>  
>func (s *GuestPanicInformation) UnmarshalJSON(data []byte) error {
>tmp := jsonGuestPanicInformation{}
>  
>err := json.Unmarshal(data, )
>if err != nil {
>return err
>}
>  
>switch tmp.Discriminator {
>case "hyper-v":
>s.HyperV := GuestPanicInformationHyperV{}
>err := json.Unmarshal(tmp.Payload, s.HyperV)
>if err != nil {
>   return err
>}
>case "s390":
>s.S390 := GuestPanicInformationS390{}
>err := 

Re: [BUG] cxl can not create region

2022-08-17 Thread Jonathan Cameron via
On Thu, 11 Aug 2022 17:46:55 -0700
Dan Williams  wrote:

> Dan Williams wrote:
> > Bobo WL wrote:  
> > > Hi Dan,
> > > 
> > > Thanks for your reply!
> > > 
> > > On Mon, Aug 8, 2022 at 11:58 PM Dan Williams  
> > > wrote:  
> > > >
> > > > What is the output of:
> > > >
> > > > cxl list -MDTu -d decoder0.0
> > > >
> > > > ...? It might be the case that mem1 cannot be mapped by decoder0.0, or
> > > > at least not in the specified order, or that validation check is 
> > > > broken.  
> > > 
> > > Command "cxl list -MDTu -d decoder0.0" output:  
> > 
> > Thanks for this, I think I know the problem, but will try some
> > experiments with cxl_test first.  
> 
> Hmm, so my cxl_test experiment unfortunately passed so I'm not
> reproducing the failure mode. This is the result of creating x4 region
> with devices directly attached to a single host-bridge:
> 
> # cxl create-region -d decoder3.5 -w 4 -m -g 256 mem{12,10,9,11} -s $((1<<30))
> {
>   "region":"region8",
>   "resource":"0xf1f000",
>   "size":"1024.00 MiB (1073.74 MB)",
>   "interleave_ways":4,
>   "interleave_granularity":256,
>   "decode_state":"commit",
>   "mappings":[
> {
>   "position":3,
>   "memdev":"mem11",
>   "decoder":"decoder21.0"
> },
> {
>   "position":2,
>   "memdev":"mem9",
>   "decoder":"decoder19.0"
> },
> {
>   "position":1,
>   "memdev":"mem10",
>   "decoder":"decoder20.0"
> },
> {
>   "position":0,
>   "memdev":"mem12",
>   "decoder":"decoder22.0"
> }
>   ]
> }
> cxl region: cmd_create_region: created 1 region
> 
> > Did the commit_store() crash stop reproducing with latest cxl/preview
> > branch?  
> 
> I missed the answer to this question.
> 
> All of these changes are now in Linus' tree perhaps give that a try and
> post the debug log again?

Hi Dan,

I've moved onto looking at this one.
1 HB, 2RP (to make it configure the HDM decoder in the QEMU HB, I'll tidy that 
up
at some stage), 1 switch, 4 downstream switch ports each with a type 3

I'm not getting a crash, but can't successfully setup a region.
Upon adding the final target
It's failing in check_last_peer() as pos < distance.
Seems distance is 4 which makes me think it's using the wrong level of the 
heirarchy for
some reason or that distance check is wrong.
Wasn't a good idea to just skip that step though as it goes boom - though
stack trace is not useful.

Jonathan









[PULL 08/10] hw/cxl: Correctly handle variable sized mailbox input payloads.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

A placeholder of ~0 is used to indicate variable payload size.
Whilst the checks for output payload correctly took this into
account, those for input payload did not.

This results in failure of the Set LSA command.

Fixes: 464e14ac43 ("hw/cxl/device: Implement basic mailbox (8.2.8.4)")
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-4-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-mailbox-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 3cea8b17a8..bc1bb18844 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -425,7 +425,7 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
 cxl_cmd = _cmd_set[set][cmd];
 h = cxl_cmd->handler;
 if (h) {
-if (len == cxl_cmd->in) {
+if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
 cxl_cmd->payload = cxl_dstate->mbox_reg_state +
 A_CXL_DEV_CMD_PAYLOAD;
 ret = (*h)(cxl_cmd, cxl_dstate, );
-- 
MST




[PATCH] target/s390x: Fix CLFIT and CLGIT immediate size

2022-08-17 Thread Ilya Leoshkevich
I2 is 16 bits, not 32.

Found by running valgrind's none/tests/s390x/traps.

Fixes: 1c2687518235 ("target-s390: Implement COMPARE AND TRAP")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/insn-data.def | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def
index 5e448bb2c4..6d2cfe5fa2 100644
--- a/target/s390x/tcg/insn-data.def
+++ b/target/s390x/tcg/insn-data.def
@@ -290,8 +290,8 @@
 D(0xb961, CLGRT,   RRF_c, GIE, r1_o, r2_o, 0, 0, ct, 0, 1)
 D(0xeb23, CLT, RSY_b, MIE, r1_32u, m2_32u, 0, 0, ct, 0, 1)
 D(0xeb2b, CLGT,RSY_b, MIE, r1_o, m2_64, 0, 0, ct, 0, 1)
-D(0xec73, CLFIT,   RIE_a, GIE, r1_32u, i2_32u, 0, 0, ct, 0, 1)
-D(0xec71, CLGIT,   RIE_a, GIE, r1_o, i2_32u, 0, 0, ct, 0, 1)
+D(0xec73, CLFIT,   RIE_a, GIE, r1_32u, i2_16u, 0, 0, ct, 0, 1)
+D(0xec71, CLGIT,   RIE_a, GIE, r1_o, i2_16u, 0, 0, ct, 0, 1)
 
 /* CONVERT TO DECIMAL */
 C(0x4e00, CVD, RX_a,  Z,   r1_o, a2, 0, 0, cvd, 0)
-- 
2.37.1




[PULL 02/10] hw/virtio: gracefully handle unset vhost_dev vdev

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

I've noticed asserts firing because we query the status of vdev after
a vhost connection is closed down. Rather than faulting on the NULL
indirect just quietly reply false.

Signed-off-by: Alex Bennée 
Message-Id: <20220728135503.1060062-3-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 0827d631c0..f758f177bb 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -306,7 +306,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev 
*dev, uint64_t size)
 dev->log_size = size;
 }
 
-static int vhost_dev_has_iommu(struct vhost_dev *dev)
+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
 {
 VirtIODevice *vdev = dev->vdev;
 
@@ -316,8 +316,12 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
  * does not have IOMMU, there's no need to enable this feature
  * which may cause unnecessary IOTLB miss/update transactions.
  */
-return virtio_bus_device_iommu_enabled(vdev) &&
-   virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+if (vdev) {
+return virtio_bus_device_iommu_enabled(vdev) &&
+virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+} else {
+return false;
+}
 }
 
 static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
-- 
MST




[PULL 06/10] hw/cxl: Add stub write function for RO MemoryRegionOps entries.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

There is no checking on the availability of a write callback.
Hence QEMU crashes if a write does occur to one of these regions.

Discovered whilst chasing a Linux kernel bug that incorrectly
wrote into one of these regions.

Fixes: 6364adacdf ("hw/cxl/device: Implement the CAP array (8.2.8.1-2)")
Reported-by: Bobo WL 
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-2-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-device-utils.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 687759b301..83ce7a8270 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -141,9 +141,15 @@ static uint64_t mdev_reg_read(void *opaque, hwaddr offset, 
unsigned size)
 return retval;
 }
 
+static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
+   unsigned size)
+{
+/* Many register sets are read only */
+}
+
 static const MemoryRegionOps mdev_ops = {
 .read = mdev_reg_read,
-.write = NULL, /* memory device register is read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
@@ -173,7 +179,7 @@ static const MemoryRegionOps mailbox_ops = {
 
 static const MemoryRegionOps dev_ops = {
 .read = dev_reg_read,
-.write = NULL, /* status register is read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
@@ -188,7 +194,7 @@ static const MemoryRegionOps dev_ops = {
 
 static const MemoryRegionOps caps_ops = {
 .read = caps_reg_read,
-.write = NULL, /* caps registers are read only */
+.write = ro_reg_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
-- 
MST




Re: [PATCH v5 0/4] linux-user: Fix siginfo_t contents when jumping to non-readable pages

2022-08-17 Thread Richard Henderson

On 8/17/22 10:05, Ilya Leoshkevich wrote:

Hi,

I noticed that when we get a SEGV due to jumping to non-readable
memory, sometimes si_addr and program counter in siginfo_t are slightly
off. I tracked this down to the assumption that translators stop before
the end of a page, while in reality they may stop right after it.

Patch 1 fixes an invalidation issue, which may prevent SEGV from
happening altogether.
Patches 2-3 fix the main issue on x86_64 and s390x. Many other
architectures have fixed-size instructions and are not affected.
Patch 4 adds tests.

Note: this series depends on [1].


Hah.  I was just thinking that I should queue your patch set to tcg-next-7.2, and then 
rebase my stuff off of that.  It would ensure that I have your test cases in tree so that 
I don't keep regressing them on you.  :-)


I'll cherry pick the one patch you're depending on.


r~



[PULL 05/10] x86: disable rng seeding via setup_data

2022-08-17 Thread Michael S. Tsirkin
From: Gerd Hoffmann 

Causes regressions when doing direct kernel boots with OVMF.

At this point in the release cycle the only sensible action
is to just disable this for 7.1 and sort it properly in the
7.2 devel cycle.

Cc: Jason A. Donenfeld 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Laurent Vivier 
Signed-off-by: Gerd Hoffmann 
Message-Id: <20220817083940.3174933-1-kra...@redhat.com>
Cc: Jason A. Donenfeld 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Peter Maydell 
Cc: Philippe Mathieu-Daudé 
Cc: Laurent Vivier 
Signed-off-by: Gerd Hoffmann 
---
 hw/i386/microvm.c | 2 +-
 hw/i386/pc_piix.c | 2 +-
 hw/i386/pc_q35.c  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 7fe8cce03e..52cafa003d 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -332,7 +332,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
 rom_set_fw(fw_cfg);
 
 if (machine->kernel_filename != NULL) {
-x86_load_linux(x86ms, fw_cfg, 0, true, false);
+x86_load_linux(x86ms, fw_cfg, 0, true, true);
 }
 
 if (mms->option_roms) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a5c65c1c35..20962c34e7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -439,6 +439,7 @@ static void pc_i440fx_7_1_machine_options(MachineClass *m)
 m->alias = "pc";
 m->is_default = true;
 pcmc->default_cpu_version = 1;
+pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL,
@@ -450,7 +451,6 @@ static void pc_i440fx_7_0_machine_options(MachineClass *m)
 pc_i440fx_7_1_machine_options(m);
 m->alias = NULL;
 m->is_default = false;
-pcmc->legacy_no_rng_seed = true;
 pcmc->enforce_amd_1tb_hole = false;
 compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
 compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 3a35193ff7..2e5dae9a89 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -376,6 +376,7 @@ static void pc_q35_7_1_machine_options(MachineClass *m)
 pc_q35_machine_options(m);
 m->alias = "q35";
 pcmc->default_cpu_version = 1;
+pcmc->legacy_no_rng_seed = true;
 }
 
 DEFINE_Q35_MACHINE(v7_1, "pc-q35-7.1", NULL,
@@ -386,7 +387,6 @@ static void pc_q35_7_0_machine_options(MachineClass *m)
 PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
 pc_q35_7_1_machine_options(m);
 m->alias = NULL;
-pcmc->legacy_no_rng_seed = true;
 pcmc->enforce_amd_1tb_hole = false;
 compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
 compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
-- 
MST




[PULL 01/10] virtio-scsi: fix race in virtio_scsi_dataplane_start()

2022-08-17 Thread Michael S. Tsirkin
From: Stefan Hajnoczi 

As soon as virtio_scsi_data_plane_start() attaches host notifiers the
IOThread may start virtqueue processing. There is a race between
IOThread virtqueue processing and virtio_scsi_data_plane_start() because
it only assigns s->dataplane_started after attaching host notifiers.

When a virtqueue handler function in the IOThread calls
virtio_scsi_defer_to_dataplane() it may see !s->dataplane_started and
attempt to start dataplane even though we're already in the IOThread:

  #0  0x7f67b360857c __pthread_kill_implementation (libc.so.6 + 0xa257c)
  #1  0x7f67b35bbd56 raise (libc.so.6 + 0x55d56)
  #2  0x7f67b358e833 abort (libc.so.6 + 0x28833)
  #3  0x7f67b358e75b __assert_fail_base.cold (libc.so.6 + 0x2875b)
  #4  0x7f67b35b4cd6 __assert_fail (libc.so.6 + 0x4ecd6)
  #5  0x55ca87fd411b memory_region_transaction_commit (qemu-kvm + 0x67511b)
  #6  0x55ca87e17811 virtio_pci_ioeventfd_assign (qemu-kvm + 0x4b8811)
  #7  0x55ca87e14836 virtio_bus_set_host_notifier (qemu-kvm + 0x4b5836)
  #8  0x55ca87f8e14e virtio_scsi_set_host_notifier (qemu-kvm + 0x62f14e)
  #9  0x55ca87f8dd62 virtio_scsi_dataplane_start (qemu-kvm + 0x62ed62)
  #10 0x55ca87e14610 virtio_bus_start_ioeventfd (qemu-kvm + 0x4b5610)
  #11 0x55ca87f8c29a virtio_scsi_handle_ctrl (qemu-kvm + 0x62d29a)
  #12 0x55ca87fa5902 virtio_queue_host_notifier_read (qemu-kvm + 0x646902)
  #13 0x55ca882c099e aio_dispatch_handler (qemu-kvm + 0x96199e)
  #14 0x55ca882c1761 aio_poll (qemu-kvm + 0x962761)
  #15 0x55ca880e1052 iothread_run (qemu-kvm + 0x782052)
  #16 0x55ca882c562a qemu_thread_start (qemu-kvm + 0x96662a)

This patch assigns s->dataplane_started before attaching host notifiers
so that virtqueue handler functions that run in the IOThread before
virtio_scsi_data_plane_start() returns correctly identify that dataplane
does not need to be started. This fix is taken from the virtio-blk
dataplane code and it's worth adding a comment in virtio-blk as well to
explain why it works.

Note that s->dataplane_started does not need the AioContext lock because
it is set before attaching host notifiers and cleared after detaching
host notifiers. In other words, the IOThread always sees the value true
and the main loop thread does not modify it while the IOThread is
active.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2099541
Reported-by: Qing Wang 
Signed-off-by: Stefan Hajnoczi 
Message-Id: <20220808162134.240405-1-stefa...@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/dataplane/virtio-blk.c |  5 +
 hw/scsi/virtio-scsi-dataplane.c | 11 ---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 49276e46f2..26f965cabc 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -219,6 +219,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
 
 memory_region_transaction_commit();
 
+/*
+ * These fields are visible to the IOThread so we rely on implicit barriers
+ * in aio_context_acquire() on the write side and aio_notify_accept() on
+ * the read side.
+ */
 s->starting = false;
 vblk->dataplane_started = true;
 trace_virtio_blk_data_plane_start(s);
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 8bb6e6acfc..20bb91766e 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -136,6 +136,14 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
 
 memory_region_transaction_commit();
 
+/*
+ * These fields are visible to the IOThread so we rely on implicit barriers
+ * in aio_context_acquire() on the write side and aio_notify_accept() on
+ * the read side.
+ */
+s->dataplane_starting = false;
+s->dataplane_started = true;
+
 aio_context_acquire(s->ctx);
 virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx);
 virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx);
@@ -143,9 +151,6 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
 for (i = 0; i < vs->conf.num_queues; i++) {
 virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx);
 }
-
-s->dataplane_starting = false;
-s->dataplane_started = true;
 aio_context_release(s->ctx);
 return 0;
 
-- 
MST




[PATCH for-7.2] hw/usb/hcd-xhci: Check whether DMA accesses fail

2022-08-17 Thread Thomas Huth
If a guest sets up bad descriptors, it could force QEMU to access
non-existing memory regions. Thus we should check the return value
of dma_memory_read/write() to make sure that these errors don't go
unnoticed.

Signed-off-by: Thomas Huth 
---
 hw/usb/hcd-xhci.c | 64 +++
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 3c48b58dde..acd60b1a49 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -463,6 +463,12 @@ static void xhci_mfwrap_timer(void *opaque)
 xhci_mfwrap_update(xhci);
 }
 
+static void xhci_die(XHCIState *xhci)
+{
+xhci->usbsts |= USBSTS_HCE;
+DPRINTF("xhci: asserted controller error\n");
+}
+
 static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high)
 {
 if (sizeof(dma_addr_t) == 4) {
@@ -488,7 +494,14 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, 
dma_addr_t addr,
 
 assert((len % sizeof(uint32_t)) == 0);
 
-dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_read(xhci->as, addr, buf, len,
+MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+  __func__);
+memset(buf, 0xff, len);
+xhci_die(xhci);
+return;
+}
 
 for (i = 0; i < (len / sizeof(uint32_t)); i++) {
 buf[i] = le32_to_cpu(buf[i]);
@@ -496,7 +509,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, 
dma_addr_t addr,
 }
 
 static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
-   uint32_t *buf, size_t len)
+   const uint32_t *buf, size_t len)
 {
 int i;
 uint32_t tmp[5];
@@ -508,7 +521,13 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci, 
dma_addr_t addr,
 for (i = 0; i < n; i++) {
 tmp[i] = cpu_to_le32(buf[i]);
 }
-dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_write(xhci->as, addr, tmp, len,
+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+  __func__);
+xhci_die(xhci);
+return;
+}
 }
 
 static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
@@ -593,12 +612,6 @@ static inline int xhci_running(XHCIState *xhci)
 return !(xhci->usbsts & USBSTS_HCH);
 }
 
-static void xhci_die(XHCIState *xhci)
-{
-xhci->usbsts |= USBSTS_HCE;
-DPRINTF("xhci: asserted controller error\n");
-}
-
 static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
 {
 XHCIInterrupter *intr = >intr[v];
@@ -619,7 +632,12 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent 
*event, int v)
ev_trb.status, ev_trb.control);
 
 addr = intr->er_start + TRB_SIZE*intr->er_ep_idx;
-dma_memory_write(xhci->as, addr, _trb, TRB_SIZE, 
MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_write(xhci->as, addr, _trb, TRB_SIZE,
+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+  __func__);
+xhci_die(xhci);
+}
 
 intr->er_ep_idx++;
 if (intr->er_ep_idx >= intr->er_size) {
@@ -680,8 +698,12 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing 
*ring, XHCITRB *trb,
 
 while (1) {
 TRBType type;
-dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
-MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
+MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+  __func__);
+return 0;
+}
 trb->addr = ring->dequeue;
 trb->ccs = ring->ccs;
 le64_to_cpus(>parameter);
@@ -798,8 +820,14 @@ static void xhci_er_reset(XHCIState *xhci, int v)
 xhci_die(xhci);
 return;
 }
-dma_memory_read(xhci->as, erstba, , sizeof(seg),
-MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_read(xhci->as, erstba, , sizeof(seg),
+MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
+  __func__);
+xhci_die(xhci);
+return;
+}
+
 le32_to_cpus(_low);
 le32_to_cpus(_high);
 le32_to_cpus();
@@ -2415,8 +2443,12 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, 
uint64_t pctx)
 /* TODO: actually implement real values here */
 bw_ctx[0] = 0;
 memset(_ctx[1], 80, xhci->numports); /* 80% */
-dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
- MEMTXATTRS_UNSPECIFIED);
+if (dma_memory_write(xhci->as, ctx, bw_ctx, 

[PULL 09/10] tests: acpi: silence applesmc warning about invalid key

2022-08-17 Thread Michael S. Tsirkin
From: Igor Mammedov 

OSK value is irrelevant for ACPI test case.
Supply fake OSK explicitly to prevent QEMU complaining about
invalid key when it fallbacks to default_osk.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Igor Mammedov 
Message-Id: <20220728133713.1369596-1-imamm...@redhat.com>
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/qtest/bios-tables-test.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 359916c228..7c5f736b51 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1632,7 +1632,9 @@ static void test_acpi_q35_applesmc(void)
 .variant = ".applesmc",
 };
 
-test_acpi_one("-device isa-applesmc", );
+/* supply fake 64-byte OSK to silence missing key warning */
+test_acpi_one("-device isa-applesmc,osk=any64characterfakeoskisenough"
+  "topreventinvalidkeywarningsonstderr", );
 free_test_data();
 }
 
-- 
MST




Re: [PATCH for-7.2 14/21] accel/tcg: Hoist get_page_addr_code out of tb_lookup

2022-08-17 Thread Richard Henderson

On 8/17/22 09:07, Ilya Leoshkevich wrote:

Oh my.  Well, we could

(1) revert that patch because the premise is wrong,
(2) go with your per-tb clearing,
(3) clear the whole thing with cpu_tb_jmp_cache_clear

Ideally we'd have some benchmark numbers to inform the choice...


FWIW 6f1653180f570 still looks useful.
Reverting it caused 620.omnetpp_s to take ~4% more time.
I ran the benchmark with reduced values in omnetpp.ini so as not to
wait forever, therefore the real figures might be closer to what the
commit message says. In any case this still shows that the patch has
measurable impact.


Thanks for the testing.

I think option (3) will be best for user-only, because mprotect/munmap of existing code 
pages is rare -- usually only at process startup.



r~



[PULL 10/10] virtio-pci: don't touch pci on virtio reset

2022-08-17 Thread Michael S. Tsirkin
virtio level reset should not affect pci express
registers such as PM, error or link.

Fixes: 27ce0f3afc ("hw/virtio: fix Power Management Control Register for PCI 
Express virtio devices")
Fixes: d584f1b9ca ("hw/virtio: fix Link Control Register for PCI Express virtio 
devices")
Fixes: c2cabb3422 ("hw/virtio: fix error enabling flags in Device Control 
register")
Cc: "Marcel Apfelbaum" 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 5ce61f9b45..a50c5a57d7 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1947,7 +1947,6 @@ static void virtio_pci_reset(DeviceState *qdev)
 {
 VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
 VirtioBusState *bus = VIRTIO_BUS(>bus);
-PCIDevice *dev = PCI_DEVICE(qdev);
 int i;
 
 virtio_bus_reset(bus);
@@ -1960,6 +1959,13 @@ static void virtio_pci_reset(DeviceState *qdev)
 proxy->vqs[i].avail[0] = proxy->vqs[i].avail[1] = 0;
 proxy->vqs[i].used[0] = proxy->vqs[i].used[1] = 0;
 }
+}
+
+static void virtio_pci_bus_reset(DeviceState *qdev)
+{
+PCIDevice *dev = PCI_DEVICE(qdev);
+
+virtio_pci_reset(qdev);
 
 if (pci_is_express(dev)) {
 pcie_cap_deverr_reset(dev);
@@ -2027,7 +2033,7 @@ static void virtio_pci_class_init(ObjectClass *klass, 
void *data)
 k->class_id = PCI_CLASS_OTHERS;
 device_class_set_parent_realize(dc, virtio_pci_dc_realize,
 >parent_dc_realize);
-dc->reset = virtio_pci_reset;
+dc->reset = virtio_pci_bus_reset;
 }
 
 static const TypeInfo virtio_pci_info = {
-- 
MST




[PULL 07/10] hw/cxl: Fix Get LSA input payload size which should be 8 bytes.

2022-08-17 Thread Michael S. Tsirkin
From: Jonathan Cameron 

Get LSA needs 4 byte offset and 4 byte length arguments.
CXL rev 2.0 Table 178.

Fixes: 3ebe676a34 ("hw/cxl/device: Implement get/set Label Storage Area (LSA)")
Signed-off-by: Jonathan Cameron 
Message-Id: <20220817145759.32603-3-jonathan.came...@huawei.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/cxl/cxl-mailbox-utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index bb66c765a5..3cea8b17a8 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -406,7 +406,7 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
 cmd_identify_memory_device, 0, 0 },
 [CCLS][GET_PARTITION_INFO] = { "CCLS_GET_PARTITION_INFO",
 cmd_ccls_get_partition_info, 0, 0 },
-[CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 0, 0 },
+[CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 },
 [CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa,
 ~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
 };
-- 
MST




[PULL 00/10] pc,virtio: fixes

2022-08-17 Thread Michael S. Tsirkin
The following changes since commit c7208a6e0d049f9e8af15df908168a79b1f99685:

  Update version for v7.1.0-rc3 release (2022-08-16 20:45:19 -0500)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 019d2530a7cf082af01280a9ad265722a15601f9:

  virtio-pci: don't touch pci on virtio reset (2022-08-17 12:11:05 -0400)


pc,virtio: fixes

Several bugfixes, they all look very safe to me. Revert
seed support since we aren't any closer to a proper fix.

Signed-off-by: Michael S. Tsirkin 


Alex Bennée (3):
  hw/virtio: gracefully handle unset vhost_dev vdev
  hw/virtio: handle un-configured shutdown in virtio-pci
  hw/virtio: fix vhost_user_read tracepoint

Gerd Hoffmann (1):
  x86: disable rng seeding via setup_data

Igor Mammedov (1):
  tests: acpi: silence applesmc warning about invalid key

Jonathan Cameron (3):
  hw/cxl: Add stub write function for RO MemoryRegionOps entries.
  hw/cxl: Fix Get LSA input payload size which should be 8 bytes.
  hw/cxl: Correctly handle variable sized mailbox input payloads.

Michael S. Tsirkin (1):
  virtio-pci: don't touch pci on virtio reset

Stefan Hajnoczi (1):
  virtio-scsi: fix race in virtio_scsi_dataplane_start()

 hw/block/dataplane/virtio-blk.c |  5 +
 hw/cxl/cxl-device-utils.c   | 12 +---
 hw/cxl/cxl-mailbox-utils.c  |  4 ++--
 hw/i386/microvm.c   |  2 +-
 hw/i386/pc_piix.c   |  2 +-
 hw/i386/pc_q35.c|  2 +-
 hw/scsi/virtio-scsi-dataplane.c | 11 ---
 hw/virtio/vhost-user.c  |  4 ++--
 hw/virtio/vhost.c   | 10 +++---
 hw/virtio/virtio-pci.c  | 19 +++
 tests/qtest/bios-tables-test.c  |  4 +++-
 11 files changed, 54 insertions(+), 21 deletions(-)




[PULL 04/10] hw/virtio: fix vhost_user_read tracepoint

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

As reads happen in the callback we were never seeing them. We only
really care about the header so move the tracepoint to when the header
is complete.

Fixes: 6ca6d8ee9d (hw/virtio: add vhost_user_[read|write] trace points)
Signed-off-by: Alex Bennée 
Acked-by: Jason Wang 
Message-Id: <20220728135503.1060062-5-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost-user.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 75b8df21a4..bd24741be8 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -295,6 +295,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, 
VhostUserMsg *msg)
 return -EPROTO;
 }
 
+trace_vhost_user_read(msg->hdr.request, msg->hdr.flags);
+
 return 0;
 }
 
@@ -544,8 +546,6 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, 
uint64_t base,
 }
 }
 
-trace_vhost_user_read(msg.hdr.request, msg.hdr.flags);
-
 return 0;
 }
 
-- 
MST




Re: [PATCH] error handling: Use TFR() macro where applicable

2022-08-17 Thread Peter Maydell
On Wed, 17 Aug 2022 at 15:49, Nikita Ivanov  wrote:
>
> Well...
>
> What exactly is still under discussion? In my perspective, the main pitfalls 
> have been resolved:
>
> 0. All possible places where TFR() macro could be applied are covered.
> 1. Macro has been renamed in order to be more transparent. The name has been 
> chosen in comparison with a similar glibc macro.
> 2. The macro itself has been refactored, in order to replace it entirely with 
> glibc alternative.
> 3. Problems with statement/expressions differences in qemu and glibc 
> implementation have been resolved.
>
> Is there any room for improvement?

(a) do we want the statement version or the expression version?
(b) do we want "use the glibc one, with same-semantics version for
compatibility", or do we want "we have our own thing"?

I would have voted for following glibc, except that it does
that cast-to-long thing, which is incorrect behaviour when
long is 32 bits and the return value from the function being
tested is 64 bits.

thanks
-- PMM



Re: [RFC PATCH v2 4/8] qapi: golang: Generate qapi's union types in Go

2022-08-17 Thread Victor Toso
Hi,

On Wed, Jul 06, 2022 at 04:28:16AM -0500, Andrea Bolognani wrote:
> On Tue, Jul 05, 2022 at 05:35:26PM +0100, Daniel P. Berrangé wrote:
> > On Tue, Jul 05, 2022 at 08:45:30AM -0700, Andrea Bolognani wrote:
> > > All this string manipulation looks sketchy. Is there some reason that
> > > I'm not seeing preventing you for doing something like the untested
> > > code below?
> > >
> > >   func (s GuestPanicInformation) MarshalJSON() ([]byte, error) {
> > >   if s.HyperV != nil {
> > >   type union struct {
> > >   Discriminator string  `json:"type"`
> > >   HyperVGuestPanicInformationHyperV `json:"hyper-v"`
> > >   }
> > >   tmp := union {
> > >   Discriminator: "hyper-v",
> > >   HyperV:s.HyperV,
> > >   }
> > >   return json.Marshal(tmp)
> > >   } else if s.S390 != nil {
> > >   type union struct {
> > >   Discriminator string  `json:"type"`
> > >   S390  GuestPanicInformationHyperV `json:"s390"`
> > >   }
> > >   tmp := union {
> > >   Discriminator: "s390",
> > >   S390:  s.S390,
> > >   }
> > >   return json.Marshal(tmp)
> > >   }
> > >   return nil, errors.New("...")
> > >   }
> >
> > Using these dummy structs is the way I've approached the
> > discriminated union issue in the libvirt Golang XML bindings
> > and it works well. It is the bit I like the least, but it was
> > the lesser of many evils, and on the plus side in the QEMU case
> > it'll be auto-generated code.
>
> It appears to be the standard way to approach the problem in Go. It
> sort of comes naturally given how the APIs for marshal/unmarshal have
> been defined.

Yep, string manipulation was bad choice. Some sort of anonymous
struct is a better fit. So I'll be changing this ...

> > > > func (s *GuestPanicInformation) UnmarshalJSON(data []byte) error {
> > > > type Alias GuestPanicInformation
> > > > peek := struct {
> > > > Alias
> > > > Driver string `json:"type"`
> > > > }{}
> > > >
> > > > if err := json.Unmarshal(data, ); err != nil {
> > > > return err
> > > > }
> > > > *s = GuestPanicInformation(peek.Alias)
> > > >
> > > > switch peek.Driver {
> > > >
> > > > case "hyper-v":
> > > > s.HyperV = new(GuestPanicInformationHyperV)
> > > > if err := json.Unmarshal(data, s.HyperV); err != nil {
> > > > s.HyperV = nil
> > > > return err
> > > > }
> > > > case "s390":
> > > > s.S390 = new(GuestPanicInformationS390)
> > > > if err := json.Unmarshal(data, s.S390); err != nil {
> > > > s.S390 = nil
> > > > return err
> > > > }
> > > > }
> > > > // Unrecognizer drivers are silently ignored.
> > > > return nil
> > >
> > > This looks pretty reasonable, but since you're only using "peek" to
> > > look at the discriminator you should be able to leave out the Alias
> > > type entirely and perform the initial Unmarshal operation while
> > > ignoring all other fields.
> >
> > Once you've defined the dummy structs for the Marshall case
> > though, you might as well use them for Unmarshall too, so you're
> > not parsing the JSON twice.
>
> You're right, that is undesirable. What about something like this?
>
>   type GuestPanicInformation struct {
>   HyperV *GuestPanicInformationHyperV
>   S390   *GuestPanicInformationS390
>   }
>
>   type jsonGuestPanicInformation struct {
>   Discriminator string   `json:"type"`
>   HyperV*GuestPanicInformationHyperV `json:"hyper-v"`
>   S390  *GuestPanicInformationS390   `json:"s390"`
>   }

I didn't test this so I could be wrong but, I think this should
not work in case you want to remove the string manipulation.

The marshalling of either HyperV or S390 fields would return a
JSON Object but QAPI spec expects the fields at the same level as
the discriminator's type [0]. So, with this you still need some
string manipulation to remove the extra {}, like I did poorly
without any comment 0:-)

[0] 
https://gitlab.com/qemu-project/qemu/-/blob/master/docs/devel/qapi-code-gen.rst?plain=1#L358

>   func (s GuestPanicInformation) MarshalJSON() ([]byte, error) {
>   if (s.HyperV != nil && s.S390 != nil) ||
>   (s.HyperV == nil && s.S390 == nil) {
>   // client hasn't filled in the struct properly
>   return nil, errors.New("...")
>   }
>
>   tmp := jsonGuestPanicInformation{}
>
>   if s.HyperV != nil {
>   tmp.Discriminator = "hyper-v"
>   tmp.HyperV = s.HyperV
>   } else if s.S390 != nil {
>   tmp.Discriminator = "s390"
>   tmp.S390 = s.S390
>   }
>
>   return json.Marshal(tmp)
>   }
>
>   func (s *GuestPanicInformation) UnmarshalJSON(data []byte) error {
>

[PULL 03/10] hw/virtio: handle un-configured shutdown in virtio-pci

2022-08-17 Thread Michael S. Tsirkin
From: Alex Bennée 

The assert() protecting against leakage is a little aggressive and
causes needless crashes if a device is shutdown without having been
configured. In this case no descriptors are lost because none have
been assigned.

Signed-off-by: Alex Bennée 
Message-Id: <20220728135503.1060062-4-alex.ben...@linaro.org>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-pci.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 45327f0b31..5ce61f9b45 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -996,9 +996,14 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, 
int nvqs, bool assign)
 
 nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
 
-/* When deassigning, pass a consistent nvqs value
- * to avoid leaking notifiers.
+/*
+ * When deassigning, pass a consistent nvqs value to avoid leaking
+ * notifiers. But first check we've actually been configured, exit
+ * early if we haven't.
  */
+if (!assign && !proxy->nvqs_with_notifiers) {
+return 0;
+}
 assert(assign || nvqs == proxy->nvqs_with_notifiers);
 
 proxy->nvqs_with_notifiers = nvqs;
-- 
MST




[PATCH 09/10] iotests: Refactor tests of parallels images checks (131)

2022-08-17 Thread Alexander Ivanov
Replace hardcoded numbers by variables.

Signed-off-by: Alexander Ivanov 
---
 tests/qemu-iotests/131 | 29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
index a847692b4c..601546c84c 100755
--- a/tests/qemu-iotests/131
+++ b/tests/qemu-iotests/131
@@ -44,31 +44,34 @@ _supported_os Linux
 inuse_offset=$((0x2c))
 
 size=$((64 * 1024 * 1024))
-CLUSTER_SIZE=64k
+CLUSTER_SIZE=$((64 * 1024))
 IMGFMT=parallels
 _make_test_img $size
 
+CLUSTER_HALF_SIZE=$((CLUSTER_SIZE / 2))
+CLUSTER_DBL_SIZE=$((CLUSTER_SIZE * 2))
+
 echo == read empty image ==
-{ $QEMU_IO -c "read -P 0 32k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0 $CLUSTER_HALF_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 
| _filter_qemu_io | _filter_testdir
 echo == write more than 1 block in a row ==
-{ $QEMU_IO -c "write -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "write -P 0x11 $CLUSTER_HALF_SIZE $CLUSTER_DBL_SIZE" 
"$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
 echo == read less than block ==
-{ $QEMU_IO -c "read -P 0x11 32k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_HALF_SIZE $CLUSTER_HALF_SIZE" 
"$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
 echo == read exactly 1 block ==
-{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
 echo == read more than 1 block ==
-{ $QEMU_IO -c "read -P 0x11 32k 128k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_HALF_SIZE $CLUSTER_DBL_SIZE" "$TEST_IMG"; 
} 2>&1 | _filter_qemu_io | _filter_testdir
 echo == check that there is no trash after written ==
-{ $QEMU_IO -c "read -P 0 160k 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0 $((CLUSTER_HALF_SIZE + CLUSTER_DBL_SIZE)) 
$CLUSTER_HALF_SIZE" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | _filter_testdir
 echo == check that there is no trash before written ==
-{ $QEMU_IO -c "read -P 0 0 32k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0 0 $CLUSTER_HALF_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
 
 echo "== Corrupt image =="
 poke_file "$TEST_IMG" "$inuse_offset" "\x59\x6e\x6f\x74"
-{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
 _check_test_img
 _check_test_img -r all
-{ $QEMU_IO -c "read -P 0x11 64k 64k" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
 
 echo "== allocate with backing =="
 # Verify that allocating clusters works fine even when there is a backing 
image.
@@ -83,7 +86,7 @@ TEST_IMG="$TEST_IMG.base" _make_test_img $size
 
 # Write some data to the base image (which would trigger an assertion failure 
if
 # interpreted as a QEMUIOVector)
-$QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG.base" | _filter_qemu_io
+$QEMU_IO -c "write -P 42 0 $CLUSTER_SIZE" "$TEST_IMG.base" | _filter_qemu_io
 
 # Parallels does not seem to support storing a backing filename in the image
 # itself, so we need to build our backing chain on the command line
@@ -99,8 +102,8 @@ QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT \
 QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT \
 $QEMU_IO --image-opts "$imgopts" \
 -c 'read -P 1 0 64' \
--c "read -P 42 64 $((64 * 1024 - 64))" \
--c "read -P 0 64k $((size - 64 * 1024))" \
+-c "read -P 42 64 $((CLUSTER_SIZE - 64))" \
+-c "read -P 0 $CLUSTER_SIZE $((size - CLUSTER_SIZE))" \
 | _filter_qemu_io
 
 # success, all done
-- 
2.34.1




[PATCH 08/10] iotests: Add test for BAT entries duplication check

2022-08-17 Thread Alexander Ivanov
Fill the image with a pattern and write another pattern
in the second cluster. Corrupt the image and check if the pattern
changes. Repair the image and check the patterns on guest
and host sides.

Signed-off-by: Alexander Ivanov 
---
 tests/qemu-iotests/tests/parallels-checks | 31 +++
 tests/qemu-iotests/tests/parallels-checks.out | 31 +++
 2 files changed, 62 insertions(+)

diff --git a/tests/qemu-iotests/tests/parallels-checks 
b/tests/qemu-iotests/tests/parallels-checks
index a793b8c2fe..64d9f9c273 100755
--- a/tests/qemu-iotests/tests/parallels-checks
+++ b/tests/qemu-iotests/tests/parallels-checks
@@ -98,6 +98,37 @@ echo "file size: $file_size"
 echo "== check last cluster =="
 { $QEMU_IO -c "read -P 0x11 $LAST_CLUSTER_OFF $CLUSTER_SIZE" "$TEST_IMG"; } 
2>&1 | _filter_qemu_io | _filter_testdir
 
+# Clear image
+_make_test_img $SIZE
+
+echo "== TEST DUPLICATION CHECK =="
+
+echo "== write pattern to whole image =="
+{ $QEMU_IO -c "write -P 0x11 0 $SIZE" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+
+echo "== write another pattern to second cluster =="
+{ $QEMU_IO -c "write -P 0x55 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 
| _filter_qemu_io | _filter_testdir
+
+echo "== check second cluster =="
+{ $QEMU_IO -c "read -P 0x55 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
+
+echo "== corrupt image =="
+poke_file "$TEST_IMG" "$(($BAT_OFFSET + 4))" "\x01\x00\x00\x00"
+
+echo "== check second cluster =="
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
+
+echo "== repair image =="
+_check_test_img -r all
+
+echo "== check second cluster =="
+{ $QEMU_IO -c "read -P 0x11 $CLUSTER_SIZE $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
+
+echo "== check first cluster on host =="
+printf "content: 0x%02x\n" `peek_file_le $TEST_IMG $(($CLUSTER_SIZE)) 1`
+
+echo "== check second cluster on host =="
+printf "content: 0x%02x\n" `peek_file_le $TEST_IMG $(($CLUSTER_SIZE)) 1`
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/tests/parallels-checks.out 
b/tests/qemu-iotests/tests/parallels-checks.out
index fa0fca953e..725420875a 100644
--- a/tests/qemu-iotests/tests/parallels-checks.out
+++ b/tests/qemu-iotests/tests/parallels-checks.out
@@ -41,4 +41,35 @@ file size: 2097152
 == check last cluster ==
 read 1048576/1048576 bytes at offset 3145728
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
+== TEST DUPLICATION CHECK ==
+== write pattern to whole image ==
+wrote 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== write another pattern to second cluster ==
+wrote 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check second cluster ==
+read 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== corrupt image ==
+== check second cluster ==
+read 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== repair image ==
+Repairing duplicate offset in BAT entry 1
+The following inconsistencies were found and repaired:
+
+0 leaked clusters
+1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+== check second cluster ==
+read 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== check first cluster on host ==
+content: 0x11
+== check second cluster on host ==
+content: 0x11
 *** done
-- 
2.34.1




[PATCH 06/10] iotests: Add out-of-image check test for parallels format

2022-08-17 Thread Alexander Ivanov
Fill the image with a pattern to generate entries in the BAT,
set the first BAT entry outside the image, try to read the corrupted image,
repair and check for zeroes in the first cluster.

Signed-off-by: Alexander Ivanov 
---
 tests/qemu-iotests/tests/parallels-checks | 78 +++
 tests/qemu-iotests/tests/parallels-checks.out | 22 ++
 2 files changed, 100 insertions(+)
 create mode 100755 tests/qemu-iotests/tests/parallels-checks
 create mode 100644 tests/qemu-iotests/tests/parallels-checks.out

diff --git a/tests/qemu-iotests/tests/parallels-checks 
b/tests/qemu-iotests/tests/parallels-checks
new file mode 100755
index 00..5aaadb0c74
--- /dev/null
+++ b/tests/qemu-iotests/tests/parallels-checks
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+# group: rw quick
+#
+# Test qemu-img check for parallels format
+#
+# Copyright (C) 2022 Virtuozzo International GmbH
+#
+# 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 .
+#
+
+# creator
+owner=alexander.iva...@virtuozzo.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1   # failure is the default!
+
+_cleanup()
+{
+_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ../common.rc
+. ../common.filter
+
+_supported_fmt parallels
+_supported_proto file
+_supported_os Linux
+
+SIZE=$((4 * 1024 * 1024))
+IMGFMT=parallels
+CLUSTER_SIZE_OFFSET=28
+BAT_OFFSET=64
+
+_make_test_img $SIZE
+
+CLUSTER_SIZE=$(peek_file_le $TEST_IMG $CLUSTER_SIZE_OFFSET 4)
+CLUSTER_SIZE=$((CLUSTER_SIZE * 512))
+LAST_CLUSTER_OFF=$((SIZE - CLUSTER_SIZE))
+LAST_CLUSTER=$((LAST_CLUSTER_OFF/CLUSTER_SIZE))
+
+echo "== TEST OUT OF IMAGE CHECK =="
+
+echo "== write pattern =="
+{ $QEMU_IO -c "write -P 0x11 0 $SIZE" "$TEST_IMG"; } 2>&1 | _filter_qemu_io | 
_filter_testdir
+
+echo "== corrupt image =="
+cluster=$(($LAST_CLUSTER + 2))
+poke_file "$TEST_IMG" "$BAT_OFFSET" "\x$cluster\x00\x00\x00"
+
+echo "== read corrupted image =="
+{ $QEMU_IO -c "read -P 0x11 0 $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
+
+echo "== repair image =="
+_check_test_img -r all
+
+echo "== read repaired image =="
+{ $QEMU_IO -c "read -P 0x00 0 $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
+
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/tests/parallels-checks.out 
b/tests/qemu-iotests/tests/parallels-checks.out
new file mode 100644
index 00..787851a250
--- /dev/null
+++ b/tests/qemu-iotests/tests/parallels-checks.out
@@ -0,0 +1,22 @@
+QA output created by parallels-checks
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
+== TEST OUT OF IMAGE CHECK ==
+== write pattern ==
+wrote 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== corrupt image ==
+== read corrupted image ==
+qemu-io: can't open device TEST_DIR/t.parallels: parallels: Offset in BAT is 
out of image
+== repair image ==
+Repairing cluster 0 is outside image
+The following inconsistencies were found and repaired:
+
+0 leaked clusters
+1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+== read repaired image ==
+read 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
-- 
2.34.1




[PATCH 07/10] iotests: Add leak check test for parallels format

2022-08-17 Thread Alexander Ivanov
Write a pattern to the last cluster, extend the image
by 1 claster, repair and check that the last cluster
still has the same pattern.

Signed-off-by: Alexander Ivanov 
---
 tests/qemu-iotests/tests/parallels-checks | 27 +++
 tests/qemu-iotests/tests/parallels-checks.out | 22 +++
 2 files changed, 49 insertions(+)

diff --git a/tests/qemu-iotests/tests/parallels-checks 
b/tests/qemu-iotests/tests/parallels-checks
index 5aaadb0c74..a793b8c2fe 100755
--- a/tests/qemu-iotests/tests/parallels-checks
+++ b/tests/qemu-iotests/tests/parallels-checks
@@ -71,6 +71,33 @@ _check_test_img -r all
 echo "== read repaired image =="
 { $QEMU_IO -c "read -P 0x00 0 $CLUSTER_SIZE" "$TEST_IMG"; } 2>&1 | 
_filter_qemu_io | _filter_testdir
 
+# Clear image
+_make_test_img $SIZE
+
+echo "== TEST LEAK CHECK =="
+
+echo "== write pattern to last cluster =="
+echo "write -P 0x11 $LAST_CLUSTER_OFF $CLUSTER_SIZE"
+{ $QEMU_IO -c "write -P 0x11 $LAST_CLUSTER_OFF $CLUSTER_SIZE" "$TEST_IMG"; } 
2>&1 | _filter_qemu_io | _filter_testdir
+
+file_size=`stat --printf="%s" "$TEST_IMG"`
+echo "file size: $file_size"
+
+echo "== extend image by 1 cluster =="
+fallocate -l $((file_size + CLUSTER_SIZE)) "$TEST_IMG"
+
+file_size=`stat --printf="%s" "$TEST_IMG"`
+echo "file size: $file_size"
+
+echo "== repair image =="
+_check_test_img -r all
+
+file_size=`stat --printf="%s" "$TEST_IMG"`
+echo "file size: $file_size"
+
+echo "== check last cluster =="
+{ $QEMU_IO -c "read -P 0x11 $LAST_CLUSTER_OFF $CLUSTER_SIZE" "$TEST_IMG"; } 
2>&1 | _filter_qemu_io | _filter_testdir
+
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/tests/parallels-checks.out 
b/tests/qemu-iotests/tests/parallels-checks.out
index 787851a250..fa0fca953e 100644
--- a/tests/qemu-iotests/tests/parallels-checks.out
+++ b/tests/qemu-iotests/tests/parallels-checks.out
@@ -19,4 +19,26 @@ No errors were found on the image.
 == read repaired image ==
 read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
+== TEST LEAK CHECK ==
+== write pattern to last cluster ==
+write -P 0x11 3145728 1048576
+wrote 1048576/1048576 bytes at offset 3145728
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+file size: 2097152
+== extend image by 1 cluster ==
+file size: 3145728
+== repair image ==
+Repairing space leaked at the end of the image 1048576
+The following inconsistencies were found and repaired:
+
+1 leaked clusters
+0 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+file size: 2097152
+== check last cluster ==
+read 1048576/1048576 bytes at offset 3145728
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
-- 
2.34.1




[PATCH 00/10] parallels: Add duplication check, refactor, fix bugs

2022-08-17 Thread Alexander Ivanov
This patchset depends on the patchset
[PATCH v3 0/8] parallels: Refactor the code of images checks and fix a bug

Fix an incorrect condition in out-of-image check and
incorrect data end calculation in parallels_open().

Add parallels_handle_leak() and highest_offset() helpers.

Add checking and repairing duplicate offsets in BAT.

Add tests for parallels format checks.
Refactor and fix old parallels tests.

Alexander Ivanov (10):
  parallels: Incorrect condition in out-of-image check
  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
  iotests: Add out-of-image check test for parallels format
  iotests: Add leak check test for parallels format
  iotests: Add test for BAT entries duplication check
  iotests: Refactor tests of parallels images checks (131)
  iotests: Fix cluster size in parallels images tests (131)

 block/parallels.c | 217 +++---
 tests/qemu-iotests/131|  32 +--
 tests/qemu-iotests/131.out|  44 ++--
 tests/qemu-iotests/tests/parallels-checks | 136 +++
 tests/qemu-iotests/tests/parallels-checks.out |  75 ++
 5 files changed, 437 insertions(+), 67 deletions(-)
 create mode 100755 tests/qemu-iotests/tests/parallels-checks
 create mode 100644 tests/qemu-iotests/tests/parallels-checks.out

-- 
2.34.1




[PATCH 10/10] iotests: Fix cluster size in parallels images tests (131)

2022-08-17 Thread Alexander Ivanov
In this test cluster size is 64k, but modern tools generate images
with cluster size 1M.
Calculate cluster size using track field from image header.

Signed-off-by: Alexander Ivanov 
---
 tests/qemu-iotests/131 |  5 -
 tests/qemu-iotests/131.out | 44 +++---
 2 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
index 601546c84c..78ef238c64 100755
--- a/tests/qemu-iotests/131
+++ b/tests/qemu-iotests/131
@@ -44,10 +44,13 @@ _supported_os Linux
 inuse_offset=$((0x2c))
 
 size=$((64 * 1024 * 1024))
-CLUSTER_SIZE=$((64 * 1024))
 IMGFMT=parallels
 _make_test_img $size
 
+# get cluster size in sectros from "tracks" header field
+CLUSTER_SIZE_OFFSET=28
+CLUSTER_SIZE=$(peek_file_le $TEST_IMG $CLUSTER_SIZE_OFFSET 4)
+CLUSTER_SIZE=$((CLUSTER_SIZE * 512))
 CLUSTER_HALF_SIZE=$((CLUSTER_SIZE / 2))
 CLUSTER_DBL_SIZE=$((CLUSTER_SIZE * 2))
 
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
index de5ef7a8f5..98017a067e 100644
--- a/tests/qemu-iotests/131.out
+++ b/tests/qemu-iotests/131.out
@@ -1,26 +1,26 @@
 QA output created by 131
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 == read empty image ==
-read 65536/65536 bytes at offset 32768
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048576/1048576 bytes at offset 524288
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == write more than 1 block in a row ==
-wrote 131072/131072 bytes at offset 32768
-128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2097152/2097152 bytes at offset 524288
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == read less than block ==
-read 32768/32768 bytes at offset 32768
-32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 524288/524288 bytes at offset 524288
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == read exactly 1 block ==
-read 65536/65536 bytes at offset 65536
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == read more than 1 block ==
-read 131072/131072 bytes at offset 32768
-128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 2097152/2097152 bytes at offset 524288
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == check that there is no trash after written ==
-read 32768/32768 bytes at offset 163840
-32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 524288/524288 bytes at offset 2621440
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == check that there is no trash before written ==
-read 32768/32768 bytes at offset 0
-32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 524288/524288 bytes at offset 0
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == Corrupt image ==
 qemu-io: can't open device TEST_DIR/t.parallels: parallels: Image was not 
closed correctly; cannot be opened read/write
 ERROR image was not closed correctly
@@ -35,19 +35,19 @@ The following inconsistencies were found and repaired:
 
 Double checking the fixed image now...
 No errors were found on the image.
-read 65536/65536 bytes at offset 65536
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048576/1048576 bytes at offset 1048576
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 == allocate with backing ==
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
-wrote 65536/65536 bytes at offset 0
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 64/64 bytes at offset 0
 64 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 64/64 bytes at offset 0
 64 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 65472/65472 bytes at offset 64
-63.938 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read 67043328/67043328 bytes at offset 65536
-63.938 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 1048512/1048512 bytes at offset 64
+1023.938 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 66060288/66060288 bytes at offset 1048576
+63 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
-- 
2.34.1




[PATCH 05/10] parallels: Use highest_offset() helper in leak check

2022-08-17 Thread Alexander Ivanov
Deduplicate code by using highest_offset() helper.

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

diff --git a/block/parallels.c b/block/parallels.c
index bd129f44fa..93d21804f2 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -530,15 +530,8 @@ static int parallels_check_leak(BlockDriverState *bs,
 {
 BDRVParallelsState *s = bs->opaque;
 int64_t off, high_off, count, cut_out;
-int 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;
-}
-}
+high_off = highest_offset(s);
 
 cut_out = parallels_handle_leak(bs, res, high_off, fix & BDRV_FIX_LEAKS);
 if (cut_out < 0) {
-- 
2.34.1




[PATCH 04/10] parallels: Add checking and repairing duplicate offsets in BAT

2022-08-17 Thread Alexander Ivanov
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 eba064247a..bd129f44fa 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;
+}
+
+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)
 {
@@ -541,6 +561,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.
+ * 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);
+
+buf = g_malloc(s->cluster_size);
+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);
+if (ret < 0) {
+res->check_errors++;
+goto out;
+}
+
+sector = (i * s->cluster_size) >> BDRV_SECTOR_BITS;
+off = allocate_clusters(bs, sector, s->tracks, );
+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, s->cluster_size, , 
0);
+if (ret < 0) {
+res->check_errors++;
+goto out;
+}
+
+new_allocations = true;
+res->corruptions_fixed++;
+}
+
+} else {
+bitmap_set(bitmap, cluster_index, 1);
+}
+}
+
+if (new_allocations) {
+/*
+ * When new clusters are allocated, file size increases
+ * by 128 Mb blocks. We need to truncate the file to the
+ * right size.
+ */
+ret = parallels_handle_leak(bs, res, high_off, true);
+if (ret < 0) {
+res->check_errors++;
+goto out;
+}
+}
+
+out:
+qemu_iovec_destroy();
+g_free(buf);
+g_free(bitmap);
+return ret;
+}
+
 static void 

[PATCH 01/10] parallels: Incorrect condition in out-of-image check

2022-08-17 Thread Alexander Ivanov
All the offsets in the BAT must be at least one cluster away from
the end of the data area.
Fix the check condition for correct check.

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

diff --git a/block/parallels.c b/block/parallels.c
index e124a8bb7d..c42c955075 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -455,7 +455,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) {
+if (off + s->cluster_size > size) {
 fprintf(stderr, "%s cluster %u is outside image\n",
 fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
 res->corruptions++;
-- 
2.34.1




[PATCH 02/10] parallels: Incorrect data end calculation in parallels_open

2022-08-17 Thread Alexander Ivanov
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.

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

diff --git a/block/parallels.c b/block/parallels.c
index c42c955075..ce04a4da71 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -850,7 +850,8 @@ 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(bat_entry_off(s->bat_size),
+   BDRV_SECTOR_SIZE);
 }
 if (s->data_end < s->header_size) {
 /* there is not enough unused space to fit to block align between BAT
-- 
2.34.1




[PATCH 1/2] target/riscv: rvv-1.0: Simplify vfwredsum code

2022-08-17 Thread Yang Liu
Remove duplicate code by wrapping vfwredsum_vs's OP function.

Signed-off-by: Yang Liu 
---
 target/riscv/vector_helper.c | 56 +++-
 1 file changed, 10 insertions(+), 46 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a96fc49c71..fd83c0b20b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4655,58 +4655,22 @@ GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, 
H2, float16_minimum_number)
 GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, 
float32_minimum_number)
 GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, 
float64_minimum_number)
 
-/* Vector Widening Floating-Point Reduction Instructions */
-/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
-void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1,
-void *vs2, CPURISCVState *env, uint32_t desc)
+/* Vector Widening Floating-Point Add Instructions */
+static uint32_t fwadd16(uint32_t a, uint16_t b, float_status *s)
 {
-uint32_t vm = vext_vm(desc);
-uint32_t vl = env->vl;
-uint32_t esz = sizeof(uint32_t);
-uint32_t vlenb = simd_maxsz(desc);
-uint32_t vta = vext_vta(desc);
-uint32_t i;
-uint32_t s1 =  *((uint32_t *)vs1 + H4(0));
-
-for (i = env->vstart; i < vl; i++) {
-uint16_t s2 = *((uint16_t *)vs2 + H2(i));
-if (!vm && !vext_elem_mask(v0, i)) {
-continue;
-}
-s1 = float32_add(s1, float16_to_float32(s2, true, >fp_status),
- >fp_status);
-}
-*((uint32_t *)vd + H4(0)) = s1;
-env->vstart = 0;
-/* set tail elements to 1s */
-vext_set_elems_1s(vd, vta, esz, vlenb);
+return float32_add(a, float16_to_float32(b, true, s), s);
 }
 
-void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
-void *vs2, CPURISCVState *env, uint32_t desc)
+static uint64_t fwadd32(uint64_t a, uint32_t b, float_status *s)
 {
-uint32_t vm = vext_vm(desc);
-uint32_t vl = env->vl;
-uint32_t esz = sizeof(uint64_t);
-uint32_t vlenb = simd_maxsz(desc);
-uint32_t vta = vext_vta(desc);
-uint32_t i;
-uint64_t s1 =  *((uint64_t *)vs1);
-
-for (i = env->vstart; i < vl; i++) {
-uint32_t s2 = *((uint32_t *)vs2 + H4(i));
-if (!vm && !vext_elem_mask(v0, i)) {
-continue;
-}
-s1 = float64_add(s1, float32_to_float64(s2, >fp_status),
- >fp_status);
-}
-*((uint64_t *)vd) = s1;
-env->vstart = 0;
-/* set tail elements to 1s */
-vext_set_elems_1s(vd, vta, esz, vlenb);
+return float64_add(a, float32_to_float64(b, s), s);
 }
 
+/* Vector Widening Floating-Point Reduction Instructions */
+/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
+GEN_VEXT_FRED(vfwredsum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
+GEN_VEXT_FRED(vfwredsum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
+
 /*
  *** Vector Mask Operations
  */
-- 
2.30.1 (Apple Git-130)




[PATCH 03/10] parallels: Create parallels_handle_leak() to truncate excess clusters

2022-08-17 Thread Alexander Ivanov
This helper will be reused in the next patch for duplications check.

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

diff --git a/block/parallels.c b/block/parallels.c
index ce04a4da71..eba064247a 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -469,19 +469,48 @@ static int parallels_check_outside_image(BlockDriverState 
*bs,
 return 0;
 }
 
+static int64_t parallels_handle_leak(BlockDriverState *bs,
+ BdrvCheckResult *res,
+ int64_t high_off,
+ bool fix)
+{
+BDRVParallelsState *s = bs->opaque;
+int64_t size;
+int ret;
+
+size = bdrv_getlength(bs->file->bs);
+if (size < 0) {
+return size;
+}
+
+res->image_end_offset = high_off + s->cluster_size;
+if (size <= res->image_end_offset) {
+return 0;
+}
+
+if (fix) {
+Error *local_err = NULL;
+/*
+ * In order to really repair the image, we must shrink it.
+ * That means we have to pass exact=true.
+ */
+ret = bdrv_truncate(bs->file, res->image_end_offset, true,
+PREALLOC_MODE_OFF, 0, _err);
+if (ret < 0) {
+error_report_err(local_err);
+return ret;
+}
+}
+return size - res->image_end_offset;
+}
+
 static int parallels_check_leak(BlockDriverState *bs,
 BdrvCheckResult *res,
 BdrvCheckMode fix)
 {
 BDRVParallelsState *s = bs->opaque;
-int64_t size, off, high_off, count;
-int i, ret;
-
-size = bdrv_getlength(bs->file->bs);
-if (size < 0) {
-res->check_errors++;
-return size;
-}
+int64_t off, high_off, count, cut_out;
+int i;
 
 high_off = 0;
 for (i = 0; i < s->bat_size; i++) {
@@ -491,30 +520,24 @@ static int parallels_check_leak(BlockDriverState *bs,
 }
 }
 
-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) {
-Error *local_err = NULL;
+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;
+}
 
-/*
- * In order to really repair the image, we must shrink it.
- * That means we have to pass exact=true.
- */
-ret = bdrv_truncate(bs->file, res->image_end_offset, true,
-PREALLOC_MODE_OFF, 0, _err);
-if (ret < 0) {
-error_report_err(local_err);
-res->check_errors++;
-return ret;
-}
-res->leaks_fixed += count;
-}
+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;
 }
 
-- 
2.34.1




[PATCH v2 29/31] ppc440_bamboo: Add missing 4 MiB valid memory size

2022-08-17 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
---
 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;
-- 
2.30.4




Re: [PATCH 00/22] QOMify PPC4xx devices and minor clean ups

2022-08-17 Thread BALATON Zoltan

On Tue, 16 Aug 2022, Cédric Le Goater wrote:

On 8/13/22 17:34, BALATON Zoltan wrote:

Hello,

This is mased on gitlab.com/danielhb/qemu/tree/ppc-7.2

This series contains the rest of Cédric's patches modified according
my review comments and some other small clean ups I've noticed along
the way. I've kept the From line of Cédric for patches that were
originally his even though they are modified a bit. Not sure what's
the best way for this or what Cédric prefers.

The last sdram changes are not yet here because I'm still looking at
those and will come back to them but this series is ready to merge
unless there are comments that need further changes. Please let me
know what do you think.


LGTM. In case you resend, may be change the names of the models which
are now common to PPC4xx. That's minor really.

I would dig the default case labels a little more before removing
them.


I've sent a v2 that includes the proposed name changes and dropped the 
patch removing empty default cases for now. This v2 now also includes my 
version of the sdram changes so that's all from me for now.


Regards,
BALATON Zoltan


Thanks,

C.




Regards,
BALATON Zoltan

BALATON Zoltan (22):
   ppc/ppc4xx: Introduce a DCR device model
   ppc/ppc405: QOM'ify CPC
   ppc/ppc405: QOM'ify GPT
   ppc/ppc405: QOM'ify OCM
   ppc/ppc405: QOM'ify GPIO
   ppc/ppc405: QOM'ify DMA
   ppc/ppc405: QOM'ify EBC
   ppc/ppc405: QOM'ify OPBA
   ppc/ppc405: QOM'ify POB
   ppc/ppc405: QOM'ify PLB
   ppc/ppc405: QOM'ify MAL
   ppc4xx: Move PLB model to ppc4xx_devs.c
   ppc4xx: Move EBC model to ppc4xx_devs.c
   ppc/ppc405: Use an embedded PPCUIC model in SoC state
   hw/intc/ppc-uic: Convert ppc-uic to a PPC4xx DCR device
   ppc/ppc405: Use an explicit I2C object
   ppc/ppc405: QOM'ify FPGA
   ppc405: Move machine specific code to ppc405_boards.c
   hw/ppc/Kconfig: Remove PPC405 dependency from sam460ex
   hw/ppc/Kconfig: Move imply before select
   ppc4xx: Drop empty default cases
   ppc/ppc4xx: Fix sdram trace events

  hw/intc/ppc-uic.c |   26 +-
  hw/ppc/Kconfig|3 +-
  hw/ppc/ppc405.h   |  182 +--
  hw/ppc/ppc405_boards.c|  360 +
  hw/ppc/ppc405_uc.c| 1071 -
  hw/ppc/ppc440_bamboo.c|7 +-
  hw/ppc/ppc440_uc.c|   27 -
  hw/ppc/ppc4xx_devs.c  |  473 +---
  hw/ppc/sam460ex.c |   37 +-
  hw/ppc/trace-events   |3 -
  hw/ppc/virtex_ml507.c |7 +-
  include/hw/intc/ppc-uic.h |6 +-
  include/hw/ppc/ppc4xx.h   |   71 ++-
  13 files changed, 1223 insertions(+), 1050 deletions(-)






[PATCH v2 24/31] ppc4xx: Fix code style problems reported by checkpatch

2022-08-17 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405_uc.c |  5 +++--
 hw/ppc/ppc440_bamboo.c | 27 ++--
 hw/ppc/ppc440_uc.c |  3 ++-
 hw/ppc/ppc4xx_devs.c   | 48 +++---
 hw/ppc/ppc4xx_pci.c| 31 +--
 5 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index d541134632..6296130936 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -540,10 +540,11 @@ static void ppc4xx_gpt_set_irqs(Ppc405GptState *gpt)
 
 mask = 0x8000;
 for (i = 0; i < 5; i++) {
-if (gpt->is & gpt->im & mask)
+if (gpt->is & gpt->im & mask) {
 qemu_irq_raise(gpt->irqs[i]);
-else
+} else {
 qemu_irq_lower(gpt->irqs[i]);
+}
 mask = mask >> 1;
 }
 }
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index b14a9ef776..ea945a1c99 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -84,27 +84,30 @@ static int bamboo_load_device_tree(hwaddr addr,
 
 ret = qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
-if (ret < 0)
+if (ret < 0) {
 fprintf(stderr, "couldn't set /memory/reg\n");
-
+}
 ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
 initrd_base);
-if (ret < 0)
+if (ret < 0) {
 fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
-
+}
 ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
 (initrd_base + initrd_size));
-if (ret < 0)
+if (ret < 0) {
 fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
-
+}
 ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
   kernel_cmdline);
-if (ret < 0)
+if (ret < 0) {
 fprintf(stderr, "couldn't set /chosen/bootargs\n");
+}
 
-/* Copy data from the host device tree into the guest. Since the guest can
+/*
+ * Copy data from the host device tree into the guest. Since the guest can
  * directly access the timebase without host involvement, we must expose
- * the correct frequencies. */
+ * the correct frequencies.
+ */
 if (kvm_enabled()) {
 tb_freq = kvmppc_get_tbfreq();
 clock_freq = kvmppc_get_clockfreq();
@@ -246,8 +249,10 @@ static void bamboo_init(MachineState *machine)
 if (pcibus) {
 /* Register network interfaces. */
 for (i = 0; i < nb_nics; i++) {
-/* There are no PCI NICs on the Bamboo board, but there are
- * PCI slots, so we can pick whatever default model we want. */
+/*
+ * There are no PCI NICs on the Bamboo board, but there are
+ * PCI slots, so we can pick whatever default model we want.
+ */
 pci_nic_init_nofail(_table[i], pcibus, "e1000", NULL);
 }
 }
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 11fdb88c22..53e981ddf4 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -1028,7 +1028,8 @@ void ppc4xx_dma_init(CPUPPCState *env, int dcr_base)
 
 /*/
 /* PCI Express controller */
-/* FIXME: This is not complete and does not work, only implemented partially
+/*
+ * FIXME: This is not complete and does not work, only implemented partially
  * to allow firmware and guests to find an empty bus. Cards should use PCI.
  */
 #include "hw/pci/pcie_host.h"
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 27ebbb2ffc..ce38ae65e6 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -65,12 +65,12 @@ enum {
 SDRAM0_CFGDATA = 0x011,
 };
 
-/* XXX: TOFIX: some patches have made this code become inconsistent:
+/*
+ * XXX: TOFIX: some patches have made this code become inconsistent:
  *  there are type inconsistencies, mixing hwaddr, target_ulong
  *  and uint32_t
  */
-static uint32_t sdram_bcr (hwaddr ram_base,
-   hwaddr ram_size)
+static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
 {
 uint32_t bcr;
 
@@ -113,16 +113,17 @@ static inline hwaddr sdram_base(uint32_t bcr)
 return bcr & 0xFF80;
 }
 
-static target_ulong sdram_size (uint32_t bcr)
+static target_ulong sdram_size(uint32_t bcr)
 {
 target_ulong size;
 int sh;
 
 sh = (bcr >> 17) & 0x7;
-if (sh == 7)
+if (sh == 7) {
 size = -1;
-else
+} else {
 size = (4 * MiB) << sh;
+}
 
 return size;
 }
@@ -153,7 +154,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 }
 }
 
-static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
+static void sdram_map_bcr(ppc4xx_sdram_t *sdram)
 {
 int i;
 
@@ -167,7 +168,7 @@ static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
 }
 }
 
-static void sdram_unmap_bcr 

RE: AST2600 support in QEMU

2022-08-17 Thread Amit Kumar (Engrg-SW)
Hi Dan,

Responding on behalf of Shivi.

>> "So what does the "PCIe RC support" means? the BMC will be the PCIe RC?"
Yes, BMC will be the PCIe RC to control downstream PCIe devices (end-points).

- Amit

-Original Message-
From: Dan Zhang  
Sent: 15 August 2022 11:18
To: Cédric Le Goater 
Cc: Joel Stanley ; Shivi Fotedar ; Peter 
Delevoryas ; Jeremy Kerr ; Klaus Jensen 
; Jonathan Cameron ; 
qemu-devel@nongnu.org; Andrew Jeffery ; Amit Kumar (Engrg-SW) 
; Prasanna Karmalkar ; Tim Chen 
(SW-GPU) ; Newton Liu ; Deepak Kodihalli 
; qemu-arm 
Subject: Re: AST2600 support in QEMU

External email: Use caution opening links or attachments


On Tue, Aug 9, 2022 at 10:51 PM Cédric Le Goater  wrote:
>
> Hello,
>
> On 8/10/22 04:37, Joel Stanley wrote:
> > Hello Shivi,
> >
> > I've added others to cc who may have some input.
> >
> > On Tue, 9 Aug 2022 at 21:38, Shivi Fotedar  wrote:
> >>
> >> Hello, we are looking for support for few features for AST2600 in 
> >> QEMU, specifically
> >>
> >> PCIe RC support so BMC can talk to downstream devices for management 
> >> functions.
Normally the RC is the host CPU, BMC and the devices to be managed, which 
support MCTP-over-PCIe will be the endpoint (downstream) device as BMC.  The 
MCTP message Peer transaction between BMC and managed device will using 
route-by-Id to RC(host) then down to endpoint.  I am referring to DMTF DSP0238 
spec. section 6.4

So what does the "PCIe RC support" means? the BMC will be the PCIe RC?
or BMC will be PCIe-Endpoint connect to host PCIe RC.

> >
> > I haven't seen any PCIe work done yet.
>
> I haven't either. There is clearly a need now that we are moving away 
> from LPC.
>
> >> MCTP controller to run MCTP protocol on top of PCIe or I2C.
> >
> > What work would be required to do this on top of i2c?
>
> I think Jonathan and Klaus worked on this. See :
>
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> .kernel.org%2Fqemu-devel%2F20220525121422.3a84%40Huawei.com%2F
> ;data=05%7C01%7Casinghal%40nvidia.com%7C714d293de2ac4b7f5f9308da7e81b2
> 7b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637961392786299602%7CU
> nknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1ha
> WwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=9I35YQPk86Tjza6fa0jFVnLGCM
> SZ7ioTHpJEQN5c%2F1g%3Dreserved=0
>
> >> I2C slave so BMC can talk to host CPU QEMU for IPMI
> >
> > Some support for slave mode was merged in v7.1.
>
> yes.
>
> Peter D. experimented with IPMI. See :
>
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> .kernel.org%2Fqemu-devel%2F20220630045133.32251-14-me%40pjd.dev%2F
> ;data=05%7C01%7Casinghal%40nvidia.com%7C714d293de2ac4b7f5f9308da7e81b2
> 7b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637961392786299602%7CU
> nknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1ha
> WwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=HwFjdPHcM4MocoDz8hrZatYJiz
> gmDePy24KFivENpeU%3Dreserved=0
>
> We also merged a new machine including a BMC ast2600 running OpenBMC 
> and an ast1030 SoC running OpenBIC. Work to interconnect them on the 
> same I2C bus is in progress.
>
> Thanks,
>
> C.
>



[PATCH 2/2] target/riscv: rvv-1.0: vf[w]redsum distinguish between ordered/unordered

2022-08-17 Thread Yang Liu
Starting with RVV1.0, the original vf[w]redsum_vs instruction was renamed
to vf[w]redusum_vs. The distinction between ordered and unordered is also
more consistent with other instructions, although there is no difference
in implementation between the two for QEMU.

Signed-off-by: Yang Liu 
---
 target/riscv/helper.h   | 15 ++-
 target/riscv/insn32.decode  |  6 --
 target/riscv/insn_trans/trans_rvv.c.inc |  6 --
 target/riscv/vector_helper.c| 19 +--
 4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 4ef3b2251d..a03014fe67 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1009,9 +1009,12 @@ DEF_HELPER_6(vwredsum_vs_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_6(vfredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vfredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vfredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredusum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredusum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredusum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredosum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredosum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredosum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
@@ -1019,8 +1022,10 @@ DEF_HELPER_6(vfredmin_vs_h, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_6(vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwredusum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwredusum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwredosum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwredosum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_6(vmand_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4033565393..2873a7ae04 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -659,11 +659,13 @@ vredmax_vs  000111 . . . 010 . 1010111 
@r_vm
 vwredsumu_vs11 . . . 000 . 1010111 @r_vm
 vwredsum_vs 110001 . . . 000 . 1010111 @r_vm
 # Vector ordered and unordered reduction sum
-vfredsum_vs -1 . . . 001 . 1010111 @r_vm
+vfredusum_vs01 . . . 001 . 1010111 @r_vm
+vfredosum_vs11 . . . 001 . 1010111 @r_vm
 vfredmin_vs 000101 . . . 001 . 1010111 @r_vm
 vfredmax_vs 000111 . . . 001 . 1010111 @r_vm
 # Vector widening ordered and unordered float reduction sum
-vfwredsum_vs1100-1 . . . 001 . 1010111 @r_vm
+vfwredusum_vs   110001 . . . 001 . 1010111 @r_vm
+vfwredosum_vs   110011 . . . 001 . 1010111 @r_vm
 vmand_mm011001 - . . 010 . 1010111 @r
 vmnand_mm   011101 - . . 010 . 1010111 @r
 vmandn_mm   011000 - . . 010 . 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6c091824b6..9c9de17f8a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3112,7 +3112,8 @@ static bool freduction_check(DisasContext *s, arg_rmrr *a)
require_zve64f(s);
 }
 
-GEN_OPFVV_TRANS(vfredsum_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredusum_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredosum_vs, freduction_check)
 GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
 GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
@@ -3124,7 +3125,8 @@ static bool freduction_widen_check(DisasContext *s, 
arg_rmrr *a)
(s->sew != MO_8);
 }
 
-GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, freduction_widen_check)
+GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
+GEN_OPFVV_WIDEN_TRANS(vfwredosum_vs, freduction_widen_check)
 
 /*
  *** Vector Mask Operations
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index fd83c0b20b..d87f79ad82 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4641,9 +4641,14 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, 
  \
 }
 
 /* Unordered sum */
-GEN_VEXT_FRED(vfredsum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
-GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, 

[PATCH v2 31/31] ppc4xx_sdram: QOM'ify

2022-08-17 Thread BALATON Zoltan
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 
---
 hw/ppc/ppc405.h |  3 +-
 hw/ppc/ppc405_uc.c  | 22 +-
 hw/ppc/ppc440_bamboo.c  | 10 +++--
 hw/ppc/ppc4xx_devs.c| 89 +++--
 include/hw/ppc/ppc4xx.h | 24 +++
 5 files changed, 93 insertions(+), 55 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, 14));
 /* Enable SDRAM memory regions, this should be done by the firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
 

[PATCH v2 20/31] ppc405: Move machine specific code to ppc405_boards.c

2022-08-17 Thread BALATON Zoltan
These are only used by the board code so move out from the shared SoC
model and put it in the boards file.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  38 -
 hw/ppc/ppc405_boards.c | 375 +++--
 hw/ppc/ppc405_uc.c |  92 --
 3 files changed, 251 insertions(+), 254 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index efa29fdfb1..1e558c7831 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -30,41 +30,6 @@
 #include "hw/intc/ppc-uic.h"
 #include "hw/i2c/ppc4xx_i2c.h"
 
-#define PPC405EP_SDRAM_BASE 0x
-#define PPC405EP_NVRAM_BASE 0xF000
-#define PPC405EP_FPGA_BASE  0xF030
-#define PPC405EP_SRAM_BASE  0xFFF0
-#define PPC405EP_SRAM_SIZE  (512 * KiB)
-#define PPC405EP_FLASH_BASE 0xFFF8
-
-/* Bootinfo as set-up by u-boot */
-typedef struct ppc4xx_bd_info_t ppc4xx_bd_info_t;
-struct ppc4xx_bd_info_t {
-uint32_t bi_memstart;
-uint32_t bi_memsize;
-uint32_t bi_flashstart;
-uint32_t bi_flashsize;
-uint32_t bi_flashoffset; /* 0x10 */
-uint32_t bi_sramstart;
-uint32_t bi_sramsize;
-uint32_t bi_bootflags;
-uint32_t bi_ipaddr; /* 0x20 */
-uint8_t  bi_enetaddr[6];
-uint16_t bi_ethspeed;
-uint32_t bi_intfreq;
-uint32_t bi_busfreq; /* 0x30 */
-uint32_t bi_baudrate;
-uint8_t  bi_s_version[4];
-uint8_t  bi_r_version[32];
-uint32_t bi_procfreq;
-uint32_t bi_plb_busfreq;
-uint32_t bi_pci_busfreq;
-uint8_t  bi_pci_enetaddr[6];
-uint8_t  bi_pci_enetaddr2[6]; /* PPC405EP specific */
-uint32_t bi_opbfreq;
-uint32_t bi_iic_fast[2];
-};
-
 /* PLB to OPB bridge */
 #define TYPE_PPC405_POB "ppc405-pob"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
@@ -224,7 +189,4 @@ struct Ppc405SoCState {
 Ppc4xxMalState mal;
 };
 
-/* PowerPC 405 core */
-ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
-
 #endif /* PPC405_H */
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 7af0d7feef..083f12b23e 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -48,6 +48,10 @@
 #define KERNEL_LOAD_ADDR 0x0100
 #define INITRD_LOAD_ADDR 0x0180
 
+#define PPC405EP_SDRAM_BASE 0x
+#define PPC405EP_SRAM_BASE  0xFFF0
+#define PPC405EP_SRAM_SIZE  (512 * KiB)
+
 #define USE_FLASH_BIOS
 
 #define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
@@ -61,112 +65,7 @@ struct Ppc405MachineState {
 Ppc405SoCState soc;
 };
 
-/*/
-/* PPC405EP reference board (IBM) */
-/* Standalone board with:
- * - PowerPC 405EP CPU
- * - SDRAM (0x)
- * - Flash (0xFFF8)
- * - SRAM  (0xFFF0)
- * - NVRAM (0xF000)
- * - FPGA  (0xF030)
- */
-
-#define TYPE_REF405EP_FPGA "ref405ep-fpga"
-OBJECT_DECLARE_SIMPLE_TYPE(Ref405epFpgaState, REF405EP_FPGA);
-struct Ref405epFpgaState {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-
-uint8_t reg0;
-uint8_t reg1;
-};
-
-static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
-{
-Ref405epFpgaState *fpga = opaque;
-uint32_t ret;
-
-switch (addr) {
-case 0x0:
-ret = fpga->reg0;
-break;
-case 0x1:
-ret = fpga->reg1;
-break;
-default:
-ret = 0;
-break;
-}
-
-return ret;
-}
-
-static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
-Ref405epFpgaState *fpga = opaque;
-
-switch (addr) {
-case 0x0:
-/* Read only */
-break;
-case 0x1:
-fpga->reg1 = value;
-break;
-default:
-break;
-}
-}
-
-static const MemoryRegionOps ref405ep_fpga_ops = {
-.read = ref405ep_fpga_readb,
-.write = ref405ep_fpga_writeb,
-.impl.min_access_size = 1,
-.impl.max_access_size = 1,
-.valid.min_access_size = 1,
-.valid.max_access_size = 4,
-.endianness = DEVICE_BIG_ENDIAN,
-};
-
-static void ref405ep_fpga_reset(DeviceState *dev)
-{
-Ref405epFpgaState *fpga = REF405EP_FPGA(dev);
-
-fpga->reg0 = 0x00;
-fpga->reg1 = 0x0F;
-}
-
-static void ref405ep_fpga_realize(DeviceState *dev, Error **errp)
-{
-Ref405epFpgaState *s = REF405EP_FPGA(dev);
-
-memory_region_init_io(>iomem, OBJECT(s), _fpga_ops, s,
-  "fpga", 0x0100);
-sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
-}
-
-static void ref405ep_fpga_class_init(ObjectClass *oc, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(oc);
-
-dc->realize = ref405ep_fpga_realize;
-dc->reset = ref405ep_fpga_reset;
-/* Reason: only works as part of a ppc405 board */
-dc->user_creatable = false;
-}
-
-static const TypeInfo ref405ep_fpga_type = {
-.name = TYPE_REF405EP_FPGA,
-.parent = TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(Ref405epFpgaState),
-.class_init = 

[PATCH v2 16/31] ppc/ppc405: Use an embedded PPCUIC model in SoC state

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
[balaton: Simplify sysbus device casts for readability]
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h|  3 ++-
 hw/ppc/ppc405_uc.c | 28 ++--
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 343a84c98e..67f4c14f50 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -27,6 +27,7 @@
 
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
+#include "hw/intc/ppc-uic.h"
 
 #define PPC405EP_SDRAM_BASE 0x
 #define PPC405EP_NVRAM_BASE 0xF000
@@ -208,7 +209,7 @@ struct Ppc405SoCState {
 hwaddr ram_size;
 
 PowerPCCPU cpu;
-DeviceState *uic;
+PPCUIC uic;
 Ppc405CpcState cpc;
 Ppc405GptState gpt;
 Ppc405OcmState ocm;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index e817f00ad1..8412c11dd5 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1080,6 +1080,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "cpu", >cpu,
 POWERPC_CPU_TYPE_NAME("405ep"));
 
+object_initialize_child(obj, "uic", >uic, TYPE_PPC_UIC);
+
 object_initialize_child(obj, "cpc", >cpc, TYPE_PPC405_CPC);
 object_property_add_alias(obj, "sys-clk", OBJECT(>cpc), "sys-clk");
 
@@ -1147,17 +1149,15 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_map(sbd, 0, 0xef600600);
 
 /* Universal interrupt controller */
-s->uic = qdev_new(TYPE_PPC_UIC);
-
-object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(>cpu),
+object_property_set_link(OBJECT(>uic), "cpu", OBJECT(>cpu),
  _fatal);
-if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
+sbd = SYS_BUS_DEVICE(>uic);
+if (!sysbus_realize(sbd, errp)) {
 return;
 }
-
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
+sysbus_connect_irq(sbd, PPCUIC_OUTPUT_INT,
qdev_get_gpio_in(DEVICE(>cpu), PPC40x_INPUT_INT));
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
+sysbus_connect_irq(sbd, PPCUIC_OUTPUT_CINT,
qdev_get_gpio_in(DEVICE(>cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
@@ -1168,7 +1168,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  "ppc405.sdram0", s->dram_mr,
  s->ram_bases[0], s->ram_sizes[0]);
 
-ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17), 1,
+ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(>uic), 17), 1,
   s->ram_banks, s->ram_bases, s->ram_sizes,
   s->do_dram_init);
 
@@ -1183,12 +1183,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 sbd = SYS_BUS_DEVICE(>dma);
 for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
-sysbus_connect_irq(sbd, i, qdev_get_gpio_in(s->uic, 5 + i));
+sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(>uic), 5 + i));
 }
 
 /* I2C controller */
 sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
- qdev_get_gpio_in(s->uic, 2));
+ qdev_get_gpio_in(DEVICE(>uic), 2));
 
 /* GPIO */
 sbd = SYS_BUS_DEVICE(>gpio);
@@ -1200,13 +1200,13 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 /* Serial ports */
 if (serial_hd(0) != NULL) {
 serial_mm_init(get_system_memory(), 0xef600300, 0,
-   qdev_get_gpio_in(s->uic, 0),
+   qdev_get_gpio_in(DEVICE(>uic), 0),
PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
DEVICE_BIG_ENDIAN);
 }
 if (serial_hd(1) != NULL) {
 serial_mm_init(get_system_memory(), 0xef600400, 0,
-   qdev_get_gpio_in(s->uic, 1),
+   qdev_get_gpio_in(DEVICE(>uic), 1),
PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
DEVICE_BIG_ENDIAN);
 }
@@ -1223,7 +1223,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 sysbus_mmio_map(sbd, 0, 0xef60);
 for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {
-sysbus_connect_irq(sbd, i, qdev_get_gpio_in(s->uic, 19 + i));
+sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(>uic), 19 + i));
 }
 
 /* MAL */
@@ -1234,7 +1234,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 sbd = SYS_BUS_DEVICE(>mal);
 for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
-sysbus_connect_irq(sbd, i, qdev_get_gpio_in(s->uic, 11 + i));
+sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(>uic), 11 + i));
 }
 
 /* Ethernet */
-- 
2.30.4




[PATCH v2 23/31] ppc/ppc4xx: Fix sdram trace events

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_devs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 37e3b87c2e..27ebbb2ffc 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -142,7 +142,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
 }
 sdram->bcr[i] = bcr & 0xFFDEE001;
 if (enabled && (bcr & 0x0001)) {
-trace_ppc4xx_sdram_unmap(sdram_base(bcr), sdram_size(bcr));
+trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
 memory_region_init(>containers[i], NULL, "sdram-containers",
sdram_size(bcr));
 memory_region_add_subregion(>containers[i], 0,
-- 
2.30.4




[PATCH v2 28/31] ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()

2022-08-17 Thread BALATON Zoltan
Change ppc4xx_sdram_banks() to take one Ppc4xxSdramBank array instead
of the separate arrays and adjust ppc4xx_sdram_init() and
ppc440_sdram_init() accordingly as well as machines using these.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h |  4 +---
 hw/ppc/ppc405_uc.c  | 10 +-
 hw/ppc/ppc440.h |  5 ++---
 hw/ppc/ppc440_bamboo.c  | 15 ++-
 hw/ppc/ppc440_uc.c  |  9 -
 hw/ppc/ppc4xx_devs.c| 21 +
 hw/ppc/sam460ex.c   | 15 +--
 include/hw/ppc/ppc4xx.h |  9 +++--
 8 files changed, 35 insertions(+), 53 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 756865621b..ca0972b88b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
 DeviceState parent_obj;
 
 /* Public */
-MemoryRegion ram_banks[2];
-hwaddr ram_bases[2], ram_sizes[2];
-
+Ppc4xxSdramBank ram_banks[2];
 MemoryRegion *dram_mr;
 hwaddr ram_size;
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 2833d0d538..461d18c8a5 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1071,14 +1071,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 
 /* SDRAM controller */
 /* XXX 405EP has no ECC interrupt */
-s->ram_bases[0] = 0;
-s->ram_sizes[0] = s->ram_size;
-memory_region_init_alias(>ram_banks[0], OBJECT(s),
+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_bases[0], s->ram_sizes[0]);
+ s->ram_banks[0].base, s->ram_banks[0].size);
 
 ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(>uic), 17), 1,
-  s->ram_banks, s->ram_bases, s->ram_sizes);
+  s->ram_banks);
 
 /* External bus controller */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>ebc), >cpu, errp)) {
diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 7cef936125..5eb2f9a6b3 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,14 +11,13 @@
 #ifndef PPC440_H
 #define PPC440_H
 
-#include "hw/ppc/ppc.h"
+#include "hw/ppc/ppc4xx.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,
-   MemoryRegion *ram_memories,
-   hwaddr *ram_bases, hwaddr *ram_sizes,
+   Ppc4xxSdramBank ram_banks[],
int do_init);
 void ppc4xx_ahb_init(CPUPPCState *env);
 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index e3412c4fcd..2aac8a3fe9 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -168,9 +168,8 @@ 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);
-MemoryRegion *ram_memories = g_new(MemoryRegion, PPC440EP_SDRAM_NR_BANKS);
-hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS] = {0};
-hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS] = {0};
+Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
+PPC440EP_SDRAM_NR_BANKS);
 PCIBus *pcibus;
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -205,13 +204,11 @@ 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_memories,
-   ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes);
+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_memories,
-  ram_bases, ram_sizes);
+ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
+  PPC440EP_SDRAM_NR_BANKS, ram_banks);
 /* Enable SDRAM memory regions, this should be done by the firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
 ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 6ab0ad7985..3507c35b63 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -690,8 +690,7 @@ static void sdram_reset(void *opaque)
 }
 
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram_memories,
-   hwaddr *ram_bases, hwaddr *ram_sizes,
+   Ppc4xxSdramBank ram_banks[],

[PATCH v2 12/31] ppc4xx: Move PLB model to ppc4xx_devs.c

2022-08-17 Thread BALATON Zoltan
The PLB is shared between 405 and 440 so move it to the shared file.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h | 11 -
 hw/ppc/ppc405_uc.c  | 93 
 hw/ppc/ppc4xx_devs.c| 94 +
 include/hw/ppc/ppc4xx.h | 11 +
 4 files changed, 105 insertions(+), 104 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 31c94e4742..d85c595f9d 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -63,17 +63,6 @@ struct ppc4xx_bd_info_t {
 uint32_t bi_iic_fast[2];
 };
 
-/* Peripheral local bus arbitrer */
-#define TYPE_PPC405_PLB "ppc405-plb"
-OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PlbState, PPC405_PLB);
-struct Ppc405PlbState {
-Ppc4xxDcrDeviceState parent_obj;
-
-uint32_t acr;
-uint32_t bear;
-uint32_t besr;
-};
-
 /* PLB to OPB bridge */
 #define TYPE_PPC405_POB "ppc405-pob"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 922c23346f..3de6c77631 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -137,94 +137,6 @@ ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, 
ram_addr_t ram_size)
 /*/
 /* Shared peripherals */
 
-/*/
-/* Peripheral local bus arbitrer */
-enum {
-PLB3A0_ACR = 0x077,
-PLB4A0_ACR = 0x081,
-PLB0_BESR  = 0x084,
-PLB0_BEAR  = 0x086,
-PLB0_ACR   = 0x087,
-PLB4A1_ACR = 0x089,
-};
-
-static uint32_t dcr_read_plb(void *opaque, int dcrn)
-{
-Ppc405PlbState *plb = opaque;
-uint32_t ret;
-
-switch (dcrn) {
-case PLB0_ACR:
-ret = plb->acr;
-break;
-case PLB0_BEAR:
-ret = plb->bear;
-break;
-case PLB0_BESR:
-ret = plb->besr;
-break;
-default:
-/* Avoid gcc warning */
-ret = 0;
-break;
-}
-
-return ret;
-}
-
-static void dcr_write_plb(void *opaque, int dcrn, uint32_t val)
-{
-Ppc405PlbState *plb = opaque;
-
-switch (dcrn) {
-case PLB0_ACR:
-/* We don't care about the actual parameters written as
- * we don't manage any priorities on the bus
- */
-plb->acr = val & 0xF800;
-break;
-case PLB0_BEAR:
-/* Read only */
-break;
-case PLB0_BESR:
-/* Write-clear */
-plb->besr &= ~val;
-break;
-}
-}
-
-static void ppc405_plb_reset(DeviceState *dev)
-{
-Ppc405PlbState *plb = PPC405_PLB(dev);
-
-plb->acr = 0x;
-plb->bear = 0x;
-plb->besr = 0x;
-}
-
-static void ppc405_plb_realize(DeviceState *dev, Error **errp)
-{
-Ppc405PlbState *plb = PPC405_PLB(dev);
-Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
-
-ppc4xx_dcr_register(dcr, PLB3A0_ACR, plb, _read_plb, _write_plb);
-ppc4xx_dcr_register(dcr, PLB4A0_ACR, plb, _read_plb, _write_plb);
-ppc4xx_dcr_register(dcr, PLB0_ACR, plb, _read_plb, _write_plb);
-ppc4xx_dcr_register(dcr, PLB0_BEAR, plb, _read_plb, _write_plb);
-ppc4xx_dcr_register(dcr, PLB0_BESR, plb, _read_plb, _write_plb);
-ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, _read_plb, _write_plb);
-}
-
-static void ppc405_plb_class_init(ObjectClass *oc, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(oc);
-
-dc->realize = ppc405_plb_realize;
-dc->reset = ppc405_plb_reset;
-/* Reason: only works as function of a ppc4xx SoC */
-dc->user_creatable = false;
-}
-
 /*/
 /* PLB to OPB bridge */
 enum {
@@ -1535,11 +1447,6 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
-.name   = TYPE_PPC405_PLB,
-.parent = TYPE_PPC4xx_DCR_DEVICE,
-.instance_size  = sizeof(Ppc405PlbState),
-.class_init = ppc405_plb_class_init,
-}, {
 .name   = TYPE_PPC405_POB,
 .parent = TYPE_PPC4xx_DCR_DEVICE,
 .instance_size  = sizeof(Ppc405PobState),
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 7d40c1b68a..843d759b1b 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -658,6 +658,95 @@ static void ppc4xx_mal_class_init(ObjectClass *oc, void 
*data)
 device_class_set_props(dc, ppc4xx_mal_properties);
 }
 
+/*/
+/* Peripheral local bus arbitrer */
+enum {
+PLB3A0_ACR = 0x077,
+PLB4A0_ACR = 0x081,
+PLB0_BESR  = 0x084,
+PLB0_BEAR  = 0x086,
+PLB0_ACR   = 0x087,
+PLB4A1_ACR = 0x089,
+};
+
+static uint32_t dcr_read_plb(void *opaque, int dcrn)
+{
+Ppc405PlbState *plb = opaque;
+uint32_t ret;
+
+switch (dcrn) {
+case PLB0_ACR:
+ret = plb->acr;
+break;
+case PLB0_BEAR:
+ret = 

[PATCH v2 25/31] ppc440_bamboo: Remove unnecessary memsets

2022-08-17 Thread BALATON Zoltan
In ppc4xx_sdram_init() the struct is allocated with g_new0() so no
need to clear its elements. In the bamboo machine init memset can be
replaced with array initialiser which is shorter.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440_bamboo.c | 6 ++
 hw/ppc/ppc4xx_devs.c   | 8 ++--
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index ea945a1c99..5ec82fa8c2 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -169,8 +169,8 @@ static void bamboo_init(MachineState *machine)
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
 MemoryRegion *ram_memories = g_new(MemoryRegion, PPC440EP_SDRAM_NR_BANKS);
-hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS];
-hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS];
+hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS] = {0};
+hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS] = {0};
 PCIBus *pcibus;
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -205,8 +205,6 @@ static void bamboo_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
-memset(ram_bases, 0, sizeof(ram_bases));
-memset(ram_sizes, 0, sizeof(ram_sizes));
 ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_memories,
ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes);
 /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index ce38ae65e6..b4cd10f735 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -363,12 +363,8 @@ void ppc4xx_sdram_init(CPUPPCState *env, qemu_irq irq, int 
nbanks,
 sdram->irq = irq;
 sdram->nbanks = nbanks;
 sdram->ram_memories = ram_memories;
-memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr));
-memcpy(sdram->ram_bases, ram_bases,
-   nbanks * sizeof(hwaddr));
-memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr));
-memcpy(sdram->ram_sizes, ram_sizes,
-   nbanks * sizeof(hwaddr));
+memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
+memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
 qemu_register_reset(_reset, sdram);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
  sdram, _read_sdram, _write_sdram);
-- 
2.30.4




[PATCH v2 22/31] hw/ppc/Kconfig: Move imply before select

2022-08-17 Thread BALATON Zoltan
In pegasos2 section move imply before select to match other sections.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 205f9f98d7..3a4418a69e 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -71,6 +71,7 @@ config SAM460EX
 
 config PEGASOS2
 bool
+imply ATI_VGA
 select MV64361
 select VT82C686
 select IDE_VIA
@@ -78,7 +79,6 @@ config PEGASOS2
 select VOF
 # This should come with VT82C686
 select ACPI_X86
-imply ATI_VGA
 
 config PREP
 bool
-- 
2.30.4




[PATCH v2 26/31] ppc4xx: Introduce Ppc4xxSdramBank struct

2022-08-17 Thread BALATON Zoltan
Instead of storing sdram bank parameters in unrelated arrays put them
in a struct so it's clear they belong to the same bank and simplify
the state struct using this bank type.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440_uc.c  | 49 +-
 hw/ppc/ppc4xx_devs.c| 59 -
 include/hw/ppc/ppc4xx.h |  8 ++
 3 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 53e981ddf4..db4e29 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -16,7 +16,7 @@
 #include "qemu/module.h"
 #include "hw/irq.h"
 #include "exec/memory.h"
-#include "hw/ppc/ppc.h"
+#include "hw/ppc/ppc4xx.h"
 #include "hw/qdev-properties.h"
 #include "hw/pci/pci.h"
 #include "sysemu/block-backend.h"
@@ -485,11 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
 typedef struct ppc440_sdram_t {
 uint32_t addr;
 int nbanks;
-MemoryRegion containers[4]; /* used for clipping */
-MemoryRegion *ram_memories;
-hwaddr ram_bases[4];
-hwaddr ram_sizes[4];
-uint32_t bcr[4];
+Ppc4xxSdramBank bank[4];
 } ppc440_sdram_t;
 
 enum {
@@ -570,23 +566,23 @@ static uint64_t sdram_size(uint32_t bcr)
 static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
   uint32_t bcr, int enabled)
 {
-if (sdram->bcr[i] & 1) {
+if (sdram->bank[i].bcr & 1) {
 /* First unmap RAM if enabled */
 memory_region_del_subregion(get_system_memory(),
->containers[i]);
-memory_region_del_subregion(>containers[i],
->ram_memories[i]);
-object_unparent(OBJECT(>containers[i]));
+>bank[i].container);
+memory_region_del_subregion(>bank[i].container,
+>bank[i].ram);
+object_unparent(OBJECT(>bank[i].container));
 }
-sdram->bcr[i] = bcr & 0xffe0ffc1;
+sdram->bank[i].bcr = bcr & 0xffe0ffc1;
 if (enabled && (bcr & 1)) {
-memory_region_init(>containers[i], NULL, "sdram-containers",
+memory_region_init(>bank[i].container, NULL, "sdram-container",
sdram_size(bcr));
-memory_region_add_subregion(>containers[i], 0,
->ram_memories[i]);
+memory_region_add_subregion(>bank[i].container, 0,
+>bank[i].ram);
 memory_region_add_subregion(get_system_memory(),
 sdram_base(bcr),
->containers[i]);
+>bank[i].container);
 }
 }
 
@@ -595,9 +591,9 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->ram_sizes[i] != 0) {
-sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
-  sdram->ram_sizes[i]), 1);
+if (sdram->bank[i].size != 0) {
+sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
+  sdram->bank[i].size), 1);
 } else {
 sdram_set_bcr(sdram, i, 0, 0);
 }
@@ -614,9 +610,9 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 case SDRAM_R1BAS:
 case SDRAM_R2BAS:
 case SDRAM_R3BAS:
-if (sdram->ram_sizes[dcrn - SDRAM_R0BAS]) {
-ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
-sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
+if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
+ret = sdram_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
+sdram->bank[dcrn - SDRAM_R0BAS].size);
 }
 break;
 case SDRAM_CONF1HB:
@@ -701,12 +697,15 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks,
int do_init)
 {
 ppc440_sdram_t *sdram;
+int i;
 
 sdram = g_malloc0(sizeof(*sdram));
 sdram->nbanks = nbanks;
-sdram->ram_memories = ram_memories;
-memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
-memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
+for (i = 0; i < nbanks; i++) {
+sdram->bank[i].ram = ram_memories[i];
+sdram->bank[i].base = ram_bases[i];
+sdram->bank[i].size = ram_sizes[i];
+}
 qemu_register_reset(_reset, sdram);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
  sdram, _read_sdram, _write_sdram);
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index b4cd10f735..1226ec4aa9 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -42,10 +42,7 @@ typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
 struct ppc4xx_sdram_t {
 uint32_t addr;
 int nbanks;
-MemoryRegion containers[4]; /* used for clipping */
-MemoryRegion *ram_memories;
-hwaddr ram_bases[4];
-hwaddr ram_sizes[4];
+

[PATCH v2 09/31] ppc/ppc405: QOM'ify POB

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

POB is currently modeled as a simple DCR device.

Signed-off-by: Cédric Le Goater 
[balaton: ppc4xx_dcr_register changes]
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h| 12 ++
 hw/ppc/ppc405_uc.c | 56 ++
 2 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index d63c2acdc7..4140e811d5 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -63,6 +63,17 @@ struct ppc4xx_bd_info_t {
 uint32_t bi_iic_fast[2];
 };
 
+/* PLB to OPB bridge */
+#define TYPE_PPC405_POB "ppc405-pob"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
+struct Ppc405PobState {
+Ppc4xxDcrDeviceState parent_obj;
+
+uint32_t bear;
+uint32_t besr0;
+uint32_t besr1;
+};
+
 /* OPB arbitrer */
 #define TYPE_PPC405_OPBA "ppc405-opba"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA);
@@ -220,6 +231,7 @@ struct Ppc405SoCState {
 Ppc405DmaState dma;
 Ppc405EbcState ebc;
 Ppc405OpbaState opba;
+Ppc405PobState pob;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 911ec958c6..0ad1cce790 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -234,19 +234,11 @@ enum {
 POB0_BEAR  = 0x0A4,
 };
 
-typedef struct ppc4xx_pob_t ppc4xx_pob_t;
-struct ppc4xx_pob_t {
-uint32_t bear;
-uint32_t besr0;
-uint32_t besr1;
-};
-
-static uint32_t dcr_read_pob (void *opaque, int dcrn)
+static uint32_t dcr_read_pob(void *opaque, int dcrn)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = opaque;
 uint32_t ret;
 
-pob = opaque;
 switch (dcrn) {
 case POB0_BEAR:
 ret = pob->bear;
@@ -266,11 +258,10 @@ static uint32_t dcr_read_pob (void *opaque, int dcrn)
 return ret;
 }
 
-static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)
+static void dcr_write_pob(void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = opaque;
 
-pob = opaque;
 switch (dcrn) {
 case POB0_BEAR:
 /* Read only */
@@ -286,26 +277,34 @@ static void dcr_write_pob (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ppc4xx_pob_reset (void *opaque)
+static void ppc405_pob_reset(DeviceState *dev)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = PPC405_POB(dev);
 
-pob = opaque;
 /* No error */
 pob->bear = 0x;
 pob->besr0 = 0x000;
 pob->besr1 = 0x000;
 }
 
-static void ppc4xx_pob_init(CPUPPCState *env)
+static void ppc405_pob_realize(DeviceState *dev, Error **errp)
+{
+Ppc405PobState *pob = PPC405_POB(dev);
+Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
+
+ppc4xx_dcr_register(dcr, POB0_BEAR, pob, _read_pob, _write_pob);
+ppc4xx_dcr_register(dcr, POB0_BESR0, pob, _read_pob, _write_pob);
+ppc4xx_dcr_register(dcr, POB0_BESR1, pob, _read_pob, _write_pob);
+}
+
+static void ppc405_pob_class_init(ObjectClass *oc, void *data)
 {
-ppc4xx_pob_t *pob;
+DeviceClass *dc = DEVICE_CLASS(oc);
 
-pob = g_new0(ppc4xx_pob_t, 1);
-ppc_dcr_register(env, POB0_BEAR, pob, _read_pob, _write_pob);
-ppc_dcr_register(env, POB0_BESR0, pob, _read_pob, _write_pob);
-ppc_dcr_register(env, POB0_BESR1, pob, _read_pob, _write_pob);
-qemu_register_reset(ppc4xx_pob_reset, pob);
+dc->realize = ppc405_pob_realize;
+dc->reset = ppc405_pob_reset;
+/* Reason: only works as function of a ppc4xx SoC */
+dc->user_creatable = false;
 }
 
 /*/
@@ -1370,6 +1369,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "ebc", >ebc, TYPE_PPC405_EBC);
 
 object_initialize_child(obj, "opba", >opba, TYPE_PPC405_OPBA);
+
+object_initialize_child(obj, "pob", >pob, TYPE_PPC405_POB);
 }
 
 static void ppc405_reset(void *opaque)
@@ -1404,7 +1405,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 ppc4xx_plb_init(env);
 
 /* PLB to OPB bridge */
-ppc4xx_pob_init(env);
+if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>pob), >cpu, errp)) {
+return;
+}
 
 /* OBP arbitrer */
 sbd = SYS_BUS_DEVICE(>opba);
@@ -1524,6 +1527,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
+.name   = TYPE_PPC405_POB,
+.parent = TYPE_PPC4xx_DCR_DEVICE,
+.instance_size  = sizeof(Ppc405PobState),
+.class_init = ppc405_pob_class_init,
+}, {
 .name   = TYPE_PPC405_OPBA,
 .parent = TYPE_SYS_BUS_DEVICE,
 .instance_size  = sizeof(Ppc405OpbaState),
-- 
2.30.4




[PATCH v2 18/31] ppc/ppc405: Use an explicit I2C object

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

Having an explicit I2C model object will help if one day we want to
add I2C devices on the bus from the machine init routine.

Signed-off-by: Cédric Le Goater 
[balaton: Symplify sysbus device casts for readibility]
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h|  2 ++
 hw/ppc/ppc405_uc.c | 10 --
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 67f4c14f50..efa29fdfb1 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -28,6 +28,7 @@
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
 #include "hw/intc/ppc-uic.h"
+#include "hw/i2c/ppc4xx_i2c.h"
 
 #define PPC405EP_SDRAM_BASE 0x
 #define PPC405EP_NVRAM_BASE 0xF000
@@ -215,6 +216,7 @@ struct Ppc405SoCState {
 Ppc405OcmState ocm;
 Ppc405GpioState gpio;
 Ppc405DmaState dma;
+PPC4xxI2CState i2c;
 Ppc4xxEbcState ebc;
 Ppc405OpbaState opba;
 Ppc405PobState pob;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index c070102b14..54a51594ca 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1093,6 +1093,8 @@ static void ppc405_soc_instance_init(Object *obj)
 
 object_initialize_child(obj, "dma", >dma, TYPE_PPC405_DMA);
 
+object_initialize_child(obj, "i2c", >i2c, TYPE_PPC4xx_I2C);
+
 object_initialize_child(obj, "ebc", >ebc, TYPE_PPC4xx_EBC);
 
 object_initialize_child(obj, "opba", >opba, TYPE_PPC405_OPBA);
@@ -1185,8 +1187,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* I2C controller */
-sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
- qdev_get_gpio_in(DEVICE(>uic), 2));
+sbd = SYS_BUS_DEVICE(>i2c);
+if (!sysbus_realize(sbd, errp)) {
+return;
+}
+sysbus_mmio_map(sbd, 0, 0xef600500);
+sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(DEVICE(>uic), 2));
 
 /* GPIO */
 sbd = SYS_BUS_DEVICE(>gpio);
-- 
2.30.4




[PATCH v2 21/31] hw/ppc/Kconfig: Remove PPC405 dependency from sam460ex

2022-08-17 Thread BALATON Zoltan
Now that shared PPC4xx devices are separated from PPC405 ones we can
drop this depencency.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 400511c6b7..205f9f98d7 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -58,7 +58,6 @@ config PPC4XX
 
 config SAM460EX
 bool
-select PPC405
 select PFLASH_CFI01
 select IDE_SII3112
 select M41T80
-- 
2.30.4




[PATCH v2 10/31] ppc/ppc405: QOM'ify PLB

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

PLB is currently modeled as a simple DCR device. Also drop the
ppc4xx_plb_init() helper and adapt the sam460ex machine.

Signed-off-by: Cédric Le Goater 
[balaton: ppc4xx_dcr_register changes]
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h| 14 --
 hw/ppc/ppc405_uc.c | 64 ++
 hw/ppc/sam460ex.c  |  4 ++-
 3 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 4140e811d5..cb34792daf 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -63,6 +63,17 @@ struct ppc4xx_bd_info_t {
 uint32_t bi_iic_fast[2];
 };
 
+/* Peripheral local bus arbitrer */
+#define TYPE_PPC405_PLB "ppc405-plb"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PlbState, PPC405_PLB);
+struct Ppc405PlbState {
+Ppc4xxDcrDeviceState parent_obj;
+
+uint32_t acr;
+uint32_t bear;
+uint32_t besr;
+};
+
 /* PLB to OPB bridge */
 #define TYPE_PPC405_POB "ppc405-pob"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
@@ -232,11 +243,10 @@ struct Ppc405SoCState {
 Ppc405EbcState ebc;
 Ppc405OpbaState opba;
 Ppc405PobState pob;
+Ppc405PlbState plb;
 };
 
 /* PowerPC 405 core */
 ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
 
-void ppc4xx_plb_init(CPUPPCState *env);
-
 #endif /* PPC405_H */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0ad1cce790..94ea6b5b70 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -148,19 +148,11 @@ enum {
 PLB4A1_ACR = 0x089,
 };
 
-typedef struct ppc4xx_plb_t ppc4xx_plb_t;
-struct ppc4xx_plb_t {
-uint32_t acr;
-uint32_t bear;
-uint32_t besr;
-};
-
-static uint32_t dcr_read_plb (void *opaque, int dcrn)
+static uint32_t dcr_read_plb(void *opaque, int dcrn)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = opaque;
 uint32_t ret;
 
-plb = opaque;
 switch (dcrn) {
 case PLB0_ACR:
 ret = plb->acr;
@@ -180,11 +172,10 @@ static uint32_t dcr_read_plb (void *opaque, int dcrn)
 return ret;
 }
 
-static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
+static void dcr_write_plb(void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = opaque;
 
-plb = opaque;
 switch (dcrn) {
 case PLB0_ACR:
 /* We don't care about the actual parameters written as
@@ -202,28 +193,36 @@ static void dcr_write_plb (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ppc4xx_plb_reset (void *opaque)
+static void ppc405_plb_reset(DeviceState *dev)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = PPC405_PLB(dev);
 
-plb = opaque;
 plb->acr = 0x;
 plb->bear = 0x;
 plb->besr = 0x;
 }
 
-void ppc4xx_plb_init(CPUPPCState *env)
+static void ppc405_plb_realize(DeviceState *dev, Error **errp)
+{
+Ppc405PlbState *plb = PPC405_PLB(dev);
+Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
+
+ppc4xx_dcr_register(dcr, PLB3A0_ACR, plb, _read_plb, _write_plb);
+ppc4xx_dcr_register(dcr, PLB4A0_ACR, plb, _read_plb, _write_plb);
+ppc4xx_dcr_register(dcr, PLB0_ACR, plb, _read_plb, _write_plb);
+ppc4xx_dcr_register(dcr, PLB0_BEAR, plb, _read_plb, _write_plb);
+ppc4xx_dcr_register(dcr, PLB0_BESR, plb, _read_plb, _write_plb);
+ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, _read_plb, _write_plb);
+}
+
+static void ppc405_plb_class_init(ObjectClass *oc, void *data)
 {
-ppc4xx_plb_t *plb;
-
-plb = g_new0(ppc4xx_plb_t, 1);
-ppc_dcr_register(env, PLB3A0_ACR, plb, _read_plb, _write_plb);
-ppc_dcr_register(env, PLB4A0_ACR, plb, _read_plb, _write_plb);
-ppc_dcr_register(env, PLB0_ACR, plb, _read_plb, _write_plb);
-ppc_dcr_register(env, PLB0_BEAR, plb, _read_plb, _write_plb);
-ppc_dcr_register(env, PLB0_BESR, plb, _read_plb, _write_plb);
-ppc_dcr_register(env, PLB4A1_ACR, plb, _read_plb, _write_plb);
-qemu_register_reset(ppc4xx_plb_reset, plb);
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_plb_realize;
+dc->reset = ppc405_plb_reset;
+/* Reason: only works as function of a ppc4xx SoC */
+dc->user_creatable = false;
 }
 
 /*/
@@ -1371,6 +1370,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "opba", >opba, TYPE_PPC405_OPBA);
 
 object_initialize_child(obj, "pob", >pob, TYPE_PPC405_POB);
+
+object_initialize_child(obj, "plb", >plb, TYPE_PPC405_PLB);
 }
 
 static void ppc405_reset(void *opaque)
@@ -1402,7 +1403,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* PLB arbitrer */
-ppc4xx_plb_init(env);
+if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>plb), >cpu, errp)) {
+return;
+}
 
 /* PLB to OPB bridge */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(>pob), >cpu, errp)) {
@@ -1527,6 +1530,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, 

[PATCH v2 30/31] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-08-17 Thread BALATON Zoltan
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 
---
 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| 16 
 include/hw/ppc/ppc4xx.h |  2 +-
 6 files changed, 12 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);
+  PPC440EP_SDRAM_NR_BANKS, machine->ram);
 /* Enable SDRAM memory regions, this should be done by the firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
 ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index e0b5931c04..764533f9f4 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ 

[PATCH v2 19/31] ppc/ppc405: QOM'ify FPGA

2022-08-17 Thread BALATON Zoltan
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405_boards.c | 56 +-
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 3677793adc..7af0d7feef 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -71,18 +71,23 @@ struct Ppc405MachineState {
  * - NVRAM (0xF000)
  * - FPGA  (0xF030)
  */
-typedef struct ref405ep_fpga_t ref405ep_fpga_t;
-struct ref405ep_fpga_t {
+
+#define TYPE_REF405EP_FPGA "ref405ep-fpga"
+OBJECT_DECLARE_SIMPLE_TYPE(Ref405epFpgaState, REF405EP_FPGA);
+struct Ref405epFpgaState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+
 uint8_t reg0;
 uint8_t reg1;
 };
 
 static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
 {
-ref405ep_fpga_t *fpga;
+Ref405epFpgaState *fpga = opaque;
 uint32_t ret;
 
-fpga = opaque;
 switch (addr) {
 case 0x0:
 ret = fpga->reg0;
@@ -101,9 +106,8 @@ static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr 
addr, unsigned size)
 static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
  unsigned size)
 {
-ref405ep_fpga_t *fpga;
+Ref405epFpgaState *fpga = opaque;
 
-fpga = opaque;
 switch (addr) {
 case 0x0:
 /* Read only */
@@ -126,27 +130,40 @@ static const MemoryRegionOps ref405ep_fpga_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void ref405ep_fpga_reset (void *opaque)
+static void ref405ep_fpga_reset(DeviceState *dev)
 {
-ref405ep_fpga_t *fpga;
+Ref405epFpgaState *fpga = REF405EP_FPGA(dev);
 
-fpga = opaque;
 fpga->reg0 = 0x00;
 fpga->reg1 = 0x0F;
 }
 
-static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
+static void ref405ep_fpga_realize(DeviceState *dev, Error **errp)
 {
-ref405ep_fpga_t *fpga;
-MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
+Ref405epFpgaState *s = REF405EP_FPGA(dev);
 
-fpga = g_new0(ref405ep_fpga_t, 1);
-memory_region_init_io(fpga_memory, NULL, _fpga_ops, fpga,
+memory_region_init_io(>iomem, OBJECT(s), _fpga_ops, s,
   "fpga", 0x0100);
-memory_region_add_subregion(sysmem, base, fpga_memory);
-qemu_register_reset(_fpga_reset, fpga);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), >iomem);
+}
+
+static void ref405ep_fpga_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ref405ep_fpga_realize;
+dc->reset = ref405ep_fpga_reset;
+/* Reason: only works as part of a ppc405 board */
+dc->user_creatable = false;
 }
 
+static const TypeInfo ref405ep_fpga_type = {
+.name = TYPE_REF405EP_FPGA,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(Ref405epFpgaState),
+.class_init = ref405ep_fpga_class_init,
+};
+
 /*
  * CPU reset handler when booting directly from a loaded kernel
  */
@@ -331,7 +348,11 @@ static void ref405ep_init(MachineState *machine)
 memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE, sram);
 
 /* Register FPGA */
-ref405ep_fpga_init(get_system_memory(), PPC405EP_FPGA_BASE);
+dev = qdev_new(TYPE_REF405EP_FPGA);
+object_property_add_child(OBJECT(machine), "fpga", OBJECT(dev));
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, PPC405EP_FPGA_BASE);
+
 /* Register NVRAM */
 dev = qdev_new("sysbus-m48t08");
 qdev_prop_set_int32(dev, "base-year", 1968);
@@ -376,6 +397,7 @@ static void ppc405_machine_init(void)
 {
 type_register_static(_machine_type);
 type_register_static(_type);
+type_register_static(_fpga_type);
 }
 
 type_init(ppc405_machine_init)
-- 
2.30.4




[PATCH v2 14/31] ppc4xx: Move EBC model to ppc4xx_devs.c

2022-08-17 Thread BALATON Zoltan
The EBC is shared between 405 and 440 so move it to shared file.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h |  15 
 hw/ppc/ppc405_uc.c  | 191 
 hw/ppc/ppc4xx_devs.c| 191 
 include/hw/ppc/ppc4xx.h |  15 
 4 files changed, 206 insertions(+), 206 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 8521be317d..57e1494b05 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -85,21 +85,6 @@ struct Ppc405OpbaState {
 uint8_t pr;
 };
 
-/* Peripheral controller */
-#define TYPE_PPC405_EBC "ppc405-ebc"
-OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
-struct Ppc405EbcState {
-Ppc4xxDcrDeviceState parent_obj;
-
-uint32_t addr;
-uint32_t bcr[8];
-uint32_t bap[8];
-uint32_t bear;
-uint32_t besr0;
-uint32_t besr1;
-uint32_t cfg;
-};
-
 /* DMA controller */
 #define TYPE_PPC405_DMA "ppc405-dma"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405DmaState, PPC405_DMA);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 4e875288be..c4268e4c40 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -299,192 +299,6 @@ static void ppc405_opba_class_init(ObjectClass *oc, void 
*data)
 /* Code decompression controller */
 /* XXX: TODO */
 
-/*/
-/* Peripheral controller */
-enum {
-EBC0_CFGADDR = 0x012,
-EBC0_CFGDATA = 0x013,
-};
-
-static uint32_t dcr_read_ebc(void *opaque, int dcrn)
-{
-Ppc405EbcState *ebc = opaque;
-uint32_t ret;
-
-switch (dcrn) {
-case EBC0_CFGADDR:
-ret = ebc->addr;
-break;
-case EBC0_CFGDATA:
-switch (ebc->addr) {
-case 0x00: /* B0CR */
-ret = ebc->bcr[0];
-break;
-case 0x01: /* B1CR */
-ret = ebc->bcr[1];
-break;
-case 0x02: /* B2CR */
-ret = ebc->bcr[2];
-break;
-case 0x03: /* B3CR */
-ret = ebc->bcr[3];
-break;
-case 0x04: /* B4CR */
-ret = ebc->bcr[4];
-break;
-case 0x05: /* B5CR */
-ret = ebc->bcr[5];
-break;
-case 0x06: /* B6CR */
-ret = ebc->bcr[6];
-break;
-case 0x07: /* B7CR */
-ret = ebc->bcr[7];
-break;
-case 0x10: /* B0AP */
-ret = ebc->bap[0];
-break;
-case 0x11: /* B1AP */
-ret = ebc->bap[1];
-break;
-case 0x12: /* B2AP */
-ret = ebc->bap[2];
-break;
-case 0x13: /* B3AP */
-ret = ebc->bap[3];
-break;
-case 0x14: /* B4AP */
-ret = ebc->bap[4];
-break;
-case 0x15: /* B5AP */
-ret = ebc->bap[5];
-break;
-case 0x16: /* B6AP */
-ret = ebc->bap[6];
-break;
-case 0x17: /* B7AP */
-ret = ebc->bap[7];
-break;
-case 0x20: /* BEAR */
-ret = ebc->bear;
-break;
-case 0x21: /* BESR0 */
-ret = ebc->besr0;
-break;
-case 0x22: /* BESR1 */
-ret = ebc->besr1;
-break;
-case 0x23: /* CFG */
-ret = ebc->cfg;
-break;
-default:
-ret = 0x;
-break;
-}
-break;
-default:
-ret = 0x;
-break;
-}
-
-return ret;
-}
-
-static void dcr_write_ebc(void *opaque, int dcrn, uint32_t val)
-{
-Ppc405EbcState *ebc = opaque;
-
-switch (dcrn) {
-case EBC0_CFGADDR:
-ebc->addr = val;
-break;
-case EBC0_CFGDATA:
-switch (ebc->addr) {
-case 0x00: /* B0CR */
-break;
-case 0x01: /* B1CR */
-break;
-case 0x02: /* B2CR */
-break;
-case 0x03: /* B3CR */
-break;
-case 0x04: /* B4CR */
-break;
-case 0x05: /* B5CR */
-break;
-case 0x06: /* B6CR */
-break;
-case 0x07: /* B7CR */
-break;
-case 0x10: /* B0AP */
-break;
-case 0x11: /* B1AP */
-break;
-case 0x12: /* B2AP */
-break;
-case 0x13: /* B3AP */
-break;
-case 0x14: /* B4AP */
-break;
-case 0x15: /* B5AP */
-break;
-case 0x16: /* B6AP */
-break;
-case 0x17: /* B7AP */
-break;
-case 0x20: /* BEAR */
-break;
-case 0x21: /* BESR0 */
-break;
-case 0x22: /* BESR1 */
-break;
-case 0x23: /* CFG */
-break;
-default:
-break;
-}
-break;
-default:
-break;
-}
-}
-
-static void ppc405_ebc_reset(DeviceState *dev)

  1   2   >