Re: Intention to work on GSoC project

2024-03-15 Thread Sahil
Hi,

Thank you for your email.

On Thursday, March 14, 2024 8:39:45 PM IST Eugenio Perez Martin wrote:
> Hi Sahil,
> 
> It's being hard to find a good self-contained small task related to
> the project to be honest. As it would be out of SVQ, would it be ok
> for you if we start straight to the task of adding the packed vq
> format to SVQ?
> 
> Thanks!

Sure, this works too! I would love to get started with the project.

I have a small update as well. I have read through a few docs and
articles to familiarize myself with the relevant terminology and
technicalities.

1. "About", "system emulation" and "user mode emulation" sections of
the user documentation [1]
2. The migration subsystem [2]

Some sections in the above docs were difficult to grasp. For the time
being, I have focused on those parts that I thought were relevant
to the project.

I have also read through the following articles:

1. Introduction to virtio-networking and vhost-net [3]
2. Deep dive into Virtio-networking and vhost-net [4]
3. Virtualized Hardware Devices [5]
4. VFIO - "Virtual Function I/O" (Just the introduction) [6]
5. Virtio-net failover: An introduction [7]

I hope I haven't gone off on a tangent. I was planning to finish reading
up on the following articles as well:

1. Virtqueues and virtio ring: How the data travels [8]
2. Packed virtqueue: How to reduce overhead with virtio [9]
3. Virtio live migration technical deep dive [10]
4. Hands on vDPA: what do you do when you ain't got the hardware v2 (Part 1) 
[11]

I believe the hands-on vPDA article will have me set up a development
environment for the project as well.

Please let me know if I should amend my roadmap. I am
excited to get started :)

Thanks,
Sahil

[1] https://www.qemu.org/docs/master/index.html
[2] https://www.qemu.org/docs/master/devel/migration/index.html
[3] https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net
[4] https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net
[5] 
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_getting_started_guide/sec-virtualization_getting_started-products-virtualized-hardware-devices
[6] https://www.kernel.org/doc/html/latest/driver-api/vfio.html
[7] https://www.redhat.com/en/blog/virtio-net-failover-introduction
[8] https://www.redhat.com/en/blog/virtqueues-and-virtio-ring-how-data-travels
[9] 
https://developers.redhat.com/articles/2024/02/21/virtio-live-migration-technical-deep-dive
[10] https://www.redhat.com/en/blog/packed-virtqueue-how-reduce-overhead-virtio
[11] 
https://www.redhat.com/en/blog/hands-vdpa-what-do-you-do-when-you-aint-got-hardware-part-1





[PATCH V5] target/loongarch: Fix tlb huge page loading issue

2024-03-15 Thread Xianglai Li
When we use qemu tcg simulation, the page size of bios is 4KB.
When using the level 2 super huge page (page size is 1G) to create the page 
table,
it is found that the content of the corresponding address space is abnormal,
resulting in the bios can not start the operating system and graphical 
interface normally.

The lddir and ldpte instruction emulation has
a problem with the use of super huge page processing above level 2.
The page size is not correctly calculated,
resulting in the wrong page size of the table entry found by tlb.

Signed-off-by: Xianglai Li 
---
 target/loongarch/cpu-csr.h|   3 +
 target/loongarch/internals.h  |   5 --
 target/loongarch/tcg/tlb_helper.c | 111 +-
 3 files changed, 80 insertions(+), 39 deletions(-)

Changes log:
V4->V5:
Modifying the patch Title.
Fix incorrect usage of FIELD macro and code logic errors in patch.

V3->V4:
Optimize the huge page calculation method,
use the FIELD macro for bit calculation.

V2->V3:
Delete the intermediate variable LDDIR_PS, and implement lddir and ldpte
huge pages by referring to the latest architecture reference manual.

V1->V2:
Modified the patch title format and Enrich the commit mesg description

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index c59d7a9fcb..0834e91f30 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -67,6 +67,9 @@ FIELD(TLBENTRY, D, 1, 1)
 FIELD(TLBENTRY, PLV, 2, 2)
 FIELD(TLBENTRY, MAT, 4, 2)
 FIELD(TLBENTRY, G, 6, 1)
+FIELD(TLBENTRY, HUGE, 6, 1)
+FIELD(TLBENTRY, HGLOBAL, 12, 1)
+FIELD(TLBENTRY, LEVEL, 13, 2)
 FIELD(TLBENTRY_32, PPN, 8, 24)
 FIELD(TLBENTRY_64, PPN, 12, 36)
 FIELD(TLBENTRY_64, NR, 61, 1)
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index a2fc54c8a7..944153b180 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -16,11 +16,6 @@
 #define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS)
 #define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS)
 
-/* Global bit used for lddir/ldpte */
-#define LOONGARCH_PAGE_HUGE_SHIFT   6
-/* Global bit for huge page */
-#define LOONGARCH_HGLOBAL_SHIFT 12
-
 void loongarch_translate_init(void);
 
 void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/loongarch/tcg/tlb_helper.c 
b/target/loongarch/tcg/tlb_helper.c
index 22be031ac7..1d22afddd3 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -17,6 +17,34 @@
 #include "exec/log.h"
 #include "cpu-csr.h"
 
+static void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
+   uint64_t *dir_width, target_ulong level)
+{
+switch (level) {
+case 1:
+*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
+*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH);
+break;
+case 2:
+*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE);
+*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH);
+break;
+case 3:
+*dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE);
+*dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH);
+break;
+case 4:
+*dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE);
+*dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH);
+break;
+default:
+/* level may be zero for ldpte */
+*dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
+*dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
+break;
+}
+}
+
 static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
 MMUAccessType access_type, int tlb_error)
 {
@@ -485,7 +513,23 @@ target_ulong helper_lddir(CPULoongArchState *env, 
target_ulong base,
 target_ulong badvaddr, index, phys, ret;
 int shift;
 uint64_t dir_base, dir_width;
-bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1;
+
+if (unlikely((level == 0) || (level > 4))) {
+return base;
+}
+
+if (FIELD_EX64(base, TLBENTRY, HUGE)) {
+if (unlikely(level == 4)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "Attempted use of level %lu huge page\n", level);
+}
+
+if (FIELD_EX64(base, TLBENTRY, LEVEL)) {
+return base;
+} else {
+return FIELD_DP64(base, TLBENTRY, LEVEL, level);
+}
+}
 
 badvaddr = env->CSR_TLBRBADV;
 base = base & TARGET_PHYS_MASK;
@@ -494,30 +538,7 @@ target_ulong helper_lddir(CPULoongArchState *env, 
target_ulong base,
 shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
 shift = (shift + 1) * 3;
 
-if (huge) {
-return base;
-}
-switch (level) {
-case 1:
-dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE);
-dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_W

Re: [PATCH] target/i386: Export RFDS bit to guests

2024-03-15 Thread Zhao Liu
Hi Pawan,

On Wed, Mar 13, 2024 at 07:53:23AM -0700, Pawan Gupta wrote:
> Date: Wed, 13 Mar 2024 07:53:23 -0700
> From: Pawan Gupta 
> Subject: [PATCH] target/i386: Export RFDS bit to guests
> 
> Register File Data Sampling (RFDS) is a CPU side-channel vulnerability
> that may expose stale register value. CPUs that set RFDS_NO bit in MSR
> IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS.
> Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has
> the microcode to help mitigate RFDS.
> 
> Make RFDS_CLEAR and RFDS_NO bits available to guests.

Are these two bits going to be supported by microcode updates to
existing products?

(Let me aslo attach the related spec to make it easy for more people to
learn about backgrounds: 
https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/register-file-data-sampling.html)

> Signed-off-by: Pawan Gupta 
> ---
>  target/i386/cpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

LGTM,

Reviewed-by: Zhao Liu 





Re: [PATCH for 9.0 v15 03/10] target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess

2024-03-15 Thread Richard Henderson

On 3/14/24 07:56, Daniel Henrique Barboza wrote:

vmvr_v isn't handling the case where the host might be big endian and
the bytes to be copied aren't sequential.

Suggested-by: Richard Henderson
Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza
---
  target/riscv/vector_helper.c | 10 +-
  1 file changed, 9 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH for 9.0 v15 04/10] target/riscv: always clear vstart in whole vec move insns

2024-03-15 Thread Richard Henderson

On 3/14/24 07:56, Daniel Henrique Barboza wrote:

These insns have 2 paths: we'll either have vstart already cleared if
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
the 'vmvr_v' helper. The helper will clear vstart if it executes until
the end, or if vstart >= vl.

For starters, the check itself is wrong: we're checking vstart >= maxsz,
when in fact we should use vstart in bytes, or 'startb' like 'vmvr_v' is
calling, to do the comparison. But even after fixing the comparison we'll
still need to clear vstart in the end, which isn't happening too.

We want to make the helpers responsible to manage vstart, including
these corner cases, precisely to avoid these situations:

- remove the wrong vstart >= maxsz cond from the translation;
- add a 'startb >= maxsz' cond in 'vmvr_v', and clear vstart if that
   happens.

This way we're now sure that vstart is being cleared in the end of the
execution, regardless of the path taken.

Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza
---
  target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
  target/riscv/vector_helper.c| 5 +
  2 files changed, 5 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH V4 1/1] target/loongarch: Fixed tlb huge page loading issue

2024-03-15 Thread Richard Henderson

On 3/14/24 20:22, lixianglai wrote:

Hi Richard:

On 3/13/24 15:33, Xianglai Li wrote:

+    if (unlikely((level == 0) || (level > 4))) {
+    return base;
+    }

...

Perhaps it would be worthwhile to add another for the level==0 or > 4 case 
above?


A normal level 4 page table should not print an error log,

only if a level 4 page is large, so we should put it in

     if (FIELD_EX64(base, TLBENTRY, HUGE)) {
     if (unlikely(level == 4)) {
     qemu_log_mask(LOG_GUEST_ERROR,
   "Attempted use of level %lu huge page\n", level);
     }

     if (FIELD_EX64(base, TLBENTRY, LEVEL)) {
     return base;
     } else {
     return  FIELD_DP64(base, TLBENTRY, LEVEL, level);
     }
     }


A level 5 page table is not normal, nor is a level 0 lddir.


r~



Re: [PATCH v4 0/3] Adjust the output of x-query-virtio-status

2024-03-15 Thread Markus Armbruster
"Michael S. Tsirkin"  writes:

> On Wed, Mar 13, 2024 at 10:40:21AM +0100, Markus Armbruster wrote:
>> I could be awkward for the use case described in PATCH 1's commit
>> message:
>> 
>> However, we sometimes want to compare features and status bits without
>> caring for their exact meaning.  Say we want to verify the correctness
>> of the virtio negotiation between guest, QEMU, and OVS-DPDK.  We can use
>> QMP command x-query-virtio-status to retrieve vhost-user net device
>> features, and the "ovs-vsctl list interface" command to retrieve
>> interface features.  Without commit f3034ad71fc, we could then simply
>> compare the numbers.  With this commit, we first have to map from the
>> strings back to the numeric encoding.
>
> So, consider how guest kernel presents features then. Do you happen to know?
> It's actually a binary string:
>
> static ssize_t features_show(struct device *_d,
>  struct device_attribute *attr, char *buf)
> {
> struct virtio_device *dev = dev_to_virtio(_d);
> unsigned int i;
> ssize_t len = 0;
>
> /* We actually represent this as a bitstring, as it could be
>  * arbitrary length in future. */
> for (i = 0; i < sizeof(dev->features)*8; i++)
> len += sysfs_emit_at(buf, len, "%c",
>__virtio_test_bit(dev, i) ? '1' : '0');
> len += sysfs_emit_at(buf, len, "\n");
> return len;
> }
> static DEVICE_ATTR_RO(features);

I'm willing to accept any reasonably compact representation of the bits
that is easy to use for the comparison use case.

I strongly prefer integers as long as their width suffices.

Since out integers are limited to 64 bits, and you want us to design for
more, we need something else.

I'm fine with array of integers, but you don't like it.

We generally avoid encoding stuff in strings, but using strings for
"overwide" integers isn't as bad as using them for structured data.  I
guess I'd be okay with it.

I'd use decimal simply to keep these "overwide" integers as close as
possible to regular ones.

If using base 2 enables string compare for the comparison use case,
that's an argument for base 2.

Hyman Huang, can you show us example output of "ovs-vsctl list
interface"?




Re: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err check

2024-03-15 Thread Zhao Liu
On Thu, Feb 29, 2024 at 11:37:38AM +0800, Zhenzhong Duan wrote:
> Date: Thu, 29 Feb 2024 11:37:38 +0800
> From: Zhenzhong Duan 
> Subject: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err
>  check
> X-Mailer: git-send-email 2.34.1
> 
> In the error return path, local_err is always set, no need to check it.

The original error handling code indicates "local_err is always set",
and error_propagate() can handle the case that local_err is NULL.

> Signed-off-by: Zhenzhong Duan 
> ---
>  qom/object_interfaces.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
> index e0833c8bfe..255a7bf659 100644
> --- a/qom/object_interfaces.c
> +++ b/qom/object_interfaces.c
> @@ -128,13 +128,11 @@ Object *user_creatable_add_type(const char *type, const 
> char *id,
>  }
>  goto out;
>  }
> -out:
> -if (local_err) {
> -error_propagate(errp, local_err);
> -object_unref(obj);
> -return NULL;
> -}
>  return obj;
> +out:

Maybe rename this to "err:"? Since now it's just used to handle error,
and "goto err" seems more clear.

> +error_propagate(errp, local_err);
> +object_unref(obj);
> +return NULL;
>  }
>  
>  void user_creatable_add_qapi(ObjectOptions *options, Error **errp)
> -- 
> 2.34.1
> 

Otherwise,

Reviewed-by: Zhao Liu 





Re: [PATCH 2/2] qom/object_interfaces: Remove local_err in user_creatable_add_type

2024-03-15 Thread Zhao Liu
On Thu, Feb 29, 2024 at 11:37:39AM +0800, Zhenzhong Duan wrote:
> Date: Thu, 29 Feb 2024 11:37:39 +0800
> From: Zhenzhong Duan 
> Subject: [PATCH 2/2] qom/object_interfaces: Remove local_err in
>  user_creatable_add_type
> X-Mailer: git-send-email 2.34.1
> 
> In user_creatable_add_type, there is mixed usage of ERRP_GUARD and
> local_err. This makes error_abort not taking effect in those callee
> functions with local_err passed.
> 
> Now that we already has ERRP_GUARD, remove local_err and use *errp
> instead.
> 
> Signed-off-by: Zhenzhong Duan 
> ---
>  qom/object_interfaces.c | 12 +---
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
> index 255a7bf659..165cd433e7 100644
> --- a/qom/object_interfaces.c
> +++ b/qom/object_interfaces.c
> @@ -81,7 +81,6 @@ Object *user_creatable_add_type(const char *type, const 
> char *id,
>  ERRP_GUARD();
>  Object *obj;
>  ObjectClass *klass;
> -Error *local_err = NULL;
>  
>  if (id != NULL && !id_wellformed(id)) {
>  error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an 
> identifier");
> @@ -109,20 +108,20 @@ Object *user_creatable_add_type(const char *type, const 
> char *id,
>  
>  assert(qdict);
>  obj = object_new(type);
> -object_set_properties_from_qdict(obj, qdict, v, &local_err);
> -if (local_err) {
> +object_set_properties_from_qdict(obj, qdict, v, errp);

It's better to make object_set_properties_from_qdict someting (e.g.,
boolean). Maybe an extra cleanup?

> +if (*errp) {
>  goto out;
>  }
>  
>  if (id != NULL) {
>  object_property_try_add_child(object_get_objects_root(),
> -  id, obj, &local_err);
> -if (local_err) {
> +  id, obj, errp);
> +if (*errp) {
>  goto out;
>  }
>  }

Here we could check whether the returned ObjectProperty* is NULL instaed
of dereferencing errp.

Thanks,
Zhao




Re: [PATCH] vhost-vdpa: check vhost_vdpa_set_vring_ready() return value

2024-03-15 Thread Stefano Garzarella

On Thu, Mar 14, 2024 at 11:17:01AM +0800, Jason Wang wrote:

On Wed, Feb 7, 2024 at 5:27 PM Stefano Garzarella  wrote:


vhost_vdpa_set_vring_ready() could already fail, but if Linux's
patch [1] will be merged, it may fail with more chance if
userspace does not activate virtqueues before DRIVER_OK when
VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK is not negotiated.


I wonder what happens if we just leave it as is.


Are you referring to this patch or the kernel patch?

Here I'm just checking the return value of vhost_vdpa_set_vring_ready().
It can return an error also without that kernel patch, so IMHO is
better to check the return value here in QEMU.

What issue do you see with this patch applied?



VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK: We do know enabling could be
done after driver_ok.
Without VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK: We don't know whether
enabling could be done after driver_ok or not.


I see your point, indeed I didn't send a v2 of that patch.
Maybe we should document that, because it could be interpreted that if
VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK is not negotiated the enabling
should always be done before driver_ok (which is true for example in
VDUSE).

BTW I think we should discuss it in the kernel patch.

Thanks,
Stefano



Thanks



So better check its return value anyway.

[1] 
https://lore.kernel.org/virtualization/20240206145154.118044-1-sgarz...@redhat.com/T/#u

Signed-off-by: Stefano Garzarella 
---
Note: This patch conflicts with [2], but the resolution is simple,
so for now I sent a patch for the current master, but I'll rebase
this patch if we merge the other one first.

[2] 
https://lore.kernel.org/qemu-devel/20240202132521.32714-1-kw...@redhat.com/

---
 hw/virtio/vdpa-dev.c |  8 +++-
 net/vhost-vdpa.c | 15 ---
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index eb9ecea83b..d57cd76c18 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -259,7 +259,11 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, 
Error **errp)
 goto err_guest_notifiers;
 }
 for (i = 0; i < s->dev.nvqs; ++i) {
-vhost_vdpa_set_vring_ready(&s->vdpa, i);
+ret = vhost_vdpa_set_vring_ready(&s->vdpa, i);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error starting vring %d", i);
+goto err_dev_stop;
+}
 }
 s->started = true;

@@ -274,6 +278,8 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, 
Error **errp)

 return ret;

+err_dev_stop:
+vhost_dev_stop(&s->dev, vdev, false);
 err_guest_notifiers:
 k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
 err_host_notifiers:
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 3726ee5d67..e3d8036479 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -381,7 +381,10 @@ static int vhost_vdpa_net_data_load(NetClientState *nc)
 }

 for (int i = 0; i < v->dev->nvqs; ++i) {
-vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index);
+int ret = vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index);
+if (ret < 0) {
+return ret;
+}
 }
 return 0;
 }
@@ -1213,7 +1216,10 @@ static int vhost_vdpa_net_cvq_load(NetClientState *nc)

 assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);

-vhost_vdpa_set_vring_ready(v, v->dev->vq_index);
+r = vhost_vdpa_set_vring_ready(v, v->dev->vq_index);
+if (unlikely(r < 0)) {
+return r;
+}

 if (v->shadow_vqs_enabled) {
 n = VIRTIO_NET(v->dev->vdev);
@@ -1252,7 +1258,10 @@ static int vhost_vdpa_net_cvq_load(NetClientState *nc)
 }

 for (int i = 0; i < v->dev->vq_index; ++i) {
-vhost_vdpa_set_vring_ready(v, i);
+r = vhost_vdpa_set_vring_ready(v, i);
+if (unlikely(r < 0)) {
+return r;
+}
 }

 return 0;
--
2.43.0








Re: [PATCH v5 49/65] i386/tdx: handle TDG.VP.VMCALL

2024-03-15 Thread Xiaoyao Li

On 3/13/2024 11:31 PM, Daniel P. Berrangé wrote:

On Tue, Mar 12, 2024 at 03:44:32PM +0800, Xiaoyao Li wrote:

On 3/11/2024 5:27 PM, Daniel P. Berrangé wrote:

On Thu, Feb 29, 2024 at 01:37:10AM -0500, Xiaoyao Li wrote:

From: Isaku Yamahata 

Add property "quote-generation-socket" to tdx-guest, which is a property
of type SocketAddress to specify Quote Generation Service(QGS).

On request of GetQuote, it connects to the QGS socket, read request
data from shared guest memory, send the request data to the QGS,
and store the response into shared guest memory, at last notify
TD guest by interrupt.

command line example:
qemu-system-x86_64 \
  -object '{"qom-type":"tdx-guest","id":"tdx0","quote-generation-socket":{"type": "vsock", 
"cid":"1","port":"1234"}}' \


Can you illustrate this with 'unix' sockets, not 'vsock'.


Are you suggesting only updating the commit message to an example of unix
socket? Or you want the code to test with some unix socket QGS?

(It seems the QGS I got for testing, only supports vsock socket. Because at
the time when it got developed, it was supposed to communicate with drivers
inside TD guest directly not via VMM (KVM+QEMU). Anyway, I will talk to
internal folks to see if any plan to support unix socket.)


The QGS provided as part of DCAP supports running with both
UNIX sockets and VSOCK, and I would expect QEMU to be made
to work with this, since its is Intel's OSS reference impl.


After synced with internal folks, yes, the QGS I used does support unix 
socket. I tested it and it worked.


-object 
'{"qom-type":"tdx-guest","id":"tdx","quote-generation-socket":{"type":"unix", 
"path":"/var/run/tdx-qgs/qgs.socket"}}'



Exposing QGS to the guest when we only intend for it to be
used by the host QEMU is needlessly expanding the attack
surface.

With regards,
Daniel





Re: [RFC PATCH v3 3/3] migration: Add fd to FileMigrationArgs

2024-03-15 Thread Daniel P . Berrangé
On Fri, Mar 15, 2024 at 12:20:40AM -0300, Fabiano Rosas wrote:
> The fd: URI has supported migration to a file or socket since before
> QEMU 8.2. In 8.2 we added the file: URI that supported migration to a
> file. So now we have two ways (three if you count exec:>cat) to
> migrate to a file. Fine.
> 
> However,
> 
> In 8.2 we also added the new qmp_migrate API that uses a JSON channel
> list instead of the URI. It added two migration transports SOCKET and
> FILE. It was decided that the new API would classify the fd migration
> as a type of socket migration, neglecting the fact that the fd.c code
> also supported file migrations.
> 
> In 9.0 we're adding support for fd + multifd + mapped-ram, which is
> tied to the file migration. This was implemented in fd.c, which is
> only reachable when the SOCKET address type is used.
> 
> The result of this is that we're asking users of the new API to create   (1)
> something called a "socket" to perform migration to a plain file. And
> creating something called a "file" provides no way of passing in a
> file descriptor. This is confusing.

The 'file:' protocol eventually calls into qemu_open, and this
transparently allows for FD passing using /dev/fdset/NNN syntax
to pass in FDs. 


> diff --git a/qapi/migration.json b/qapi/migration.json
> index aa1b39bce1..37f4b9c6fb 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1656,13 +1656,20 @@
>  #
>  # @filename: The file to receive the migration stream
>  #
> +# @fd: A file descriptor name or number.  File descriptors must be
> +# first added with the 'getfd' command. (since 9.0).
> +#
>  # @offset: The file offset where the migration stream will start
>  #
> +# Since 9.0, all members are optional, but at least one of @filename
> +# or @fd are required.
> +#
>  # Since: 8.2
>  ##
>  { 'struct': 'FileMigrationArgs',
> -  'data': { 'filename': 'str',
> -'offset': 'uint64' } }
> +  'data': { '*filename': 'str',
> +'*fd': 'str',
> +'*offset': 'uint64' } }

Adding 'fd' here is not desirable, because 'filename' is
resolved via qemu_open which allows for FD passing without
introducing any new syntax in interfaces which take filenames.

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




[PATCH v3] block: Use LVM tools for LV block device truncation

2024-03-15 Thread Alexander Ivanov
If a block device is an LVM logical volume we can resize it using
standard LVM tools.

Add a helper to detect if a device is a DM device. In raw_co_truncate()
check if the block device is DM and resize it executing lvresize.

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

diff --git a/block/file-posix.c b/block/file-posix.c
index 35684f7e21..af17a43fe9 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2642,6 +2642,38 @@ raw_regular_truncate(BlockDriverState *bs, int fd, 
int64_t offset,
 return raw_thread_pool_submit(handle_aiocb_truncate, &acb);
 }
 
+static bool device_is_dm(struct stat *st)
+{
+unsigned int maj, maj2;
+char line[32], devname[16];
+bool ret = false;
+FILE *f;
+
+if (!S_ISBLK(st->st_mode)) {
+return false;
+}
+
+f = fopen("/proc/devices", "r");
+if (!f) {
+return false;
+}
+
+maj = major(st->st_rdev);
+
+while (fgets(line, sizeof(line), f)) {
+if (sscanf(line, "%u %15s", &maj2, devname) != 2) {
+continue;
+}
+if (strcmp(devname, "device-mapper") == 0) {
+ret = (maj == maj2);
+break;
+}
+}
+
+fclose(f);
+return ret;
+}
+
 static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
 bool exact, PreallocMode prealloc,
 BdrvRequestFlags flags, Error **errp)
@@ -2670,6 +2702,35 @@ static int coroutine_fn raw_co_truncate(BlockDriverState 
*bs, int64_t offset,
 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
 int64_t cur_length = raw_getlength(bs);
 
+/*
+ * Try to resize an LVM device using LVM tools.
+ */
+if (device_is_dm(&st) && offset > 0) {
+int spawn_flags = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL;
+int status;
+bool success;
+char *err;
+GError *gerr = NULL, *gerr_exit = NULL;
+g_autofree char *size_str = g_strdup_printf("%" PRId64 "B", 
offset);
+const char *cmd[] = {"lvresize", "-f", "-L",
+ size_str, bs->filename, NULL};
+
+success = g_spawn_sync(NULL, (gchar **)cmd, NULL, spawn_flags,
+   NULL, NULL, NULL, &err, &status, &gerr);
+
+if (success && g_spawn_check_exit_status(status, &gerr_exit)) {
+return 0;
+}
+
+if (success) {
+error_setg(errp, "%s: %s", gerr_exit->message, err);
+} else {
+error_setg(errp, "lvresize execution error: %s", 
gerr->message);
+}
+
+return -EINVAL;
+}
+
 if (offset != cur_length && exact) {
 error_setg(errp, "Cannot resize device files");
 return -ENOTSUP;
-- 
2.40.1




Re: [PATCH V4 1/1] target/loongarch: Fixed tlb huge page loading issue

2024-03-15 Thread lixianglai

Hi Richard :


On 3/14/24 20:22, lixianglai wrote:

Hi Richard:

On 3/13/24 15:33, Xianglai Li wrote:

+    if (unlikely((level == 0) || (level > 4))) {
+    return base;
+    }

...
Perhaps it would be worthwhile to add another for the level==0 or > 
4 case above?



A normal level 4 page table should not print an error log,

only if a level 4 page is large, so we should put it in

 if (FIELD_EX64(base, TLBENTRY, HUGE)) {
 if (unlikely(level == 4)) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "Attempted use of level %lu huge page\n", 
level);

 }

 if (FIELD_EX64(base, TLBENTRY, LEVEL)) {
 return base;
 } else {
 return  FIELD_DP64(base, TLBENTRY, LEVEL, level);
 }
 }


A level 5 page table is not normal, nor is a level 0 lddir.



We communicate with the hardware guys that the behavior above level 4 
and lddir 0 is undefined behavior.


The result of our test on 3A5000 is that it has no any effect on "base",

however in future chips the behavior may change since it may support 
5-level page table and width for level[13:14] may change also.



So in this context,I am not sure which level to use to print logs,

which content to print, and where to add these prints,

any more detailed advice?


Thanks!

Xianglai.





r~





Re: [PATCH v3] block: Use LVM tools for LV block device truncation

2024-03-15 Thread Daniel P . Berrangé
On Fri, Mar 15, 2024 at 09:58:38AM +0100, Alexander Ivanov wrote:
> If a block device is an LVM logical volume we can resize it using
> standard LVM tools.
> 
> Add a helper to detect if a device is a DM device. In raw_co_truncate()
> check if the block device is DM and resize it executing lvresize.
> 
> Signed-off-by: Alexander Ivanov 
> ---
>  block/file-posix.c | 61 ++
>  1 file changed, 61 insertions(+)

Reviewed-by: Daniel P. Berrangé 


> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 35684f7e21..af17a43fe9 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2642,6 +2642,38 @@ raw_regular_truncate(BlockDriverState *bs, int fd, 
> int64_t offset,
>  return raw_thread_pool_submit(handle_aiocb_truncate, &acb);
>  }
>  
> +static bool device_is_dm(struct stat *st)
> +{
> +unsigned int maj, maj2;
> +char line[32], devname[16];
> +bool ret = false;
> +FILE *f;
> +
> +if (!S_ISBLK(st->st_mode)) {
> +return false;
> +}
> +
> +f = fopen("/proc/devices", "r");
> +if (!f) {
> +return false;
> +}
> +
> +maj = major(st->st_rdev);
> +
> +while (fgets(line, sizeof(line), f)) {
> +if (sscanf(line, "%u %15s", &maj2, devname) != 2) {
> +continue;
> +}
> +if (strcmp(devname, "device-mapper") == 0) {
> +ret = (maj == maj2);
> +break;
> +}
> +}
> +
> +fclose(f);
> +return ret;
> +}
> +
>  static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
>  bool exact, PreallocMode prealloc,
>  BdrvRequestFlags flags, Error **errp)
> @@ -2670,6 +2702,35 @@ static int coroutine_fn 
> raw_co_truncate(BlockDriverState *bs, int64_t offset,
>  if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
>  int64_t cur_length = raw_getlength(bs);
>  
> +/*
> + * Try to resize an LVM device using LVM tools.
> + */
> +if (device_is_dm(&st) && offset > 0) {
> +int spawn_flags = G_SPAWN_SEARCH_PATH | 
> G_SPAWN_STDOUT_TO_DEV_NULL;
> +int status;
> +bool success;
> +char *err;
> +GError *gerr = NULL, *gerr_exit = NULL;
> +g_autofree char *size_str = g_strdup_printf("%" PRId64 "B", 
> offset);
> +const char *cmd[] = {"lvresize", "-f", "-L",
> + size_str, bs->filename, NULL};
> +
> +success = g_spawn_sync(NULL, (gchar **)cmd, NULL, spawn_flags,
> +   NULL, NULL, NULL, &err, &status, &gerr);
> +
> +if (success && g_spawn_check_exit_status(status, &gerr_exit)) {
> +return 0;
> +}
> +
> +if (success) {
> +error_setg(errp, "%s: %s", gerr_exit->message, err);
> +} else {
> +error_setg(errp, "lvresize execution error: %s", 
> gerr->message);
> +}
> +
> +return -EINVAL;
> +}
> +
>  if (offset != cur_length && exact) {
>  error_setg(errp, "Cannot resize device files");
>  return -ENOTSUP;
> -- 
> 2.40.1
> 
> 

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




Re: [PATCH v2 1/6] virtio/virtio-pci: Handle extra notification data

2024-03-15 Thread Eugenio Perez Martin
On Thu, Mar 14, 2024 at 9:24 PM Jonah Palmer  wrote:
>
>
>
> On 3/14/24 3:05 PM, Eugenio Perez Martin wrote:
> > On Thu, Mar 14, 2024 at 5:06 PM Jonah Palmer  
> > wrote:
> >>
> >>
> >>
> >> On 3/14/24 10:55 AM, Eugenio Perez Martin wrote:
> >>> On Thu, Mar 14, 2024 at 1:16 PM Jonah Palmer  
> >>> wrote:
> 
> 
> 
>  On 3/13/24 11:01 PM, Jason Wang wrote:
> > On Wed, Mar 13, 2024 at 7:55 PM Jonah Palmer  
> > wrote:
> >>
> >> Add support to virtio-pci devices for handling the extra data sent
> >> from the driver to the device when the VIRTIO_F_NOTIFICATION_DATA
> >> transport feature has been negotiated.
> >>
> >> The extra data that's passed to the virtio-pci device when this
> >> feature is enabled varies depending on the device's virtqueue
> >> layout.
> >>
> >> In a split virtqueue layout, this data includes:
> >> - upper 16 bits: shadow_avail_idx
> >> - lower 16 bits: virtqueue index
> >>
> >> In a packed virtqueue layout, this data includes:
> >> - upper 16 bits: 1-bit wrap counter & 15-bit shadow_avail_idx
> >> - lower 16 bits: virtqueue index
> >>
> >> Tested-by: Lei Yang 
> >> Reviewed-by: Eugenio Pérez 
> >> Signed-off-by: Jonah Palmer 
> >> ---
> >> hw/virtio/virtio-pci.c | 10 +++---
> >> hw/virtio/virtio.c | 18 ++
> >> include/hw/virtio/virtio.h |  1 +
> >> 3 files changed, 26 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> >> index cb6940fc0e..0f5c3c3b2f 100644
> >> --- a/hw/virtio/virtio-pci.c
> >> +++ b/hw/virtio/virtio-pci.c
> >> @@ -384,7 +384,7 @@ static void virtio_ioport_write(void *opaque, 
> >> uint32_t addr, uint32_t val)
> >> {
> >> VirtIOPCIProxy *proxy = opaque;
> >> VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
> >> -uint16_t vector;
> >> +uint16_t vector, vq_idx;
> >> hwaddr pa;
> >>
> >> switch (addr) {
> >> @@ -408,8 +408,12 @@ static void virtio_ioport_write(void *opaque, 
> >> uint32_t addr, uint32_t val)
> >> vdev->queue_sel = val;
> >> break;
> >> case VIRTIO_PCI_QUEUE_NOTIFY:
> >> -if (val < VIRTIO_QUEUE_MAX) {
> >> -virtio_queue_notify(vdev, val);
> >> +vq_idx = val;
> >> +if (vq_idx < VIRTIO_QUEUE_MAX) {
> >> +if (virtio_vdev_has_feature(vdev, 
> >> VIRTIO_F_NOTIFICATION_DATA)) {
> >> +virtio_queue_set_shadow_avail_data(vdev, val);
> >> +}
> >> +virtio_queue_notify(vdev, vq_idx);
> >> }
> >> break;
> >> case VIRTIO_PCI_STATUS:
> >> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> >> index d229755eae..bcb9e09df0 100644
> >> --- a/hw/virtio/virtio.c
> >> +++ b/hw/virtio/virtio.c
> >> @@ -2255,6 +2255,24 @@ void virtio_queue_set_align(VirtIODevice *vdev, 
> >> int n, int align)
> >> }
> >> }
> >>
> >> +void virtio_queue_set_shadow_avail_data(VirtIODevice *vdev, uint32_t 
> >> data)
> >>>
> >>> Maybe I didn't explain well, but I think it is better to pass directly
> >>> idx to a VirtQueue *. That way only the caller needs to check for a
> >>> valid vq idx, and (my understanding is) the virtio.c interface is
> >>> migrating to VirtQueue * use anyway.
> >>>
> >>
> >> Oh, are you saying to just pass in a VirtQueue *vq instead of
> >> VirtIODevice *vdev and get rid of the vq->vring.desc check in the function?
> >>
> >
> > No, that needs to be kept. I meant the access to vdev->vq[i] without
> > checking for a valid i.
> >
>
> Ahh okay I see what you mean. But I thought the following was checking
> for a valid VQ index:
>
> if (vq_idx < VIRTIO_QUEUE_MAX)
>

Right, but then the (potentially multiple) callers are responsible to
check for that. If we accept a VirtQueue *, it is assumed it is valid
already.

> Of course the virtio device may not have up to VIRTIO_QUEUE_MAX
> virtqueues, so maybe we should be checking for validity like this?
>
> if (vdev->vq[i].vring.num == 0)
>

Actually yes, if you're going to send a new version I think checking
against num is better. Good find!

> Or was there something else you had in mind? Apologies for the confusion.
>

No worries, virtio.c is full of checks like that :).

Thanks!

> > You can get the VirtQueue in the caller with virtio_get_queue. Which
> > also does not check for a valid index, but that way is clearer the
> > caller needs to check it.
> >
>
> Roger, I'll use this instead for clarity.
>
> > As a side note, the check for desc != 0 is widespread in QEMU but the
> > driver may use 0 address for desc, so it's not 100% valid. But to
> > change that now requires a deeper change out of the scope of this
>

RE: [PATCH 1/2] qom/object_interfaces: Remove unnecessary local_err check

2024-03-15 Thread Duan, Zhenzhong



>-Original Message-
>From: Liu, Zhao1 
>Subject: Re: [PATCH 1/2] qom/object_interfaces: Remove unnecessary
>local_err check
>
>On Thu, Feb 29, 2024 at 11:37:38AM +0800, Zhenzhong Duan wrote:
>> Date: Thu, 29 Feb 2024 11:37:38 +0800
>> From: Zhenzhong Duan 
>> Subject: [PATCH 1/2] qom/object_interfaces: Remove unnecessary
>local_err
>>  check
>> X-Mailer: git-send-email 2.34.1
>>
>> In the error return path, local_err is always set, no need to check it.
>
>The original error handling code indicates "local_err is always set",
>and error_propagate() can handle the case that local_err is NULL.

Will do.

>
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  qom/object_interfaces.c | 10 --
>>  1 file changed, 4 insertions(+), 6 deletions(-)
>>
>> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
>> index e0833c8bfe..255a7bf659 100644
>> --- a/qom/object_interfaces.c
>> +++ b/qom/object_interfaces.c
>> @@ -128,13 +128,11 @@ Object *user_creatable_add_type(const char
>*type, const char *id,
>>  }
>>  goto out;
>>  }
>> -out:
>> -if (local_err) {
>> -error_propagate(errp, local_err);
>> -object_unref(obj);
>> -return NULL;
>> -}
>>  return obj;
>> +out:
>
>Maybe rename this to "err:"? Since now it's just used to handle error,
>and "goto err" seems more clear.

Good suggestion, will do.

Thanks
Zhenzhong

>
>> +error_propagate(errp, local_err);
>> +object_unref(obj);
>> +return NULL;
>>  }
>>
>>  void user_creatable_add_qapi(ObjectOptions *options, Error **errp)
>> --
>> 2.34.1
>>
>
>Otherwise,
>
>Reviewed-by: Zhao Liu 
>




