Re: [RFC PATCH v9 03/23] vdpa: delay set_vring_ready after DRIVER_OK

2022-07-12 Thread Michael S. Tsirkin
On Wed, Jul 06, 2022 at 08:39:48PM +0200, Eugenio Pérez wrote:
> To restore the device in the destination of a live migration we send the
> commands through control virtqueue. For a device to read CVQ it must
> have received DRIVER_OK status bit.
> 
> However this open a window where the device could start receiving
> packets in rx queue 0 before it receive the RSS configuration. To avoid
> that, we will not send vring_enable until all configuration is used by
> the device.
> 
> As a first step, reverse the DRIVER_OK and SET_VRING_ENABLE steps.
> 
> Signed-off-by: Eugenio Pérez 

Not a comment on this patch specifically, but generally:

You should know that lots of existing drivers are buggy and
try to poke at the VQs before DRIVER_OK. We are doing our best
to fix them but it's taking forever. For now it's a good
idea to support such drivers even if they are out of spec.
You do that by starting on the first kick in absence of DRIVER_OK.
Further, adding buffers before DRIVER_OK is actually allowed,
as long as you don't kick.


> ---
>  hw/virtio/vhost-vdpa.c | 22 --
>  1 file changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> index 66f054a12c..2ee8009594 100644
> --- a/hw/virtio/vhost-vdpa.c
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -728,13 +728,18 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev 
> *dev, int idx)
>  return idx;
>  }
>  
> +/**
> + * Set ready all vring of the device
> + *
> + * @dev: Vhost device
> + */
>  static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev)
>  {
>  int i;
>  trace_vhost_vdpa_set_vring_ready(dev);
> -for (i = 0; i < dev->nvqs; ++i) {
> +for (i = 0; i < dev->vq_index_end; ++i) {
>  struct vhost_vring_state state = {
> -.index = dev->vq_index + i,
> +.index = i,
>  .num = 1,
>  };
>  vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, );
> @@ -1097,7 +1102,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, 
> bool started)
>  if (unlikely(!ok)) {
>  return -1;
>  }
> -vhost_vdpa_set_vring_ready(dev);
>  } else {
>  ok = vhost_vdpa_svqs_stop(dev);
>  if (unlikely(!ok)) {
> @@ -,16 +1115,22 @@ static int vhost_vdpa_dev_start(struct vhost_dev 
> *dev, bool started)
>  }
>  
>  if (started) {
> +int r;
> +
>  memory_listener_register(>listener, _space_memory);
> -return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> +r = vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> +if (unlikely(r)) {
> +return r;
> +}
> +vhost_vdpa_set_vring_ready(dev);
>  } else {
>  vhost_vdpa_reset_device(dev);
>  vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> VIRTIO_CONFIG_S_DRIVER);
>  memory_listener_unregister(>listener);
> -
> -return 0;
>  }
> +
> +return 0;
>  }
>  
>  static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
> -- 
> 2.31.1




RE: [Virtio-fs] [Qemu] how to use viriofs in qemu without NUMA

2022-07-12 Thread Zhao, Shirley
Get it, thanks for our information. Vivek. 

Thanks. 
- Shirley 

-Original Message-
From: Vivek Goyal  
Sent: Tuesday, July 12, 2022 8:33 PM
To: Zhao, Shirley 
Cc: Dr. David Alan Gilbert ; virtio...@redhat.com; Thomas 
Huth ; qemu-devel@nongnu.org
Subject: Re: [Virtio-fs] [Qemu] how to use viriofs in qemu without NUMA

On Tue, Jul 12, 2022 at 07:06:50AM +, Zhao, Shirley wrote:
> Hi, all,
> 
> I have another question want to consult you. 
> To enable DAX in virtiofs, according to the memu 
> https://virtio-fs.gitlab.io/howto-qemu.html. 
> I need to add "cache-size=2G" as below. 
> -device 
> vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=myfs,cache-size=2G
> 
> My qemu command is: 
> sudo qemu-system-x86_64 -M pc -cpu host --enable-kvm -smp 2 -m 4G 
> -drive if=virtio,file=ubuntu.img -object 
> memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on -machine 
> q35,memory-backend=mem -chardev socket,id=char0,path=/tmp/vhostqemu 
> -device 
> vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=myfs_root,cache-si
> ze=2G -chardev stdio,mux=on,id=mon -mon chardev=mon,mode=readline 
> -device virtio-serial-pci -device virtconsole,chardev=mon -vga none 
> -display none
> 
> And virtiofsd command is:
> sudo ./virtiofsd --socket-path=/tmp/vhostqemu -o 
> source=/home/shirley/testdir -o cache=always
> 
> But there is no option of "cache-size" in qemu 6.0, like below. So how to 
> enable it? 

Hi Shirley,

DAX support in qemu is not upstream yet. We are carrying DAX patches out of the 
tree on a branch here.

https://gitlab.com/virtio-fs/qemu/-/commits/virtio-fs-dev

There are some changes required and David Gilbert is looking into making these 
changes. I am hoping at some point of time these patches will make into 
upstream.

So for the time being, to test DAX, you will have to fetch above branch, build 
it and use that qemu.

Thanks
Vivek

> qemu-6.0.0$ qemu-system-x86_64 -device vhost-user-fs-pci,help 
> vhost-user-fs-pci options:
>   acpi-index=-  (default: 0)
>   addr=   - Slot and optional function number, example: 06.0 
> or 06 (default: -1)
>   aer= - on/off (default: false)
>   any_layout=  - on/off (default: true)
>   ats= - on/off (default: false)
>   bootindex=
>   chardev=  - ID of a chardev to use as a backend
>   event_idx=   - on/off (default: true)
>   failover_pair_id=
>   indirect_desc=   - on/off (default: true)
>   iommu_platform=  - on/off (default: false)
>   migrate-extra=   - on/off (default: true)
>   modern-pio-notify= - on/off (default: false)
>   multifunction=   - on/off (default: false)
>   notify_on_empty= - on/off (default: true)
>   num-request-queues= -  (default: 1)
>   packed=  - on/off (default: false)
>   page-per-vq= - on/off (default: false)
>   queue-size=-  (default: 128)
>   rombar=-  (default: 1)
>   romfile=
>   romsize=   -  (default: 4294967295)
>   tag=
>   use-disabled-flag= -  (default: true)
>   use-started= -  (default: true)
>   vectors=   -  (default: 4294967295)
>   virtio-backend=>
>   virtio-pci-bus-master-bug-migration= - on/off (default: false)
>   x-ats-page-aligned= - on/off (default: true)
>   x-disable-legacy-check= -  (default: false)
>   x-disable-pcie=  - on/off (default: false)
>   x-ignore-backend-features= -  (default: false)
>   x-pcie-deverr-init= - on/off (default: true)
>   x-pcie-extcap-init= - on/off (default: true)
>   x-pcie-flr-init= - on/off (default: true)
>   x-pcie-lnkctl-init= - on/off (default: true)
>   x-pcie-lnksta-dllla= - on/off (default: true)
>   x-pcie-pm-init=  - on/off (default: true)
> 
> 
> -Original Message-
> From: Zhao, Shirley
> Sent: Friday, July 8, 2022 8:40 AM
> To: Dr. David Alan Gilbert 
> Cc: Thomas Huth ; qemu-devel@nongnu.org; 
> virtio...@redhat.com; Stefan Hajnoczi 
> Subject: RE: [Qemu] how to use viriofs in qemu without NUMA
> 
> Yes, the qemu version is too old. 
> My previous qemu version is 4.2, and I upgraded it into 6.0, and it worked 
> now. 
> Thanks a lot. 
> 
> - Shirley
> 
> -Original Message-
> From: Dr. David Alan Gilbert 
> Sent: Tuesday, July 5, 2022 5:37 PM
> To: Zhao, Shirley 
> Cc: Thomas Huth ; qemu-devel@nongnu.org; 
> virtio...@redhat.com; Stefan Hajnoczi 
> Subject: Re: [Qemu] how to use viriofs in qemu without NUMA
> 
> * Zhao, Shirley (shirley.z...@intel.com) wrote:
> > Thanks for the information. 
> > Yes, I also found the memory backend options on s390x, and also copy the 
> > command to x86, but failed. 
> > 
> > The following is the command used to start qemu + virtiofs + ubuntu 20.04. 
> > One is worked well using NUMA, another one is failed without NUMA. 
> > Is there anything wrong? 
> > 
> > The worked one with NUMA options: 
> > 
> > qemu-system-x86_64 -M pc -cpu host --enable-kvm -smp 2 -m 4G -object 
> > memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on -numa 
> > node,memdev=mem -chardev socket,id=char0,path=/tmp/vfsd.sock -device 

Re: [PATCH v2] target/ppc/kvm: Skip current and parent directories in kvmppc_find_cpu_dt

2022-07-12 Thread David Gibson
On Tue, Jul 12, 2022 at 06:08:10PM -0300, Murilo Opsfelder Araujo wrote:
> Some systems have /proc/device-tree/cpus/../clock-frequency. However,
> this is not the expected path for a CPU device tree directory.
> 
> Signed-off-by: Murilo Opsfelder Araujo 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: David Gibson 

and, I believe, mea culpa.

> ---
> v2:
> - Skip current and parent directories.
> 
> v1: 
> https://lore.kernel.org/qemu-devel/20220711193743.51456-1-muri...@linux.ibm.com/
> 
>  target/ppc/kvm.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 6eed466f80..466d0d2f4c 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1877,6 +1877,12 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len)
>  buf[0] = '\0';
>  while ((dirp = readdir(dp)) != NULL) {
>  FILE *f;
> +
> +/* Don't accidentally read from the current and parent directories */
> +if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 
> 0) {
> +continue;
> +}
> +
>  snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU,
>   dirp->d_name);
>  f = fopen(buf, "r");

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


signature.asc
Description: PGP signature


Re: [RFC PATCH] target/ppc: don't print TB in ppc_cpu_dump_state if it's not initialized

2022-07-12 Thread David Gibson
On Tue, Jul 12, 2022 at 06:13:44PM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 7/12/22 16:25, Matheus Ferst wrote:
> > When using "-machine none", env->tb_env is not allocated, causing the
> > segmentation fault reported in issue #85 (launchpad bug #811683). To
> > avoid this problem, check if the pointer != NULL before calling the
> > methods to print TBU/TBL/DECR.
> > 
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/85
> > Signed-off-by: Matheus Ferst 
> > ---
> > This patch fixes the reported problem, but may be an incomplete solution
> > since many other places dereference env->tb_env without checking for
> > NULL. AFAICS, "-machine none" is the only way to trigger this problem,
> > and I'm not familiar with the use-cases for this option.
> 
> The "none"  machine type is mainly used by libvirt to do instrospection
> of the available options/capabilities of the QEMU binary. It starts a QEMU
> process like the following:
> 
> ./x86_64-softmmu/qemu-system-x86_64 -S -no-user-config -nodefaults \
>   -nographic -machine none,accel=kvm:tcg -daemonize
> 
> And then it uses QMP to probe the binary.
> 
> Aside from this libvirt usage I am not aware of anyone else using -machine
> none extensively.

Right.  -machine none basically cannot work as a real machine for
POWER (maybe some other CPUs as well).  At least the more modern POWER
CPUs simply cannot boot without a bunch of supporting board/system
level elements, and there's not really a sane way to encode those into
individual emulated devices at present (maybe ever).

One of those things is that POWER expects the timebases to be
synchronized across all CPUs in the system, which obviously can't be
done locally to a single CPU chip.  It requires system level
operations, which is why it's handled by the machine type

[Example: a typical sequence which might be handled in hardware by
 low-level firmware would be to use machine-specific board-level
 registers to suspend the clock pulse to the CPUs which drives the
 timebase, then write the same value to the TB on each CPU, then
 (atomically) restart the clock pulse using board registers again]
 
> > Should we stop assuming env->tb_env != NULL and add checks everywhere?
> > Or should we find a way to provide Time Base/Decrementer for
> > "-machine none"?
> > ---
> 
> Are there other cases where env->tb_env can be NULL, aside from the case
> reported in the bug?

If there are, I'd say that's a bug in the machine type.  Setting up
(and synchronizing) the timebase is part of the machine's job.

> I don't mind the bug fix, but I'm not fond of the idea of adding additional
> checks because of this particular issue. I mean, the bug is using  the 'prep'
> machine that Thomas removed year ago in b2ce76a0730. If there's no other
> foreseeable problem, that we care about, with env->tb_env being NULL, IMO
> let's fix the bug and move on.
> 
> 
> 
> Thanks,
> 
> 
> Daniel
> 
> 
> 
> 
> >   target/ppc/cpu_init.c | 16 
> >   1 file changed, 8 insertions(+), 8 deletions(-)
> > 
> > diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> > index 86ad28466a..7e96baac9f 100644
> > --- a/target/ppc/cpu_init.c
> > +++ b/target/ppc/cpu_init.c
> > @@ -7476,18 +7476,18 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int 
> > flags)
> >"%08x iidx %d didx %d\n",
> >env->msr, env->spr[SPR_HID0], env->hflags,
> >cpu_mmu_index(env, true), cpu_mmu_index(env, false));
> > -#if !defined(NO_TIMER_DUMP)
> > -qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
> > +if (env->tb_env) {
> > +qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
> >   #if !defined(CONFIG_USER_ONLY)
> > - " DECR " TARGET_FMT_lu
> > + " DECR " TARGET_FMT_lu
> >   #endif
> > - "\n",
> > - cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
> > + "\n",
> > + cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
> >   #if !defined(CONFIG_USER_ONLY)
> > - , cpu_ppc_load_decr(env)
> > -#endif
> > -);
> > + , cpu_ppc_load_decr(env)
> >   #endif
> > +);
> > +}
> >   for (i = 0; i < 32; i++) {
> >   if ((i & (RGPL - 1)) == 0) {
> >   qemu_fprintf(f, "GPR%02d", i);
> 

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


signature.asc
Description: PGP signature


[PATCH 2/2] target/arm: Fix aarch64_sve_change_el for SME

2022-07-12 Thread Richard Henderson
We were only checking for SVE disabled and not taking into
account PSTATE.SM to check SME disabled, which resulted in
vectors being incorrectly truncated.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6fff7fc64f..24c45a9bf3 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11228,6 +11228,21 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned 
vq)
 }
 }
 
+static uint32_t sve_vqm1_for_el_sm_ena(CPUARMState *env, int el, bool sm)
+{
+int exc_el;
+
+if (sm) {
+exc_el = sme_exception_el(env, el);
+} else {
+exc_el = sve_exception_el(env, el);
+}
+if (exc_el) {
+return 0; /* disabled */
+}
+return sve_vqm1_for_el_sm(env, el, sm);
+}
+
 /*
  * Notice a change in SVE vector size when changing EL.
  */
@@ -11236,7 +11251,7 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
 {
 ARMCPU *cpu = env_archcpu(env);
 int old_len, new_len;
-bool old_a64, new_a64;
+bool old_a64, new_a64, sm;
 
 /* Nothing to do if no SVE.  */
 if (!cpu_isar_feature(aa64_sve, cpu)) {
@@ -11256,7 +11271,8 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
  * invoke ResetSVEState when taking an exception from, or
  * returning to, AArch32 state when PSTATE.SM is enabled.
  */
-if (old_a64 != new_a64 && FIELD_EX64(env->svcr, SVCR, SM)) {
+sm = FIELD_EX64(env->svcr, SVCR, SM);
+if (old_a64 != new_a64 && sm) {
 arm_reset_sve_state(env);
 return;
 }
@@ -11273,10 +11289,13 @@ void aarch64_sve_change_el(CPUARMState *env, int 
old_el,
  * we already have the correct register contents when encountering the
  * vq0->vq0 transition between EL0->EL1.
  */
-old_len = (old_a64 && !sve_exception_el(env, old_el)
-   ? sve_vqm1_for_el(env, old_el) : 0);
-new_len = (new_a64 && !sve_exception_el(env, new_el)
-   ? sve_vqm1_for_el(env, new_el) : 0);
+old_len = new_len = 0;
+if (old_a64) {
+old_len = sve_vqm1_for_el_sm_ena(env, old_el, sm);
+}
+if (new_a64) {
+new_len = sve_vqm1_for_el_sm_ena(env, new_el, sm);
+}
 
 /* When changing vector length, clear inaccessible state.  */
 if (new_len < old_len) {
-- 
2.34.1




[PATCH 1/2] target/arm: Fill in VL for tbflags when SME enabled and SVE disabled

2022-07-12 Thread Richard Henderson
When PSTATE.SM, VL = SVL even if SVE is disabled.
This is visible in kselftest ssve-test.

Reported-by: Mark Brown 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index cfcad97ce0..6fff7fc64f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10882,13 +10882,19 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState 
*env, int el, int fp_el,
 }
 if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
 int sme_el = sme_exception_el(env, el);
+bool sm = FIELD_EX64(env->svcr, SVCR, SM);
 
 DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
 if (sme_el == 0) {
 /* Similarly, do not compute SVL if SME is disabled. */
-DP_TBFLAG_A64(flags, SVL, sve_vqm1_for_el_sm(env, el, true));
+int svl = sve_vqm1_for_el_sm(env, el, true);
+DP_TBFLAG_A64(flags, SVL, svl);
+if (sm) {
+/* If SVE is disabled, we will not have set VL above. */
+DP_TBFLAG_A64(flags, VL, svl);
+}
 }
-if (FIELD_EX64(env->svcr, SVCR, SM)) {
+if (sm) {
 DP_TBFLAG_A64(flags, PSTATE_SM, 1);
 DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
 }
-- 
2.34.1




[PATCH 0/2] target/arm: Two SME fixes

2022-07-12 Thread Richard Henderson
Ho hum.  Let a feature loose on users and they find bugs.  Mark noticed
that the wrong value was being picked up for VL when SVE is disabled.
I had run the same test but failed to notice the vector length wasn't
as expected, though the test otherwise produced expected results.


r~


Richard Henderson (2):
  target/arm: Fill in VL for tbflags when SME enabled and SVE disabled
  target/arm: Fix aarch64_sve_change_el for SME

 target/arm/helper.c | 41 +
 1 file changed, 33 insertions(+), 8 deletions(-)

-- 
2.34.1




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

2022-07-12 Thread Gupta, Pankaj




This is the v7 of this series which tries to implement the fd-based KVM
guest private memory. The patches are based on latest kvm/queue branch
commit:

   b9b71f43683a (kvm/queue) KVM: x86/mmu: Buffer nested MMU
split_desc_cache only by default capacity

Introduction

In general this patch series introduce fd-based memslot which provides
guest memory through memory file descriptor fd[offset,size] instead of
hva/size. The fd can be created from a supported memory filesystem
like tmpfs/hugetlbfs etc. which we refer as memory backing store. KVM


Thinking a bit, As host side fd on tmpfs or shmem will store memory on 
host page cache instead of mapping pages into userspace address space. 
Can we hit double (un-coordinated) page cache problem with this when 
guest page cache is also used?


Thanks,
Pankaj


and the the memory backing store exchange callbacks when such memslot
gets created. At runtime KVM will call into callbacks provided by the
backing store to get the pfn with the fd+offset. Memory backing store
will also call into KVM callbacks when userspace punch hole on the fd
to notify KVM to unmap secondary MMU page table entries.

Comparing to existing hva-based memslot, this new type of memslot allows
guest memory unmapped from host userspace like QEMU and even the kernel
itself, therefore reduce attack surface and prevent bugs.

Based on this fd-based memslot, we can build guest private memory that
is going to be used in confidential computing environments such as Intel
TDX and AMD SEV. When supported, the memory backing store can provide
more enforcement on the fd and KVM can use a single memslot to hold both
the private and shared part of the guest memory.

mm extension
-
Introduces new MFD_INACCESSIBLE flag for memfd_create(), the file
created with these flags cannot read(), write() or mmap() etc via normal
MMU operations. The file content can only be used with the newly
introduced memfile_notifier extension.

The memfile_notifier extension provides two sets of callbacks for KVM to
interact with the memory backing store:
   - memfile_notifier_ops: callbacks for memory backing store to notify
 KVM when memory gets invalidated.
   - backing store callbacks: callbacks for KVM to call into memory
 backing store to request memory pages for guest private memory.

The memfile_notifier extension also provides APIs for memory backing
store to register/unregister itself and to trigger the notifier when the
bookmarked memory gets invalidated.

The patchset also introduces a new memfd seal F_SEAL_AUTO_ALLOCATE to
prevent double allocation caused by unintentional guest when we only
have a single side of the shared/private memfds effective.

memslot extension
-
Add the private fd and the fd offset to existing 'shared' memslot so
that both private/shared guest memory can live in one single memslot.
A page in the memslot is either private or shared. Whether a guest page
is private or shared is maintained through reusing existing SEV ioctls
KVM_MEMORY_ENCRYPT_{UN,}REG_REGION.

Test

To test the new functionalities of this patch TDX patchset is needed.
Since TDX patchset has not been merged so I did two kinds of test:

-  Regresion test on kvm/queue (this patchset)
Most new code are not covered. Code also in below repo:
https://github.com/chao-p/linux/tree/privmem-v7

-  New Funational test on latest TDX code
The patch is rebased to latest TDX code and tested the new
funcationalities. See below repos:
Linux: https://github.com/chao-p/linux/tree/privmem-v7-tdx
QEMU: https://github.com/chao-p/qemu/tree/privmem-v7

An example QEMU command line for TDX test:
-object tdx-guest,id=tdx,debug=off,sept-ve-disable=off \
-machine confidential-guest-support=tdx \
-object memory-backend-memfd-private,id=ram1,size=${mem} \
-machine memory-backend=ram1

Changelog
--
v7:
   - Move the private/shared info from backing store to KVM.
   - Introduce F_SEAL_AUTO_ALLOCATE to avoid double allocation.
   - Rework on the sync mechanism between zap/page fault paths.
   - Addressed other comments in v6.
v6:
   - Re-organzied patch for both mm/KVM parts.
   - Added flags for memfile_notifier so its consumers can state their
 features and memory backing store can check against these flags.
   - Put a backing store reference in the memfile_notifier and move pfn_ops
 into backing store.
   - Only support boot time backing store register.
   - Overall KVM part improvement suggested by Sean and some others.
v5:
   - Removed userspace visible F_SEAL_INACCESSIBLE, instead using an
 in-kernel flag (SHM_F_INACCESSIBLE for shmem). Private fd can only
 be created by MFD_INACCESSIBLE.
   - Introduced new APIs for backing store to register itself to
 memfile_notifier instead of direct function call.
   - Added the accounting and restriction for MFD_INACCESSIBLE memory.
   - Added KVM API doc for new memslot extensions and man page for the 

Re: loongarch missing tests/qtest/machine-none-test.c support

2022-07-12 Thread gaosong

HI, Peter

On 2022/7/12 下午11:32, Peter Maydell wrote:

The tests/qtest/machine-none-test has a cpus_map[] array which needs
to be updated to list a CPU that will work with the 'none' machine type
for the longarch64 target. This results in a warning message during
'make check':

$ QTEST_QEMU_BINARY=qemu-system-loongarch64 ./tests/qtest/machine-none-test
# random seed: R02Sb57df3405339b14ef8e45e32fb787d3d
1..1
# Start of loongarch64 tests
# Start of machine tests
# Start of none tests
WARNING: cpu name for target 'loongarch64' isn't defined, add it to cpus_map
ok 1 /loongarch64/machine/none/cpu_option
# End of none tests
# End of machine tests
# End of loongarch64 tests

Could somebody update the test appropriately, please?

I had send a patch to fix this.

Thanks.
Song Gao




[PATCH] qtest/machine-none: Add LoongArch support

2022-07-12 Thread Song Gao
Update the cpu_maps[] to support the LoongArch target.

Signed-off-by: Song Gao 
---
 tests/qtest/machine-none-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index d0f8cd9902..f92fab479f 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -54,6 +54,7 @@ static struct arch2cpu cpus_map[] = {
 { "riscv64", "rv64" },
 { "riscv32", "rv32" },
 { "rx", "rx62n" },
+{ "loongarch64", "la464"},
 };
 
 static const char *get_cpu_model_by_arch(const char *arch)
-- 
2.31.1




Re: [RFC v4 1/9] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-07-12 Thread Sam Li
Damien Le Moal  于2022年7月12日周二 15:35写道:
>
> On 7/12/22 11:13, Sam Li wrote:
> > By adding zone management operations in BlockDriver, storage
> > controller emulation can use the new block layer APIs including
> > zone_report and zone_mgmt(open, close, finish, reset).
> >
> > Signed-off-by: Sam Li 
> > ---
> >  block/block-backend.c|  41 ++
> >  block/coroutines.h   |   5 +
> >  block/file-posix.c   | 236 +++
> >  include/block/block-common.h |  43 +-
> >  include/block/block_int-common.h |  20 +++
> >  5 files changed, 344 insertions(+), 1 deletion(-)
> >
> > diff --git a/block/block-backend.c b/block/block-backend.c
> > index f425b00793..0a05247ae4 100644
> > --- a/block/block-backend.c
> > +++ b/block/block-backend.c
> > @@ -1806,6 +1806,47 @@ int blk_flush(BlockBackend *blk)
> >  return ret;
> >  }
> >
> > +/*
> > + * Send a zone_report command.
> > + * offset can be any number within the zone size. No alignment for offset.
> > + * nr_zones represents IN maximum and OUT actual.
> > + */
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +int64_t *nr_zones,
> > +BlockZoneDescriptor *zones)
> > +{
> > +int ret;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk); /* increase before waiting */
> > +blk_wait_while_drained(blk);
> > +ret = bdrv_co_zone_report(blk->root->bs, offset, nr_zones, zones);
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> > +/*
> > + * Send a zone_management command.
> > + * Offset is the start of a zone and len is aligned to zones.
> > + */
> > +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
> > +int64_t offset, int64_t len)
> > +{
> > +int ret;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk);
> > +blk_wait_while_drained(blk);
> > +ret = blk_check_byte_request(blk, offset, len);
> > +if (ret < 0) {
> > +return ret;
>
> You missed adding "blk_dec_in_flight(blk);" before return here. But I
> think you can move the call to blk_check_byte_request() before
> blk_inc_in_flight() to avoid having to call blk_dec_in_flight().

Yes, I'll just remove them.

> > +}
> > +
> > +ret = bdrv_co_zone_mgmt(blk->root->bs, op, offset, len);
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> >  void blk_drain(BlockBackend *blk)
> >  {
> >  BlockDriverState *bs = blk_bs(blk);
> > diff --git a/block/coroutines.h b/block/coroutines.h
> > index 830ecaa733..19aa96cc56 100644
> > --- a/block/coroutines.h
> > +++ b/block/coroutines.h
> > @@ -80,6 +80,11 @@ int coroutine_fn
> >  blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
> >
> >  int coroutine_fn blk_co_do_flush(BlockBackend *blk);
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +int64_t *nr_zones,
> > +BlockZoneDescriptor *zones);
> > +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
> > +  int64_t offset, int64_t len);
> >
> >
> >  /*
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index 48cd096624..e7523ae2ed 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -67,6 +67,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
>
> You need to conditionally include this because not all kernels provide
> this file. Old kernels will not have it. So you need something like:
>
> #if defined(CONFIG_BLKZONED)
> #include 
> #endif
>
> And adding this to meson.build should do the trick:
>
> diff --git a/meson.build b/meson.build
> index 65a885ea69..31d8852a35 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1869,6 +1869,7 @@ config_host_data.set('CONFIG_REPLICATION',
> get_option('live_block_migration').al
>
>  # has_header
>  config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
> +config_host_data.set('CONFIG_BLKZONED', cc.has_header('linux/blkzoned.h'))
>  config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
>  config_host_data.set('CONFIG_VALGRIND_H',
> cc.has_header('valgrind/valgrind.h'))
>  config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
>
> Then in build/config-host.h, you will see "#define CONFIG_BLKZONED". You
> then can use "#if defined(CONFIG_BLKZONED)" to conditionally define the
> code related to zoned devices.
>
> To test all this, temporarily rename your host
> /usr/include/linux/blkzoned.h file to some other name, configure qemu and
> see if it compiles.

Thanks!

> >  #include 
> >  #include 
> >  #include 
> > @@ -216,6 +217,13 @@ typedef struct RawPosixAIOData {
> >  PreallocMode prealloc;
> >  Error **errp;
> >  } truncate;
> > +struct {
> > +int64_t *nr_zones;
> > +BlockZoneDescriptor *zones;
> 

Re: [RFC v4 1/9] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-07-12 Thread Sam Li
Stefan Hajnoczi  于2022年7月12日周二 23:49写道:
>
> On Tue, Jul 12, 2022 at 10:13:37AM +0800, Sam Li wrote:
> > By adding zone management operations in BlockDriver, storage
> > controller emulation can use the new block layer APIs including
> > zone_report and zone_mgmt(open, close, finish, reset).
> >
> > Signed-off-by: Sam Li 
> > ---
> >  block/block-backend.c|  41 ++
> >  block/coroutines.h   |   5 +
> >  block/file-posix.c   | 236 +++
> >  include/block/block-common.h |  43 +-
> >  include/block/block_int-common.h |  20 +++
> >  5 files changed, 344 insertions(+), 1 deletion(-)
> >
> > diff --git a/block/block-backend.c b/block/block-backend.c
> > index f425b00793..0a05247ae4 100644
> > --- a/block/block-backend.c
> > +++ b/block/block-backend.c
> > @@ -1806,6 +1806,47 @@ int blk_flush(BlockBackend *blk)
> >  return ret;
> >  }
> >
> > +/*
> > + * Send a zone_report command.
> > + * offset can be any number within the zone size. No alignment for offset.
>
> I think offset is a byte offset from the start of the device and its
> range is [0, total_sectors * BDRV_SECTOR_SIZE)?
>
> "any number within the zone size" gives the impression that the value
> must be [0, zone_size_in_bytes), which is not right.
>
> I suggest changing the text to "offset can be any number of bytes from
> the start of the device" or similar.
>
> > + * nr_zones represents IN maximum and OUT actual.
> > + */
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +int64_t *nr_zones,
> > +BlockZoneDescriptor *zones)
> > +{
> > +int ret;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk); /* increase before waiting */
> > +blk_wait_while_drained(blk);
> > +ret = bdrv_co_zone_report(blk->root->bs, offset, nr_zones, zones);
>
> The !blk_is_available(blk) case needs to return -ENOMEDIUM before we can
> safely dereference blk->root->bs (which can also be written as
> blk_bs(blk)).
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> > +/*
> > + * Send a zone_management command.
> > + * Offset is the start of a zone and len is aligned to zones.
> > + */
> > +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
>
> Please define typedef enum { ... } BlockZoneOp instead of enum { ... }
> zone_op and then use a BlockZoneOp op argument instead of enum zone_op.
> QEMU coding style uses typedefs instead of struct foo or enum foo when
> possible.