RE: [PATCH 2/2] qom/object_interfaces: Remove local_err in user_creatable_add_type

2024-03-15 Thread Duan, Zhenzhong



>-Original Message-
>From: Liu, Zhao1 
>Subject: Re: [PATCH 2/2] qom/object_interfaces: Remove local_err in
>user_creatable_add_type
>
>On Thu, Feb 29, 2024 at 11:37:39AM +0800, Zhenzhong Duan wrote:
>> Date: Thu, 29 Feb 2024 11:37:39 +0800
>> From: Zhenzhong Duan 
>> Subject: [PATCH 2/2] qom/object_interfaces: Remove local_err in
>>  user_creatable_add_type
>> X-Mailer: git-send-email 2.34.1
>>
>> In user_creatable_add_type, there is mixed usage of ERRP_GUARD and
>> local_err. This makes error_abort not taking effect in those callee
>> functions with local_err passed.
>>
>> Now that we already has ERRP_GUARD, remove local_err and use *errp
>> instead.
>>
>> Signed-off-by: Zhenzhong Duan 
>> ---
>>  qom/object_interfaces.c | 12 +---
>>  1 file changed, 5 insertions(+), 7 deletions(-)
>>
>> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
>> index 255a7bf659..165cd433e7 100644
>> --- a/qom/object_interfaces.c
>> +++ b/qom/object_interfaces.c
>> @@ -81,7 +81,6 @@ Object *user_creatable_add_type(const char *type,
>const char *id,
>>  ERRP_GUARD();
>>  Object *obj;
>>  ObjectClass *klass;
>> -Error *local_err = NULL;
>>
>>  if (id != NULL && !id_wellformed(id)) {
>>  error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an
>identifier");
>> @@ -109,20 +108,20 @@ Object *user_creatable_add_type(const char
>*type, const char *id,
>>
>>  assert(qdict);
>>  obj = object_new(type);
>> -object_set_properties_from_qdict(obj, qdict, v, &local_err);
>> -if (local_err) {
>> +object_set_properties_from_qdict(obj, qdict, v, errp);
>
>It's better to make object_set_properties_from_qdict someting (e.g.,
>boolean). Maybe an extra cleanup?

OK, will do.

>
>> +if (*errp) {
>>  goto out;
>>  }
>>
>>  if (id != NULL) {
>>  object_property_try_add_child(object_get_objects_root(),
>> -  id, obj, &local_err);
>> -if (local_err) {
>> +  id, obj, errp);
>> +if (*errp) {
>>  goto out;
>>  }
>>  }
>
>Here we could check whether the returned ObjectProperty* is NULL instaed
>of dereferencing errp.

Indeed, that's better, will do.

Thanks
Zhenzhong



Another CXL/MMIO tcg tlb corner case

2024-03-15 Thread Jørgen Hansen
Hi,

While doing some testing using numactl-based interleaving of application memory
across regular memory and CXL-based memory using QEMU with tcg, I ran into an
issue similar to what we saw a while back - link to old issue:
https://lore.kernel.org/qemu-devel/CAFEAcA_a_AyQ=epz3_+cheat8crsk9mou894wbnw_fywamk...@mail.gmail.com/#t.

When running:

numactl --interleave 0,1 ./cachebench …

I hit the following:

numactl --interleave 0,1 ./cachebench --json_test_config 
../test_configs/hit_ratio/graph_cache_follower_assocs/config.json
qemu: fatal: cpu_io_recompile: could not find TB for pc=0x7fffc3926dd4
RAX=7f65df55ba18 RBX=7f65df55ba60 RCX=7f65df221620 
RDX=
RSI=011c0260 RDI=7f65df55ba60 RBP=7ffdb4b4b280 
RSP=7ffdb4b4b1d0
R8 =011c02c0 R9 =7f65debf6b20 R10=011bf5d0 
R11=7f65deb7d300
R12=7ffdb4b4b260 R13=7ffdb4b4b200 R14=7ffdb4b4b220 
R15=011bf5a0
RIP=7f65df18affc RFL=0246 [---Z-P-] CPL=3 II=0 A20=1 SMM=0 HLT=0
ES =   
CS =0033   00affb00 DPL=3 CS64 [-RA]
SS =002b   00cff300 DPL=3 DS   [-WA]
DS =   
FS = 7f65de2f64c0  
GS =   
LDT=   8200 DPL=0 LDT
TR =0040 fe6c3799 4087 8900 DPL=0 TSS64-avl
GDT= fe6c3798e000 007f
IDT= fe00 0fff
CR0=80050033 CR2=7f65df1b3eb0 CR3=000152a1e000 CR4=00350ef0
DR0= DR1= DR2= 
DR3=
DR6=0ff0 DR7=0400
CCS= CCD=0001 CCO=CLR
EFER=0d01
FCW=037f FSW= [ST=0] FTW=00 MXCSR=1f80
FPR0=  FPR1= 
FPR2=  FPR3= 
FPR4=  FPR5= 
FPR6=  FPR7= 
YMM00=  7f65df2233e0 7f65df221620
YMM01=   43e0
YMM02=   
YMM03=   
YMM04=   3ff0
YMM05=   7f65df2233e0
YMM06=   7f65df2233b0
YMM07=  62694c6568636143 2f65636170736b72
YMM08=  6d622070656d7320 327876612031696d
YMM09=  0004 0004
YMM10=  0002 0002
YMM11=  0010 0010
YMM12=  00ff00fb 00fe00fa
YMM13=   00ff00fd00fb00f9
YMM14=   
YMM15=   

The backtrace is (using Jonathans cxl-2024-03-05 branch):

(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737297516096) 
at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737297516096) at 
./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737297516096, signo=signo@entry=6) at 
./nptl/pthread_kill.c:89
#3  0x77642476 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/posix/raise.c:26
#4  0x776287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x55c5a9df in cpu_abort (cpu=cpu@entry=0x578c19c0, 
fmt=fmt@entry=0x5605d100 "cpu_io_recompile: could not find TB for pc=%p") 
at ../cpu-target.c:371
#6  0x55caa065 in cpu_io_recompile (cpu=cpu@entry=0x578c19c0, 
retaddr=140736474541524) at ../accel/tcg/translate-all.c:610
#7  0x55cacee7 in io_prepare (retaddr=140736474541524, 
addr=140075515361944, attrs=..., xlat=, cpu=0x578c19c0, 
out_offset=) at ../accel/tcg/cputlb.c:1336
#8  do_st_mmio_leN (cpu=0x578c19c0, full=0x7ffd1a1554d0, 
val_le=140075515361816, addr=140075515361944, size=8, mmu_idx=3, 
ra=140736474541524) at ../accel/tcg/cputlb.c:2591
#9  0x55cb179d in do_st_8 (ra=, memop=, 
mmu_idx=, val=140075515361816, p=, cpu=) at ../accel/tcg/cputlb.c:2784
#10 do_st8_mmu (cpu=0x578c19c0, addr=39050, val=140075515361816, oi=6, 
ra=140736474541524) at ../accel/tcg/cputlb.c:2862
#11 0x7fffc3926e15 in code_gen_buffer ()
#12 0x55ca0e5b in cpu_tb_exec (cpu=cpu@entry=0x578c19c0, 
itb=itb@entry=0x7fffc3926cc0 , 
tb_exit=tb_exit@entry=0x749ff6d8) at ../accel/tcg/cpu-exec.c:449
#13 0x55ca13ac in cpu_loop_exec_tb (tb_exit=0x749ff6d8, 
last_tb=, pc=, tb=0x7fffc3926cc0 
, cpu=0x578c19c0) at ../accel/tcg/cpu-exe

Re: [PATCH v3] blockcommit: Reopen base image as RO after abort

2024-03-15 Thread Alexander Ivanov




On 2/28/24 17:48, Vladimir Sementsov-Ogievskiy wrote:

On 09.02.24 15:29, Alexander Ivanov wrote:

Could you please review the patch?


Sorry for long delay.

Honestly, I don't like refcnt in block-driver. It violate 
incapsulation, refcnt is interal thing of common block layer. And 
actually, you can't make any assumptions from value of refcnt, as you 
don't know which additional parents were created and why, and when 
they are going unref their children.
Hmmm... Maybe I can just exclude refcnt check from the condition, can't 
I. If BDS will be removed it doesn't matter if we make it RO. What do 
you think?


What was wrong with v2?

My bad, it seems, I didn't send v2 before I decided to change the patch.




On 1/30/24 10:14, Alexander Ivanov wrote:
If a blockcommit is aborted the base image remains in RW mode, that 
leads

to a fail of subsequent live migration.

How to reproduce:
   $ virsh snapshot-create-as vm snp1 --disk-only

   *** write something to the disk inside the guest ***

   $ virsh blockcommit vm vda --active --shallow && virsh blockjob 
vm vda --abort

   $ lsof /vzt/vm.qcow2
   COMMAND  PID USER   FD   TYPE DEVICE   SIZE/OFF NODE NAME
   qemu-syst 433203 root   45u   REG  253,0 1724776448  133 
/vzt/vm.qcow2

   $ cat /proc/433203/fdinfo/45
   pos:    0
   flags:  02140002 < The last 2 means RW mode

If the base image is in RW mode at the end of blockcommit and was in RO
mode before blockcommit, check if src BDS has refcnt > 1. If so, the 
BDS
will not be removed after blockcommit, and we should make the base 
image

RO. Otherwise check recursively if there is a parent BDS of src BDS and
reopen the base BDS in RO in this case.

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

diff --git a/block/mirror.c b/block/mirror.c
index 5145eb53e1..52a7fee75e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -93,6 +93,7 @@ typedef struct MirrorBlockJob {
  int64_t active_write_bytes_in_flight;
  bool prepared;
  bool in_drain;
+    bool base_ro;
  } MirrorBlockJob;
  typedef struct MirrorBDSOpaque {
@@ -652,6 +653,32 @@ static void coroutine_fn 
mirror_wait_for_all_io(MirrorBlockJob *s)

  }
  }
+/*
+ * Check recursively if there is a parent BDS referenced more than
+ * min_refcnt times. This argument is needed because at the first
+ * call there is a bds referenced in blockcommit.
+ */
+static bool bdrv_chain_has_significant_parent(BlockDriverState *bs)
+{
+    BdrvChild *parent;
+    BlockDriverState *parent_bs;
+
+    QLIST_FOREACH(parent, &bs->parents, next) {
+    if (!(parent->klass->parent_is_bds)) {
+    continue;
+    }
+    parent_bs = parent->opaque;
+    if (parent_bs->drv && !parent_bs->drv->is_filter) {
+    return true;
+    }
+    if (bdrv_chain_has_significant_parent(parent_bs)) {
+    return true;
+    }
+    }
+
+    return false;
+}
+
  /**
   * mirror_exit_common: handle both abort() and prepare() cases.
   * for .prepare, returns 0 on success and -errno on failure.
@@ -793,6 +820,11 @@ static int mirror_exit_common(Job *job)
  bdrv_drained_end(target_bs);
  bdrv_unref(target_bs);
+    if (s->base_ro && !bdrv_is_read_only(target_bs) &&
+    (src->refcnt > 1 || bdrv_chain_has_significant_parent(src))) {
+    bdrv_reopen_set_read_only(target_bs, true, NULL);
+    }
+
  bs_opaque->job = NULL;
  bdrv_drained_end(src);
@@ -1715,6 +1747,7 @@ static BlockJob *mirror_start_job(
   bool is_none_mode, BlockDriverState 
*base,
   bool auto_complete, const char 
*filter_node_name,
   bool is_mirror, MirrorCopyMode 
copy_mode,

+ bool base_ro,
   Error **errp)
  {
  MirrorBlockJob *s;
@@ -1798,6 +1831,7 @@ static BlockJob *mirror_start_job(
  bdrv_unref(mirror_top_bs);
  s->mirror_top_bs = mirror_top_bs;
+    s->base_ro = base_ro;
  /* No resize for the target either; while the mirror is still 
running, a
   * consistent read isn't necessarily possible. We could 
possibly allow
@@ -2027,7 +2061,7 @@ void mirror_start(const char *job_id, 
BlockDriverState *bs,
   speed, granularity, buf_size, backing_mode, 
zero_target,
   on_source_error, on_target_error, unmap, 
NULL, NULL,

   &mirror_job_driver, is_none_mode, base, false,
- filter_node_name, true, copy_mode, errp);
+ filter_node_name, true, copy_mode, false, errp);
  }
  BlockJob *commit_active_start(const char *job_id, BlockDriverState 
*bs,
@@ -2056,7 +2090,7 @@ BlockJob *commit_active_start(const char 
*job_id, BlockDriverState *bs,

   on_error, on_error, true, cb, opaque,
   &commit_active_job_driver, false, base, 
auto_complete,
   

Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()

2024-03-15 Thread Cédric Le Goater

On 3/12/24 19:28, Fabiano Rosas wrote:

Peter Xu  writes:


On Tue, Mar 12, 2024 at 11:24:39AM -0300, Fabiano Rosas wrote:

Cédric Le Goater  writes:


On 3/12/24 14:34, Cédric Le Goater wrote:

On 3/12/24 13:32, Cédric Le Goater wrote:

On 3/11/24 20:03, Fabiano Rosas wrote:

Cédric Le Goater  writes:


On 3/8/24 15:36, Fabiano Rosas wrote:

Cédric Le Goater  writes:


This prepares ground for the changes coming next which add an Error**
argument to the .save_setup() handler. Callers of qemu_savevm_state_setup()
now handle the error and fail earlier setting the migration state from
MIGRATION_STATUS_SETUP to MIGRATION_STATUS_FAILED.

In qemu_savevm_state(), move the cleanup to preserve the error
reported by .save_setup() handlers.

Since the previous behavior was to ignore errors at this step of
migration, this change should be examined closely to check that
cleanups are still correctly done.

Signed-off-by: Cédric Le Goater 
---

    Changes in v4:
    - Merged cleanup change in qemu_savevm_state()
    Changes in v3:
    - Set migration state to MIGRATION_STATUS_FAILED
    - Fixed error handling to be done under lock in bg_migration_thread()
    - Made sure an error is always set in case of failure in
  qemu_savevm_state_setup()
    migration/savevm.h    |  2 +-
    migration/migration.c | 27 ---
    migration/savevm.c    | 26 +++---
    3 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/migration/savevm.h b/migration/savevm.h
index 
74669733dd63a080b765866c703234a5c4939223..9ec96a995c93a42aad621595f0ed58596c532328
 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -32,7 +32,7 @@
    bool qemu_savevm_state_blocked(Error **errp);
    void qemu_savevm_non_migratable_list(strList **reasons);
    int qemu_savevm_state_prepare(Error **errp);
-void qemu_savevm_state_setup(QEMUFile *f);
+int qemu_savevm_state_setup(QEMUFile *f, Error **errp);
    bool qemu_savevm_state_guest_unplug_pending(void);
    int qemu_savevm_state_resume_prepare(MigrationState *s);
    void qemu_savevm_state_header(QEMUFile *f);
diff --git a/migration/migration.c b/migration/migration.c
index 
a49fcd53ee19df1ce0182bc99d7e064968f0317b..6d1544224e96f5edfe56939a9c8395d88ef29581
 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3408,6 +3408,8 @@ static void *migration_thread(void *opaque)
    int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
    MigThrError thr_error;
    bool urgent = false;
+    Error *local_err = NULL;
+    int ret;
    thread = migration_threads_add("live_migration", qemu_get_thread_id());
@@ -3451,9 +3453,17 @@ static void *migration_thread(void *opaque)
    }
    bql_lock();
-    qemu_savevm_state_setup(s->to_dst_file);
+    ret = qemu_savevm_state_setup(s->to_dst_file, &local_err);
    bql_unlock();
+    if (ret) {
+    migrate_set_error(s, local_err);
+    error_free(local_err);
+    migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
+  MIGRATION_STATUS_FAILED);
+    goto out;
+ }
+
    qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
   MIGRATION_STATUS_ACTIVE);


This^ should be before the new block it seems:

GOOD:
migrate_set_state new state setup
migrate_set_state new state wait-unplug
migrate_fd_cancel
migrate_set_state new state cancelling
migrate_fd_cleanup
migrate_set_state new state cancelled
migrate_fd_cancel
ok 1 /x86_64/failover-virtio-net/migrate/abort/wait-unplug

BAD:
migrate_set_state new state setup
migrate_fd_cancel
migrate_set_state new state cancelling
migrate_fd_cleanup
migrate_set_state new state cancelled
qemu-system-x86_64: ram_save_setup failed: Input/output error
**
ERROR:../tests/qtest/virtio-net-failover.c:1203:test_migrate_abort_wait_unplug:
assertion failed (status == "cancelling"): ("cancelled" == "cancelling")

Otherwise migration_iteration_finish() will schedule the cleanup BH and
that will run concurrently with migrate_fd_cancel() issued by the test
and bad things happens.


This hack makes things work :

@@ -3452,6 +3452,9 @@ static void *migration_thread(void *opaq
    qemu_savevm_send_colo_enable(s->to_dst_file);
    }
+    qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
+    MIGRATION_STATUS_SETUP);
+


Why move it all the way up here? Has moving the wait_unplug before the
'if (ret)' block not worked for you?


We could be sleeping while holding the BQL. It looked wrong.


Sorry wrong answer. Yes I can try moving it before the 'if (ret)' block.
I can reproduce easily with an x86 guest running on PPC64.


That works just the same.

Peter, Fabiano,

What would you prefer  ?

1. move qemu_savevm_wait_unplug() before qemu_savevm_state_setup(),
 means one new patch.


Is there a point to this except "because we can"? Honest question, I
might have missed the motivation.


My previous point was, it avoids holding the resources (that wil

Re: [PATCH v2 2/2] hmat acpi: Fix out of bounds access due to missing use of indirection

2024-03-15 Thread Jonathan Cameron via
On Wed, 13 Mar 2024 21:24:06 +0300
Michael Tokarev  wrote:

> 07.03.2024 19:03, Jonathan Cameron via wrote:
> > With a numa set up such as
> > 
> > -numa nodeid=0,cpus=0 \
> > -numa nodeid=1,memdev=mem \
> > -numa nodeid=2,cpus=1
> > 
> > and appropriate hmat_lb entries the initiator list is correctly
> > computed and writen to HMAT as 0,2 but then the LB data is accessed
> > using the node id (here 2), landing outside the entry_list array.
> > 
> > Stash the reverse lookup when writing the initiator list and use
> > it to get the correct array index index.
> > 
> > Fixes: 4586a2cb83 ("hmat acpi: Build System Locality Latency and Bandwidth 
> > Information Structure(s)")
> > Signed-off-by: Jonathan Cameron   
> 
> This seems like a -stable material, is it not?

Yes. Use case is obscure, but indeed seems suitable for stable.
Thanks.

Jonathan

> 
> Thanks,
> 
> /mjt
> 
> > ---
> >   hw/acpi/hmat.c | 6 +-
> >   1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
> > index 723ae28d32..b933ae3c06 100644
> > --- a/hw/acpi/hmat.c
> > +++ b/hw/acpi/hmat.c
> > @@ -78,6 +78,7 @@ static void build_hmat_lb(GArray *table_data, 
> > HMAT_LB_Info *hmat_lb,
> > uint32_t *initiator_list)
> >   {
> >   int i, index;
> > +uint32_t initiator_to_index[MAX_NODES] = {};
> >   HMAT_LB_Data *lb_data;
> >   uint16_t *entry_list;
> >   uint32_t base;
> > @@ -121,6 +122,8 @@ static void build_hmat_lb(GArray *table_data, 
> > HMAT_LB_Info *hmat_lb,
> >   /* Initiator Proximity Domain List */
> >   for (i = 0; i < num_initiator; i++) {
> >   build_append_int_noprefix(table_data, initiator_list[i], 4);
> > +/* Reverse mapping for array possitions */
> > +initiator_to_index[initiator_list[i]] = i;
> >   }
> >   
> >   /* Target Proximity Domain List */
> > @@ -132,7 +135,8 @@ static void build_hmat_lb(GArray *table_data, 
> > HMAT_LB_Info *hmat_lb,
> >   entry_list = g_new0(uint16_t, num_initiator * num_target);
> >   for (i = 0; i < hmat_lb->list->len; i++) {
> >   lb_data = &g_array_index(hmat_lb->list, HMAT_LB_Data, i);
> > -index = lb_data->initiator * num_target + lb_data->target;
> > +index = initiator_to_index[lb_data->initiator] * num_target +
> > +lb_data->target;
> >   
> >   entry_list[index] = (uint16_t)(lb_data->data / hmat_lb->base);
> >   }  
> 




Re: [PATCH v9 0/7] QEMU CXL Provide mock CXL events and irq support

2024-03-15 Thread Jonathan Cameron via
On Fri, 15 Mar 2024 09:52:28 +0800
Yuquan Wang  wrote:

> Hello, Jonathan
> 
> When during the test of qmps of CXL events like 
> "cxl-inject-general-media-event", 
> I am confuesd about the argument "flags". According to "qapi/cxl.json" in 
> qemu, 
> this argument represents "Event Record Flags" in Common Event Record Format.
> However, it seems like the specific 'Event Record Severity' in this field can 
> be
> different from the value of 'Event Status' in "Event Status Register". 
> 
> For instance (take an injection example in the coverlatter):
> 
> { "execute": "cxl-inject-general-media-event",
> "arguments": {
> "path": "/machine/peripheral/cxl-mem0",
> "log": "informational",
> "flags": 1,
> "dpa": 1000,
> "descriptor": 3,
> "type": 3,
> "transaction-type": 192,
> "channel": 3,
> "device": 5,
> "component-id": "iras mem"
> }}
> 
> In my understanding, the 'Event Status' is informational and the 
> 'Event Record Severity' is Warning event, which means these two arguments are
> independent of each other. Is my understanding correct?

The event status registers dictates the notification path (which log).
So I think that's "informational" here.

Whereas flags is about the specific error. One case where they might be
different is where the Related Event Record Handle is set.
An error might be reported as
1) Several things that were non fatal (each with their own record)
2) In combination they result in a fatal situation (also has it's own record).

The QEMU injection shouldn't restrict these combinations more than the spec
does (which is not at all!).

This same disconnect in error severity is seen in UEFI CPER records for example
where there is a containing record with one severity field, but more specific
parts of record can have lower (or in theory higher) severity.

Jonathan


> 
> Many thanks
> Yuquan
> 




[PATCH 0/1] cxl/mem: Fix for the index of Clear Event Record Handle

2024-03-15 Thread Yuquan Wang
This is a simple fix for the index of 'Clear Event Record' Handle. The
print content of dev_dbg from Clear Event Records mailbox command would
report the handle of the next record to clear not the current one.
The problem was found when I was doing the debug of CXL Event Error on
Qemu. I injected an individual event through QMP 
'cxl-inject-general-media-event':
{ "execute": "cxl-inject-general-media-event",
"arguments": {
"path": "/machine/peripheral/cxl-mem0",
"log": "informational",
"flags": 1,
"dpa": 1000,
"descriptor": 3,
"type": 3,
"transaction-type": 192,
"channel": 3,
"device": 5,
"component-id": "iras mem"
}}

Then the kernel printed: 
[ 1639.106181] cxl_pci :0d:00.0: Event log '0': Clearing 0

However, the line 36 in 'hw/cxl/cxl-events.c': log->next_handle = 1;
It will set the actual handle value of injected event to '1'.

With this fix, the kernel will print:
[  122.456750] cxl_pci :0d:00.0: Event log '0': Clearing 1
which is in line with the simulated value in Qemu.

Yuquan Wang (1):
  cxl/mem: Fix for the index of Clear Event Record Handle

 drivers/cxl/core/mbox.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

-- 
2.34.1




[PATCH 1/1] cxl/mem: Fix for the index of Clear Event Record Handle

2024-03-15 Thread Yuquan Wang
The dev_dbg info for Clear Event Records mailbox command would report
the handle of the next record to clear not the current one.

This was because the index 'i' had incremented before printing the
current handle value.

This fix also adjusts the index variable name from 'i' to 'clear_cnt'
which can be easier for developers to distinguish and understand.

Signed-off-by: Yuquan Wang 
---
 drivers/cxl/core/mbox.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 9adda4795eb7..3ca2845ae6aa 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -881,7 +881,7 @@ static int cxl_clear_event_record(struct cxl_memdev_state 
*mds,
struct cxl_mbox_cmd mbox_cmd;
u16 cnt;
int rc = 0;
-   int i;
+   int clear_cnt;
 
/* Payload size may limit the max handles */
if (pl_size > mds->payload_size) {
@@ -908,28 +908,29 @@ static int cxl_clear_event_record(struct cxl_memdev_state 
*mds,
 * Clear Event Records uses u8 for the handle cnt while Get Event
 * Record can return up to 0x records.
 */
-   i = 0;
+   clear_cnt = 0;
for (cnt = 0; cnt < total; cnt++) {
struct cxl_event_record_raw *raw = &get_pl->records[cnt];
struct cxl_event_generic *gen = &raw->event.generic;
 
-   payload->handles[i++] = gen->hdr.handle;
+   payload->handles[clear_cnt] = gen->hdr.handle;
dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log,
-   le16_to_cpu(payload->handles[i]));
+   le16_to_cpu(payload->handles[clear_cnt]));
 
-   if (i == max_handles) {
-   payload->nr_recs = i;
+   clear_cnt++;
+   if (clear_cnt == max_handles) {
+   payload->nr_recs = clear_cnt;
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
if (rc)
goto free_pl;
-   i = 0;
+   clear_cnt = 0;
}
}
 
/* Clear what is left if any */
-   if (i) {
-   payload->nr_recs = i;
-   mbox_cmd.size_in = struct_size(payload, handles, i);
+   if (clear_cnt) {
+   payload->nr_recs = clear_cnt;
+   mbox_cmd.size_in = struct_size(payload, handles, clear_cnt);
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
if (rc)
goto free_pl;
-- 
2.34.1




Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()

2024-03-15 Thread Peter Xu
On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote:
> > migrate_set_state is also unintuitive because it ignores invalid state
> > transitions and we've been using that property to deal with special
> > states such as POSTCOPY_PAUSED and FAILED:
> > 
> > - After the migration goes into POSTCOPY_PAUSED, the resumed migration's
> >migrate_init() will try to set the state NONE->SETUP, which is not
> >valid.
> > 
> > - After save_setup fails, the migration goes into FAILED, but wait_unplug
> >will try to transition SETUP->ACTIVE, which is also not valid.
> > 
> 
> I am not sure I understand what the plan is. Both solutions are problematic
> regarding the state transitions.
> 
> Should we consider that waiting for failover devices to unplug is an internal
> step of the SETUP phase not transitioning to ACTIVE ?

If to unblock this series, IIUC the simplest solution is to do what Fabiano
suggested, that we move qemu_savevm_wait_unplug() to be before the check of
setup() ret.  In that case, the state change in qemu_savevm_wait_unplug()
should be benign and we should see a super small window it became ACTIVE
but then it should be FAILED (and IIUC the patch itself will need to use
ACTIVE as "old_state", not SETUP anymore).

For the long term, maybe we can remove the WAIT_UNPLUG state?  The only
Libvirt support seems to be here:

commit 8a226ddb3602586a2ba2359afc4448c02f566a0e
Author: Laine Stump 
Date:   Wed Jan 15 16:38:57 2020 -0500

qemu: add wait-unplug to qemu migration status enum

Considering that qemu_savevm_wait_unplug() can be a noop if the device is
already unplugged, I think it means no upper layer app should rely on this
state to present.

Thanks,

-- 
Peter Xu




Re: Any interest in the QEMU community attending DVCon Europe October 2024?

2024-03-15 Thread Alex Bennée
Alex Bennée  writes:

> Hi,
>
> Over recent years there has been a push to make QEMU more flexible for
> EDA type applications. As long time developers know there are a number
> of downstream forks of QEMU which have their own solutions for modelling
> heterogeneous systems and integrating with hardware models. The work by
> Philippe, Anton and others to build a single binary with composable
> hardware is aiming at least to solve the heterogeneous modelling problem
> in the upstream project.
>
> While we do discuss these "TCG" topics during KVM Forum the project may
> benefit from doing some outreach at some conferences where simulation
> and emulation are the primary focus.
>
> The Design and Verification Conference & Exhibition Europe (DVCon
> Europe) is the premier European technical conference on system,
> software, design, verification, validation and integration. This year it
> will be on the 15-16 October 2024 in Munich. See: https://dvcon-europe.org/
>
> There have been a number of papers and workshops on QEMU/KVM topics over
> the years. Unfortunately the website doesn't provide slides or videos of
> the talks but topics have included how QEMU can be used as a fast
> instruction simulator alongside things such as SystemC models or
> virtualisation can be leveraged to accelerate full system emulation.
>
> The main tracks are fairly academic where engineering and research
> papers are submitted and if accepted can then be presented at the
> conference. This is probably over the top for QEMU related stuff but
> their is a tutorial track (deadline for Abstracts 1st July) which could
> be a good target for a introduction to the features and capabilities of
> the QEMU upstream. I suspect there would be interest in the wider
> modelling community to find out more about how to use the upstream
> project directly.
>
> There is a co-located "SystemC Evolution Day" on the 17th where there
> might well be a strong overlap between SystemC users and QEMU. Mark
> Burton is involved with that and is keen for proposals talking about
> integrating SystemC models with QEMU. Please send a message to
> mbur...@quicinc.com if you're interested.
>
> So is anyone interested?
>
> Should we do more within the community to network and discuss our plans
> for QEMU as a modelling solution?
>
> Any other thoughts?

Gentle ping, any interest?

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH 5/9] tests/qemu-iotests: Restrict test 134 and 158 to the 'file' protocol

2024-03-15 Thread Thomas Huth
Commit b25b387fa592 updated the iotests 134 and 158 to use the --image-opts
parameter for qemu-io with file protocol related options, but forgot to
update the _supported_proto line accordingly. So let's do that now.

Fixes: b25b387fa5 ("qcow2: convert QCow2 to use QCryptoBlock for encryption")
Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/134 | 2 +-
 tests/qemu-iotests/158 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
index ded153c0b9..b2c3c03f08 100755
--- a/tests/qemu-iotests/134
+++ b/tests/qemu-iotests/134
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow qcow2
-_supported_proto generic
+_supported_proto file
 
 
 size=128M
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
index a95878e4ce..3a9ad7eed0 100755
--- a/tests/qemu-iotests/158
+++ b/tests/qemu-iotests/158
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow qcow2
-_supported_proto generic
+_supported_proto file
 
 
 size=128M
-- 
2.44.0




[PATCH 9/9] tests/qemu-iotests: Restrict tests using "--blockdev file" to the file protocol

2024-03-15 Thread Thomas Huth
Tests that use "--blockdev" with the "file" driver cannot work with
other protocols, so we should mark them accordingly.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/tests/qcow2-internal-snapshots | 2 +-
 tests/qemu-iotests/tests/qsd-jobs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/tests/qcow2-internal-snapshots 
b/tests/qemu-iotests/tests/qcow2-internal-snapshots
index 36523aba06..9f83aa8903 100755
--- a/tests/qemu-iotests/tests/qcow2-internal-snapshots
+++ b/tests/qemu-iotests/tests/qcow2-internal-snapshots
@@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # This tests qcow2-specific low-level functionality
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 # Internal snapshots are (currently) impossible with refcount_bits=1,
 # and generally impossible with external data files
 _unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
diff --git a/tests/qemu-iotests/tests/qsd-jobs 
b/tests/qemu-iotests/tests/qsd-jobs
index 510bf0a9dc..9b843af631 100755
--- a/tests/qemu-iotests/tests/qsd-jobs
+++ b/tests/qemu-iotests/tests/qsd-jobs
@@ -40,7 +40,7 @@ cd ..
 . ./common.filter
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 
 size=128M
 
-- 
2.44.0




[PATCH 4/9] tests/qemu-iotests: Restrict test 130 to the 'file' protocol

2024-03-15 Thread Thomas Huth
Using "-drive ...,backing.file.filename=..." only works with the
file protocol, but not with URIs, so mark this test accordingly.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/130 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index 7257f09677..7af85d20a8 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -42,7 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.qemu
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 _supported_os Linux
 # We are going to use lazy-refcounts
 _unsupported_imgopts 'compat=0.10'
-- 
2.44.0




[PATCH 8/9] tests/qemu-iotests: Fix some tests that use --image-opts for other protocols

2024-03-15 Thread Thomas Huth
Tests 263, 284 and detect-zeroes-registered-buf use qemu-io
with --image-opts so we have to enforce IMGOPTSSYNTAX=true here
to get $TEST_IMG in shape for other protocols than "file".

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/263| 6 --
 tests/qemu-iotests/284| 7 +++
 tests/qemu-iotests/tests/detect-zeroes-registered-buf | 4 +++-
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/tests/qemu-iotests/263 b/tests/qemu-iotests/263
index ec09b41405..44fdada0d6 100755
--- a/tests/qemu-iotests/263
+++ b/tests/qemu-iotests/263
@@ -34,6 +34,8 @@ _cleanup()
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
+IMGOPTSSYNTAX=true
+
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
@@ -73,7 +75,7 @@ echo "testing LUKS qcow2 encryption"
 echo
 
 _make_test_img --object $SECRET -o 
"encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=64K"
 $size
-_run_test "driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG"
+_run_test "$TEST_IMG,encrypt.key-secret=sec0"
 _cleanup_test_img
 
 echo
@@ -82,7 +84,7 @@ echo
 
 
 _make_test_img --object $SECRET -o 
"encrypt.format=aes,encrypt.key-secret=sec0,cluster_size=64K" $size
-_run_test "driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG"
+_run_test "$TEST_IMG,encrypt.key-secret=sec0"
 _cleanup_test_img
 
 
diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284
index 5a82639e7f..722267486d 100755
--- a/tests/qemu-iotests/284
+++ b/tests/qemu-iotests/284
@@ -33,6 +33,8 @@ _cleanup()
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
+IMGOPTSSYNTAX=true
+
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
@@ -47,14 +49,12 @@ size=1M
 
 SECRET="secret,id=sec0,data=astrochicken"
 
-IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
 QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
 
 _run_test()
 {
-IMGOPTSSYNTAX=true
 OLD_TEST_IMG="$TEST_IMG"
-
TEST_IMG="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
+TEST_IMG="$TEST_IMG,encrypt.key-secret=sec0"
 QEMU_IMG_EXTRA_ARGS="--image-opts --object $SECRET"
 
 echo
@@ -78,7 +78,6 @@ _run_test()
 
 TEST_IMG="$OLD_TEST_IMG"
 QEMU_IMG_EXTRA_ARGS=
-IMGOPTSSYNTAX=
 }
 
 
diff --git a/tests/qemu-iotests/tests/detect-zeroes-registered-buf 
b/tests/qemu-iotests/tests/detect-zeroes-registered-buf
index edb5f2cee5..5eaf34e5a6 100755
--- a/tests/qemu-iotests/tests/detect-zeroes-registered-buf
+++ b/tests/qemu-iotests/tests/detect-zeroes-registered-buf
@@ -36,6 +36,8 @@ _cleanup()
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
+IMGOPTSSYNTAX=true
+
 # get standard environment, filters and checks
 cd ..
 . ./common.rc
@@ -46,7 +48,7 @@ _supported_proto generic
 
 size=128M
 _make_test_img $size
-IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,discard=unmap,detect-zeroes=unmap"
+IMGSPEC="$TEST_IMG,discard=unmap,detect-zeroes=unmap"
 
 echo
 echo "== writing zero buffer to image =="
-- 
2.44.0




[PATCH 1/9] tests/qemu-iotests: Fix test 033 for running with non-file protocols

2024-03-15 Thread Thomas Huth
When running iotest 033 with the ssh protocol, it fails with:

 033   fail   [14:48:31] [14:48:41]   10.2soutput mismatch
 --- /.../tests/qemu-iotests/033.out
 +++ /.../tests/qemu-iotests/scratch/qcow2-ssh-033/033.out.bad
 @@ -174,6 +174,7 @@
  512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
  wrote 512/512 bytes at offset 2097152
  512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 +qemu-io: warning: Failed to truncate the tail of the image: ssh driver does 
not support shrinking files
  read 512/512 bytes at offset 0
  512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

We already check for the qcow2 format here, so let's simply also
add a check for the protocol here, too, to only test the truncation
with the file protocol.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/033 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
index da9133c44b..4bc7a071bd 100755
--- a/tests/qemu-iotests/033
+++ b/tests/qemu-iotests/033
@@ -123,9 +123,9 @@ do_test 512 "write -P 1 0 0x200" "$TEST_IMG" | 
_filter_qemu_io
 # next L2 table
 do_test 512 "write -P 1 $L2_COVERAGE 0x200" "$TEST_IMG" | _filter_qemu_io
 
-# only interested in qcow2 here; also other formats might respond with
-#  "not supported" error message
-if [ $IMGFMT = "qcow2" ]; then
+# only interested in qcow2 with file protocol here; also other formats
+# might respond with "not supported" error message
+if [ $IMGFMT = "qcow2" ] && [ $IMGPROTO = "file" ]; then
 do_test 512 "truncate $L2_COVERAGE" "$TEST_IMG" | _filter_qemu_io
 fi
 
-- 
2.44.0




[PATCH 3/9] tests/qemu-iotests: Restrict test 114 to the 'file' protocol

2024-03-15 Thread Thomas Huth
iotest 114 uses "truncate" and the qcow2.py script on the destination file,
which both cannot deal with URIs. Thus this test needs the "file" protocol,
otherwise it fails with an error message like this:

 truncate: cannot open 
'ssh://127.0.0.1/tmp/qemu-build/tests/qemu-iotests/scratch/qcow2-ssh-114/t.qcow2.orig'
  for writing: No such file or directory

Thus mark this test for "file protocol only" accordingly.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/114 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
index de6fd327ee..dccc71008b 100755
--- a/tests/qemu-iotests/114
+++ b/tests/qemu-iotests/114
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 # At least OpenBSD doesn't seem to have truncate
 _supported_os Linux
 # qcow2.py does not work too well with external data files
-- 
2.44.0




[PATCH 6/9] tests/qemu-iotests: Restrict test 156 to the 'file' protocol

2024-03-15 Thread Thomas Huth
The test fails completely when you try to use it with a different
protocol, e.g. with "./check -ssh -qcow2 156".
The test uses some hand-crafted JSON statements which cannot work with other
protocols, thus let's change this test to only support the 'file' protocol.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/156 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index a9540bd80d..97c2d86ce5 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -50,7 +50,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.qemu
 
 _supported_fmt qcow2 qed
-_supported_proto generic
+_supported_proto file
 # Copying files around with cp does not work with external data files
 _unsupported_imgopts data_file
 
-- 
2.44.0




Re: [PATCH v2 7/7] qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper

2024-03-15 Thread Andrey Drobyshev
On 3/5/24 20:38, Daniel P. Berrangé wrote:
> On Fri, Mar 01, 2024 at 07:28:58PM +0200, Andrey Drobyshev wrote:
>> There's no need to check for the existence of the "chpasswd", "pw"
>> executables, as the exec() call will do that for us.
>>
>> Signed-off-by: Andrey Drobyshev 
>> ---
>>  qga/commands-posix.c | 96 ++--
>>  1 file changed, 13 insertions(+), 83 deletions(-)
>>
>> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
>> index f3f4a05e2d..f2e9496b80 100644
>> --- a/qga/commands-posix.c
>> +++ b/qga/commands-posix.c
>> @@ -2144,14 +2144,8 @@ void qmp_guest_set_user_password(const char *username,
>>   Error **errp)
>>  {
>>  Error *local_err = NULL;
>> -char *passwd_path = NULL;
>> -pid_t pid;
>> -int status;
>> -int datafd[2] = { -1, -1 };
>> -char *rawpasswddata = NULL;
>> +g_autofree char *rawpasswddata = NULL;
>>  size_t rawpasswdlen;
>> -char *chpasswddata = NULL;
>> -size_t chpasswdlen;
>>
>>  rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, 
>> errp);
>>  if (!rawpasswddata) {
>> @@ -2162,95 +2156,31 @@ void qmp_guest_set_user_password(const char 
>> *username,
>>
>>  if (strchr(rawpasswddata, '\n')) {
>>  error_setg(errp, "forbidden characters in raw password");
>> -goto out;
>> +return;
>>  }
>>
>>  if (strchr(username, '\n') ||
>>  strchr(username, ':')) {
>>  error_setg(errp, "forbidden characters in username");
>> -goto out;
>> +return;
>>  }
>>
>>  #ifdef __FreeBSD__
>> -chpasswddata = g_strdup(rawpasswddata);
>> -passwd_path = g_find_program_in_path("pw");
>> +g_autofree char *chpasswdata = g_strdup(rawpasswddata);
>> +const char *crypt_flag = (crypted) ? "-H" : "-h";
>> +const char *argv[] = {"pw", "usermod", "-n", username,
>> +  crypt_flag, "0", NULL};
>>  #else
>> -chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata);
>> -passwd_path = g_find_program_in_path("chpasswd");
>> +g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username,
>> +rawpasswddata);
>> +const char *crypt_flag = (crypted) ? "-e" : NULL;
> 
> Style nit-pick - no '(...)' around 'crypted' is needed here, or
> the other place later in this method.
> 
> Yes, that was a pre-existing issue, but since you're refactoring
> the code, might as well kill the redundant brackets.
> 
> [...]

Sure, let's get rid of them. Thanks.




[PATCH 2/9] tests/qemu-iotests: Restrict test 066 to the 'file' protocol

2024-03-15 Thread Thomas Huth
The hand-crafted json statement in this test only works if the test
is run with the "file" protocol, so mark this test accordingly.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/066 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
index cf63144cb9..336d8565dd 100755
--- a/tests/qemu-iotests/066
+++ b/tests/qemu-iotests/066
@@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # This tests qcow2-specific low-level functionality
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 # We need zero clusters and snapshots
 # (TODO: Consider splitting the snapshot part into a separate test
 #file, so this one runs with refcount_bits=1 and data_file)
-- 
2.44.0




[PATCH 7/9] tests/qemu-iotests: Restrict tests that use --image-opts to the 'file' protocol

2024-03-15 Thread Thomas Huth
These tests 188, 189 and 198 use qemu-io with --image-opts with additional
hard-coded parameters for the file protocol, so they cannot work for other
protocols. Thus we have to limit these tests to the file protocol only.

Signed-off-by: Thomas Huth 
---
 tests/qemu-iotests/188 | 2 +-
 tests/qemu-iotests/189 | 2 +-
 tests/qemu-iotests/198 | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188
index ce087d1873..2950b1dc31 100755
--- a/tests/qemu-iotests/188
+++ b/tests/qemu-iotests/188
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 _supported_os Linux
 _require_working_luks
 
diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189
index 801494c6b9..008f73b07d 100755
--- a/tests/qemu-iotests/189
+++ b/tests/qemu-iotests/189
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 _supported_os Linux
 _require_working_luks
 
diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198
index 1c93dea1f7..6ddeffddd2 100755
--- a/tests/qemu-iotests/198
+++ b/tests/qemu-iotests/198
@@ -38,7 +38,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.filter
 
 _supported_fmt qcow2
-_supported_proto generic
+_supported_proto file
 _supported_os Linux
 _require_working_luks
 
-- 
2.44.0




Re: [PATCH v2 2/7] qga: introduce ga_run_command() helper for guest cmd execution

2024-03-15 Thread Andrey Drobyshev
On 3/5/24 19:58, Daniel P. Berrangé wrote:
> On Fri, Mar 01, 2024 at 07:28:53PM +0200, Andrey Drobyshev wrote:
>> When executing guest commands in *nix environment, we repeat the same
>> fork/exec pattern multiple times.  Let's just separate it into a single
>> helper which would also be able to feed input data into the launched
>> process' stdin.  This way we can avoid code duplication.
>>
>> To keep the history more bisectable, let's replace qmp commands
>> implementations one by one.  Also add G_GNUC_UNUSED attribute to the
>> helper and remove it in the next commit.
>>
>> Originally-by: Yuri Pudgorodskiy 
>> Signed-off-by: Andrey Drobyshev 
>> ---
>>  qga/commands-posix.c | 140 +++
>>  1 file changed, 140 insertions(+)
>>
>> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
>> index 8207c4c47e..781498418f 100644
>> --- a/qga/commands-posix.c
>> +++ b/qga/commands-posix.c
>> @@ -76,6 +76,146 @@ static void ga_wait_child(pid_t pid, int *status, Error 
>> **errp)
>>  g_assert(rpid == pid);
>>  }
>>
>> +static void ga_pipe_read_str(int fd[2], char **str, size_t *len)
>> +{
>> +ssize_t n;
>> +char buf[1024];
>> +close(fd[1]);
>> +fd[1] = -1;
>> +while ((n = read(fd[0], buf, sizeof(buf))) != 0) {
>> +if (n < 0) {
>> +if (errno == EINTR) {
>> +continue;
>> +} else {
>> +break;
> 
> This is a fatal error condition
> 
>> +}
>> +}
>> +*str = g_realloc(*str, *len + n);
>> +memcpy(*str + *len, buf, n);
>> +*len += n;
>> +}
>> +close(fd[0]);
>> +fd[0] = -1;
> 
> and yet as far as the caller is concerned we're not indicating
> any sense of failure here. They're just being returned a partially
> read data stream as if it were successful. IMHO this needs to be
> reported properly.
>

Agreed.  We might make this helper return -errno in case of an erroneous
read from pipe, check the value in the caller and do error_setg_errno()
if smth went wrong.

> 
> Nothing in this method has NUL terminated 'str', so we are
> relying on the caller *always* honouring 'len', but.
>

Agreed as well.  Let's allocate +1 additional byte and store '\0' in
there on every iteration, making sure our result is always
null-terminated. That way we won't need to check 'len' in the caller.

>> +}
>> +
>> +/*
>> + * Helper to run command with input/output redirection,
>> + * sending string to stdin and taking error message from
>> + * stdout/err.
>> + */
>> +G_GNUC_UNUSED
>> +static int ga_run_command(const char *argv[], const char *in_str,
>> +  const char *action, Error **errp)
>> +{
>> +pid_t pid;
>> +int status;
>> +int retcode = -1;
>> +int infd[2] = { -1, -1 };
>> +int outfd[2] = { -1, -1 };
>> +char *str = NULL;
>> +size_t len = 0;
>> +
>> +if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) ||
>> +!g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) {
>> +error_setg(errp, "cannot create pipe FDs");
>> +goto out;
>> +}
>> +
>> +pid = fork();
>> +if (pid == 0) {
>> +char *cherr = NULL;
>> +
>> +setsid();
>> +
>> +if (in_str) {
>> +/* Redirect stdin to infd. */
>> +close(infd[1]);
>> +dup2(infd[0], 0);
>> +close(infd[0]);
>> +} else {
>> +reopen_fd_to_null(0);
>> +}
>> +
>> +/* Redirect stdout/stderr to outfd. */
>> +close(outfd[0]);
>> +dup2(outfd[1], 1);
>> +dup2(outfd[1], 2);
>> +close(outfd[1]);
>> +
>> +execvp(argv[0], (char *const *)argv);
>> +
>> +/* Write the cause of failed exec to pipe for the parent to read 
>> it. */
>> +cherr = g_strdup_printf("failed to exec '%s'", argv[0]);
>> +perror(cherr);
>> +g_free(cherr);
>> +_exit(EXIT_FAILURE);
>> +} else if (pid < 0) {
>> +error_setg_errno(errp, errno, "failed to create child process");
>> +goto out;
>> +}
>> +
>> +if (in_str) {
>> +close(infd[0]);
>> +infd[0] = -1;
>> +if (qemu_write_full(infd[1], in_str, strlen(in_str)) !=
>> +strlen(in_str)) {
>> +error_setg_errno(errp, errno, "%s: cannot write to stdin pipe",
>> + action);
>> +goto out;
>> +}
>> +close(infd[1]);
>> +infd[1] = -1;
>> +}
>> +
>> +ga_pipe_read_str(outfd, &str, &len);
>> +
>> +ga_wait_child(pid, &status, errp);
>> +if (*errp) {
>> +goto out;
>> +}
>> +
>> +if (!WIFEXITED(status)) {
>> +if (len) {
>> +error_setg(errp, "child process has terminated abnormally: %s",
>> +   str);
> 
> ...this is reading 'str' without honouring 'len', so is likely
> an array out of bounds read.
> 
>> +} else {
>> +error_setg(errp, "child p

[PATCH 0/9] tests/qemu-iotests: Fix running with "check -ssh -qcow2"

2024-03-15 Thread Thomas Huth
I recently wanted to check for some changes that I did to the URI handling
in the block layer code, but I had to discover that a lot of iotests only
work with the raw file format when using a protocol that is not "file",
i.e. "./check -ssh -qcow2" shows a lot of failures.
While some tests could be fixed to work with the "ssh" protocol, too,
many other tests seem to be written for the "file" protocol only and
thus have to be marked accordingly.

After applying these patches, there is still one failure left in test 181
where I'm unsure whether it's a real bug or whether this test should also
simply be marked to work with the "file" protocol only. Suggestions are
welcome!

Thomas Huth (9):
  tests/qemu-iotests: Fix test 033 for running with non-file protocols
  tests/qemu-iotests: Restrict test 066 to the 'file' protocol
  tests/qemu-iotests: Restrict test 114 to the 'file' protocol
  tests/qemu-iotests: Restrict test 130 to the 'file' protocol
  tests/qemu-iotests: Restrict test 134 and 158 to the 'file' protocol
  tests/qemu-iotests: Restrict test 156 to the 'file' protocol
  tests/qemu-iotests: Restrict tests that use --image-opts to the 'file'
protocol
  tests/qemu-iotests: Fix some tests that use --image-opts for other
protocols
  tests/qemu-iotests: Restrict tests using "--blockdev file" to the file
protocol

 tests/qemu-iotests/033| 6 +++---
 tests/qemu-iotests/066| 2 +-
 tests/qemu-iotests/114| 2 +-
 tests/qemu-iotests/130| 2 +-
 tests/qemu-iotests/134| 2 +-
 tests/qemu-iotests/156| 2 +-
 tests/qemu-iotests/158| 2 +-
 tests/qemu-iotests/188| 2 +-
 tests/qemu-iotests/189| 2 +-
 tests/qemu-iotests/198| 2 +-
 tests/qemu-iotests/263| 6 --
 tests/qemu-iotests/284| 7 +++
 tests/qemu-iotests/tests/detect-zeroes-registered-buf | 4 +++-
 tests/qemu-iotests/tests/qcow2-internal-snapshots | 2 +-
 tests/qemu-iotests/tests/qsd-jobs | 2 +-
 15 files changed, 24 insertions(+), 21 deletions(-)

-- 
2.44.0




Re: [PATCH v4 13/25] memory: Add Error** argument to .log_global_start() handler

2024-03-15 Thread Peter Xu
On Wed, Mar 06, 2024 at 02:34:28PM +0100, Cédric Le Goater wrote:
> diff --git a/system/memory.c b/system/memory.c
> index 
> a229a79988fce2aa3cb77e3a130db4c694e8cd49..3600e716149407c10a1f6bf8f0a81c2611cf15ba
>  100644
> --- a/system/memory.c
> +++ b/system/memory.c
> @@ -2914,9 +2914,27 @@ static unsigned int postponed_stop_flags;
>  static VMChangeStateEntry *vmstate_change;
>  static void memory_global_dirty_log_stop_postponed_run(void);
>  
> +/*
> + * Stop dirty logging on all listeners where it was previously enabled.
> + */
> +static void memory_global_dirty_log_rollback(MemoryListener *listener,
> + unsigned int flags)
> +{
> +global_dirty_tracking &= ~flags;

Having a hook rollback function to touch the global_dirty_tracking flag is
IMHO tricky.

Can we instead provide a helper to call all log_global_start() hooks, but
allow a gracefully fail (so rollback will be called if it fails)?

  bool memory_global_dirty_log_start_hooks(...)

Or any better names..  Leaving global_dirty_tracking rollback to
memory_global_dirty_log_start() when it returns false.

Would this be cleaner?

> +trace_global_dirty_changed(global_dirty_tracking);
> +
> +while (listener) {
> +if (listener->log_global_stop) {
> +listener->log_global_stop(listener);
> +}
> +listener = QTAILQ_PREV(listener, link);
> +}
> +}
> +
>  void memory_global_dirty_log_start(unsigned int flags)
>  {
>  unsigned int old_flags;
> +Error *local_err = NULL;
>  
>  assert(flags && !(flags & (~GLOBAL_DIRTY_MASK)));
>  
> @@ -2936,7 +2954,25 @@ void memory_global_dirty_log_start(unsigned int flags)
>  trace_global_dirty_changed(global_dirty_tracking);
>  
>  if (!old_flags) {
> -MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
> +MemoryListener *listener;
> +bool ret = true;
> +
> +QTAILQ_FOREACH(listener, &memory_listeners, link) {
> +if (listener->log_global_start) {
> +ret = listener->log_global_start(listener, &local_err);
> +if (!ret) {
> +break;
> +}
> +}
> +}
> +
> +if (!ret) {
> +memory_global_dirty_log_rollback(QTAILQ_PREV(listener, link),
> + flags);
> +error_report_err(local_err);
> +return;
> +}
> +
>  memory_region_transaction_begin();
>  memory_region_update_pending = true;
>  memory_region_transaction_commit();
> @@ -3009,13 +3045,16 @@ static void listener_add_address_space(MemoryListener 
> *listener,
>  {
>  FlatView *view;
>  FlatRange *fr;
> +Error *local_err = NULL;
>  
>  if (listener->begin) {
>  listener->begin(listener);
>  }
>  if (global_dirty_tracking) {
>  if (listener->log_global_start) {
> -listener->log_global_start(listener);
> +if (!listener->log_global_start(listener, &local_err)) {
> +error_report_err(local_err);
> +}

IMHO we should assert here instead of error report.  We have this to guard
hot-plug during migration so I think the assert is justified:

qdev_device_add_from_qdict():

if (!migration_is_idle()) {
error_setg(errp, "device_add not allowed while migrating");
return NULL;
}

If it really happens it's a bug, as listener_add_address_space() will still
keep the rest things around even if the hook failed.  It'll start to be a
total mess..

Thanks,

>  }
>  }
>  
> -- 
> 2.44.0
> 

-- 
Peter Xu




Re: [PATCH for 9.0 v15 05/10] target/riscv: always clear vstart for ldst_whole insns

2024-03-15 Thread Max Chou

Reviewed-by: Max Chou 

On 2024/3/15 1:56 AM, Daniel Henrique Barboza wrote:

Commit 8ff8ac6329 added a conditional to guard the vext_ldst_whole()
helper if vstart >= evl. But by skipping the helper we're also not
setting vstart = 0 at the end of the insns, which is incorrect.

We'll move the conditional to vext_ldst_whole(), following in line with
the removal of all brconds vstart >= vl that the next patch will do. The
idea is to make the helpers responsible for their own vstart management.

Fix ldst_whole isns by:

- remove the brcond that skips the helper if vstart is >= evl;

- vext_ldst_whole() now does an early exit with the same check, where
   evl = (vlenb * nf) >> log2_esz, but the early exit will also clear
   vstart.

The 'width' param is now unneeded in ldst_whole_trans() and is also
removed. It was used for the evl calculation for the brcond and has no
other use now.  The 'width' is reflected in vext_ldst_whole() via
log2_esz, which is encoded by GEN_VEXT_LD_WHOLE() as
"ctzl(sizeof(ETYPE))".

Suggested-by: Max Chou 
Fixes: 8ff8ac6329 ("target/riscv: rvv: Add missing early exit condition for whole 
register load/store")
Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/insn_trans/trans_rvv.c.inc | 52 +++--
  target/riscv/vector_helper.c|  5 +++
  2 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 52c26a7834..1366445e1f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1097,13 +1097,9 @@ GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, 
ld_us_check)
  typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32);
  
  static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,

- uint32_t width, gen_helper_ldst_whole *fn,
+ gen_helper_ldst_whole *fn,
   DisasContext *s)
  {
-uint32_t evl = s->cfg_ptr->vlenb * nf / width;
-TCGLabel *over = gen_new_label();
-tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, evl, over);
-
  TCGv_ptr dest;
  TCGv base;
  TCGv_i32 desc;
@@ -1120,8 +1116,6 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, 
uint32_t nf,
  
  fn(dest, base, tcg_env, desc);
  
-gen_set_label(over);

-
  return true;
  }
  
@@ -1129,42 +1123,42 @@ static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,

   * load and store whole register instructions ignore vtype and vl setting.
   * Thus, we don't need to check vill bit. (Section 7.9)
   */
-#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF, WIDTH)   \
+#define GEN_LDST_WHOLE_TRANS(NAME, ARG_NF)\
  static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \
  { \
  if (require_rvv(s) && \
  QEMU_IS_ALIGNED(a->rd, ARG_NF)) { \
-return ldst_whole_trans(a->rd, a->rs1, ARG_NF, WIDTH, \
+return ldst_whole_trans(a->rd, a->rs1, ARG_NF,\
  gen_helper_##NAME, s);\
  } \
  return false; \
  }
  
-GEN_LDST_WHOLE_TRANS(vl1re8_v,  1, 1)

-GEN_LDST_WHOLE_TRANS(vl1re16_v, 1, 2)
-GEN_LDST_WHOLE_TRANS(vl1re32_v, 1, 4)
-GEN_LDST_WHOLE_TRANS(vl1re64_v, 1, 8)
-GEN_LDST_WHOLE_TRANS(vl2re8_v,  2, 1)
-GEN_LDST_WHOLE_TRANS(vl2re16_v, 2, 2)
-GEN_LDST_WHOLE_TRANS(vl2re32_v, 2, 4)
-GEN_LDST_WHOLE_TRANS(vl2re64_v, 2, 8)
-GEN_LDST_WHOLE_TRANS(vl4re8_v,  4, 1)
-GEN_LDST_WHOLE_TRANS(vl4re16_v, 4, 2)
-GEN_LDST_WHOLE_TRANS(vl4re32_v, 4, 4)
-GEN_LDST_WHOLE_TRANS(vl4re64_v, 4, 8)
-GEN_LDST_WHOLE_TRANS(vl8re8_v,  8, 1)
-GEN_LDST_WHOLE_TRANS(vl8re16_v, 8, 2)
-GEN_LDST_WHOLE_TRANS(vl8re32_v, 8, 4)
-GEN_LDST_WHOLE_TRANS(vl8re64_v, 8, 8)
+GEN_LDST_WHOLE_TRANS(vl1re8_v,  1)
+GEN_LDST_WHOLE_TRANS(vl1re16_v, 1)
+GEN_LDST_WHOLE_TRANS(vl1re32_v, 1)
+GEN_LDST_WHOLE_TRANS(vl1re64_v, 1)
+GEN_LDST_WHOLE_TRANS(vl2re8_v,  2)
+GEN_LDST_WHOLE_TRANS(vl2re16_v, 2)
+GEN_LDST_WHOLE_TRANS(vl2re32_v, 2)
+GEN_LDST_WHOLE_TRANS(vl2re64_v, 2)
+GEN_LDST_WHOLE_TRANS(vl4re8_v,  4)
+GEN_LDST_WHOLE_TRANS(vl4re16_v, 4)
+GEN_LDST_WHOLE_TRANS(vl4re32_v, 4)
+GEN_LDST_WHOLE_TRANS(vl4re64_v, 4)
+GEN_LDST_WHOLE_TRANS(vl8re8_v,  8)
+GEN_LDST_WHOLE_TRANS(vl8re16_v, 8)
+GEN_LDST_WHOLE_TRANS(vl8re32_v, 8)
+GEN_LDST_WHOLE_TRANS(vl8re64_v, 8)
  
  /*

   * The vector whole register store instructions are encoded similar to
   * unmasked unit-stride store of elements with EEW=8.
   */
-GEN_LDST_WHOLE_TRANS(vs1r_v, 1, 1)
-GEN_LDST_WHOLE_TRANS(vs2r_v, 2, 1)
-GEN_LDST_WHOLE_TRANS(vs4r_v, 4, 1)
-GEN_LDST_WHOLE_TRANS(vs8r_v, 8, 1)
+GEN_

Re: Intention to work on GSoC project

2024-03-15 Thread Eugenio Perez Martin
On Fri, Mar 15, 2024 at 8:15 AM Sahil  wrote:
>
> Hi,
>
> Thank you for your email.
>
> On Thursday, March 14, 2024 8:39:45 PM IST Eugenio Perez Martin wrote:
> > Hi Sahil,
> >
> > It's being hard to find a good self-contained small task related to
> > the project to be honest. As it would be out of SVQ, would it be ok
> > for you if we start straight to the task of adding the packed vq
> > format to SVQ?
> >
> > Thanks!
>
> Sure, this works too! I would love to get started with the project.
>
> I have a small update as well. I have read through a few docs and
> articles to familiarize myself with the relevant terminology and
> technicalities.
>
> 1. "About", "system emulation" and "user mode emulation" sections of
> the user documentation [1]
> 2. The migration subsystem [2]
>
> Some sections in the above docs were difficult to grasp. For the time
> being, I have focused on those parts that I thought were relevant
> to the project.
>

Please feel free to ask any questions, maybe we can improve the doc :).

> I have also read through the following articles:
>
> 1. Introduction to virtio-networking and vhost-net [3]
> 2. Deep dive into Virtio-networking and vhost-net [4]
> 3. Virtualized Hardware Devices [5]
> 4. VFIO - "Virtual Function I/O" (Just the introduction) [6]
> 5. Virtio-net failover: An introduction [7]
>
> I hope I haven't gone off on a tangent. I was planning to finish reading
> up on the following articles as well:
>

There is a post before the first in the series:
https://www.redhat.com/en/blog/virtio-devices-and-drivers-overview-headjack-and-phone

> 1. Virtqueues and virtio ring: How the data travels [8]
> 2. Packed virtqueue: How to reduce overhead with virtio [9]
> 3. Virtio live migration technical deep dive [10]
> 4. Hands on vDPA: what do you do when you ain't got the hardware v2 (Part 1) 
> [11]
>

I think it's a good plan!

If you feel like you're reading a lot of theory and want to get your
hands dirty already, you can also start messing with the code with the
blogs you already read. Or, maybe, after reading the Packed virtqueue
one, your call.

In a very brute-forced description, you can start trying to copy all
the *packed* stuff of kernel's drivers/virtio/virtio_ring.c into
vhost_shadow_virtqueue.c. There is a lot more in the task, and I can
get into more detail if you want either here or in a meeting.

If you prefer to continue with the theory it is ok too.

> I believe the hands-on vPDA article will have me set up a development
> environment for the project as well.
>

Yes, that's right.

> Please let me know if I should amend my roadmap. I am
> excited to get started :)
>

I think it is a great plan!

Thanks!

> Thanks,
> Sahil
>
> [1] https://www.qemu.org/docs/master/index.html
> [2] https://www.qemu.org/docs/master/devel/migration/index.html
> [3] 
> https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net
> [4] https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net
> [5] 
> https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/virtualization_getting_started_guide/sec-virtualization_getting_started-products-virtualized-hardware-devices
> [6] https://www.kernel.org/doc/html/latest/driver-api/vfio.html
> [7] https://www.redhat.com/en/blog/virtio-net-failover-introduction
> [8] https://www.redhat.com/en/blog/virtqueues-and-virtio-ring-how-data-travels
> [9] 
> https://developers.redhat.com/articles/2024/02/21/virtio-live-migration-technical-deep-dive
> [10] 
> https://www.redhat.com/en/blog/packed-virtqueue-how-reduce-overhead-virtio
> [11] 
> https://www.redhat.com/en/blog/hands-vdpa-what-do-you-do-when-you-aint-got-hardware-part-1
>
>




Re: [PATCH v4 14/25] memory: Add Error** argument to the global_dirty_log routines

2024-03-15 Thread Peter Xu
On Wed, Mar 06, 2024 at 02:34:29PM +0100, Cédric Le Goater wrote:
> Now that the log_global*() handlers take an Error** parameter and
> return a bool, do the same for memory_global_dirty_log_start() and
> memory_global_dirty_log_stop(). The error is reported in the callers
> for now and it will be propagated in the call stack in the next
> changes.
> 
> To be noted a functional change in ram_init_bitmaps(), if the dirty
> pages logger fails to start, there is no need to synchronize the dirty
> pages bitmaps. colo_incoming_start_dirty_log() could be modified in a
> similar way.
> 
> Cc: Stefano Stabellini 
> Cc: Anthony Perard 
> Cc: Paul Durrant 
> Cc: "Michael S. Tsirkin" 
> Cc: Paolo Bonzini 
> Cc: David Hildenbrand 
> Cc: Hyman Huang 
> Reviewed-by: Hyman Huang 
> Signed-off-by: Cédric Le Goater 
> ---
> 
>  Changes in v4:
> 
>  - Dropped log_global_stop() and log_global_sync() changes
>  
>  include/exec/memory.h |  5 -
>  hw/i386/xen/xen-hvm.c |  2 +-
>  migration/dirtyrate.c | 13 +++--
>  migration/ram.c   | 22 --
>  system/memory.c   | 11 +--
>  5 files changed, 41 insertions(+), 12 deletions(-)
> 
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 
> 567bc4c9fdb53e8f63487f1400980275687d..c129ee6db7162504bd72d4cfc69b5affb2cd87e8
>  100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -2570,8 +2570,11 @@ void memory_listener_unregister(MemoryListener 
> *listener);
>   * memory_global_dirty_log_start: begin dirty logging for all regions
>   *
>   * @flags: purpose of starting dirty log, migration or dirty rate
> + * @errp: pointer to Error*, to store an error if it happens.
> + *
> + * Return: true on success, else false setting @errp with error.
>   */
> -void memory_global_dirty_log_start(unsigned int flags);
> +bool memory_global_dirty_log_start(unsigned int flags, Error **errp);
>  
>  /**
>   * memory_global_dirty_log_stop: end dirty logging for all regions
> diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
> index 
> 0608ca99f5166fd6379ee674442484e805eff9c0..57cb7df50788a6c31eff68c95e8eaa856fdebede
>  100644
> --- a/hw/i386/xen/xen-hvm.c
> +++ b/hw/i386/xen/xen-hvm.c
> @@ -654,7 +654,7 @@ void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t 
> length)
>  void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
>  {
>  if (enable) {
> -memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION);
> +memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION, errp);
>  } else {
>  memory_global_dirty_log_stop(GLOBAL_DIRTY_MIGRATION);
>  }
> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
> index 
> 1d2e85746fb7b10eb7f149976970f9a92125af8a..d02d70b7b4b86a29d4d5540ded416543536d8f98
>  100644
> --- a/migration/dirtyrate.c
> +++ b/migration/dirtyrate.c
> @@ -90,9 +90,15 @@ static int64_t do_calculate_dirtyrate(DirtyPageRecord 
> dirty_pages,
>  
>  void global_dirty_log_change(unsigned int flag, bool start)
>  {
> +Error *local_err = NULL;
> +bool ret;
> +
>  bql_lock();
>  if (start) {
> -memory_global_dirty_log_start(flag);
> +ret = memory_global_dirty_log_start(flag, &local_err);
> +if (!ret) {
> +error_report_err(local_err);
> +}
>  } else {
>  memory_global_dirty_log_stop(flag);
>  }
> @@ -608,9 +614,12 @@ static void calculate_dirtyrate_dirty_bitmap(struct 
> DirtyRateConfig config)
>  {
>  int64_t start_time;
>  DirtyPageRecord dirty_pages;
> +Error *local_err = NULL;
>  
>  bql_lock();
> -memory_global_dirty_log_start(GLOBAL_DIRTY_DIRTY_RATE);
> +if (!memory_global_dirty_log_start(GLOBAL_DIRTY_DIRTY_RATE, &local_err)) 
> {
> +error_report_err(local_err);
> +}
>  
>  /*
>   * 1'round of log sync may return all 1 bits with
> diff --git a/migration/ram.c b/migration/ram.c
> index 
> c5149b7d717aefad7f590422af0ea4a40e7507be..397b4c0f218a66d194e44f9c5f9fe8e9885c48b6
>  100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -2836,18 +2836,31 @@ static void 
> migration_bitmap_clear_discarded_pages(RAMState *rs)
>  
>  static void ram_init_bitmaps(RAMState *rs)
>  {
> +Error *local_err = NULL;
> +bool ret = true;
> +
>  qemu_mutex_lock_ramlist();
>  
>  WITH_RCU_READ_LOCK_GUARD() {
>  ram_list_init_bitmaps();
>  /* We don't use dirty log with background snapshots */
>  if (!migrate_background_snapshot()) {
> -memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION);
> +ret = memory_global_dirty_log_start(GLOBAL_DIRTY_MIGRATION,
> +&local_err);
> +if (!ret) {
> +error_report_err(local_err);
> +goto out_unlock;

Here we may need to free the bitmaps created in ram_list_init_bitmaps().

We can have a helper ram_bitmaps_destroy() for that.

One thing be careful is the new file_bmap can be cre

Re: [PATCH v3 1/3] migration/multifd: Ensure we're not given a socket for file migration

2024-03-15 Thread Peter Xu
On Fri, Mar 15, 2024 at 12:20:38AM -0300, Fabiano Rosas wrote:
> When doing migration using the fd: URI, QEMU will fetch the file
> descriptor passed in via the monitor at
> fd_start_outgoing|incoming_migration(), which means the checks at
> migration_channels_and_transport_compatible() happen too soon and we
> don't know at that point whether the FD refers to a plain file or a
> socket.
> 
> For this reason, we've been allowing a migration channel of type
> SOCKET_ADDRESS_TYPE_FD to pass the initial verifications in scenarios
> where the socket migration is not supported, such as with fd + multifd.
> 
> The commit decdc76772 ("migration/multifd: Add mapped-ram support to
> fd: URI") was supposed to add a second check prior to starting
> migration to make sure a socket fd is not passed instead of a file fd,
> but failed to do so.
> 
> Add the missing verification and update the comment explaining this
> situation which is currently incorrect.
> 
> Fixes: decdc76772 ("migration/multifd: Add mapped-ram support to fd: URI")
> Signed-off-by: Fabiano Rosas 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v3 2/3] migration/multifd: Duplicate the fd for the outgoing_args

2024-03-15 Thread Peter Xu
On Fri, Mar 15, 2024 at 12:20:39AM -0300, Fabiano Rosas wrote:
> We currently store the file descriptor used during the main outgoing
> channel creation to use it again when creating the multifd
> channels.
> 
> Since this fd is used for the first iochannel, there's risk that the
> QIOChannel gets freed and the fd closed while outgoing_args.fd still
> has it available. This could lead to an fd-reuse bug.
> 
> Duplicate the outgoing_args fd to avoid this issue.
> 
> Suggested-by: Peter Xu 
> Signed-off-by: Fabiano Rosas 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v2 6/7] qga/commands-posix: use ga_run_command helper when suspending via sysfs

2024-03-15 Thread Andrey Drobyshev
On 3/5/24 20:34, Daniel P. Berrangé wrote:
> [Вы нечасто получаете письма от berra...@redhat.com. Узнайте, почему это 
> важно, по адресу https://aka.ms/LearnAboutSenderIdentification ]
> 
> On Fri, Mar 01, 2024 at 07:28:57PM +0200, Andrey Drobyshev wrote:
>> We replace the direct call to open() with a "sh -c 'echo ...'" call, so
>> that it becomes an executable command.
> 
> Introduced an indirection via the shell is a significant step
> backwards IMHO.
> 
>>
>> Signed-off-by: Andrey Drobyshev 
>> ---
>>  qga/commands-posix.c | 36 
>>  1 file changed, 4 insertions(+), 32 deletions(-)
>>
>> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
>> index dd2a7ad2e6..f3f4a05e2d 100644
>> --- a/qga/commands-posix.c
>> +++ b/qga/commands-posix.c
>> @@ -1921,49 +1921,21 @@ static void linux_sys_state_suspend(SuspendMode 
>> mode, Error **errp)
>>  Error *local_err = NULL;
>>  const char *sysfile_strs[3] = {"disk", "mem", NULL};
>>  const char *sysfile_str = sysfile_strs[mode];
>> -pid_t pid;
>> -int status;
>>
>>  if (!sysfile_str) {
>>  error_setg(errp, "unknown guest suspend mode");
>>  return;
>>  }
>>
>> -pid = fork();
>> -if (!pid) {
>> -/* child */
>> -int fd;
>> -
>> -setsid();
>> -reopen_fd_to_null(0);
>> -reopen_fd_to_null(1);
>> -reopen_fd_to_null(2);
>> -
>> -fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
>> -if (fd < 0) {
>> -_exit(EXIT_FAILURE);
>> -}
>> -
>> -if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
>> -_exit(EXIT_FAILURE);
>> -}
>> -
>> -_exit(EXIT_SUCCESS);
> 
> 
> This pre-existing code is strange to me.  Why do we need to fork a
> new process in order to write to /sys/power/state ?
> 
> Looking at the original commit
> 
>   commit 11d0f1255bd5651f628280dc96c4ce9d63ae9236
>   Author: Luiz Capitulino 
>   Date:   Tue Feb 28 11:03:03 2012 -0300
> 
> qemu-ga: add guest-suspend-disk
> 
> 
> The code made a little more sense, as after fork() it first
> tried to execve  'pm-utils', and then had the sysfs codepath
> as a fallback. IOW having the sysfs code after fork() was a
> much easier code structure.
> 
> This was all changed in
> 
>   commit 246d76eba1944d7e59affb288ec27d7fcfb5d256
>   Author: Daniel Henrique Barboza 
>   Date:   Thu Jun 21 07:21:50 2018 -0300
> 
> qga: guest_suspend: decoupling pm-utils and sys logic
> 
> 
> so the pm-utils logic runs in a separate forked child
> from the sysfs logic.
> 
> AFAICT, that should have made it completely redundant to
> fork a process to access /sys/power/state.
> 
> Does anyone know of a reason to keep the fork() here ? Of
> not we should just be calling 'g_file_set_contents' without
> fork
> 

In the original commit message Luiz Capitulino explained that multiple
forks are needed to properly reap child processes needed for execl().
AFAIU since writing to /sys/power/state doesn't require execl(), fork()
isn't needed either.  I think the 2nd commit you mention simply kept
things as they were since it wasn't the original goal of the patch.  So
we're just looking at legacy code.

I agree that in this case my original patch is redundant and we may
replace it with smth like g_file_set_contents().  I'll add it in v3.

>> -} else if (pid < 0) {
>> -error_setg_errno(errp, errno, "failed to create child process");
>> -return;
>> -}
>> +g_autofree char *echo_cmd = g_strdup_printf(
>> +"echo %s > " LINUX_SYS_STATE_FILE, sysfile_str);
>> +const char *argv[] = {"sh", "-c", echo_cmd, NULL};
>>
>> -ga_wait_child(pid, &status, &local_err);
>> +ga_run_command(argv, NULL, "suspend", &local_err);
>>  if (local_err) {
>>  error_propagate(errp, local_err);
>>  return;
>>  }
>> -
>> -if (WEXITSTATUS(status)) {
>> -error_setg(errp, "child process has failed to suspend");
>> -}
>> -
>>  }
>>
>>  static void guest_suspend(SuspendMode mode, Error **errp)
>> --
>> 2.39.3
>>
>>
> 
> With regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
> 




Re: [RFC PATCH v3 3/3] migration: Add fd to FileMigrationArgs

2024-03-15 Thread Fabiano Rosas
Daniel P. Berrangé  writes:

> On Fri, Mar 15, 2024 at 12:20:40AM -0300, Fabiano Rosas wrote:
>> The fd: URI has supported migration to a file or socket since before
>> QEMU 8.2. In 8.2 we added the file: URI that supported migration to a
>> file. So now we have two ways (three if you count exec:>cat) to
>> migrate to a file. Fine.
>> 
>> However,
>> 
>> In 8.2 we also added the new qmp_migrate API that uses a JSON channel
>> list instead of the URI. It added two migration transports SOCKET and
>> FILE. It was decided that the new API would classify the fd migration
>> as a type of socket migration, neglecting the fact that the fd.c code
>> also supported file migrations.
>> 
>> In 9.0 we're adding support for fd + multifd + mapped-ram, which is
>> tied to the file migration. This was implemented in fd.c, which is
>> only reachable when the SOCKET address type is used.
>> 
>> The result of this is that we're asking users of the new API to create   (1)
>> something called a "socket" to perform migration to a plain file. And
>> creating something called a "file" provides no way of passing in a
>> file descriptor. This is confusing.
>
> The 'file:' protocol eventually calls into qemu_open, and this
> transparently allows for FD passing using /dev/fdset/NNN syntax
> to pass in FDs. 
>

Ok, that's technically correct. But it works differently from
fd:fdname.

/dev/fdset requires the user to switch from getfd to add-fd and it
requires QEMU and libvirt/user to synchronize on the open() flags being
used. QEMU cannot just receive any fd, it must be an fd that matches the
flags QEMU passed into qio_channel_file_new_path().

Users will have to adapt to the new API anyway, so it might be ok to
require these changes around it as well.

To keep compatibility, we'd continue to accept the fd that comes from
"fd:" or SOCKET_ADDRESS_TYPE_FD. But we'd be making it harder for users
of the fd: syntax to move to the new API.

I also don't know how we would deal with fdset when (if) we add support
for passing in more channels in the new API. It supports multiple fds,
but how do we deal with something like:

"[ { 'channel-type': 'main',"
"'addr': { 'transport': 'file',"
"  'filename': '/dev/fdset/1' } },
"  { 'channel-type': 'second',"
"'addr': { 'transport': 'file',"
"  'filename': '/dev/fdset/2' } } ]",

Maybe that's too far ahead for this discussion.

>> diff --git a/qapi/migration.json b/qapi/migration.json
>> index aa1b39bce1..37f4b9c6fb 100644
>> --- a/qapi/migration.json
>> +++ b/qapi/migration.json
>> @@ -1656,13 +1656,20 @@
>>  #
>>  # @filename: The file to receive the migration stream
>>  #
>> +# @fd: A file descriptor name or number.  File descriptors must be
>> +# first added with the 'getfd' command. (since 9.0).
>> +#
>>  # @offset: The file offset where the migration stream will start
>>  #
>> +# Since 9.0, all members are optional, but at least one of @filename
>> +# or @fd are required.
>> +#
>>  # Since: 8.2
>>  ##
>>  { 'struct': 'FileMigrationArgs',
>> -  'data': { 'filename': 'str',
>> -'offset': 'uint64' } }
>> +  'data': { '*filename': 'str',
>> +'*fd': 'str',
>> +'*offset': 'uint64' } }
>
> Adding 'fd' here is not desirable, because 'filename' is
> resolved via qemu_open which allows for FD passing without
> introducing any new syntax in interfaces which take filenames.
>
> With regards,
> Daniel



Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()

2024-03-15 Thread Cédric Le Goater

On 3/15/24 12:01, Peter Xu wrote:

On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote:

migrate_set_state is also unintuitive because it ignores invalid state
transitions and we've been using that property to deal with special
states such as POSTCOPY_PAUSED and FAILED:

- After the migration goes into POSTCOPY_PAUSED, the resumed migration's
migrate_init() will try to set the state NONE->SETUP, which is not
valid.

- After save_setup fails, the migration goes into FAILED, but wait_unplug
will try to transition SETUP->ACTIVE, which is also not valid.



I am not sure I understand what the plan is. Both solutions are problematic
regarding the state transitions.

Should we consider that waiting for failover devices to unplug is an internal
step of the SETUP phase not transitioning to ACTIVE ?


If to unblock this series, IIUC the simplest solution is to do what Fabiano
suggested, that we move qemu_savevm_wait_unplug() to be before the check of
setup() ret. 


The simplest is IMHO moving qemu_savevm_wait_unplug() before
qemu_savevm_state_setup() and leave patch 10 is unchanged. See
below the extra patch. It looks much cleaner than what we have
today.


In that case, the state change in qemu_savevm_wait_unplug()
should be benign and we should see a super small window it became ACTIVE
but then it should be FAILED (and IIUC the patch itself will need to use
ACTIVE as "old_state", not SETUP anymore).


OK. I will give it a try to compare.

For the long term, maybe we can remove the WAIT_UNPLUG state?  


I hope so, it's an internal SETUP state for me.


The only Libvirt support seems to be here:

commit 8a226ddb3602586a2ba2359afc4448c02f566a0e
Author: Laine Stump 
Date:   Wed Jan 15 16:38:57 2020 -0500

 qemu: add wait-unplug to qemu migration status enum

Considering that qemu_savevm_wait_unplug() can be a noop if the device is
already unplugged, I think it means no upper layer app should rely on this
state to present.


Thanks,

C.





@@ -3383,11 +3383,10 @@ bool migration_rate_limit(void)
  * unplugged
  */
 
-static void qemu_savevm_wait_unplug(MigrationState *s, int old_state,

-int new_state)
+static void qemu_savevm_wait_unplug(MigrationState *s, int state)
 {
 if (qemu_savevm_state_guest_unplug_pending()) {
-migrate_set_state(&s->state, old_state, MIGRATION_STATUS_WAIT_UNPLUG);
+migrate_set_state(&s->state, state, MIGRATION_STATUS_WAIT_UNPLUG);
 
 while (s->state == MIGRATION_STATUS_WAIT_UNPLUG &&

qemu_savevm_state_guest_unplug_pending()) {
@@ -3410,9 +3409,7 @@ static void qemu_savevm_wait_unplug(Migr
 }
 }
 
-migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, new_state);

-} else {
-migrate_set_state(&s->state, old_state, new_state);
+migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, state);
 }
 }
 
@@ -3469,17 +3466,19 @@ static void *migration_thread(void *opaq

 qemu_savevm_send_colo_enable(s->to_dst_file);
 }
 
+qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP);

+
 bql_lock();
 qemu_savevm_state_setup(s->to_dst_file);
 bql_unlock();
 
-qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,

-   MIGRATION_STATUS_ACTIVE);
-
 s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
 
 trace_migration_thread_setup_complete();
 
+migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,

+  MIGRATION_STATUS_ACTIVE);
+
 while (migration_is_active()) {
 if (urgent || !migration_rate_exceeded(s->to_dst_file)) {
 MigIterateState iter_state = migration_iteration_run(s);
@@ -3580,18 +3579,20 @@ static void *bg_migration_thread(void *o
 ram_write_tracking_prepare();
 #endif
 
+qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP);

+
 bql_lock();
 qemu_savevm_state_header(s->to_dst_file);
 qemu_savevm_state_setup(s->to_dst_file);
 bql_unlock();
 
-qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,

-   MIGRATION_STATUS_ACTIVE);
-
 s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
 
 trace_migration_thread_setup_complete();
 
+migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,

+  MIGRATION_STATUS_ACTIVE);
+
 bql_lock();
 
 if (migration_stop_vm(s, RUN_STATE_PAUSED)) {





Re: [PATCH 17/18] target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types

2024-03-15 Thread Philippe Mathieu-Daudé

On 13/10/23 06:34, Richard Henderson wrote:

On 10/10/23 02:28, Philippe Mathieu-Daudé wrote:

"target/foo/cpu-qom.h" can not use any target specific definitions.

Currently "target/mips/cpu-qom.h" defines TYPE_MIPS_CPU depending
on the mips(32)/mips64 build type. This doesn't scale in a
heterogeneous context where we need to access both types concurrently.

In order to do that, introduce the new MIPS32_CPU / MIPS64_CPU types,
both inheriting a common TYPE_MIPS_CPU base type.

Keep the current CPU types registered in mips_register_cpudef_type()
as 32 or 64-bit, but instead of depending on the binary built being
targeting 32/64-bit, check whether the CPU is 64-bit by looking at
the CPU_MIPS64 bit.

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/mips/cpu-qom.h | 13 ++---
  target/mips/cpu.h |  3 +++
  target/mips/cpu.c | 11 ++-
  3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h
index 9c98ca1956..1a71509b5e 100644
--- a/target/mips/cpu-qom.h
+++ b/target/mips/cpu-qom.h
@@ -1,5 +1,5 @@
  /*
- * QEMU MIPS CPU
+ * QEMU MIPS CPU QOM header (target agnostic)
   *
   * Copyright (c) 2012 SUSE LINUX Products GmbH
   *
@@ -23,13 +23,12 @@
  #include "hw/core/cpu.h"
  #include "qom/object.h"
-#ifdef TARGET_MIPS64
-#define TYPE_MIPS_CPU "mips64-cpu"
-#else
-#define TYPE_MIPS_CPU "mips-cpu"
-#endif
+#define TYPE_MIPS_CPU   "mips-cpu"
+#define TYPE_MIPS32_CPU "mips32-cpu"
+#define TYPE_MIPS64_CPU "mips64-cpu"
-OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU)
+OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU)
+OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU)
  #define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU
  #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 6b026e6bcf..3b6d0a7a8a 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -10,6 +10,9 @@
  #include "hw/clock.h"
  #include "mips-defs.h"
+/* Abstract QOM MIPS CPU, not exposed to other targets */
+OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU)


Why is this one moved back to cpu.h?
You exposed TYPE_X86_CPU in i386/cpu-qom.h...


First thinking was to expose the base TYPE, so we can use QOM methods
to enumerate implementations, but not expose QOM state/class getter
for the base type (except in target/foo/). HW would use concrete
32 or 64b type state/class getter. I might be wrong, so I'll keep
the base type exposed for now. We might restrict later.



Re: Another CXL/MMIO tcg tlb corner case

2024-03-15 Thread Alex Bennée
Jørgen Hansen  writes:

> Hi,
>
> While doing some testing using numactl-based interleaving of application 
> memory
> across regular memory and CXL-based memory using QEMU with tcg, I ran into an
> issue similar to what we saw a while back - link to old issue:
> https://lore.kernel.org/qemu-devel/CAFEAcA_a_AyQ=epz3_+cheat8crsk9mou894wbnw_fywamk...@mail.gmail.com/#t.
>
> When running:
>
> numactl --interleave 0,1 ./cachebench …
>
> I hit the following:
>
> numactl --interleave 0,1 ./cachebench --json_test_config 
> ../test_configs/hit_ratio/graph_cache_follower_assocs/config.json
> qemu: fatal: cpu_io_recompile: could not find TB for pc=0x7fffc3926dd4

Ok so this will be because we (by design) don't cache TB's for MMIO
regions. But as you say:
>
> Looking at the tb being executed, it looks like it is a single instruction tb,
> so with my _very_ limited understanding of tcg, it shouldn’t be necessary to
> do the IO recompile:
>
> (gdb) up 13
>
> #13 0x55ca13ac in cpu_loop_exec_tb (tb_exit=0x749ff6d8, 
> last_tb=, pc=, tb=0x7fffc3926cc0 
> , cpu=0x578c19c0) at 
> ../accel/tcg/cpu-exec.c:904
> 904 tb = cpu_tb_exec(cpu, tb, tb_exit);
> (gdb) print *tb
> $1 = {pc = 0, cs_base = 0, flags = 415285939, cflags = 4278321152, size = 7, 
> icount = 1, tc = {ptr = 0x7fffc3926d80 , size = 
> 176}, page_next = {0, 0}, page_addr = {18446744073709551615,
> 18446744073709551615}, jmp_lock = {value = 0}, jmp_reset_offset =
> {65535, 65535}, jmp_insn_offset = {65535, 65535}, jmp_target_addr =
> {0, 0}, jmp_list_head = 140736474540928, jmp_list_next = {0, 0},
> jmp_dest = {0, 0}}

with an icount of 1 we by definition can do io. This is done in the
translator_loop:

/*
 * Disassemble one instruction.  The translate_insn hook should
 * update db->pc_next and db->is_jmp to indicate what should be
 * done next -- either exiting this loop or locate the start of
 * the next instruction.
 */
if (db->num_insns == db->max_insns) {
/* Accept I/O on the last instruction.  */
set_can_do_io(db, true);
}

and we see later on:

tb->icount = db->num_insns;

So I guess we must have gone into the translator loop expecting to
translate more? (side note having int8_t type for the saved bool value
seems weird).

Could you confirm by doing something like:

  if (tb->icount == 1 &&  db->max_insns > 1) {
 fprintf(stderr, "ended up doing one insn (%d, %d)", db->max_insns, 
db->saved_can_do_io);
  }

after we set tb->icount?

> If the application is run entirely out of MMIO memory, things work fine (the
> previous patches related to this is in Jonathans branch), so one thought is 
> that
> it is related to having the code on a mix of regular and CXL memory. Since we
> previously had issues with code crossing page boundaries where only the second
> page is MMIO, I tried out the following change to the fix introduced for that
> issue thinking that reverting to the slow path in the middle of the 
> translation
> might not correctly update can_do_io:
>
> diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
> index 38c34009a5..db6ea360e0 100644
> --- a/accel/tcg/translator.c
> +++ b/accel/tcg/translator.c
> @@ -258,6 +258,7 @@ static void *translator_access(CPUArchState *env, 
> DisasContextBase *db,
>  if (unlikely(new_page1 == -1)) {
>  tb_unlock_pages(tb);
>  tb_set_page_addr0(tb, -1);
> +set_can_do_io(db, true);
>  return NULL;
>  }
>
> With that change, things work fine. Not saying that this is a valid fix for 
> the
> issue, but just trying to provide as much information as possible :)

I can see why this works, my worry is if we address all the early exit
cases here.

>
> Thanks,
> Jorgen

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH] target/s390x: improve cpu compatibility check error message

2024-03-15 Thread Christian Borntraeger

Am 14.03.24 um 20:00 schrieb Claudio Fontana:

some users were confused by this message showing under TCG:

Selected CPU generation is too new. Maximum supported model
in the configuration: 'xyz'

Try to clarify that the maximum can depend on the accel by
adding also the current accelerator to the message as such:

Selected CPU generation is too new. Maximum supported model
in the accelerator 'tcg' configuration: 'xyz'

Signed-off-by: Claudio Fontana 


Independent on which message we end up with (see comments
in this mail thread), I agree that improving the
error message is helpful.

Acked-by: Christian Borntraeger 


---
  target/s390x/cpu_models.c | 11 ++-
  1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 1a1c096122..0d6d8fc727 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -508,14 +508,14 @@ static void check_compatibility(const S390CPUModel 
*max_model,
  
  if (model->def->gen > max_model->def->gen) {

  error_setg(errp, "Selected CPU generation is too new. Maximum "
-   "supported model in the configuration: \'%s\'",
-   max_model->def->name);
+   "supported model in the accelerator \'%s\' configuration: 
\'%s\'",
+   current_accel_name(), max_model->def->name);
  return;
  } else if (model->def->gen == max_model->def->gen &&
 model->def->ec_ga > max_model->def->ec_ga) {
  error_setg(errp, "Selected CPU GA level is too new. Maximum "
-   "supported model in the configuration: \'%s\'",
-   max_model->def->name);
+   "supported model in the accelerator \'%s\' configuration: 
\'%s\'",
+   current_accel_name(), max_model->def->name);
  return;
  }
  
@@ -537,7 +537,8 @@ static void check_compatibility(const S390CPUModel *max_model,

  error_setg(errp, " ");
  s390_feat_bitmap_to_ascii(missing, errp, error_prepend_missing_feat);
  error_prepend(errp, "Some features requested in the CPU model are not "
-  "available in the configuration: ");
+  "available in the accelerator \'%s\' configuration: ",
+  current_accel_name());
  }
  
  S390CPUModel *get_max_cpu_model(Error **errp)




Re: Any interest in the QEMU community attending DVCon Europe October 2024?

2024-03-15 Thread ff


> Le 5 mars 2024 à 16:50, Alex Bennée  a écrit :
> 
> 
> Hi,
> 
> Over recent years there has been a push to make QEMU more flexible for
> EDA type applications. As long time developers know there are a number
> of downstream forks of QEMU which have their own solutions for modelling
> heterogeneous systems and integrating with hardware models. The work by
> Philippe, Anton and others to build a single binary with composable
> hardware is aiming at least to solve the heterogeneous modelling problem
> in the upstream project.
> 
> While we do discuss these "TCG" topics during KVM Forum the project may
> benefit from doing some outreach at some conferences where simulation
> and emulation are the primary focus.
> 
> The Design and Verification Conference & Exhibition Europe (DVCon
> Europe) is the premier European technical conference on system,
> software, design, verification, validation and integration. This year it
> will be on the 15-16 October 2024 in Munich. See: https://dvcon-europe.org/
> 
> There have been a number of papers and workshops on QEMU/KVM topics over
> the years. Unfortunately the website doesn't provide slides or videos of
> the talks but topics have included how QEMU can be used as a fast
> instruction simulator alongside things such as SystemC models or
> virtualisation can be leveraged to accelerate full system emulation.
> 
> The main tracks are fairly academic where engineering and research
> papers are submitted and if accepted can then be presented at the
> conference. This is probably over the top for QEMU related stuff but
> their is a tutorial track (deadline for Abstracts 1st July) which could
> be a good target for a introduction to the features and capabilities of
> the QEMU upstream. I suspect there would be interest in the wider
> modelling community to find out more about how to use the upstream
> project directly.
> 
> There is a co-located "SystemC Evolution Day" on the 17th where there
> might well be a strong overlap between SystemC users and QEMU. Mark
> Burton is involved with that and is keen for proposals talking about
> integrating SystemC models with QEMU. Please send a message to
> mbur...@quicinc.com if you're interested.
> 
> So is anyone interested?
> 
> Should we do more within the community to network and discuss our plans
> for QEMU as a modelling solution?
> 
> Any other thoughts?

I would love to hear how Qemu can participate into heterogeneous simulations.
One case is where multiple Qemu instances collaborate with limited interactions,
One case is where there is with memory aliasing (cortex M/R see a « window » of 
the main memory with a different address for the same byte) between Qemu.
One case Qemu is integrated with  other simulators. An interface to handle 
aliasing,  MMIO, SMMU, GIC are required to allow all possible cases of which 
simulator emulate what.
> 
> --
> Alex Bennée
> Virtualisation Tech Lead @ Linaro


[PATCH v3 1/7] qga: guest-get-fsinfo: add optional 'total-bytes-root' field

2024-03-15 Thread Andrey Drobyshev
Since the commit 25b5ff1a86 ("qga: add mountpoint usage info to
GuestFilesystemInfo") we have 2 values reported in guest-get-fsinfo:
used = (f_blocks - f_bfree), total = (f_blocks - f_bfree + f_bavail) as
returned by statvfs(3).  While on Windows guests that's all we can get
with GetDiskFreeSpaceExA(), on POSIX guests we might also be interested in
total file system size, as it's visible for root user.  Let's add an
optional field 'total-bytes-root' to GuestFilesystemInfo struct, which'd
only be reported on POSIX and represent f_blocks value as returned by
statvfs(3).

While here, let's document better where those values come from in both
POSIX and Windows.

Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c |  2 ++
 qga/commands-win32.c |  1 +
 qga/qapi-schema.json | 12 +++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 26008db497..8207c4c47e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1569,8 +1569,10 @@ static GuestFilesystemInfo *build_guest_fsinfo(struct 
FsMount *mount,
 nonroot_total = used + buf.f_bavail;
 fs->used_bytes = used * fr_size;
 fs->total_bytes = nonroot_total * fr_size;
+fs->total_bytes_root = buf.f_blocks * fr_size;
 
 fs->has_total_bytes = true;
+fs->has_total_bytes_root = true;
 fs->has_used_bytes = true;
 }
 
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index a1015757d8..9e820aad8d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1143,6 +1143,7 @@ static GuestFilesystemInfo *build_guest_fsinfo(char 
*guid, Error **errp)
 fs = g_malloc(sizeof(*fs));
 fs->name = g_strdup(guid);
 fs->has_total_bytes = false;
+fs->has_total_bytes_root = false;
 fs->has_used_bytes = false;
 if (len == 0) {
 fs->mountpoint = g_strdup("System Reserved");
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index b8efe31897..093a5ab602 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1031,8 +1031,18 @@
 # @type: file system type string
 #
 # @used-bytes: file system used bytes (since 3.0)
+# * POSIX: (f_blocks - f_bfree) * f_frsize, as returned by statvfs(3)
+# * Windows: (TotalNumberOfBytes - TotalNumberOfFreeBytes), as returned
+#   by GetDiskFreeSpaceEx()
 #
 # @total-bytes: non-root file system total bytes (since 3.0)
+# * POSIX: (f_blocks - f_bfree + f_bavail) * f_frsize, as returned by
+#   statvfs(3)
+# * Windows: TotalNumberOfBytes, as returned by GetDiskFreeSpaceEx()
+#
+# @total-bytes-root: total file system size in bytes (as visible for a
+# priviledged user) (since 8.3)
+# * POSIX only: (f_blocks * f_frsize), returned by statvfs(3)
 #
 # @disk: an array of disk hardware information that the volume lies
 # on, which may be empty if the disk type is not supported
@@ -1042,7 +1052,7 @@
 { 'struct': 'GuestFilesystemInfo',
   'data': {'name': 'str', 'mountpoint': 'str', 'type': 'str',
'*used-bytes': 'uint64', '*total-bytes': 'uint64',
-   'disk': ['GuestDiskAddress']} }
+   '*total-bytes-root': 'uint64', 'disk': ['GuestDiskAddress']} }
 
 ##
 # @guest-get-fsinfo:
-- 
2.39.3




[PATCH v3 0/7] qga/commands-posix: replace code duplicating commands with a helper

2024-03-15 Thread Andrey Drobyshev
v2 -> v3:
  * Patch 2/7:
- ga_pipe_read_str() helper now returns -errno in case of an error
  during read from pipe, so that the caller may use it to set
  error_setg_errno();
- ga_pipe_read_str() allocates +1 additional byte to make the
  string read from pipe null-terminated on every iteration;
  * Patch 6/7: patch is rewritten to completely get rid of fork()/exec()
when suspending via sysfs, it now simply uses g_file_set_contents()
(suggested by Daniel);
  * Patch 7/7: cosmetic change: removed unneeded brackets in an
expression.

v2: https://lists.nongnu.org/archive/html/qemu-devel/2024-03/msg00147.html

Andrey Drobyshev (7):
  qga: guest-get-fsinfo: add optional 'total-bytes-root' field
  qga: introduce ga_run_command() helper for guest cmd execution
  qga/commands-posix: qmp_guest_shutdown: use ga_run_command helper
  qga/commands-posix: qmp_guest_set_time: use ga_run_command helper
  qga/commands-posix: execute_fsfreeze_hook: use ga_run_command helper
  qga/commands-posix: don't do fork()/exec() when suspending via sysfs
  qga/commands-posix: qmp_guest_set_user_password: use ga_run_command
helper

 qga/commands-posix.c | 404 +++
 qga/commands-win32.c |   1 +
 qga/qapi-schema.json |  12 +-
 3 files changed, 193 insertions(+), 224 deletions(-)

-- 
2.39.3




[PATCH v3 6/7] qga/commands-posix: don't do fork()/exec() when suspending via sysfs