Yes, it must be a type.

> > +int64_t offset, int64_t len)
> > +{
> > +int ret;
> > +IO_CODE();
> > +
> > +blk_inc_in_flight(blk);
> > +blk_wait_while_drained(blk);
> > +ret = blk_check_byte_request(blk, offset, len);
> > +if (ret < 0) {
> > +return ret;
> > +}
> > +
> > +ret = bdrv_co_zone_mgmt(blk->root->bs, op, offset, len);
> > +blk_dec_in_flight(blk);
> > +return ret;
> > +}
> > +
> >  void blk_drain(BlockBackend *blk)
> >  {
> >  BlockDriverState *bs = blk_bs(blk);
> > diff --git a/block/coroutines.h b/block/coroutines.h
> > index 830ecaa733..19aa96cc56 100644
> > --- a/block/coroutines.h
> > +++ b/block/coroutines.h
> > @@ -80,6 +80,11 @@ int coroutine_fn
> >  blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
> >
> >  int coroutine_fn blk_co_do_flush(BlockBackend *blk);
> > +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> > +int64_t *nr_zones,
> > +BlockZoneDescriptor *zones);
> > +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
> > +  int64_t offset, int64_t len);
> >
> >
> >  /*
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index 48cd096624..e7523ae2ed 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -67,6 +67,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -216,6 +217,13 @@ typedef struct RawPosixAIOData {
> >  PreallocMode prealloc;
> >  Error **errp;
> >  } truncate;
> > +struct {
> > +int64_t *nr_zones;
> > +BlockZoneDescriptor *zones;
> > +} zone_report;
> > +struct {
> > +zone_op op;
> > +} zone_mgmt;
> >  };
> >  } RawPosixAIOData;
> >
> > @@ -1801,6 +1809,130 @@ static off_t copy_file_range(int in_fd, off_t 
> > *in_off, int out_fd,
> >  }
> >  #endif
> >
>
> Are the functions below within #ifdef __linux__?

Maybe add them later?

> > +/*
> > + * parse_zone - Fill a zone descriptor
> > + */
> > +static inline void parse_zone(struct BlockZoneDescriptor *zone,
> > +  struct blk_zone *blkz) {
> > +zone->start = blkz->start;
> > +zone->length = blkz->len;
> > +zone->cap = blkz->capacity;
> > +

Re: [PATCH v4 3/3] migration/multifd: Report to user when zerocopy not working

2022-07-12 Thread Leonardo Bras Soares Passos
On Tue, Jul 12, 2022 at 7:42 PM Peter Xu  wrote:
>
> On Mon, Jul 11, 2022 at 06:11:13PM -0300, Leonardo Bras wrote:
> > Some errors, like the lack of Scatter-Gather support by the network
> > interface(NETIF_F_SG) may cause sendmsg(...,MSG_ZEROCOPY) to fail on using
> > zero-copy, which causes it to fall back to the default copying mechanism.
> >
> > After each full dirty-bitmap scan there should be a zero-copy flush
> > happening, which checks for errors each of the previous calls to
> > sendmsg(...,MSG_ZEROCOPY). If all of them failed to use zero-copy, then
> > increment dirty_sync_missed_zero_copy migration stat to let the user know
> > about it.
> >
> > Signed-off-by: Leonardo Bras 
> > Reviewed-by: Daniel P. Berrangé 
>
> Acked-by: Peter Xu 

Thanks Peter!

> --
> Peter Xu
>




Re: [PATCH] hw/intc/armv7m_nvic: ICPRn must not unpend an IRQ that is being held high

2022-07-12 Thread Philippe Mathieu-Daudé via

On 28/6/22 17:47, Peter Maydell wrote:

In the M-profile Arm ARM, rule R_CVJS defines when an interrupt should
be set to the Pending state:
  A) when the input line is high and the interrupt is not Active
  B) when the input line transitions from low to high and the interrupt
 is Active
(Note that the first of these is an ongoing condition, and the
second is a point-in-time event.)

This can be rephrased as:
  1 when the line goes from low to high, set Pending
  2 when Active goes from 1 to 0, if line is high then set Pending
  3 ignore attempts to clear Pending when the line is high
and Active is 0

where 1 covers both B and one of the "transition into condition A"
cases, 2 deals with the other "transition into condition A"
possibility, and 3 is "don't drop Pending if we're already in
condition A".  Transitions out of condition A don't affect Pending
state.

We handle case 1 in set_irq_level(). For an interrupt (as opposed
to other kinds of exception) the only place where we clear Active
is in armv7m_nvic_complete_irq(), where we handle case 2 by
checking for whether we need to re-pend the exception. For case 3,
the only places where we clear Pending state on an interrupt are in
armv7m_nvic_acknowledge_irq() (where we are setting Active so it
doesn't count) and for writes to NVIC_CPSRn.

It is the "write to NVIC_ICPRn" case that we missed: we must ignore
this if the input line is high and the interrupt is not Active.
(This required behaviour is differently and perhaps more clearly
stated in the v7M Arm ARM, which has pseudocode in section B3.4.1
that implies it.)

Reported-by: Igor Kotrasiński 
Signed-off-by: Peter Maydell 
---
Simple change, commit message long because I included all
the analysis that we haven't forgotten any other cases.
This is essentially the change Igor suggested in the qemu-arm
thread, but it took me a while to find time to audit the code
to confirm that was the only change we needed here.
---
  hw/intc/armv7m_nvic.c | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 13df002ce4d..1f7763964c3 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2389,8 +2389,15 @@ static MemTxResult nvic_sysreg_write(void *opaque, 
hwaddr addr,
  startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
  
  for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {

+/*
+ * Note that if the input line is still held high and the interrupt
+ * is not active then rule R_CVJS requires that the Pending state
+ * remains set; in that case we mustn't let it be cleared.
+ */
  if (value & (1 << i) &&
-(attrs.secure || s->itns[startvec + i])) {
+(attrs.secure || s->itns[startvec + i]) &&
+!(setval == 0 && s->vectors[startvec + i].level &&
+  !s->vectors[startvec + i].active)) {
  s->vectors[startvec + i].pending = setval;
  }
  }


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v4 1/3] QIOChannelSocket: Fix zero-copy flush returning code 1 when nothing sent

2022-07-12 Thread Peter Xu
On Mon, Jul 11, 2022 at 06:11:11PM -0300, Leonardo Bras wrote:
> If flush is called when no buffer was sent with MSG_ZEROCOPY, it currently
> returns 1. This return code should be used only when Linux fails to use
> MSG_ZEROCOPY on a lot of sendmsg().
> 
> Fix this by returning early from flush if no sendmsg(...,MSG_ZEROCOPY)
> was attempted.
> 
> Fixes: 2bc58ffc2926 ("QIOChannelSocket: Implement io_writev zero copy flag & 
> io_flush for CONFIG_LINUX")
> Signed-off-by: Leonardo Bras 
> Reviewed-by: Daniel P. Berrangé 
> Acked-by: Daniel P. Berrangé 
> Reviewed-by: Juan Quintela 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH] Align Raspberry Pi DMA interrupts with Linux DTS

2022-07-12 Thread Philippe Mathieu-Daudé via

+Pete/Jeremy

On 26/6/22 12:16, Peter Maydell wrote:

On Fri, 24 Jun 2022 at 21:54, Andrey Makarov  wrote:


All Raspberry Pi models 1-3 (based on bcm2835) have
Linux device tree (arch/arm/boot/dts/bcm2835-common.dtsi +25):

 /* dma channel 11-14 share one irq */

which mismatched the Qemu model.
In this patch channels 0--10 and 11--14 are handled separately.


Is there any hardware documentation that says whether QEMU or
the DTB is correct? The device tree is at best a secondary source...


There are 10 DMA channels, one is labelled "reserved".

EDK2 lists it too:
https://github.com/tianocore/edk2-platforms/blob/master/Platform/RaspberryPi/AcpiTables/AcpiTables.h#L57

I couldn't find any precise information regarding channels 11-14.


Signed-off-by: Andrey Makarov 
---
  hw/arm/bcm2835_peripherals.c | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 48538c9360..3d808b0e31 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -322,13 +322,21 @@ static void bcm2835_peripherals_realize(DeviceState *dev, 
Error **errp)
  memory_region_add_subregion(>peri_mr, DMA15_OFFSET,
  sysbus_mmio_get_region(SYS_BUS_DEVICE(>dma), 1));

-for (n = 0; n <= 12; n++) {
+for (n = 0; n <= 10; n++) {
  sysbus_connect_irq(SYS_BUS_DEVICE(>dma), n,
 qdev_get_gpio_in_named(DEVICE(>ic),
BCM2835_IC_GPU_IRQ,
INTERRUPT_DMA0 + n));
  }

+/* According to DTS, dma channels 11-14 share one irq */
+for (n = 11; n <= 14; n++) {
+sysbus_connect_irq(SYS_BUS_DEVICE(>dma), n,
+   qdev_get_gpio_in_named(DEVICE(>ic),
+  BCM2835_IC_GPU_IRQ,
+  INTERRUPT_DMA0 + 11));


You can't connect multiple qemu_irq lines to one like this.
If the hardware behaves this way then you need to create
an OR gate, wire all the lines from the devices to the
OR gate inputs, and wire the OR gate output to the destination.

thanks
-- PMM






[PULL 4/5] ui/cocoa: Take refresh rate into account

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Akihiko Odaki 

Retrieve the refresh rate of the display and reflect it with
dpy_set_ui_info() and update_displaychangelistener(), allowing the
guest and DisplayChangeListener to consume the information.

The information will be used as a hint how often the display should
be updated. For example, when we run 30 Hz physical display updates
it is pointless for the guest to update the screen at 60Hz
frequency, the guest can spare some work instead.

Signed-off-by: Akihiko Odaki 
Reviewed-by: Peter Maydell 
Message-Id: <20220702142519.12188-1-akihiko.od...@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 meson.build |  3 ++-
 ui/cocoa.m  | 12 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index ad92d288a6..fea3566ea8 100644
--- a/meson.build
+++ b/meson.build
@@ -583,7 +583,8 @@ if get_option('attr').allowed()
   endif
 endif
 
-cocoa = dependency('appleframeworks', modules: 'Cocoa', required: 
get_option('cocoa'))
+cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
+   required: get_option('cocoa'))
 if cocoa.found() and get_option('sdl').enabled()
   error('Cocoa and SDL cannot be enabled at the same time')
 endif
diff --git a/ui/cocoa.m b/ui/cocoa.m
index e883c7466e..5a8bd5dd84 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -561,8 +561,20 @@ - (void) updateUIInfoLocked
 CGDirectDisplayID display = [[description 
objectForKey:@"NSScreenNumber"] unsignedIntValue];
 NSSize screenSize = [[[self window] screen] frame].size;
 CGSize screenPhysicalSize = CGDisplayScreenSize(display);
+CVDisplayLinkRef displayLink;
 
 frameSize = isFullscreen ? screenSize : [self frame].size;
+
+if (!CVDisplayLinkCreateWithCGDisplay(display, )) {
+CVTime period = 
CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
+CVDisplayLinkRelease(displayLink);
+if (!(period.flags & kCVTimeIsIndefinite)) {
+update_displaychangelistener(,
+ 1000 * period.timeValue / 
period.timeScale);
+info.refresh_rate = (int64_t)1000 * period.timeScale / 
period.timeValue;
+}
+}
+
 info.width_mm = frameSize.width / screenSize.width * 
screenPhysicalSize.width;
 info.height_mm = frameSize.height / screenSize.height * 
screenPhysicalSize.height;
 } else {
-- 
2.36.1




Re: [PATCH v4 3/3] migration/multifd: Report to user when zerocopy not working

2022-07-12 Thread Peter Xu
On Mon, Jul 11, 2022 at 06:11:13PM -0300, Leonardo Bras wrote:
> Some errors, like the lack of Scatter-Gather support by the network
> interface(NETIF_F_SG) may cause sendmsg(...,MSG_ZEROCOPY) to fail on using
> zero-copy, which causes it to fall back to the default copying mechanism.
> 
> After each full dirty-bitmap scan there should be a zero-copy flush
> happening, which checks for errors each of the previous calls to
> sendmsg(...,MSG_ZEROCOPY). If all of them failed to use zero-copy, then
> increment dirty_sync_missed_zero_copy migration stat to let the user know
> about it.
> 
> Signed-off-by: Leonardo Bras 
> Reviewed-by: Daniel P. Berrangé 

Acked-by: Peter Xu 

-- 
Peter Xu




[PULL 2/5] configure: Restrict TCG to emulation

2022-07-12 Thread Philippe Mathieu-Daudé via
If we don't need to emulate any target, we certainly don't need TCG.

This should also help to compile again with
 ".../configure --enable-tools --disable-system --disable-user"
on systems that do not have a TCG backend.

Signed-off-by: Philippe Mathieu-Daudé 
[thuth: Re-arranged the code, remove check-softfloat from buildtest.yml]
Signed-off-by: Thomas Huth 
Reviewed-by: Richard Henderson 
Message-Id: <20220706153816.768143-1-th...@redhat.com>
---
 .gitlab-ci.d/buildtest.yml |  2 +-
 configure  | 20 ++--
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 8a4353ef93..1931b77b49 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -599,7 +599,7 @@ build-tools-and-docs-debian:
 optional: true
   variables:
 IMAGE: debian-amd64
-MAKE_CHECK_ARGS: check-unit check-softfloat ctags TAGS cscope
+MAKE_CHECK_ARGS: check-unit ctags TAGS cscope
 CONFIGURE_ARGS: --disable-system --disable-user --enable-docs 
--enable-tools
 QEMU_JOB_PUBLISH: 1
   artifacts:
diff --git a/configure b/configure
index e8cc850727..465c5000ee 100755
--- a/configure
+++ b/configure
@@ -329,7 +329,7 @@ fi
 fdt="auto"
 
 # 2. Automatically enable/disable other options
-tcg="enabled"
+tcg="auto"
 cfi="false"
 
 # parse CC options second
@@ -1409,11 +1409,6 @@ EOF
   fi
 fi
 
-if test "$tcg" = "enabled"; then
-git_submodules="$git_submodules tests/fp/berkeley-testfloat-3"
-git_submodules="$git_submodules tests/fp/berkeley-softfloat-3"
-fi
-
 if test -z "${target_list+xxx}" ; then
 default_targets=yes
 for target in $default_target_list; do
@@ -1444,6 +1439,19 @@ case " $target_list " in
   ;;
 esac
 
+if test "$tcg" = "auto"; then
+  if test -z "$target_list"; then
+tcg="disabled"
+  else
+tcg="enabled"
+  fi
+fi
+
+if test "$tcg" = "enabled"; then
+git_submodules="$git_submodules tests/fp/berkeley-testfloat-3"
+git_submodules="$git_submodules tests/fp/berkeley-softfloat-3"
+fi
+
 feature_not_found() {
   feature=$1
   remedy=$2
-- 
2.36.1




[PULL 1/5] hvf: Enable RDTSCP support

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Cameron Esfahani 

Pass through RDPID and RDTSCP support in CPUID if host supports it.
Correctly detect if CPU_BASED_TSC_OFFSET and CPU_BASED2_RDTSCP would
be supported in primary and secondary processor-based VM-execution
controls.  Enable RDTSCP in secondary processor controls if RDTSCP
support is indicated in CPUID.

Signed-off-by: Cameron Esfahani 
Message-Id: <20220214185605.28087-7-f4...@amsat.org>
Tested-by: Silvio Moioli 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1011
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/i386/hvf/hvf.c   | 26 +-
 target/i386/hvf/vmcs.h  |  3 ++-
 target/i386/hvf/x86_cpuid.c |  7 ---
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index f8833277ab..8d2248bb3f 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -221,6 +221,7 @@ int hvf_arch_init_vcpu(CPUState *cpu)
 {
 X86CPU *x86cpu = X86_CPU(cpu);
 CPUX86State *env = >env;
+uint64_t reqCap;
 
 init_emu();
 init_decoder();
@@ -257,19 +258,26 @@ int hvf_arch_init_vcpu(CPUState *cpu)
 /* set VMCS control fields */
 wvmcs(cpu->hvf->fd, VMCS_PIN_BASED_CTLS,
   cap2ctrl(hvf_state->hvf_caps->vmx_cap_pinbased,
-  VMCS_PIN_BASED_CTLS_EXTINT |
-  VMCS_PIN_BASED_CTLS_NMI |
-  VMCS_PIN_BASED_CTLS_VNMI));
+   VMCS_PIN_BASED_CTLS_EXTINT |
+   VMCS_PIN_BASED_CTLS_NMI |
+   VMCS_PIN_BASED_CTLS_VNMI));
 wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS,
   cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased,
-  VMCS_PRI_PROC_BASED_CTLS_HLT |
-  VMCS_PRI_PROC_BASED_CTLS_MWAIT |
-  VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
-  VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
+   VMCS_PRI_PROC_BASED_CTLS_HLT |
+   VMCS_PRI_PROC_BASED_CTLS_MWAIT |
+   VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
+   VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
   VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
+
+reqCap = VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES;
+
+/* Is RDTSCP support in CPUID?  If so, enable it in the VMCS. */
+if (hvf_get_supported_cpuid(0x8001, 0, R_EDX) & CPUID_EXT2_RDTSCP) {
+reqCap |= VMCS_PRI_PROC_BASED2_CTLS_RDTSCP;
+}
+
 wvmcs(cpu->hvf->fd, VMCS_SEC_PROC_BASED_CTLS,
-  cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2,
-   VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
+  cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2, reqCap));
 
 wvmcs(cpu->hvf->fd, VMCS_ENTRY_CTLS, 
cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
   0));
diff --git a/target/i386/hvf/vmcs.h b/target/i386/hvf/vmcs.h
index b4692f63f6..aee6f75dfd 100644
--- a/target/i386/hvf/vmcs.h
+++ b/target/i386/hvf/vmcs.h
@@ -354,7 +354,7 @@
 #define VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET (1 << 3)
 #define VMCS_PRI_PROC_BASED_CTLS_HLT (1 << 7)
 #define VMCS_PRI_PROC_BASED_CTLS_MWAIT (1 << 10)
-#define VMCS_PRI_PROC_BASED_CTLS_TSC   (1 << 12)
+#define VMCS_PRI_PROC_BASED_CTLS_RDTSC (1 << 12)
 #define VMCS_PRI_PROC_BASED_CTLS_CR8_LOAD  (1 << 19)
 #define VMCS_PRI_PROC_BASED_CTLS_CR8_STORE (1 << 20)
 #define VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW(1 << 21)
@@ -362,6 +362,7 @@
 #define VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL   (1 << 31)
 
 #define VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES (1 << 0)
+#define VMCS_PRI_PROC_BASED2_CTLS_RDTSCP(1 << 3)
 #define VMCS_PRI_PROC_BASED2_CTLS_X2APIC(1 << 4)
 
 enum task_switch_reason {
diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c
index f24dd50e48..7323a7a94b 100644
--- a/target/i386/hvf/x86_cpuid.c
+++ b/target/i386/hvf/x86_cpuid.c
@@ -95,7 +95,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
 ebx &= ~CPUID_7_0_EBX_INVPCID;
 }
 
-ecx &= CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ;
+ecx &= CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ |
+   CPUID_7_0_ECX_RDPID;
 edx &= CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS;
 } else {
 ebx = 0;
@@ -132,11 +133,11 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t 
idx,
 CPUID_FXSR | CPUID_EXT2_FXSR | CPUID_EXT2_PDPE1GB | 
CPUID_EXT2_3DNOWEXT |
 CPUID_EXT2_3DNOW | CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | 
CPUID_EXT2_NX;
 hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, );
-if (!(cap & CPU_BASED2_RDTSCP)) {
+if (!(cap2ctrl(cap, CPU_BASED2_RDTSCP) & CPU_BASED2_RDTSCP)) {
 edx &= ~CPUID_EXT2_RDTSCP;
 }
 hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, );
-if (!(cap & CPU_BASED_TSC_OFFSET)) {
+if (!(cap2ctrl(cap, CPU_BASED_TSC_OFFSET) & CPU_BASED_TSC_OFFSET)) {
 edx &= ~CPUID_EXT2_RDTSCP;
 }
 

Re: [PATCH] linux-user/hppa: Fix segfaults on page zero

2022-07-12 Thread Philippe Mathieu-Daudé via

On 7/7/22 21:45, Helge Deller wrote:

This program:

 int main(void) { asm("bv %r0(%r0)"); return 0; }

produces on real hardware the expected segfault:

--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x3} ---
+++ killed by SIGSEGV +++
Segmentation fault

But when run on linux-user you get instead internal qemu errors:

ERROR: linux-user/hppa/cpu_loop.c:172:cpu_loop: code should not be reached
Bail out! ERROR: linux-user/hppa/cpu_loop.c:172:cpu_loop: code should not be 
reached
ERROR: accel/tcg/cpu-exec.c:933:cpu_exec: assertion failed: (cpu == current_cpu)
Bail out! ERROR: accel/tcg/cpu-exec.c:933:cpu_exec: assertion failed: (cpu == 
current_cpu)

Fix it by adding the missing case for the EXCP_IMP trap in
cpu_loop() and raise a segfault.

Signed-off-by: Helge Deller 

diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index a576d1a249..8f374aeef6 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -143,6 +143,9 @@ void cpu_loop(CPUHPPAState *env)
  env->iaoq_f = env->gr[31];
  env->iaoq_b = env->gr[31] + 4;
  break;
+case EXCP_IMP:
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f);
+break;
  case EXCP_ILL:
  force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f);
  break;


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH] target/ppc/kvm: Skip ".." directory in kvmppc_find_cpu_dt

2022-07-12 Thread Murilo Opsfelder Araújo

Hi, Daniel, David.

On 7/12/22 10:03, Daniel Henrique Barboza wrote:



On 7/12/22 00:46, David Gibson wrote:

On Mon, Jul 11, 2022 at 04:37:43PM -0300, Murilo Opsfelder Araujo wrote:

Some systems have /proc/device-tree/cpus/../clock-frequency. However,
this is not the expected path for a CPU device tree directory.

Signed-off-by: Murilo Opsfelder Araujo 
Signed-off-by: Fabiano Rosas 
---
  target/ppc/kvm.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 6eed466f80..c8485a5cc0 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1877,6 +1877,12 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len)
  buf[0] = '\0';
  while ((dirp = readdir(dp)) != NULL) {
  FILE *f;
+
+    /* Don't accidentally read from the upper directory */
+    if (strcmp(dirp->d_name, "..") == 0) {


It might not be causing problems now, but it would be technically more
correct to also skip ".", wouldn't it?


Given that the use of this function is inside kvmppc_read_int_cpu_dt(), which
is used to read a property that belongs to a CPU node, I believe you're right.
It's better to avoid returning "PROC_DEVTREE_CPU" as well.

Murilo, can you please re-send it skipping both ".." and "." ? Better be
on the safe side.


Daniel


I've sent v2:


https://lore.kernel.org/qemu-devel/20220712210810.35514-1-muri...@linux.ibm.com/

Thank you for reviewing.

--
Murilo



Re: [PATCH v2 00/40] PS2 device QOMification - part 2

2022-07-12 Thread Philippe Mathieu-Daudé via

On 12/7/22 23:52, Mark Cave-Ayland wrote:

Here is the follow-on series from part 1 which completes the work to remove
the legacy global device init functions for PS2 devices. Now that part 1 has
been applied, the hard part to remove the PS2 function callback and argument
has been completed and all that remains is to improve the PS2 device
QOMification to allow the legacy PS2 functions to be removed.

Patches 1-11 update the pl050 device to remove the use of ps2_kbd_init() and
ps2_mouse_init(), whilst patches 12-34 make some more involved changes to
the lasips2 device (in particular completing the LASIPS2Port abstraction)
before doing the same.

Finally patches 35-40 complete the process for the pckbd (I8042 and I8042_MMIO
devices) before removing the now unused ps2_kbd_init(), ps2_mouse_init() and
i8042_mm_init() functions.

Note that this series is a migration break for the HPPA B160L and MIPS magnum
machines: I've had agreement from both Helge and Hervé that this is worth
doing to allow the use of the DeviceClass vmsd property to set the
VMStateDescription rather than manually calling vmstate_register().

Signed-off-by: Mark Cave-Ayland 

Patches still requiring review for updated commit messages (no code changes
from v1): 27, 28 and 34

v2:
- Rebase onto master
- Add A-B and R-B tags from Helge and Peter
- s/jazz/magnum/ for consistency in commit message for patch 35
- Update commit messages in patches 27 and 28 to clarify why the int_status
   bitmap isn't immediately added to the vmstate_lasips2 VMStateDescription
- Update commit message in patch 34 to detail the extra changes to the
   vmstate_lasips2 VMStateDescription


Series:
Reviewed-by: Philippe Mathieu-Daudé 





Re: [PATCH v2] Align Raspberry Pi DMA interrupts with Linux DTS

2022-07-12 Thread Philippe Mathieu-Daudé via

Hi Andrey,

On 12/7/22 12:45, Andrey Makarov wrote:

There is nothing in the specs on DMA engine interrupt lines: it should have
been in the "BCM2835 ARM Peripherals" datasheet but the appropriate
"ARM peripherals interrupt table" (p.113) is nearly empty.

All Raspberry Pi models 1-3 (based on bcm2835) have
Linux device tree (arch/arm/boot/dts/bcm2835-common.dtsi +25):

 /* dma channel 11-14 share one irq */

This information is repeated in the driver code
(drivers/dma/bcm2835-dma.c +1344):

 /*
  * in case of channel >= 11
  * use the 11th interrupt and that is shared
  */

In this patch channels 0--10 and 11--14 are handled separately.

In version v2:

1) an OR-gate is added according to review
2) a simple qtest is added for testing DMA & its interrupts

Signed-off-by: Andrey Makarov 
---
  hw/arm/bcm2835_peripherals.c |  21 +-
  include/hw/arm/bcm2835_peripherals.h |   2 +
  tests/qtest/bcm2835-dma-test.c   | 106 +++
  tests/qtest/meson.build  |   3 +-
  4 files changed, 130 insertions(+), 2 deletions(-)
  create mode 100644 tests/qtest/bcm2835-dma-test.c

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 48538c9360..5a9c472b5a 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -101,6 +101,11 @@ static void bcm2835_peripherals_init(Object *obj)
  /* DMA Channels */
  object_initialize_child(obj, "dma", >dma, TYPE_BCM2835_DMA);
  
+object_initialize_child(obj, "dma-11-14-irq-orgate",


Maybe name "shared-dma-irq-orgate"?


+>dma_11_14_irq_orgate, TYPE_OR_IRQ);


Similarly 'shared_dma' or 'orgated-dma'? But not _11_14_.


+object_property_set_int(OBJECT(>dma_11_14_irq_orgate), "num-lines", 4,


Instead of using a magic number:

#define BCM2835_SHARED_DMA_COUNT 4


+_abort);
+
  object_property_add_const_link(OBJECT(>dma), "dma-mr",
 OBJECT(>gpu_bus_mr));
  
@@ -322,13 +327,27 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)

  memory_region_add_subregion(>peri_mr, DMA15_OFFSET,
  sysbus_mmio_get_region(SYS_BUS_DEVICE(>dma), 1));
  
-for (n = 0; n <= 12; n++) {

+for (n = 0; n <= 10; n++) {


So before we could trigger IRQ #12, and now it is unbound?

Also:

#define BCM2835_DMA_CHANNELS 10


  sysbus_connect_irq(SYS_BUS_DEVICE(>dma), n,
 qdev_get_gpio_in_named(DEVICE(>ic),
BCM2835_IC_GPU_IRQ,
INTERRUPT_DMA0 + n));
  }
  
+/* According to DTS, dma channels 11-14 share one irq */

+if (!qdev_realize(DEVICE(>dma_11_14_irq_orgate), NULL, errp)) {
+return;
+}
+for (n = 11; n <= 14; n++) {


Logic simplified if you use the [0 .. BCM2835_SHARED_DMA_COUNT-1] range:

  for (n = 0; n < BCM2835_SHARED_DMA_COUNT; n++) {


+sysbus_connect_irq(SYS_BUS_DEVICE(>dma), n,


BCM2835_DMA_CHANNELS + 1 + n,


+   qdev_get_gpio_in(DEVICE(>dma_11_14_irq_orgate),
+n - 11));


n)


+}
+qdev_connect_gpio_out(DEVICE(>dma_11_14_irq_orgate), 0,
+  qdev_get_gpio_in_named(DEVICE(>ic),
+ BCM2835_IC_GPU_IRQ,
+ INTERRUPT_DMA0 + 11));
+
  /* THERMAL */
  if (!sysbus_realize(SYS_BUS_DEVICE(>thermal), errp)) {
  return;
diff --git a/include/hw/arm/bcm2835_peripherals.h 
b/include/hw/arm/bcm2835_peripherals.h
index d864879421..79e2f2771a 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -17,6 +17,7 @@
  #include "hw/char/bcm2835_aux.h"
  #include "hw/display/bcm2835_fb.h"
  #include "hw/dma/bcm2835_dma.h"
+#include "hw/or-irq.h"
  #include "hw/intc/bcm2835_ic.h"
  #include "hw/misc/bcm2835_property.h"
  #include "hw/misc/bcm2835_rng.h"
@@ -55,6 +56,7 @@ struct BCM2835PeripheralState {
  BCM2835AuxState aux;
  BCM2835FBState fb;
  BCM2835DMAState dma;
+qemu_or_irq dma_11_14_irq_orgate;
  BCM2835ICState ic;
  BCM2835PropertyState property;
  BCM2835RngState rng;


Regards,

Phil.



[PATCH v2 39/40] ps2: remove unused legacy ps2_mouse_init() function

2022-07-12 Thread Mark Cave-Ayland
Now that the legacy ps2_mouse_init() function is no longer used, it can be 
completely
removed along with its associated trace-event.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/ps2.c | 13 -
 hw/input/trace-events  |  1 -
 include/hw/input/ps2.h |  1 -
 3 files changed, 15 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 5b1728ef02..05cf7111e3 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -1236,19 +1236,6 @@ static void ps2_mouse_realize(DeviceState *dev, Error 
**errp)
 qemu_input_handler_register(dev, _mouse_handler);
 }
 
-void *ps2_mouse_init(void)
-{
-DeviceState *dev;
-PS2MouseState *s;
-
-dev = qdev_new(TYPE_PS2_MOUSE_DEVICE);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-s = PS2_MOUSE_DEVICE(dev);
-
-trace_ps2_mouse_init(s);
-return s;
-}
-
 static void ps2_kbd_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/input/trace-events b/hw/input/trace-events
index df998d13eb..29001a827d 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -41,7 +41,6 @@ ps2_mouse_fake_event(void *opaque) "%p"
 ps2_write_mouse(void *opaque, int val) "%p val %d"
 ps2_kbd_reset(void *opaque) "%p"
 ps2_mouse_reset(void *opaque) "%p"
-ps2_mouse_init(void *s) "%p"
 
 # hid.c
 hid_kbd_queue_full(void) "queue full"
diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h
index 18fd10cc75..ff777582cd 100644
--- a/include/hw/input/ps2.h
+++ b/include/hw/input/ps2.h
@@ -98,7 +98,6 @@ struct PS2MouseState {
 OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE)
 
 /* ps2.c */
-void *ps2_mouse_init(void);
 void ps2_write_mouse(PS2MouseState *s, int val);
 void ps2_write_keyboard(PS2KbdState *s, int val);
 uint32_t ps2_read_data(PS2State *s);
-- 
2.30.2




[PATCH v2 40/40] pckbd: remove legacy i8042_mm_init() function

2022-07-12 Thread Mark Cave-Ayland
This legacy function is only used during the initialisation of the MIPS magnum
machine, so inline its functionality directly into mips_jazz_init() and then
remove it.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pckbd.c | 16 
 hw/mips/jazz.c   | 13 ++---
 include/hw/input/i8042.h |  2 --
 3 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 0fc1af403e..b92b63bedc 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -762,22 +762,6 @@ static void i8042_mmio_class_init(ObjectClass *klass, void 
*data)
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
-MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
-ram_addr_t size, hwaddr mask)
-{
-DeviceState *dev;
-
-dev = qdev_new(TYPE_I8042_MMIO);
-qdev_prop_set_uint64(dev, "mask", mask);
-qdev_prop_set_uint32(dev, "size", size);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-
-qdev_connect_gpio_out(dev, I8042_KBD_IRQ, kbd_irq);
-qdev_connect_gpio_out(dev, I8042_MOUSE_IRQ, mouse_irq);
-
-return I8042_MMIO(dev);
-}
-
 static const TypeInfo i8042_mmio_info = {
 .name  = TYPE_I8042_MMIO,
 .parent= TYPE_SYS_BUS_DEVICE,
diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c
index 1eb8bd5018..6aefe9a61b 100644
--- a/hw/mips/jazz.c
+++ b/hw/mips/jazz.c
@@ -361,9 +361,16 @@ static void mips_jazz_init(MachineState *machine,
 memory_region_add_subregion(address_space, 0x80004000, rtc);
 
 /* Keyboard (i8042) */
-i8042 = i8042_mm_init(qdev_get_gpio_in(rc4030, 6),
-  qdev_get_gpio_in(rc4030, 7),
-  0x1000, 0x1);
+i8042 = I8042_MMIO(qdev_new(TYPE_I8042_MMIO));
+qdev_prop_set_uint64(DEVICE(i8042), "mask", 1);
+qdev_prop_set_uint32(DEVICE(i8042), "size", 0x1000);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(i8042), _fatal);
+
+qdev_connect_gpio_out(DEVICE(i8042), I8042_KBD_IRQ,
+  qdev_get_gpio_in(rc4030, 6));
+qdev_connect_gpio_out(DEVICE(i8042), I8042_MOUSE_IRQ,
+  qdev_get_gpio_in(rc4030, 7));
+
 memory_region_add_subregion(address_space, 0x80005000,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(i8042),
0));
diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h
index e199f1ece8..9fb3f8d787 100644
--- a/include/hw/input/i8042.h
+++ b/include/hw/input/i8042.h
@@ -88,8 +88,6 @@ struct MMIOKBDState {
 #define I8042_A20_LINE "a20"
 
 
-MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
-ram_addr_t size, hwaddr mask);
 void i8042_isa_mouse_fake_event(ISAKBDState *isa);
 void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out);
 
-- 
2.30.2




Re: [PATCH v4 2/3] Add dirty-sync-missed-zero-copy migration stat

2022-07-12 Thread Peter Xu
On Mon, Jul 11, 2022 at 06:11:12PM -0300, Leonardo Bras wrote:
> Signed-off-by: Leonardo Bras 
> Acked-by: Markus Armbruster 
> Reviewed-by: Daniel P. Berrangé 
> ---
>  qapi/migration.json   | 7 ++-
>  migration/migration.c | 2 ++
>  monitor/hmp-cmds.c| 5 +
>  3 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 7102e474a6..4a03e8f173 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -55,6 +55,10 @@
>  # @postcopy-bytes: The number of bytes sent during the post-copy phase
>  #  (since 7.0).
>  #
> +# @dirty-sync-missed-zero-copy: Number of times dirty RAM synchronization 
> could
> +#   not avoid copying dirty pages. This is 
> between
> +#   0 and @dirty-sync-count * @multifd-channels.
> +#   (since 7.1)
>  # Since: 0.14
>  ##
>  { 'struct': 'MigrationStats',
> @@ -65,7 +69,8 @@
> 'postcopy-requests' : 'int', 'page-size' : 'int',
> 'multifd-bytes' : 'uint64', 'pages-per-second' : 'uint64',
> 'precopy-bytes' : 'uint64', 'downtime-bytes' : 'uint64',
> -   'postcopy-bytes' : 'uint64' } }
> +   'postcopy-bytes' : 'uint64',
> +   'dirty-sync-missed-zero-copy' : 'uint64' } }
>  
>  ##
>  # @XBZRLECacheStats:
> diff --git a/migration/migration.c b/migration/migration.c
> index 78f5057373..048f7f8bdb 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1027,6 +1027,8 @@ static void populate_ram_info(MigrationInfo *info, 
> MigrationState *s)
>  info->ram->normal_bytes = ram_counters.normal * page_size;
>  info->ram->mbps = s->mbps;
>  info->ram->dirty_sync_count = ram_counters.dirty_sync_count;
> +info->ram->dirty_sync_missed_zero_copy =
> +ram_counters.dirty_sync_missed_zero_copy;
>  info->ram->postcopy_requests = ram_counters.postcopy_requests;
>  info->ram->page_size = page_size;
>  info->ram->multifd_bytes = ram_counters.multifd_bytes;
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index ca98df0495..a6dc79e0d5 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -307,6 +307,11 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
>  monitor_printf(mon, "postcopy ram: %" PRIu64 " kbytes\n",
> info->ram->postcopy_bytes >> 10);
>  }
> +if (info->ram->dirty_sync_missed_zero_copy) {
> +monitor_printf(mon,
> +   "Zero-copy-send fallbacks happened: %" PRIu64 " 
> times\n",
> +   info->ram->dirty_sync_missed_zero_copy);

Thanks, this looks better.  Though I think all the "dirty-sync" wordings
are still kept there, assuming flush() is bound to dirty sync even it's not
yet.  Not a big deal, but let's still keep an eye on the follow up patches..

Acked-by: Peter Xu 

-- 
Peter Xu




[PULL 0/5] Darwin patches for 2022-07-12

2022-07-12 Thread Philippe Mathieu-Daudé via
The following changes since commit 8e3d85d36b77f11ad7bded3a2d48c1f0cc334f82:

  Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging 
(2022-07-12 14:12:15 +0100)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/darwin-20220712

for you to fetch changes up to 50b13d31f4cc6c70330cc3a92561a581fc176ec9:

  avocado: Fix BUILD_DIR if it's equal to SOURCE_DIR (2022-07-13 00:06:02 +0200)


Darwin patches:

- Enable RDTSCP support on HVF
- ui/cocoa: Take refresh rate into account

Few buildsys fixes:

- Restrict TCG to emulation
- Remove a unused-but-set-variable warning
- Allow running Avocado from pseudo-"in source tree" builds



Akihiko Odaki (1):
  ui/cocoa: Take refresh rate into account

Cameron Esfahani (1):
  hvf: Enable RDTSCP support

Peter Delevoryas (2):
  ui/cocoa: Fix switched_to_fullscreen warning
  avocado: Fix BUILD_DIR if it's equal to SOURCE_DIR

Philippe Mathieu-Daudé (1):
  configure: Restrict TCG to emulation

 .gitlab-ci.d/buildtest.yml |  2 +-
 configure  | 20 ++--
 meson.build|  3 ++-
 target/i386/hvf/hvf.c  | 26 +-
 target/i386/hvf/vmcs.h |  3 ++-
 target/i386/hvf/x86_cpuid.c|  7 ---
 tests/avocado/avocado_qemu/__init__.py | 17 +
 ui/cocoa.m | 20 
 8 files changed, 61 insertions(+), 37 deletions(-)

-- 
2.36.1




[PATCH v2 38/40] pckbd: don't use legacy ps2_mouse_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 mouse device within KBDState using
object_initialize_child() in i8042_initfn() and i8042_mmio_init() and realize
it in i8042_realizefn() and i8042_mmio_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pckbd.c | 27 +++
 include/hw/input/i8042.h |  2 +-
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index cb452f2612..0fc1af403e 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -286,7 +286,7 @@ static void kbd_queue(KBDState *s, int b, int aux)
 s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD;
 kbd_safe_update_irq(s);
 } else {
-ps2_queue(aux ? s->mouse : PS2_DEVICE(>ps2kbd), b);
+ps2_queue(aux ? PS2_DEVICE(>ps2mouse) : PS2_DEVICE(>ps2kbd), b);
 }
 }
 
@@ -410,7 +410,7 @@ static uint64_t kbd_read_data(void *opaque, hwaddr addr,
 }
 s->obdata = ps2_read_data(PS2_DEVICE(>ps2kbd));
 } else if (s->obsrc & KBD_OBSRC_MOUSE) {
-s->obdata = ps2_read_data(s->mouse);
+s->obdata = ps2_read_data(PS2_DEVICE(>ps2mouse));
 } else if (s->obsrc & KBD_OBSRC_CTRL) {
 s->obdata = kbd_dequeue(s);
 }
@@ -459,7 +459,7 @@ static void kbd_write_data(void *opaque, hwaddr addr,
 outport_write(s, val);
 break;
 case KBD_CCMD_WRITE_MOUSE:
-ps2_write_mouse(s->mouse, val);
+ps2_write_mouse(>ps2mouse, val);
 /* sending data to the mouse reenables PS/2 communication */
 s->mode &= ~KBD_MODE_DISABLE_MOUSE;
 kbd_safe_update_irq(s);
@@ -704,12 +704,15 @@ static void i8042_mmio_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (!sysbus_realize(SYS_BUS_DEVICE(>ps2mouse), errp)) {
+return;
+}
+
 qdev_connect_gpio_out(DEVICE(>ps2kbd), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
 
-ks->mouse = ps2_mouse_init();
-qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ,
+qdev_connect_gpio_out(DEVICE(>ps2mouse), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
  0));
 }
@@ -722,6 +725,8 @@ static void i8042_mmio_init(Object *obj)
 ks->extended_state = true;
 
 object_initialize_child(obj, "ps2kbd", >ps2kbd, TYPE_PS2_KBD_DEVICE);
+object_initialize_child(obj, "ps2mouse", >ps2mouse,
+TYPE_PS2_MOUSE_DEVICE);
 
 qdev_init_gpio_out(DEVICE(obj), ks->irqs, 2);
 qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_kbd_irq,
@@ -785,7 +790,7 @@ void i8042_isa_mouse_fake_event(ISAKBDState *isa)
 {
 KBDState *s = >kbd;
 
-ps2_mouse_fake_event(s->mouse);
+ps2_mouse_fake_event(>ps2mouse);
 }
 
 void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out)
@@ -859,6 +864,8 @@ static void i8042_initfn(Object *obj)
   "i8042-cmd", 1);
 
 object_initialize_child(obj, "ps2kbd", >ps2kbd, TYPE_PS2_KBD_DEVICE);
+object_initialize_child(obj, "ps2mouse", >ps2mouse,
+TYPE_PS2_MOUSE_DEVICE);
 
 qdev_init_gpio_out_named(DEVICE(obj), >a20_out, I8042_A20_LINE, 1);
 
@@ -901,10 +908,14 @@ static void i8042_realizefn(DeviceState *dev, Error 
**errp)
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
 
-s->mouse = ps2_mouse_init();
-qdev_connect_gpio_out(DEVICE(s->mouse), PS2_DEVICE_IRQ,
+if (!sysbus_realize(SYS_BUS_DEVICE(>ps2mouse), errp)) {
+return;
+}
+
+qdev_connect_gpio_out(DEVICE(>ps2mouse), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
  0));
+
 if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) {
 warn_report(TYPE_I8042 ": can't enable kbd-throttle without"
 " extended-state, disabling kbd-throttle");
diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h
index 8beb0ac01f..e199f1ece8 100644
--- a/include/hw/input/i8042.h
+++ b/include/hw/input/i8042.h
@@ -32,7 +32,7 @@ typedef struct KBDState {
 uint8_t cbdata;
 uint8_t pending_tmp;
 PS2KbdState ps2kbd;
-void *mouse;
+PS2MouseState ps2mouse;
 QEMUTimer *throttle_timer;
 
 qemu_irq irqs[2];
-- 
2.30.2




Re: [RFC v4 1/9] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls.

2022-07-12 Thread Damien Le Moal
On 7/13/22 00:49, Stefan Hajnoczi wrote:
> On Tue, Jul 12, 2022 at 10:13:37AM +0800, Sam Li wrote:
>> By adding zone management operations in BlockDriver, storage
>> controller emulation can use the new block layer APIs including
>> zone_report and zone_mgmt(open, close, finish, reset).
>>
>> Signed-off-by: Sam Li 
>> ---
>>  block/block-backend.c|  41 ++
>>  block/coroutines.h   |   5 +
>>  block/file-posix.c   | 236 +++
>>  include/block/block-common.h |  43 +-
>>  include/block/block_int-common.h |  20 +++
>>  5 files changed, 344 insertions(+), 1 deletion(-)
>>
>> diff --git a/block/block-backend.c b/block/block-backend.c
>> index f425b00793..0a05247ae4 100644
>> --- a/block/block-backend.c
>> +++ b/block/block-backend.c
>> @@ -1806,6 +1806,47 @@ int blk_flush(BlockBackend *blk)
>>  return ret;
>>  }
>>  
>> +/*
>> + * Send a zone_report command.
>> + * offset can be any number within the zone size. No alignment for offset.
> 
> I think offset is a byte offset from the start of the device and its
> range is [0, total_sectors * BDRV_SECTOR_SIZE)?
> 
> "any number within the zone size" gives the impression that the value
> must be [0, zone_size_in_bytes), which is not right.
> 
> I suggest changing the text to "offset can be any number of bytes from
> the start of the device" or similar.
> 
>> + * nr_zones represents IN maximum and OUT actual.
>> + */
>> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
>> +int64_t *nr_zones,
>> +BlockZoneDescriptor *zones)
>> +{
>> +int ret;
>> +IO_CODE();
>> +
>> +blk_inc_in_flight(blk); /* increase before waiting */
>> +blk_wait_while_drained(blk);
>> +ret = bdrv_co_zone_report(blk->root->bs, offset, nr_zones, zones);
> 
> The !blk_is_available(blk) case needs to return -ENOMEDIUM before we can
> safely dereference blk->root->bs (which can also be written as
> blk_bs(blk)).
> 
>> +blk_dec_in_flight(blk);
>> +return ret;
>> +}
>> +
>> +/*
>> + * Send a zone_management command.
>> + * Offset is the start of a zone and len is aligned to zones.
>> + */
>> +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
> 
> Please define typedef enum { ... } BlockZoneOp instead of enum { ... }
> zone_op and then use a BlockZoneOp op argument instead of enum zone_op.
> QEMU coding style uses typedefs instead of struct foo or enum foo when
> possible.
> 
>> +int64_t offset, int64_t len)
>> +{
>> +int ret;
>> +IO_CODE();
>> +
>> +blk_inc_in_flight(blk);
>> +blk_wait_while_drained(blk);
>> +ret = blk_check_byte_request(blk, offset, len);
>> +if (ret < 0) {
>> +return ret;
>> +}
>> +
>> +ret = bdrv_co_zone_mgmt(blk->root->bs, op, offset, len);
>> +blk_dec_in_flight(blk);
>> +return ret;
>> +}
>> +
>>  void blk_drain(BlockBackend *blk)
>>  {
>>  BlockDriverState *bs = blk_bs(blk);
>> diff --git a/block/coroutines.h b/block/coroutines.h
>> index 830ecaa733..19aa96cc56 100644
>> --- a/block/coroutines.h
>> +++ b/block/coroutines.h
>> @@ -80,6 +80,11 @@ int coroutine_fn
>>  blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
>>  
>>  int coroutine_fn blk_co_do_flush(BlockBackend *blk);
>> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
>> +int64_t *nr_zones,
>> +BlockZoneDescriptor *zones);
>> +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, enum zone_op op,
>> +  int64_t offset, int64_t len);
>>  
>>  
>>  /*
>> diff --git a/block/file-posix.c b/block/file-posix.c
>> index 48cd096624..e7523ae2ed 100644
>> --- a/block/file-posix.c
>> +++ b/block/file-posix.c
>> @@ -67,6 +67,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -216,6 +217,13 @@ typedef struct RawPosixAIOData {
>>  PreallocMode prealloc;
>>  Error **errp;
>>  } truncate;
>> +struct {
>> +int64_t *nr_zones;
>> +BlockZoneDescriptor *zones;
>> +} zone_report;
>> +struct {
>> +zone_op op;
>> +} zone_mgmt;
>>  };
>>  } RawPosixAIOData;
>>  
>> @@ -1801,6 +1809,130 @@ static off_t copy_file_range(int in_fd, off_t 
>> *in_off, int out_fd,
>>  }
>>  #endif
>>  
> 
> Are the functions below within #ifdef __linux__?

We need more than that: linux AND blkzoned.h header present (meaning a
recent kernel). So the ifdef should be "#if defined(CONFIG_BLKZONED)" or
something like it, with CONFIG_BLKZONED defined for linux AND
/usr/include/linux/blkzoned.h present.

> 
>> +/*
>> + * parse_zone - Fill a zone descriptor
>> + */
>> +static inline void parse_zone(struct BlockZoneDescriptor *zone,
>> +  struct blk_zone *blkz) {
>> +

[PATCH v2 32/40] lasips2: don't use legacy ps2_kbd_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 keyboard device within LASIPS2KbdPort using
object_initialize_child() in lasips2_kbd_port_init() and realize it in
lasips2_kbd_port_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 10 +-
 include/hw/input/lasips2.h |  2 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 7bf6077b58..4b3264a02d 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -353,10 +353,15 @@ static const TypeInfo lasips2_port_info = {
 
 static void lasips2_kbd_port_realize(DeviceState *dev, Error **errp)
 {
+LASIPS2KbdPort *s = LASIPS2_KBD_PORT(dev);
 LASIPS2Port *lp = LASIPS2_PORT(dev);
 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp);
 
-lp->ps2dev = ps2_kbd_init();
+if (!sysbus_realize(SYS_BUS_DEVICE(>kbd), errp)) {
+return;
+}
+
+lp->ps2dev = PS2_DEVICE(>kbd);
 lpdc->parent_realize(dev, errp);
 }
 
@@ -367,6 +372,9 @@ static void lasips2_kbd_port_init(Object *obj)
 
 memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-kbd",
   0x100);
+
+object_initialize_child(obj, "kbd", >kbd, TYPE_PS2_KBD_DEVICE);
+
 lp->id = 0;
 lp->lasips2 = container_of(s, LASIPS2State, kbd_port);
 }
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 9fe9e63a66..4a0ad999d7 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -52,6 +52,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2KbdPort, LASIPS2_KBD_PORT)
 
 struct LASIPS2KbdPort {
 LASIPS2Port parent_obj;
+
+PS2KbdState kbd;
 };
 
 #define TYPE_LASIPS2_MOUSE_PORT "lasips2-mouse-port"
-- 
2.30.2




[PATCH v2 34/40] lasips2: update VMStateDescription for LASIPS2 device

2022-07-12 Thread Mark Cave-Ayland
Since this series has already introduced a migration break for the HPPA B160L
machine, we can use this opportunity to improve the VMStateDescription for
the LASIPS2 device.

Add the new int_status field to the VMStateDescription and remodel the ports
as separate VMSTATE_STRUCT instances representing each LASIPS2Port. Once this
is done, the migration stream can be updated to include buf and loopback_rbne
for each port (which is necessary since the values are accessed across separate
IO accesses), and drop the port id as this is hardcoded for each port type.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
---
 hw/input/lasips2.c | 25 +++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index e602e3c986..ea7c07a2ba 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -35,15 +35,28 @@
 #include "qapi/error.h"
 
 
+static const VMStateDescription vmstate_lasips2_port = {
+.name = "lasips2-port",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT8(control, LASIPS2Port),
+VMSTATE_UINT8(buf, LASIPS2Port),
+VMSTATE_BOOL(loopback_rbne, LASIPS2Port),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_lasips2 = {
 .name = "lasips2",
-.version_id = 0,
-.minimum_version_id = 0,
+.version_id = 1,
+.minimum_version_id = 1,
 .fields = (VMStateField[]) {
-VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State),
-VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State),
-VMSTATE_UINT8(mouse_port.parent_obj.control, LASIPS2State),
-VMSTATE_UINT8(mouse_port.parent_obj.id, LASIPS2State),
+VMSTATE_UINT8(int_status, LASIPS2State),
+VMSTATE_STRUCT(kbd_port.parent_obj, LASIPS2State, 1,
+   vmstate_lasips2_port, LASIPS2Port),
+VMSTATE_STRUCT(mouse_port.parent_obj, LASIPS2State, 1,
+   vmstate_lasips2_port, LASIPS2Port),
 VMSTATE_END_OF_LIST()
 }
 };
-- 
2.30.2




[PATCH v2 26/40] lasips2: add named input gpio to port for downstream PS2 device IRQ

2022-07-12 Thread Mark Cave-Ayland
The named input gpio is to be connected to the IRQ output of the downstream
PS2 device and used to drive the port IRQ. Initialise the named input gpio
in lasips2_port_init() and add new lasips2_port_class_init() and
lasips2_port_realize() functions to connect the PS2 device output gpio to
the new named input gpio.

Note that the reference to lasips2_port_realize() is stored in
LASIPS2PortDeviceClass but not yet used.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 32 ++--
 include/hw/input/lasips2.h |  2 ++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 10494a2322..ec1661a8f1 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -322,11 +322,35 @@ static const TypeInfo lasips2_info = {
 .class_init= lasips2_class_init,
 };
 
+static void lasips2_port_set_irq(void *opaque, int n, int level)
+{
+LASIPS2Port *s = LASIPS2_PORT(opaque);
+
+qemu_set_irq(s->irq, level);
+}
+
+static void lasips2_port_realize(DeviceState *dev, Error **errp)
+{
+LASIPS2Port *s = LASIPS2_PORT(dev);
+
+qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ,
+  qdev_get_gpio_in_named(dev, "ps2-input-irq", 0));
+}
+
 static void lasips2_port_init(Object *obj)
 {
 LASIPS2Port *s = LASIPS2_PORT(obj);
 
 qdev_init_gpio_out(DEVICE(obj), >irq, 1);
+qdev_init_gpio_in_named(DEVICE(obj), lasips2_port_set_irq,
+"ps2-input-irq", 1);
+}
+
+static void lasips2_port_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = lasips2_port_realize;
 }
 
 static const TypeInfo lasips2_port_info = {
@@ -360,8 +384,10 @@ static void lasips2_kbd_port_init(Object *obj)
 static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
+LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass);
 
-dc->realize = lasips2_kbd_port_realize;
+device_class_set_parent_realize(dc, lasips2_kbd_port_realize,
+>parent_realize);
 }
 
 static const TypeInfo lasips2_kbd_port_info = {
@@ -393,8 +419,10 @@ static void lasips2_mouse_port_init(Object *obj)
 static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
+LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass);
 
-dc->realize = lasips2_mouse_port_realize;
+device_class_set_parent_realize(dc, lasips2_mouse_port_realize,
+>parent_realize);
 }
 
 static const TypeInfo lasips2_mouse_port_info = {
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 426aa1371f..35e0aa26eb 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -30,6 +30,8 @@ OBJECT_DECLARE_TYPE(LASIPS2Port, LASIPS2PortDeviceClass, 
LASIPS2_PORT)
 
 struct LASIPS2PortDeviceClass {
 DeviceClass parent;
+
+DeviceRealize parent_realize;
 };
 
 typedef struct LASIPS2State LASIPS2State;
-- 
2.30.2




[PATCH v2 33/40] lasips2: don't use legacy ps2_mouse_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 mouse device within LASIPS2MousePort using
object_initialize_child() in lasips2_mouse_port_init() and realize it in
lasips2_mouse_port_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 10 +-
 include/hw/input/lasips2.h |  2 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 4b3264a02d..e602e3c986 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -398,10 +398,15 @@ static const TypeInfo lasips2_kbd_port_info = {
 
 static void lasips2_mouse_port_realize(DeviceState *dev, Error **errp)
 {
+LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(dev);
 LASIPS2Port *lp = LASIPS2_PORT(dev);
 LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_GET_CLASS(lp);
 
-lp->ps2dev = ps2_mouse_init();
+if (!sysbus_realize(SYS_BUS_DEVICE(>mouse), errp)) {
+return;
+}
+
+lp->ps2dev = PS2_DEVICE(>mouse);
 lpdc->parent_realize(dev, errp);
 }
 
@@ -412,6 +417,9 @@ static void lasips2_mouse_port_init(Object *obj)
 
 memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-mouse",
   0x100);
+
+object_initialize_child(obj, "mouse", >mouse, TYPE_PS2_MOUSE_DEVICE);
+
 lp->id = 1;
 lp->lasips2 = container_of(s, LASIPS2State, mouse_port);
 }
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 4a0ad999d7..01911c50f9 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -61,6 +61,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2MousePort, 
LASIPS2_MOUSE_PORT)
 
 struct LASIPS2MousePort {
 LASIPS2Port parent_obj;
+
+PS2MouseState mouse;
 };
 
 struct LASIPS2State {
-- 
2.30.2




[PATCH v2 36/40] pckbd: don't use legacy ps2_kbd_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 keyboard device within KBDState using
object_initialize_child() in i8042_initfn() and i8042_mmio_init() and realize
it in i8042_realizefn() and i8042_mmio_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pckbd.c | 29 +
 include/hw/input/i8042.h |  3 ++-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 195a64f520..cb452f2612 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -286,7 +286,7 @@ static void kbd_queue(KBDState *s, int b, int aux)
 s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD;
 kbd_safe_update_irq(s);
 } else {
-ps2_queue(aux ? s->mouse : s->kbd, b);
+ps2_queue(aux ? s->mouse : PS2_DEVICE(>ps2kbd), b);
 }
 }
 
@@ -408,7 +408,7 @@ static uint64_t kbd_read_data(void *opaque, hwaddr addr,
 timer_mod(s->throttle_timer,
   qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 1000);
 }