2024-03-15 Thread Andrey Drobyshev
Since commit 246d76eba ("qga: guest_suspend: decoupling pm-utils and sys
logic") pm-utils logic is running in a separate child from the sysfs
logic.  Now when suspending via sysfs we don't really need to do that in
a separate process as we only need to perform one write to /sys/power/state.

Let's just use g_file_set_contents() to simplify things here.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 41 +
 1 file changed, 5 insertions(+), 36 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 610d225d30..e0ea377f65 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1928,52 +1928,21 @@ static bool linux_sys_state_supports_mode(SuspendMode 
mode, Error **errp)
 
 static void linux_sys_state_suspend(SuspendMode mode, Error **errp)
 {
-Error *local_err = NULL;
+GError *local_gerr = NULL;
 const char *sysfile_strs[3] = {"disk", "mem", NULL};
 const char *sysfile_str = sysfile_strs[mode];
-pid_t pid;
-int status;
 
 if (!sysfile_str) {
 error_setg(errp, "unknown guest suspend mode");
 return;
 }
 
-pid = fork();
-if (!pid) {
-/* child */
-int fd;
-
-setsid();
-reopen_fd_to_null(0);
-reopen_fd_to_null(1);
-reopen_fd_to_null(2);
-
-fd = open(LINUX_SYS_STATE_FILE, O_WRONLY);
-if (fd < 0) {
-_exit(EXIT_FAILURE);
-}
-
-if (write(fd, sysfile_str, strlen(sysfile_str)) < 0) {
-_exit(EXIT_FAILURE);
-}
-
-_exit(EXIT_SUCCESS);
-} else if (pid < 0) {
-error_setg_errno(errp, errno, "failed to create child process");
-return;
-}
-
-ga_wait_child(pid, &status, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
+if (!g_file_set_contents(LINUX_SYS_STATE_FILE, sysfile_str,
+ -1, &local_gerr)) {
+error_setg(errp, "suspend: cannot write to '%s': %s",
+   LINUX_SYS_STATE_FILE, local_gerr->message);
 return;
 }
-
-if (WEXITSTATUS(status)) {
-error_setg(errp, "child process has failed to suspend");
-}
-
 }
 
 static void guest_suspend(SuspendMode mode, Error **errp)
-- 
2.39.3




[PATCH v3 2/7] qga: introduce ga_run_command() helper for guest cmd execution

2024-03-15 Thread Andrey Drobyshev
When executing guest commands in *nix environment, we repeat the same
fork/exec pattern multiple times.  Let's just separate it into a single
helper which would also be able to feed input data into the launched
process' stdin.  This way we can avoid code duplication.

To keep the history more bisectable, let's replace qmp commands
implementations one by one.  Also add G_GNUC_UNUSED attribute to the
helper and remove it in the next commit.

Originally-by: Yuri Pudgorodskiy 
Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 150 +++
 1 file changed, 150 insertions(+)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 8207c4c47e..ad05630086 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -76,6 +76,156 @@ static void ga_wait_child(pid_t pid, int *status, Error 
**errp)
 g_assert(rpid == pid);
 }
 
+static ssize_t ga_pipe_read_str(int fd[2], char **str)
+{
+ssize_t n, len = 0;
+char buf[1024];
+
+close(fd[1]);
+fd[1] = -1;
+while ((n = read(fd[0], buf, sizeof(buf))) != 0) {
+if (n < 0) {
+if (errno == EINTR) {
+continue;
+} else {
+len = -errno;
+break;
+}
+}
+*str = g_realloc(*str, len + n + 1);
+memcpy(*str + len, buf, n);
+len += n;
+*str[len] = '\0';
+}
+close(fd[0]);
+fd[0] = -1;
+
+return len;
+}
+
+/*
+ * Helper to run command with input/output redirection,
+ * sending string to stdin and taking error message from
+ * stdout/err.
+ */
+G_GNUC_UNUSED
+static int ga_run_command(const char *argv[], const char *in_str,
+  const char *action, Error **errp)
+{
+pid_t pid;
+int status;
+int retcode = -1;
+int infd[2] = { -1, -1 };
+int outfd[2] = { -1, -1 };
+char *str = NULL;
+ssize_t len = 0;
+
+if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) ||
+!g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) {
+error_setg(errp, "cannot create pipe FDs");
+goto out;
+}
+
+pid = fork();
+if (pid == 0) {
+char *cherr = NULL;
+
+setsid();
+
+if (in_str) {
+/* Redirect stdin to infd. */
+close(infd[1]);
+dup2(infd[0], 0);
+close(infd[0]);
+} else {
+reopen_fd_to_null(0);
+}
+
+/* Redirect stdout/stderr to outfd. */
+close(outfd[0]);
+dup2(outfd[1], 1);
+dup2(outfd[1], 2);
+close(outfd[1]);
+
+execvp(argv[0], (char *const *)argv);
+
+/* Write the cause of failed exec to pipe for the parent to read it. */
+cherr = g_strdup_printf("failed to exec '%s'", argv[0]);
+perror(cherr);
+g_free(cherr);
+_exit(EXIT_FAILURE);
+} else if (pid < 0) {
+error_setg_errno(errp, errno, "failed to create child process");
+goto out;
+}
+
+if (in_str) {
+close(infd[0]);
+infd[0] = -1;
+if (qemu_write_full(infd[1], in_str, strlen(in_str)) !=
+strlen(in_str)) {
+error_setg_errno(errp, errno, "%s: cannot write to stdin pipe",
+ action);
+goto out;
+}
+close(infd[1]);
+infd[1] = -1;
+}
+
+len = ga_pipe_read_str(outfd, &str);
+if (len < 0) {
+error_setg_errno(errp, -len, "%s: cannot read from stdout/stderr pipe",
+ action);
+goto out;
+}
+
+ga_wait_child(pid, &status, errp);
+if (*errp) {
+goto out;
+}
+
+if (!WIFEXITED(status)) {
+if (len) {
+error_setg(errp, "child process has terminated abnormally: %s",
+   str);
+} else {
+error_setg(errp, "child process has terminated abnormally");
+}
+goto out;
+}
+
+retcode = WEXITSTATUS(status);
+
+if (WEXITSTATUS(status)) {
+if (len) {
+error_setg(errp, "child process has failed to %s: %s",
+   action, str);
+} else {
+error_setg(errp, "child process has failed to %s: exit status %d",
+   action, WEXITSTATUS(status));
+}
+goto out;
+}
+
+out:
+g_free(str);
+
+if (infd[0] != -1) {
+close(infd[0]);
+}
+if (infd[1] != -1) {
+close(infd[1]);
+}
+if (outfd[0] != -1) {
+close(outfd[0]);
+}
+if (outfd[1] != -1) {
+close(outfd[1]);
+}
+
+return retcode;
+}
+
 void qmp_guest_shutdown(const char *mode, Error **errp)
 {
 const char *shutdown_flag;
-- 
2.39.3




[PATCH v3 4/7] qga/commands-posix: qmp_guest_set_time: use ga_run_command helper

2024-03-15 Thread Andrey Drobyshev
There's no need to check for the existence of "/sbin/hwclock", the
exec() call will do that for us.

Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 43 +++
 1 file changed, 3 insertions(+), 40 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d4025e0c1e..94b652d54e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -279,21 +279,9 @@ void qmp_guest_shutdown(const char *mode, Error **errp)
 void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
 {
 int ret;
-int status;
-pid_t pid;
 Error *local_err = NULL;
 struct timeval tv;
-static const char hwclock_path[] = "/sbin/hwclock";
-static int hwclock_available = -1;
-
-if (hwclock_available < 0) {
-hwclock_available = (access(hwclock_path, X_OK) == 0);
-}
-
-if (!hwclock_available) {
-error_setg(errp, QERR_UNSUPPORTED);
-return;
-}
+const char *argv[] = {"/sbin/hwclock", has_time ? "-w" : "-s", NULL};
 
 /* If user has passed a time, validate and set it. */
 if (has_time) {
@@ -324,37 +312,12 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, 
Error **errp)
  * just need to synchronize the hardware clock. However, if no time was
  * passed, user is requesting the opposite: set the system time from the
  * hardware clock (RTC). */
-pid = fork();
-if (pid == 0) {
-setsid();
-reopen_fd_to_null(0);
-reopen_fd_to_null(1);
-reopen_fd_to_null(2);
-
-/* Use '/sbin/hwclock -w' to set RTC from the system time,
- * or '/sbin/hwclock -s' to set the system time from RTC. */
-execl(hwclock_path, "hwclock", has_time ? "-w" : "-s", NULL);
-_exit(EXIT_FAILURE);
-} else if (pid < 0) {
-error_setg_errno(errp, errno, "failed to create child process");
-return;
-}
-
-ga_wait_child(pid, &status, &local_err);
+ga_run_command(argv, NULL, "set hardware clock to system time",
+   &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
-
-if (!WIFEXITED(status)) {
-error_setg(errp, "child process has terminated abnormally");
-return;
-}
-
-if (WEXITSTATUS(status)) {
-error_setg(errp, "hwclock failed to set hardware clock to system 
time");
-return;
-}
 }
 
 typedef enum {
-- 
2.39.3




[PATCH v3 3/7] qga/commands-posix: qmp_guest_shutdown: use ga_run_command helper

2024-03-15 Thread Andrey Drobyshev
Also remove the G_GNUC_UNUSED attribute added in the previous commit from
the helper.

Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 39 ++-
 1 file changed, 6 insertions(+), 33 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ad05630086..d4025e0c1e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -108,7 +108,6 @@ static ssize_t ga_pipe_read_str(int fd[2], char **str)
  * sending string to stdin and taking error message from
  * stdout/err.
  */
-G_GNUC_UNUSED
 static int ga_run_command(const char *argv[], const char *in_str,
   const char *action, Error **errp)
 {
@@ -230,8 +229,6 @@ void qmp_guest_shutdown(const char *mode, Error **errp)
 {
 const char *shutdown_flag;
 Error *local_err = NULL;
-pid_t pid;
-int status;
 
 #ifdef CONFIG_SOLARIS
 const char *powerdown_flag = "-i5";
@@ -260,46 +257,22 @@ void qmp_guest_shutdown(const char *mode, Error **errp)
 return;
 }
 
-pid = fork();
-if (pid == 0) {
-/* child, start the shutdown */
-setsid();
-reopen_fd_to_null(0);
-reopen_fd_to_null(1);
-reopen_fd_to_null(2);
-
+const char *argv[] = {"/sbin/shutdown",
 #ifdef CONFIG_SOLARIS
-execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y",
-  "hypervisor initiated shutdown", (char *)NULL);
+  shutdown_flag, "-g0", "-y",
 #elif defined(CONFIG_BSD)
-execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
-   "hypervisor initiated shutdown", (char *)NULL);
+  shutdown_flag, "+0",
 #else
-execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
-   "hypervisor initiated shutdown", (char *)NULL);
+  "-h", shutdown_flag, "+0",
 #endif
-_exit(EXIT_FAILURE);
-} else if (pid < 0) {
-error_setg_errno(errp, errno, "failed to create child process");
-return;
-}
+  "hypervisor initiated shutdown", (char *) NULL};
 
-ga_wait_child(pid, &status, &local_err);
+ga_run_command(argv, NULL, "shutdown", &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-if (!WIFEXITED(status)) {
-error_setg(errp, "child process has terminated abnormally");
-return;
-}
-
-if (WEXITSTATUS(status)) {
-error_setg(errp, "child process has failed to shutdown");
-return;
-}
-
 /* succeeded */
 }
 
-- 
2.39.3




[PATCH v3 7/7] qga/commands-posix: qmp_guest_set_user_password: use ga_run_command helper

2024-03-15 Thread Andrey Drobyshev
There's no need to check for the existence of the "chpasswd", "pw"
executables, as the exec() call will do that for us.

Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 96 ++--
 1 file changed, 13 insertions(+), 83 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index e0ea377f65..ffea69c3f0 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2151,14 +2151,8 @@ void qmp_guest_set_user_password(const char *username,
  Error **errp)
 {
 Error *local_err = NULL;
-char *passwd_path = NULL;
-pid_t pid;
-int status;
-int datafd[2] = { -1, -1 };
-char *rawpasswddata = NULL;
+g_autofree char *rawpasswddata = NULL;
 size_t rawpasswdlen;
-char *chpasswddata = NULL;
-size_t chpasswdlen;
 
 rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
 if (!rawpasswddata) {
@@ -2169,95 +2163,31 @@ void qmp_guest_set_user_password(const char *username,
 
 if (strchr(rawpasswddata, '\n')) {
 error_setg(errp, "forbidden characters in raw password");
-goto out;
+return;
 }
 
 if (strchr(username, '\n') ||
 strchr(username, ':')) {
 error_setg(errp, "forbidden characters in username");
-goto out;
+return;
 }
 
 #ifdef __FreeBSD__
-chpasswddata = g_strdup(rawpasswddata);
-passwd_path = g_find_program_in_path("pw");
+g_autofree char *chpasswdata = g_strdup(rawpasswddata);
+const char *crypt_flag = crypted ? "-H" : "-h";
+const char *argv[] = {"pw", "usermod", "-n", username,
+  crypt_flag, "0", NULL};
 #else
-chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata);
-passwd_path = g_find_program_in_path("chpasswd");
+g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username,
+rawpasswddata);
+const char *crypt_flag = crypted ? "-e" : NULL;
+const char *argv[] = {"chpasswd", crypt_flag, NULL};
 #endif
 
-chpasswdlen = strlen(chpasswddata);
-
-if (!passwd_path) {
-error_setg(errp, "cannot find 'passwd' program in PATH");
-goto out;
-}
-
-if (!g_unix_open_pipe(datafd, FD_CLOEXEC, NULL)) {
-error_setg(errp, "cannot create pipe FDs");
-goto out;
-}
-
-pid = fork();
-if (pid == 0) {
-close(datafd[1]);
-/* child */
-setsid();
-dup2(datafd[0], 0);
-reopen_fd_to_null(1);
-reopen_fd_to_null(2);
-
-#ifdef __FreeBSD__
-const char *h_arg;
-h_arg = (crypted) ? "-H" : "-h";
-execl(passwd_path, "pw", "usermod", "-n", username, h_arg, "0", NULL);
-#else
-if (crypted) {
-execl(passwd_path, "chpasswd", "-e", NULL);
-} else {
-execl(passwd_path, "chpasswd", NULL);
-}
-#endif
-_exit(EXIT_FAILURE);
-} else if (pid < 0) {
-error_setg_errno(errp, errno, "failed to create child process");
-goto out;
-}
-close(datafd[0]);
-datafd[0] = -1;
-
-if (qemu_write_full(datafd[1], chpasswddata, chpasswdlen) != chpasswdlen) {
-error_setg_errno(errp, errno, "cannot write new account password");
-goto out;
-}
-close(datafd[1]);
-datafd[1] = -1;
-
-ga_wait_child(pid, &status, &local_err);
+ga_run_command(argv, chpasswddata, "set user password", &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
-goto out;
-}
-
-if (!WIFEXITED(status)) {
-error_setg(errp, "child process has terminated abnormally");
-goto out;
-}
-
-if (WEXITSTATUS(status)) {
-error_setg(errp, "child process has failed to set user password");
-goto out;
-}
-
-out:
-g_free(chpasswddata);
-g_free(rawpasswddata);
-g_free(passwd_path);
-if (datafd[0] != -1) {
-close(datafd[0]);
-}
-if (datafd[1] != -1) {
-close(datafd[1]);
+return;
 }
 }
 #else /* __linux__ || __FreeBSD__ */
-- 
2.39.3




[PATCH v3 5/7] qga/commands-posix: execute_fsfreeze_hook: use ga_run_command helper

2024-03-15 Thread Andrey Drobyshev
There's no need to check for the existence of the hook executable, as the
exec() call will do that for us.

Signed-off-by: Andrey Drobyshev 
---
 qga/commands-posix.c | 35 +++
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 94b652d54e..610d225d30 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -736,8 +736,6 @@ static const char *fsfreeze_hook_arg_string[] = {
 
 static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp)
 {
-int status;
-pid_t pid;
 const char *hook;
 const char *arg_str = fsfreeze_hook_arg_string[arg];
 Error *local_err = NULL;
@@ -746,42 +744,15 @@ static void execute_fsfreeze_hook(FsfreezeHookArg arg, 
Error **errp)
 if (!hook) {
 return;
 }
-if (access(hook, X_OK) != 0) {
-error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook);
-return;
-}
 
-slog("executing fsfreeze hook with arg '%s'", arg_str);
-pid = fork();
-if (pid == 0) {
-setsid();
-reopen_fd_to_null(0);
-reopen_fd_to_null(1);
-reopen_fd_to_null(2);
-
-execl(hook, hook, arg_str, NULL);
-_exit(EXIT_FAILURE);
-} else if (pid < 0) {
-error_setg_errno(errp, errno, "failed to create child process");
-return;
-}
+const char *argv[] = {hook, arg_str, NULL};
 
-ga_wait_child(pid, &status, &local_err);
+slog("executing fsfreeze hook with arg '%s'", arg_str);
+ga_run_command(argv, NULL, "execute fsfreeze hook", &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
-
-if (!WIFEXITED(status)) {
-error_setg(errp, "fsfreeze hook has terminated abnormally");
-return;
-}
-
-status = WEXITSTATUS(status);
-if (status) {
-error_setg(errp, "fsfreeze hook has failed with status %d", status);
-return;
-}
 }
 
 /*
-- 
2.39.3




Re: [PATCH v2 3/6] qdev-monitor: add option to report GenericError from find_device_state

2024-03-15 Thread Markus Armbruster
Sorry for the late answer.

Vladimir Sementsov-Ogievskiy  writes:

> On 07.03.24 12:46, Markus Armbruster wrote:

[...]

>> I appreciate the attempt to curb the spread of DeviceNotFound errors.
>> Two issues:
>>
>> * Copy-pasting find_device_state() with a false argument is an easy
>>   error to make.
>>
>> * Most uses of find_device_state() are via blk_by_qdev_id() and
>>   qmp_get_blk().  Any new uses of qemu_get_blk() will still produce
>>   DeviceNotFound.
>>
>> Hmm.
>
> Hmm. Right. Wait a bit, I can make the change stricter.
>
> Could you still explain (or give a link), why and when we decided to use only 
> GenericError? I think, having different "error-codes" is a good thing, why we 
> are trying to get rid of it?

We actually got rid of most of them years ago :)

But you deserve a more complete answer.

QMP initially specified the following error response[1]:

2.4.2 error
---

The error response is issued when the command execution could not be
completed because of an error condition.

The format is:

{ "error": { "class": json-string, "data": json-value }, "id": json-value }

 Where,

- The "class" member contains the error class name (eg. 
"ServiceUnavailable")
- The "data" member contains specific error data and is defined in a
  per-command basis, it will be an empty json-object if the error has no 
data
- The "id" member contains the transaction identification associated with
  the command execution (if issued by the Client)

Note the structure of @data depends on @class.  We documented a
command's possible error classes (well, we tried), but never bothered to
document the @data it comes with.

Documentation deficits aside, this is looks quite expressive.  There are
issues, though:

1. Formatting errors in human-readable form is bothersome, and creates a
   tight coupling between QMP server and client.

   Consider:

{"class": "DeviceNotFound", "data": {"device": "ide1-cd0"}}

   To format this in human-readable form, you need to know the error.

   The server does.  Fine print: it has a table mapping JSON templates
   to human-readable error message templates.

   The client needs to duplicate this somehow.  If it receives an error
   it doesn't know, all it can do is barf (possibly dressed up) JSON at
   the human.  To avoid that, clients need to track the server closely:
   tight coupling.

2. Errors have notational overhead, which leads to bad errors.

   To create a new error, you have to edit two source files (not
   counting clients).  Strong incentive to reuse existing errors.  Even
   when they don't quite fit.  When a name provided by the user couldn't
   be resolved, reusing DeviceNotFound is easier than creating a new
   error that is more precise.

3. The human-readable error message is hidden from the programmer's
   view, which leads to bad error messages.

   At the point in the source where the error is created, we see
   something like QERR_DEVICE_NOT_FOUND, name.  To see the
   human-readable message, we have to look up macro
   QERR_DEVICE_NOT_FOUND's error message template in the table, or
   actually test (*gasp*) the error.  People generally do neither, and
   bad error messages proliferate.

4. Too little gain for the pain

   Clients rarely want to handle different errors differently.  More
   often than not, all they do with @class and @data is log them.  Only
   occasionally do they switch on @class, and basically never on @data.

It me took a considerable fight to get the protocol amended to include a
human-readable message[2].  This addressed issue 1.

Over the next two years or so, issues 2. to 4. slowly sank in.  We
eventually tired of the complexity, ripped out @data, and dumbed down
all error classes to GenericError, except for the few clients actually
cared for[3].  We also mandated that new errors avoid the QERR_ macros.

Eliminating the existing QERR_ macros has been slow.  We're down to 13
in master, with patches deleting 7 on the list.

This has served us reasonably well.

Questions?


[1] Commit f544d174dfc
QMP: Introduce specification
Dec 2009

[2] Commit 77e595e7c61q
QMP: add human-readable description to error response
Dec 2009

[3] Commit de253f14912
qmp: switch to the new error format on the wire
Aug 2012




Re: [PATCH v7 3/8] tests/qtest/migration: Replace migrate_get_connect_uri inplace of migrate_get_socket_address

2024-03-15 Thread Fabiano Rosas
Het Gala  writes:

> Refactor migrate_get_socket_address to internally utilize 'socket-address'
> parameter, reducing redundancy in the function definition.
>
> migrate_get_socket_address implicitly converts SocketAddress into str.
> Move migrate_get_socket_address inside migrate_get_connect_uri which
> should return the uri string instead.
>
> Signed-off-by: Het Gala 
> Suggested-by: Fabiano Rosas 
> Reviewed-by: Fabiano Rosas 
> ---
>  tests/qtest/migration-helpers.c | 29 +++--
>  1 file changed, 19 insertions(+), 10 deletions(-)
>
> diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c
> index 3e8c19c4de..8806dc841e 100644
> --- a/tests/qtest/migration-helpers.c
> +++ b/tests/qtest/migration-helpers.c
> @@ -48,28 +48,37 @@ static char *SocketAddress_to_str(SocketAddress *addr)
>  }
>  }
>  
> -static char *
> -migrate_get_socket_address(QTestState *who, const char *parameter)
> +static SocketAddress *migrate_get_socket_address(QTestState *who)
>  {
>  QDict *rsp;
> -char *result;
>  SocketAddressList *addrs;
> +SocketAddress *addr;
>  Visitor *iv = NULL;
>  QObject *object;
>  
>  rsp = migrate_query(who);
> -object = qdict_get(rsp, parameter);
> +object = qdict_get(rsp, "socket-address");

Just a heads up, none of what I'm about to say applies to current
master.

This can return NULL if there is no socket-address, such as with a file
migration. Then the visitor code below just barfs. It would be nice if
we touched this up eventually.

I only noticed this because I was fiddling with the file migration API
and this series helped me a lot to test my changes. So thanks for that,
Het.

Another point is: we really need to encourage people to write tests
using the new channels API. I added the FileMigrationArgs with the
'offset' as a required parameter, not even knowing optional parameters
were a thing. So it's obviously not enough to write support for the new
API if no tests ever touch it.

>  
>  iv = qobject_input_visitor_new(object);
>  visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
> +addr = addrs->value;
>  visit_free(iv);
>  
> -/* we are only using a single address */
> -result = SocketAddress_to_str(addrs->value);
> -
> -qapi_free_SocketAddressList(addrs);
>  qobject_unref(rsp);
> -return result;
> +return addr;
> +}
> +
> +static char *
> +migrate_get_connect_uri(QTestState *who)
> +{
> +SocketAddress *addrs;
> +char *connect_uri;
> +
> +addrs = migrate_get_socket_address(who);
> +connect_uri = SocketAddress_to_str(addrs);
> +
> +qapi_free_SocketAddress(addrs);
> +return connect_uri;
>  }
>  
>  bool migrate_watch_for_events(QTestState *who, const char *name,
> @@ -129,7 +138,7 @@ void migrate_qmp(QTestState *who, QTestState *to, const 
> char *uri,
>  
>  g_assert(!qdict_haskey(args, "uri"));
>  if (!uri) {
> -connect_uri = migrate_get_socket_address(to, "socket-address");
> +connect_uri = migrate_get_connect_uri(to);
>  }
>  qdict_put_str(args, "uri", uri ? uri : connect_uri);



Re: [PATCH v4 0/3] Adjust the output of x-query-virtio-status

2024-03-15 Thread Yong Huang
On Fri, Mar 15, 2024 at 3:51 PM Markus Armbruster  wrote:

> "Michael S. Tsirkin"  writes:
>
> > On Wed, Mar 13, 2024 at 10:40:21AM +0100, Markus Armbruster wrote:
> >> I could be awkward for the use case described in PATCH 1's commit
> >> message:
> >>
> >> However, we sometimes want to compare features and status bits
> without
> >> caring for their exact meaning.  Say we want to verify the
> correctness
> >> of the virtio negotiation between guest, QEMU, and OVS-DPDK.  We
> can use
> >> QMP command x-query-virtio-status to retrieve vhost-user net device
> >> features, and the "ovs-vsctl list interface" command to retrieve
> >> interface features.  Without commit f3034ad71fc, we could then
> simply
> >> compare the numbers.  With this commit, we first have to map from
> the
> >> strings back to the numeric encoding.
> >
> > So, consider how guest kernel presents features then. Do you happen to
> know?
> > It's actually a binary string:
> >
> > static ssize_t features_show(struct device *_d,
> >  struct device_attribute *attr, char *buf)
> > {
> > struct virtio_device *dev = dev_to_virtio(_d);
> > unsigned int i;
> > ssize_t len = 0;
> >
> > /* We actually represent this as a bitstring, as it could be
> >  * arbitrary length in future. */
> > for (i = 0; i < sizeof(dev->features)*8; i++)
> > len += sysfs_emit_at(buf, len, "%c",
> >__virtio_test_bit(dev, i) ? '1' : '0');
> > len += sysfs_emit_at(buf, len, "\n");
> > return len;
> > }
> > static DEVICE_ATTR_RO(features);
>
> I'm willing to accept any reasonably compact representation of the bits
> that is easy to use for the comparison use case.
>
> I strongly prefer integers as long as their width suffices.
>
> Since out integers are limited to 64 bits, and you want us to design for
> more, we need something else.
>
> I'm fine with array of integers, but you don't like it.
>
> We generally avoid encoding stuff in strings, but using strings for
> "overwide" integers isn't as bad as using them for structured data.  I
> guess I'd be okay with it.
>
> I'd use decimal simply to keep these "overwide" integers as close as
> possible to regular ones.
>
> If using base 2 enables string compare for the comparison use case,
> that's an argument for base 2.
>
> Hyman Huang, can you show us example output of "ovs-vsctl list
> interface"?
>
>
Here is the output of an active interface enable the dpdk feature:

# ovs-vsctl list interface port-testvm2pn8

_uuid:
admin_state: up
name: port-testvm2pn8
..
status:   {features="0x00017060a782", mode=client,
num_of_vrings="4"..}


Yong


-- 
Best regards


[PATCH 02/12] uefi-test-tools/UefiTestToolsPkg: Add RISC-V support

2024-03-15 Thread Sunil V L
Enable building the test application for RISC-V with appropriate
dependencies updated.

Signed-off-by: Sunil V L 
---
 tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc 
b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
index c8511cd732..0902fd3c73 100644
--- a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
+++ b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
@@ -19,7 +19,7 @@
   PLATFORM_VERSION= 0.1
   PLATFORM_NAME   = UefiTestTools
   SKUID_IDENTIFIER= DEFAULT
-  SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64
+  SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64
   BUILD_TARGETS   = DEBUG
 
 [BuildOptions.IA32]
@@ -60,6 +60,10 @@
 
 [LibraryClasses.IA32, LibraryClasses.X64]
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
+
+[LibraryClasses.RISCV64]
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
 
 [PcdsFixedAtBuild]
   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
-- 
2.40.1




[PATCH 00/12] Add support for RISC-V ACPI tests

2024-03-15 Thread Sunil V L
Currently, bios-table-test doesn't support RISC-V. This series enables
the framework changes required and basic testing. Things like NUMA
related test cases will be added later.

This needs refactoring/renaming of ARM64 bios table tests. Importantly,
the test cases now look for the expected AML files under
tests/data/acpi/virt/aarch64 path instead of directly under
tests/data/acpi/virt. To keep test cases not to fail because of this
movement, they are updated to look for both paths first.

As part of this effort, it is found that uefi-test-tools is currently
broken to build. So, updated its Makefile as well to use python based
edk2 build script.

The series depends on Gerd's below series.
https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg03855.html

The changes are also available at branch
https://gitlab.com/vlsunil/qemu/-/tree/riscv_bios_table_test_v1

This branch which is on top of Gerd's series completed CI tests.
https://gitlab.com/vlsunil/qemu/-/pipelines/1214784985


Sunil V L (12):
  roms/edk2-build.py: Add --module support
  uefi-test-tools/UefiTestToolsPkg: Add RISC-V support
  uefi-test-tools: Add support for python based build script
  tests/data/uefi-boot-images: Add RISC-V ISO image
  qtest: bios-tables-test: Rename aarch64 tests with aarch64 in them
  tests/qtest/bios-tables-test.c: Add support for arch in path
  tests/data/acpi/virt: Move ACPI tables under aarch64
  meson.build: Add RISC-V to the edk2-target list
  pc-bios/meson.build: Add support for RISC-V in unpack_edk2_blobs
  tests/data/acpi/rebuild-expected-aml.sh: Add RISC-V
  tests/data/acpi/virt/riscv64: Add expected ACPI tables for RISC-V
  tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V

 meson.build   |   2 +-
 pc-bios/meson.build   |   2 +
 roms/edk2-build.py|   3 +
 tests/data/acpi/rebuild-expected-aml.sh   |   5 +-
 tests/data/acpi/virt/{ => aarch64}/APIC   | Bin
 .../acpi/virt/{ => aarch64}/APIC.acpihmatvirt | Bin
 .../acpi/virt/{ => aarch64}/APIC.topology | Bin
 tests/data/acpi/virt/{ => aarch64}/DBG2   | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT   | Bin
 .../acpi/virt/{ => aarch64}/DSDT.acpihmatvirt | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT.memhp | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT.pxb   | Bin
 .../acpi/virt/{ => aarch64}/DSDT.topology | Bin
 tests/data/acpi/virt/{ => aarch64}/FACP   | Bin
 tests/data/acpi/virt/{ => aarch64}/GTDT   | Bin
 .../acpi/virt/{ => aarch64}/HMAT.acpihmatvirt | Bin
 tests/data/acpi/virt/{ => aarch64}/IORT   | Bin
 tests/data/acpi/virt/{ => aarch64}/MCFG   | Bin
 tests/data/acpi/virt/{ => aarch64}/NFIT.memhp | Bin
 tests/data/acpi/virt/{ => aarch64}/PPTT   | Bin
 .../acpi/virt/{ => aarch64}/PPTT.acpihmatvirt | Bin
 .../acpi/virt/{ => aarch64}/PPTT.topology | Bin
 tests/data/acpi/virt/{ => aarch64}/SLIT.memhp | Bin
 tests/data/acpi/virt/{ => aarch64}/SPCR   | Bin
 .../acpi/virt/{ => aarch64}/SRAT.acpihmatvirt | Bin
 tests/data/acpi/virt/{ => aarch64}/SRAT.memhp | Bin
 .../data/acpi/virt/{ => aarch64}/SRAT.numamem | Bin
 tests/data/acpi/virt/{ => aarch64}/SSDT.memhp | Bin
 tests/data/acpi/virt/{ => aarch64}/VIOT   | Bin
 tests/data/acpi/virt/riscv64/APIC | Bin 0 -> 116 bytes
 tests/data/acpi/virt/riscv64/BGRT | Bin 0 -> 56 bytes
 tests/data/acpi/virt/riscv64/DSDT | Bin 0 -> 3518 bytes
 tests/data/acpi/virt/riscv64/FACP | Bin 0 -> 276 bytes
 tests/data/acpi/virt/riscv64/MCFG | Bin 0 -> 60 bytes
 tests/data/acpi/virt/riscv64/RHCT | Bin 0 -> 314 bytes
 tests/data/acpi/virt/riscv64/RSDP | Bin 0 -> 36 bytes
 tests/data/acpi/virt/riscv64/SPCR | Bin 0 -> 80 bytes
 tests/data/acpi/virt/riscv64/XSDT | Bin 0 -> 84 bytes
 .../bios-tables-test.riscv64.iso.qcow2| Bin 0 -> 16896 bytes
 tests/qtest/bios-tables-test.c|  95 ++
 tests/qtest/meson.build   |   3 +
 tests/uefi-test-tools/Makefile|  18 ++--
 .../UefiTestToolsPkg/UefiTestToolsPkg.dsc |   6 +-
 tests/uefi-test-tools/uefi-test-build.config  |  57 +++
 44 files changed, 156 insertions(+), 35 deletions(-)
 rename tests/data/acpi/virt/{ => aarch64}/APIC (100%)
 rename tests/data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/APIC.topology (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DBG2 (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.pxb (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.topology (100%)
 rename tests/data/acpi/virt/{ => aarch64}/FACP (100%)
 rename tests/data/acpi/virt/{ => aarch64}/GTDT (100%)
 rename tests/data/acpi/virt/{ => aarch6

[PATCH 01/12] roms/edk2-build.py: Add --module support

2024-03-15 Thread Sunil V L
UefiTestToolsPkg which should use edk2-build.py needs --module parameter
support. Add this optional parameter handling.

Signed-off-by: Sunil V L 
---
 roms/edk2-build.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/roms/edk2-build.py b/roms/edk2-build.py
index e564765aaa..3bfe200929 100755
--- a/roms/edk2-build.py
+++ b/roms/edk2-build.py
@@ -192,6 +192,9 @@ def build_one(cfg, build, jobs = None, silent = False, 
nologs = False):
 cmdline += [ '-n', jobs ]
 for arch in b['arch'].split():
 cmdline += [ '-a', arch ]
+if 'module' in b:
+for module in b['module'].split():
+cmdline += [ '-m', module ]
 if 'opts' in b:
 for name in b['opts'].split():
 section = 'opts.' + name
-- 
2.40.1




Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()

2024-03-15 Thread Peter Xu
On Fri, Mar 15, 2024 at 01:20:49PM +0100, Cédric Le Goater wrote:
> On 3/15/24 12:01, Peter Xu wrote:
> > On Fri, Mar 15, 2024 at 11:17:45AM +0100, Cédric Le Goater wrote:
> > > > migrate_set_state is also unintuitive because it ignores invalid state
> > > > transitions and we've been using that property to deal with special
> > > > states such as POSTCOPY_PAUSED and FAILED:
> > > > 
> > > > - After the migration goes into POSTCOPY_PAUSED, the resumed migration's
> > > > migrate_init() will try to set the state NONE->SETUP, which is not
> > > > valid.
> > > > 
> > > > - After save_setup fails, the migration goes into FAILED, but 
> > > > wait_unplug
> > > > will try to transition SETUP->ACTIVE, which is also not valid.
> > > > 
> > > 
> > > I am not sure I understand what the plan is. Both solutions are 
> > > problematic
> > > regarding the state transitions.
> > > 
> > > Should we consider that waiting for failover devices to unplug is an 
> > > internal
> > > step of the SETUP phase not transitioning to ACTIVE ?
> > 
> > If to unblock this series, IIUC the simplest solution is to do what Fabiano
> > suggested, that we move qemu_savevm_wait_unplug() to be before the check of
> > setup() ret.
> 
> The simplest is IMHO moving qemu_savevm_wait_unplug() before
> qemu_savevm_state_setup() and leave patch 10 is unchanged. See
> below the extra patch. It looks much cleaner than what we have
> today.

Yes it looks cleaner indeed, it's just that then we'll have one more
possible state conversions like SETUP->UNPLUG->SETUP.  I'd say it's fine,
but let's also copy Laruent and Laine if it's going to be posted formally.

Thanks,

> 
> > In that case, the state change in qemu_savevm_wait_unplug()
> > should be benign and we should see a super small window it became ACTIVE
> > but then it should be FAILED (and IIUC the patch itself will need to use
> > ACTIVE as "old_state", not SETUP anymore).
> 
> OK. I will give it a try to compare.
> 
> > For the long term, maybe we can remove the WAIT_UNPLUG state?
> 
> I hope so, it's an internal SETUP state for me.
> 
> > The only Libvirt support seems to be here:
> > 
> > commit 8a226ddb3602586a2ba2359afc4448c02f566a0e
> > Author: Laine Stump 
> > Date:   Wed Jan 15 16:38:57 2020 -0500
> > 
> >  qemu: add wait-unplug to qemu migration status enum
> > 
> > Considering that qemu_savevm_wait_unplug() can be a noop if the device is
> > already unplugged, I think it means no upper layer app should rely on this
> > state to present.
> 
> Thanks,
> 
> C.
> 
> 
> > 
> @@ -3383,11 +3383,10 @@ bool migration_rate_limit(void)
>   * unplugged
>   */
> -static void qemu_savevm_wait_unplug(MigrationState *s, int old_state,
> -int new_state)
> +static void qemu_savevm_wait_unplug(MigrationState *s, int state)
>  {
>  if (qemu_savevm_state_guest_unplug_pending()) {
> -migrate_set_state(&s->state, old_state, 
> MIGRATION_STATUS_WAIT_UNPLUG);
> +migrate_set_state(&s->state, state, MIGRATION_STATUS_WAIT_UNPLUG);
>  while (s->state == MIGRATION_STATUS_WAIT_UNPLUG &&
> qemu_savevm_state_guest_unplug_pending()) {
> @@ -3410,9 +3409,7 @@ static void qemu_savevm_wait_unplug(Migr
>  }
>  }
> -migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, 
> new_state);
> -} else {
> -migrate_set_state(&s->state, old_state, new_state);
> +migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, state);
>  }
>  }
> @@ -3469,17 +3466,19 @@ static void *migration_thread(void *opaq
>  qemu_savevm_send_colo_enable(s->to_dst_file);
>  }
> +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP);
> +
>  bql_lock();
>  qemu_savevm_state_setup(s->to_dst_file);
>  bql_unlock();
> -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
> -   MIGRATION_STATUS_ACTIVE);
> -
>  s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
>  trace_migration_thread_setup_complete();
> +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
> +  MIGRATION_STATUS_ACTIVE);
> +
>  while (migration_is_active()) {
>  if (urgent || !migration_rate_exceeded(s->to_dst_file)) {
>  MigIterateState iter_state = migration_iteration_run(s);
> @@ -3580,18 +3579,20 @@ static void *bg_migration_thread(void *o
>  ram_write_tracking_prepare();
>  #endif
> +qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP);
> +
>  bql_lock();
>  qemu_savevm_state_header(s->to_dst_file);
>  qemu_savevm_state_setup(s->to_dst_file);
>  bql_unlock();
> -qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
> -   MIGRATION_STATUS_ACTIVE);
> -
>  s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
>  trace_migration_thread_setup_complete();
> +migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
> +  MIGRATION_ST

[PATCH-for-9.1 01/21] target/i386: Declare CPU QOM types using DEFINE_TYPES() macro

2024-03-15 Thread Philippe Mathieu-Daudé
When multiple QOM types are registered in the same file,
it is simpler to use the the DEFINE_TYPES() macro. In
particular because type array declared with such macro
are easier to review.

In few commits we are going to add more types, so replace
the type_register_static() to ease further reviews.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Zhao Liu 
Message-Id: <20231013140116.255-14-phi...@linaro.org>
---
 target/i386/cpu.c | 50 ++-
 1 file changed, 23 insertions(+), 27 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 9a210d8d92..ebf555f50f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4991,13 +4991,6 @@ static void max_x86_cpu_initfn(Object *obj)
 &error_abort);
 }
 
-static const TypeInfo max_x86_cpu_type_info = {
-.name = X86_CPU_TYPE_NAME("max"),
-.parent = TYPE_X86_CPU,
-.instance_init = max_x86_cpu_initfn,
-.class_init = max_x86_cpu_class_init,
-};
-
 static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
 {
 assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD);
@@ -8041,19 +8034,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 }
 }
 
-static const TypeInfo x86_cpu_type_info = {
-.name = TYPE_X86_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(X86CPU),
-.instance_align = __alignof(X86CPU),
-.instance_init = x86_cpu_initfn,
-.instance_post_init = x86_cpu_post_initfn,
-
-.abstract = true,
-.class_size = sizeof(X86CPUClass),
-.class_init = x86_cpu_common_class_init,
-};
-
 /* "base" CPU model, used by query-cpu-model-expansion */
 static void x86_cpu_base_class_init(ObjectClass *oc, void *data)
 {
@@ -8065,22 +8045,38 @@ static void x86_cpu_base_class_init(ObjectClass *oc, 
void *data)
 xcc->ordering = 8;
 }
 
-static const TypeInfo x86_base_cpu_type_info = {
-.name = X86_CPU_TYPE_NAME("base"),
-.parent = TYPE_X86_CPU,
-.class_init = x86_cpu_base_class_init,
+static const TypeInfo x86_cpu_types[] = {
+{
+.name   = TYPE_X86_CPU,
+.parent = TYPE_CPU,
+.abstract   = true,
+.instance_size  = sizeof(X86CPU),
+.instance_align = __alignof(X86CPU),
+.instance_init  = x86_cpu_initfn,
+.instance_post_init = x86_cpu_post_initfn,
+.class_size = sizeof(X86CPUClass),
+.class_init = x86_cpu_common_class_init,
+}, {
+.name   = X86_CPU_TYPE_NAME("base"),
+.parent = TYPE_X86_CPU,
+.class_init = x86_cpu_base_class_init,
+}, {
+.name   = X86_CPU_TYPE_NAME("max"),
+.parent = TYPE_X86_CPU,
+.instance_init  = max_x86_cpu_initfn,
+.class_init = max_x86_cpu_class_init,
+}
 };
 
+DEFINE_TYPES(x86_cpu_types)
+
 static void x86_cpu_register_types(void)
 {
 int i;
 
-type_register_static(&x86_cpu_type_info);
 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
 x86_register_cpudef_types(&builtin_x86_defs[i]);
 }
-type_register_static(&max_x86_cpu_type_info);
-type_register_static(&x86_base_cpu_type_info);
 }
 
 type_init(x86_cpu_register_types)
-- 
2.41.0




[PATCH 04/12] tests/data/uefi-boot-images: Add RISC-V ISO image

2024-03-15 Thread Sunil V L
To test ACPI tables, edk2 needs to be booted with a disk image having
EFI partition. This image is created using UefiTestToolsPkg.

Signed-off-by: Sunil V L 
---
 .../bios-tables-test.riscv64.iso.qcow2  | Bin 0 -> 16896 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 
tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2