-s->obdata = ps2_read_data(s->kbd);
+s->obdata = ps2_read_data(PS2_DEVICE(>ps2kbd));
 } else if (s->obsrc & KBD_OBSRC_MOUSE) {
 s->obdata = ps2_read_data(s->mouse);
 } else if (s->obsrc & KBD_OBSRC_CTRL) {
@@ -429,14 +429,15 @@ static void kbd_write_data(void *opaque, hwaddr addr,
 
 switch (s->write_cmd) {
 case 0:
-ps2_write_keyboard(s->kbd, val);
+ps2_write_keyboard(>ps2kbd, val);
 /* sending data to the keyboard reenables PS/2 communication */
 s->mode &= ~KBD_MODE_DISABLE_KBD;
 kbd_safe_update_irq(s);
 break;
 case KBD_CCMD_WRITE_MODE:
 s->mode = val;
-ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0);
+ps2_keyboard_set_translation(>ps2kbd,
+ (s->mode & KBD_MODE_KCC) != 0);
 /*
  * a write to the mode byte interrupt enable flags directly updates
  * the irq lines
@@ -699,10 +700,14 @@ static void i8042_mmio_realize(DeviceState *dev, Error 
**errp)
 
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >region);
 
-ks->kbd = ps2_kbd_init();
-qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ,
+if (!sysbus_realize(SYS_BUS_DEVICE(>ps2kbd), errp)) {
+return;
+}
+
+qdev_connect_gpio_out(DEVICE(>ps2kbd), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
+
 ks->mouse = ps2_mouse_init();
 qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
@@ -716,6 +721,8 @@ static void i8042_mmio_init(Object *obj)
 
 ks->extended_state = true;
 
+object_initialize_child(obj, "ps2kbd", >ps2kbd, TYPE_PS2_KBD_DEVICE);
+
 qdev_init_gpio_out(DEVICE(obj), ks->irqs, 2);
 qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_kbd_irq,
 "ps2-kbd-input-irq", 1);
@@ -851,6 +858,8 @@ static void i8042_initfn(Object *obj)
 memory_region_init_io(isa_s->io + 1, obj, _cmd_ops, s,
   "i8042-cmd", 1);
 
+object_initialize_child(obj, "ps2kbd", >ps2kbd, TYPE_PS2_KBD_DEVICE);
+
 qdev_init_gpio_out_named(DEVICE(obj), >a20_out, I8042_A20_LINE, 1);
 
 qdev_init_gpio_out(DEVICE(obj), s->irqs, 2);
@@ -884,10 +893,14 @@ static void i8042_realizefn(DeviceState *dev, Error 
**errp)
 isa_register_ioport(isadev, isa_s->io + 0, 0x60);
 isa_register_ioport(isadev, isa_s->io + 1, 0x64);
 
-s->kbd = ps2_kbd_init();
-qdev_connect_gpio_out(DEVICE(s->kbd), PS2_DEVICE_IRQ,
+if (!sysbus_realize(SYS_BUS_DEVICE(>ps2kbd), errp)) {
+return;
+}
+
+qdev_connect_gpio_out(DEVICE(>ps2kbd), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
+
 s->mouse = ps2_mouse_init();
 qdev_connect_gpio_out(DEVICE(s->mouse), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
diff --git a/include/hw/input/i8042.h b/include/hw/input/i8042.h
index ca933d8e1b..8beb0ac01f 100644
--- a/include/hw/input/i8042.h
+++ b/include/hw/input/i8042.h
@@ -10,6 +10,7 @@
 
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
+#include "hw/input/ps2.h"
 #include "qom/object.h"
 
 #define I8042_KBD_IRQ  0
@@ -30,7 +31,7 @@ typedef struct KBDState {
 uint8_t obdata;
 uint8_t cbdata;
 uint8_t pending_tmp;
-void *kbd;
+PS2KbdState ps2kbd;
 void *mouse;
 QEMUTimer *throttle_timer;
 
-- 
2.30.2




[PATCH v2 19/40] lasips2: move keyboard port initialisation to new lasips2_kbd_port_init() function

2022-07-12 Thread Mark Cave-Ayland
Move the initialisation of the keyboard port from lasips2_init() to
a new lasips2_kbd_port_init() function which will be invoked using
object_initialize_child() during the LASIPS2 device init.

Update LASIPS2State so that it now holds the new LASIPS2KbdPort child object and
ensure that it is realised in lasips2_realize().

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 47 ++
 include/hw/input/lasips2.h |  2 +-
 2 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index f70cf893f6..74427c9990 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -40,9 +40,9 @@ static const VMStateDescription vmstate_lasips2 = {
 .version_id = 0,
 .minimum_version_id = 0,
 .fields = (VMStateField[]) {
-VMSTATE_UINT8(kbd.control, LASIPS2State),
-VMSTATE_UINT8(kbd.id, LASIPS2State),
-VMSTATE_BOOL(kbd.irq, LASIPS2State),
+VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State),
+VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State),
+VMSTATE_BOOL(kbd_port.parent_obj.irq, LASIPS2State),
 VMSTATE_UINT8(mouse.control, LASIPS2State),
 VMSTATE_UINT8(mouse.id, LASIPS2State),
 VMSTATE_BOOL(mouse.irq, LASIPS2State),
@@ -119,8 +119,8 @@ static const char *lasips2_write_reg_name(uint64_t addr)
 
 static void lasips2_update_irq(LASIPS2State *s)
 {
-trace_lasips2_intr(s->kbd.irq | s->mouse.irq);
-qemu_set_irq(s->irq, s->kbd.irq | s->mouse.irq);
+trace_lasips2_intr(s->kbd_port.parent_obj.irq | s->mouse.irq);
+qemu_set_irq(s->irq, s->kbd_port.parent_obj.irq | s->mouse.irq);
 }
 
 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
@@ -211,7 +211,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 }
 
-if (port->parent->kbd.irq || port->parent->mouse.irq) {
+if (port->parent->kbd_port.parent_obj.irq || port->parent->mouse.irq) {
 ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
@@ -240,7 +240,7 @@ static const MemoryRegionOps lasips2_reg_ops = {
 static void lasips2_set_kbd_irq(void *opaque, int n, int level)
 {
 LASIPS2State *s = LASIPS2(opaque);
-LASIPS2Port *port = >kbd;
+LASIPS2Port *port = LASIPS2_PORT(>kbd_port);
 
 port->irq = level;
 lasips2_update_irq(port->parent);
@@ -258,9 +258,15 @@ static void lasips2_set_mouse_irq(void *opaque, int n, int 
level)
 static void lasips2_realize(DeviceState *dev, Error **errp)
 {
 LASIPS2State *s = LASIPS2(dev);
+LASIPS2Port *lp;
 
-s->kbd.ps2dev = ps2_kbd_init();
-qdev_connect_gpio_out(DEVICE(s->kbd.ps2dev), PS2_DEVICE_IRQ,
+lp = LASIPS2_PORT(>kbd_port);
+if (!(qdev_realize(DEVICE(lp), NULL, errp))) {
+return;
+}
+
+lp->ps2dev = ps2_kbd_init();
+qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
 s->mouse.ps2dev = ps2_mouse_init();
@@ -272,18 +278,19 @@ static void lasips2_realize(DeviceState *dev, Error 
**errp)
 static void lasips2_init(Object *obj)
 {
 LASIPS2State *s = LASIPS2(obj);
+LASIPS2Port *lp;
+
+object_initialize_child(obj, "lasips2-kbd-port", >kbd_port,
+TYPE_LASIPS2_KBD_PORT);
 
-s->kbd.id = 0;
 s->mouse.id = 1;
-s->kbd.parent = s;
 s->mouse.parent = s;
 
-memory_region_init_io(>kbd.reg, obj, _reg_ops, >kbd,
-  "lasips2-kbd", 0x100);
 memory_region_init_io(>mouse.reg, obj, _reg_ops, >mouse,
   "lasips2-mouse", 0x100);
 
-sysbus_init_mmio(SYS_BUS_DEVICE(obj), >kbd.reg);
+lp = LASIPS2_PORT(>kbd_port);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >reg);
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mouse.reg);
 
 sysbus_init_irq(SYS_BUS_DEVICE(obj), >irq);
@@ -318,10 +325,22 @@ static const TypeInfo lasips2_port_info = {
 .abstract  = true,
 };
 
+static void lasips2_kbd_port_init(Object *obj)
+{
+LASIPS2KbdPort *s = LASIPS2_KBD_PORT(obj);
+LASIPS2Port *lp = LASIPS2_PORT(obj);
+
+memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-kbd",
+  0x100);
+lp->id = 0;
+lp->parent = container_of(s, LASIPS2State, kbd_port);
+}
+
 static const TypeInfo lasips2_kbd_port_info = {
 .name  = TYPE_LASIPS2_KBD_PORT,
 .parent= TYPE_LASIPS2_PORT,
 .instance_size = sizeof(LASIPS2KbdPort),
+.instance_init = lasips2_kbd_port_init,
 };
 
 static const TypeInfo lasips2_mouse_port_info = {
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index aab6a3500c..f728f54c78 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -60,7 +60,7 @@ struct LASIPS2MousePort {
 struct 

[PATCH v2 31/40] lasips2: switch register memory region to DEVICE_BIG_ENDIAN

2022-07-12 Thread Mark Cave-Ayland
The LASI device (and so also the LASIPS2 device) are only used for the HPPA
B160L machine which is a big endian architecture.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 09d909c843..7bf6077b58 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -245,7 +245,7 @@ static const MemoryRegionOps lasips2_reg_ops = {
 .min_access_size = 1,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };
 
 static void lasips2_realize(DeviceState *dev, Error **errp)
-- 
2.30.2




Re: [PATCH] avocado: Fix BUILD_DIR if it's equal to SOURCE_DIR

2022-07-12 Thread Peter Delevoryas
On Tue, Jul 12, 2022 at 11:53:14PM +0200, Philippe Mathieu-Daudé wrote:
> On 2/7/22 20:56, Peter Delevoryas wrote:
> > I like to build QEMU from the root source directory, rather than cd'ing
> > into the build directory. This code may as well include a search path
> > for that, so that you can run avocado tests individually without
> > specifying "-p qemu_bin=build/qemu-system-arm" manually.
> > 
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   tests/avocado/avocado_qemu/__init__.py | 17 +
> >   1 file changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/tests/avocado/avocado_qemu/__init__.py 
> > b/tests/avocado/avocado_qemu/__init__.py
> > index b656a70c55..ed4853c805 100644
> > --- a/tests/avocado/avocado_qemu/__init__.py
> > +++ b/tests/avocado/avocado_qemu/__init__.py
> > @@ -120,14 +120,15 @@ def pick_default_qemu_bin(bin_prefix='qemu-system-', 
> > arch=None):
> >   # qemu binary path does not match arch for powerpc, handle it
> >   if 'ppc64le' in arch:
> >   arch = 'ppc64'
> > -qemu_bin_relative_path = os.path.join(".", bin_prefix + arch)
> > -if is_readable_executable_file(qemu_bin_relative_path):
> > -return qemu_bin_relative_path
> > -
> > -qemu_bin_from_bld_dir_path = os.path.join(BUILD_DIR,
> > -  qemu_bin_relative_path)
> > -if is_readable_executable_file(qemu_bin_from_bld_dir_path):
> > -return qemu_bin_from_bld_dir_path
> > +qemu_bin_name = bin_prefix + arch
> > +qemu_bin_paths = [
> > +os.path.join(".", qemu_bin_name),
> > +os.path.join(BUILD_DIR, qemu_bin_name),
> > +os.path.join(BUILD_DIR, "build", qemu_bin_name),
> 
> I suppose you are building as pseudo-in-tree (see commit dedad02720:
> "configure: add support for pseudo-"in source tree" builds"). OK.

That's right, thanks for adding the reference in the commit message.

> 
> > +]
> > +for path in qemu_bin_paths:
> > +if is_readable_executable_file(path):
> > +return path
> >   return None
> 
> Reviewed-by: Philippe Mathieu-Daudé 

Thanks!!
Peter

> 
> And queued.



[PATCH v2 35/40] pckbd: introduce new vmstate_kbd_mmio VMStateDescription for the I8042_MMIO device

2022-07-12 Thread Mark Cave-Ayland
This enables us to register the VMStateDescription using the DeviceClass vmsd
property rather than having to call vmstate_register() from 
i8042_mmio_realize().

Note that this is a migration break for the MIPS magnum machine which is the 
only
user of the I8042_MMIO device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pckbd.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 9184411c3e..195a64f520 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -699,9 +699,6 @@ static void i8042_mmio_realize(DeviceState *dev, Error 
**errp)
 
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >region);
 
-/* Note we can't use dc->vmsd without breaking migration compatibility */
-vmstate_register(NULL, 0, _kbd, ks);
-
 ks->kbd = ps2_kbd_init();
 qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
@@ -732,12 +729,23 @@ static Property i8042_mmio_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const VMStateDescription vmstate_kbd_mmio = {
+.name = "pckbd-mmio",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT(kbd, MMIOKBDState, 0, vmstate_kbd, KBDState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static void i8042_mmio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->realize = i8042_mmio_realize;
 dc->reset = i8042_mmio_reset;
+dc->vmsd = _kbd_mmio;
 device_class_set_props(dc, i8042_mmio_properties);
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
-- 
2.30.2




[PATCH v2 30/40] lasips2: standardise on lp name for LASIPS2Port variables

2022-07-12 Thread Mark Cave-Ayland
This is shorter to type and keeps the naming convention consistent within the
LASIPS2 device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 52 +++---
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 0f392e2bee..09d909c843 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -139,28 +139,28 @@ static void lasips2_set_irq(void *opaque, int n, int 
level)
 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
   unsigned size)
 {
-LASIPS2Port *port = opaque;
+LASIPS2Port *lp = LASIPS2_PORT(opaque);
 
-trace_lasips2_reg_write(size, port->id, addr,
+trace_lasips2_reg_write(size, lp->id, addr,
 lasips2_write_reg_name(addr), val);
 
 switch (addr & 0xc) {
 case REG_PS2_CONTROL:
-port->control = val;
+lp->control = val;
 break;
 
 case REG_PS2_XMTDATA:
-if (port->control & LASIPS2_CONTROL_LOOPBACK) {
-port->buf = val;
-port->loopback_rbne = true;
-qemu_set_irq(port->irq, 1);
+if (lp->control & LASIPS2_CONTROL_LOOPBACK) {
+lp->buf = val;
+lp->loopback_rbne = true;
+qemu_set_irq(lp->irq, 1);
 break;
 }
 
-if (port->id) {
-ps2_write_mouse(PS2_MOUSE_DEVICE(port->ps2dev), val);
+if (lp->id) {
+ps2_write_mouse(PS2_MOUSE_DEVICE(lp->ps2dev), val);
 } else {
-ps2_write_keyboard(PS2_KBD_DEVICE(port->ps2dev), val);
+ps2_write_keyboard(PS2_KBD_DEVICE(lp->ps2dev), val);
 }
 break;
 
@@ -176,53 +176,53 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, 
uint64_t val,
 
 static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, unsigned size)
 {
-LASIPS2Port *port = opaque;
+LASIPS2Port *lp = LASIPS2_PORT(opaque);
 uint64_t ret = 0;
 
 switch (addr & 0xc) {
 case REG_PS2_ID:
-ret = port->id;
+ret = lp->id;
 break;
 
 case REG_PS2_RCVDATA:
-if (port->control & LASIPS2_CONTROL_LOOPBACK) {
-port->loopback_rbne = false;
-qemu_set_irq(port->irq, 0);
-ret = port->buf;
+if (lp->control & LASIPS2_CONTROL_LOOPBACK) {
+lp->loopback_rbne = false;
+qemu_set_irq(lp->irq, 0);
+ret = lp->buf;
 break;
 }
 
-ret = ps2_read_data(port->ps2dev);
+ret = ps2_read_data(lp->ps2dev);
 break;
 
 case REG_PS2_CONTROL:
-ret = port->control;
+ret = lp->control;
 break;
 
 case REG_PS2_STATUS:
 ret = LASIPS2_STATUS_DATSHD | LASIPS2_STATUS_CLKSHD;
 
-if (port->control & LASIPS2_CONTROL_DIAG) {
-if (!(port->control & LASIPS2_CONTROL_DATDIR)) {
+if (lp->control & LASIPS2_CONTROL_DIAG) {
+if (!(lp->control & LASIPS2_CONTROL_DATDIR)) {
 ret &= ~LASIPS2_STATUS_DATSHD;
 }
 
-if (!(port->control & LASIPS2_CONTROL_CLKDIR)) {
+if (!(lp->control & LASIPS2_CONTROL_CLKDIR)) {
 ret &= ~LASIPS2_STATUS_CLKSHD;
 }
 }
 
-if (port->control & LASIPS2_CONTROL_LOOPBACK) {
-if (port->loopback_rbne) {
+if (lp->control & LASIPS2_CONTROL_LOOPBACK) {
+if (lp->loopback_rbne) {
 ret |= LASIPS2_STATUS_RBNE;
 }
 } else {
-if (!ps2_queue_empty(port->ps2dev)) {
+if (!ps2_queue_empty(lp->ps2dev)) {
 ret |= LASIPS2_STATUS_RBNE;
 }
 }
 
-if (port->lasips2->int_status) {
+if (lp->lasips2->int_status) {
 ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
@@ -233,7 +233,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 break;
 }
 
-trace_lasips2_reg_read(size, port->id, addr,
+trace_lasips2_reg_read(size, lp->id, addr,
lasips2_read_reg_name(addr), ret);
 return ret;
 }
-- 
2.30.2




[PATCH v2 17/40] lasips2: introduce new LASIPS2_KBD_PORT QOM type

2022-07-12 Thread Mark Cave-Ayland
This will be soon be used to hold the underlying PS2_KBD_DEVICE object.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 7 +++
 include/hw/input/lasips2.h | 7 +++
 2 files changed, 14 insertions(+)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 56bfd759af..b043f2e264 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -318,10 +318,17 @@ static const TypeInfo lasips2_port_info = {
 .abstract  = true,
 };
 
+static const TypeInfo lasips2_kbd_port_info = {
+.name  = TYPE_LASIPS2_KBD_PORT,
+.parent= TYPE_LASIPS2_PORT,
+.instance_size = sizeof(LASIPS2KbdPort),
+};
+
 static void lasips2_register_types(void)
 {
 type_register_static(_info);
 type_register_static(_port_info);
+type_register_static(_kbd_port_info);
 }
 
 type_init(lasips2_register_types)
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index f4514081fe..504e2c06de 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -43,6 +43,13 @@ struct LASIPS2Port {
 bool irq;
 };
 
+#define TYPE_LASIPS2_KBD_PORT "lasips2-kbd-port"
+OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2KbdPort, LASIPS2_KBD_PORT)
+
+struct LASIPS2KbdPort {
+LASIPS2Port parent_obj;
+};
+
 struct LASIPS2State {
 SysBusDevice parent_obj;
 
-- 
2.30.2




[PULL 5/5] avocado: Fix BUILD_DIR if it's equal to SOURCE_DIR

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Peter Delevoryas 

I like to build QEMU from the root source directory [*], rather
than cd'ing into the build directory. This code may as well include
a search path for that, so that you can run avocado tests individually
without specifying "-p qemu_bin=build/qemu-system-arm" manually.

[*] See commit dedad02720 ("configure: add support for pseudo-"in source tree" 
builds")

Signed-off-by: Peter Delevoryas 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220702185604.46643-1-pe...@pjd.dev>
[PMD: Mention commit dedad02720]
Signed-off-by: Philippe Mathieu-Daudé 
---
 tests/avocado/avocado_qemu/__init__.py | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tests/avocado/avocado_qemu/__init__.py 
b/tests/avocado/avocado_qemu/__init__.py
index b656a70c55..ed4853c805 100644
--- a/tests/avocado/avocado_qemu/__init__.py
+++ b/tests/avocado/avocado_qemu/__init__.py
@@ -120,14 +120,15 @@ def pick_default_qemu_bin(bin_prefix='qemu-system-', 
arch=None):
 # qemu binary path does not match arch for powerpc, handle it
 if 'ppc64le' in arch:
 arch = 'ppc64'
-qemu_bin_relative_path = os.path.join(".", bin_prefix + arch)
-if is_readable_executable_file(qemu_bin_relative_path):
-return qemu_bin_relative_path
-
-qemu_bin_from_bld_dir_path = os.path.join(BUILD_DIR,
-  qemu_bin_relative_path)
-if is_readable_executable_file(qemu_bin_from_bld_dir_path):
-return qemu_bin_from_bld_dir_path
+qemu_bin_name = bin_prefix + arch
+qemu_bin_paths = [
+os.path.join(".", qemu_bin_name),
+os.path.join(BUILD_DIR, qemu_bin_name),
+os.path.join(BUILD_DIR, "build", qemu_bin_name),
+]
+for path in qemu_bin_paths:
+if is_readable_executable_file(path):
+return path
 return None
 
 
-- 
2.36.1




[PATCH v2 29/40] lasips2: rename LASIPS2Port parent pointer to lasips2

2022-07-12 Thread Mark Cave-Ayland
This makes it clearer that the pointer is a reference to the LASIPS2 container
device rather than an implied part of the QOM hierarchy.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 6 +++---
 include/hw/input/lasips2.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 5ceb38c1af..0f392e2bee 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -222,7 +222,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 }
 
-if (port->parent->int_status) {
+if (port->lasips2->int_status) {
 ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
@@ -368,7 +368,7 @@ static void lasips2_kbd_port_init(Object *obj)
 memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-kbd",
   0x100);
 lp->id = 0;
-lp->parent = container_of(s, LASIPS2State, kbd_port);
+lp->lasips2 = container_of(s, LASIPS2State, kbd_port);
 }
 
 static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data)
@@ -405,7 +405,7 @@ static void lasips2_mouse_port_init(Object *obj)
 memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-mouse",
   0x100);
 lp->id = 1;
-lp->parent = container_of(s, LASIPS2State, mouse_port);
+lp->lasips2 = container_of(s, LASIPS2State, mouse_port);
 }
 
 static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 7199f16622..9fe9e63a66 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -37,7 +37,7 @@ typedef struct LASIPS2State LASIPS2State;
 struct LASIPS2Port {
 DeviceState parent_obj;
 
-LASIPS2State *parent;
+LASIPS2State *lasips2;
 MemoryRegion reg;
 PS2State *ps2dev;
 uint8_t id;
-- 
2.30.2




[PATCH v2 28/40] lasips2: switch to using port-based IRQs

2022-07-12 Thread Mark Cave-Ayland
Now we can implement port-based IRQs by wiring the PS2 device IRQs to the
LASI2Port named input gpios rather than directly to the LASIPS2 device, and
generate the LASIPS2 output IRQ from the int_status bitmap representing the
individual port IRQs instead of the birq boolean.

This enables us to remove the separate PS2 keyboard and PS2 mouse named input
gpios from the LASIPS2 device and simplify the register implementation to
drive the port IRQ using qemu_set_irq() rather than accessing the LASIPS2
device IRQs directly. As a consequence the IRQ level logic in lasips2_set_irq()
can also be simplified accordingly.

For now this patch ignores adding the int_status bitmap and simply drops the
birq boolean from the vmstate_lasips2 VMStateDescription. This is because the
migration stream is already missing some required LASIPS2 fields, and as this
series already introduces a migration break for the lasips2 device it is
easiest to fix this in a follow-up patch.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
---
 hw/input/lasips2.c | 59 --
 include/hw/input/lasips2.h |  7 ++---
 2 files changed, 20 insertions(+), 46 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 013d891af6..5ceb38c1af 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -42,10 +42,8 @@ static const VMStateDescription vmstate_lasips2 = {
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State),
 VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State),
-VMSTATE_BOOL(kbd_port.parent_obj.birq, LASIPS2State),
 VMSTATE_UINT8(mouse_port.parent_obj.control, LASIPS2State),
 VMSTATE_UINT8(mouse_port.parent_obj.id, LASIPS2State),
-VMSTATE_BOOL(mouse_port.parent_obj.birq, LASIPS2State),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -119,10 +117,10 @@ static const char *lasips2_write_reg_name(uint64_t addr)
 
 static void lasips2_update_irq(LASIPS2State *s)
 {
-trace_lasips2_intr(s->kbd_port.parent_obj.birq |
-   s->mouse_port.parent_obj.birq);
-qemu_set_irq(s->irq, s->kbd_port.parent_obj.birq |
- s->mouse_port.parent_obj.birq);
+int level = s->int_status ? 1 : 0;
+
+trace_lasips2_intr(level);
+qemu_set_irq(s->irq, level);
 }
 
 static void lasips2_set_irq(void *opaque, int n, int level)
@@ -154,9 +152,8 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, 
uint64_t val,
 case REG_PS2_XMTDATA:
 if (port->control & LASIPS2_CONTROL_LOOPBACK) {
 port->buf = val;
-port->birq = true;
 port->loopback_rbne = true;
-lasips2_update_irq(port->parent);
+qemu_set_irq(port->irq, 1);
 break;
 }
 
@@ -189,9 +186,8 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 
 case REG_PS2_RCVDATA:
 if (port->control & LASIPS2_CONTROL_LOOPBACK) {
-port->birq = false;
 port->loopback_rbne = false;
-lasips2_update_irq(port->parent);
+qemu_set_irq(port->irq, 0);
 ret = port->buf;
 break;
 }
@@ -226,9 +222,8 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 }
 
-if (port->parent->kbd_port.parent_obj.birq ||
-port->parent->mouse_port.parent_obj.birq) {
-ret |= LASIPS2_STATUS_CMPINTR;
+if (port->parent->int_status) {
+ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
 
@@ -253,24 +248,6 @@ static const MemoryRegionOps lasips2_reg_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void lasips2_set_kbd_irq(void *opaque, int n, int level)
-{
-LASIPS2State *s = LASIPS2(opaque);
-LASIPS2Port *port = LASIPS2_PORT(>kbd_port);
-
-port->birq = level;
-lasips2_update_irq(port->parent);
-}
-
-static void lasips2_set_mouse_irq(void *opaque, int n, int level)
-{
-LASIPS2State *s = LASIPS2(opaque);
-LASIPS2Port *port = LASIPS2_PORT(>mouse_port);
-
-port->birq = level;
-lasips2_update_irq(port->parent);
-}
-
 static void lasips2_realize(DeviceState *dev, Error **errp)
 {
 LASIPS2State *s = LASIPS2(dev);
@@ -281,18 +258,18 @@ static void lasips2_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
-  qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
- 0));
+qdev_connect_gpio_out(DEVICE(lp), 0,
+  qdev_get_gpio_in_named(dev, "lasips2-port-input-irq",
+ lp->id));
 
 lp = LASIPS2_PORT(>mouse_port);
 if (!(qdev_realize(DEVICE(lp), NULL, errp))) {
 return;
 }
 
-qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
-  

[PATCH v2 14/40] lasips2: remove legacy lasips2_initfn() function

2022-07-12 Thread Mark Cave-Ayland
There is only one user of the legacy lasips2_initfn() function which is in
machine_hppa_init(), so inline its functionality into machine_hppa_init() and
then remove it.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/hppa/machine.c  |  6 --
 hw/input/lasips2.c | 12 
 include/hw/input/lasips2.h |  2 --
 3 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 6080037cf1..e53d5f0fa7 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -280,8 +280,10 @@ static void machine_hppa_init(MachineState *machine)
 }
 
 /* PS/2 Keyboard/Mouse */
-dev = DEVICE(lasips2_initfn(qdev_get_gpio_in(lasi_dev,
- LASI_IRQ_PS2KBD_HPA)));
+dev = qdev_new(TYPE_LASIPS2);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+   qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
0));
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 40f77baf3e..48237816a3 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -255,18 +255,6 @@ static void lasips2_set_mouse_irq(void *opaque, int n, int 
level)
 lasips2_update_irq(port->parent);
 }
 
-LASIPS2State *lasips2_initfn(qemu_irq irq)
-{
-DeviceState *dev;
-
-dev = qdev_new(TYPE_LASIPS2);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-
-sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
-
-return LASIPS2(dev);
-}
-
 static void lasips2_realize(DeviceState *dev, Error **errp)
 {
 LASIPS2State *s = LASIPS2(dev);
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index f051c970f0..868c5521d7 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -47,6 +47,4 @@ struct LASIPS2State {
 #define TYPE_LASIPS2 "lasips2"
 OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2)
 
-LASIPS2State *lasips2_initfn(qemu_irq irq);
-
 #endif /* HW_INPUT_LASIPS2_H */
-- 
2.30.2




[PULL 3/5] ui/cocoa: Fix switched_to_fullscreen warning

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Peter Delevoryas 

I noticed this error while building QEMU on Mac OS X:

[1040/1660] Compiling Objective-C object libcommon.fa.p/ui_cocoa.m.o
../ui/cocoa.m:803:17: warning: variable 'switched_to_fullscreen' set but 
not used [-Wunused-but-set-variable]
static bool switched_to_fullscreen = false;
^
1 warning generated.

I think the behavior is fine if you remove "switched_to_fullscreen", I can
still switch in and out of mouse grabbed mode and fullscreen mode with this
change, and Command keycodes will only be passed to the guest if the mouse
is grabbed, which I think is the right behavior. I'm not sure why a static
piece of state was needed to handle that in the first place. Perhaps the
refactoring of the flags-state-change fixed that by toggling the Command
keycode on.

I tested this with an Ubuntu core image on macOS 12.4

wget 
https://cdimage.ubuntu.com/ubuntu-core/18/stable/current/ubuntu-core-18-i386.img.xz
xz -d ubuntu-core-18-i386.img.xz
qemu-system-x86_64 -drive file=ubuntu-core-18.i386.img,format=raw

Fixes: 6d73bb643aa7 ("ui/cocoa: Clear modifiers whenever possible")
Signed-off-by: Peter Delevoryas 
Reviewed-by: Akihiko Odaki 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20220702044304.90553-1-pe...@pjd.dev>
Signed-off-by: Philippe Mathieu-Daudé 
---
 ui/cocoa.m | 8 
 1 file changed, 8 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 6a4dccff7f..e883c7466e 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -800,7 +800,6 @@ - (bool) handleEventLocked:(NSEvent *)event
 int buttons = 0;
 int keycode = 0;
 bool mouse_event = false;
-static bool switched_to_fullscreen = false;
 // Location of event in virtual screen coordinates
 NSPoint p = [self screenLocationOfEvent:event];
 NSUInteger modifiers = [event modifierFlags];
@@ -952,13 +951,6 @@ - (bool) handleEventLocked:(NSEvent *)event
 
 // forward command key combos to the host UI unless the mouse is 
grabbed
 if (!isMouseGrabbed && ([event modifierFlags] & 
NSEventModifierFlagCommand)) {
-/*
- * Prevent the command key from being stuck down in the guest
- * when using Command-F to switch to full screen mode.
- */
-if (keycode == Q_KEY_CODE_F) {
-switched_to_fullscreen = true;
-}
 return false;
 }
 
-- 
2.36.1




[PATCH v2 27/40] lasips2: add named input gpio to handle incoming port IRQs

2022-07-12 Thread Mark Cave-Ayland
The LASIPS2 device named input gpio is soon to be connected to the port output
IRQs. Add a new int_status field to LASIPS2State which is a bitmap representing
the port input IRQ status which will be enabled in the next patch.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
---
 hw/input/lasips2.c | 15 +++
 include/hw/input/lasips2.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index ec1661a8f1..013d891af6 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -125,6 +125,19 @@ static void lasips2_update_irq(LASIPS2State *s)
  s->mouse_port.parent_obj.birq);
 }
 
+static void lasips2_set_irq(void *opaque, int n, int level)
+{
+LASIPS2State *s = LASIPS2(opaque);
+
+if (level) {
+s->int_status |= BIT(n);
+} else {
+s->int_status &= ~BIT(n);
+}
+
+lasips2_update_irq(s);
+}
+
 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
   unsigned size)
 {
@@ -303,6 +316,8 @@ static void lasips2_init(Object *obj)
 "ps2-kbd-input-irq", 1);
 qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_mouse_irq,
 "ps2-mouse-input-irq", 1);
+qdev_init_gpio_in_named(DEVICE(obj), lasips2_set_irq,
+"lasips2-port-input-irq", 2);
 }
 
 static void lasips2_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 35e0aa26eb..b79febf64b 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -69,6 +69,7 @@ struct LASIPS2State {
 
 LASIPS2KbdPort kbd_port;
 LASIPS2MousePort mouse_port;
+uint8_t int_status;
 qemu_irq irq;
 };
 
-- 
2.30.2




[PATCH v2 25/40] lasips2: introduce LASIPS2PortDeviceClass for the LASIPS2_PORT device

2022-07-12 Thread Mark Cave-Ayland
This will soon be used to store the reference to the LASIPS2_PORT parent device
for LASIPS2_KBD_PORT and LASIPS2_MOUSE_PORT.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 2 ++
 include/hw/input/lasips2.h | 6 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 6b53153838..10494a2322 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -334,6 +334,8 @@ static const TypeInfo lasips2_port_info = {
 .parent= TYPE_DEVICE,
 .instance_init = lasips2_port_init,
 .instance_size = sizeof(LASIPS2Port),
+.class_init= lasips2_port_class_init,
+.class_size= sizeof(LASIPS2PortDeviceClass),
 .abstract  = true,
 };
 
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index a05f26cbd9..426aa1371f 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -26,7 +26,11 @@
 #include "hw/input/ps2.h"
 
 #define TYPE_LASIPS2_PORT "lasips2-port"
-OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2Port, LASIPS2_PORT)
+OBJECT_DECLARE_TYPE(LASIPS2Port, LASIPS2PortDeviceClass, LASIPS2_PORT)
+
+struct LASIPS2PortDeviceClass {
+DeviceClass parent;
+};
 
 typedef struct LASIPS2State LASIPS2State;
 
-- 
2.30.2




[PATCH v2 15/40] lasips2: change LASIPS2State dev pointer from void to PS2State

2022-07-12 Thread Mark Cave-Ayland
This allows the compiler to enforce that the PS2 device pointer is always of
type PS2State. Update the name of the pointer from dev to ps2dev to emphasise
this type change.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 16 
 include/hw/input/lasips2.h |  3 ++-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 48237816a3..b539c4de7a 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -146,9 +146,9 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, 
uint64_t val,
 }
 
 if (port->id) {
-ps2_write_mouse(port->dev, val);
+ps2_write_mouse(PS2_MOUSE_DEVICE(port->ps2dev), val);
 } else {
-ps2_write_keyboard(port->dev, val);
+ps2_write_keyboard(PS2_KBD_DEVICE(port->ps2dev), val);
 }
 break;
 
@@ -181,7 +181,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 break;
 }
 
-ret = ps2_read_data(port->dev);
+ret = ps2_read_data(port->ps2dev);
 break;
 
 case REG_PS2_CONTROL:
@@ -206,7 +206,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 ret |= LASIPS2_STATUS_RBNE;
 }
 } else {
-if (!ps2_queue_empty(port->dev)) {
+if (!ps2_queue_empty(port->ps2dev)) {
 ret |= LASIPS2_STATUS_RBNE;
 }
 }
@@ -259,12 +259,12 @@ static void lasips2_realize(DeviceState *dev, Error 
**errp)
 {
 LASIPS2State *s = LASIPS2(dev);
 
-s->kbd.dev = ps2_kbd_init();
-qdev_connect_gpio_out(DEVICE(s->kbd.dev), PS2_DEVICE_IRQ,
+s->kbd.ps2dev = ps2_kbd_init();
+qdev_connect_gpio_out(DEVICE(s->kbd.ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
-s->mouse.dev = ps2_mouse_init();
-qdev_connect_gpio_out(DEVICE(s->mouse.dev), PS2_DEVICE_IRQ,
+s->mouse.ps2dev = ps2_mouse_init();
+qdev_connect_gpio_out(DEVICE(s->mouse.ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
  0));
 }
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 868c5521d7..9746b7a132 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -23,12 +23,13 @@
 
 #include "exec/hwaddr.h"
 #include "hw/sysbus.h"
+#include "hw/input/ps2.h"
 
 struct LASIPS2State;
 typedef struct LASIPS2Port {
 struct LASIPS2State *parent;
 MemoryRegion reg;
-void *dev;
+PS2State *ps2dev;
 uint8_t id;
 uint8_t control;
 uint8_t buf;
-- 
2.30.2




[PATCH v2 24/40] lasips2: introduce port IRQ and new lasips2_port_init() function

2022-07-12 Thread Mark Cave-Ayland
Introduce a new lasips2_port_init() QOM init function for the LASIPS2_PORT type
and use it to initialise a new gpio for use as a port IRQ. Add a new qemu_irq
representing the gpio as a new irq field within LASIPS2Port.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 8 
 include/hw/input/lasips2.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 49e5c90b73..6b53153838 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -322,9 +322,17 @@ static const TypeInfo lasips2_info = {
 .class_init= lasips2_class_init,
 };
 
+static void lasips2_port_init(Object *obj)
+{
+LASIPS2Port *s = LASIPS2_PORT(obj);
+
+qdev_init_gpio_out(DEVICE(obj), >irq, 1);
+}
+
 static const TypeInfo lasips2_port_info = {
 .name  = TYPE_LASIPS2_PORT,
 .parent= TYPE_DEVICE,
+.instance_init = lasips2_port_init,
 .instance_size = sizeof(LASIPS2Port),
 .abstract  = true,
 };
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 4c4b471737..a05f26cbd9 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -41,6 +41,7 @@ struct LASIPS2Port {
 uint8_t buf;
 bool loopback_rbne;
 bool birq;
+qemu_irq irq;
 };
 
 #define TYPE_LASIPS2_KBD_PORT "lasips2-kbd-port"
-- 
2.30.2




[PATCH v2 18/40] lasips2: introduce new LASIPS2_MOUSE_PORT QOM type

2022-07-12 Thread Mark Cave-Ayland
This will be soon be used to hold the underlying PS2_MOUSE_DEVICE object.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 7 +++
 include/hw/input/lasips2.h | 7 +++
 2 files changed, 14 insertions(+)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index b043f2e264..f70cf893f6 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -324,11 +324,18 @@ static const TypeInfo lasips2_kbd_port_info = {
 .instance_size = sizeof(LASIPS2KbdPort),
 };
 
+static const TypeInfo lasips2_mouse_port_info = {
+.name  = TYPE_LASIPS2_MOUSE_PORT,
+.parent= TYPE_LASIPS2_PORT,
+.instance_size = sizeof(LASIPS2MousePort),
+};
+
 static void lasips2_register_types(void)
 {
 type_register_static(_info);
 type_register_static(_port_info);
 type_register_static(_kbd_port_info);
+type_register_static(_mouse_port_info);
 }
 
 type_init(lasips2_register_types)
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 504e2c06de..aab6a3500c 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -50,6 +50,13 @@ struct LASIPS2KbdPort {
 LASIPS2Port parent_obj;
 };
 
+#define TYPE_LASIPS2_MOUSE_PORT "lasips2-mouse-port"
+OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2MousePort, LASIPS2_MOUSE_PORT)
+
+struct LASIPS2MousePort {
+LASIPS2Port parent_obj;
+};
+
 struct LASIPS2State {
 SysBusDevice parent_obj;
 
-- 
2.30.2




[PATCH v2 10/40] pl050: don't use legacy ps2_kbd_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 keyboard device within PL050KbdState using
object_initialize_child() in pl050_kbd_init() and realize it in
pl050_kbd_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 13 ++---
 include/hw/input/pl050.h |  2 ++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index fcc40758a3..64b579e877 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -160,17 +160,24 @@ static void pl050_realize(DeviceState *dev, Error **errp)
 static void pl050_kbd_realize(DeviceState *dev, Error **errp)
 {
 PL050DeviceClass *pdc = PL050_GET_CLASS(dev);
+PL050KbdState *s = PL050_KBD_DEVICE(dev);
 PL050State *ps = PL050(dev);
 
-ps->ps2dev = ps2_kbd_init();
+if (!sysbus_realize(SYS_BUS_DEVICE(>kbd), errp)) {
+return;
+}
+
+ps->ps2dev = PS2_DEVICE(>kbd);
 pdc->parent_realize(dev, errp);
 }
 
 static void pl050_kbd_init(Object *obj)
 {
-PL050State *s = PL050(obj);
+PL050KbdState *s = PL050_KBD_DEVICE(obj);
+PL050State *ps = PL050(obj);
 
-s->is_mouse = false;
+ps->is_mouse = false;
+object_initialize_child(obj, "kbd", >kbd, TYPE_PS2_KBD_DEVICE);
 }
 
 static void pl050_mouse_realize(DeviceState *dev, Error **errp)
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index 203f03a194..28f6216dc3 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -43,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PL050KbdState, PL050_KBD_DEVICE)
 
 struct PL050KbdState {
 PL050State parent_obj;
+
+PS2KbdState kbd;
 };
 
 #define TYPE_PL050_MOUSE_DEVICE "pl050_mouse"
-- 
2.30.2




[PATCH v2 37/40] ps2: remove unused legacy ps2_kbd_init() function

2022-07-12 Thread Mark Cave-Ayland
Now that the legacy ps2_kbd_init() function is no longer used, it can be 
completely
removed along with its associated trace-event.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/ps2.c | 13 -
 hw/input/trace-events  |  1 -
 include/hw/input/ps2.h |  1 -
 3 files changed, 15 deletions(-)

diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 59bac28ac8..5b1728ef02 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -1224,19 +1224,6 @@ static void ps2_kbd_realize(DeviceState *dev, Error 
**errp)
 qemu_input_handler_register(dev, _keyboard_handler);
 }
 
-void *ps2_kbd_init(void)
-{
-DeviceState *dev;
-PS2KbdState *s;
-
-dev = qdev_new(TYPE_PS2_KBD_DEVICE);
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
-s = PS2_KBD_DEVICE(dev);
-
-trace_ps2_kbd_init(s);
-return s;
-}
-
 static QemuInputHandler ps2_mouse_handler = {
 .name  = "QEMU PS/2 Mouse",
 .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
diff --git a/hw/input/trace-events b/hw/input/trace-events
index e0bfe7f3ee..df998d13eb 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -41,7 +41,6 @@ ps2_mouse_fake_event(void *opaque) "%p"
 ps2_write_mouse(void *opaque, int val) "%p val %d"
 ps2_kbd_reset(void *opaque) "%p"
 ps2_mouse_reset(void *opaque) "%p"
-ps2_kbd_init(void *s) "%p"
 ps2_mouse_init(void *s) "%p"
 
 # hid.c
diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h
index a78619d8cb..18fd10cc75 100644
--- a/include/hw/input/ps2.h
+++ b/include/hw/input/ps2.h
@@ -98,7 +98,6 @@ struct PS2MouseState {
 OBJECT_DECLARE_SIMPLE_TYPE(PS2MouseState, PS2_MOUSE_DEVICE)
 
 /* ps2.c */
-void *ps2_kbd_init(void);
 void *ps2_mouse_init(void);
 void ps2_write_mouse(PS2MouseState *s, int val);
 void ps2_write_keyboard(PS2KbdState *s, int val);
-- 
2.30.2




[PATCH v2 21/40] lasips2: introduce lasips2_kbd_port_class_init() and lasips2_kbd_port_realize()

2022-07-12 Thread Mark Cave-Ayland
Introduce a new lasips2_kbd_port_class_init() function which uses a new
lasips2_kbd_port_realize() function to initialise the PS2 keyboard device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 9535cab268..b4fdaed5cb 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -268,7 +268,6 @@ static void lasips2_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-lp->ps2dev = ps2_kbd_init();
 qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
@@ -331,6 +330,13 @@ static const TypeInfo lasips2_port_info = {
 .abstract  = true,
 };
 
+static void lasips2_kbd_port_realize(DeviceState *dev, Error **errp)
+{
+LASIPS2Port *lp = LASIPS2_PORT(dev);
+
+lp->ps2dev = ps2_kbd_init();
+}
+
 static void lasips2_kbd_port_init(Object *obj)
 {
 LASIPS2KbdPort *s = LASIPS2_KBD_PORT(obj);
@@ -342,11 +348,19 @@ static void lasips2_kbd_port_init(Object *obj)
 lp->parent = container_of(s, LASIPS2State, kbd_port);
 }
 
+static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = lasips2_kbd_port_realize;
+}
+
 static const TypeInfo lasips2_kbd_port_info = {
 .name  = TYPE_LASIPS2_KBD_PORT,
 .parent= TYPE_LASIPS2_PORT,
 .instance_size = sizeof(LASIPS2KbdPort),
 .instance_init = lasips2_kbd_port_init,
+.class_init= lasips2_kbd_port_class_init,
 };
 
 static void lasips2_mouse_port_init(Object *obj)
-- 
2.30.2




[PATCH v2 16/40] lasips2: QOMify LASIPS2Port

2022-07-12 Thread Mark Cave-Ayland
This becomes an abstract QOM type which will be a parent type for separate
keyboard and mouse port types.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c |  8 
 include/hw/input/lasips2.h | 14 ++
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index b539c4de7a..56bfd759af 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -311,9 +311,17 @@ static const TypeInfo lasips2_info = {
 .class_init= lasips2_class_init,
 };
 
+static const TypeInfo lasips2_port_info = {
+.name  = TYPE_LASIPS2_PORT,
+.parent= TYPE_DEVICE,
+.instance_size = sizeof(LASIPS2Port),
+.abstract  = true,
+};
+
 static void lasips2_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_port_info);
 }
 
 type_init(lasips2_register_types)
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 9746b7a132..f4514081fe 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -25,9 +25,15 @@
 #include "hw/sysbus.h"
 #include "hw/input/ps2.h"
 
-struct LASIPS2State;
-typedef struct LASIPS2Port {
-struct LASIPS2State *parent;
+#define TYPE_LASIPS2_PORT "lasips2-port"
+OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2Port, LASIPS2_PORT)
+
+typedef struct LASIPS2State LASIPS2State;
+
+struct LASIPS2Port {
+DeviceState parent_obj;
+
+LASIPS2State *parent;
 MemoryRegion reg;
 PS2State *ps2dev;
 uint8_t id;
@@ -35,7 +41,7 @@ typedef struct LASIPS2Port {
 uint8_t buf;
 bool loopback_rbne;
 bool irq;
-} LASIPS2Port;
+};
 
 struct LASIPS2State {
 SysBusDevice parent_obj;
-- 
2.30.2




[PATCH v2 08/40] pl050: introduce pl050_kbd_class_init() and pl050_kbd_realize()

2022-07-12 Thread Mark Cave-Ayland
Introduce a new pl050_kbd_class_init() function containing a call to
device_class_set_parent_realize() which calls a new pl050_kbd_realize()
function to initialise the PS2 keyboard device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index d7796b73a1..24363c007e 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -155,14 +155,21 @@ static void pl050_realize(DeviceState *dev, Error **errp)
 
 if (s->is_mouse) {
 s->ps2dev = ps2_mouse_init();
-} else {
-s->ps2dev = ps2_kbd_init();
 }
 
 qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-input-irq", 0));
 }
 
+static void pl050_kbd_realize(DeviceState *dev, Error **errp)
+{
+PL050DeviceClass *pdc = PL050_GET_CLASS(dev);
+PL050State *ps = PL050(dev);
+
+ps->ps2dev = ps2_kbd_init();
+pdc->parent_realize(dev, errp);
+}
+
 static void pl050_kbd_init(Object *obj)
 {
 PL050State *s = PL050(obj);
@@ -177,11 +184,21 @@ static void pl050_mouse_init(Object *obj)
 s->is_mouse = true;
 }
 
+static void pl050_kbd_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+PL050DeviceClass *pdc = PL050_CLASS(oc);
+
+device_class_set_parent_realize(dc, pl050_kbd_realize,
+>parent_realize);
+}
+
 static const TypeInfo pl050_kbd_info = {
 .name  = TYPE_PL050_KBD_DEVICE,
 .parent= TYPE_PL050,
 .instance_init = pl050_kbd_init,
 .instance_size = sizeof(PL050KbdState),
+.class_init= pl050_kbd_class_init,
 };
 
 static const TypeInfo pl050_mouse_info = {
-- 
2.30.2




[PATCH v2 23/40] lasips2: rename LASIPS2Port irq field to birq

2022-07-12 Thread Mark Cave-Ayland
The existing boolean irq field in LASIPS2Port will soon be replaced by a proper
qemu_irq, so rename the field to birq to allow the upcoming qemu_irq to use the
irq name.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 24 
 include/hw/input/lasips2.h |  2 +-
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index ce87c66f2a..49e5c90b73 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -42,10 +42,10 @@ static const VMStateDescription vmstate_lasips2 = {
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State),
 VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State),
-VMSTATE_BOOL(kbd_port.parent_obj.irq, LASIPS2State),
+VMSTATE_BOOL(kbd_port.parent_obj.birq, LASIPS2State),
 VMSTATE_UINT8(mouse_port.parent_obj.control, LASIPS2State),
 VMSTATE_UINT8(mouse_port.parent_obj.id, LASIPS2State),
-VMSTATE_BOOL(mouse_port.parent_obj.irq, LASIPS2State),
+VMSTATE_BOOL(mouse_port.parent_obj.birq, LASIPS2State),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -119,10 +119,10 @@ static const char *lasips2_write_reg_name(uint64_t addr)
 
 static void lasips2_update_irq(LASIPS2State *s)
 {
-trace_lasips2_intr(s->kbd_port.parent_obj.irq |
-   s->mouse_port.parent_obj.irq);
-qemu_set_irq(s->irq, s->kbd_port.parent_obj.irq |
- s->mouse_port.parent_obj.irq);
+trace_lasips2_intr(s->kbd_port.parent_obj.birq |
+   s->mouse_port.parent_obj.birq);
+qemu_set_irq(s->irq, s->kbd_port.parent_obj.birq |
+ s->mouse_port.parent_obj.birq);
 }
 
 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
@@ -141,7 +141,7 @@ static void lasips2_reg_write(void *opaque, hwaddr addr, 
uint64_t val,
 case REG_PS2_XMTDATA:
 if (port->control & LASIPS2_CONTROL_LOOPBACK) {
 port->buf = val;
-port->irq = true;
+port->birq = true;
 port->loopback_rbne = true;
 lasips2_update_irq(port->parent);
 break;
@@ -176,7 +176,7 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 
 case REG_PS2_RCVDATA:
 if (port->control & LASIPS2_CONTROL_LOOPBACK) {
-port->irq = false;
+port->birq = false;
 port->loopback_rbne = false;
 lasips2_update_irq(port->parent);
 ret = port->buf;
@@ -213,8 +213,8 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 }
 
-if (port->parent->kbd_port.parent_obj.irq ||
-port->parent->mouse_port.parent_obj.irq) {
+if (port->parent->kbd_port.parent_obj.birq ||
+port->parent->mouse_port.parent_obj.birq) {
 ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
@@ -245,7 +245,7 @@ static void lasips2_set_kbd_irq(void *opaque, int n, int 
level)
 LASIPS2State *s = LASIPS2(opaque);
 LASIPS2Port *port = LASIPS2_PORT(>kbd_port);
 
-port->irq = level;
+port->birq = level;
 lasips2_update_irq(port->parent);
 }
 
@@ -254,7 +254,7 @@ static void lasips2_set_mouse_irq(void *opaque, int n, int 
level)
 LASIPS2State *s = LASIPS2(opaque);
 LASIPS2Port *port = LASIPS2_PORT(>mouse_port);
 
-port->irq = level;
+port->birq = level;
 lasips2_update_irq(port->parent);
 }
 
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 84807bec36..4c4b471737 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -40,7 +40,7 @@ struct LASIPS2Port {
 uint8_t control;
 uint8_t buf;
 bool loopback_rbne;
-bool irq;
+bool birq;
 };
 
 #define TYPE_LASIPS2_KBD_PORT "lasips2-kbd-port"
-- 
2.30.2




[PATCH v2 20/40] lasips2: move mouse port initialisation to new lasips2_mouse_port_init() function

2022-07-12 Thread Mark Cave-Ayland
Move the initialisation of the mouse port from lasips2_init() to
a new lasips2_mouse_port_init() function which will be invoked using
object_initialize_child() during the LASIPS2 device init.

Update LASIPS2State so that it now holds the new LASIPS2MousePort child object 
and
ensure that it is realised in lasips2_realize().

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 52 +-
 include/hw/input/lasips2.h |  2 +-
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 74427c9990..9535cab268 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -43,9 +43,9 @@ static const VMStateDescription vmstate_lasips2 = {
 VMSTATE_UINT8(kbd_port.parent_obj.control, LASIPS2State),
 VMSTATE_UINT8(kbd_port.parent_obj.id, LASIPS2State),
 VMSTATE_BOOL(kbd_port.parent_obj.irq, LASIPS2State),
-VMSTATE_UINT8(mouse.control, LASIPS2State),
-VMSTATE_UINT8(mouse.id, LASIPS2State),
-VMSTATE_BOOL(mouse.irq, LASIPS2State),
+VMSTATE_UINT8(mouse_port.parent_obj.control, LASIPS2State),
+VMSTATE_UINT8(mouse_port.parent_obj.id, LASIPS2State),
+VMSTATE_BOOL(mouse_port.parent_obj.irq, LASIPS2State),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -119,8 +119,10 @@ static const char *lasips2_write_reg_name(uint64_t addr)
 
 static void lasips2_update_irq(LASIPS2State *s)
 {
-trace_lasips2_intr(s->kbd_port.parent_obj.irq | s->mouse.irq);
-qemu_set_irq(s->irq, s->kbd_port.parent_obj.irq | s->mouse.irq);
+trace_lasips2_intr(s->kbd_port.parent_obj.irq |
+   s->mouse_port.parent_obj.irq);
+qemu_set_irq(s->irq, s->kbd_port.parent_obj.irq |
+ s->mouse_port.parent_obj.irq);
 }
 
 static void lasips2_reg_write(void *opaque, hwaddr addr, uint64_t val,
@@ -211,8 +213,9 @@ static uint64_t lasips2_reg_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 }
 
-if (port->parent->kbd_port.parent_obj.irq || port->parent->mouse.irq) {
-ret |= LASIPS2_STATUS_CMPINTR;
+if (port->parent->kbd_port.parent_obj.irq ||
+port->parent->mouse_port.parent_obj.irq) {
+ret |= LASIPS2_STATUS_CMPINTR;
 }
 break;
 
@@ -249,7 +252,7 @@ static void lasips2_set_kbd_irq(void *opaque, int n, int 
level)
 static void lasips2_set_mouse_irq(void *opaque, int n, int level)
 {
 LASIPS2State *s = LASIPS2(opaque);
-LASIPS2Port *port = >mouse;
+LASIPS2Port *port = LASIPS2_PORT(>mouse_port);
 
 port->irq = level;
 lasips2_update_irq(port->parent);
@@ -269,8 +272,14 @@ static void lasips2_realize(DeviceState *dev, Error **errp)
 qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
  0));
-s->mouse.ps2dev = ps2_mouse_init();
-qdev_connect_gpio_out(DEVICE(s->mouse.ps2dev), PS2_DEVICE_IRQ,
+
+lp = LASIPS2_PORT(>mouse_port);
+if (!(qdev_realize(DEVICE(lp), NULL, errp))) {
+return;
+}
+
+lp->ps2dev = ps2_mouse_init();
+qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
  0));
 }
@@ -282,16 +291,13 @@ static void lasips2_init(Object *obj)
 
 object_initialize_child(obj, "lasips2-kbd-port", >kbd_port,
 TYPE_LASIPS2_KBD_PORT);
-
-s->mouse.id = 1;
-s->mouse.parent = s;
-
-memory_region_init_io(>mouse.reg, obj, _reg_ops, >mouse,
-  "lasips2-mouse", 0x100);
+object_initialize_child(obj, "lasips2-mouse-port", >mouse_port,
+TYPE_LASIPS2_MOUSE_PORT);
 
 lp = LASIPS2_PORT(>kbd_port);
 sysbus_init_mmio(SYS_BUS_DEVICE(obj), >reg);
-sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mouse.reg);
+lp = LASIPS2_PORT(>mouse_port);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >reg);
 
 sysbus_init_irq(SYS_BUS_DEVICE(obj), >irq);
 
@@ -343,10 +349,22 @@ static const TypeInfo lasips2_kbd_port_info = {
 .instance_init = lasips2_kbd_port_init,
 };
 
+static void lasips2_mouse_port_init(Object *obj)
+{
+LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(obj);
+LASIPS2Port *lp = LASIPS2_PORT(obj);
+
+memory_region_init_io(>reg, obj, _reg_ops, lp, "lasips2-mouse",
+  0x100);
+lp->id = 1;
+lp->parent = container_of(s, LASIPS2State, mouse_port);
+}
+
 static const TypeInfo lasips2_mouse_port_info = {
 .name  = TYPE_LASIPS2_MOUSE_PORT,
 .parent= TYPE_LASIPS2_PORT,
 .instance_size = sizeof(LASIPS2MousePort),
+.instance_init = lasips2_mouse_port_init,
 };
 
 static void lasips2_register_types(void)
diff --git 

[PATCH v2 13/40] lasips2: remove the qdev base property and the lasips2_properties array

2022-07-12 Thread Mark Cave-Ayland
The base property was only needed for use by vmstate_register() in order to
preserve migration compatibility. Now that the lasips2 migration state is
registered through the DeviceClass vmsd field, the base property and also
the lasips2_properties array can be removed completely as they are no longer
required.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/hppa/machine.c  | 3 +--
 hw/input/lasips2.c | 9 +
 include/hw/input/lasips2.h | 3 +--
 3 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 44ecd446c3..6080037cf1 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -280,8 +280,7 @@ static void machine_hppa_init(MachineState *machine)
 }
 
 /* PS/2 Keyboard/Mouse */
-dev = DEVICE(lasips2_initfn(LASI_PS2KBD_HPA,
-qdev_get_gpio_in(lasi_dev,
+dev = DEVICE(lasips2_initfn(qdev_get_gpio_in(lasi_dev,
  LASI_IRQ_PS2KBD_HPA)));
 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index d4fa248729..40f77baf3e 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -255,12 +255,11 @@ static void lasips2_set_mouse_irq(void *opaque, int n, 
int level)
 lasips2_update_irq(port->parent);
 }
 
-LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq)
+LASIPS2State *lasips2_initfn(qemu_irq irq)
 {
 DeviceState *dev;
 
 dev = qdev_new(TYPE_LASIPS2);
-qdev_prop_set_uint64(dev, "base", base);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
@@ -307,18 +306,12 @@ static void lasips2_init(Object *obj)
 "ps2-mouse-input-irq", 1);
 }
 
-static Property lasips2_properties[] = {
-DEFINE_PROP_UINT64("base", LASIPS2State, base, UINT64_MAX),
-DEFINE_PROP_END_OF_LIST(),
-};
-
 static void lasips2_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->realize = lasips2_realize;
 dc->vmsd = _lasips2;
-device_class_set_props(dc, lasips2_properties);
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
diff --git a/include/hw/input/lasips2.h b/include/hw/input/lasips2.h
index 03f0c9e9f9..f051c970f0 100644
--- a/include/hw/input/lasips2.h
+++ b/include/hw/input/lasips2.h
@@ -39,7 +39,6 @@ typedef struct LASIPS2Port {
 struct LASIPS2State {
 SysBusDevice parent_obj;
 
-hwaddr base;
 LASIPS2Port kbd;
 LASIPS2Port mouse;
 qemu_irq irq;
@@ -48,6 +47,6 @@ struct LASIPS2State {
 #define TYPE_LASIPS2 "lasips2"
 OBJECT_DECLARE_SIMPLE_TYPE(LASIPS2State, LASIPS2)
 
-LASIPS2State *lasips2_initfn(hwaddr base, qemu_irq irq);
+LASIPS2State *lasips2_initfn(qemu_irq irq);
 
 #endif /* HW_INPUT_LASIPS2_H */
-- 
2.30.2




[PATCH v2 05/40] pl050: introduce new PL050_MOUSE_DEVICE QOM type

2022-07-12 Thread Mark Cave-Ayland
This will be soon be used to hold the underlying PS2_MOUSE_DEVICE object.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 3 ++-
 include/hw/input/pl050.h | 7 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 7f4ac99081..88459997e0 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -189,9 +189,10 @@ static const TypeInfo pl050_kbd_info = {
 };
 
 static const TypeInfo pl050_mouse_info = {
-.name  = "pl050_mouse",
+.name  = TYPE_PL050_MOUSE_DEVICE,
 .parent= TYPE_PL050,
 .instance_init = pl050_mouse_init,
+.instance_size = sizeof(PL050MouseState),
 };
 
 static void pl050_init(Object *obj)
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index 9ce8794bd0..bb0e87ff45 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -39,4 +39,11 @@ struct PL050KbdState {
 PL050State parent_obj;
 };
 
+#define TYPE_PL050_MOUSE_DEVICE "pl050_mouse"
+OBJECT_DECLARE_SIMPLE_TYPE(PL050MouseState, PL050_MOUSE_DEVICE)
+
+struct PL050MouseState {
+PL050State parent_obj;
+};
+
 #endif
-- 
2.30.2




[PATCH v2 09/40] pl050: introduce pl050_mouse_class_init() and pl050_mouse_realize()

2022-07-12 Thread Mark Cave-Ayland
Introduce a new pl050_mouse_class_init() function containing a call to
device_class_set_parent_realize() which calls a new pl050_mouse_realize()
function to initialise the PS2 mouse device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 24363c007e..fcc40758a3 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -153,10 +153,6 @@ static void pl050_realize(DeviceState *dev, Error **errp)
 {
 PL050State *s = PL050(dev);
 
-if (s->is_mouse) {
-s->ps2dev = ps2_mouse_init();
-}
-
 qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-input-irq", 0));
 }
@@ -177,6 +173,15 @@ static void pl050_kbd_init(Object *obj)
 s->is_mouse = false;
 }
 
+static void pl050_mouse_realize(DeviceState *dev, Error **errp)
+{
+PL050DeviceClass *pdc = PL050_GET_CLASS(dev);
+PL050State *ps = PL050(dev);
+
+ps->ps2dev = ps2_mouse_init();
+pdc->parent_realize(dev, errp);
+}
+
 static void pl050_mouse_init(Object *obj)
 {
 PL050State *s = PL050(obj);
@@ -201,11 +206,21 @@ static const TypeInfo pl050_kbd_info = {
 .class_init= pl050_kbd_class_init,
 };
 
+static void pl050_mouse_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+PL050DeviceClass *pdc = PL050_CLASS(oc);
+
+device_class_set_parent_realize(dc, pl050_mouse_realize,
+>parent_realize);
+}
+
 static const TypeInfo pl050_mouse_info = {
 .name  = TYPE_PL050_MOUSE_DEVICE,
 .parent= TYPE_PL050,
 .instance_init = pl050_mouse_init,
 .instance_size = sizeof(PL050MouseState),
+.class_init= pl050_mouse_class_init,
 };
 
 static void pl050_init(Object *obj)
-- 
2.30.2




[PATCH v2 22/40] lasips2: introduce lasips2_mouse_port_class_init() and lasips2_mouse_port_realize()

2022-07-12 Thread Mark Cave-Ayland
Introduce a new lasips2_mouse_port_class_init() function which uses a new
lasips2_mouse_port_realize() function to initialise the PS2 mouse device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index b4fdaed5cb..ce87c66f2a 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -277,7 +277,6 @@ static void lasips2_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-lp->ps2dev = ps2_mouse_init();
 qdev_connect_gpio_out(DEVICE(lp->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
  0));
@@ -363,6 +362,13 @@ static const TypeInfo lasips2_kbd_port_info = {
 .class_init= lasips2_kbd_port_class_init,
 };
 
+static void lasips2_mouse_port_realize(DeviceState *dev, Error **errp)
+{
+LASIPS2Port *lp = LASIPS2_PORT(dev);
+
+lp->ps2dev = ps2_mouse_init();
+}
+
 static void lasips2_mouse_port_init(Object *obj)
 {
 LASIPS2MousePort *s = LASIPS2_MOUSE_PORT(obj);
@@ -374,11 +380,19 @@ static void lasips2_mouse_port_init(Object *obj)
 lp->parent = container_of(s, LASIPS2State, mouse_port);
 }
 
+static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = lasips2_mouse_port_realize;
+}
+
 static const TypeInfo lasips2_mouse_port_info = {
 .name  = TYPE_LASIPS2_MOUSE_PORT,
 .parent= TYPE_LASIPS2_PORT,
 .instance_size = sizeof(LASIPS2MousePort),
 .instance_init = lasips2_mouse_port_init,
+.class_init= lasips2_mouse_port_class_init,
 };
 
 static void lasips2_register_types(void)
-- 
2.30.2




[PATCH v2 12/40] lasips2: don't use vmstate_register() in lasips2_realize()

2022-07-12 Thread Mark Cave-Ayland
Since lasips2 is a qdev device then vmstate_ps2_mouse can be registered using
the DeviceClass vmsd field instead.

Note that due to the use of the base parameter in the original 
vmstate_register()
function call, this is actually a migration break for the HPPA B160L machine.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/lasips2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c
index 9223cb0af4..d4fa248729 100644
--- a/hw/input/lasips2.c
+++ b/hw/input/lasips2.c
@@ -272,8 +272,6 @@ static void lasips2_realize(DeviceState *dev, Error **errp)
 {
 LASIPS2State *s = LASIPS2(dev);
 
-vmstate_register(NULL, s->base, _lasips2, s);
-
 s->kbd.dev = ps2_kbd_init();
 qdev_connect_gpio_out(DEVICE(s->kbd.dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
@@ -319,6 +317,7 @@ static void lasips2_class_init(ObjectClass *klass, void 
*data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 
 dc->realize = lasips2_realize;
+dc->vmsd = _lasips2;
 device_class_set_props(dc, lasips2_properties);
 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
-- 
2.30.2




[PATCH v2 07/40] pl050: introduce PL050DeviceClass for the PL050 device

2022-07-12 Thread Mark Cave-Ayland
This will soon be used to store the reference to the PL050 parent device
for PL050_KBD_DEVICE and PL050_MOUSE_DEVICE.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 2 ++
 include/hw/input/pl050.h | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index e32d86005a..d7796b73a1 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -216,6 +216,8 @@ static const TypeInfo pl050_type_info = {
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_init = pl050_init,
 .instance_size = sizeof(PL050State),
+.class_init= pl050_class_init,
+.class_size= sizeof(PL050DeviceClass),
 .abstract  = true,
 .class_init= pl050_class_init,
 };
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index bb0e87ff45..203f03a194 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -16,8 +16,14 @@
 #include "hw/input/ps2.h"
 #include "hw/irq.h"
 
+struct PL050DeviceClass {
+SysBusDeviceClass parent_class;
+
+DeviceRealize parent_realize;
+};
+
 #define TYPE_PL050 "pl050"
-OBJECT_DECLARE_SIMPLE_TYPE(PL050State, PL050)
+OBJECT_DECLARE_TYPE(PL050State, PL050DeviceClass, PL050)
 
 struct PL050State {
 SysBusDevice parent_obj;
-- 
2.30.2




[PATCH v2 06/40] pl050: move logic from pl050_realize() to pl050_init()

2022-07-12 Thread Mark Cave-Ayland
The logic for initialising the register memory region and the sysbus output IRQ
does not depend upon any device properties and so can be moved from
pl050_realize() to pl050_init().

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 88459997e0..e32d86005a 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -152,11 +152,7 @@ static const MemoryRegionOps pl050_ops = {
 static void pl050_realize(DeviceState *dev, Error **errp)
 {
 PL050State *s = PL050(dev);
-SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-memory_region_init_io(>iomem, OBJECT(s), _ops, s, "pl050", 
0x1000);
-sysbus_init_mmio(sbd, >iomem);
-sysbus_init_irq(sbd, >irq);
 if (s->is_mouse) {
 s->ps2dev = ps2_mouse_init();
 } else {
@@ -197,6 +193,13 @@ static const TypeInfo pl050_mouse_info = {
 
 static void pl050_init(Object *obj)
 {
+PL050State *s = PL050(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(>iomem, obj, _ops, s, "pl050", 0x1000);
+sysbus_init_mmio(sbd, >iomem);
+sysbus_init_irq(sbd, >irq);
+
 qdev_init_gpio_in_named(DEVICE(obj), pl050_set_irq, "ps2-input-irq", 1);
 }
 
-- 
2.30.2




[PATCH v2 03/40] pl050: change PL050State dev pointer from void to PS2State

2022-07-12 Thread Mark Cave-Ayland
This allows the compiler to enforce that the PS2 device pointer is always of
type PS2State. Update the name of the pointer from dev to ps2dev to emphasise
this type change.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 13 +++--
 include/hw/input/pl050.h |  2 +-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 8e32b8ed46..0d91b0eaea 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -101,7 +101,7 @@ static uint64_t pl050_read(void *opaque, hwaddr offset,
 }
 case 2: /* KMIDATA */
 if (s->pending) {
-s->last = ps2_read_data(s->dev);
+s->last = ps2_read_data(s->ps2dev);
 }
 return s->last;
 case 3: /* KMICLKDIV */
@@ -130,9 +130,9 @@ static void pl050_write(void *opaque, hwaddr offset,
 /* ??? This should toggle the TX interrupt line.  */
 /* ??? This means kbd/mouse can block each other.  */
 if (s->is_mouse) {
-ps2_write_mouse(s->dev, value);
+ps2_write_mouse(PS2_MOUSE_DEVICE(s->ps2dev), value);
 } else {
-ps2_write_keyboard(s->dev, value);
+ps2_write_keyboard(PS2_KBD_DEVICE(s->ps2dev), value);
 }
 break;
 case 3: /* KMICLKDIV */
@@ -158,11 +158,12 @@ static void pl050_realize(DeviceState *dev, Error **errp)
 sysbus_init_mmio(sbd, >iomem);
 sysbus_init_irq(sbd, >irq);
 if (s->is_mouse) {
-s->dev = ps2_mouse_init();
+s->ps2dev = ps2_mouse_init();
 } else {
-s->dev = ps2_kbd_init();
+s->ps2dev = ps2_kbd_init();
 }
-qdev_connect_gpio_out(DEVICE(s->dev), PS2_DEVICE_IRQ,
+
+qdev_connect_gpio_out(DEVICE(s->ps2dev), PS2_DEVICE_IRQ,
   qdev_get_gpio_in_named(dev, "ps2-input-irq", 0));
 }
 
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index 2bbf7a9d50..c1f6c5a1fb 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -23,7 +23,7 @@ struct PL050State {
 SysBusDevice parent_obj;
 
 MemoryRegion iomem;
-void *dev;
+PS2State *ps2dev;
 uint32_t cr;
 uint32_t clk;
 uint32_t last;
-- 
2.30.2




[PATCH v2 11/40] pl050: don't use legacy ps2_mouse_init() function

2022-07-12 Thread Mark Cave-Ayland
Instantiate the PS2 mouse device within PL050MouseState using
object_initialize_child() in pl050_mouse_init() and realize it in
pl050_mouse_realize() accordingly.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 13 ++---
 include/hw/input/pl050.h |  2 ++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 64b579e877..ec5e19285e 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -183,17 +183,24 @@ static void pl050_kbd_init(Object *obj)
 static void pl050_mouse_realize(DeviceState *dev, Error **errp)
 {
 PL050DeviceClass *pdc = PL050_GET_CLASS(dev);
+PL050MouseState *s = PL050_MOUSE_DEVICE(dev);
 PL050State *ps = PL050(dev);
 
-ps->ps2dev = ps2_mouse_init();
+if (!sysbus_realize(SYS_BUS_DEVICE(>mouse), errp)) {
+return;
+}
+
+ps->ps2dev = PS2_DEVICE(>mouse);
 pdc->parent_realize(dev, errp);
 }
 
 static void pl050_mouse_init(Object *obj)
 {
-PL050State *s = PL050(obj);
+PL050MouseState *s = PL050_MOUSE_DEVICE(obj);
+PL050State *ps = PL050(obj);
 
-s->is_mouse = true;
+ps->is_mouse = true;
+object_initialize_child(obj, "mouse", >mouse, TYPE_PS2_MOUSE_DEVICE);
 }
 
 static void pl050_kbd_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index 28f6216dc3..89ec4fafc9 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -52,6 +52,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PL050MouseState, 
PL050_MOUSE_DEVICE)
 
 struct PL050MouseState {
 PL050State parent_obj;
+
+PS2MouseState mouse;
 };
 
 #endif
-- 
2.30.2




[PATCH v2 04/40] pl050: introduce new PL050_KBD_DEVICE QOM type

2022-07-12 Thread Mark Cave-Ayland
This will be soon be used to hold the underlying PS2_KBD_DEVICE object.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 3 ++-
 include/hw/input/pl050.h | 7 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 0d91b0eaea..7f4ac99081 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -182,9 +182,10 @@ static void pl050_mouse_init(Object *obj)
 }
 
 static const TypeInfo pl050_kbd_info = {
-.name  = "pl050_keyboard",
+.name  = TYPE_PL050_KBD_DEVICE,
 .parent= TYPE_PL050,
 .instance_init = pl050_kbd_init,
+.instance_size = sizeof(PL050KbdState),
 };
 
 static const TypeInfo pl050_mouse_info = {
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
index c1f6c5a1fb..9ce8794bd0 100644
--- a/include/hw/input/pl050.h
+++ b/include/hw/input/pl050.h
@@ -32,4 +32,11 @@ struct PL050State {
 bool is_mouse;
 };
 
+#define TYPE_PL050_KBD_DEVICE "pl050_keyboard"
+OBJECT_DECLARE_SIMPLE_TYPE(PL050KbdState, PL050_KBD_DEVICE)
+
+struct PL050KbdState {
+PL050State parent_obj;
+};
+
 #endif
-- 
2.30.2




[PATCH v2 02/40] pl050: rename pl050_keyboard_init() to pl050_kbd_init()

2022-07-12 Thread Mark Cave-Ayland
This is for consistency with all of the other devices that use the PS2 keyboard
device.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index c7980b6ed7..8e32b8ed46 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -166,7 +166,7 @@ static void pl050_realize(DeviceState *dev, Error **errp)
   qdev_get_gpio_in_named(dev, "ps2-input-irq", 0));
 }
 
-static void pl050_keyboard_init(Object *obj)
+static void pl050_kbd_init(Object *obj)
 {
 PL050State *s = PL050(obj);
 
@@ -183,7 +183,7 @@ static void pl050_mouse_init(Object *obj)
 static const TypeInfo pl050_kbd_info = {
 .name  = "pl050_keyboard",
 .parent= TYPE_PL050,
-.instance_init = pl050_keyboard_init,
+.instance_init = pl050_kbd_init,
 };
 
 static const TypeInfo pl050_mouse_info = {
-- 
2.30.2




[PATCH v2 01/40] pl050: move PL050State from pl050.c to new pl050.h header file

2022-07-12 Thread Mark Cave-Ayland
This allows the QOM types in pl050.c to be used elsewhere by simply including
pl050.h.

Signed-off-by: Mark Cave-Ayland 
Tested-by: Helge Deller 
Acked-by: Helge Deller 
Reviewed-by: Peter Maydell 
---
 hw/input/pl050.c | 16 +---
 include/hw/input/pl050.h | 35 +++
 2 files changed, 36 insertions(+), 15 deletions(-)
 create mode 100644 include/hw/input/pl050.h

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index 209cc001cf..c7980b6ed7 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -19,26 +19,12 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "hw/input/ps2.h"
+#include "hw/input/pl050.h"
 #include "hw/irq.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "qom/object.h"
 
-#define TYPE_PL050 "pl050"
-OBJECT_DECLARE_SIMPLE_TYPE(PL050State, PL050)
-
-struct PL050State {
-SysBusDevice parent_obj;
-
-MemoryRegion iomem;
-void *dev;
-uint32_t cr;
-uint32_t clk;
-uint32_t last;
-int pending;
-qemu_irq irq;
-bool is_mouse;
-};
 
 static const VMStateDescription vmstate_pl050 = {
 .name = "pl050",
diff --git a/include/hw/input/pl050.h b/include/hw/input/pl050.h
new file mode 100644
index 00..2bbf7a9d50
--- /dev/null
+++ b/include/hw/input/pl050.h
@@ -0,0 +1,35 @@
+/*
+ * Arm PrimeCell PL050 Keyboard / Mouse Interface
+ *
+ * Copyright (c) 2006-2007 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ */
+
+#ifndef HW_PL050_H
+#define HW_PL050_H
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "hw/input/ps2.h"
+#include "hw/irq.h"
+
+#define TYPE_PL050 "pl050"
+OBJECT_DECLARE_SIMPLE_TYPE(PL050State, PL050)
+
+struct PL050State {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+void *dev;
+uint32_t cr;
+uint32_t clk;
+uint32_t last;
+int pending;
+qemu_irq irq;
+bool is_mouse;
+};
+
+#endif
-- 
2.30.2




Re: [PATCH] avocado: Fix BUILD_DIR if it's equal to SOURCE_DIR

2022-07-12 Thread Philippe Mathieu-Daudé via

On 2/7/22 20:56, Peter Delevoryas wrote:

I like to build QEMU from the root source directory, rather than cd'ing
into the build directory. This code may as well include a search path
for that, so that you can run avocado tests individually without
specifying "-p qemu_bin=build/qemu-system-arm" manually.

Signed-off-by: Peter Delevoryas 
---
  tests/avocado/avocado_qemu/__init__.py | 17 +
  1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tests/avocado/avocado_qemu/__init__.py 
b/tests/avocado/avocado_qemu/__init__.py
index b656a70c55..ed4853c805 100644
--- a/tests/avocado/avocado_qemu/__init__.py
+++ b/tests/avocado/avocado_qemu/__init__.py
@@ -120,14 +120,15 @@ def pick_default_qemu_bin(bin_prefix='qemu-system-', 
arch=None):
  # qemu binary path does not match arch for powerpc, handle it
  if 'ppc64le' in arch:
  arch = 'ppc64'
-qemu_bin_relative_path = os.path.join(".", bin_prefix + arch)
-if is_readable_executable_file(qemu_bin_relative_path):
-return qemu_bin_relative_path
-
-qemu_bin_from_bld_dir_path = os.path.join(BUILD_DIR,
-  qemu_bin_relative_path)
-if is_readable_executable_file(qemu_bin_from_bld_dir_path):
-return qemu_bin_from_bld_dir_path
+qemu_bin_name = bin_prefix + arch
+qemu_bin_paths = [
+os.path.join(".", qemu_bin_name),
+os.path.join(BUILD_DIR, qemu_bin_name),
+os.path.join(BUILD_DIR, "build", qemu_bin_name),


I suppose you are building as pseudo-in-tree (see commit dedad02720: 
"configure: add support for pseudo-"in source tree" builds"). OK.



+]
+for path in qemu_bin_paths:
+if is_readable_executable_file(path):
+return path
  return None
  
  


Reviewed-by: Philippe Mathieu-Daudé 

And queued.



[PATCH v2 00/40] PS2 device QOMification - part 2

2022-07-12 Thread Mark Cave-Ayland
Here is the follow-on series from part 1 which completes the work to remove
the legacy global device init functions for PS2 devices. Now that part 1 has
been applied, the hard part to remove the PS2 function callback and argument
has been completed and all that remains is to improve the PS2 device
QOMification to allow the legacy PS2 functions to be removed.

Patches 1-11 update the pl050 device to remove the use of ps2_kbd_init() and
ps2_mouse_init(), whilst patches 12-34 make some more involved changes to
the lasips2 device (in particular completing the LASIPS2Port abstraction)
before doing the same.

Finally patches 35-40 complete the process for the pckbd (I8042 and I8042_MMIO
devices) before removing the now unused ps2_kbd_init(), ps2_mouse_init() and
i8042_mm_init() functions.

Note that this series is a migration break for the HPPA B160L and MIPS magnum
machines: I've had agreement from both Helge and Hervé that this is worth
doing to allow the use of the DeviceClass vmsd property to set the
VMStateDescription rather than manually calling vmstate_register().

Signed-off-by: Mark Cave-Ayland 

Patches still requiring review for updated commit messages (no code changes
from v1): 27, 28 and 34

v2:
- Rebase onto master
- Add A-B and R-B tags from Helge and Peter
- s/jazz/magnum/ for consistency in commit message for patch 35
- Update commit messages in patches 27 and 28 to clarify why the int_status
  bitmap isn't immediately added to the vmstate_lasips2 VMStateDescription
- Update commit message in patch 34 to detail the extra changes to the
  vmstate_lasips2 VMStateDescription


Mark Cave-Ayland (40):
  pl050: move PL050State from pl050.c to new pl050.h header file
  pl050: rename pl050_keyboard_init() to pl050_kbd_init()
  pl050: change PL050State dev pointer from void to PS2State
  pl050: introduce new PL050_KBD_DEVICE QOM type
  pl050: introduce new PL050_MOUSE_DEVICE QOM type
  pl050: move logic from pl050_realize() to pl050_init()
  pl050: introduce PL050DeviceClass for the PL050 device
  pl050: introduce pl050_kbd_class_init() and pl050_kbd_realize()
  pl050: introduce pl050_mouse_class_init() and pl050_mouse_realize()
  pl050: don't use legacy ps2_kbd_init() function
  pl050: don't use legacy ps2_mouse_init() function
  lasips2: don't use vmstate_register() in lasips2_realize()
  lasips2: remove the qdev base property and the lasips2_properties
array
  lasips2: remove legacy lasips2_initfn() function
  lasips2: change LASIPS2State dev pointer from void to PS2State
  lasips2: QOMify LASIPS2Port
  lasips2: introduce new LASIPS2_KBD_PORT QOM type
  lasips2: introduce new LASIPS2_MOUSE_PORT QOM type
  lasips2: move keyboard port initialisation to new
lasips2_kbd_port_init() function
  lasips2: move mouse port initialisation to new
lasips2_mouse_port_init() function
  lasips2: introduce lasips2_kbd_port_class_init() and
lasips2_kbd_port_realize()
  lasips2: introduce lasips2_mouse_port_class_init() and
lasips2_mouse_port_realize()
  lasips2: rename LASIPS2Port irq field to birq
  lasips2: introduce port IRQ and new lasips2_port_init() function
  lasips2: introduce LASIPS2PortDeviceClass for the LASIPS2_PORT device
  lasips2: add named input gpio to port for downstream PS2 device IRQ
  lasips2: add named input gpio to handle incoming port IRQs
  lasips2: switch to using port-based IRQs
  lasips2: rename LASIPS2Port parent pointer to lasips2
  lasips2: standardise on lp name for LASIPS2Port variables
  lasips2: switch register memory region to DEVICE_BIG_ENDIAN
  lasips2: don't use legacy ps2_kbd_init() function
  lasips2: don't use legacy ps2_mouse_init() function
  lasips2: update VMStateDescription for LASIPS2 device
  pckbd: introduce new vmstate_kbd_mmio VMStateDescription for the
I8042_MMIO device
  pckbd: don't use legacy ps2_kbd_init() function
  ps2: remove unused legacy ps2_kbd_init() function
  pckbd: don't use legacy ps2_mouse_init() function
  ps2: remove unused legacy ps2_mouse_init() function
  pckbd: remove legacy i8042_mm_init() function

 hw/hppa/machine.c  |   7 +-
 hw/input/lasips2.c | 320 ++---
 hw/input/pckbd.c   |  82 ++
 hw/input/pl050.c   | 112 -
 hw/input/ps2.c |  26 ---
 hw/input/trace-events  |   2 -
 hw/mips/jazz.c |  13 +-
 include/hw/input/i8042.h   |   7 +-
 include/hw/input/lasips2.h |  57 +--
 include/hw/input/pl050.h   |  59 +++
 include/hw/input/ps2.h |   2 -
 11 files changed, 466 insertions(+), 221 deletions(-)
 create mode 100644 include/hw/input/pl050.h

-- 
2.30.2




Re: [PATCH] target/avr: Drop avr_cpu_memory_rw_debug()

2022-07-12 Thread Philippe Mathieu-Daudé via
On Mon, Jun 20, 2022 at 10:01 PM Richard Henderson
 wrote:
> On 3/22/22 02:50, Bin Meng wrote:
> > CPUClass::memory_rw_debug() holds a callback for GDB memory access.
> > If not provided, cpu_memory_rw_debug() is used by the GDB stub.
> > Drop avr_cpu_memory_rw_debug() which does nothing special.
> >
> > Signed-off-by: Bin Meng 
>
> Queued to tcg-next, for lack of anything better.

Thank you!



Re: [PATCH 1/3] ui/cocoa: Run qemu_init in the main thread

2022-07-12 Thread Philippe Mathieu-Daudé via

Hi Akihiko,

On 6/7/22 04:13, Akihiko Odaki wrote:

This work is based on:
https://patchew.org/QEMU/20220317125534.38706-1-philippe.mathieu.da...@gmail.com/

Simplify the initialization dance by running qemu_init() in the main
thread before the Cocoa event loop starts. The secondary thread only
runs only qemu_main_loop() and qemu_cleanup().

This fixes a case where addRemovableDevicesMenuItems() calls
qmp_query_block() while expecting the main thread to still hold
the BQL.

Overriding the code after calling qemu_init() is done by dynamically
replacing a function pointer variable, qemu_main when initializing
ui/cocoa, which unifies the static implementation of main() for
builds with ui/cocoa and ones without ui/cocoa.

Signed-off-by: Akihiko Odaki 
---
  docs/devel/fuzzing.rst  |   4 +-
  include/qemu-main.h |   3 +-
  include/sysemu/sysemu.h |   2 +-
  softmmu/main.c  |  14 +--
  softmmu/vl.c|   2 +-
  tests/qtest/fuzz/fuzz.c |   2 +-
  ui/cocoa.m  | 185 
  7 files changed, 69 insertions(+), 143 deletions(-)

diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
index 784ecb99e66..715330c8561 100644
--- a/docs/devel/fuzzing.rst
+++ b/docs/devel/fuzzing.rst
@@ -287,8 +287,8 @@ select the fuzz target. Then, the qtest client is 
initialized. If the target
  requires qos, qgraph is set up and the QOM/LIBQOS modules are initialized.
  Then the QGraph is walked and the QEMU cmd_line is determined and saved.
  
-After this, the ``vl.c:qemu_main`` is called to set up the guest. There are

-target-specific hooks that can be called before and after qemu_main, for
+After this, the ``vl.c:main`` is called to set up the guest. There are
+target-specific hooks that can be called before and after main, for
  additional setup(e.g. PCI setup, or VM snapshotting).
  
  ``LLVMFuzzerTestOneInput``: Uses qtest/qos functions to act based on the fuzz

diff --git a/include/qemu-main.h b/include/qemu-main.h
index 6a3e90d0ad5..6889375e7c2 100644
--- a/include/qemu-main.h
+++ b/include/qemu-main.h
@@ -5,6 +5,7 @@
  #ifndef QEMU_MAIN_H
  #define QEMU_MAIN_H
  
-int qemu_main(int argc, char **argv, char **envp);

+void qemu_default_main(void);
+extern void (*qemu_main)(void);
  
  #endif /* QEMU_MAIN_H */

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 812f66a31a9..254c1eabf57 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -102,7 +102,7 @@ void qemu_boot_set(const char *boot_order, Error **errp);
  
  bool defaults_enabled(void);
  
-void qemu_init(int argc, char **argv, char **envp);

+void qemu_init(int argc, char **argv);
  void qemu_main_loop(void);
  void qemu_cleanup(void);
  
diff --git a/softmmu/main.c b/softmmu/main.c

index c00432ff098..41a091f2c72 100644
--- a/softmmu/main.c
+++ b/softmmu/main.c
@@ -30,18 +30,18 @@
  #include 
  #endif
  
-int qemu_main(int argc, char **argv, char **envp)

+void qemu_default_main(void)
  {
-qemu_init(argc, argv, envp);
  qemu_main_loop();
  qemu_cleanup();
-
-return 0;
  }
  
-#ifndef CONFIG_COCOA

+void (*qemu_main)(void) = qemu_default_main;
+
  int main(int argc, char **argv)
  {
-return qemu_main(argc, argv, NULL);
+qemu_init(argc, argv);
+qemu_main();
+
+return 0;
  }
-#endif
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 3f264d4b093..e8c73d0bb40 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2589,7 +2589,7 @@ void qmp_x_exit_preconfig(Error **errp)
  }
  }
  
-void qemu_init(int argc, char **argv, char **envp)

+void qemu_init(int argc, char **argv)
  {
  QemuOpts *opts;
  QemuOpts *icount_opts = NULL, *accel_opts = NULL;
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index 2062b40d82b..0bde925bf83 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -221,7 +221,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char 
***envp)
  g_free(pretty_cmd_line);
  }
  
-qemu_init(result.we_wordc, result.we_wordv, NULL);

+qemu_init(result.we_wordc, result.we_wordv);
  
  /* re-enable the rcu atfork, which was previously disabled in qemu_init */

  rcu_enable_atfork();
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 6a4dccff7f0..55413594d14 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -100,15 +100,11 @@ static void cocoa_switch(DisplayChangeListener *dcl,
  static int left_command_key_enabled = 1;
  static bool swap_opt_cmd;
  
-static int gArgc;

-static char **gArgv;
+static QemuThread qemu_main_thread;
+static bool qemu_main_terminating;
  static bool stretch_video;
  static NSTextField *pauseLabel;
  
-static QemuSemaphore display_init_sem;

-static QemuSemaphore app_started_sem;
-static bool allow_events;
-
  static NSInteger cbchangecount = -1;
  static QemuClipboardInfo *cbinfo;
  static QemuEvent cbevent;
@@ -581,18 +577,6 @@ - (void) updateUIInfoLocked
  
  - (void) updateUIInfo

  {
-if (!allow_events) {
-/*
- * Don't try to tell QEMU 

[RFC PATCH 3/8] RFC: block: use transactions as a replacement of ->{can_}set_aio_context()

2022-07-12 Thread Emanuele Giuseppe Esposito
-
RFC because I am not sure about the AioContext locks.
- Do we need to take the new AioContext lock? what does it protect?
- Taking the old AioContext lock is required now, because of
  bdrv_drained_begin calling AIO_WAIT_WHILE that unlocks the
  aiocontext. If we replace it with AIO_WAIT_WHILE_UNLOCKED,
  could we get rid of taking every time the old AioContext?
  drain would be enough to protect the graph modification.
--

Simplify the way the aiocontext can be changed in a BDS graph.
There are currently two problems in bdrv_try_set_aio_context:
- There is a confusion of AioContext locks taken and released, because
  we assume that old aiocontext is always taken and new one is
  taken inside.

- It doesn't look very safe to call bdrv_drained_begin while some
  nodes have already switched to the new aiocontext and others haven't.
  This could be especially dangerous because bdrv_drained_begin polls, so
  something else could be executed while graph is in an inconsistent
  state.

Additional minor nitpick: can_set and set_ callbacks both traverse the
graph, both using the ignored list of visited nodes in a different way.

Therefore, get rid of all of this and introduce a new callback,
change_aio_context, that uses transactions to efficiently, cleanly
and most importantly safely change the aiocontext of a graph.

This new callback is a "merge" of the two previous ones:
- Just like can_set_aio_context, recursively traverses the graph.
  Marks all nodes that are visited using a GList, and checks if
  they *could* change the aio_context.
- For each node that passes the above check, add a new transaction
  that implements a callback that effectively changes the aiocontext.
- If a node is a BDS, add two transactions: one taking care of draining
  the node at the beginning of the list (so that will be executed first)
  and one at the end taking care of changing the AioContext.
- Once done, the recursive function returns if *all* nodes can change
  the AioContext. If so, commit the above transactions. Otherwise don't
  do anything.
- The transaction list contains first all "drain" transactions, so
  we are sure we are draining all nodes in the same context, and then
  all the other switch the AioContext. In this way we make sure that
  bdrv_drained_begin() is always called under the old AioContext, and
  bdrv_drained_end() under the new one.
- Because of the above, we don't need to release and re-acquire the
  old AioContext every time, as everything is done once (and not
  per-node drain and aiocontext change).

Note that the "change" API is not yet invoked anywhere.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block.c| 197 +
 include/block/block-global-state.h |   9 ++
 include/block/block_int-common.h   |   3 +
 3 files changed, 209 insertions(+)

diff --git a/block.c b/block.c
index 267a39c0de..bda4e1bcef 100644
--- a/block.c
+++ b/block.c
@@ -7437,6 +7437,51 @@ static bool bdrv_parent_can_set_aio_context(BdrvChild 
*c, AioContext *ctx,
 return true;
 }
 
+typedef struct BdrvStateSetAioContext {
+AioContext *new_ctx;
+BlockDriverState *bs;
+} BdrvStateSetAioContext;
+
+/*
+ * Changes the AioContext used for fd handlers, timers, and BHs by this
+ * BlockDriverState and all its children and parents.
+ *
+ * Must be called from the main AioContext.
+ *
+ * The caller must own the AioContext lock for the old AioContext of bs, but it
+ * must not own the AioContext lock for new_context (unless new_context is the
+ * same as the current context of bs).
+ *
+ * @visited will accumulate all visited BdrvChild object. The caller is
+ * responsible for freeing the list afterwards.
+ */
+static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
+   GSList **visited, Transaction *tran,
+   Error **errp)
+{
+GLOBAL_STATE_CODE();
+if (g_slist_find(*visited, c)) {
+return true;
+}
+*visited = g_slist_prepend(*visited, c);
+
+/*
+ * A BdrvChildClass that doesn't handle AioContext changes cannot
+ * tolerate any AioContext changes
+ */
+if (!c->klass->change_aio_ctx) {
+char *user = bdrv_child_user_desc(c);
+error_setg(errp, "Changing iothreads is not supported by %s", user);
+g_free(user);
+return false;
+}
+if (!c->klass->change_aio_ctx(c, ctx, visited, tran, errp)) {
+assert(!errp || *errp);
+return false;
+}
+return true;
+}
+
 bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
 GSList **ignore, Error **errp)
 {
@@ -7448,6 +7493,18 @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, 
AioContext *ctx,
 return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp);
 }
 
+bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
+   GSList 

[RFC PATCH 6/8] block-backend: implement .change_aio_ctx in child_root

2022-07-12 Thread Emanuele Giuseppe Esposito
blk_root_change_aio_ctx() is very similar to blk_root_can_set_aio_ctx(),
but implements a new transaction so that if all check pass, the new
transaction's .commit will take care of changing the BlockBackend
AioContext. blk_root_set_aio_ctx_commit() is the same as
blk_root_set_aio_ctx().

Note: bdrv_child_try_change_aio_context() is not called by
anyone at this point.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block/block-backend.c | 54 +++
 1 file changed, 54 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index f425b00793..674eaaa2bf 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -138,6 +138,9 @@ static bool blk_root_can_set_aio_ctx(BdrvChild *child, 
AioContext *ctx,
  GSList **ignore, Error **errp);
 static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
  GSList **ignore);
+static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
+GSList **visited, Transaction *tran,
+Error **errp);
 
 static char *blk_root_get_parent_desc(BdrvChild *child)
 {
@@ -336,6 +339,7 @@ static const BdrvChildClass child_root = {
 
 .can_set_aio_ctx= blk_root_can_set_aio_ctx,
 .set_aio_ctx= blk_root_set_aio_ctx,
+.change_aio_ctx = blk_root_change_aio_ctx,
 
 .get_parent_aio_context = blk_root_get_parent_aio_context,
 };
@@ -2208,6 +2212,56 @@ int blk_set_aio_context(BlockBackend *blk, AioContext 
*new_context,
 return blk_do_set_aio_context(blk, new_context, true, errp);
 }
 
+typedef struct BdrvStateBlkRootContext {
+AioContext *new_ctx;
+BlockBackend *blk;
+} BdrvStateBlkRootContext;
+
+static void blk_root_set_aio_ctx_commit(void *opaque)
+{
+BdrvStateBlkRootContext *s = opaque;
+BlockBackend *blk = s->blk;
+
+blk_do_set_aio_context(blk, s->new_ctx, false, _abort);
+}
+
+static TransactionActionDrv set_blk_root_context = {
+.commit = blk_root_set_aio_ctx_commit,
+.clean = g_free,
+};
+
+static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx,
+GSList **visited, Transaction *tran,
+Error **errp)
+{
+BlockBackend *blk = child->opaque;
+BdrvStateBlkRootContext *s;
+
+if (blk->allow_aio_context_change) {
+goto finish;
+}
+
+/*
+ * Only manually created BlockBackends that are not attached to anything
+ * can change their AioContext without updating their user.
+ */
+if (!blk->name || blk->dev) {
+/* TODO Add BB name/QOM path */
+error_setg(errp, "Cannot change iothread of active block backend");
+return false;
+}
+
+finish:
+s = g_new(BdrvStateBlkRootContext, 1);
+*s = (BdrvStateBlkRootContext) {
+.new_ctx = ctx,
+.blk = blk,
+};
+
+tran_add_tail(tran, _blk_root_context, s);
+return true;
+}
+
 static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
  GSList **ignore, Error **errp)
 {
-- 
2.31.1




[RFC PATCH 7/8] block: use the new _change_ API instead of _can_set_ and _set_

2022-07-12 Thread Emanuele Giuseppe Esposito
Replace all direct usage of ->can_set_aio_ctx and ->set_aio_ctx,
and call bdrv_child_try_change_aio_context() in
bdrv_try_set_aio_context(), the main function called through
the whole block layer.

>From this point onwards, ->can_set_aio_ctx and ->set_aio_ctx
won't be used anymore.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block.c   | 30 --
 block/block-backend.c |  8 ++--
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/block.c b/block.c
index a7ba590dfa..101188a2d4 100644
--- a/block.c
+++ b/block.c
@@ -2966,17 +2966,18 @@ static void bdrv_attach_child_common_abort(void *opaque)
 }
 
 if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) {
+Transaction *tran;
 GSList *ignore;
+bool ret;
 
-/* No need to ignore `child`, because it has been detached already */
-ignore = NULL;
-child->klass->can_set_aio_ctx(child, s->old_parent_ctx, ,
-  _abort);
-g_slist_free(ignore);
+tran = tran_new();
 
+/* No need to ignore `child`, because it has been detached already */
 ignore = NULL;
-child->klass->set_aio_ctx(child, s->old_parent_ctx, );
+ret = child->klass->change_aio_ctx(child, s->old_parent_ctx, ,
+   tran, _abort);
 g_slist_free(ignore);
+tran_finalize(tran, ret ? ret : -1);
 }
 
 bdrv_unref(bs);
@@ -3037,17 +3038,18 @@ static int bdrv_attach_child_common(BlockDriverState 
*child_bs,
 Error *local_err = NULL;
 int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, _err);
 
-if (ret < 0 && child_class->can_set_aio_ctx) {
+if (ret < 0 && child_class->change_aio_ctx) {
+Transaction *tran = tran_new();
 GSList *ignore = g_slist_prepend(NULL, new_child);
-if (child_class->can_set_aio_ctx(new_child, child_ctx, ,
- NULL))
-{
+bool ret_child;
+
+ret_child = child_class->change_aio_ctx(new_child, child_ctx,
+, tran, NULL);
+if (ret_child) {
 error_free(local_err);
 ret = 0;
-g_slist_free(ignore);
-ignore = g_slist_prepend(NULL, new_child);
-child_class->set_aio_ctx(new_child, child_ctx, );
 }
+tran_finalize(tran, ret_child ? ret_child : -1);
 g_slist_free(ignore);
 }
 
@@ -7708,7 +7710,7 @@ int bdrv_try_set_aio_context(BlockDriverState *bs, 
AioContext *ctx,
  Error **errp)
 {
 GLOBAL_STATE_CODE();
-return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp);
+return bdrv_child_try_change_aio_context(bs, ctx, NULL, errp);
 }
 
 void bdrv_add_aio_context_notifier(BlockDriverState *bs,
diff --git a/block/block-backend.c b/block/block-backend.c
index 674eaaa2bf..6e90ac3a6a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -2184,8 +2184,12 @@ static int blk_do_set_aio_context(BlockBackend *blk, 
AioContext *new_context,
 bdrv_ref(bs);
 
 if (update_root_node) {
-ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root,
- errp);
+/*
+ * update_root_node MUST be false for 
blk_root_set_aio_ctx_commit(),
+ * as we are already in the commit function of a transaction.
+ */
+ret = bdrv_child_try_change_aio_context(bs, new_context, blk->root,
+errp);
 if (ret < 0) {
 bdrv_unref(bs);
 return ret;
-- 
2.31.1




[RFC PATCH 8/8] block: remove all unused ->can_set_aio_ctx and ->set_aio_ctx callbacks

2022-07-12 Thread Emanuele Giuseppe Esposito
Together with all _can_set_ and _set_ APIs, as they are not needed
anymore.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block.c| 196 -
 block/block-backend.c  |  33 -
 blockjob.c |  35 --
 include/block/block-global-state.h |   9 --
 include/block/block_int-common.h   |   4 -
 5 files changed, 277 deletions(-)

diff --git a/block.c b/block.c
index 101188a2d4..d99784dff1 100644
--- a/block.c
+++ b/block.c
@@ -1243,20 +1243,6 @@ static bool bdrv_child_cb_change_aio_ctx(BdrvChild 
*child, AioContext *ctx,
 return bdrv_change_aio_context(bs, ctx, visited, tran, errp);
 }
 
-static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
-  GSList **ignore, Error **errp)
-{
-BlockDriverState *bs = child->opaque;
-return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
-}
-
-static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
-  GSList **ignore)
-{
-BlockDriverState *bs = child->opaque;
-return bdrv_set_aio_context_ignore(bs, ctx, ignore);
-}
-
 /*
  * Returns the options and flags that a temporary snapshot should get, based on
  * the originally requested flags (the originally requested image will have
@@ -1497,8 +1483,6 @@ const BdrvChildClass child_of_bds = {
 .attach  = bdrv_child_cb_attach,
 .detach  = bdrv_child_cb_detach,
 .inactivate  = bdrv_child_cb_inactivate,
-.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
-.set_aio_ctx = bdrv_child_cb_set_aio_ctx,
 .change_aio_ctx  = bdrv_child_cb_change_aio_ctx,
 .update_filename = bdrv_child_cb_update_filename,
 .get_parent_aio_context = child_of_bds_get_parent_aio_context,
@@ -7329,125 +7313,6 @@ static void bdrv_attach_aio_context(BlockDriverState 
*bs,
 bs->walking_aio_notifiers = false;
 }
 
-/*
- * Changes the AioContext used for fd handlers, timers, and BHs by this
- * BlockDriverState and all its children and parents.
- *
- * Must be called from the main AioContext.
- *
- * The caller must own the AioContext lock for the old AioContext of bs, but it
- * must not own the AioContext lock for new_context (unless new_context is the
- * same as the current context of bs).
- *
- * @ignore will accumulate all visited BdrvChild object. The caller is
- * responsible for freeing the list afterwards.
- */
-void bdrv_set_aio_context_ignore(BlockDriverState *bs,
- AioContext *new_context, GSList **ignore)
-{
-AioContext *old_context = bdrv_get_aio_context(bs);
-GSList *children_to_process = NULL;
-GSList *parents_to_process = NULL;
-GSList *entry;
-BdrvChild *child, *parent;
-
-g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
-GLOBAL_STATE_CODE();
-
-if (old_context == new_context) {
-return;
-}
-
-bdrv_drained_begin(bs);
-
-QLIST_FOREACH(child, >children, next) {
-if (g_slist_find(*ignore, child)) {
-continue;
-}
-*ignore = g_slist_prepend(*ignore, child);
-children_to_process = g_slist_prepend(children_to_process, child);
-}
-
-QLIST_FOREACH(parent, >parents, next_parent) {
-if (g_slist_find(*ignore, parent)) {
-continue;
-}
-*ignore = g_slist_prepend(*ignore, parent);
-parents_to_process = g_slist_prepend(parents_to_process, parent);
-}
-
-for (entry = children_to_process;
- entry != NULL;
- entry = g_slist_next(entry)) {
-child = entry->data;
-bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
-}
-g_slist_free(children_to_process);
-
-for (entry = parents_to_process;
- entry != NULL;
- entry = g_slist_next(entry)) {
-parent = entry->data;
-assert(parent->klass->set_aio_ctx);
-parent->klass->set_aio_ctx(parent, new_context, ignore);
-}
-g_slist_free(parents_to_process);
-
-bdrv_detach_aio_context(bs);
-
-/* Acquire the new context, if necessary */
-if (qemu_get_aio_context() != new_context) {
-aio_context_acquire(new_context);
-}
-
-bdrv_attach_aio_context(bs, new_context);
-
-/*
- * If this function was recursively called from
- * bdrv_set_aio_context_ignore(), there may be nodes in the
- * subtree that have not yet been moved to the new AioContext.
- * Release the old one so bdrv_drained_end() can poll them.
- */
-if (qemu_get_aio_context() != old_context) {
-aio_context_release(old_context);
-}
-
-bdrv_drained_end(bs);
-
-if (qemu_get_aio_context() != old_context) {
-aio_context_acquire(old_context);
-}
-if (qemu_get_aio_context() != new_context) {
-aio_context_release(new_context);
-}
-}
-
-static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
- 

[RFC PATCH 5/8] block: implement .change_aio_ctx in child_of_bds

2022-07-12 Thread Emanuele Giuseppe Esposito
bdrv_child_cb_change_aio_ctx() is identical to
bdrv_child_cb_can_set_aio_ctx(), as we only need
to recursively go on the parent bs.

Note: bdrv_child_try_change_aio_context() is not called by
anyone at this point.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/block.c b/block.c
index bda4e1bcef..a7ba590dfa 100644
--- a/block.c
+++ b/block.c
@@ -1235,6 +1235,14 @@ static int bdrv_child_cb_inactivate(BdrvChild *child)
 return 0;
 }
 
+static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx,
+ GSList **visited, Transaction *tran,
+ Error **errp)
+{
+BlockDriverState *bs = child->opaque;
+return bdrv_change_aio_context(bs, ctx, visited, tran, errp);
+}
+
 static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
   GSList **ignore, Error **errp)
 {
@@ -1491,6 +1499,7 @@ const BdrvChildClass child_of_bds = {
 .inactivate  = bdrv_child_cb_inactivate,
 .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
 .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
+.change_aio_ctx  = bdrv_child_cb_change_aio_ctx,
 .update_filename = bdrv_child_cb_update_filename,
 .get_parent_aio_context = child_of_bds_get_parent_aio_context,
 };
-- 
2.31.1




[RFC PATCH 4/8] blockjob: implement .change_aio_ctx in child_job

2022-07-12 Thread Emanuele Giuseppe Esposito
child_job_change_aio_ctx() is very similar to
child_job_can_set_aio_ctx(), but it implements a new transaction
so that if all check pass, the new transaction's .commit()
will take care of changin the BlockJob AioContext.
child_job_set_aio_ctx_commit() is similar to child_job_set_aio_ctx(),
but it doesn't need to invoke the recursion, as this is already
taken care by child_job_change_aio_ctx().

Note: bdrv_child_try_change_aio_context() is not called by
anyone at this point.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 blockjob.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/blockjob.c b/blockjob.c
index bb82e8d04c..9e26b06ed4 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -124,6 +124,50 @@ static void child_job_drained_end(BdrvChild *c, int 
*drained_end_counter)
 }
 }
 
+typedef struct BdrvStateChildJobContext {
+AioContext *new_ctx;
+BlockJob *job;
+} BdrvStateChildJobContext;
+
+static void child_job_set_aio_ctx_commit(void *opaque)
+{
+BdrvStateChildJobContext *s = opaque;
+BlockJob *job = s->job;
+
+job_set_aio_context(>job, s->new_ctx);
+}
+
+static TransactionActionDrv change_child_job_context = {
+.commit = child_job_set_aio_ctx_commit,
+.clean = g_free,
+};
+
+static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx,
+ GSList **visited, Transaction *tran,
+ Error **errp)
+{
+BlockJob *job = c->opaque;
+BdrvStateChildJobContext *s;
+GSList *l;
+
+for (l = job->nodes; l; l = l->next) {
+BdrvChild *sibling = l->data;
+if (!bdrv_child_change_aio_context(sibling, ctx, visited,
+   tran, errp)) {
+return false;
+}
+}
+
+s = g_new(BdrvStateChildJobContext, 1);
+*s = (BdrvStateChildJobContext) {
+.new_ctx = ctx,
+.job = job,
+};
+
+tran_add_tail(tran, _child_job_context, s);
+return true;
+}
+
 static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
   GSList **ignore, Error **errp)
 {
@@ -172,6 +216,7 @@ static const BdrvChildClass child_job = {
 .drained_end= child_job_drained_end,
 .can_set_aio_ctx= child_job_can_set_aio_ctx,
 .set_aio_ctx= child_job_set_aio_ctx,
+.change_aio_ctx = child_job_change_aio_ctx,
 .stay_at_node   = true,
 .get_parent_aio_context = child_job_get_parent_aio_context,
 };
-- 
2.31.1




[RFC PATCH 2/8] transactions: add tran_add_back

2022-07-12 Thread Emanuele Giuseppe Esposito
First change the transactions from a QLIST to QSIMPLEQ, then
use it to implement tran_add_tail, which allows adding elements
to the end of list transactions.

This is useful if we have some "preparation" transiction callbacks
that we want to run before the others but still only when invoking
finalize/commit/abort.

For example (A and B are lists transaction callbacks):

for (i=0; i < 3; i++) {
tran_add(A[i]);
tran_add_tail(B[i]);
}

tran_commit();

Will process transactions in this order: A2 - A1 - A0 - B0 - B1 - B2

Signed-off-by: Emanuele Giuseppe Esposito 
---
 include/qemu/transactions.h |  9 +
 util/transactions.c | 29 +
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/include/qemu/transactions.h b/include/qemu/transactions.h
index 2f2060acd9..42783720b9 100644
--- a/include/qemu/transactions.h
+++ b/include/qemu/transactions.h
@@ -50,7 +50,16 @@ typedef struct TransactionActionDrv {
 typedef struct Transaction Transaction;
 
 Transaction *tran_new(void);
+/*
+ * Add transaction at the beginning of the transaction list.
+ * @tran will be the first transaction to be processed in 
finalize/commit/abort.
+ */
 void tran_add(Transaction *tran, TransactionActionDrv *drv, void *opaque);
+/*
+ * Add transaction at the end of the transaction list.
+ * @tran will be the last transaction to be processed in finalize/commit/abort.
+ */
+void tran_add_tail(Transaction *tran, TransactionActionDrv *drv, void *opaque);
 void tran_abort(Transaction *tran);
 void tran_commit(Transaction *tran);
 
diff --git a/util/transactions.c b/util/transactions.c
index 2dbdedce95..89e541c4a4 100644
--- a/util/transactions.c
+++ b/util/transactions.c
@@ -28,18 +28,18 @@
 typedef struct TransactionAction {
 TransactionActionDrv *drv;
 void *opaque;
-QSLIST_ENTRY(TransactionAction) entry;
+QSIMPLEQ_ENTRY(TransactionAction) entry;
 } TransactionAction;
 
 struct Transaction {
-QSLIST_HEAD(, TransactionAction) actions;
+QSIMPLEQ_HEAD(, TransactionAction) actions;
 };
 
 Transaction *tran_new(void)
 {
 Transaction *tran = g_new(Transaction, 1);
 
-QSLIST_INIT(>actions);
+QSIMPLEQ_INIT(>actions);
 
 return tran;
 }
@@ -54,20 +54,33 @@ void tran_add(Transaction *tran, TransactionActionDrv *drv, 
void *opaque)
 .opaque = opaque
 };
 
-QSLIST_INSERT_HEAD(>actions, act, entry);
+QSIMPLEQ_INSERT_HEAD(>actions, act, entry);
+}
+
+void tran_add_tail(Transaction *tran, TransactionActionDrv *drv, void *opaque)
+{
+TransactionAction *act;
+
+act = g_new(TransactionAction, 1);
+*act = (TransactionAction) {
+.drv = drv,
+.opaque = opaque
+};
+
+QSIMPLEQ_INSERT_TAIL(>actions, act, entry);
 }
 
 void tran_abort(Transaction *tran)
 {
 TransactionAction *act, *next;
 
-QSLIST_FOREACH(act, >actions, entry) {
+QSIMPLEQ_FOREACH(act, >actions, entry) {
 if (act->drv->abort) {
 act->drv->abort(act->opaque);
 }
 }
 
-QSLIST_FOREACH_SAFE(act, >actions, entry, next) {
+QSIMPLEQ_FOREACH_SAFE(act, >actions, entry, next) {
 if (act->drv->clean) {
 act->drv->clean(act->opaque);
 }
@@ -82,13 +95,13 @@ void tran_commit(Transaction *tran)
 {
 TransactionAction *act, *next;
 
-QSLIST_FOREACH(act, >actions, entry) {
+QSIMPLEQ_FOREACH(act, >actions, entry) {
 if (act->drv->commit) {
 act->drv->commit(act->opaque);
 }
 }
 
-QSLIST_FOREACH_SAFE(act, >actions, entry, next) {
+QSIMPLEQ_FOREACH_SAFE(act, >actions, entry, next) {
 if (act->drv->clean) {
 act->drv->clean(act->opaque);
 }
-- 
2.31.1




[RFC PATCH 1/8] block.c: assert bs->aio_context is written under BQL and drains

2022-07-12 Thread Emanuele Giuseppe Esposito
Also here ->aio_context is read by I/O threads and written
under BQL.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 block.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block.c b/block.c
index d0db104d71..267a39c0de 100644
--- a/block.c
+++ b/block.c
@@ -7285,6 +7285,7 @@ static void bdrv_detach_aio_context(BlockDriverState *bs)
 if (bs->quiesce_counter) {
 aio_enable_external(bs->aio_context);
 }
+assert_bdrv_graph_writable(bs);
 bs->aio_context = NULL;
 }
 
@@ -7298,6 +7299,7 @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
 aio_disable_external(new_context);
 }
 
+assert_bdrv_graph_writable(bs);
 bs->aio_context = new_context;
 
 if (bs->drv && bs->drv->bdrv_attach_aio_context) {
-- 
2.31.1




[RFC PATCH 0/8] Refactor bdrv_try_set_aio_context using transactions

2022-07-12 Thread Emanuele Giuseppe Esposito
The aim of this series is to reorganize bdrv_try_set_aio_context
and drop BDS ->set_aio_context and ->can_set_aio_ctx callbacks in
favour of a new one, ->change_aio_ctx.

More informations in patch 3 (which is also RFC, due to the doubts
I have with AioContext locks).

Patch 1 just add assertions in the code, 2 extends the transactions API to be 
able to add also transactions in the tail
of the list.
Patch 3 is the core of this series, and introduces the new callback.
It is marked as RFC and the reason is explained in the commit message.
Patches 4-5-6 implement ->change_aio_ctx in the various block, blockjob
and block-backend BDSes.
Patch 7 substitutes ->change_aio_ctx with the old callbacks, and
patch 8 takes care of deleting the old callbacks and unused code.

This series is based on "job: replace AioContext lock with job_mutex",
but just because it uses job_set_aio_context() introduced there.

Suggested-by: Paolo Bonzini 
Based-on: <20220706201533.289775-1-eespo...@redhat.com>

Emanuele Giuseppe Esposito (8):
  block.c: assert bs->aio_context is written under BQL and drains
  transactions: add tran_add_back
  RFC: block: use transactions as a replacement of
->{can_}set_aio_context()
  blockjob: implement .change_aio_ctx in child_job
  block: implement .change_aio_ctx in child_of_bds
  block-backend: implement .change_aio_ctx in child_root
  block: use the new _change_ API instead of _can_set_ and _set_
  block: remove all unused ->can_set_aio_ctx and ->set_aio_ctx callbacks

 block.c| 288 +++--
 block/block-backend.c  |  65 +--
 blockjob.c |  50 +++--
 include/block/block-global-state.h |  16 +-
 include/block/block_int-common.h   |   5 +-
 include/qemu/transactions.h|   9 +
 util/transactions.c|  29 ++-
 7 files changed, 266 insertions(+), 196 deletions(-)

-- 
2.31.1




Re: [RFC PATCH] target/ppc: don't print TB in ppc_cpu_dump_state if it's not initialized

2022-07-12 Thread Daniel Henrique Barboza




On 7/12/22 16:25, Matheus Ferst wrote:

When using "-machine none", env->tb_env is not allocated, causing the
segmentation fault reported in issue #85 (launchpad bug #811683). To
avoid this problem, check if the pointer != NULL before calling the
methods to print TBU/TBL/DECR.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/85
Signed-off-by: Matheus Ferst 
---
This patch fixes the reported problem, but may be an incomplete solution
since many other places dereference env->tb_env without checking for
NULL. AFAICS, "-machine none" is the only way to trigger this problem,
and I'm not familiar with the use-cases for this option.


The "none"  machine type is mainly used by libvirt to do instrospection
of the available options/capabilities of the QEMU binary. It starts a QEMU
process like the following:

./x86_64-softmmu/qemu-system-x86_64 -S -no-user-config -nodefaults \
  -nographic -machine none,accel=kvm:tcg -daemonize

And then it uses QMP to probe the binary.

Aside from this libvirt usage I am not aware of anyone else using -machine
none extensively.




Should we stop assuming env->tb_env != NULL and add checks everywhere?
Or should we find a way to provide Time Base/Decrementer for
"-machine none"?
---


Are there other cases where env->tb_env can be NULL, aside from the case
reported in the bug?

I don't mind the bug fix, but I'm not fond of the idea of adding additional
checks because of this particular issue. I mean, the bug is using  the 'prep'
machine that Thomas removed year ago in b2ce76a0730. If there's no other
foreseeable problem, that we care about, with env->tb_env being NULL, IMO
let's fix the bug and move on.



Thanks,


Daniel





  target/ppc/cpu_init.c | 16 
  1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 86ad28466a..7e96baac9f 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7476,18 +7476,18 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
   "%08x iidx %d didx %d\n",
   env->msr, env->spr[SPR_HID0], env->hflags,
   cpu_mmu_index(env, true), cpu_mmu_index(env, false));
-#if !defined(NO_TIMER_DUMP)
-qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
+if (env->tb_env) {
+qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
  #if !defined(CONFIG_USER_ONLY)
- " DECR " TARGET_FMT_lu
+ " DECR " TARGET_FMT_lu
  #endif
- "\n",
- cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
+ "\n",
+ cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
  #if !defined(CONFIG_USER_ONLY)
- , cpu_ppc_load_decr(env)
-#endif
-);
+ , cpu_ppc_load_decr(env)
  #endif
+);
+}
  for (i = 0; i < 32; i++) {
  if ((i & (RGPL - 1)) == 0) {
  qemu_fprintf(f, "GPR%02d", i);




Re: [PATCH] configure: Restrict TCG to emulation

2022-07-12 Thread Philippe Mathieu-Daudé via

On 6/7/22 17:38, Thomas Huth wrote:

From: Philippe Mathieu-Daudé 

If we don't need to emulate any target, we certainly don't need TCG.

This should also help to compile again with
  ".../configure --enable-tools --disable-system --disable-user"
on systems that do not have a TCG backend.

Signed-off-by: Philippe Mathieu-Daudé 
[thuth: Re-arranged the code, remove check-softfloat from buildtest.yml]
Signed-off-by: Thomas Huth 
---
  configure  | 20 ++--
  .gitlab-ci.d/buildtest.yml |  2 +-
  2 files changed, 15 insertions(+), 7 deletions(-)


Thanks for re-spinning! Queued via mips-next.



[PATCH v2] target/ppc/kvm: Skip current and parent directories in kvmppc_find_cpu_dt

2022-07-12 Thread Murilo Opsfelder Araujo
Some systems have /proc/device-tree/cpus/../clock-frequency. However,
this is not the expected path for a CPU device tree directory.

Signed-off-by: Murilo Opsfelder Araujo 
Signed-off-by: Fabiano Rosas 
---
v2:
- Skip current and parent directories.

v1: 
https://lore.kernel.org/qemu-devel/20220711193743.51456-1-muri...@linux.ibm.com/

 target/ppc/kvm.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 6eed466f80..466d0d2f4c 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1877,6 +1877,12 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len)
 buf[0] = '\0';
 while ((dirp = readdir(dp)) != NULL) {
 FILE *f;
+
+/* Don't accidentally read from the current and parent directories */
+if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) 
{
+continue;
+}
+
 snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU,
  dirp->d_name);
 f = fopen(buf, "r");
-- 
2.36.1




Re: [PATCH v4] ui/cocoa: Take refresh rate into account

2022-07-12 Thread Philippe Mathieu-Daudé via

On 2/7/22 16:25, Akihiko Odaki wrote:

Retreieve the refresh rate of the display and reflect it with
dpy_set_ui_info() and update_displaychangelistener(), allowing the
guest and DisplayChangeListener to consume the information.

The information will be used as a hint how often the display should
be updated. For example, when we run 30 Hz physical display updates
it is pointless for the guest to update the screen at 60Hz
frequency, the guest can spare some work instead.

Signed-off-by: Akihiko Odaki 
---
  meson.build |  3 ++-
  ui/cocoa.m  | 12 
  2 files changed, 14 insertions(+), 1 deletion(-)


Thanks, patch queued.



Re: [PULL 09/18] tests/tcg: compile system emulation tests as freestanding

2022-07-12 Thread Philippe Mathieu-Daudé via

On 12/7/22 14:49, Paolo Bonzini wrote:

System emulation tests do not run in a hosted environment, since they
do not link with libc.  They should only use freestanding headers
(float.h, limits.h, stdarg.h, stddef.h, stdbool.h, stdint.h,
stdalign.h, stdnoreturn.h) and should be compiled with -ffreestanding
in order to use the compiler implementation of those headers
rather than the one in libc.

Some tests are using inttypes.h instead of stdint.h, so fix that.

Signed-off-by: Paolo Bonzini 
---
  tests/tcg/Makefile.target  | 1 +
  tests/tcg/aarch64/system/pauth-3.c | 2 +-
  tests/tcg/aarch64/system/semiconsole.c | 2 +-
  tests/tcg/aarch64/system/semiheap.c| 2 +-
  tests/tcg/multiarch/system/memory.c| 2 +-
  5 files changed, 5 insertions(+), 4 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 



[PULL 12/12] target/mips: Remove GET_TARGET_STRING and FREE_TARGET_STRING

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

Inline these macros into the only two callers.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20220628111701.677216-9-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 27 +--
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index b54267681e..5fb1ad9092 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -198,19 +198,6 @@ static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int 
err)
 uhi_cb(cs, ret, err);
 }
 
-#define GET_TARGET_STRING(p, addr)  \
-do {\
-p = lock_user_string(addr); \
-if (!p) {   \
-report_fault(env);  \
-}   \
-} while (0)
-
-#define FREE_TARGET_STRING(p, gpr)  \
-do {\
-unlock_user(p, gpr, 0); \
-} while (0)
-
 void mips_semihosting(CPUMIPSState *env)
 {
 CPUState *cs = env_cpu(env);
@@ -225,9 +212,13 @@ void mips_semihosting(CPUMIPSState *env)
 
 case UHI_open:
 {
+target_ulong fname = gpr[4];
 int ret = -1;
 
-GET_TARGET_STRING(p, gpr[4]);
+p = lock_user_string(fname);
+if (!p) {
+report_fault(env);
+}
 if (!strcmp("/dev/stdin", p)) {
 ret = 0;
 } else if (!strcmp("/dev/stdout", p)) {
@@ -235,7 +226,7 @@ void mips_semihosting(CPUMIPSState *env)
 } else if (!strcmp("/dev/stderr", p)) {
 ret = 2;
 }
-FREE_TARGET_STRING(p, gpr[4]);
+unlock_user(p, fname, 0);
 
 /* FIXME: reusing a guest fd doesn't seem correct. */
 if (ret >= 0) {
@@ -243,7 +234,7 @@ void mips_semihosting(CPUMIPSState *env)
 break;
 }
 
-semihost_sys_open(cs, uhi_cb, gpr[4], 0, gpr[5], gpr[6]);
+semihost_sys_open(cs, uhi_cb, fname, 0, gpr[5], gpr[6]);
 }
 break;
 
@@ -314,14 +305,14 @@ void mips_semihosting(CPUMIPSState *env)
 
 pct_d = strstr(p, "%d");
 if (!pct_d) {
-FREE_TARGET_STRING(p, addr);
+unlock_user(p, addr, 0);
 semihost_sys_write(cs, uhi_cb, 2, addr, len);
 break;
 }
 
 str = g_string_new_len(p, pct_d - p);
 g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
-FREE_TARGET_STRING(p, addr);
+unlock_user(p, addr, 0);
 
 /*
  * When we're using gdb, we need a guest address, so
-- 
2.36.1




[PULL 11/12] target/mips: Simplify UHI_argnlen and UHI_argn

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

With semihosting_get_arg, we already have a check vs argc, so
there's no point replicating it -- just check the result vs NULL.
Merge copy_argn_to_target into its caller.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-8-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 44 ++
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index ae4b8849b1..b54267681e 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -198,21 +198,6 @@ static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int 
err)
 uhi_cb(cs, ret, err);
 }
 
-static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
-   target_ulong vaddr)
-{
-int strsize = strlen(semihosting_get_arg(arg_num)) + 1;
-char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
-if (!dst) {
-report_fault(env);
-}
-
-strcpy(dst, semihosting_get_arg(arg_num));
-
-unlock_user(dst, vaddr, strsize);
-return 0;
-}
-
 #define GET_TARGET_STRING(p, addr)  \
 do {\
 p = lock_user_string(addr); \
@@ -285,18 +270,31 @@ void mips_semihosting(CPUMIPSState *env)
 gpr[2] = semihosting_get_argc();
 break;
 case UHI_argnlen:
-if (gpr[4] >= semihosting_get_argc()) {
-gpr[2] = -1;
-return;
+{
+const char *s = semihosting_get_arg(gpr[4]);
+gpr[2] = s ? strlen(s) : -1;
 }
-gpr[2] = strlen(semihosting_get_arg(gpr[4]));
 break;
 case UHI_argn:
-if (gpr[4] >= semihosting_get_argc()) {
-gpr[2] = -1;
-return;
+{
+const char *s = semihosting_get_arg(gpr[4]);
+target_ulong addr;
+size_t len;
+
+if (!s) {
+gpr[2] = -1;
+break;
+}
+len = strlen(s) + 1;
+addr = gpr[5];
+p = lock_user(VERIFY_WRITE, addr, len, 0);
+if (!p) {
+report_fault(env);
+}
+memcpy(p, s, len);
+unlock_user(p, addr, len);
+gpr[2] = 0;
 }
-gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
 break;
 
 case UHI_plog:
-- 
2.36.1




[PULL 07/12] target/mips: Use semihosting/syscalls.h

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

This separates guest file descriptors from host file descriptors,
and utilizes shared infrastructure for integration with gdbstub.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-4-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 219 +
 1 file changed, 95 insertions(+), 124 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index 93c9d3d0b3..5b78cf21a7 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -20,9 +20,11 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "qemu/log.h"
+#include "exec/gdbstub.h"
 #include "semihosting/softmmu-uaccess.h"
 #include "semihosting/semihost.h"
 #include "semihosting/console.h"
+#include "semihosting/syscalls.h"
 #include "internal.h"
 
 typedef enum UHIOp {
@@ -121,101 +123,79 @@ static void report_fault(CPUMIPSState *env)
 abort();
 }
 
-static int errno_mips(int host_errno)
+static void uhi_cb(CPUState *cs, uint64_t ret, int err)
 {
-/* Errno values taken from asm-mips/errno.h */
-switch (host_errno) {
-case 0: return 0;
-case ENAMETOOLONG:  return 78;
-#ifdef EOVERFLOW
-case EOVERFLOW: return 79;
-#endif
-#ifdef ELOOP
-case ELOOP: return 90;
-#endif
-default:return EINVAL;
-}
-}
+CPUMIPSState *env = cs->env_ptr;
 
-static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
-   target_ulong vaddr)
-{
-hwaddr len = sizeof(struct UHIStat);
-UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
-if (!dst) {
+#define E(N) case E##N: err = UHI_E##N; break
+
+switch (err) {
+case 0:
+break;
+E(PERM);
+E(NOENT);
+E(INTR);
+E(BADF);
+E(BUSY);
+E(EXIST);
+E(NOTDIR);
+E(ISDIR);
+E(INVAL);
+E(NFILE);
+E(MFILE);
+E(FBIG);
+E(NOSPC);
+E(SPIPE);
+E(ROFS);
+E(NAMETOOLONG);
+default:
+err = UHI_EINVAL;
+break;
+case EFAULT:
 report_fault(env);
 }
 
-dst->uhi_st_dev = tswap16(src->st_dev);
-dst->uhi_st_ino = tswap16(src->st_ino);
-dst->uhi_st_mode = tswap32(src->st_mode);
-dst->uhi_st_nlink = tswap16(src->st_nlink);
-dst->uhi_st_uid = tswap16(src->st_uid);
-dst->uhi_st_gid = tswap16(src->st_gid);
-dst->uhi_st_rdev = tswap16(src->st_rdev);
-dst->uhi_st_size = tswap64(src->st_size);
-dst->uhi_st_atime = tswap64(src->st_atime);
-dst->uhi_st_mtime = tswap64(src->st_mtime);
-dst->uhi_st_ctime = tswap64(src->st_ctime);
-#ifdef _WIN32
-dst->uhi_st_blksize = 0;
-dst->uhi_st_blocks = 0;
-#else
-dst->uhi_st_blksize = tswap64(src->st_blksize);
-dst->uhi_st_blocks = tswap64(src->st_blocks);
-#endif
-unlock_user(dst, vaddr, len);
-return 0;
+#undef E
+
+env->active_tc.gpr[2] = ret;
+env->active_tc.gpr[3] = err;
 }
 
-static int get_open_flags(target_ulong target_flags)
+static void uhi_fstat_cb(CPUState *cs, uint64_t ret, int err)
 {
-int open_flags = 0;
+QEMU_BUILD_BUG_ON(sizeof(UHIStat) < sizeof(struct gdb_stat));
 
-if (target_flags & UHIOpen_RDWR) {
-open_flags |= O_RDWR;
-} else if (target_flags & UHIOpen_WRONLY) {
-open_flags |= O_WRONLY;
-} else {
-open_flags |= O_RDONLY;
+if (!err) {
+CPUMIPSState *env = cs->env_ptr;
+target_ulong addr = env->active_tc.gpr[5];
+UHIStat *dst = lock_user(VERIFY_WRITE, addr, sizeof(UHIStat), 1);
+struct gdb_stat s;
+
+if (!dst) {
+report_fault(env);
+}
+
+memcpy(, dst, sizeof(struct gdb_stat));
+memset(dst, 0, sizeof(UHIStat));
+
+dst->uhi_st_dev = tswap16(be32_to_cpu(s.gdb_st_dev));
+dst->uhi_st_ino = tswap16(be32_to_cpu(s.gdb_st_ino));
+dst->uhi_st_mode = tswap32(be32_to_cpu(s.gdb_st_mode));
+dst->uhi_st_nlink = tswap16(be32_to_cpu(s.gdb_st_nlink));
+dst->uhi_st_uid = tswap16(be32_to_cpu(s.gdb_st_uid));
+dst->uhi_st_gid = tswap16(be32_to_cpu(s.gdb_st_gid));
+dst->uhi_st_rdev = tswap16(be32_to_cpu(s.gdb_st_rdev));
+dst->uhi_st_size = tswap64(be64_to_cpu(s.gdb_st_size));
+dst->uhi_st_atime = tswap64(be32_to_cpu(s.gdb_st_atime));
+dst->uhi_st_mtime = tswap64(be32_to_cpu(s.gdb_st_mtime));
+dst->uhi_st_ctime = tswap64(be32_to_cpu(s.gdb_st_ctime));
+dst->uhi_st_blksize = tswap64(be64_to_cpu(s.gdb_st_blksize));
+dst->uhi_st_blocks = tswap64(be64_to_cpu(s.gdb_st_blocks));
+
+unlock_user(dst, addr, sizeof(UHIStat));
 }
 
-open_flags |= (target_flags & UHIOpen_APPEND) ? O_APPEND : 0;
-open_flags |= (target_flags & UHIOpen_CREAT)  ? O_CREAT  : 0;
-open_flags |= (target_flags & UHIOpen_TRUNC)  ? O_TRUNC  : 0;
-open_flags |= 

[PULL 04/12] target/mips: introduce Cavium Octeon CPU model

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Pavel Dovgalyuk 

This patch adds Cavium Octeon 68XX vCPU which provides
Octeon-specific instructions.

Signed-off-by: Pavel Dovgalyuk 
Message-Id: <165572673785.167724.7604881144978983510.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu-defs.c.inc | 28 
 1 file changed, 28 insertions(+)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 582f940070..7f53c94ec8 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -921,6 +921,34 @@ const mips_def_t mips_defs[] =
 .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSP_R2,
 .mmu_type = MMU_TYPE_R4000,
 },
+{
+/*
+ * Octeon 68xx with MIPS64 Cavium Octeon features.
+ */
+.name = "Octeon68XX",
+.CP0_PRid = 0x000D9100,
+.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
+   (MMU_TYPE_R4000 << CP0C0_MT),
+.CP0_Config1 = MIPS_CONFIG1 | (0x3F << CP0C1_MMU) |
+   (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
+   (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
+   (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+.CP0_Config2 = MIPS_CONFIG2,
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) ,
+.CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) |
+   (0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) |
+   (3U << CP0C4_MMUSizeExt),
+.CP0_LLAddr_rw_bitmask = 0,
+.CP0_LLAddr_shift = 4,
+.CP0_PageGrain = (1 << CP0PG_ELPA),
+.SYNCI_Step = 32,
+.CCRes = 2,
+.CP0_Status_rw_bitmask = 0x12F8,
+.SEGBITS = 42,
+.PABITS = 49,
+.insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP,
+.mmu_type = MMU_TYPE_R4000,
+},
 
 #endif
 };
-- 
2.36.1




[PULL 09/12] target/mips: Use error_report for UHI_assert

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

Always log the assert locally.  Do not report_fault, but
instead include the fact of the fault in the assertion.
Don't bother freeing allocated strings before the abort().

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-6-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 39 ++
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index ad11a46820..ae4b8849b1 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -221,18 +221,6 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 }   \
 } while (0)
 
-#define GET_TARGET_STRINGS_2(p, addr, p2, addr2)\
-do {\
-p = lock_user_string(addr); \
-if (!p) {   \
-report_fault(env);  \
-}   \
-p2 = lock_user_string(addr2);   \
-if (!p2) {  \
-report_fault(env);  \
-}   \
-} while (0)
-
 #define FREE_TARGET_STRING(p, gpr)  \
 do {\
 unlock_user(p, gpr, 0); \
@@ -243,7 +231,7 @@ void mips_semihosting(CPUMIPSState *env)
 CPUState *cs = env_cpu(env);
 target_ulong *gpr = env->active_tc.gpr;
 const UHIOp op = gpr[25];
-char *p, *p2;
+char *p;
 
 switch (op) {
 case UHI_exit:
@@ -355,14 +343,23 @@ void mips_semihosting(CPUMIPSState *env)
 break;
 
 case UHI_assert:
-GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
-printf("assertion '");
-printf("\"%s\"", p);
-printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
-FREE_TARGET_STRING(p2, gpr[5]);
-FREE_TARGET_STRING(p, gpr[4]);
-abort();
-break;
+{
+const char *msg, *file;
+
+msg = lock_user_string(gpr[4]);
+if (!msg) {
+msg = "";
+}
+file = lock_user_string(gpr[5]);
+if (!file) {
+file = "";
+}
+
+error_report("UHI assertion \"%s\": file \"%s\", line %d",
+ msg, file, (int)gpr[6]);
+abort();
+}
+
 default:
 error_report("Unknown UHI operation %d", op);
 abort();
-- 
2.36.1




[PULL 02/12] target/mips: implement Octeon-specific BBIT instructions

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Pavel Dovgalyuk 

This patch introduces Octeon-specific decoder and implements
check-bit-and-jump instructions.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Richard Henderson 
Message-Id: <165572672705.167724.16667636081912075906.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/octeon.decode  |  9 +
 target/mips/tcg/octeon_translate.c | 30 ++
 2 files changed, 39 insertions(+)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index b21c735a6c..8062715578 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -4,3 +4,12 @@
 #
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
+
+# Branch on bit set or clear
+# BBIT0  110010 . . 
+# BBIT032110110 . . 
+# BBIT1  111010 . . 
+# BBIT13210 . . 
+
+%bbit_p  28:1 16:5
+BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
diff --git a/target/mips/tcg/octeon_translate.c 
b/target/mips/tcg/octeon_translate.c
index 8b5eb1a823..1558f74a8e 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -14,3 +14,33 @@
 
 /* Include the auto-generated decoder.  */
 #include "decode-octeon.c.inc"
+
+static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
+{
+TCGv p;
+
+if (ctx->hflags & MIPS_HFLAG_BMASK) {
+LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
+  TARGET_FMT_lx "\n", ctx->base.pc_next);
+generate_exception_end(ctx, EXCP_RI);
+return true;
+}
+
+/* Load needed operands */
+TCGv t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+
+p = tcg_constant_tl(1ULL << a->p);
+if (a->set) {
+tcg_gen_and_tl(bcond, p, t0);
+} else {
+tcg_gen_andc_tl(bcond, p, t0);
+}
+
+ctx->hflags |= MIPS_HFLAG_BC;
+ctx->btarget = ctx->base.pc_next + 4 + a->offset * 4;
+ctx->hflags |= MIPS_HFLAG_BDS32;
+
+tcg_temp_free(t0);
+return true;
+}
-- 
2.36.1




[PULL 10/12] semihosting: Remove qemu_semihosting_log_out

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

The function is no longer used.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20220628111701.677216-7-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/semihosting/console.h | 13 -
 semihosting/console.c |  9 -
 2 files changed, 22 deletions(-)

diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index 61b0cb3a94..bd78e5f03f 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -40,19 +40,6 @@ int qemu_semihosting_console_read(CPUState *cs, void *buf, 
int len);
  */
 int qemu_semihosting_console_write(void *buf, int len);
 
-/**
- * qemu_semihosting_log_out:
- * @s: pointer to string
- * @len: length of string
- *
- * Send a string to the debug output. Unlike console_out these strings
- * can't be sent to a remote gdb instance as they don't exist in guest
- * memory.
- *
- * Returns: number of bytes written
- */
-int qemu_semihosting_log_out(const char *s, int len);
-
 /*
  * qemu_semihosting_console_block_until_ready:
  * @cs: CPUState
diff --git a/semihosting/console.c b/semihosting/console.c
index cda7cf1905..5b1ec0a1c3 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -38,15 +38,6 @@ typedef struct SemihostingConsole {
 
 static SemihostingConsole console;
 
-int qemu_semihosting_log_out(const char *s, int len)
-{
-if (console.chr) {
-return qemu_chr_write_all(console.chr, (uint8_t *) s, len);
-} else {
-return write(STDERR_FILENO, s, len);
-}
-}
-
 #define FIFO_SIZE   1024
 
 static int console_can_read(void *opaque)
-- 
2.36.1




[PULL 05/12] target/mips: Create report_fault for semihosting

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

The UHI specification does not have an EFAULT value,
and further specifies that "undefined UHI operations
should not return control to the target".

So, log the error and abort.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-2-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 33 ++
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index 67c35fe7f9..153df1fa15 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -114,6 +114,13 @@ enum UHIErrno {
 UHI_EXDEV   = 18,
 };
 
+static void report_fault(CPUMIPSState *env)
+{
+int op = env->active_tc.gpr[25];
+error_report("Fault during UHI operation %d", op);
+abort();
+}
+
 static int errno_mips(int host_errno)
 {
 /* Errno values taken from asm-mips/errno.h */
@@ -136,8 +143,7 @@ static int copy_stat_to_target(CPUMIPSState *env, const 
struct stat *src,
 hwaddr len = sizeof(struct UHIStat);
 UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
 if (!dst) {
-errno = EFAULT;
-return -1;
+report_fault(env);
 }
 
 dst->uhi_st_dev = tswap16(src->st_dev);
@@ -188,8 +194,7 @@ static int write_to_file(CPUMIPSState *env, target_ulong fd,
 int num_of_bytes;
 void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
 if (!dst) {
-errno = EFAULT;
-return -1;
+report_fault(env);
 }
 
 num_of_bytes = write(fd, dst, len);
@@ -204,8 +209,7 @@ static int read_from_file(CPUMIPSState *env, target_ulong 
fd,
 int num_of_bytes;
 void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
 if (!dst) {
-errno = EFAULT;
-return -1;
+report_fault(env);
 }
 
 num_of_bytes = read(fd, dst, len);
@@ -220,7 +224,7 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 int strsize = strlen(semihosting_get_arg(arg_num)) + 1;
 char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
 if (!dst) {
-return -1;
+report_fault(env);
 }
 
 strcpy(dst, semihosting_get_arg(arg_num));
@@ -233,9 +237,7 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 do {\
 p = lock_user_string(addr); \
 if (!p) {   \
-gpr[2] = -1;\
-gpr[3] = EFAULT;\
-return; \
+report_fault(env);  \
 }   \
 } while (0)
 
@@ -243,16 +245,11 @@ static int copy_argn_to_target(CPUMIPSState *env, int 
arg_num,
 do {\
 p = lock_user_string(addr); \
 if (!p) {   \
-gpr[2] = -1;\
-gpr[3] = EFAULT;\
-return; \
+report_fault(env);  \
 }   \
 p2 = lock_user_string(addr2);   \
 if (!p2) {  \
-unlock_user(p, addr, 0);\
-gpr[2] = -1;\
-gpr[3] = EFAULT;\
-return; \
+report_fault(env);  \
 }   \
 } while (0)
 
@@ -375,7 +372,7 @@ void mips_semihosting(CPUMIPSState *env)
 break;
 #endif
 default:
-fprintf(stderr, "Unknown UHI operation %d\n", op);
+error_report("Unknown UHI operation %d", op);
 abort();
 }
 return;
-- 
2.36.1




[PULL 01/12] target/mips: introduce decodetree structure for Cavium Octeon extension

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Pavel Dovgalyuk 

This patch adds decodetree for Cavium Octeon extension and
an instruction set extension flag for using it in CPU models.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Richard Henderson 
Message-Id: <165572672162.167724.13656301229517693806.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/mips-defs.h|  1 +
 target/mips/tcg/meson.build|  2 ++
 target/mips/tcg/octeon.decode  |  6 ++
 target/mips/tcg/octeon_translate.c | 16 
 target/mips/tcg/translate.c|  5 +
 target/mips/tcg/translate.h|  1 +
 6 files changed, 31 insertions(+)
 create mode 100644 target/mips/tcg/octeon.decode
 create mode 100644 target/mips/tcg/octeon_translate.c

diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index 0a12d982a7..a6cebe0265 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -42,6 +42,7 @@
 #define INSN_LOONGSON2E   0x0400ULL
 #define INSN_LOONGSON2F   0x0800ULL
 #define INSN_LOONGSON3A   0x1000ULL
+#define INSN_OCTEON   0x2000ULL
 /*
  *   bits 52-63: vendor-specific ASEs
  */
diff --git a/target/mips/tcg/meson.build b/target/mips/tcg/meson.build
index 98003779ae..7ee969ec8f 100644
--- a/target/mips/tcg/meson.build
+++ b/target/mips/tcg/meson.build
@@ -3,6 +3,7 @@ gen = [
   decodetree.process('msa.decode', extra_args: '--decode=decode_ase_msa'),
   decodetree.process('tx79.decode', extra_args: '--static-decode=decode_tx79'),
   decodetree.process('vr54xx.decode', extra_args: 
'--decode=decode_ext_vr54xx'),
+  decodetree.process('octeon.decode', extra_args: 
'--decode=decode_ext_octeon'),
 ]
 
 mips_ss.add(gen)
@@ -24,6 +25,7 @@ mips_ss.add(files(
 ))
 mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
   'tx79_translate.c',
+  'octeon_translate.c',
 ), if_false: files(
   'mxu_translate.c',
 ))
diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
new file mode 100644
index 00..b21c735a6c
--- /dev/null
+++ b/target/mips/tcg/octeon.decode
@@ -0,0 +1,6 @@
+# Octeon Architecture Module instruction set
+#
+# Copyright (C) 2022 Pavel Dovgalyuk
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
diff --git a/target/mips/tcg/octeon_translate.c 
b/target/mips/tcg/octeon_translate.c
new file mode 100644
index 00..8b5eb1a823
--- /dev/null
+++ b/target/mips/tcg/octeon_translate.c
@@ -0,0 +1,16 @@
+/*
+ * Octeon-specific instructions translation routines
+ *
+ *  Copyright (c) 2022 Pavel Dovgalyuk
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "tcg/tcg-op.h"
+#include "tcg/tcg-op-gvec.h"
+#include "exec/helper-gen.h"
+#include "translate.h"
+
+/* Include the auto-generated decoder.  */
+#include "decode-octeon.c.inc"
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index d9d7692765..1f6a779808 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -15955,6 +15955,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, 
ctx->opcode)) {
 return;
 }
+#if defined(TARGET_MIPS64)
+if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, 
ctx->opcode)) {
+return;
+}
+#endif
 
 /* ISA extensions */
 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index 9997fe2f3c..55053226ae 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -215,6 +215,7 @@ bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
 bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
 #if defined(TARGET_MIPS64)
 bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
+bool decode_ext_octeon(DisasContext *ctx, uint32_t insn);
 #endif
 bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
 
-- 
2.36.1




[PULL 08/12] target/mips: Avoid qemu_semihosting_log_out for UHI_plog

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

Use semihost_sys_write and/or qemu_semihosting_console_write
for implementing plog.  When using gdbstub, copy the temp
string below the stack so that gdb has a guest address from
which to perform the log.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-5-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 52 +++---
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index 5b78cf21a7..ad11a46820 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -310,20 +310,50 @@ void mips_semihosting(CPUMIPSState *env)
 }
 gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
 break;
+
 case UHI_plog:
-GET_TARGET_STRING(p, gpr[4]);
-p2 = strstr(p, "%d");
-if (p2) {
-int char_num = p2 - p;
-GString *s = g_string_new_len(p, char_num);
-g_string_append_printf(s, "%d%s", (int)gpr[5], p2 + 2);
-gpr[2] = qemu_semihosting_log_out(s->str, s->len);
-g_string_free(s, true);
-} else {
-gpr[2] = qemu_semihosting_log_out(p, strlen(p));
+{
+target_ulong addr = gpr[4];
+ssize_t len = target_strlen(addr);
+GString *str;
+char *pct_d;
+
+if (len < 0) {
+report_fault(env);
+}
+p = lock_user(VERIFY_READ, addr, len, 1);
+if (!p) {
+report_fault(env);
+}
+
+pct_d = strstr(p, "%d");
+if (!pct_d) {
+FREE_TARGET_STRING(p, addr);
+semihost_sys_write(cs, uhi_cb, 2, addr, len);
+break;
+}
+
+str = g_string_new_len(p, pct_d - p);
+g_string_append_printf(str, "%d%s", (int)gpr[5], pct_d + 2);
+FREE_TARGET_STRING(p, addr);
+
+/*
+ * When we're using gdb, we need a guest address, so
+ * drop the string onto the stack below the stack pointer.
+ */
+if (use_gdb_syscalls()) {
+addr = gpr[29] - str->len;
+p = lock_user(VERIFY_WRITE, addr, str->len, 0);
+memcpy(p, str->str, str->len);
+unlock_user(p, addr, str->len);
+semihost_sys_write(cs, uhi_cb, 2, addr, str->len);
+} else {
+gpr[2] = qemu_semihosting_console_write(str->str, str->len);
+}
+g_string_free(str, true);
 }
-FREE_TARGET_STRING(p, gpr[4]);
 break;
+
 case UHI_assert:
 GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
 printf("assertion '");
-- 
2.36.1




[PULL 06/12] target/mips: Drop link syscall from semihosting

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Richard Henderson 

We don't implement it with _WIN32 hosts, and the syscall
is missing from the gdb remote file i/o interface.
Since we can't implement it universally, drop it.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220628111701.677216-3-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/sysemu/mips-semi.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/mips/tcg/sysemu/mips-semi.c 
b/target/mips/tcg/sysemu/mips-semi.c
index 153df1fa15..93c9d3d0b3 100644
--- a/target/mips/tcg/sysemu/mips-semi.c
+++ b/target/mips/tcg/sysemu/mips-semi.c
@@ -362,15 +362,6 @@ void mips_semihosting(CPUMIPSState *env)
 FREE_TARGET_STRING(p, gpr[4]);
 abort();
 break;
-#ifndef _WIN32
-case UHI_link:
-GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
-gpr[2] = link(p, p2);
-gpr[3] = errno_mips(errno);
-FREE_TARGET_STRING(p2, gpr[5]);
-FREE_TARGET_STRING(p, gpr[4]);
-break;
-#endif
 default:
 error_report("Unknown UHI operation %d", op);
 abort();
-- 
2.36.1




[PULL 03/12] target/mips: implement Octeon-specific arithmetic instructions

2022-07-12 Thread Philippe Mathieu-Daudé via
From: Pavel Dovgalyuk 

This patch implements several Octeon-specific instructions:
- BADDU
- DMUL
- EXTS/EXTS32
- CINS/CINS32
- POP/DPOP
- SEQ/SEQI
- SNE/SNEI

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Richard Henderson 
Message-Id: <165572673245.167724.17377788816335619000.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/octeon.decode  |  26 +
 target/mips/tcg/octeon_translate.c | 155 +
 2 files changed, 181 insertions(+)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 8062715578..8929ad088e 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -13,3 +13,29 @@
 
 %bbit_p  28:1 16:5
 BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
+
+# Arithmetic
+# BADDU rd, rs, rt
+# DMUL rd, rs, rt
+# EXTS rt, rs, p, lenm1
+# EXTS32 rt, rs, p, lenm1
+# CINS rt, rs, p, lenm1
+# CINS32 rt, rs, p, lenm1
+# DPOP rd, rs
+# POP rd, rs
+# SEQ rd, rs, rt
+# SEQI rt, rs, immediate
+# SNE rd, rs, rt
+# SNEI rt, rs, immediate
+
+@r3  .. rs:5 rt:5 rd:5 . ..
+%bitfield_p  0:1 6:5
+@bitfield.. rs:5 rt:5 lenm1:5 . . . p=%bitfield_p
+
+BADDU011100 . . . 0 101000 @r3
+DMUL 011100 . . . 0 11 @r3
+EXTS 011100 . . . . 11101 . @bitfield
+CINS 011100 . . . . 11001 . @bitfield
+POP  011100 rs:5 0 rd:5 0 10110 dw:1
+SEQNE011100 rs:5 rt:5 rd:5 0 10101 ne:1
+SEQNEI   011100 rs:5 rt:5 imm:s10 10111 ne:1
diff --git a/target/mips/tcg/octeon_translate.c 
b/target/mips/tcg/octeon_translate.c
index 1558f74a8e..6a207d2e7e 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -44,3 +44,158 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
 tcg_temp_free(t0);
 return true;
 }
+
+static bool trans_BADDU(DisasContext *ctx, arg_BADDU *a)
+{
+TCGv t0, t1;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+tcg_gen_add_tl(t0, t0, t1);
+tcg_gen_andi_i64(cpu_gpr[a->rd], t0, 0xff);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_DMUL(DisasContext *ctx, arg_DMUL *a)
+{
+TCGv t0, t1;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+tcg_gen_mul_i64(cpu_gpr[a->rd], t0, t1);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_EXTS(DisasContext *ctx, arg_EXTS *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+tcg_gen_sextract_tl(t0, t0, a->p, a->lenm1 + 1);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_CINS(DisasContext *ctx, arg_CINS *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+tcg_gen_deposit_z_tl(t0, t0, a->p, a->lenm1 + 1);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_POP(DisasContext *ctx, arg_POP *a)
+{
+TCGv t0;
+
+if (a->rd == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+if (!a->dw) {
+tcg_gen_andi_i64(t0, t0, 0x);
+}
+tcg_gen_ctpop_tl(t0, t0);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_SEQNE(DisasContext *ctx, arg_SEQNE *a)
+{
+TCGv t0, t1;
+
+if (a->rd == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+if (a->ne) {
+tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr[a->rd], t1, t0);
+} else {
+tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr[a->rd], t1, t0);
+}
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+
+gen_load_gpr(t0, a->rs);
+
+/* Sign-extend to 64 bit value */
+target_ulong imm = a->imm;
+if (a->ne) {
+tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr[a->rt], t0, imm);
+} else {
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr[a->rt], t0, imm);
+}
+
+tcg_temp_free(t0);
+
+return true;
+}
-- 
2.36.1




  1   2   3   4   >