diff --git a/tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2 
b/tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2
new file mode 100644
index 
..c720bf99a45fab6d1e21963cca563ee0ea059b82
GIT binary patch
literal 16896
zcmeIZbyQp5w=Wvpf_t$*DNx*s76?*Gkpjhw1#fW*1ef3~T4-^K6sNdLaVJ>O;85J1
zQtYN*dfvO^_r|&BjPd@sc6P{~`K&p2_F8kzHD!gZF8|^R005vN-~auA^AEuE|F<^$
z`wy6ZG3pwPn*YYNLL{
z@~dP#ETCmdJ*7_kgqm;AKA-YZ)H7i(_@NMQyg)%>KxsGsR-2gBcMs8>CNZu}?giTr
zW$PK&8%mMm2N;bN$uC%lqEk?%*o3+>e_ic4JOyZ|QDL}X0t1oRteN9K<8(Pw$37xF
z1|I2P6F9n_yPUW{fk&qoW*`a$lHzw{Kz0D&>R{It0_pAL#g%74US}QyK_2E*7!OJR
zAOI>3rhJGxFB1wt!!!m0K*PZ#AnIyU>wpil!a2G-TU)W^B7llPn!FEq6{Iy4q~)j}
z>{K9cNmkXnrC&tPStW#fh-_pr=`de}dA<-N&D^d}y}pq>O>MJ&j$(%bF!LVvC;g^~
zXE=dk`Gi+tSz8DwS_3uBWFbZj%AzyV%_=l~oF%n-a=AdsJV^C9}F;wuhCstjLCnUP*F48|zU^QfHp
zBMJ#O{w?+cY7szMfzGGoxOAWs2Ye9nKr0PthyUvz;D5RZZ20$j`j@}-Kj!00+{+OG
zApZywo!w&+yn9UQdymNi?=d<2o>EHQw^NnfV`{`brO~{nv}N~vdis0JU~x}DfBiTU
z_#QueeNUO^!GJ#p3peB+${KJ_*~Y>DV0OiO%z=B4IqmK-*N1z`!*k!xn|6=+obNIJ
z-|rFdzsG_R_xvXb_gE=9YrM4Ci?)1f@8Iihn0CWpe5WAz@Sgkk!
z`gPpBm$H~L9JTE~PC!(x9k^sr57SWaemy2t{-hFrElVz*fv{aT9xicJN6~n1W2%AH
zFz7ge3Yn;tW&tB8wW|-F68=c@4o$;g>UMmqbv5_1c)wkvMLraUAyg?f9Xt3O+n84
zxsFBX$^U1H-jvM19JShUm36pu-|w@BOyrj!y)XL!K-(D4iF`Jx?;EZRkq(^%-V;CE
zcCCm2TZd0Zyx9J>IzrROgqwwaV4a)5#CQHST8)M~U(xf(CglJ&*7=;~S6QbpX;V)T
zw2syD4S@~j;erLP2kkcLLaZLfMRkwS0(o~v2kvzw!X~{MrJ5esl&4GEOJV7d&hn8{
zeXmzCDRM1cZ?;5Rdn$LUpGE2RNlNXtlH|}3`e>#khWUA_OBnq{A4nn&@%q-@rrO#r
zxunkjqcl+%<=?T&QPlY8on}hQAT0X`EyB5^YASJg%Nk_nMh*dNzwzGuKByng+~1e4
z(>xQDn?MQP0zxSLe$(8ldOyAz4en>*y!(XjKOM3bU4b#c5Vo*p2u|1JNb!apiEl7F
z6oe$t^09h6zbrWyIyW4@vXsP?ApYD`Ds;wbvlic;r&SvoW5h{zAnIo~U0XGI;nY+E^rWKx**=fVr<=(@I
zO5qv}aXk5CR8{LkI<~~9xK4fKH@V}TA6(DfZG-1LPdWF)-~zu^aB6Q!#@P^;GI@u;
z4tpm`m-41mquxn8e1f?;V%ABiZlX3YrJ~3ltEae`Zce;$8)|WdW*6O}gvLkKGd3_9
zK`!RvNGvcn)8@&>_L<;My9Y^gH$Wy9eAsc
z*l+dtwVGq!z*W<*a1;Eh1G*bV8qoDlueCBHZfEf7Q`bwwGQ{VxZ8~GZq<3WpzWh?k
zT^6RC1loy@L<6#`Y~N7#q0j_Ql`njd2(+Sh@_)AET3l<&=RUtU`}k1AHlY=2AWFiR
zovd$E!^p++iWWXf$oR@TjbdO6BO>4t4(8kFvAP_iAL-p&EUHtW1AuDMT@z$@l<*S619(Zb8
z11;tS2SD(-G3d&nqSq}%+pP^FazC!cZ==@6M{`LtD{*?fm96(&ehVYezoIYJk4S))
zQ@i?t9&_f*Va3bo2_~kAP|b(*l9fU*#m*RR{`>>b<@(Mp5FAI6`bxJvxvJG&>q@ii
zg+L}t4!No&{*r%U&TG_aRqAZhC;`bhs?$*wv3TL6Y8Z{_D;vpiNzt+web{los3i}D
zk=~Bo$0P=jR8wMzSnp-9$l=K-yPkD#7M)*XV5<^J@Ux1wx3U7f9})pl;@=IKPZese
z;0ivjh}nz&5sitdmdK%Rd-?DXy!yTqFG;u`lM~+0!UT^)NS`K1Wr!rt4c$`qVj_-)
zONtSn)_5x44j6~gkfT#mgH6(L1vL^s9+gzQ&xoy%{z?)E9PzpMgkLj<)^HeA(e+t;
zZ2nJZY*Z3rKz0D&^~+lf4XxuO1hZaiPlHf6rE)Ii(#RkZCY?CQ<;uT0auZ$W*bk0WdiVP6=D`al1d^tu2Ltds|9(CyFZmdEpQ3olTc!W)ow(-WJ(Ev
zwi!l6z4{Hr?d$K(pG0wVla<{5y%qX0=B$2JR@RyaLH#_5k@PH40g9?rA|TJG6q(a1
zC>p>j>_f`2cPTO`1%Z0{y)kBl@U`3s2ou*@iRwJrR=)?3|!
zzb=BOYGq}bI)_Y74y>ePd|u(&FjaV31ajTwHU^%S`I)=w*t-w4_5w6I{@8s(;o3pc
zpx*7E`y7z@g6yD=0_y{AC4=AWCd&|}c{$yc>xfpO7C7^*=huINDC<+poR;LcId^*N
zS5G>b&k{)bw2M18?fr&;r?U|~W7K~V3y~(Hi3KlOrjzTf)YYVet_kqIdSw#a)BlA5
zd9S5Pb#T629fsBg)e2=;e!FuJ&VDozOO@zLOD#x9;*vFvdWs|d>NZ`Mn)7}K-2D*S
zME*)5h`MK&rBVny2ze4b-Rds`CUae3wFSI=ecVBi37ia{_9X$`wzVfKjeoXPs^+Kc!n;i1!26
zA`<~LJYj@y42SeBtp3-&M_Bm81;_vhutDByM$ixe>1+AxgU^etTRa+&nY8gSK9nFV
zvE%m76x250soo4>6YDub{@fXE$$6Js#E-OMJ1x0**F?^e?p6@IM)@uO4w{iu2Cm7Z
zCQklkk*1Ea8`kz)sb-It$EnACww!*66Vcb0$!A_jrEzp}L9R;61OyxOxd9b-Y$@I-
zAF8h_ZG7UF;fgfVejt~<>InIEyHe52-fM@#)Fjt12qKU-5uJ*
z6j-Jy(hHe)^D%cCW{NQ=o0_+-zf;S9l7a>>yR3cackc`@5CZh7RuG8$f+J+V@OH!+K$dW|Xf^n8IhY(28FQjzKhKv?y
ze6l{B5)tTJ?F2fh8%aR(uX%Y=Vwmm0|L!t?qb
z{rTWLU#p-QVdwifL^>0+dA|Cy0+8l;$K4(H3_+Aofuo9Cz_7a0eC+XS7VMi0hULa{
z`k;fkY?jIg;Ik@R8MsD1R(;QX#l$hH2=v02G=?LJP8APMYjgQqLv!*QYvGgx#F);KHR7v7iorV`*AdN
zN%-+a5@19pszp)hFGb=uz$S{&)ezk}-gX9g#<09oveKK$Z%;T2t!WrK0Evv+JX-j~Aj
zsW6n@A!HH4nuJ_l=~}bR+CerXU!<=A??#cf7^}%-SOp@SfA-ckPLDhY#Qn-5H2+;#
z$6nT{U`BWapW&(_<=C@`07VBXbnwcb1@WX|wwfiUET9Xq!1f)`S9U#S066}Mw6trZnJ;%&bBRIBNS|kMb>&4SDDpb>mFe|)6A@ul913}EBRz{^MT-)L>_a<<8ykGHdKa24#OxJD~jA&`h6*jiA
za=)ZuHl1q7_b=#tQeKc*p|*t=7*sJBE7eb-e+yW<6{5#V;yZEr+Q|KqM)#vFAPIj3
zWl(Bp=#bdDnPl4KxpWPyA|aJXt^hCZQwNdO&fYRM*yFB`#D**|V#W@^%mUa)lx&$T
z95tgfn8`bFuUT5Fj3mfqzf28}B7?uZklwK>0x}?Fk@65+YkVnigEZw~ng`xG$kG-F
zHN1eItXKnq?Y7qSNYgodUxbSIrg{R}rm}_I{t~_{6p{TZE->;Onb7zJBdBx}k@d2)
zAxBFgooMPIqHrnX?N0f4-#09D#+sU3*>Nu3V1(E_?P@7Bl)7(F*Uk?VW$R_mILna3
zfDbHleE?#>Hw4VsK&8y|4{t=K}1(|XNK{H@e>m_(=V*BCAA_EYiUOnyB{Ee
zX94I~(sEda1_rwznW8A}fTA~i1dkrSikNBK6gTVITA24*JlOCmRrIvE;R$r5T@&Rz
zd)I(%RrLZF=gVfYd?qv#%Jad%fH9a#wLVb>KPcw0>Ug;ewqch_QFKw9jZzZ6hoqZY
zT%+T5%+e}#+pEt@n{;gjGpzCM7w+kom~=ga>>n&hop5q;URpHLosQK{5$)ugI?f+e
zO3uCJl^wu*S+4n^=!33x!(n$Xv-l1#A+GiBswHoJ*VmDpmY@Omm!OUV{@>}{KR-ms
zOFtLucFElC4!3wx`~c;gL(n;EnYoNfYigjqHmS?GbulY@GX)Omq~=zGQwd
zlPN+Jydg0^MT

[PATCH-for-9.1 02/21] target/mips: Declare CPU QOM types using DEFINE_TYPES() macro

2024-03-15 Thread Philippe Mathieu-Daudé
When multiple QOM types are registered in the same file,
it is simpler to use the the DEFINE_TYPES() macro. In
particular because type array declared with such macro
are easier to review.

In few commits we are going to add more types, so replace
the type_register_static() to ease further reviews.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20231013140116.255-15-phi...@linaro.org>
---
 target/mips/cpu.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 8d8f690a53..c096d97fe3 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -594,17 +594,21 @@ static void mips_cpu_class_init(ObjectClass *c, void 
*data)
 #endif /* CONFIG_TCG */
 }
 
-static const TypeInfo mips_cpu_type_info = {
-.name = TYPE_MIPS_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(MIPSCPU),
-.instance_align = __alignof(MIPSCPU),
-.instance_init = mips_cpu_initfn,
-.abstract = true,
-.class_size = sizeof(MIPSCPUClass),
-.class_init = mips_cpu_class_init,
+static const TypeInfo mips_cpu_types[] = {
+{
+.name   = TYPE_MIPS_CPU,
+.parent = TYPE_CPU,
+.instance_size  = sizeof(MIPSCPU),
+.instance_align = __alignof(MIPSCPU),
+.instance_init  = mips_cpu_initfn,
+.abstract   = true,
+.class_size = sizeof(MIPSCPUClass),
+.class_init = mips_cpu_class_init,
+}
 };
 
+DEFINE_TYPES(mips_cpu_types)
+
 static void mips_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 {
 MIPSCPUClass *mcc = MIPS_CPU_CLASS(oc);
@@ -629,7 +633,6 @@ static void mips_cpu_register_types(void)
 {
 int i;
 
-type_register_static(&mips_cpu_type_info);
 for (i = 0; i < mips_defs_number; i++) {
 mips_register_cpudef_type(&mips_defs[i]);
 }
-- 
2.41.0




[PATCH 12/12] tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V

2024-03-15 Thread Sunil V L
Add basic ACPI table testing for RISC-V.

Signed-off-by: Sunil V L 
---
 tests/qtest/bios-tables-test.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index c492438ced..033acc8958 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1923,6 +1923,30 @@ static void test_acpi_microvm_acpi_erst(void)
 }
 #endif /* CONFIG_POSIX */
 
+static void test_acpi_riscv64_virt_tcg(void)
+{
+test_data data = {
+.machine = "virt",
+.arch = "riscv64",
+.tcg_only = true,
+.uefi_fl1 = "pc-bios/edk2-riscv-code.fd",
+.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
+.ram_start = 0x8000ULL,
+.scan_len = 128ULL * 1024 * 1024,
+};
+
+/*
+ * RHCT will have ISA string encoded. To reduce the effort
+ * of updating expected AML file for any new default ISA extension,
+ * use the profile rva22s64. Once profile is ratified, there may
+ * not be new extension possible.
+ */
+test_acpi_one("-cpu rva22s64 -device virtio-blk-device,drive=hd0 "
+  "-drive 
file=tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2,id=hd0",
+  &data);
+free_test_data(&data);
+}
+
 static void test_acpi_aarch64_virt_tcg(void)
 {
 test_data data = {
@@ -2342,6 +2366,10 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
 }
 }
+} else if (strcmp(arch, "riscv64") == 0) {
+if (has_tcg && qtest_has_device("virtio-blk-pci")) {
+qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg);
+}
 }
 ret = g_test_run();
 boot_sector_cleanup(disk);
-- 
2.40.1




[RFC PATCH-for-9.1 15/21] target/arm: Use QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/arm/arm-qmp-cmds.c | 25 ++---
 1 file changed, 2 insertions(+), 23 deletions(-)

diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 3cc8cc738b..c5091e64ec 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -28,6 +28,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qapi-commands-machine-target.h"
 #include "qapi/qapi-commands-misc-target.h"
+#include "qapi/commands-target-compat.h"
 #include "qapi/qmp/qdict.h"
 #include "qom/qom-qobject.h"
 
@@ -220,29 +221,7 @@ CpuModelExpansionInfo 
*qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 return expansion_info;
 }
 
-static void arm_cpu_add_definition(gpointer data, gpointer user_data)
-{
-ObjectClass *oc = data;
-CpuDefinitionInfoList **cpu_list = user_data;
-CpuDefinitionInfo *info;
-const char *typename;
-
-typename = object_class_get_name(oc);
-info = g_malloc0(sizeof(*info));
-info->name = cpu_model_from_type(typename);
-info->q_typename = g_strdup(typename);
-
-QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list;
-
-list = object_class_get_list(TYPE_ARM_CPU, false);
-g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
-g_slist_free(list);
-
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
-- 
2.41.0




[PATCH-for-9.1 04/21] target/sparc: Declare CPU QOM types using DEFINE_TYPES() macro

2024-03-15 Thread Philippe Mathieu-Daudé
When multiple QOM types are registered in the same file,
it is simpler to use the the DEFINE_TYPES() macro. In
particular because type array declared with such macro
are easier to review.

In few commits we are going to add more types, so replace
the type_register_static() to ease further reviews.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Mark Cave-Ayland 
Message-Id: <20231013140116.255-17-phi...@linaro.org>
---
 target/sparc/cpu.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index dc9ead21fc..42b13ab63f 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -949,17 +949,21 @@ static void sparc_cpu_class_init(ObjectClass *oc, void 
*data)
 cc->tcg_ops = &sparc_tcg_ops;
 }
 
-static const TypeInfo sparc_cpu_type_info = {
-.name = TYPE_SPARC_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(SPARCCPU),
-.instance_align = __alignof(SPARCCPU),
-.instance_init = sparc_cpu_initfn,
-.abstract = true,
-.class_size = sizeof(SPARCCPUClass),
-.class_init = sparc_cpu_class_init,
+static const TypeInfo sparc_cpu_types[] = {
+{
+.name   = TYPE_SPARC_CPU,
+.parent = TYPE_CPU,
+.instance_size  = sizeof(SPARCCPU),
+.instance_align = __alignof(SPARCCPU),
+.instance_init  = sparc_cpu_initfn,
+.abstract   = true,
+.class_size = sizeof(SPARCCPUClass),
+.class_init = sparc_cpu_class_init,
+}
 };
 
+DEFINE_TYPES(sparc_cpu_types)
+
 static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 {
 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
@@ -984,7 +988,6 @@ static void sparc_cpu_register_types(void)
 {
 int i;
 
-type_register_static(&sparc_cpu_type_info);
 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
 sparc_register_cpudef_type(&sparc_defs[i]);
 }
-- 
2.41.0




[PATCH 03/12] uefi-test-tools: Add support for python based build script

2024-03-15 Thread Sunil V L
edk2-funcs.sh which is used in this Makefile, was removed in the commit
c28a2891f3 ("edk2: update build script"). It is replaced with a python
based script. So, update the Makefile and add the configuration file as
required to support the python based build script.

Signed-off-by: Sunil V L 
---
 tests/uefi-test-tools/Makefile   | 18 +++
 tests/uefi-test-tools/uefi-test-build.config | 57 
 2 files changed, 63 insertions(+), 12 deletions(-)
 create mode 100644 tests/uefi-test-tools/uefi-test-build.config

diff --git a/tests/uefi-test-tools/Makefile b/tests/uefi-test-tools/Makefile
index 0c003f2877..f94738b645 100644
--- a/tests/uefi-test-tools/Makefile
+++ b/tests/uefi-test-tools/Makefile
@@ -12,7 +12,7 @@
 
 edk2_dir  := ../../roms/edk2
 images_dir:= ../data/uefi-boot-images
-emulation_targets := arm aarch64 i386 x86_64
+emulation_targets := arm aarch64 i386 x86_64 riscv64
 uefi_binaries := bios-tables-test
 intermediate_suffixes := .efi .fat .iso.raw
 
@@ -56,7 +56,8 @@ Build/%.iso.raw: Build/%.fat
 # stripped from, the argument.
 map_arm_to_uefi = $(subst arm,ARM,$(1))
 map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1)))
-map_i386_to_uefi= $(subst i386,IA32,$(call map_aarch64_to_uefi,$(1)))
+map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_aarch64_to_uefi,$(1)))
+map_i386_to_uefi= $(subst i386,IA32,$(call map_riscv64_to_uefi,$(1)))
 map_x86_64_to_uefi  = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1)))
 map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1)))
 
@@ -70,7 +71,7 @@ Build/%.fat: Build/%.efi
uefi_bin_b=$$(stat --format=%s -- $<) && \
uefi_fat_kb=$$(( (uefi_bin_b * 11 / 10 + 1023) / 1024 )) && \
uefi_fat_kb=$$(( uefi_fat_kb >= 64 ? uefi_fat_kb : 64 )) && \
-   mkdosfs -C $@ -n $(basename $(@F)) -- $$uefi_fat_kb
+   mkdosfs -C $@ -n "bios-test" -- $$uefi_fat_kb
MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI
MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI/BOOT
MTOOLS_SKIP_CHECK=1 mcopy -i $@ -- $< \
@@ -95,15 +96,8 @@ Build/%.fat: Build/%.efi
 # we must mark the recipe manually as recursive, by using the "+" indicator.
 # This way, when the inner "make" starts a parallel build of the target edk2
 # module, it can communicate with the outer "make"'s job server.
-Build/bios-tables-test.%.efi: build-edk2-tools
-   +./build.sh $(edk2_dir) BiosTablesTest $* $@
-
-build-edk2-tools:
-   cd $(edk2_dir)/BaseTools && git submodule update --init --force
-   $(MAKE) -C $(edk2_dir)/BaseTools \
-   PYTHON_COMMAND=$${EDK2_PYTHON_COMMAND:-python3} \
-   EXTRA_OPTFLAGS='$(EDK2_BASETOOLS_OPTFLAGS)' \
-   EXTRA_LDFLAGS='$(EDK2_BASETOOLS_LDFLAGS)'
+Build/bios-tables-test.%.efi:
+   $(PYTHON) ../../roms/edk2-build.py --config uefi-test-build.config
 
 clean:
rm -rf Build Conf log
diff --git a/tests/uefi-test-tools/uefi-test-build.config 
b/tests/uefi-test-tools/uefi-test-build.config
new file mode 100644
index 00..4fb89f7db9
--- /dev/null
+++ b/tests/uefi-test-tools/uefi-test-build.config
@@ -0,0 +1,57 @@
+[global]
+core = ../../roms/edk2
+
+
+# arm
+
+[build.arm]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
+dest = ./Build
+arch = ARM
+cpy1 = ARM/BiosTablesTest.efi  bios-tables-test.arm.efi
+
+
+# aarch64
+
+[build.aarch64]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
+dest = ./Build
+arch = AARCH64
+cpy1 = AARCH64/BiosTablesTest.efi  bios-tables-test.aarch64.efi
+
+
+# riscv64
+
+[build.riscv]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
+dest = ./Build
+arch = RISCV64
+cpy1 = RISCV64/BiosTablesTest.efi  bios-tables-test.riscv64.efi
+
+
+# ia32
+
+[build.ia32]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
+dest = ./Build
+arch = IA32
+cpy1 = IA32/BiosTablesTest.efi  bios-tables-test.i386.efi
+
+
+# x64
+
+[build.x64]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+module = UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
+dest = ./Build
+arch = X64
+cpy1 = X64/BiosTablesTest.efi  bios-tables-test.x86_64.efi
-- 
2.40.1




[PATCH 08/12] meson.build: Add RISC-V to the edk2-target list

2024-03-15 Thread Sunil V L
so that ACPI table test can be supported.

Signed-off-by: Sunil V L 
---
 meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index b8ded80cbe..bf50688593 100644
--- a/meson.build
+++ b/meson.build
@@ -93,7 +93,7 @@ else
   iasl = find_program(get_option('iasl'), required: true)
 endif
 
-edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 
'x86_64-softmmu' ]
+edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 
'x86_64-softmmu', 'riscv64-softmmu' ]
 unpack_edk2_blobs = false
 foreach target : edk2_targets
   if target in target_dirs
-- 
2.40.1




[PATCH-for-9.1 05/21] cpus: Open code OBJECT_DECLARE_TYPE() in OBJECT_DECLARE_CPU_TYPE()

2024-03-15 Thread Philippe Mathieu-Daudé
Since the OBJECT_DECLARE_CPU_TYPE() macro uses the abstract ArchCPU
type, when declaring multiple CPUs of the same ArchCPU type we get
an error related to the indirect G_DEFINE_AUTOPTR_CLEANUP_FUNC()
use within OBJECT_DECLARE_TYPE():

  target/mips/cpu-qom.h:31:1: error: redefinition of 
'glib_autoptr_clear_ArchCPU'
  OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU)
  ^
  include/hw/core/cpu.h:82:5: note: expanded from macro 
'OBJECT_DECLARE_CPU_TYPE'
  OBJECT_DECLARE_TYPE(ArchCPU, CpuClassType, CPU_MODULE_OBJ_NAME);
  ^
  include/qom/object.h:237:5: note: expanded from macro 'OBJECT_DECLARE_TYPE'
  G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
  ^
  /usr/include/glib-2.0/glib/gmacros.h:1371:3: note: expanded from macro 
'G_DEFINE_AUTOPTR_CLEANUP_FUNC'
_GLIB_DEFINE_AUTOPTR_CLEANUP_FUNCS(TypeName, TypeName, func)
^
  /usr/include/glib-2.0/glib/gmacros.h:1354:36: note: expanded from macro 
'_GLIB_DEFINE_AUTOPTR_CLEANUP_FUNCS'
static G_GNUC_UNUSED inline void _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) 
(TypeName *_ptr) \
 ^
  /usr/include/glib-2.0/glib/gmacros.h:1338:49: note: expanded from macro 
'_GLIB_AUTOPTR_CLEAR_FUNC_NAME'
  #define _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) glib_autoptr_clear_##TypeName
  ^
  :54:1: note: expanded from here
  glib_autoptr_clear_ArchCPU
  ^
  target/mips/cpu-qom.h:30:1: note: previous definition is here
  OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU)
  ^

Avoid that problem by expanding the OBJECT_DECLARE_TYPE() macro
within OBJECT_DECLARE_CPU_TYPE().

Signed-off-by: Philippe Mathieu-Daudé 
Acked-by: Richard Henderson 
---
TODO: check rth comment:
What about adding an OBJECT_DECLARE_CPU_SUBTYPE that omits half the stuff 
instead?
We don't need another object typedef at all, for instance.
---
 include/hw/core/cpu.h | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index ec14f74ce5..4c2e5095bf 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -78,7 +78,12 @@ DECLARE_CLASS_CHECKERS(CPUClass, CPU,
  */
 #define OBJECT_DECLARE_CPU_TYPE(CpuInstanceType, CpuClassType, 
CPU_MODULE_OBJ_NAME) \
 typedef struct ArchCPU CpuInstanceType; \
-OBJECT_DECLARE_TYPE(ArchCPU, CpuClassType, CPU_MODULE_OBJ_NAME);
+typedef struct CpuClassType CpuClassType; \
+\
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(CpuInstanceType, object_unref) \
+\
+DECLARE_OBJ_CHECKERS(CpuInstanceType, CpuClassType, \
+ CPU_MODULE_OBJ_NAME, TYPE_##CPU_MODULE_OBJ_NAME)
 
 typedef enum MMUAccessType {
 MMU_DATA_LOAD  = 0,
-- 
2.41.0




[PATCH 06/12] tests/qtest/bios-tables-test.c: Add support for arch in path

2024-03-15 Thread Sunil V L
Since virt machine is common for multiple architectures, add "arch" in
the path to search expected AML files. Since the AML files are still
under old path, support both by searching with and without arch in the
path.

Signed-off-by: Sunil V L 
---
 tests/qtest/bios-tables-test.c | 32 +---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index ea3ba1992b..c492438ced 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -78,6 +78,7 @@
 typedef struct {
 bool tcg_only;
 const char *machine;
+const char *arch;
 const char *machine_param;
 const char *variant;
 const char *uefi_fl1;
@@ -262,8 +263,20 @@ static void dump_aml_files(test_data *data, bool rebuild)
 g_assert(exp_sdt->aml);
 
 if (rebuild) {
-aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
+aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir,
+   data->machine, data->arch,
sdt->aml, ext);
+
+/*
+ * To keep test cases not failing when the DATA files are moved to
+ * ARCH under virt folder, add this check which can be removed once
+ * the DATA files are moved.
+ */
+if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
+aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, 
data->machine,
+   sdt->aml, ext);
+}
+
 if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) &&
 sdt->aml_len == exp_sdt->aml_len &&
 !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) {
@@ -398,8 +411,13 @@ static GArray *load_expected_aml(test_data *data)
 memset(&exp_sdt, 0, sizeof(exp_sdt));
 
 try_again:
-aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
-   sdt->aml, ext);
+aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, data->machine,
+   data->arch, sdt->aml, ext);
+if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
+aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
+   sdt->aml, ext);
+}
+exp_sdt.aml_file = aml_file;
 if (verbosity_level >= 2) {
 fprintf(stderr, "Looking for expected file '%s'\n", aml_file);
 }
@@ -1561,6 +1579,7 @@ static void test_acpi_aarch64_virt_tcg_memhp(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -1654,6 +1673,7 @@ static void test_acpi_aarch64_virt_tcg_numamem(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -1676,6 +1696,7 @@ static void test_acpi_aarch64_virt_tcg_pxb(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -1749,6 +1770,7 @@ static void test_acpi_aarch64_virt_tcg_acpi_hmat(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -1905,6 +1927,7 @@ static void test_acpi_aarch64_virt_tcg(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -1924,6 +1947,7 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .variant = ".topology",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
@@ -2007,6 +2031,7 @@ static void test_acpi_aarch64_virt_viot(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
@@ -2139,6 +2164,7 @@ static void test_acpi_aarch64_virt_oem_fields(void)
 {
 test_data data = {
 .machine = "virt",
+.arch = "aarch64",
 .tcg_only = true,
 .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
 .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
-- 
2.40.1




[RFC PATCH-for-9.1 21/21] qapi: Make @query-cpu-definitions target-agnostic

2024-03-15 Thread Philippe Mathieu-Daudé
All targets use the generic_query_cpu_definitions() method,
which is not target-specific. Make the command target agnostic
by moving it to machine.json. Rename generic_query_cpu_definitions
as qmp_query_cpu_definitions.

This is an introspection change for the target that were not
implementing qmp_query_cpu_definitions(): now query-cpu-definitions
returns an their CPUs list.

Example with SH4 before:

  { "execute": "query-cpu-definitions" }

  { "error": {"class": "CommandNotFound", "desc": "The command 
query-cpu-definitions has not been found"} }

and after:

  { "execute": "query-cpu-definitions" }

  { "return": [
  {"name": "sh7751r", "typename": "sh7751r-superh-cpu", "static": 
false, "deprecated": false},
  {"name": "sh7750r", "typename": "sh7750r-superh-cpu", "static": 
false, "deprecated": false},
  {"name": "sh7785", "typename": "sh7785-superh-cpu", "static": false, 
"deprecated": false}
  ]
  }

However this allows heterogeneous emulation to return a correct list.

Signed-off-by: Philippe Mathieu-Daudé 
---
Well, not all target got converted, I left the s390x one for later :)
---
 MAINTAINERS   |  1 -
 qapi/machine-target.json  | 18 --
 qapi/machine.json | 11 +++
 include/qapi/commands-target-compat.h | 14 --
 system/cpu-qmp-cmds.c |  4 ++--
 target/arm/arm-qmp-cmds.c |  6 --
 target/i386/cpu.c |  6 --
 target/loongarch/loongarch-qmp-cmds.c |  6 --
 target/mips/sysemu/mips-qmp-cmds.c|  9 -
 target/ppc/ppc-qmp-cmds.c |  7 ---
 target/riscv/riscv-qmp-cmds.c |  6 --
 11 files changed, 13 insertions(+), 75 deletions(-)
 delete mode 100644 include/qapi/commands-target-compat.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 39d7c14d98..71f446311b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1895,7 +1895,6 @@ F: qapi/machine-target.json
 F: include/hw/boards.h
 F: include/hw/core/cpu.h
 F: include/hw/cpu/cluster.h
-F: include/qapi/commands-target-compat.h
 F: include/sysemu/numa.h
 F: tests/unit/test-smp-parse.c
 T: git https://gitlab.com/ehabkost/qemu.git machine-next
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 7480921d33..2065972d8a 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -212,24 +212,6 @@
'TARGET_LOONGARCH64',
'TARGET_RISCV' ] } }
 
-##
-# @query-cpu-definitions:
-#
-# Return a list of supported virtual CPU definitions
-#
-# Returns: a list of CpuDefinitionInfo
-#
-# Since: 1.2
-##
-{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
-  'if': { 'any': [ 'TARGET_PPC',
-   'TARGET_ARM',
-   'TARGET_I386',
-   'TARGET_S390X',
-   'TARGET_MIPS',
-   'TARGET_LOONGARCH64',
-   'TARGET_RISCV' ] } }
-
 ##
 # @CpuS390Polarization:
 #
diff --git a/qapi/machine.json b/qapi/machine.json
index 9c44b8fa82..987c64f8e7 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -73,6 +73,17 @@
 'deprecated' : 'bool' }
 }
 
+##
+# @query-cpu-definitions:
+#
+# Return a list of supported virtual CPU definitions
+#
+# Returns: a list of CpuDefinitionInfo
+#
+# Since: 1.2
+##
+{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
+
 ##
 # @CpuModelInfo:
 #
diff --git a/include/qapi/commands-target-compat.h 
b/include/qapi/commands-target-compat.h
deleted file mode 100644
index 86d45d8fcc..00
--- a/include/qapi/commands-target-compat.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * QAPI helpers for target specific QMP commands
- *
- * SPDX-FileCopyrightText: 2024 Linaro Ltd.
- * SPDX-License-Identifier: GPL-2.0-or-later
- */
-#ifndef QAPI_COMPAT_TARGET_H
-#define QAPI_COMPAT_TARGET_H
-
-#include "qapi/qapi-types-machine.h"
-
-CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp);
-
-#endif
diff --git a/system/cpu-qmp-cmds.c b/system/cpu-qmp-cmds.c
index daeb131159..049e8b9d35 100644
--- a/system/cpu-qmp-cmds.c
+++ b/system/cpu-qmp-cmds.c
@@ -7,7 +7,7 @@
 
 #include "qemu/osdep.h"
 #include "qom/object.h"
-#include "qapi/commands-target-compat.h"
+#include "qapi/qapi-commands-machine.h"
 #include "sysemu/arch_init.h"
 #include "hw/core/cpu.h"
 #include "hw/core/sysemu-cpu-ops.h"
@@ -53,7 +53,7 @@ static void arch_add_cpu_definitions(CpuDefinitionInfoList 
**cpu_list,
 }
 }
 
-CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
 CpuDefinitionInfoList *cpu_list = NULL;
 
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index c5091e64ec..ac8d890bc0 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -28,7 +28,6 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qapi-commands-machine-target.h"
 #include "qapi/qapi-comm

[PATCH 11/12] tests/data/acpi/virt/riscv64: Add expected ACPI tables for RISC-V

2024-03-15 Thread Sunil V L
Add expected ACPI tables for RISC-V so that bios-table-test can be
enabled for RISC-V.

Signed-off-by: Sunil V L 
---
 tests/data/acpi/virt/riscv64/APIC | Bin 0 -> 116 bytes
 tests/data/acpi/virt/riscv64/BGRT | Bin 0 -> 56 bytes
 tests/data/acpi/virt/riscv64/DSDT | Bin 0 -> 3518 bytes
 tests/data/acpi/virt/riscv64/FACP | Bin 0 -> 276 bytes
 tests/data/acpi/virt/riscv64/MCFG | Bin 0 -> 60 bytes
 tests/data/acpi/virt/riscv64/RHCT | Bin 0 -> 314 bytes
 tests/data/acpi/virt/riscv64/RSDP | Bin 0 -> 36 bytes
 tests/data/acpi/virt/riscv64/SPCR | Bin 0 -> 80 bytes
 tests/data/acpi/virt/riscv64/XSDT | Bin 0 -> 84 bytes
 9 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 tests/data/acpi/virt/riscv64/APIC
 create mode 100755 tests/data/acpi/virt/riscv64/BGRT
 create mode 100755 tests/data/acpi/virt/riscv64/DSDT
 create mode 100755 tests/data/acpi/virt/riscv64/FACP
 create mode 100755 tests/data/acpi/virt/riscv64/MCFG
 create mode 100755 tests/data/acpi/virt/riscv64/RHCT
 create mode 100755 tests/data/acpi/virt/riscv64/RSDP
 create mode 100755 tests/data/acpi/virt/riscv64/SPCR
 create mode 100755 tests/data/acpi/virt/riscv64/XSDT

diff --git a/tests/data/acpi/virt/riscv64/APIC 
b/tests/data/acpi/virt/riscv64/APIC
new file mode 100755
index 
..66a25dfd2d6ea2b607c024722b2eab95873a01e9
GIT binary patch
literal 116
zcmZ<^@N_O=U|?X|;^gn_5v<@85#X!<1dKp25F13pfP@Mo12P{Zj?R|`s)2!c7=s}J
I#NvT*0o0BN0RR91

literal 0
HcmV?d1

diff --git a/tests/data/acpi/virt/riscv64/BGRT 
b/tests/data/acpi/virt/riscv64/BGRT
new file mode 100755
index 
..dccf14cce4063dbfe18cd8a459aaa8b206d3b3f0
GIT binary patch
literal 56
zcmZ>A4+^nhU|?XZ_Vf#J^-*wj@itNb0w$msh!zG)F#_2V3gY!3S{^7-3}gTR|5yhB

literal 0
HcmV?d1

diff --git a/tests/data/acpi/virt/riscv64/DSDT 
b/tests/data/acpi/virt/riscv64/DSDT
new file mode 100755
index 
..0fb2d5e0e389541209b765d5092d0706f40298f6
GIT binary patch
literal 3518
zcmZvf%WvaU6vnR;w@IBxlQexl(t(j!ppl%0(ryqeCJ*}oI`D?w!iChKA+$9t$orAn%(bn
zN+n)t?0eh6a^of6TgGN7rRbcFh1Tyc_k%{iceZVNuIr}z+pT7)qm0&dr&dmZB`a{a^Ra*0&D5Eo1b;X8Qm}E3gQYkTOF1_DRa)WNl^t#{A^TNmZNji{btZCtt5&QPNDqU;E!+b
zecnEQ^xc;~?0jvN=B?69B6sx0n@1-LMChb{iWO(USDtFAW3{YY{55g*p1P}!a8zWX
z7lz;IPVBzpJS=7G%wV8y2Q62ba|`EHRm#%1lYm%>L=vK=N;x|_7+?*WxKL3R0`umY
z&O>MhKe$y(1g;N2-TU8l!@sOMoiwl`i1tW@cj+o4-cu3BPCB-VhD+4MD9hIDroD&Pl#Oi8OIy2%-
zNlr-4iRFXLXr|LTGn$gLp$V}cX!M^n3=p)tt`$vN>NG_kr`M{qil6Owag1ZPHY
zW+W#h=gbPutl-Q_PDsv)?-Htwo@Y*Q<|HR1=gbSvyx`1BPDsup=eXpAX~8)yIHx5iBIp+lDoZy_3oRFMzUU1F}&UwiR$vGDU=Yrr|kera5b5U?E3eH8z3CTH^1m}|A
zT#}rSoU5@qiM`L8Qmx@>rXnqyVu6bqy3;0
zSfN$e$O$X-aop-gjFlN1TJ2C(VM8aZsGs9rPsDhcG3gaHcG3%d9rt=N#>h-rEXOMpLn!a_)bcQwbVUYCt>d6Z~go(OKwiV=x$e6rJOWm8FJLZ)jL(gSOQ9
z(=101Q%{N90rg{iGreXyIPiUy_PU*2Ro)uw?+2cJexkhQVfAu5b@3W?^1b$-wSOuL
z8($pWumAYmuXoN*92)^EIHqx|osu9QI;oM>2efl4w7)DozPM|Bh$~ecUA>%od=bT&
z;R0PerC=JrI{7MZ#_1;2tCR9A{Hkc%mp4o`zpVZISFrki`_c5@?b)Ba_T|{c>*}hQ
pv@F`;cR<_jYzAT_(hnb+|8pBtRxTSGr9{slF`>K_0A

literal 0
HcmV?d1

diff --git a/tests/data/acpi/virt/riscv64/FACP 
b/tests/data/acpi/virt/riscv64/FACP
new file mode 100755
index 
..a5276b65ea8ce46cc9b40d96d98f0669c9089ed4
GIT binary patch
literal 276
zcmZ>BbPf<`lE(^DK1@Wog4=(iq&1K
z7;1J`gewX|OE=3Z>{xM3wM)ljIQKa+635YaZ7jrOeGc+eJEnks*|jl=GEUBVQ8WhX
zK@GjINg;u`)Bd);9H

literal 0
HcmV?d1

diff --git a/tests/data/acpi/virt/riscv64/RSDP 
b/tests/data/acpi/virt/riscv64/RSDP
new file mode 100755
index 
..55054f8730c389d0d7eba90c24a1dae6d1283b90
GIT binary patch
literal 36
ncmWFvc2Nij2~zmyE!S15v<@85#X!<1dKp25F12;fdT`FDF9*%FmM4$c8~z`e;@#f
G!2kgKJqrN<

literal 0
HcmV?d1

diff --git a/tests/data/acpi/virt/riscv64/XSDT 
b/tests/data/acpi/virt/riscv64/XSDT
new file mode 100755
index 
..c69474889664d72d075419c0a1dcf1d82ec44268
GIT binary patch
literal 84
zcmazDb_oe#U|?VrcJg=j2v%^42yj*a0!E-1h!zG)F&y~+AIN23*Z`#$K

[RFC PATCH-for-9.1 14/21] system: Introduce QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Each target use a common template for qmp_query_cpu_definitions().

Extract it as generic_query_cpu_definitions(), keeping the
target-specific implementations as the following SysemuCPUOps
handlers:
 - cpu_list_compare()
 - add_definition()
 - add_alias_definitions()

Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS   |  2 +
 include/hw/core/sysemu-cpu-ops.h  | 14 ++
 include/qapi/commands-target-compat.h | 14 ++
 system/cpu-qmp-cmds.c | 71 +++
 system/meson.build|  1 +
 5 files changed, 102 insertions(+)
 create mode 100644 include/qapi/commands-target-compat.h
 create mode 100644 system/cpu-qmp-cmds.c

diff --git a/MAINTAINERS b/MAINTAINERS
index af27490243..39d7c14d98 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -148,6 +148,7 @@ M: Richard Henderson 
 R: Paolo Bonzini 
 S: Maintained
 F: system/cpus.c
+F: system/cpu-qmp-cmds.c
 F: system/cpu-qom-helpers.c
 F: system/watchpoint.c
 F: cpu-common.c
@@ -1894,6 +1895,7 @@ F: qapi/machine-target.json
 F: include/hw/boards.h
 F: include/hw/core/cpu.h
 F: include/hw/cpu/cluster.h
+F: include/qapi/commands-target-compat.h
 F: include/sysemu/numa.h
 F: tests/unit/test-smp-parse.c
 T: git https://gitlab.com/ehabkost/qemu.git machine-next
diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index 24d003fe04..2173226e97 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -11,6 +11,7 @@
 #define SYSEMU_CPU_OPS_H
 
 #include "hw/core/cpu.h"
+#include "qapi/qapi-types-machine.h"
 
 /*
  * struct SysemuCPUOps: System operations specific to a CPU class
@@ -81,6 +82,19 @@ typedef struct SysemuCPUOps {
  */
 bool (*virtio_is_big_endian)(CPUState *cpu);
 
+/**
+ * @cpu_list_compare: Sort alphabetically by type name,
+ *respecting CPUClass::ordering.
+ */
+gint (*cpu_list_compare)(gconstpointer cpu_class_a, gconstpointer 
cpu_class_b);
+/**
+ * @add_definition: Add the @cpu_class definition to @cpu_list.
+ */
+void (*add_definition)(gpointer cpu_class, gpointer cpu_list);
+/**
+ * @add_alias_definitions: Add CPU alias definitions to @cpu_list.
+ */
+void (*add_alias_definitions)(CpuDefinitionInfoList **cpu_list);
 /**
  * @legacy_vmsd: Legacy state for migration.
  *   Do not use in new targets, use #DeviceClass::vmsd instead.
diff --git a/include/qapi/commands-target-compat.h 
b/include/qapi/commands-target-compat.h
new file mode 100644
index 00..86d45d8fcc
--- /dev/null
+++ b/include/qapi/commands-target-compat.h
@@ -0,0 +1,14 @@
+/*
+ * QAPI helpers for target specific QMP commands
+ *
+ * SPDX-FileCopyrightText: 2024 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef QAPI_COMPAT_TARGET_H
+#define QAPI_COMPAT_TARGET_H
+
+#include "qapi/qapi-types-machine.h"
+
+CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp);
+
+#endif
diff --git a/system/cpu-qmp-cmds.c b/system/cpu-qmp-cmds.c
new file mode 100644
index 00..daeb131159
--- /dev/null
+++ b/system/cpu-qmp-cmds.c
@@ -0,0 +1,71 @@
+/*
+ * QAPI helpers for target specific QMP commands
+ *
+ * SPDX-FileCopyrightText: 2024 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "qapi/commands-target-compat.h"
+#include "sysemu/arch_init.h"
+#include "hw/core/cpu.h"
+#include "hw/core/sysemu-cpu-ops.h"
+
+static void cpu_common_add_definition(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CpuDefinitionInfoList **cpu_list = user_data;
+CpuDefinitionInfo *info;
+const char *typename;
+
+typename = object_class_get_name(oc);
+info = g_malloc0(sizeof(*info));
+info->name = cpu_model_from_type(typename);
+info->q_typename = g_strdup(typename);
+
+QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+static void arch_add_cpu_definitions(CpuDefinitionInfoList **cpu_list,
+ const char *cpu_typename)
+{
+ObjectClass *oc;
+GSList *list;
+const struct SysemuCPUOps *ops;
+
+oc = object_class_by_name(cpu_typename);
+if (!oc) {
+return;
+}
+ops = CPU_CLASS(oc)->sysemu_ops;
+
+list = object_class_get_list(cpu_typename, false);
+if (ops->cpu_list_compare) {
+list = g_slist_sort(list, ops->cpu_list_compare);
+}
+g_slist_foreach(list, ops->add_definition ? : cpu_common_add_definition,
+cpu_list);
+g_slist_free(list);
+
+if (ops->add_alias_definitions) {
+ops->add_alias_definitions(cpu_list);
+}
+}
+
+CpuDefinitionInfoList *generic_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+
+for (unsigned i = 0; i <= QEMU_ARCH_BIT_LAST; i++) {
+const char *cpu_typename;
+
+cpu_typename = cpu_typename_by_arch_bit(i);
+if (!cpu_typename

[RFC PATCH-for-9.1 18/21] target/i386: Use QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Register x86_cpu_definition_entry() and x86_cpu_list_compare()
as handler so we can use the QMP generic_query_cpu_definitions()
method.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/i386/cpu.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 07f64c1ea5..e5dbd307d8 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -38,6 +38,7 @@
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/reset.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "qapi/commands-target-compat.h"
 #include "exec/address-spaces.h"
 #include "hw/boards.h"
 #include "hw/i386/sgx-epc.h"
@@ -5667,11 +5668,7 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
 
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list = get_sorted_cpu_model_list();
-g_slist_foreach(list, x86_cpu_definition_entry, &cpu_list);
-g_slist_free(list);
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
 
 #endif /* !CONFIG_USER_ONLY */
@@ -7937,6 +7934,8 @@ static Property x86_cpu_properties[] = {
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps i386_sysemu_ops = {
+.add_definition = x86_cpu_definition_entry,
+.cpu_list_compare = x86_cpu_list_compare,
 .get_memory_mapping = x86_cpu_get_memory_mapping,
 .get_paging_enabled = x86_cpu_get_paging_enabled,
 .get_phys_page_attrs_debug = x86_cpu_get_phys_page_attrs_debug,
-- 
2.41.0




[PATCH-for-9.1 11/21] qapi: Make CpuDefinitionInfo target agnostic

2024-03-15 Thread Philippe Mathieu-Daudé
Generate the CpuDefinitionInfo type once for all targets.
In few commits @query-cpu-definitions will become generic
and all target will return their CPUs list.

Signed-off-by: Philippe Mathieu-Daudé 
---
 qapi/machine-target.json | 69 
 qapi/machine.json| 63 
 2 files changed, 63 insertions(+), 69 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 0412400df3..7480921d33 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -212,75 +212,6 @@
'TARGET_LOONGARCH64',
'TARGET_RISCV' ] } }
 
-##
-# @CpuDefinitionInfo:
-#
-# Virtual CPU definition.
-#
-# @name: the name of the CPU definition
-#
-# @migration-safe: whether a CPU definition can be safely used for
-# migration in combination with a QEMU compatibility machine when
-# migrating between different QEMU versions and between hosts with
-# different sets of (hardware or software) capabilities.  If not
-# provided, information is not available and callers should not
-# assume the CPU definition to be migration-safe.  (since 2.8)
-#
-# @static: whether a CPU definition is static and will not change
-# depending on QEMU version, machine type, machine options and
-# accelerator options.  A static model is always migration-safe.
-# (since 2.8)
-#
-# @unavailable-features: List of properties that prevent the CPU model
-# from running in the current host.  (since 2.8)
-#
-# @typename: Type name that can be used as argument to
-# @device-list-properties, to introspect properties configurable
-# using -cpu or -global.  (since 2.9)
-#
-# @alias-of: Name of CPU model this model is an alias for.  The target
-# of the CPU model alias may change depending on the machine type.
-# Management software is supposed to translate CPU model aliases
-# in the VM configuration, because aliases may stop being
-# migration-safe in the future (since 4.1)
-#
-# @deprecated: If true, this CPU model is deprecated and may be
-# removed in in some future version of QEMU according to the QEMU
-# deprecation policy.  (since 5.2)
-#
-# @unavailable-features is a list of QOM property names that represent
-# CPU model attributes that prevent the CPU from running.  If the QOM
-# property is read-only, that means there's no known way to make the
-# CPU model run in the current host.  Implementations that choose not
-# to provide specific information return the property name "type". If
-# the property is read-write, it means that it MAY be possible to run
-# the CPU model in the current host if that property is changed.
-# Management software can use it as hints to suggest or choose an
-# alternative for the user, or just to generate meaningful error
-# messages explaining why the CPU model can't be used.  If
-# @unavailable-features is an empty list, the CPU model is runnable
-# using the current host and machine-type.  If @unavailable-features
-# is not present, runnability information for the CPU is not
-# available.
-#
-# Since: 1.2
-##
-{ 'struct': 'CpuDefinitionInfo',
-  'data': { 'name': 'str',
-'*migration-safe': 'bool',
-'static': 'bool',
-'*unavailable-features': [ 'str' ],
-'typename': 'str',
-'*alias-of' : 'str',
-'deprecated' : 'bool' },
-  'if': { 'any': [ 'TARGET_PPC',
-   'TARGET_ARM',
-   'TARGET_I386',
-   'TARGET_S390X',
-   'TARGET_MIPS',
-   'TARGET_LOONGARCH64',
-   'TARGET_RISCV' ] } }
-
 ##
 # @query-cpu-definitions:
 #
diff --git a/qapi/machine.json b/qapi/machine.json
index 65702c2c78..9c44b8fa82 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -10,6 +10,69 @@
 
 { 'include': 'common.json' }
 
+##
+# @CpuDefinitionInfo:
+#
+# Virtual CPU definition.
+#
+# @name: the name of the CPU definition
+#
+# @migration-safe: whether a CPU definition can be safely used for
+# migration in combination with a QEMU compatibility machine when
+# migrating between different QEMU versions and between hosts with
+# different sets of (hardware or software) capabilities.  If not
+# provided, information is not available and callers should not
+# assume the CPU definition to be migration-safe.  (since 2.8)
+#
+# @static: whether a CPU definition is static and will not change
+# depending on QEMU version, machine type, machine options and
+# accelerator options.  A static model is always migration-safe.
+# (since 2.8)
+#
+# @unavailable-features: List of properties that prevent the CPU model
+# from running in the current host.  (since 2.8)
+#
+# @typename: Type name that can be used as argument to
+# @device-list-properties, to introspect properties configurable
+# using -cpu or -global.  (since 2.9)
+#
+# @alias-of: Name of CPU model 

[RFC PATCH-for-9.1 16/21] target/loongarch: Use QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/loongarch-qmp-cmds.c | 23 ++-
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/target/loongarch/loongarch-qmp-cmds.c 
b/target/loongarch/loongarch-qmp-cmds.c
index 8721a5eb13..ef5aedc1cd 100644
--- a/target/loongarch/loongarch-qmp-cmds.c
+++ b/target/loongarch/loongarch-qmp-cmds.c
@@ -9,34 +9,15 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "qapi/commands-target-compat.h"
 #include "cpu.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qom/qom-qobject.h"
 
-static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
-{
-ObjectClass *oc = data;
-CpuDefinitionInfoList **cpu_list = user_data;
-CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
-const char *typename = object_class_get_name(oc);
-
-info->name = cpu_model_from_type(typename);
-info->q_typename = g_strdup(typename);
-
-QAPI_LIST_PREPEND(*cpu_list, info);
-}
-
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list;
-
-list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
-g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
-g_slist_free(list);
-
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
 
 static const char *cpu_model_advertised_features[] = {
-- 
2.41.0




[PATCH-for-9.1 09/21] qapi: Merge machine-common.json with qapi/machine.json

2024-03-15 Thread Philippe Mathieu-Daudé
machine-common.json declares a single type, which isn't
restricted to a particular target. Move this type in
machine.json.

Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS  |  1 -
 qapi/machine-common.json | 21 -
 qapi/machine-target.json |  2 +-
 qapi/machine.json| 13 -
 qapi/qapi-schema.json|  1 -
 target/s390x/cpu.h   |  2 +-
 qapi/meson.build |  1 -
 7 files changed, 14 insertions(+), 27 deletions(-)
 delete mode 100644 qapi/machine-common.json

diff --git a/MAINTAINERS b/MAINTAINERS
index a3130f64fd..ed98814398 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1889,7 +1889,6 @@ F: hw/core/null-machine.c
 F: hw/core/numa.c
 F: hw/cpu/cluster.c
 F: qapi/machine.json
-F: qapi/machine-common.json
 F: qapi/machine-target.json
 F: include/hw/boards.h
 F: include/hw/core/cpu.h
diff --git a/qapi/machine-common.json b/qapi/machine-common.json
deleted file mode 100644
index fa6bd71d12..00
--- a/qapi/machine-common.json
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- Mode: Python -*-
-# vim: filetype=python
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or later.
-# See the COPYING file in the top-level directory.
-
-##
-# = Machines S390 data types
-##
-
-##
-# @CpuS390Entitlement:
-#
-# An enumeration of CPU entitlements that can be assumed by a virtual
-# S390 CPU
-#
-# Since: 8.2
-##
-{ 'enum': 'CpuS390Entitlement',
-  'prefix': 'S390_CPU_ENTITLEMENT',
-  'data': [ 'auto', 'low', 'medium', 'high' ] }
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 519adf3220..5f17b25d50 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -4,7 +4,7 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or later.
 # See the COPYING file in the top-level directory.
 
-{ 'include': 'machine-common.json' }
+{ 'include': 'machine.json' }
 
 ##
 # @CpuModelInfo:
diff --git a/qapi/machine.json b/qapi/machine.json
index bb5a178909..4bc38e86fd 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -9,7 +9,6 @@
 ##
 
 { 'include': 'common.json' }
-{ 'include': 'machine-common.json' }
 
 ##
 # @SysEmuTarget:
@@ -50,6 +49,18 @@
   'prefix': 'S390_CPU_STATE',
   'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] }
 
+##
+# @CpuS390Entitlement:
+#
+# An enumeration of CPU entitlements that can be assumed by a virtual
+# S390 CPU
+#
+# Since: 8.2
+##
+{ 'enum': 'CpuS390Entitlement',
+  'prefix': 'S390_CPU_ENTITLEMENT',
+  'data': [ 'auto', 'low', 'medium', 'high' ] }
+
 ##
 # @CpuInfoS390:
 #
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 8304d45625..2c82a49bae 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -67,7 +67,6 @@
 { 'include': 'introspect.json' }
 { 'include': 'qom.json' }
 { 'include': 'qdev.json' }
-{ 'include': 'machine-common.json' }
 { 'include': 'machine.json' }
 { 'include': 'machine-target.json' }
 { 'include': 'replay.json' }
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 43a46a5a06..b46339bd7c 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -29,7 +29,7 @@
 #include "cpu_models.h"
 #include "exec/cpu-defs.h"
 #include "qemu/cpu-float.h"
-#include "qapi/qapi-types-machine-common.h"
+#include "qapi/qapi-types-machine.h"
 
 #define ELF_MACHINE_UNAME "S390X"
 
diff --git a/qapi/meson.build b/qapi/meson.build
index 375d564277..90047dae1c 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -37,7 +37,6 @@ qapi_all_modules = [
   'error',
   'introspect',
   'job',
-  'machine-common',
   'machine',
   'machine-target',
   'migration',
-- 
2.41.0




[PATCH-for-9.1 19/21] target/ppc: Factor ppc_add_alias_definitions() out

2024-03-15 Thread Philippe Mathieu-Daudé
Factor ppc_add_alias_definitions() out of qmp_query_cpu_definitions()
to clearly see the generic pattern used in all targets.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/ppc/cpu-models.h   |  4 
 target/ppc/ppc-qmp-cmds.c | 26 +++---
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index 0229ef3a9a..89a5e232b7 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -21,6 +21,8 @@
 #ifndef TARGET_PPC_CPU_MODELS_H
 #define TARGET_PPC_CPU_MODELS_H
 
+#include "qapi/qapi-types-machine.h"
+
 /**
  * PowerPCCPUAlias:
  * @alias: The alias name.
@@ -480,4 +482,6 @@ enum {
 POWERPC_SVR_8641D  = 0x80900121,
 };
 
+void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list);
+
 #endif
diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c
index a25d86a8d1..528cc3e4af 100644
--- a/target/ppc/ppc-qmp-cmds.c
+++ b/target/ppc/ppc-qmp-cmds.c
@@ -189,17 +189,9 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer 
user_data)
 QAPI_LIST_PREPEND(*first, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list;
-int i;
-
-list = object_class_get_list(TYPE_POWERPC_CPU, false);
-g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
-g_slist_free(list);
-
-for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+for (unsigned i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
 ObjectClass *oc;
 CpuDefinitionInfo *info;
@@ -213,8 +205,20 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error 
**errp)
 info->name = g_strdup(alias->alias);
 info->q_typename = g_strdup(object_class_get_name(oc));
 
-QAPI_LIST_PREPEND(cpu_list, info);
+QAPI_LIST_PREPEND(*cpu_list, info);
 }
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+GSList *list;
+
+list = object_class_get_list(TYPE_POWERPC_CPU, false);
+g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
+g_slist_free(list);
+
+ppc_add_alias_definitions(&cpu_list);
 
 return cpu_list;
 }
-- 
2.41.0




[PATCH-for-9.1 13/21] system: Introduce cpu_typename_by_arch_bit()

2024-03-15 Thread Philippe Mathieu-Daudé
Introduce a helper to return the CPU type name given a QemuArchBit.

The TYPE_PPC_CPU target have different 32/64-bit definitions
so we can not include it yet.

Signed-off-by: Philippe Mathieu-Daudé 
---
---
 MAINTAINERS|  1 +
 include/sysemu/arch_init.h |  2 ++
 system/cpu-qom-helpers.c   | 58 ++
 system/meson.build |  1 +
 4 files changed, 62 insertions(+)
 create mode 100644 system/cpu-qom-helpers.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ed98814398..af27490243 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -148,6 +148,7 @@ M: Richard Henderson 
 R: Paolo Bonzini 
 S: Maintained
 F: system/cpus.c
+F: system/cpu-qom-helpers.c
 F: system/watchpoint.c
 F: cpu-common.c
 F: cpu-target.c
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index cf597c40a3..1874f18e67 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -27,6 +27,8 @@ typedef enum QemuArchBit {
 QEMU_ARCH_BIT_LAST  = QEMU_ARCH_BIT_LOONGARCH
 } QemuArchBit;
 
+const char *cpu_typename_by_arch_bit(QemuArchBit arch_bit);
+
 enum QemuArchMask {
 QEMU_ARCH_ALL = -1,
 QEMU_ARCH_ALPHA = (1 << QEMU_ARCH_BIT_ALPHA),
diff --git a/system/cpu-qom-helpers.c b/system/cpu-qom-helpers.c
new file mode 100644
index 00..0d402ee3a0
--- /dev/null
+++ b/system/cpu-qom-helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Helpers for CPU QOM types
+ *
+ * SPDX-FileCopyrightText: 2024 Linaro Ltd.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/arch_init.h"
+
+#include "target/alpha/cpu-qom.h"
+#include "target/arm/cpu-qom.h"
+#include "target/avr/cpu-qom.h"
+#include "target/cris/cpu-qom.h"
+#include "target/hexagon/cpu-qom.h"
+#include "target/hppa/cpu-qom.h"
+#include "target/i386/cpu-qom.h"
+#include "target/loongarch/cpu-qom.h"
+#include "target/m68k/cpu-qom.h"
+#include "target/microblaze/cpu-qom.h"
+#include "target/mips/cpu-qom.h"
+#include "target/nios2/cpu-qom.h"
+#include "target/openrisc/cpu-qom.h"
+#include "target/riscv/cpu-qom.h"
+#include "target/rx/cpu-qom.h"
+#include "target/s390x/cpu-qom.h"
+#include "target/sparc/cpu-qom.h"
+#include "target/sh4/cpu-qom.h"
+#include "target/tricore/cpu-qom.h"
+#include "target/xtensa/cpu-qom.h"
+
+const char *cpu_typename_by_arch_bit(QemuArchBit arch_bit)
+{
+static const char *cpu_bit_to_typename[QEMU_ARCH_BIT_LAST + 1] = {
+[QEMU_ARCH_BIT_ALPHA]   = TYPE_ALPHA_CPU,
+[QEMU_ARCH_BIT_ARM] = TYPE_ARM_CPU,
+[QEMU_ARCH_BIT_CRIS]= TYPE_CRIS_CPU,
+[QEMU_ARCH_BIT_I386]= TYPE_I386_CPU,
+[QEMU_ARCH_BIT_M68K]= TYPE_M68K_CPU,
+[QEMU_ARCH_BIT_MICROBLAZE]  = TYPE_MICROBLAZE_CPU,
+[QEMU_ARCH_BIT_MIPS]= TYPE_MIPS_CPU,
+/* TODO:  TYPE_PPC_CPU */
+[QEMU_ARCH_BIT_S390X]   = TYPE_S390_CPU,
+[QEMU_ARCH_BIT_SH4] = TYPE_SUPERH_CPU,
+[QEMU_ARCH_BIT_SPARC]   = TYPE_SPARC_CPU,
+[QEMU_ARCH_BIT_XTENSA]  = TYPE_XTENSA_CPU,
+[QEMU_ARCH_BIT_OPENRISC]= TYPE_OPENRISC_CPU,
+[QEMU_ARCH_BIT_TRICORE] = TYPE_TRICORE_CPU,
+[QEMU_ARCH_BIT_NIOS2]   = TYPE_NIOS2_CPU,
+[QEMU_ARCH_BIT_HPPA]= TYPE_HPPA_CPU,
+[QEMU_ARCH_BIT_RISCV]   = TYPE_RISCV_CPU,
+[QEMU_ARCH_BIT_RX]  = TYPE_RX_CPU,
+[QEMU_ARCH_BIT_AVR] = TYPE_AVR_CPU,
+[QEMU_ARCH_BIT_HEXAGON] = TYPE_HEXAGON_CPU,
+[QEMU_ARCH_BIT_LOONGARCH]   = TYPE_LOONGARCH_CPU,
+};
+return cpu_bit_to_typename[arch_bit];
+}
diff --git a/system/meson.build b/system/meson.build
index 25e2117250..c6ee97e3b2 100644
--- a/system/meson.build
+++ b/system/meson.build
@@ -10,6 +10,7 @@ system_ss.add(files(
   'balloon.c',
   'bootdevice.c',
   'cpus.c',
+  'cpu-qom-helpers.c',
   'cpu-throttle.c',
   'cpu-timers.c',
   'datadir.c',
-- 
2.41.0




[PATCH 09/12] pc-bios/meson.build: Add support for RISC-V in unpack_edk2_blobs

2024-03-15 Thread Sunil V L
Update list of images supported in unpack_edk2_blobs to enable RISC-V
ACPI table testing.

Signed-off-by: Sunil V L 
---
 pc-bios/meson.build | 2 ++
 tests/qtest/meson.build | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index 0760612bea..8602b45b9b 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -4,6 +4,8 @@ if unpack_edk2_blobs
 'edk2-aarch64-code.fd',
 'edk2-arm-code.fd',
 'edk2-arm-vars.fd',
+'edk2-riscv-code.fd',
+'edk2-riscv-vars.fd',
 'edk2-i386-code.fd',
 'edk2-i386-secure-code.fd',
 'edk2-i386-vars.fd',
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 36c5c13a7b..dd19711d9f 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -252,6 +252,9 @@ qtests_s390x = \
 qtests_riscv32 = \
   (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? 
['sifive-e-aon-watchdog-test'] : [])
 
+qtests_riscv64 = \
+  (unpack_edk2_blobs ? ['bios-tables-test'] : [])
+
 qos_test_ss = ss.source_set()
 qos_test_ss.add(
   'ac97-test.c',
-- 
2.40.1




[PATCH 10/12] tests/data/acpi/rebuild-expected-aml.sh: Add RISC-V

2024-03-15 Thread Sunil V L
Update the list of supported architectures to include RISC-V.

Signed-off-by: Sunil V L 
---
 tests/data/acpi/rebuild-expected-aml.sh | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/data/acpi/rebuild-expected-aml.sh 
b/tests/data/acpi/rebuild-expected-aml.sh
index dcf2e2f221..c1092fb8ba 100755
--- a/tests/data/acpi/rebuild-expected-aml.sh
+++ b/tests/data/acpi/rebuild-expected-aml.sh
@@ -12,7 +12,7 @@
 # This work is licensed under the terms of the GNU GPLv2.
 # See the COPYING.LIB file in the top-level directory.
 
-qemu_arches="x86_64 aarch64"
+qemu_arches="x86_64 aarch64 riscv64"
 
 if [ ! -e "tests/qtest/bios-tables-test" ]; then
 echo "Test: bios-tables-test is required! Run make check before this 
script."
@@ -36,7 +36,8 @@ fi
 if [ -z "$qemu_bins" ]; then
 echo "Only the following architectures are currently supported: 
$qemu_arches"
 echo "None of these configured!"
-echo "To fix, run configure --target-list=x86_64-softmmu,aarch64-softmmu"
+echo "To fix, run configure \
+ --target-list=x86_64-softmmu,aarch64-softmmu,riscv64-softmmu"
 exit 1;
 fi
 
-- 
2.40.1




[PATCH-for-9.1 10/21] qapi: Make CpuModel* definitions target agnostic

2024-03-15 Thread Philippe Mathieu-Daudé
CpuModelInfo, CpuModelExpansionType and CpuModelCompareResult
are not restricted to any particular target. Define them in
machine.json to generate them once.

Signed-off-by: Philippe Mathieu-Daudé 
---
 qapi/machine-target.json | 78 ---
 qapi/machine.json| 79 
 2 files changed, 79 insertions(+), 78 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 5f17b25d50..0412400df3 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -6,84 +6,6 @@
 
 { 'include': 'machine.json' }
 
-##
-# @CpuModelInfo:
-#
-# Virtual CPU model.
-#
-# A CPU model consists of the name of a CPU definition, to which delta
-# changes are applied (e.g. features added/removed). Most magic values
-# that an architecture might require should be hidden behind the name.
-# However, if required, architectures can expose relevant properties.
-#
-# @name: the name of the CPU definition the model is based on
-#
-# @props: a dictionary of QOM properties to be applied
-#
-# Since: 2.8
-##
-{ 'struct': 'CpuModelInfo',
-  'data': { 'name': 'str',
-'*props': 'any' } }
-
-##
-# @CpuModelExpansionType:
-#
-# An enumeration of CPU model expansion types.
-#
-# @static: Expand to a static CPU model, a combination of a static
-# base model name and property delta changes.  As the static base
-# model will never change, the expanded CPU model will be the
-# same, independent of QEMU version, machine type, machine
-# options, and accelerator options.  Therefore, the resulting
-# model can be used by tooling without having to specify a
-# compatibility machine - e.g. when displaying the "host" model.
-# The @static CPU models are migration-safe.
-#
-# @full: Expand all properties.  The produced model is not guaranteed
-# to be migration-safe, but allows tooling to get an insight and
-# work with model details.
-#
-# Note: When a non-migration-safe CPU model is expanded in static
-# mode, some features enabled by the CPU model may be omitted,
-# because they can't be implemented by a static CPU model
-# definition (e.g. cache info passthrough and PMU passthrough in
-# x86). If you need an accurate representation of the features
-# enabled by a non-migration-safe CPU model, use @full.  If you
-# need a static representation that will keep ABI compatibility
-# even when changing QEMU version or machine-type, use @static
-# (but keep in mind that some features may be omitted).
-#
-# Since: 2.8
-##
-{ 'enum': 'CpuModelExpansionType',
-  'data': [ 'static', 'full' ] }
-
-##
-# @CpuModelCompareResult:
-#
-# An enumeration of CPU model comparison results.  The result is
-# usually calculated using e.g. CPU features or CPU generations.
-#
-# @incompatible: If model A is incompatible to model B, model A is not
-# guaranteed to run where model B runs and the other way around.
-#
-# @identical: If model A is identical to model B, model A is
-# guaranteed to run where model B runs and the other way around.
-#
-# @superset: If model A is a superset of model B, model B is
-# guaranteed to run where model A runs.  There are no guarantees
-# about the other way.
-#
-# @subset: If model A is a subset of model B, model A is guaranteed to
-# run where model B runs.  There are no guarantees about the other
-# way.
-#
-# Since: 2.8
-##
-{ 'enum': 'CpuModelCompareResult',
-  'data': [ 'incompatible', 'identical', 'superset', 'subset' ] }
-
 ##
 # @CpuModelBaselineInfo:
 #
diff --git a/qapi/machine.json b/qapi/machine.json
index 4bc38e86fd..65702c2c78 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -10,6 +10,85 @@
 
 { 'include': 'common.json' }
 
+##
+# @CpuModelInfo:
+#
+# Virtual CPU model.
+#
+# A CPU model consists of the name of a CPU definition, to which delta
+# changes are applied (e.g. features added/removed). Most magic values
+# that an architecture might require should be hidden behind the name.
+# However, if required, architectures can expose relevant properties.
+#
+# @name: the name of the CPU definition the model is based on
+#
+# @props: a dictionary of QOM properties to be applied
+#
+# Since: 2.8
+##
+{ 'struct': 'CpuModelInfo',
+  'data': { 'name': 'str',
+'*props': 'any' }
+}
+
+##
+# @CpuModelExpansionType:
+#
+# An enumeration of CPU model expansion types.
+#
+# @static: Expand to a static CPU model, a combination of a static
+# base model name and property delta changes.  As the static base
+# model will never change, the expanded CPU model will be the
+# same, independent of QEMU version, machine type, machine
+# options, and accelerator options.  Therefore, the resulting
+# model can be used by tooling without having to specify a
+# compatibility machine - e.g. when displaying the "host" model.
+# The @static CPU models are migration-safe.
+#
+# @full: Expand all propertie

[PATCH 05/12] qtest: bios-tables-test: Rename aarch64 tests with aarch64 in them

2024-03-15 Thread Sunil V L
Existing AARCH64 virt test functions do not have AARCH64 in their name.
To add RISC-V virt related test cases, better to rename existing
functions to indicate they are ARM only.

Signed-off-by: Sunil V L 
---
 tests/qtest/bios-tables-test.c | 35 ++
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 21811a1ab5..ea3ba1992b 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1557,7 +1557,7 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
 test_acpi_tcg_dimm_pxm(MACHINE_PC);
 }
 
-static void test_acpi_virt_tcg_memhp(void)
+static void test_acpi_aarch64_virt_tcg_memhp(void)
 {
 test_data data = {
 .machine = "virt",
@@ -1650,7 +1650,7 @@ static void test_acpi_microvm_ioapic2_tcg(void)
 free_test_data(&data);
 }
 
-static void test_acpi_virt_tcg_numamem(void)
+static void test_acpi_aarch64_virt_tcg_numamem(void)
 {
 test_data data = {
 .machine = "virt",
@@ -1672,7 +1672,7 @@ static void test_acpi_virt_tcg_numamem(void)
 
 }
 
-static void test_acpi_virt_tcg_pxb(void)
+static void test_acpi_aarch64_virt_tcg_pxb(void)
 {
 test_data data = {
 .machine = "virt",
@@ -1745,7 +1745,7 @@ static void test_acpi_piix4_tcg_acpi_hmat(void)
 test_acpi_tcg_acpi_hmat(MACHINE_PC);
 }
 
-static void test_acpi_virt_tcg_acpi_hmat(void)
+static void test_acpi_aarch64_virt_tcg_acpi_hmat(void)
 {
 test_data data = {
 .machine = "virt",
@@ -1901,7 +1901,7 @@ static void test_acpi_microvm_acpi_erst(void)
 }
 #endif /* CONFIG_POSIX */
 
-static void test_acpi_virt_tcg(void)
+static void test_acpi_aarch64_virt_tcg(void)
 {
 test_data data = {
 .machine = "virt",
@@ -1920,7 +1920,7 @@ static void test_acpi_virt_tcg(void)
 free_test_data(&data);
 }
 
-static void test_acpi_virt_tcg_topology(void)
+static void test_acpi_aarch64_virt_tcg_topology(void)
 {
 test_data data = {
 .machine = "virt",
@@ -2003,7 +2003,7 @@ static void test_acpi_q35_cxl(void)
 }
 #endif /* CONFIG_POSIX */
 
-static void test_acpi_virt_viot(void)
+static void test_acpi_aarch64_virt_viot(void)
 {
 test_data data = {
 .machine = "virt",
@@ -2135,7 +2135,7 @@ static void test_acpi_microvm_oem_fields(void)
 g_free(args);
 }
 
-static void test_acpi_virt_oem_fields(void)
+static void test_acpi_aarch64_virt_oem_fields(void)
 {
 test_data data = {
 .machine = "virt",
@@ -2301,16 +2301,19 @@ int main(int argc, char *argv[])
 }
 } else if (strcmp(arch, "aarch64") == 0) {
 if (has_tcg && qtest_has_device("virtio-blk-pci")) {
-qtest_add_func("acpi/virt", test_acpi_virt_tcg);
+qtest_add_func("acpi/virt", test_acpi_aarch64_virt_tcg);
 qtest_add_func("acpi/virt/acpihmatvirt",
-test_acpi_virt_tcg_acpi_hmat);
-qtest_add_func("acpi/virt/topology", test_acpi_virt_tcg_topology);
-qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);
-qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
-qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
-qtest_add_func("acpi/virt/oem-fields", test_acpi_virt_oem_fields);
+   test_acpi_aarch64_virt_tcg_acpi_hmat);
+qtest_add_func("acpi/virt/topology",
+   test_acpi_aarch64_virt_tcg_topology);
+qtest_add_func("acpi/virt/numamem",
+   test_acpi_aarch64_virt_tcg_numamem);
+qtest_add_func("acpi/virt/memhp", 
test_acpi_aarch64_virt_tcg_memhp);
+qtest_add_func("acpi/virt/pxb", test_acpi_aarch64_virt_tcg_pxb);
+qtest_add_func("acpi/virt/oem-fields",
+   test_acpi_aarch64_virt_oem_fields);
 if (qtest_has_device("virtio-iommu-pci")) {
-qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
+qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
 }
 }
 }
-- 
2.40.1




[RFC PATCH-for-9.1 20/21] target/ppc: Use QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Register ppc_add_alias_definitions() as handler so we can
use the QMP generic_query_cpu_definitions() method.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/ppc/cpu_init.c |  1 +
 target/ppc/ppc-qmp-cmds.c | 26 ++
 2 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index d5e227a6fb..3b500c95a4 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7348,6 +7348,7 @@ static Property ppc_cpu_properties[] = {
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps ppc_sysemu_ops = {
+.add_alias_definitions = ppc_add_alias_definitions,
 .get_phys_page_debug = ppc_cpu_get_phys_page_debug,
 .write_elf32_note = ppc32_cpu_write_elf32_note,
 .write_elf64_note = ppc64_cpu_write_elf64_note,
diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c
index 528cc3e4af..267dd84718 100644
--- a/target/ppc/ppc-qmp-cmds.c
+++ b/target/ppc/ppc-qmp-cmds.c
@@ -29,6 +29,7 @@
 #include "monitor/hmp-target.h"
 #include "monitor/hmp.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "qapi/commands-target-compat.h"
 #include "cpu-models.h"
 #include "cpu-qom.h"
 
@@ -175,20 +176,6 @@ int target_get_monitor_def(CPUState *cs, const char *name, 
uint64_t *pval)
 return -EINVAL;
 }
 
-static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
-{
-ObjectClass *oc = data;
-CpuDefinitionInfoList **first = user_data;
-const char *typename;
-CpuDefinitionInfo *info;
-
-typename = object_class_get_name(oc);
-info = g_malloc0(sizeof(*info));
-info->name = cpu_model_from_type(typename);
-
-QAPI_LIST_PREPEND(*first, info);
-}
-
 void ppc_add_alias_definitions(CpuDefinitionInfoList **cpu_list)
 {
 for (unsigned i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
@@ -211,14 +198,5 @@ void ppc_add_alias_definitions(CpuDefinitionInfoList 
**cpu_list)
 
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list;
-
-list = object_class_get_list(TYPE_POWERPC_CPU, false);
-g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
-g_slist_free(list);
-
-ppc_add_alias_definitions(&cpu_list);
-
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
-- 
2.41.0




[PATCH-for-9.1 12/21] system: Introduce QemuArchBit enum

2024-03-15 Thread Philippe Mathieu-Daudé
Current QEMU_ARCH_foo definitions are used as masks.
Extract the bit values, so we can easily iterate over.

Signed-off-by: Philippe Mathieu-Daudé 
---
 include/sysemu/arch_init.h | 69 ++
 1 file changed, 47 insertions(+), 22 deletions(-)

diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 8850cb1a14..cf597c40a3 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -1,30 +1,55 @@
 #ifndef QEMU_ARCH_INIT_H
 #define QEMU_ARCH_INIT_H
 
+typedef enum QemuArchBit {
+QEMU_ARCH_BIT_ALPHA = 0,
+QEMU_ARCH_BIT_ARM   = 1,
+QEMU_ARCH_BIT_CRIS  = 2,
+QEMU_ARCH_BIT_I386  = 3,
+QEMU_ARCH_BIT_M68K  = 4,
+QEMU_ARCH_BIT_MICROBLAZE= 6,
+QEMU_ARCH_BIT_MIPS  = 7,
+QEMU_ARCH_BIT_PPC   = 8,
+QEMU_ARCH_BIT_S390X = 9,
+QEMU_ARCH_BIT_SH4   = 10,
+QEMU_ARCH_BIT_SPARC = 11,
+QEMU_ARCH_BIT_XTENSA= 12,
+QEMU_ARCH_BIT_OPENRISC  = 13,
+QEMU_ARCH_BIT_TRICORE   = 16,
+QEMU_ARCH_BIT_NIOS2 = 17,
+QEMU_ARCH_BIT_HPPA  = 18,
+QEMU_ARCH_BIT_RISCV = 19,
+QEMU_ARCH_BIT_RX= 20,
+QEMU_ARCH_BIT_AVR   = 21,
+QEMU_ARCH_BIT_HEXAGON   = 22,
+QEMU_ARCH_BIT_LOONGARCH = 23,
 
-enum {
+QEMU_ARCH_BIT_LAST  = QEMU_ARCH_BIT_LOONGARCH
+} QemuArchBit;
+
+enum QemuArchMask {
 QEMU_ARCH_ALL = -1,
-QEMU_ARCH_ALPHA = (1 << 0),
-QEMU_ARCH_ARM = (1 << 1),
-QEMU_ARCH_CRIS = (1 << 2),
-QEMU_ARCH_I386 = (1 << 3),
-QEMU_ARCH_M68K = (1 << 4),
-QEMU_ARCH_MICROBLAZE = (1 << 6),
-QEMU_ARCH_MIPS = (1 << 7),
-QEMU_ARCH_PPC = (1 << 8),
-QEMU_ARCH_S390X = (1 << 9),
-QEMU_ARCH_SH4 = (1 << 10),
-QEMU_ARCH_SPARC = (1 << 11),
-QEMU_ARCH_XTENSA = (1 << 12),
-QEMU_ARCH_OPENRISC = (1 << 13),
-QEMU_ARCH_TRICORE = (1 << 16),
-QEMU_ARCH_NIOS2 = (1 << 17),
-QEMU_ARCH_HPPA = (1 << 18),
-QEMU_ARCH_RISCV = (1 << 19),
-QEMU_ARCH_RX = (1 << 20),
-QEMU_ARCH_AVR = (1 << 21),
-QEMU_ARCH_HEXAGON = (1 << 22),
-QEMU_ARCH_LOONGARCH = (1 << 23),
+QEMU_ARCH_ALPHA = (1 << QEMU_ARCH_BIT_ALPHA),
+QEMU_ARCH_ARM   = (1 << QEMU_ARCH_BIT_ARM),
+QEMU_ARCH_CRIS  = (1 << QEMU_ARCH_BIT_CRIS),
+QEMU_ARCH_I386  = (1 << QEMU_ARCH_BIT_I386),
+QEMU_ARCH_M68K  = (1 << QEMU_ARCH_BIT_M68K),
+QEMU_ARCH_MICROBLAZE= (1 << QEMU_ARCH_BIT_MICROBLAZE),
+QEMU_ARCH_MIPS  = (1 << QEMU_ARCH_BIT_MIPS),
+QEMU_ARCH_PPC   = (1 << QEMU_ARCH_BIT_PPC),
+QEMU_ARCH_S390X = (1 << QEMU_ARCH_BIT_S390X),
+QEMU_ARCH_SH4   = (1 << QEMU_ARCH_BIT_SH4),
+QEMU_ARCH_SPARC = (1 << QEMU_ARCH_BIT_SPARC),
+QEMU_ARCH_XTENSA= (1 << QEMU_ARCH_BIT_XTENSA),
+QEMU_ARCH_OPENRISC  = (1 << QEMU_ARCH_BIT_OPENRISC),
+QEMU_ARCH_TRICORE   = (1 << QEMU_ARCH_BIT_TRICORE),
+QEMU_ARCH_NIOS2 = (1 << QEMU_ARCH_BIT_NIOS2),
+QEMU_ARCH_HPPA  = (1 << QEMU_ARCH_BIT_HPPA),
+QEMU_ARCH_RISCV = (1 << QEMU_ARCH_BIT_RISCV),
+QEMU_ARCH_RX= (1 << QEMU_ARCH_BIT_RX),
+QEMU_ARCH_AVR   = (1 << QEMU_ARCH_BIT_AVR),
+QEMU_ARCH_HEXAGON   = (1 << QEMU_ARCH_BIT_HEXAGON),
+QEMU_ARCH_LOONGARCH = (1 << QEMU_ARCH_BIT_LOONGARCH),
 };
 
 extern const uint32_t arch_type;
-- 
2.41.0




[RFC PATCH-for-9.1 00/21] qapi: Make @query-cpu-definitions command target-agnostic

2024-03-15 Thread Philippe Mathieu-Daudé
Hi Alex, Markus,

Markus mentioned QAPI problems with the heterogeneous emulation
binary. My understanding is, while QAPI can use host-specific
conditional (OS, library available, configure option), it
shouldn't use target-specific ones.

This series is an example on how to remove target specific
bits from the @query-cpu-definitions command. Target specific
code is registered as CPUClass handlers, then a generic method
is used, iterating over all targets built in.

The first set of patches were already posted / reviewed last
year.

The PPC and S390X targets still need work (help welcomed),
however the code is useful enough to be tested and see if this
is a good approach.

The only drawback is a change in QAPI introspection, because
targets not implementing @query-cpu-definitions were returning
"CommandNotFound". My view is this was an incomplete
implementation, rather than a feature.

Regards,

Phil.

Philippe Mathieu-Daudé (21):
  target/i386: Declare CPU QOM types using DEFINE_TYPES() macro
  target/mips: Declare CPU QOM types using DEFINE_TYPES() macro
  target/ppc: Declare CPU QOM types using DEFINE_TYPES() macro
  target/sparc: Declare CPU QOM types using DEFINE_TYPES() macro
  cpus: Open code OBJECT_DECLARE_TYPE() in OBJECT_DECLARE_CPU_TYPE()
  target/i386: Make X86_CPU common to new I386_CPU / X86_64_CPU types
  target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types
  target/sparc: Make SPARC_CPU common to new SPARC32_CPU/SPARC64_CPU
types
  qapi: Merge machine-common.json with qapi/machine.json
  qapi: Make CpuModel* definitions target agnostic
  qapi: Make CpuDefinitionInfo target agnostic
  system: Introduce QemuArchBit enum
  system: Introduce cpu_typename_by_arch_bit()
  system: Introduce QMP generic_query_cpu_definitions()
  target/arm: Use QMP generic_query_cpu_definitions()
  target/loongarch: Use QMP generic_query_cpu_definitions()
  target/riscv: Use QMP generic_query_cpu_definitions()
  target/i386: Use QMP generic_query_cpu_definitions()
  target/ppc: Factor ppc_add_alias_definitions() out
  target/ppc: Use QMP generic_query_cpu_definitions()
  qapi: Make @query-cpu-definitions target-agnostic

 MAINTAINERS   |   3 +-
 qapi/machine-common.json  |  21 
 qapi/machine-target.json  | 167 +-
 qapi/machine.json | 166 -
 qapi/qapi-schema.json |   1 -
 include/hw/core/cpu.h |   7 +-
 include/hw/core/sysemu-cpu-ops.h  |  14 +++
 include/sysemu/arch_init.h|  71 +++
 target/i386/cpu-qom.h |  16 ++-
 target/mips/cpu-qom.h |  13 +-
 target/ppc/cpu-models.h   |   4 +
 target/riscv/cpu.h|   2 +
 target/s390x/cpu.h|   2 +-
 target/sparc/cpu-qom.h|   9 +-
 system/cpu-qmp-cmds.c |  71 +++
 system/cpu-qom-helpers.c  |  58 +
 target/arm/arm-qmp-cmds.c |  27 -
 target/i386/cpu.c |  77 ++--
 target/loongarch/loongarch-qmp-cmds.c |  25 
 target/mips/cpu.c |  34 --
 target/mips/sysemu/mips-qmp-cmds.c|  31 -
 target/ppc/cpu_init.c |  53 
 target/ppc/ppc-qmp-cmds.c |  31 +
 target/riscv/cpu.c|   1 +
 target/riscv/riscv-qmp-cmds.c |  13 +-
 target/sparc/cpu.c|  35 --
 tests/qtest/cpu-plug-test.c   |   2 +-
 qapi/meson.build  |   1 -
 system/meson.build|   2 +
 29 files changed, 515 insertions(+), 442 deletions(-)
 delete mode 100644 qapi/machine-common.json
 create mode 100644 system/cpu-qmp-cmds.c
 create mode 100644 system/cpu-qom-helpers.c

-- 
2.41.0




Re: [PATCH v4 10/25] migration: Add Error** argument to qemu_savevm_state_setup()

2024-03-15 Thread Peter Xu
On Fri, Mar 15, 2024 at 01:20:49PM +0100, Cédric Le Goater wrote:
> +static void qemu_savevm_wait_unplug(MigrationState *s, int state)

One more trivial comment: I'd even consider dropping "state" altogether, as
this should be the only state this function should be invoked.  So we can
perhaps assert it instead of passing it over?

-- 
Peter Xu




[PATCH 07/12] tests/data/acpi/virt: Move ACPI tables under aarch64

2024-03-15 Thread Sunil V L
Since virt is a common machine name across architectures like ARM64 and
RISC-V, move existing ARM64 ACPI tables under aarch64 folder so that
RISC-V tables can be added under riscv64 folder in future.

Signed-off-by: Sunil V L 
---
 tests/data/acpi/virt/{ => aarch64}/APIC | Bin
 .../data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt  | Bin
 tests/data/acpi/virt/{ => aarch64}/APIC.topology| Bin
 tests/data/acpi/virt/{ => aarch64}/DBG2 | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT | Bin
 .../data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt  | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT.memhp   | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT.pxb | Bin
 tests/data/acpi/virt/{ => aarch64}/DSDT.topology| Bin
 tests/data/acpi/virt/{ => aarch64}/FACP | Bin
 tests/data/acpi/virt/{ => aarch64}/GTDT | Bin
 .../data/acpi/virt/{ => aarch64}/HMAT.acpihmatvirt  | Bin
 tests/data/acpi/virt/{ => aarch64}/IORT | Bin
 tests/data/acpi/virt/{ => aarch64}/MCFG | Bin
 tests/data/acpi/virt/{ => aarch64}/NFIT.memhp   | Bin
 tests/data/acpi/virt/{ => aarch64}/PPTT | Bin
 .../data/acpi/virt/{ => aarch64}/PPTT.acpihmatvirt  | Bin
 tests/data/acpi/virt/{ => aarch64}/PPTT.topology| Bin
 tests/data/acpi/virt/{ => aarch64}/SLIT.memhp   | Bin
 tests/data/acpi/virt/{ => aarch64}/SPCR | Bin
 .../data/acpi/virt/{ => aarch64}/SRAT.acpihmatvirt  | Bin
 tests/data/acpi/virt/{ => aarch64}/SRAT.memhp   | Bin
 tests/data/acpi/virt/{ => aarch64}/SRAT.numamem | Bin
 tests/data/acpi/virt/{ => aarch64}/SSDT.memhp   | Bin
 tests/data/acpi/virt/{ => aarch64}/VIOT | Bin
 25 files changed, 0 insertions(+), 0 deletions(-)
 rename tests/data/acpi/virt/{ => aarch64}/APIC (100%)
 rename tests/data/acpi/virt/{ => aarch64}/APIC.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/APIC.topology (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DBG2 (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.pxb (100%)
 rename tests/data/acpi/virt/{ => aarch64}/DSDT.topology (100%)
 rename tests/data/acpi/virt/{ => aarch64}/FACP (100%)
 rename tests/data/acpi/virt/{ => aarch64}/GTDT (100%)
 rename tests/data/acpi/virt/{ => aarch64}/HMAT.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/IORT (100%)
 rename tests/data/acpi/virt/{ => aarch64}/MCFG (100%)
 rename tests/data/acpi/virt/{ => aarch64}/NFIT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/PPTT (100%)
 rename tests/data/acpi/virt/{ => aarch64}/PPTT.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/PPTT.topology (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SLIT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SPCR (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SRAT.acpihmatvirt (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SRAT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SRAT.numamem (100%)
 rename tests/data/acpi/virt/{ => aarch64}/SSDT.memhp (100%)
 rename tests/data/acpi/virt/{ => aarch64}/VIOT (100%)

diff --git a/tests/data/acpi/virt/APIC b/tests/data/acpi/virt/aarch64/APIC
similarity index 100%
rename from tests/data/acpi/virt/APIC
rename to tests/data/acpi/virt/aarch64/APIC
diff --git a/tests/data/acpi/virt/APIC.acpihmatvirt 
b/tests/data/acpi/virt/aarch64/APIC.acpihmatvirt
similarity index 100%
rename from tests/data/acpi/virt/APIC.acpihmatvirt
rename to tests/data/acpi/virt/aarch64/APIC.acpihmatvirt
diff --git a/tests/data/acpi/virt/APIC.topology 
b/tests/data/acpi/virt/aarch64/APIC.topology
similarity index 100%
rename from tests/data/acpi/virt/APIC.topology
rename to tests/data/acpi/virt/aarch64/APIC.topology
diff --git a/tests/data/acpi/virt/DBG2 b/tests/data/acpi/virt/aarch64/DBG2
similarity index 100%
rename from tests/data/acpi/virt/DBG2
rename to tests/data/acpi/virt/aarch64/DBG2
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/aarch64/DSDT
similarity index 100%
rename from tests/data/acpi/virt/DSDT
rename to tests/data/acpi/virt/aarch64/DSDT
diff --git a/tests/data/acpi/virt/DSDT.acpihmatvirt 
b/tests/data/acpi/virt/aarch64/DSDT.acpihmatvirt
similarity index 100%
rename from tests/data/acpi/virt/DSDT.acpihmatvirt
rename to tests/data/acpi/virt/aarch64/DSDT.acpihmatvirt
diff --git a/tests/data/acpi/virt/DSDT.memhp 
b/tests/data/acpi/virt/aarch64/DSDT.memhp
similarity index 100%
rename from tests/data/acpi/virt/DSDT.memhp
rename to tests/data/acpi/virt/aarch64/DSDT.memhp
diff --git a/tests/data/acpi/virt/DSDT.pxb 
b/tests/data/acpi/virt/aarch64/DSDT.pxb
similarity index 100%
rename from tests/data/acpi/virt/DSDT.pxb
rename to tests/data/acpi/virt/aarch64/DSDT.pxb
diff --git a/tests/data/acpi/virt/DSDT.topology 
b/tests/data/acpi/virt/aarch64/DSDT.topology
similarity index 100%

[PATCH-for-9.1 08/21] target/sparc: Make SPARC_CPU common to new SPARC32_CPU/SPARC64_CPU types

2024-03-15 Thread Philippe Mathieu-Daudé
"target/foo/cpu-qom.h" can not use any target specific definitions.

Currently "target/sparc/cpu-qom.h" defines TYPE_SPARC_CPU
depending on the sparc(32)/sparc64 build type. This doesn't
scale in a heterogeneous context where we need to access both
types concurrently.

In order to do that, introduce the new SPARC32_CPU / SPARC64_CPU
types, both inheriting a common TYPE_SPARC_CPU base type.

Keep the current CPU types registered in sparc_register_cpudef_type()
as 32 or 64-bit, depending on the binary built.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Mark Cave-Ayland 
---
 target/sparc/cpu-qom.h |  9 +
 target/sparc/cpu.c | 12 +++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/target/sparc/cpu-qom.h b/target/sparc/cpu-qom.h
index a86331bd58..6ad283506e 100644
--- a/target/sparc/cpu-qom.h
+++ b/target/sparc/cpu-qom.h
@@ -22,14 +22,15 @@
 
 #include "hw/core/cpu.h"
 
-#ifdef TARGET_SPARC64
-#define TYPE_SPARC_CPU "sparc64-cpu"
-#else
 #define TYPE_SPARC_CPU "sparc-cpu"
-#endif
+#define TYPE_SPARC32_CPU "sparc32-cpu"
+#define TYPE_SPARC64_CPU "sparc64-cpu"
 
 OBJECT_DECLARE_CPU_TYPE(SPARCCPU, SPARCCPUClass, SPARC_CPU)
 
+OBJECT_DECLARE_CPU_TYPE(SPARC32CPU, SPARCCPUClass, SPARC32_CPU)
+OBJECT_DECLARE_CPU_TYPE(SPARC64CPU, SPARCCPUClass, SPARC64_CPU)
+
 #define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU
 #define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX
 
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 42b13ab63f..9e27e16b75 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -959,6 +959,12 @@ static const TypeInfo sparc_cpu_types[] = {
 .abstract   = true,
 .class_size = sizeof(SPARCCPUClass),
 .class_init = sparc_cpu_class_init,
+}, {
+.name   = TYPE_SPARC32_CPU,
+.parent = TYPE_SPARC_CPU,
+}, {
+.name   = TYPE_SPARC64_CPU,
+.parent = TYPE_SPARC_CPU,
 }
 };
 
@@ -975,7 +981,11 @@ static void sparc_register_cpudef_type(const struct 
sparc_def_t *def)
 char *typename = sparc_cpu_type_name(def->name);
 TypeInfo ti = {
 .name = typename,
-.parent = TYPE_SPARC_CPU,
+#ifdef TARGET_SPARC64
+.parent = TYPE_SPARC64_CPU,
+#else
+.parent = TYPE_SPARC32_CPU,
+#endif
 .class_init = sparc_cpu_cpudef_class_init,
 .class_data = (void *)def,
 };
-- 
2.41.0




[RFC PATCH-for-9.1 17/21] target/riscv: Use QMP generic_query_cpu_definitions()

2024-03-15 Thread Philippe Mathieu-Daudé
Expose riscv_cpu_add_definition() and use it as add_definition()
handler, then use the QMP generic_query_cpu_definitions() method.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu.c|  1 +
 target/riscv/riscv-qmp-cmds.c | 11 +++
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..15fc287680 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -824,4 +824,6 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 uint8_t satp_mode_max_from_map(uint32_t map);
 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
 
+void riscv_cpu_add_definition(gpointer data, gpointer user_data);
+
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c160b9216b..2da9364335 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2341,6 +2341,7 @@ static int64_t riscv_get_arch_id(CPUState *cs)
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps riscv_sysemu_ops = {
+.add_definition = riscv_cpu_add_definition,
 .get_phys_page_debug = riscv_cpu_get_phys_page_debug,
 .write_elf64_note = riscv_cpu_write_elf64_note,
 .write_elf32_note = riscv_cpu_write_elf32_note,
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index d363dc318d..45adc90d3b 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -26,6 +26,7 @@
 
 #include "qapi/error.h"
 #include "qapi/qapi-commands-machine-target.h"
+#include "qapi/commands-target-compat.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qobject-input-visitor.h"
@@ -36,7 +37,7 @@
 #include "cpu-qom.h"
 #include "cpu.h"
 
-static void riscv_cpu_add_definition(gpointer data, gpointer user_data)
+void riscv_cpu_add_definition(gpointer data, gpointer user_data)
 {
 ObjectClass *oc = data;
 CpuDefinitionInfoList **cpu_list = user_data;
@@ -55,13 +56,7 @@ static void riscv_cpu_add_definition(gpointer data, gpointer 
user_data)
 
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list = object_class_get_list(TYPE_RISCV_CPU, false);
-
-g_slist_foreach(list, riscv_cpu_add_definition, &cpu_list);
-g_slist_free(list);
-
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
 
 static void riscv_check_if_cpu_available(RISCVCPU *cpu, Error **errp)
-- 
2.41.0




[PATCH-for-9.1 06/21] target/i386: Make X86_CPU common to new I386_CPU / X86_64_CPU types

2024-03-15 Thread Philippe Mathieu-Daudé
"target/foo/cpu-qom.h" can not use any target specific definitions.

Currently "target/i386/cpu-qom.h" defines TYPE_X86_CPU depending
on the i386/x86_64 build type. This doesn't scale in a heterogeneous
context where we need to access both types concurrently.

In order to do that, introduce the new I386_CPU / X86_64_CPU
types, both inheriting a common TYPE_X86_CPU base type.

Keep the current "base" and "max" CPU types as 32 or 64-bit,
depending on the binary built.

Adapt the cpu-plug-test, since the 'base' architecture is now
common to both 32/64-bit x86 targets.

Signed-off-by: Philippe Mathieu-Daudé 
Acked-by: Richard Henderson 
---
 target/i386/cpu-qom.h   | 16 ++--
 target/i386/cpu.c   | 20 ++--
 tests/qtest/cpu-plug-test.c |  2 +-
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h
index d4e216d000..de28d7ea20 100644
--- a/target/i386/cpu-qom.h
+++ b/target/i386/cpu-qom.h
@@ -1,5 +1,5 @@
 /*
- * QEMU x86 CPU
+ * QEMU x86 CPU QOM header (target agnostic)
  *
  * Copyright (c) 2012 SUSE LINUX Products GmbH
  *
@@ -22,14 +22,18 @@
 
 #include "hw/core/cpu.h"
 
-#ifdef TARGET_X86_64
-#define TYPE_X86_CPU "x86_64-cpu"
-#else
-#define TYPE_X86_CPU "i386-cpu"
-#endif
+#define TYPE_X86_CPU"x86-cpu"
+#define TYPE_I386_CPU   "i386-cpu"
+#define TYPE_X86_64_CPU "x86_64-cpu"
 
 OBJECT_DECLARE_CPU_TYPE(X86CPU, X86CPUClass, X86_CPU)
 
+OBJECT_DECLARE_CPU_TYPE(I386CPU, X86CPUClass, I386_CPU)
+OBJECT_DECLARE_CPU_TYPE(X86_64CPU, X86CPUClass, X86_64_CPU)
+
+#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
+#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
+
 #define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
 #define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ebf555f50f..07f64c1ea5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8057,12 +8057,28 @@ static const TypeInfo x86_cpu_types[] = {
 .class_size = sizeof(X86CPUClass),
 .class_init = x86_cpu_common_class_init,
 }, {
-.name   = X86_CPU_TYPE_NAME("base"),
+.name   = TYPE_I386_CPU,
 .parent = TYPE_X86_CPU,
+.abstract   = true,
+}, {
+.name   = TYPE_X86_64_CPU,
+.parent = TYPE_X86_CPU,
+.abstract   = true,
+}, {
+.name   = X86_CPU_TYPE_NAME("base"),
+#ifdef TARGET_X86_64
+.parent = TYPE_X86_64_CPU,
+#else
+.parent = TYPE_I386_CPU,
+#endif
 .class_init = x86_cpu_base_class_init,
 }, {
 .name   = X86_CPU_TYPE_NAME("max"),
-.parent = TYPE_X86_CPU,
+#ifdef TARGET_X86_64
+.parent = TYPE_X86_64_CPU,
+#else
+.parent = TYPE_I386_CPU,
+#endif
 .instance_init  = max_x86_cpu_initfn,
 .class_init = max_x86_cpu_class_init,
 }
diff --git a/tests/qtest/cpu-plug-test.c b/tests/qtest/cpu-plug-test.c
index 7f5dd5f85a..97316d131f 100644
--- a/tests/qtest/cpu-plug-test.c
+++ b/tests/qtest/cpu-plug-test.c
@@ -90,7 +90,7 @@ static void add_pc_test_case(const char *mname)
 data->machine = g_strdup(mname);
 data->cpu_model = "Haswell"; /* 1.3+ theoretically */
 data->device_model = g_strdup_printf("%s-%s-cpu", data->cpu_model,
- qtest_get_arch());
+ qtest_get_base_arch());
 data->sockets = 1;
 data->cores = 3;
 data->threads = 2;
-- 
2.41.0




[PATCH-for-9.1 07/21] target/mips: Make MIPS_CPU common to new MIPS32_CPU / MIPS64_CPU types

2024-03-15 Thread Philippe Mathieu-Daudé
"target/foo/cpu-qom.h" can not use any target specific definitions.

Currently "target/mips/cpu-qom.h" defines TYPE_MIPS_CPU depending
on the mips(32)/mips64 build type. This doesn't scale in a
heterogeneous context where we need to access both types concurrently.

In order to do that, introduce the new MIPS32_CPU / MIPS64_CPU types,
both inheriting a common TYPE_MIPS_CPU base type.

Keep the current CPU types registered in mips_register_cpudef_type()
as 32 or 64-bit, but instead of depending on the binary built being
targeting 32/64-bit, check whether the CPU is 64-bit by looking at
the CPU_MIPS64 bit.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu-qom.h  | 13 +++--
 target/mips/cpu.c  | 11 ++-
 target/mips/sysemu/mips-qmp-cmds.c | 26 ++
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/target/mips/cpu-qom.h b/target/mips/cpu-qom.h
index 0eea2a2598..bf464f16b6 100644
--- a/target/mips/cpu-qom.h
+++ b/target/mips/cpu-qom.h
@@ -1,5 +1,5 @@
 /*
- * QEMU MIPS CPU
+ * QEMU MIPS CPU QOM header (target agnostic)
  *
  * Copyright (c) 2012 SUSE LINUX Products GmbH
  *
@@ -22,14 +22,15 @@
 
 #include "hw/core/cpu.h"
 
-#ifdef TARGET_MIPS64
-#define TYPE_MIPS_CPU "mips64-cpu"
-#else
-#define TYPE_MIPS_CPU "mips-cpu"
-#endif
+#define TYPE_MIPS_CPU   "mips-cpu"
+#define TYPE_MIPS32_CPU "mips32-cpu"
+#define TYPE_MIPS64_CPU "mips64-cpu"
 
 OBJECT_DECLARE_CPU_TYPE(MIPSCPU, MIPSCPUClass, MIPS_CPU)
 
+OBJECT_DECLARE_CPU_TYPE(MIPS32CPU, MIPSCPUClass, MIPS32_CPU)
+OBJECT_DECLARE_CPU_TYPE(MIPS64CPU, MIPSCPUClass, MIPS64_CPU)
+
 #define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU
 #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX
 
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index c096d97fe3..f3ea6175f2 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -604,6 +604,14 @@ static const TypeInfo mips_cpu_types[] = {
 .abstract   = true,
 .class_size = sizeof(MIPSCPUClass),
 .class_init = mips_cpu_class_init,
+}, {
+.name   = TYPE_MIPS32_CPU,
+.parent = TYPE_MIPS_CPU,
+.abstract   = true,
+}, {
+.name   = TYPE_MIPS64_CPU,
+.parent = TYPE_MIPS_CPU,
+.abstract   = true,
 }
 };
 
@@ -620,7 +628,8 @@ static void mips_register_cpudef_type(const struct 
mips_def_t *def)
 char *typename = mips_cpu_type_name(def->name);
 TypeInfo ti = {
 .name = typename,
-.parent = TYPE_MIPS_CPU,
+.parent = def->insn_flags & CPU_MIPS64
+  ? TYPE_MIPS64_CPU : TYPE_MIPS32_CPU,
 .class_init = mips_cpu_cpudef_class_init,
 .class_data = (void *)def,
 };
diff --git a/target/mips/sysemu/mips-qmp-cmds.c 
b/target/mips/sysemu/mips-qmp-cmds.c
index 7340ac70ba..329db3a028 100644
--- a/target/mips/sysemu/mips-qmp-cmds.c
+++ b/target/mips/sysemu/mips-qmp-cmds.c
@@ -8,31 +8,9 @@
 
 #include "qemu/osdep.h"
 #include "qapi/qapi-commands-machine-target.h"
-#include "cpu.h"
-
-static void mips_cpu_add_definition(gpointer data, gpointer user_data)
-{
-ObjectClass *oc = data;
-CpuDefinitionInfoList **cpu_list = user_data;
-CpuDefinitionInfo *info;
-const char *typename;
-
-typename = object_class_get_name(oc);
-info = g_malloc0(sizeof(*info));
-info->name = cpu_model_from_type(typename);
-info->q_typename = g_strdup(typename);
-
-QAPI_LIST_PREPEND(*cpu_list, info);
-}
+#include "qapi/commands-target-compat.h"
 
 CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 {
-CpuDefinitionInfoList *cpu_list = NULL;
-GSList *list;
-
-list = object_class_get_list(TYPE_MIPS_CPU, false);
-g_slist_foreach(list, mips_cpu_add_definition, &cpu_list);
-g_slist_free(list);
-
-return cpu_list;
+return generic_query_cpu_definitions(errp);
 }
-- 
2.41.0




[PATCH-for-9.1 03/21] target/ppc: Declare CPU QOM types using DEFINE_TYPES() macro

2024-03-15 Thread Philippe Mathieu-Daudé
When multiple QOM types are registered in the same file,
it is simpler to use the the DEFINE_TYPES() macro. In
particular because type array declared with such macro
are easier to review.

In few commits we are going to add more types, so replace
the type_register_static() to ease further reviews.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20231013140116.255-16-phi...@linaro.org>
---
 target/ppc/cpu_init.c | 52 +++
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 7e65f08147..d5e227a6fb 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7432,39 +7432,34 @@ static void ppc_cpu_class_init(ObjectClass *oc, void 
*data)
 #endif /* CONFIG_TCG */
 }
 
-static const TypeInfo ppc_cpu_type_info = {
-.name = TYPE_POWERPC_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(PowerPCCPU),
-.instance_align = __alignof__(PowerPCCPU),
-.instance_init = ppc_cpu_instance_init,
-.instance_finalize = ppc_cpu_instance_finalize,
-.abstract = true,
-.class_size = sizeof(PowerPCCPUClass),
-.class_init = ppc_cpu_class_init,
+static const TypeInfo ppc_cpu_types[] = {
+{
+.name   = TYPE_POWERPC_CPU,
+.parent = TYPE_CPU,
+.abstract   = true,
+.instance_size  = sizeof(PowerPCCPU),
+.instance_align = __alignof__(PowerPCCPU),
+.instance_init  = ppc_cpu_instance_init,
+.instance_finalize = ppc_cpu_instance_finalize,
+.class_size = sizeof(PowerPCCPUClass),
+.class_init = ppc_cpu_class_init,
 #ifndef CONFIG_USER_ONLY
-.interfaces = (InterfaceInfo[]) {
-  { TYPE_INTERRUPT_STATS_PROVIDER },
-  { }
+.interfaces = (InterfaceInfo[]) {
+  { TYPE_INTERRUPT_STATS_PROVIDER },
+  { }
+},
+#endif
+},
+#ifndef CONFIG_USER_ONLY
+{
+.name   = TYPE_PPC_VIRTUAL_HYPERVISOR,
+.parent = TYPE_INTERFACE,
+.class_size = sizeof(PPCVirtualHypervisorClass),
 },
 #endif
 };
 
-#ifndef CONFIG_USER_ONLY
-static const TypeInfo ppc_vhyp_type_info = {
-.name = TYPE_PPC_VIRTUAL_HYPERVISOR,
-.parent = TYPE_INTERFACE,
-.class_size = sizeof(PPCVirtualHypervisorClass),
-};
-#endif
-
-static void ppc_cpu_register_types(void)
-{
-type_register_static(&ppc_cpu_type_info);
-#ifndef CONFIG_USER_ONLY
-type_register_static(&ppc_vhyp_type_info);
-#endif
-}
+DEFINE_TYPES(ppc_cpu_types)
 
 void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 {
@@ -7658,4 +7653,3 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 #undef RGPL
 #undef RFPL
 }
-type_init(ppc_cpu_register_types)
-- 
2.41.0




  1   2   3   >