Re: [PATCH] target/riscv: rvzicbo: Fixup CBO extension register calculation

2024-05-14 Thread Richard Henderson

On 5/14/24 04:39, Alistair Francis wrote:

When running the instruction

```
 cbo.flush 0(x0)
```

QEMU would segfault.

The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
allocated.

In order to fix this let's use the existing get_address()
helper. This also has the benefit of performing pointer mask
calculations on the address specified in rs1.

The pointer masking specificiation specifically states:

"""
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
"""

So this is the correct behaviour and we previously have been incorrectly
not masking the address.

Signed-off-by: Alistair Francis
Reported-by: Fabian Thomas
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
---
  target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 
  1 file changed, 12 insertions(+), 4 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 0/3] Assorted fixes for PMU

2024-05-14 Thread Atish Kumar Patra
On Mon, May 13, 2024 at 11:29 PM Alistair Francis  wrote:
>
> On Tue, Apr 30, 2024 at 5:29 AM Atish Patra  wrote:
> >
> > This series contains few miscallenous fixes related to hpmcounters
> > and related code. The first patch fixes an issue with cycle/instret
> > counters overcouting while the remaining two are more for specification
> > compliance.
> >
> > Signed-off-by: Atish Patra 
> > ---
> > Atish Patra (3):
> >   target/riscv: Save counter values during countinhibit update
> >   target/riscv: Enforce WARL behavior for scounteren/hcounteren
> >   target/riscv: Fix the predicate functions for mhpmeventhX CSRs
>
> Thanks!
>
> Applied to riscv-to-apply.next
>

Hi Alistair,
Thanks for your review. But the patch 1 had some comments about
vmstate which needs updating.
We also found a few more fixes that I was planning to include in v2.

I can send a separate fixes series on top riscv-to-apply.next or this
series can be dropped for the time being.
You can queue it v2 later. Let me know what you prefer.


> Alistair
>
> >
> >  target/riscv/cpu.h |   1 -
> >  target/riscv/csr.c | 111 
> > ++---
> >  target/riscv/machine.c |   1 -
> >  3 files changed, 68 insertions(+), 45 deletions(-)
> > ---
> > base-commit: 1642f979a71a5667a05070be2df82f48bd43ad7a
> > change-id: 20240428-countinhibit_fix-c6a1c11f4375
> > --
> > Regards,
> > Atish patra
> >
> >



RE: [PATCH ats_vtd v1 03/24] intel_iommu: check if the input address is canonical

2024-05-14 Thread Duan, Zhenzhong
Hi Clement,

>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 03/24] intel_iommu: check if the input address
>is canonical
>
>First stage translation must fail if the address to translate is
>not canonical.
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/i386/intel_iommu.c  | 22 ++
> hw/i386/intel_iommu_internal.h |  2 ++
> 2 files changed, 24 insertions(+)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index 80cdf37870..240ecb8f72 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -1912,6 +1912,7 @@ static const bool vtd_qualified_faults[] = {
> [VTD_FR_PASID_ENTRY_P] = true,
> [VTD_FR_PASID_TABLE_ENTRY_INV] = true,
> [VTD_FR_SM_INTERRUPT_ADDR] = true,
>+[VTD_FR_FS_NON_CANONICAL] = true,
> [VTD_FR_MAX] = false,
> };
>
>@@ -2023,6 +2024,21 @@ static inline uint64_t
>vtd_get_flpte_addr(uint64_t flpte, uint8_t aw)
> return flpte & VTD_FL_PT_BASE_ADDR_MASK(aw);
> }
>
>+/* Return true if IOVA is canonical, otherwise false. */
>+static bool vtd_iova_fl_check_canonical(IntelIOMMUState *s,
>+uint64_t iova, VTDContextEntry *ce,
>+uint8_t aw, uint32_t pasid)
>+{
>+uint64_t iova_limit = vtd_iova_limit(s, ce, aw, pasid);

According to spec:

"Input-address in the request subjected to first-stage translation is not
canonical (i.e., address bits 63:N are not same value as address bits [N-
1], where N is 48 bits with 4-level paging and 57 bits with 5-level paging)."

So it looks not correct to use aw filed in pasid entry to calculate iova_limit.
Aw can be a value configured by guest and it's used for stage-2 table. See spec:

" This field is treated as Reserved(0) for implementations not supporting 
Second-stage
Translation (SSTS=0 in the Extended Capability Register).
This field indicates the adjusted guest-address-width (AGAW) to be used by 
hardware
for second-stage translation through paging structures referenced through the
SSPTPTR field.
• The following encodings are defined for this field:
• 001b: 39-bit AGAW (3-level page table)
• 010b: 48-bit AGAW (4-level page table)
• 011b: 57-bit AGAW (5-level page table)
• 000b,100b-111b: Reserved
When not treated as Reserved(0), hardware ignores this field for 
first-stage-only
(PGTT=001b) and pass-through (PGTT=100b) translations."

Thanks
Zhenzhong


>+uint64_t upper_bits_mask = ~(iova_limit - 1);
>+uint64_t upper_bits = iova & upper_bits_mask;
>+bool msb = ((iova & (iova_limit >> 1)) != 0);
>+return !(
>+ (!msb && (upper_bits != 0)) ||
>+ (msb && (upper_bits != upper_bits_mask))
>+);
>+}
>+
> /*
>  * Given the @iova, get relevant @flptep. @flpte_level will be the last level
>  * of the translation, can be used for deciding the size of large page.
>@@ -2038,6 +2054,12 @@ static int vtd_iova_to_flpte(IntelIOMMUState *s,
>VTDContextEntry *ce,
> uint32_t offset;
> uint64_t flpte;
>
>+if (!vtd_iova_fl_check_canonical(s, iova, ce, aw_bits, pasid)) {
>+error_report_once("%s: detected non canonical IOVA (iova=0x%"
>PRIx64 ","
>+  "pasid=0x%" PRIx32 ")", __func__, iova, pasid);
>+return -VTD_FR_FS_NON_CANONICAL;
>+}
>+
> while (true) {
> offset = vtd_iova_fl_level_offset(iova, level);
> flpte = vtd_get_flpte(addr, offset);
>diff --git a/hw/i386/intel_iommu_internal.h
>b/hw/i386/intel_iommu_internal.h
>index 901691afb9..e9448291a4 100644
>--- a/hw/i386/intel_iommu_internal.h
>+++ b/hw/i386/intel_iommu_internal.h
>@@ -324,6 +324,8 @@ typedef enum VTDFaultReason {
> VTD_FR_PASID_ENTRY_P = 0x59, /* The Present(P) field of pasidt-entry is
>0 */
> VTD_FR_PASID_TABLE_ENTRY_INV = 0x5b,  /*Invalid PASID table entry */
>
>+VTD_FR_FS_NON_CANONICAL = 0x80, /* SNG.1 : Address for FS not
>canonical.*/
>+
> /* Output address in the interrupt address range for scalable mode */
> VTD_FR_SM_INTERRUPT_ADDR = 0x87,
> VTD_FR_MAX, /* Guard */
>--
>2.44.0


Re: [PATCH v2 3/4] virtio-gpu: add x-vmstate-version

2024-05-14 Thread Marc-André Lureau
Hi

On Tue, May 14, 2024 at 8:35 AM Peter Xu  wrote:
>
> Hey, Marc-Andre,
>
> On Mon, May 13, 2024 at 11:19:04AM +0400, marcandre.lur...@redhat.com wrote:
> > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > index ae831b6b3e..7f9fb5eacc 100644
> > --- a/hw/display/virtio-gpu.c
> > +++ b/hw/display/virtio-gpu.c
> > @@ -1234,7 +1234,8 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, 
> > size_t size,
> >  }
> >  qemu_put_be32(f, 0); /* end of list */
> >
> > -return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
> > +return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
> > +NULL, g->vmstate_version, NULL);
> >  }
> >
> >  static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> > @@ -1339,7 +1340,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, 
> > size_t size,
> >  }
> >
> >  /* load & apply scanout state */
> > -vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
> > +vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 
> > g->vmstate_version);
>
> [sorry for a late response; attending a conf, and will reply to the v1
>  thread later for the other discussions..]
>
> These two changes shouldn't be needed if we go with the .field_exists()
> approach, am I right?  IIUC in that case we can keep the version 1 here and
> don't boost anything, because we relied on the machine versions.
>
> IIUC this might be the reason why we found 9.0 mahines are broken on
> migration.  E.g, IIUC my original patch should work for 9.0<->9.0 too.
>

Indeed, but for consistency, shouldn't it use the x-vmstate-version
value for the top-level VMSD save/load ?

Otherwise, it feels a bit odd that this x-vmstate-version is only used
for the nested "virtio-gpu-one-scanout" version.

Or perhaps we should rename it to x-scanout-vmstate-version ? wdyt


> Thanks,
>
> >
> >  return 0;
> >  }
> > @@ -1659,6 +1660,7 @@ static Property virtio_gpu_properties[] = {
> >  DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
> >  VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
> >  DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
> > +DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 1),
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> >
> > --
> > 2.41.0.28.gd7d8841f67
> >
>
> --
> Peter Xu
>




Re: [PATCH] scripts/simpletrace: Mark output with unstable timestamp as WARN

2024-05-14 Thread Zhao Liu
Hi Stefan,

> QEMU uses clock_gettime(CLOCK_MONOTONIC) on Linux hosts. The man page
> says:
> 
>   All CLOCK_MONOTONIC variants guarantee that the time returned by
>   consecutive  calls  will  not go backwards, but successive calls
>   may—depending  on  the  architecture—return  identical  (not-in‐
>   creased) time values.
> 
> trace_record_start() calls clock_gettime(CLOCK_MONOTONIC) so trace events
> should have monotonically increasing timestamps.
> 
> I don't see a scenario where trace record A's timestamp is greater than
> trace record B's timestamp unless the clock is non-monotonic.
> 
> Which host CPU architecture and operating system are you running?

I tested on these 2 machines:
* CML (intel 10th) with Ubuntu 22.04 + kernel v6.5.0-28
* MTL (intel 14th) with Ubuntu 22.04.2 + kernel v6.9.0

> Please attach to the QEMU process with gdb and print out the value of
> the use_rt_clock variable or add a printf in init_get_clock(). The value
> should be 1.

Thanks, on both above machines, use_rt_clock is 1 and there're both
timestamp reversal issues with the following debug print:

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a366e551fb3..7657785c27dc 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -831,10 +831,17 @@ extern int use_rt_clock;

 static inline int64_t get_clock(void)
 {
+static int64_t clock = 0;
 if (use_rt_clock) {
 struct timespec ts;
 clock_gettime(CLOCK_MONOTONIC, &ts);
-return ts.tv_sec * 10LL + ts.tv_nsec;
+int64_t tmp = ts.tv_sec * 10LL + ts.tv_nsec;
+if (tmp <= clock) {
+printf("get_clock: strange, clock: %ld, tmp: %ld\n", clock, tmp);
+}
+assert(tmp > clock);
+clock = tmp;
+return clock;
 } else {
 /* XXX: using gettimeofday leads to problems if the date
changes, so it should be avoided. */
diff --git a/util/qemu-timer-common.c b/util/qemu-timer-common.c
index cc1326f72646..3bf06eb4a4ce 100644
--- a/util/qemu-timer-common.c
+++ b/util/qemu-timer-common.c
@@ -59,5 +59,6 @@ static void __attribute__((constructor)) init_get_clock(void)
 use_rt_clock = 1;
 }
 clock_start = get_clock();
+printf("init_get_clock: use_rt_clock: %d\n", use_rt_clock);
 }
 #endif

---
The timestamp interval is very small, for example:
get_clock: strange, clock: 3302130503505, tmp: 3302130503503

or

get_clock: strange, clock: 2761577819846455, tmp: 2761577819846395

I also tried to use CLOCK_MONOTONIC_RAW, but there's still the reversal
issue.

Thanks,
Zhao




Re: [PATCH v5 04/10] vfio: Use new Error** argument in vfio_save_setup()

2024-05-14 Thread Cédric Le Goater

On 5/13/24 15:21, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Nit: change commit title prefix to vfio/migration (also in other patches that 
are closely related to vfio migration)

Plus, maybe change subject to "Add an Error** argument to vfio_migration_set_state() 
and adjust callers" as it's the main subject of the patch?



Add an Error** argument to vfio_migration_set_state() and adjust
callers, including vfio_save_setup(). The error will be propagated up
to qemu_savevm_state_setup() where the save_setup() handler is
executed.

Modify vfio_vmstate_change_prepare() and vfio_vmstate_change() to
store a reported error under the migration stream if a migration is in
progress.

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

  Changes in v5:

  - Replaced error_setg() by error_setg_errno() in vfio_migration_set_state()
  - Rebased on 20c64c8a51a4 ("migration: migration_file_set_error")

  hw/vfio/migration.c | 76 +
  1 file changed, 43 insertions(+), 33 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4..9b6375c949f7a8dca857ead2506855f63fa051e4
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -82,7 +82,8 @@ static const char *mig_state_to_str(enum 
vfio_device_mig_state state)

  static int vfio_migration_set_state(VFIODevice *vbasedev,
  enum vfio_device_mig_state new_state,
-    enum vfio_device_mig_state recover_state)
+    enum vfio_device_mig_state recover_state,
+    Error **errp)
  {
  VFIOMigration *migration = vbasedev->migration;
  uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) +
@@ -102,25 +103,26 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
  ret = -errno;

  if (recover_state == VFIO_DEVICE_STATE_ERROR) {
-    error_report("%s: Failed setting device state to %s, err: %s. "
- "Recover state is ERROR. Resetting device",
- vbasedev->name, mig_state_to_str(new_state),
- strerror(errno));
+    error_setg_errno(errp, errno,
+ "%s: Failed setting device state to %s. "
+ "Recover state is ERROR. Resetting device",
+ vbasedev->name, mig_state_to_str(new_state));

  goto reset_device;
  }

-    error_report(
-    "%s: Failed setting device state to %s, err: %s. Setting device in 
recover state %s",
- vbasedev->name, mig_state_to_str(new_state),
- strerror(errno), mig_state_to_str(recover_state));
+    error_setg_errno(errp, errno,
+ "%s: Failed setting device state to %s. "
+ "Setting device in recover state %s",
+ vbasedev->name, mig_state_to_str(new_state),
+ mig_state_to_str(recover_state));

  mig_state->device_state = recover_state;
  if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
  ret = -errno;
-    error_report(
-    "%s: Failed setting device in recover state, err: %s. Resetting 
device",
- vbasedev->name, strerror(errno));
+    error_setg_errno(errp, errno,
+ "%s: Failed setting device in recover state. "
+ "Resetting device", vbasedev->name);


Here we set errp again when it's already set.


yes.


Maybe in this case just:

error_report_err(*errp);
*errp = NULL;
error_setg_errno(errp, errno,
  "%s: Failed setting device in recover state. "
  "Resetting device", vbasedev->name);
?



I see two alternatives for the recover state error :

1. append to the existing one, but we lack an error_append() helper
2. report as done today.

I tend to prefer 2. and we cab come back to 1. later on.





  goto reset_device;
  }
@@ -137,7 +139,7 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
   * This can happen if the device is asynchronously reset and
   * terminates a data transfer.
   */
-    error_report("%s: data_fd out of sync", vbasedev->name);
+    error_setg(errp, "%s: data_fd out of sync", vbasedev->name);
  close(mig_state->data_fd);

  return -EBADF;
@@ -168,10 +170,11 @@ reset_device:
   */
  static int
  vfio_migration_set_state_or_reset(VFIODevice *vbasedev,
-  enum vfio_device_mig_state new_state)
+  enum vfio_device_mig_state new_state,
+  Error **errp)
  {
  return vfio_migration_set_state(vbased

RE: [PATCH ats_vtd v1 06/24] intel_iommu: do not consider wait_desc as an invalid descriptor

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 06/24] intel_iommu: do not consider wait_desc
>as an invalid descriptor
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/i386/intel_iommu.c | 5 +
> 1 file changed, 5 insertions(+)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index 85a7ebac67..c475a354a0 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -3365,6 +3365,11 @@ static bool
>vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
> } else if (inv_desc->lo & VTD_INV_DESC_WAIT_IF) {
> /* Interrupt flag */
> vtd_generate_completion_event(s);
>+} else if (inv_desc->lo & VTD_INV_DESC_WAIT_FN) {
>+/*
>+ * SW = 0, IF = 0, FN = 1
>+ * Nothing to do as we process the events sequentially
>+ */
> } else {
> error_report_once("%s: invalid wait desc: hi=%"PRIx64", lo=%"PRIx64
>   " (unknown type)", __func__, inv_desc->hi,

LGTM.

Thanks
Zhenzhong 


RE: [PATCH ats_vtd v1 04/24] intel_iommu: set accessed and dirty bits during first stage translation

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 04/24] intel_iommu: set accessed and dirty bits
>during first stage translation
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/i386/intel_iommu.c  | 26 ++
> hw/i386/intel_iommu_internal.h |  3 +++
> 2 files changed, 29 insertions(+)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index 240ecb8f72..cad70e0d05 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -1913,6 +1913,7 @@ static const bool vtd_qualified_faults[] = {
> [VTD_FR_PASID_TABLE_ENTRY_INV] = true,
> [VTD_FR_SM_INTERRUPT_ADDR] = true,
> [VTD_FR_FS_NON_CANONICAL] = true,
>+[VTD_FR_FS_BIT_UPDATE_FAILED] = true,
> [VTD_FR_MAX] = false,
> };
>
>@@ -2039,6 +2040,20 @@ static bool
>vtd_iova_fl_check_canonical(IntelIOMMUState *s,
> );
> }
>
>+static MemTxResult vtd_set_flag_in_pte(dma_addr_t base_addr, uint32_t
>index,
>+   uint64_t pte, uint64_t flag)
>+{
>+if (pte & flag) {
>+return MEMTX_OK;
>+}
>+pte |= flag;
>+pte = cpu_to_le64(pte);
>+return dma_memory_write(&address_space_memory,
>+base_addr + index * sizeof(pte),
>+&pte, sizeof(pte),
>+MEMTXATTRS_UNSPECIFIED);
>+}
>+
> /*
>  * Given the @iova, get relevant @flptep. @flpte_level will be the last level
>  * of the translation, can be used for deciding the size of large page.
>@@ -2080,11 +2095,22 @@ static int vtd_iova_to_flpte(IntelIOMMUState
>*s, VTDContextEntry *ce,
>
> *reads = true;
> *writes = (*writes) && (flpte & VTD_FL_RW_MASK);
>+
>+if (vtd_set_flag_in_pte(addr, offset, flpte, VTD_FL_PTE_A)
>+!= MEMTX_OK) {
>+return -VTD_FR_FS_BIT_UPDATE_FAILED;
>+}
>+
> if (is_write && !(flpte & VTD_FL_RW_MASK)) {
> return -VTD_FR_WRITE;
> }

May be better to set access bit here?
Speculatively setting access bit is allowed but not necessary.

Thanks
Zhenzhong

>
> if (vtd_is_last_flpte(flpte, level)) {
>+if (is_write &&
>+(vtd_set_flag_in_pte(addr, offset, flpte, VTD_FL_PTE_D) !=
>+
>MEMTX_OK)) {
>+return -VTD_FR_FS_BIT_UPDATE_FAILED;
>+}
> *flptep = flpte;
> *flpte_level = level;
> return 0;
>diff --git a/hw/i386/intel_iommu_internal.h
>b/hw/i386/intel_iommu_internal.h
>index e9448291a4..14879d3a58 100644
>--- a/hw/i386/intel_iommu_internal.h
>+++ b/hw/i386/intel_iommu_internal.h
>@@ -328,6 +328,7 @@ typedef enum VTDFaultReason {
>
> /* Output address in the interrupt address range for scalable mode */
> VTD_FR_SM_INTERRUPT_ADDR = 0x87,
>+VTD_FR_FS_BIT_UPDATE_FAILED = 0x91, /* SFS.10 */
> VTD_FR_MAX, /* Guard */
> } VTDFaultReason;
>
>@@ -649,6 +650,8 @@ typedef struct VTDPIOTLBInvInfo {
> /* First Level Paging Structure */
> #define VTD_FL_PT_LEVEL 1
> #define VTD_FL_PT_ENTRY_NR  512
>+#define VTD_FL_PTE_A0x20
>+#define VTD_FL_PTE_D0x40
>
> /* Masks for First Level Paging Entry */
> #define VTD_FL_RW_MASK  (1ULL << 1)
>--
>2.44.0


Re: [PATCH v7 04/12] hw/mem/cxl_type3: Add support to create DC regions to type3 memory devices

2024-05-14 Thread Zhijian Li (Fujitsu)


On 19/04/2024 07:10, nifan@gmail.com wrote:
> From: Fan Ni 
> 

> +}
> +
>   static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
>   {
>   DeviceState *ds = DEVICE(ct3d);
> @@ -635,6 +676,13 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error 
> **errp)
>   g_free(p_name);
>   }
>   
> +if (ct3d->dc.num_regions > 0) {
> +if (!cxl_create_dc_regions(ct3d, errp)) {
> +error_setg(errp, "setup DC regions failed");

This error_set() would cause an assertion if the errp was assigned inside 
cxl_create_dc_regions();
Try error_append_hint() instead

#3  0x7f1fdc4fafc6 in annobin_assert.c_end () at /lib64/libc.so.6
#4  0x555fd3edbea8 in error_setv
 (errp=0x7ffe6d1a3de0, src=0x555fd3fe262b "../hw/mem/cxl_type3.c", 
line=807, func=0x555fd3fe2fe0 <__func__.21> "cxl_setup_memory", 
err_class=ERROR_CLASS_GENERIC_ERROR, fmt=0x555fd3fe2939 "setup DC regions 
failed", ap=0x7ffe6d1a3
c00, suffix=0x0) at ../util/error.c:68
#5  0x555fd3edc126 in error_setg_internal
 (errp=0x7ffe6d1a3de0, src=0x555fd3fe262b "../hw/mem/cxl_type3.c", 
line=807, func=0x555fd3fe2fe0 <__func__.21> "cxl_setup_memory", 
fmt=0x555fd3fe2939 "setup DC regions failed") at ../util/error.c:105
#6  0x555fd3819c9f in cxl_setup_memory (ct3d=0x555fd8b2f3e0, 
errp=0x7ffe6d1a3de0) at ../hw/mem/cxl_type3.c:807
#7  0x555fd3819d7b in ct3_realize (pci_dev=0x555fd8b2f3e0, 
errp=0x7ffe6d1a3de0) at ../hw/mem/cxl_type3.c:833
#8  0x555fd38b575f in pci_qdev_realize (qdev=0x555fd8b2f3e0, 
errp=0x7ffe6d1a3e60) at ../hw/pci/pci.c:2093
#9  0x555fd3ccca9b in device_set_realized (obj=0x555fd8b2f3e0, value=true, 
errp=0x7ffe6d1a40d0)


RE: [PATCH ats_vtd v1 07/24] memory: add permissions in IOMMUAccessFlags

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 07/24] memory: add permissions in
>IOMMUAccessFlags
>
>This will be necessary for devices implementing ATS.
>We also define a new macro IOMMU_ACCESS_FLAG_FULL in addition to
>IOMMU_ACCESS_FLAG to support more access flags.
>IOMMU_ACCESS_FLAG is kept for convenience and backward compatibility.
>
>Here are the flags added (defined by the PCIe 5 specification) :
>- Execute Requested
>- Privileged Mode Requested
>- Global
>- Untranslated Only
>
>IOMMU_ACCESS_FLAG sets the additional flags to 0
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> include/exec/memory.h | 33 ++---
> 1 file changed, 26 insertions(+), 7 deletions(-)
>
>diff --git a/include/exec/memory.h b/include/exec/memory.h
>index 8626a355b3..304504de02 100644
>--- a/include/exec/memory.h
>+++ b/include/exec/memory.h
>@@ -110,22 +110,41 @@ struct MemoryRegionSection {
>
> typedef struct IOMMUTLBEntry IOMMUTLBEntry;
>
>-/* See address_space_translate: bit 0 is read, bit 1 is write.  */
>+/*
>+ * See address_space_translate:
>+ *  - bit 0 : read
>+ *  - bit 1 : write
>+ *  - bit 2 : exec
>+ *  - bit 3 : priv
>+ *  - bit 4 : global
>+ *  - bit 5 : untranslated only
>+ */
> typedef enum {
> IOMMU_NONE = 0,
> IOMMU_RO   = 1,
> IOMMU_WO   = 2,
> IOMMU_RW   = 3,
>+IOMMU_EXEC = 4,
>+IOMMU_PRIV = 8,
>+IOMMU_GLOBAL = 16,
>+IOMMU_UNTRANSLATED_ONLY = 32,
> } IOMMUAccessFlags;
>
>-#define IOMMU_ACCESS_FLAG(r, w) (((r) ? IOMMU_RO : 0) | ((w) ?
>IOMMU_WO : 0))
>+#define IOMMU_ACCESS_FLAG(r, w) (((r) ? IOMMU_RO : 0) | \
>+((w) ? IOMMU_WO : 0))
>+#define IOMMU_ACCESS_FLAG_FULL(r, w, x, p, g, uo) \
>+(IOMMU_ACCESS_FLAG(r, w) | \
>+((x) ? IOMMU_EXEC : 0) | \
>+((p) ? IOMMU_PRIV : 0) | \
>+((g) ? IOMMU_GLOBAL : 0) | \
>+((uo) ? IOMMU_UNTRANSLATED_ONLY : 0))
>
> struct IOMMUTLBEntry {
>-AddressSpace*target_as;
>-hwaddr   iova;
>-hwaddr   translated_addr;
>-hwaddr   addr_mask;  /* 0xfff = 4k translation */
>-IOMMUAccessFlags perm;
>+AddressSpace*target_as;
>+hwaddr  iova;
>+hwaddr  translated_addr;
>+hwaddr  addr_mask;  /* 0xfff = 4k translation */
>+IOMMUAccessFlagsperm;
> };

Any reason for this change?

Thanks
Zhenzhong


Re: [PATCH v7 06/12] hw/mem/cxl_type3: Add host backend and address space handling for DC regions

2024-05-14 Thread Zhijian Li (Fujitsu)


On 19/04/2024 07:10, nifan@gmail.com wrote:
> +uint64_t dc_size;
> +
> +mr = host_memory_backend_get_memory(ct3d->dc.host_dc);
> +dc_size = memory_region_size(mr);
> +region_len = DIV_ROUND_UP(dc_size, ct3d->dc.num_regions);
> +
> +if (dc_size % (ct3d->dc.num_regions * CXL_CAPACITY_MULTIPLIER) != 0) {
> +error_setg(errp, "host backend size must be multiples of region 
> len");

I prefer to have the %region_len% in the error message as well so that i can 
update the
backend file accordingly.



> +return false;
> +}

RE: [PATCH ats_vtd v1 08/24] pcie: add helper to declare PASID capability for a pcie device

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 08/24] pcie: add helper to declare PASID
>capability for a pcie device
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/pci/pcie.c  | 24 
> include/hw/pci/pcie.h  |  6 +-
> include/hw/pci/pcie_regs.h |  3 +++
> 3 files changed, 32 insertions(+), 1 deletion(-)
>
>diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
>index 4b2f0805c6..c8e9d4c0f7 100644
>--- a/hw/pci/pcie.c
>+++ b/hw/pci/pcie.c
>@@ -1177,3 +1177,27 @@ void pcie_acs_reset(PCIDevice *dev)
> pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, 0);
> }
> }
>+
>+/* PASID */
>+void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
>+ bool exec_perm, bool priv_mod)
>+{
>+assert(pasid_width <= PCI_EXT_CAP_PASID_MAX_WIDTH);
>+static const uint16_t control_reg_rw_mask = 0x07;
>+uint16_t capability_reg = pasid_width;
>+
>+pcie_add_capability(dev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER, offset,
>+PCI_EXT_CAP_PASID_SIZEOF);
>+
>+capability_reg <<= PCI_EXT_CAP_PASID_SIZEOF;

Not understand why PCI_EXT_CAP_PASID_SIZEOF is used for shifting?

>+capability_reg |= exec_perm ? PCI_PASID_CAP_EXEC : 0;
>+capability_reg |= priv_mod  ? PCI_PASID_CAP_PRIV : 0;
>+pci_set_word(dev->config + offset + PCI_PASID_CAP, capability_reg);
>+
>+/* Everything is disabled by default */
>+pci_set_word(dev->config + offset + PCI_PASID_CTRL, 0);
>+
>+pci_set_word(dev->wmask + offset + PCI_PASID_CTRL,
>control_reg_rw_mask);
>+
>+dev->exp.pasid_cap = offset;
>+}
>diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
>index 11f5a91bbb..c59627d556 100644
>--- a/include/hw/pci/pcie.h
>+++ b/include/hw/pci/pcie.h
>@@ -69,8 +69,9 @@ struct PCIExpressDevice {
> uint16_t aer_cap;
> PCIEAERLog aer_log;
>
>-/* Offset of ATS capability in config space */
>+/* Offset of ATS and PASID capabilities in config space */
> uint16_t ats_cap;
>+uint16_t pasid_cap;
>
> /* ACS */
> uint16_t acs_cap;
>@@ -147,4 +148,7 @@ void pcie_cap_slot_unplug_cb(HotplugHandler
>*hotplug_dev, DeviceState *dev,
>  Error **errp);
> void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
>  DeviceState *dev, Error **errp);
>+
>+void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
>+ bool exec_perm, bool priv_mod);
> #endif /* QEMU_PCIE_H */
>diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
>index 9d3b6868dc..0a86598f80 100644
>--- a/include/hw/pci/pcie_regs.h
>+++ b/include/hw/pci/pcie_regs.h
>@@ -86,6 +86,9 @@ typedef enum PCIExpLinkWidth {
> #define PCI_ARI_VER 1
> #define PCI_ARI_SIZEOF  8
>
>+/* PASID */
>+#define PCI_PASID_VER   1
>+#define PCI_EXT_CAP_PASID_MAX_WIDTH 20
> /* AER */
> #define PCI_ERR_VER 2
> #define PCI_ERR_SIZEOF  0x48
>--
>2.44.0


RE: [PATCH ats_vtd v1 09/24] pcie: helper functions to check if PASID and ATS are enabled

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 09/24] pcie: helper functions to check if PASID
>and ATS are enabled
>
>ats_enabled and pasid_enabled check whether the capabilities are
>present or not. If so, we read the configuration space to get
>the status of the feature (enabled or not).

s/present/enabled/

>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/pci/pcie.c | 18 ++
> include/hw/pci/pcie.h |  3 +++
> 2 files changed, 21 insertions(+)
>
>diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
>index c8e9d4c0f7..2a638a9c3f 100644
>--- a/hw/pci/pcie.c
>+++ b/hw/pci/pcie.c
>@@ -1201,3 +1201,21 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t
>offset, uint8_t pasid_width,
>
> dev->exp.pasid_cap = offset;
> }
>+
>+bool pcie_pasid_enabled(const PCIDevice *dev)
>+{
>+if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
>+return false;
>+}
>+return (pci_get_word(dev->config + dev->exp.pasid_cap +
>PCI_PASID_CTRL) &
>+PCI_PASID_CTRL_ENABLE) != 0;
>+}
>+
>+bool pcie_ats_enabled(const PCIDevice *dev)
>+{
>+if (!pci_is_express(dev) || !dev->exp.ats_cap) {
>+return false;
>+}
>+return (pci_get_word(dev->config + dev->exp.ats_cap + PCI_ATS_CTRL) &
>+PCI_ATS_CTRL_ENABLE) != 0;
>+}
>diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
>index c59627d556..8c222f09da 100644
>--- a/include/hw/pci/pcie.h
>+++ b/include/hw/pci/pcie.h
>@@ -151,4 +151,7 @@ void
>pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
>
> void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
>  bool exec_perm, bool priv_mod);
>+
>+bool pcie_pasid_enabled(const PCIDevice *dev);
>+bool pcie_ats_enabled(const PCIDevice *dev);
> #endif /* QEMU_PCIE_H */
>--
>2.44.0


Re: [PATCH v5 05/10] vfio: Add Error** argument to .vfio_save_config() handler

2024-05-14 Thread Cédric Le Goater

On 5/13/24 15:30, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Use vmstate_save_state_with_err() to improve error reporting in the
callers and store a reported error under the migration stream. Add
documentation while at it.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Cédric Le Goater 
---
  include/hw/vfio/vfio-common.h | 25 -
  hw/vfio/migration.c   | 18 --
  hw/vfio/pci.c |  5 +++--
  3 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b9da6c08ef41174610eb92726c590309a53696a3..46f88493634b5634a9c14a5caa33a463fbf2c50d
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -133,7 +133,30 @@ struct VFIODeviceOps {
  int (*vfio_hot_reset_multi)(VFIODevice *vdev);
  void (*vfio_eoi)(VFIODevice *vdev);
  Object *(*vfio_get_object)(VFIODevice *vdev);
-    void (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f);
+
+    /**
+ * @vfio_save_config
+ *
+ * Save device config state
+ *
+ * @vdev: #VFIODevice for which to save the config
+ * @f: #QEMUFile where to send the data
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
+    int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp);
+
+    /**
+ * @vfio_load_config
+ *
+ * Load device config state
+ *
+ * @vdev: #VFIODevice for which to load the config
+ * @f: #QEMUFile where to get the data
+ *
+ * Returns zero to indicate success and negative for error
+ */
  int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f);
  };

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
9b6375c949f7a8dca857ead2506855f63fa051e4..87437490bd50321b3eb27770c932078597053746
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -189,14 +189,19 @@ static int vfio_load_buffer(QEMUFile *f, VFIODevice 
*vbasedev,
  return ret;
  }

-static int vfio_save_device_config_state(QEMUFile *f, void *opaque)
+static int vfio_save_device_config_state(QEMUFile *f, void *opaque,
+ Error **errp)
  {
  VFIODevice *vbasedev = opaque;
+    int ret;

  qemu_put_be64(f, VFIO_MIG_FLAG_DEV_CONFIG_STATE);

  if (vbasedev->ops && vbasedev->ops->vfio_save_config) {
-    vbasedev->ops->vfio_save_config(vbasedev, f);
+    ret = vbasedev->ops->vfio_save_config(vbasedev, f, errp);
+    if (ret) {
+    return ret;
+    }
  }

  qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);


Below we have:

return qemu_file_get_error(f);

Need to set errp in case of error.


yep. I will change the returned type to bool while at it.




@@ -588,13 +593,14 @@ static int vfio_save_complete_precopy(QEMUFile *f, void 
*opaque)
  static void vfio_save_state(QEMUFile *f, void *opaque)
  {
  VFIODevice *vbasedev = opaque;
+    Error *local_err = NULL;
  int ret;

-    ret = vfio_save_device_config_state(f, opaque);
+    ret = vfio_save_device_config_state(f, opaque, &local_err);
  if (ret) {
-    error_report("%s: Failed to save device config space",
- vbasedev->name);
-    qemu_file_set_error(f, ret);
+    error_prepend(&local_err, "%s: Failed to save device config space",


Add " - " ("... device config space - "), like in the other patches?


ok. I will check how (in)consistent I was when doing these
error_prepend changes.


Thanks,

C.




Thanks.


+  vbasedev->name);
+    qemu_file_set_error_obj(f, ret, local_err);
  }
  }

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
64780d1b793345c8e8996fe6b7987059ce831c11..fc6e54e871508bb0e2a3ac9079a195c086531f21
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2586,11 +2586,12 @@ static const VMStateDescription vmstate_vfio_pci_config 
= {
  }
  };

-static void vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f)
+static int vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f, Error 
**errp)
  {
  VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);

-    vmstate_save_state(f, &vmstate_vfio_pci_config, vdev, NULL);
+    return vmstate_save_state_with_err(f, &vmstate_vfio_pci_config, vdev, NULL,
+   errp);
  }

  static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
--
2.45.0








Re: [PULL 00/27] Build/arch cleanups, target/i386 fixes for 2024-05-10

2024-05-14 Thread Richard Henderson

On 5/12/24 12:49, Paolo Bonzini wrote:

The following changes since commit dafec285bdbfe415ac6823abdc510e0b92c3f094:

   Merge tag 'pull-request-2024-05-10' ofhttps://gitlab.com/thuth/qemu  into 
staging (2024-05-10 09:41:35 +0200)

are available in the Git repository at:

   https://gitlab.com/bonzini/qemu.git  tags/for-upstream

for you to fetch changes up to 9b089d254a5623baef01f7d0ec37331c1155f1ce:

   configs: disable emulators that require it if libfdt is not found 
(2024-05-10 15:45:15 +0200)


* target/i386: miscellaneous changes, mostly TCG-related
* fix --without-default-devices build
* fix --without-default-devices qtests on s390x and arm


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/9.1 as 
appropriate.


r~




Re: [PATCH v5 06/10] vfio: Reverse test on vfio_get_dirty_bitmap()

2024-05-14 Thread Cédric Le Goater

On 5/13/24 15:42, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Title should be: Reverse test on vfio_get_xlat_addr()?


It could.




It will simplify the changes coming after.

Signed-off-by: Cédric Le Goater 
---
  hw/vfio/common.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
ed5ee6349ced78b3bde68d2ee506f78ba1a9dd9c..b929bb0b7ac60dcef34c0d5a098d5d91f75501dd
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1224,16 +1224,20 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier 
*n, IOMMUTLBEntry *iotlb)
  }

  rcu_read_lock();
-    if (vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) {
-    ret = vfio_get_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1,
-    translated_addr);
-    if (ret) {
-    error_report("vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", "
- "0x%"HWADDR_PRIx") = %d (%s)",
- bcontainer, iova, iotlb->addr_mask + 1, ret,
- strerror(-ret));
-    }
+    if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) {
+    goto out_lock;
  }
+
+    ret = vfio_get_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1,
+    translated_addr);
+    if (ret) {
+    error_report("vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", "
+ "0x%"HWADDR_PRIx") = %d (%s)",
+ bcontainer, iova, iotlb->addr_mask + 1, ret,
+ strerror(-ret));
+    }
+
+out_lock:


s/out_lock/out_unlock?


yes. better naming.



With the above,


both done.


Thanks,

C.




Reviewed-by: Avihai Horon 


  rcu_read_unlock();

  out:
--
2.45.0








Re: [PATCH v5 07/10] memory: Add Error** argument to memory_get_xlat_addr()

2024-05-14 Thread Cédric Le Goater

On 5/13/24 15:44, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Let the callers do the reporting. This will be useful in
vfio_iommu_map_dirty_notify().

Cc: "Michael S. Tsirkin" 
Cc: Paolo Bonzini 
Cc: David Hildenbrand 
Reviewed-by: Peter Xu 
Signed-off-by: Cédric Le Goater 
---
  include/exec/memory.h  | 15 ++-
  hw/vfio/common.c   | 13 +
  hw/virtio/vhost-vdpa.c |  5 -
  system/memory.c    | 10 +-
  4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 
dadb5cd65ab58b4868fcae06b4e301f0ecb0c1d2..2c45051b7b419c48b4e14c25f4d16a99ccd23996
 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -774,9 +774,22 @@ void 
ram_discard_manager_register_listener(RamDiscardManager *rdm,
  void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
   RamDiscardListener *rdl);

+/**
+ * memory_get_xlat_addr: Extract addresses from a TLB entry
+ *
+ * @iotlb: pointer to an #IOMMUTLBEntry
+ * @vaddr: virtual addressf


Nit: s/addressf/address


Fixed.


Thanks,

C.




Thanks.


+ * @ram_addr: RAM address
+ * @read_only: indicates if writes are allowed
+ * @mr_has_discard_manager: indicates memory is controlled by a
+ *  RamDiscardManager
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Return: true on success, else false setting @errp with error.
+ */
  bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
    ram_addr_t *ram_addr, bool *read_only,
-  bool *mr_has_discard_manager);
+  bool *mr_has_discard_manager, Error **errp);

  typedef struct CoalescedMemoryRange CoalescedMemoryRange;
  typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
b929bb0b7ac60dcef34c0d5a098d5d91f75501dd..da748563eb33843e93631a5240759964f33162f2
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -253,12 +253,13 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)

  /* Called with rcu_read_lock held.  */
  static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
-   ram_addr_t *ram_addr, bool *read_only)
+   ram_addr_t *ram_addr, bool *read_only,
+   Error **errp)
  {
  bool ret, mr_has_discard_manager;

  ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
-   &mr_has_discard_manager);
+   &mr_has_discard_manager, errp);
  if (ret && mr_has_discard_manager) {
  /*
   * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
@@ -288,6 +289,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  hwaddr iova = iotlb->iova + giommu->iommu_offset;
  void *vaddr;
  int ret;
+    Error *local_err = NULL;

  trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",
  iova, iova + iotlb->addr_mask);
@@ -304,7 +306,8 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
  bool read_only;

-    if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only)) {
+    if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &local_err)) {
+    error_report_err(local_err);
  goto out;
  }
  /*
@@ -1213,6 +1216,7 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  VFIOContainerBase *bcontainer = giommu->bcontainer;
  hwaddr iova = iotlb->iova + giommu->iommu_offset;
  ram_addr_t translated_addr;
+    Error *local_err = NULL;
  int ret = -EINVAL;

  trace_vfio_iommu_map_dirty_notify(iova, iova + iotlb->addr_mask);
@@ -1224,7 +1228,8 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  }

  rcu_read_lock();
-    if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL)) {
+    if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) {
+    error_report_err(local_err);
  goto out_lock;
  }

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 
e827b9175fc61f1ef419e48d90a440b00449312a..ed99ab87457d8f31b98ace960713f48d47b27102
 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -208,6 +208,7 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  void *vaddr;
  int ret;
  Int128 llend;
+    Error *local_err = NULL;

  if (iotlb->target_as != &address_space_memory) {
  error_report("Wrong target AS \"%s\", only system memory is allowed",
@@ -227,7 +228,9 @@ static void vhost_vdpa_iommu

Re: [PATCH v3 0/6] X86: Alias isa-bios area and clean up

2024-05-14 Thread Bernhard Beschow



Am 8. Mai 2024 20:39:28 UTC schrieb BALATON Zoltan :
>On Wed, 8 May 2024, Bernhard Beschow wrote:
>> This series changes the "isa-bios" MemoryRegion to be an alias rather than a
>> copy in the pflash case. This fixes issuing pflash commands in the isa-bios
>> region which matches real hardware and which some real-world legacy bioses 
>> I'm
>> running rely on. Furthermore, aliasing in the isa-bios area is already the
>
>I wonder if this allows the guest to flash the bios now, replacing or breaking 
>it which may be a new security issue.

The bios can already be flashed, just from different addresses. This series 
just adds another alias region through which flashing will be possible. AFAICS 
it doesn't impose new security issues.

Ping... The last patch still needs an R-b, the other patches are already on 
master.

Best regards,
Bernhard

> If so this may need some machine property to enable it or is that not a 
> problem in practice?
>
>Regards,
>BALATON Zoltan
>
>> current behavior in the bios (a.k.a. ROM) case, so this series consolidates
>> behavior.
>> 
>> For migration compatibility the aliasing is only performed on new versions of
>> the q34 and pc machine types.
>> 
>> v3:
>> * Amend commit message with a diff of `info mtree` (Phil)
>> * Add comments for bios memory regions (Phil)
>> 
>> v2:
>> * Don't leak bios memory regions (Phil)
>> * Add compat machinery (Michael)
>> 
>> Testing done:
>> * `make check` with qemu-system-x86_64 (QEMU 8.2.2) installed. All tests
>>  including migration tests pass.
>> * `make check-avocado`
>> 
>> Best regards,
>> Bernhard
>> 
>> Bernhard Beschow (6):
>>  hw/i386/x86: Eliminate two if statements in x86_bios_rom_init()
>>  hw/i386: Have x86_bios_rom_init() take X86MachineState rather than
>>MachineState
>>  hw/i386/x86: Don't leak "isa-bios" memory regions
>>  hw/i386/x86: Don't leak "pc.bios" memory region
>>  hw/i386/x86: Extract x86_isa_bios_init() from x86_bios_rom_init()
>>  hw/i386/pc_sysfw: Alias rather than copy isa-bios region
>> 
>> include/hw/i386/pc.h  |  1 +
>> include/hw/i386/x86.h | 17 +++-
>> hw/i386/microvm.c |  2 +-
>> hw/i386/pc.c  |  1 +
>> hw/i386/pc_piix.c |  3 +++
>> hw/i386/pc_q35.c  |  2 ++
>> hw/i386/pc_sysfw.c| 17 ++--
>> hw/i386/x86.c | 45 ++-
>> 8 files changed, 58 insertions(+), 30 deletions(-)
>> 
>> --
>> 2.45.0
>> 
>> 
>> 



Re: [PATCH v5 08/10] vfio: Add Error** argument to .get_dirty_bitmap() handler

2024-05-14 Thread Cédric Le Goater

On 5/13/24 15:51, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


Let the callers do the error reporting. Add documentation while at it.

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

  Changes in v5:

  - Replaced error_setg() by error_setg_errno() in
    vfio_devices_query_dirty_bitmap() and vfio_legacy_query_dirty_bitmap()
  - ':' -> '-' in vfio_iommu_map_dirty_notify()

  include/hw/vfio/vfio-common.h |  4 +-
  include/hw/vfio/vfio-container-base.h | 17 +++-
  hw/vfio/common.c  | 59 ++-
  hw/vfio/container-base.c  |  5 ++-
  hw/vfio/container.c   | 14 ---
  5 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
46f88493634b5634a9c14a5caa33a463fbf2c50d..68911d36676667352e94a97895828aff4b194b57
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -274,9 +274,9 @@ bool
  vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer);
  int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
  VFIOBitmap *vbmap, hwaddr iova,
-    hwaddr size);
+    hwaddr size, Error **errp);


Nit: while at it, can we fix the line wrap here?


  int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova,
-  uint64_t size, ram_addr_t ram_addr);
+  uint64_t size, ram_addr_t ram_addr, Error **errp);

  /* Returns 0 on success, or a negative errno. */
  int vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
326ceea52a2030eec9dad289a9845866c4a8c090..48c92e186231c2c2b548abed08800faff3f430a7
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -85,7 +85,7 @@ int vfio_container_set_dirty_page_tracking(VFIOContainerBase 
*bcontainer,
 bool start, Error **errp);
  int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
    VFIOBitmap *vbmap,
-  hwaddr iova, hwaddr size);
+  hwaddr iova, hwaddr size, Error **errp);


Nit: while at it, can we fix the line wrap here?


do you mean :

int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
  VFIOBitmap *vbmap, hwaddr iova,
  hwaddr size, Error **errp);

?





  void vfio_container_init(VFIOContainerBase *bcontainer,
   VFIOAddressSpace *space,
@@ -138,9 +138,22 @@ struct VFIOIOMMUClass {
   */
  int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
 bool start, Error **errp);
+    /**
+ * @query_dirty_bitmap
+ *
+ * Get list of dirty pages from container


s/list/bitmap?


yep


Thanks,

C.





+ *
+ * @bcontainer: #VFIOContainerBase from which to get dirty pages
+ * @vbmap: #VFIOBitmap internal bitmap structure
+ * @iova: iova base address
+ * @size: size of iova range
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
  int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer,
    VFIOBitmap *vbmap,
-  hwaddr iova, hwaddr size);
+  hwaddr iova, hwaddr size, Error **errp);
  /* PCI specific */
  int (*pci_hot_reset)(VFIODevice *vbasedev, bool single);

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
da748563eb33843e93631a5240759964f33162f2..c3d82a9d6e434e33f361e4b96157bf912d5c3a2f
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1141,7 +1141,7 @@ static int vfio_device_dma_logging_report(VFIODevice 
*vbasedev, hwaddr iova,

  int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
  VFIOBitmap *vbmap, hwaddr iova,
-    hwaddr size)
+    hwaddr size, Error **errp)


Nit: while at it, can we fix the line wrap here?


  {
  VFIODevice *vbasedev;
  int ret;
@@ -1150,10 +1150,10 @@ int vfio_devices_query_dirty_bitmap(const 
VFIOContainerBase *bcontainer,
  ret = vfio_device_dma_logging_report(vbasedev, iova, size,
   vbmap->bitmap);
  if (ret) {
-    error_report("%s: Failed to get DMA logging report, iova: "
- "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx
- ", err: %d

[PATCH v2 1/2] hw/intc/loongarch_extioi: Add extioi virt extension definition

2024-05-14 Thread Song Gao
On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
This patch adds the extioi virt extension definition so that the IRQ can
route to 256 vcpus.

Signed-off-by: Song Gao 
---
 include/hw/intc/loongarch_extioi.h | 21 +++
 hw/intc/loongarch_extioi.c | 92 --
 2 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index 410c6e1121..d4646fab9f 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -41,6 +41,24 @@
 #define EXTIOI_COREMAP_END   (0xD00 - APIC_OFFSET)
 #define EXTIOI_SIZE  0x800
 
+#define EXTIOI_VIRT_BASE (0x4000)
+#define EXTIOI_VIRT_SIZE (0x1000)
+#define EXTIOI_VIRT_FEATURES (0x0)
+#define  EXTIOI_HAS_VIRT_EXTENSION (0)
+#define  EXTIOI_HAS_ENABLE_OPTION  (1)
+#define  EXTIOI_HAS_INT_ENCODE (2)
+#define  EXTIOI_HAS_CPU_ENCODE (3)
+#define  EXTIOI_VIRT_HAS_FEATURES  (BIT(EXTIOI_HAS_VIRT_EXTENSION)  \
+| BIT(EXTIOI_HAS_ENABLE_OPTION) \
+| BIT(EXTIOI_HAS_INT_ENCODE)\
+   | BIT(EXTIOI_HAS_CPU_ENCODE))
+#define EXTIOI_VIRT_CONFIG   (0x4)
+#define  EXTIOI_ENABLE (1)
+#define  EXTIOI_ENABLE_INT_ENCODE  (2)
+#define  EXTIOI_ENABLE_CPU_ENCODE  (3)
+#define EXTIOI_VIRT_COREMAP_START(0x40)
+#define EXTIOI_VIRT_COREMAP_END  (0x240)
+
 typedef struct ExtIOICore {
 uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
 DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
@@ -52,6 +70,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
 struct LoongArchExtIOI {
 SysBusDevice parent_obj;
 uint32_t num_cpu;
+uint32_t features;
+uint32_t status;
 /* hardware state */
 uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
 uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
@@ -65,5 +85,6 @@ struct LoongArchExtIOI {
 qemu_irq irq[EXTIOI_IRQS];
 ExtIOICore *cpu;
 MemoryRegion extioi_system_mem;
+MemoryRegion virt_extend;
 };
 #endif /* LOONGARCH_EXTIOI_H */
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 0b358548eb..89afdb1c3c 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -143,10 +143,13 @@ static inline void 
extioi_update_sw_coremap(LoongArchExtIOI *s, int irq,
 
 for (i = 0; i < 4; i++) {
 cpu = val & 0xff;
-cpu = ctz32(cpu);
-cpu = (cpu >= 4) ? 0 : cpu;
 val = val >> 8;
 
+if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) {
+cpu = ctz32(cpu);
+cpu = (cpu >= 4) ? 0 : cpu;
+}
+
 if (s->sw_coremap[irq + i] == cpu) {
 continue;
 }
@@ -265,6 +268,61 @@ static const MemoryRegionOps extioi_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data,
+ unsigned size, MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+*data = s->features;
+break;
+case EXTIOI_VIRT_CONFIG:
+*data = s->status;
+break;
+default:
+break;
+}
+
+return MEMTX_OK;
+}
+
+static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size,
+  MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+return MEMTX_ACCESS_ERROR;
+
+case EXTIOI_VIRT_CONFIG:
+/*
+ * extioi features can only be set at disabled status
+ */
+if ((s->status & BIT(EXTIOI_ENABLE)) && val) {
+return MEMTX_ACCESS_ERROR;
+}
+
+s->status = val & s->features;
+break;
+default:
+break;
+}
+return MEMTX_OK;
+}
+
+static const MemoryRegionOps extioi_virt_ops = {
+.read_with_attrs = extioi_virt_readw,
+.write_with_attrs = extioi_virt_writew,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
 {
 LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev);
@@ -284,6 +342,16 @@ static void loongarch_extioi_realize(DeviceState *dev, 
Error **errp)
 memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
   s, "extioi_system_mem", 0x900);
 sysbus_init_mmio(sbd, &s->extioi_system_mem);
+
+if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
+memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops,
+  s, "exti

[PATCH v2 0/2] Add extioi virt extension support

2024-05-14 Thread Song Gao
Base-on: <20240514025109.3238398-1-maob...@loongson.cn>

On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
This patch adds the extioi virt extension support so that the IRQ can
route to 256 vcpus.  

v2:
- Split the patch to two small patch.
- Drop 'RFC' title. extioi virt extension suport only enable on kvm
  mode and  the extioi driver need patch[1].
  but this series do not affect the old codes in any way.
- Link to v1: 
https://lore.kernel.org/all/20240116022526.498613-1-gaos...@loongson.cn/#r

[1]: 
https://gitee.com/openeuler/kernel/commit/5d97cff72f91f4f20a536efd60eca75bfcb78a64

Thanks.
Song Gao.

Song Gao (2):
  hw/intc/loongarch_extioi: Add extioi virt extension definition
  hw/loongarch/virt: Enable extioi virt extension

 include/hw/intc/loongarch_extioi.h |  21 ++
 include/hw/loongarch/virt.h|   2 +
 target/loongarch/cpu.h |   1 +
 hw/intc/loongarch_extioi.c |  92 ++-
 hw/loongarch/virt.c| 117 +
 5 files changed, 215 insertions(+), 18 deletions(-)

-- 
2.25.1




[PATCH v2 2/2] hw/loongarch/virt: Enable extioi virt extension

2024-05-14 Thread Song Gao
This patch adds a new board attribute 'v-eiointc'.
A value of true enables the virt extended I/O interrupt controller.
VMs working in kvm mode have 'v-eiointc' enabled by default.

Signed-off-by: Song Gao 
---
 include/hw/loongarch/virt.h |   2 +
 target/loongarch/cpu.h  |   1 +
 hw/loongarch/virt.c | 117 +++-
 3 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 2c4f5cf9c8..433e7dd7f7 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -50,11 +50,13 @@ struct LoongArchVirtMachineState {
 Notifier machine_done;
 Notifier powerdown_notifier;
 OnOffAutoacpi;
+OnOffAutoveiointc;
 char *oem_id;
 char *oem_table_id;
 DeviceState  *acpi_ged;
 int  fdt_size;
 DeviceState *platform_bus_dev;
+DeviceState  *extioi;
 PCIBus   *pci_bus;
 PFlashCFI01  *flash[2];
 MemoryRegion system_iocsr;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 41b8e6d96d..6c41fafb70 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -36,6 +36,7 @@
 #define CPUNAME_REG 0x20
 #define MISC_FUNC_REG   0x420
 #define IOCSRM_EXTIOI_EN48
+#define IOCSRM_EXTIOI_INT_ENCODE 49
 
 #define IOCSR_MEM_SIZE  0x428
 
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 95f9ed5cae..f7468d61ae 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -11,6 +11,7 @@
 #include "hw/boards.h"
 #include "hw/char/serial.h"
 #include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
@@ -47,6 +48,31 @@
 #include "hw/block/flash.h"
 #include "qemu/error-report.h"
 
+static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
+{
+if (lvms->veiointc == ON_OFF_AUTO_OFF) {
+return false;
+}
+return true;
+}
+
+static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+OnOffAuto veiointc = lvms->veiointc;
+
+visit_type_OnOffAuto(v, name, &veiointc, errp);
+}
+
+static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
+}
+
 static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
const char *name,
const char *alias_prop_name)
@@ -724,9 +750,17 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
 /* Create EXTIOI device */
 extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
 qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
+if (virt_is_veiointc_enabled(lvms)) {
+qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
+}
 sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
 memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
-   sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+if (virt_is_veiointc_enabled(lvms)) {
+memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
+}
+lvms->extioi = extioi;
 
 /*
  * connect ext irq to the cpu irq
@@ -833,38 +867,85 @@ static void virt_firmware_init(LoongArchVirtMachineState 
*lvms)
 }
 }
 
-
-static void virt_iocsr_misc_write(void *opaque, hwaddr addr,
-  uint64_t val, unsigned size)
+static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
 {
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
+uint64_t features;
+
+switch (addr) {
+case MISC_FUNC_REG:
+if (!virt_is_veiointc_enabled(lvms)) {
+return MEMTX_OK;
+}
+
+features = address_space_ldl(&lvms->as_iocsr,
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
+ attrs, NULL);
+if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
+features |= BIT(EXTIOI_ENABLE);
+}
+if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
+features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
+}
+
+address_space_stl(&lvms->as_iocsr,
+  EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
+  features, attrs, NULL);
+}
+
+return MEMTX_OK;
 }
 
-static uint64_t virt_iocsr_misc_read(void *opaque

Re: [PATCH] target/riscv: rvzicbo: Fixup CBO extension register calculation

2024-05-14 Thread Daniel Henrique Barboza




On 5/13/24 23:39, Alistair Francis wrote:

When running the instruction

```
 cbo.flush 0(x0)
```

QEMU would segfault.

The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
allocated.

In order to fix this let's use the existing get_address()
helper. This also has the benefit of performing pointer mask
calculations on the address specified in rs1.

The pointer masking specificiation specifically states:

"""
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
"""

So this is the correct behaviour and we previously have been incorrectly
not masking the address.

Signed-off-by: Alistair Francis 
Reported-by: Fabian Thomas 
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
---


LGTM but I wonder if this is the same fix as this one sent by Phil a month
ago or so:

https://lore.kernel.org/qemu-riscv/20240419110514.69697-1-phi...@linaro.org/
("[PATCH] target/riscv: Use get_address() to get address with Zicbom 
extensions")


Thanks,

Daniel


  target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 
  1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc 
b/target/riscv/insn_trans/trans_rvzicbo.c.inc
index d5d7095903..15711c3140 100644
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
@@ -31,27 +31,35 @@
  static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
  {
  REQUIRE_ZICBOM(ctx);
-gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
+TCGv src = get_address(ctx, a->rs1, 0);
+
+gen_helper_cbo_clean_flush(tcg_env, src);
  return true;
  }
  
  static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)

  {
  REQUIRE_ZICBOM(ctx);
-gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
+TCGv src = get_address(ctx, a->rs1, 0);
+
+gen_helper_cbo_clean_flush(tcg_env, src);
  return true;
  }
  
  static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)

  {
  REQUIRE_ZICBOM(ctx);
-gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
+TCGv src = get_address(ctx, a->rs1, 0);
+
+gen_helper_cbo_inval(tcg_env, src);
  return true;
  }
  
  static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)

  {
  REQUIRE_ZICBOZ(ctx);
-gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
+TCGv src = get_address(ctx, a->rs1, 0);
+
+gen_helper_cbo_zero(tcg_env, src);
  return true;
  }




Re: [PATCH 0/3] Assorted fixes for PMU

2024-05-14 Thread Peter Maydell
On Mon, 29 Apr 2024 at 20:29, Atish Patra  wrote:
>
> This series contains few miscallenous fixes related to hpmcounters
> and related code. The first patch fixes an issue with cycle/instret
> counters overcouting while the remaining two are more for specification
> compliance.

I've noticed a number of riscv patchsets from various people
recently where the subject line for the cover letter doesn't
include any indication that it's a riscv related patchset.
For instance this one is just "Assorted fixes for PMU", which
could easily be an Arm PMU series. Could you all try to make sure
that cover letter subject lines indicate the architecture or
other subcomponent they affect, please? This helps people who
are skimming over the mailing list looking for patches relevant
to them.

thanks
-- PMM



RE: [PATCH ats_vtd v1 14/24] pci: add IOMMU operations to get address spaces and memory regions with PASID

2024-05-14 Thread Duan, Zhenzhong


>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: [PATCH ats_vtd v1 14/24] pci: add IOMMU operations to get
>address spaces and memory regions with PASID
>
>Signed-off-by: Clément Mathieu--Drif 
>---
> hw/pci/pci.c | 20 
> include/hw/pci/pci.h | 34 ++
> 2 files changed, 54 insertions(+)
>
>diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>index e5f72f9f1d..9ed788c95d 100644
>--- a/hw/pci/pci.c
>+++ b/hw/pci/pci.c
>@@ -2747,6 +2747,26 @@ AddressSpace
>*pci_device_iommu_address_space(PCIDevice *dev)
> return &address_space_memory;
> }
>
>+AddressSpace *pci_device_iommu_address_space_pasid(PCIDevice *dev,
>+   uint32_t pasid)
>+{
>+PCIBus *bus;
>+PCIBus *iommu_bus;
>+int devfn;
>+
>+if (!dev->is_master || !pcie_pasid_enabled(dev) || pasid ==
>PCI_NO_PASID) {
>+return NULL;
>+}
>+
>+pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn);
>+if (!pci_bus_bypass_iommu(bus) && iommu_bus->iommu_ops &&

This is implicitly checked in pci_device_get_iommu_bus_devfn().
Just do " if (iommu_bus) && "

Thanks
Zhenzhong

>+iommu_bus->iommu_ops->get_address_space_pasid) {
>+return iommu_bus->iommu_ops->get_address_space_pasid(bus,
>+iommu_bus->iommu_opaque, devfn, pasid);
>+}
>+return NULL;
>+}
>+
> int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice
>*hiod,
> Error **errp)
> {
>diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>index 849e391813..0c532c563c 100644
>--- a/include/hw/pci/pci.h
>+++ b/include/hw/pci/pci.h
>@@ -385,6 +385,38 @@ typedef struct PCIIOMMUOps {
>  * @devfn: device and function number
>  */
> AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int
>devfn);
>+/**
>+ * @get_address_space_pasid: same as get_address_space but returns
>an
>+ * address space with the requested PASID
>+ *
>+ * This callback is required for PASID-based operations
>+ *
>+ * @bus: the #PCIBus being accessed.
>+ *
>+ * @opaque: the data passed to pci_setup_iommu().
>+ *
>+ * @devfn: device and function number
>+ *
>+ * @pasid: the pasid associated with the requested memory region
>+ */
>+AddressSpace * (*get_address_space_pasid)(PCIBus *bus, void *opaque,
>+  int devfn, uint32_t pasid);
>+/**
>+ * @get_memory_region_pasid: get the iommu memory region for a
>given
>+ * device and pasid
>+ *
>+ * @bus: the #PCIBus being accessed.
>+ *
>+ * @opaque: the data passed to pci_setup_iommu().
>+ *
>+ * @devfn: device and function number
>+ *
>+ * @pasid: the pasid associated with the requested memory region
>+ */
>+IOMMUMemoryRegion * (*get_memory_region_pasid)(PCIBus *bus,
>+   void *opaque,
>+   int devfn,
>+   uint32_t pasid);
> /**
>  * @set_iommu_device: attach a HostIOMMUDevice to a vIOMMU
>  *
>@@ -420,6 +452,8 @@ typedef struct PCIIOMMUOps {
> } PCIIOMMUOps;
>
> AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
>+AddressSpace *pci_device_iommu_address_space_pasid(PCIDevice *dev,
>+   uint32_t pasid);
> int pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice
>*hiod,
> Error **errp);
> void pci_device_unset_iommu_device(PCIDevice *dev);
>--
>2.44.0


Re: [PATCH v2 1/3] qtest: allow SPCR acpi table changes

2024-05-14 Thread Peter Maydell
On Mon, 13 May 2024 at 11:36, Alistair Francis  wrote:
>
> On Mon, May 13, 2024 at 4:32 PM Michael S. Tsirkin  wrote:
> >
> > On Mon, May 13, 2024 at 01:55:50PM +1000, Alistair Francis wrote:
> > > On Tue, May 7, 2024 at 3:24 PM Sia Jee Heng
> > >  wrote:
> > >
> > > Can you describe why you are doing this and that it will be reverted
> > > in the commit message?
> > >
> > > Alistair
> >
> > What motivation are you asking? This follows the normal acpi test update
> > procedure.
>
> I find it clearer to have commits describe that they are disabling
> tests for a specific reason. That way it's easier to track what's
> going on.
>
> If ACPI test updates don't usually do that then that's fine with me

The only reason for the existence of this ignore-these-blobs file
is for the purpose of the commit sequence:
 * add the blobs to the whitelist
 * make a change that alters what the expected blobs are
 * regenerate the golden-reference blobs and remove the items
   from the whitelist

So we don't usually say much in the commit that is adding a blob
to the whitelist.

thanks
-- PMM



[RFC PATCH] target/loongarch/kvm: Add pmu support

2024-05-14 Thread Song Gao
This patch adds PMU support, We just sets some cpucfg6 default value
to PMU config on kvm mode, and then check the PMU config with kvm ioctl
KVM_GET_DEVICE_ATTR.
  e.g
'...  -cpu max,pmu=on,pmnum=[1-16]';
'...  -cpu max,pmu=on' (default pmnum = 4);
'...  -cpu max,pmu=off' (disable PMU)

Signed-off-by: Song Gao 
---

This patch adds the 'RFC' heading because it requires
the kernel to merge into patch[1] first

[1]: https://lore.kernel.org/all/20240507120140.3119714-1-gaos...@loongson.cn/


 target/loongarch/cpu.h|  2 +
 target/loongarch/cpu.c| 64 +++
 target/loongarch/kvm/kvm.c| 55 ++-
 target/loongarch/loongarch-qmp-cmds.c |  2 +-
 4 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 6c41fafb70..d834649106 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -184,6 +184,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4)
 FIELD(CPUCFG6, PMBITS, 8, 6)
 FIELD(CPUCFG6, UPM, 14, 1)
 
+#define PMNUM_MAX 16
+
 /* cpucfg[16] bits */
 FIELD(CPUCFG16, L1_IUPRE, 0, 1)
 FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index a0cad53676..c78ee3f0b1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -8,6 +8,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qemu/qemu-print.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "sysemu/qtest.h"
@@ -19,6 +20,7 @@
 #include "internals.h"
 #include "fpu/softfloat-helpers.h"
 #include "cpu-csr.h"
+#include "qapi/visitor.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/reset.h"
 #endif
@@ -421,6 +423,14 @@ static void loongarch_la464_initfn(Object *obj)
 data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1);
 env->cpucfg[5] = data;
 
+if (kvm_enabled()) {
+data = 0;
+data = FIELD_DP32(data, CPUCFG6, PMP, 1);
+data = FIELD_DP32(data, CPUCFG6, PMNUM, 3);
+data = FIELD_DP32(data, CPUCFG6, PMBITS, 63);
+env->cpucfg[6] = data;
+}
+
 data = 0;
 data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1);
 data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1);
@@ -643,6 +653,48 @@ static void loongarch_set_lasx(Object *obj, bool value, 
Error **errp)
 }
 }
 
+static bool loongarch_get_pmu(Object *obj, Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+return  !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP));
+}
+
+static void loongarch_set_pmu(Object *obj, bool value,  Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value);
+}
+
+static void loongarch_get_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM);
+
+visit_type_uint32(v, name, &value, errp);
+}
+
+static void loongarch_set_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t *value= opaque;
+
+if (!visit_type_uint32(v, name, value, errp)) {
+return;
+}
+if ((*value <= PMNUM_MAX) && (*value > 0)) {
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 
*value -1);
+} else {
+error_report("Performance counter number need be in [1- %d]\n", 
PMNUM_MAX);
+exit(EXIT_FAILURE);
+}
+}
+
 void loongarch_cpu_post_init(Object *obj)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -655,6 +707,18 @@ void loongarch_cpu_post_init(Object *obj)
 object_property_add_bool(obj, "lasx", loongarch_get_lasx,
  loongarch_set_lasx);
 }
+
+if (kvm_enabled()) {
+object_property_add_bool(obj, "pmu", loongarch_get_pmu,
+ loongarch_set_pmu);
+if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) {
+uint32_t value = 4;
+object_property_add(obj, "pmnum", "uint32",
+loongarch_get_pmnum,
+loongarch_set_pmnum, NULL,
+(void *)&value);
+}
+}
 }
 
 static void loongarch_cpu_init(Object *obj)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index bc75552d0f..a9f9020071 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -556,6 +556,53 @@ static int kvm_check_cpucfg2(CPUState *cs)
 return ret;
 }
 
+static int kvm_check_cpucfg6(CPUState *cs)
+{
+int ret;
+uint64_t val;
+struct kvm_device_attr attr = {
+.group = KVM_LOONGARCH_VCPU_CPUCFG,
+.attr = 6,
+.addr = (uint64_t)&val,
+};
+LoongArchCPU *cpu = LOONGARCH_CPU(c

Re: [PATCH 0/3] Assorted fixes for PMU

2024-05-14 Thread Alistair Francis
On Tue, May 14, 2024 at 5:15 PM Atish Kumar Patra  wrote:
>
> On Mon, May 13, 2024 at 11:29 PM Alistair Francis  
> wrote:
> >
> > On Tue, Apr 30, 2024 at 5:29 AM Atish Patra  wrote:
> > >
> > > This series contains few miscallenous fixes related to hpmcounters
> > > and related code. The first patch fixes an issue with cycle/instret
> > > counters overcouting while the remaining two are more for specification
> > > compliance.
> > >
> > > Signed-off-by: Atish Patra 
> > > ---
> > > Atish Patra (3):
> > >   target/riscv: Save counter values during countinhibit update
> > >   target/riscv: Enforce WARL behavior for scounteren/hcounteren
> > >   target/riscv: Fix the predicate functions for mhpmeventhX CSRs
> >
> > Thanks!
> >
> > Applied to riscv-to-apply.next
> >
>
> Hi Alistair,
> Thanks for your review. But the patch 1 had some comments about
> vmstate which needs updating.

Ah, I did read the comments but forgot that you were going to bump the version.

> We also found a few more fixes that I was planning to include in v2.

I found that patch `target/riscv: Save counter values during
countinhibit update` gives me this error as well

../target/riscv/csr.c: In function ‘write_mcountinhibit’:
../target/riscv/csr.c:1981:44: error: too few arguments to function ‘get_ticks’
1981 | counter->mhpmcounter_val = get_ticks(false) -
 |^
../target/riscv/csr.c:765:21: note: declared here
 765 | static target_ulong get_ticks(bool shift, bool instructions)
 | ^
../target/riscv/csr.c:1985:49: error: too few arguments to function ‘get_ticks’
1985 | counter->mhpmcounterh_val = get_ticks(false) -
 | ^
../target/riscv/csr.c:765:21: note: declared here
 765 | static target_ulong get_ticks(bool shift, bool instructions)
 | ^



>
> I can send a separate fixes series on top riscv-to-apply.next or this
> series can be dropped for the time being.

I'm going to drop it due to the build error above

Alistair

> You can queue it v2 later. Let me know what you prefer.
>
>
> > Alistair
> >
> > >
> > >  target/riscv/cpu.h |   1 -
> > >  target/riscv/csr.c | 111 
> > > ++---
> > >  target/riscv/machine.c |   1 -
> > >  3 files changed, 68 insertions(+), 45 deletions(-)
> > > ---
> > > base-commit: 1642f979a71a5667a05070be2df82f48bd43ad7a
> > > change-id: 20240428-countinhibit_fix-c6a1c11f4375
> > > --
> > > Regards,
> > > Atish patra
> > >
> > >



[PATCH 3/3] qerror: QERR_QGA_COMMAND_FAILED is no longer used, drop

2024-05-14 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 include/qapi/qmp/qerror.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 00b18e9082..390590bb81 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -29,9 +29,6 @@
 #define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
 "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", 
maximum: %" PRId64 ")"
 
-#define QERR_QGA_COMMAND_FAILED \
-"Guest agent command failed, error was '%s'"
-
 #define QERR_UNSUPPORTED \
 "this feature or command is not currently supported"
 
-- 
2.45.0




[PATCH 0/3] error: Eliminate QERR_QGA_COMMAND_FAILED

2024-05-14 Thread Markus Armbruster
Markus Armbruster (3):
  qga-win32: Improve guest-set-user-password, guest-file-open errors
  qga: Shorten several error messages
  qerror: QERR_QGA_COMMAND_FAILED is no longer used, drop

 include/qapi/qmp/qerror.h |  3 ---
 qga/commands-win32.c  | 41 ---
 qga/commands.c|  5 ++---
 3 files changed, 19 insertions(+), 30 deletions(-)

-- 
2.45.0




[PATCH 2/3] qga: Shorten several error messages

2024-05-14 Thread Markus Armbruster
Some, but not all error messages are of the form

Guest agent command failed, error was ''

For instance, command guest-exec can fail with an error message like

Guest agent command failed, error was 'Failed to execute child process 
“/bin/invalid-cmd42” (No such file or directory)'

Shorten this to just just the actual error message.  The guest-exec
example becomes

Failed to execute child process “/bin/invalid-cmd42” (No such file or 
directory)

Signed-off-by: Markus Armbruster 
---
 qga/commands-win32.c | 24 
 qga/commands.c   |  5 ++---
 2 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index ed31077457..0d1b836e87 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -278,8 +278,7 @@ static void acquire_privilege(const char *name, Error 
**errp)
 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
 {
 if (!LookupPrivilegeValue(NULL, name, &priv.Privileges[0].Luid)) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "no luid for requested privilege");
+error_setg(errp, "no luid for requested privilege");
 goto out;
 }
 
@@ -287,14 +286,12 @@ static void acquire_privilege(const char *name, Error 
**errp)
 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
 if (!AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, 0)) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "unable to acquire requested privilege");
+error_setg(errp, "unable to acquire requested privilege");
 goto out;
 }
 
 } else {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "failed to open privilege token");
+error_setg(errp, "failed to open privilege token");
 }
 
 out:
@@ -308,8 +305,7 @@ static void execute_async(DWORD WINAPI (*func)(LPVOID), 
LPVOID opaque,
 {
 HANDLE thread = CreateThread(NULL, 0, func, opaque, 0, NULL);
 if (!thread) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "failed to dispatch asynchronous command");
+error_setg(errp, "failed to dispatch asynchronous command");
 }
 }
 
@@ -1418,22 +1414,19 @@ static void check_suspend_mode(GuestSuspendMode mode, 
Error **errp)
 
 ZeroMemory(&sys_pwr_caps, sizeof(sys_pwr_caps));
 if (!GetPwrCapabilities(&sys_pwr_caps)) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "failed to determine guest suspend capabilities");
+error_setg(errp, "failed to determine guest suspend capabilities");
 return;
 }
 
 switch (mode) {
 case GUEST_SUSPEND_MODE_DISK:
 if (!sys_pwr_caps.SystemS4) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "suspend-to-disk not supported by OS");
+error_setg(errp, "suspend-to-disk not supported by OS");
 }
 break;
 case GUEST_SUSPEND_MODE_RAM:
 if (!sys_pwr_caps.SystemS3) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "suspend-to-ram not supported by OS");
+error_setg(errp, "suspend-to-ram not supported by OS");
 }
 break;
 default:
@@ -2175,8 +2168,7 @@ static void ga_get_win_version(RTL_OSVERSIONINFOEXW 
*info, Error **errp)
 HMODULE module = GetModuleHandle("ntdll");
 PVOID fun = GetProcAddress(module, "RtlGetVersion");
 if (fun == NULL) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-"Failed to get address of RtlGetVersion");
+error_setg(errp, "Failed to get address of RtlGetVersion");
 return;
 }
 
diff --git a/qga/commands.c b/qga/commands.c
index 88c1c99fe5..27b16313ea 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -475,7 +475,7 @@ GuestExec *qmp_guest_exec(const char *path,
 guest_exec_task_setup, &has_merge, &pid, input_data ? &in_fd : 
NULL,
 has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr);
 if (!ret) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message);
+error_setg(errp, "%s", gerr->message);
 g_error_free(gerr);
 goto done;
 }
@@ -586,8 +586,7 @@ GuestTimezone *qmp_guest_get_timezone(Error **errp)
 info = g_new0(GuestTimezone, 1);
 tz = g_time_zone_new_local();
 if (tz == NULL) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED,
-   "Couldn't retrieve local timezone");
+error_setg(errp, "Couldn't retrieve local timezone");
 goto error;
 }
 
-- 
2.45.0




[PATCH v2] target/riscv: Remove experimental prefix from "B" extension

2024-05-14 Thread Rob Bradford
This extension has now been ratified:
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
removed.

Since this is now a ratified extension add it to the list of extensions
included in the "max" CPU variant.

Signed-off-by: Rob Bradford 
Reviewed-by: Andrew Jones 
---
 target/riscv/cpu.c | 2 +-
 target/riscv/tcg/tcg-cpu.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index eb1a2e7d6d..861d9f4350 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1396,7 +1396,7 @@ static const MISAExtInfo misa_ext_info_arr[] = {
 MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
 MISA_EXT_INFO(RVV, "v", "Vector operations"),
 MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
-MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
+MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
 };
 
 static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 40054a391a..164a13ad0f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1281,7 +1281,7 @@ static void riscv_init_max_cpu_extensions(Object *obj)
 const RISCVCPUMultiExtConfig *prop;
 
 /* Enable RVG, RVJ and RVV that are disabled by default */
-riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
+riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
 
 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
 isa_ext_update_enabled(cpu, prop->offset, true);
-- 
2.44.0




Re: [PATCH 2/3] qga: Shorten several error messages

2024-05-14 Thread Markus Armbruster
Markus Armbruster  writes:

> Some, but not all error messages are of the form
>
> Guest agent command failed, error was ''
>
> For instance, command guest-exec can fail with an error message like
>
> Guest agent command failed, error was 'Failed to execute child process 
> “/bin/invalid-cmd42” (No such file or directory)'
>
> Shorten this to just just the actual error message.  The guest-exec
> example becomes
>
> Failed to execute child process “/bin/invalid-cmd42” (No such file or 
> directory)
>
> Signed-off-by: Markus Armbruster 

[...]

To be squashed into the patch:

diff --git a/qga/commands.c b/qga/commands.c
index 27b16313ea..5a5fad31f8 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -15,7 +15,6 @@
 #include "guest-agent-core.h"
 #include "qga-qapi-commands.h"
 #include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
 #include "qemu/base64.h"
 #include "qemu/cutils.h"
 #include "commands-common.h"




[PATCH 1/3] qga-win32: Improve guest-set-user-password, guest-file-open errors

2024-05-14 Thread Markus Armbruster
When guest-set-user-password's argument @password can't be converted
from UTF-8 to UTF-16, we report something like

Guest agent command failed, error was 'Invalid sequence in conversion input'

Improve this to

can't convert 'password' to UTF-16: Invalid sequence in conversion input

Likewise for argument @username, and guest-file-open argument @path,
even though I'm not sure you can actually get invalid input past the
QMP core there.

Signed-off-by: Markus Armbruster 
---
 qga/commands-win32.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 6fee0e1e6f..ed31077457 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -217,6 +217,9 @@ int64_t qmp_guest_file_open(const char *path, const char 
*mode, Error **errp)
 
 w_path = g_utf8_to_utf16(path, -1, NULL, NULL, &gerr);
 if (!w_path) {
+error_setg(errp, "can't convert 'path' to UTF-16: %s",
+   gerr->message);
+g_error_free(gerr);
 goto done;
 }
 
@@ -244,10 +247,6 @@ int64_t qmp_guest_file_open(const char *path, const char 
*mode, Error **errp)
 slog("guest-file-open, handle: % " PRId64, fd);
 
 done:
-if (gerr) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message);
-g_error_free(gerr);
-}
 g_free(w_path);
 return fd;
 }
@@ -1946,11 +1945,17 @@ void qmp_guest_set_user_password(const char *username,
 
 user = g_utf8_to_utf16(username, -1, NULL, NULL, &gerr);
 if (!user) {
+error_setg(errp, "can't convert 'username' to UTF-16: %s",
+   gerr->message);
+g_error_free(gerr);
 goto done;
 }
 
 wpass = g_utf8_to_utf16(rawpasswddata, -1, NULL, NULL, &gerr);
 if (!wpass) {
+error_setg(errp, "can't convert 'password' to UTF-16: %s",
+   gerr->message);
+g_error_free(gerr);
 goto done;
 }
 
@@ -1966,10 +1971,6 @@ void qmp_guest_set_user_password(const char *username,
 }
 
 done:
-if (gerr) {
-error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message);
-g_error_free(gerr);
-}
 g_free(user);
 g_free(wpass);
 g_free(rawpasswddata);
-- 
2.45.0




Re: [PATCH v2] target/riscv: Remove experimental prefix from "B" extension

2024-05-14 Thread LIU Zhiwei



On 2024/5/14 19:02, Rob Bradford wrote:

This extension has now been ratified:
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
removed.

Since this is now a ratified extension add it to the list of extensions
included in the "max" CPU variant.

Signed-off-by: Rob Bradford 
Reviewed-by: Andrew Jones 
---
  target/riscv/cpu.c | 2 +-
  target/riscv/tcg/tcg-cpu.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index eb1a2e7d6d..861d9f4350 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1396,7 +1396,7 @@ static const MISAExtInfo misa_ext_info_arr[] = {
  MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
  MISA_EXT_INFO(RVV, "v", "Vector operations"),
  MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
-MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
+MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
  };
  
  static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 40054a391a..164a13ad0f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1281,7 +1281,7 @@ static void riscv_init_max_cpu_extensions(Object *obj)
  const RISCVCPUMultiExtConfig *prop;
  
  /* Enable RVG, RVJ and RVV that are disabled by default */

-riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
+riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);

Reviewed-by: LIU Zhiwei 

Zhiwei
  
  for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {

  isa_ext_update_enabled(cpu, prop->offset, true);




[PATCH] hw/riscv/virt: Add hotplugging and virtio-md-pci support

2024-05-14 Thread Björn Töpel
From: Björn Töpel 

Virtio-based memory devices allows for dynamic resizing of virtual
machine memory, and requires proper hotplugging (add/remove) support
to work.

Enable virtio-md-pci with the corresponding missing hotplugging
callbacks for the RISC-V "virt" machine.

Signed-off-by: Björn Töpel 
---
This is basic support for MHP that works with DT. There some minor
ACPI SRAT plumbing in there as well. Ideally we'd like proper ACPI MHP
support as well. I have a branch [1], where I've applied this patch,
plus ACPI GED/PC-DIMM MHP support on top of Sunil's QEMU branch
(contains some ACPI DSDT additions) [2], for the curious/brave ones.
However, the ACPI MHP support this is not testable on upstream Linux
yet (ACPI AIA support, and ACPI NUMA SRAT series are ongoing).

I'll follow-up with proper ACPI GED/PC-DIMM MHP patches, once the
dependencies land (Linux kernel and QEMU).

I'll post the Linux MHP/virtio-mem v2 patches later this week!


Cheers,
Björn

[1] https://github.com/bjoto/qemu/commits/virtio-mem-pc-dimm-mhp-acpi/
[2] 
https://lore.kernel.org/linux-riscv/20240501121742.1215792-1-suni...@ventanamicro.com/
---
 hw/riscv/Kconfig   |  2 ++
 hw/riscv/virt-acpi-build.c |  7 +
 hw/riscv/virt.c| 64 +-
 hw/virtio/virtio-mem.c |  2 +-
 4 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index a2030e3a6ff0..08f82dbb681a 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -56,6 +56,8 @@ config RISCV_VIRT
 select PLATFORM_BUS
 select ACPI
 select ACPI_PCI
+select VIRTIO_MEM_SUPPORTED
+select VIRTIO_PMEM_SUPPORTED
 
 config SHAKTI_C
 bool
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 0925528160f8..6dc3baa9ec86 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -610,6 +610,13 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
RISCVVirtState *vms)
 }
 }
 
+if (ms->device_memory) {
+build_srat_memory(table_data, ms->device_memory->base,
+  memory_region_size(&ms->device_memory->mr),
+  ms->numa_state->num_nodes - 1,
+  MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
+}
+
 acpi_table_end(linker, &table);
 }
 
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4fdb66052587..16c2bdbfe6b6 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -53,6 +53,8 @@
 #include "hw/pci-host/gpex.h"
 #include "hw/display/ramfb.h"
 #include "hw/acpi/aml-build.h"
+#include "hw/mem/memory-device.h"
+#include "hw/virtio/virtio-mem-pci.h"
 #include "qapi/qapi-visit-common.h"
 #include "hw/virtio/virtio-iommu.h"
 
@@ -1407,6 +1409,7 @@ static void virt_machine_init(MachineState *machine)
 DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip;
 int i, base_hartid, hart_count;
 int socket_count = riscv_socket_count(machine);
+hwaddr device_memory_base, device_memory_size;
 
 /* Check socket count limit */
 if (VIRT_SOCKETS_MAX < socket_count) {
@@ -1553,6 +1556,25 @@ static void virt_machine_init(MachineState *machine)
 memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
 mask_rom);
 
+device_memory_base = ROUND_UP(s->memmap[VIRT_DRAM].base + 
machine->ram_size,
+  GiB);
+device_memory_size = machine->maxram_size - machine->ram_size;
+
+if (riscv_is_32bit(&s->soc[0])) {
+hwaddr memtop = device_memory_base + ROUND_UP(device_memory_size, GiB);
+
+if (memtop > UINT32_MAX) {
+error_report("Memory exceeds 32-bit limit by %lu bytes",
+ memtop - UINT32_MAX);
+exit(EXIT_FAILURE);
+}
+}
+
+if (device_memory_size > 0) {
+machine_memory_devices_init(machine, device_memory_base,
+device_memory_size);
+}
+
 /*
  * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the
  * device tree cannot be altered and we get FDT_ERR_NOSPACE.
@@ -1712,12 +1734,21 @@ static HotplugHandler 
*virt_machine_get_hotplug_handler(MachineState *machine,
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 
 if (device_is_dynamic_sysbus(mc, dev) ||
-object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
+object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
 return HOTPLUG_HANDLER(machine);
 }
 return NULL;
 }
 
+static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
+virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
+}
+}
+
 static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
  

[PATCH] target/loongarch/kvm: fpu save the vreg registers high 192bit

2024-05-14 Thread Song Gao
On kvm side, get_fpu/set_fpu save the vreg registers high 192bits,
but QEMU missing.

Signed-off-by: Song Gao 
---
 target/loongarch/kvm/kvm.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index a9f9020071..0b5dbb7ed8 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs)
 env->fcsr0 = fpu.fcsr;
 for (i = 0; i < 32; i++) {
 env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
+env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
+env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
+env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
 }
 for (i = 0; i < 8; i++) {
 env->cf[i] = fpu.fcc & 0xFF;
@@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
 fpu.fcc = 0;
 for (i = 0; i < 32; i++) {
 fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
+fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
+fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
+fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
 }
 
 for (i = 0; i < 8; i++) {
-- 
2.25.1




Re: [PATCH] hw/loongarch: Add VM mode in IOCSR feature register in kvm mode

2024-05-14 Thread gaosong

在 2024/5/14 上午10:51, Bibo Mao 写道:

If VM runs in kvm mode, VM mode is added in IOCSR feature register.
So guest can detect kvm hypervisor type and enable possible pv functions.

Signed-off-by: Bibo Mao 
---

Reviewed-by: Song Gao 

Thanks.
Song Gao

  hw/loongarch/virt.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index d87d9be576..44bcf25aee 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -10,6 +10,7 @@
  #include "qapi/error.h"
  #include "hw/boards.h"
  #include "hw/char/serial.h"
+#include "sysemu/kvm.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/qtest.h"
  #include "sysemu/runstate.h"
@@ -840,18 +841,23 @@ static void virt_iocsr_misc_write(void *opaque, hwaddr 
addr,
  
  static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size)

  {
+uint64_t ret;
+
  switch (addr) {
  case VERSION_REG:
  return 0x11ULL;
  case FEATURE_REG:
-return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
-   1ULL << IOCSRF_CSRIPI;
+ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
+if (kvm_enabled()) {
+ret |= BIT(IOCSRF_VM);
+}
+return ret;
  case VENDOR_REG:
  return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
  case CPUNAME_REG:
  return 0x303030354133ULL; /* "3A5000" */
  case MISC_FUNC_REG:
-return 1ULL << IOCSRM_EXTIOI_EN;
+return BIT_ULL(IOCSRM_EXTIOI_EN);
  }
  return 0ULL;
  }





RE: [PATCH v2 2/3] hw/acpi: Upgrade ACPI SPCR table to support SPCR table version 4 format

2024-05-14 Thread JeeHeng Sia



> -Original Message-
> From: Sunil V L 
> Sent: Monday, May 13, 2024 1:16 PM
> To: JeeHeng Sia 
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; peter.mayd...@linaro.org; shannon.zha...@gmail.com; 
> pal...@dabbelt.com; alistair.fran...@wdc.com;
> bin.m...@windriver.com; liwei1...@gmail.com; dbarb...@ventanamicro.com; 
> zhiwei_...@linux.alibaba.com
> Subject: Re: [PATCH v2 2/3] hw/acpi: Upgrade ACPI SPCR table to support SPCR 
> table version 4 format
> 
> Hi Sia Jee Heng,
> 
> On Mon, May 06, 2024 at 10:22:11PM -0700, Sia Jee Heng wrote:
> > Update the SPCR table to accommodate the SPCR Table version 4 [1].
> > The SPCR table has been modified to adhere to the version 4 format [2].
> >
> > [1]: 
> > https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
> > [2]: https://github.com/acpica/acpica/pull/931
> >
> > Signed-off-by: Sia Jee Heng 
> > ---
> >  hw/acpi/aml-build.c | 14 +++---
> >  hw/arm/virt-acpi-build.c| 10 --
> >  hw/riscv/virt-acpi-build.c  | 12 +---
> >  include/hw/acpi/acpi-defs.h |  7 +--
> >  include/hw/acpi/aml-build.h |  2 +-
> >  5 files changed, 34 insertions(+), 11 deletions(-)
> >
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index 6d4517cfbe..7c43573eef 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1996,7 +1996,7 @@ static void build_processor_hierarchy_node(GArray 
> > *tbl, uint32_t flags,
> >
> >  void build_spcr(GArray *table_data, BIOSLinker *linker,
> >  const AcpiSpcrData *f, const uint8_t rev,
> > -const char *oem_id, const char *oem_table_id)
> > +const char *oem_id, const char *oem_table_id, const char 
> > *name)
> >  {
> >  AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
> >  .oem_table_id = oem_table_id };
> > @@ -2042,8 +2042,16 @@ void build_spcr(GArray *table_data, BIOSLinker 
> > *linker,
> >  build_append_int_noprefix(table_data, f->pci_flags, 4);
> >  /* PCI Segment */
> >  build_append_int_noprefix(table_data, f->pci_segment, 1);
> > -/* Reserved */
> > -build_append_int_noprefix(table_data, 0, 4);
> > +/* UartClkFreq */
> > +build_append_int_noprefix(table_data, f->uart_clk_freq, 4);
> > +/* PreciseBaudrate */
> > +build_append_int_noprefix(table_data, f->precise_baudrate, 4);
> > +/* NameSpaceStringLength */
> > +build_append_int_noprefix(table_data, f->namespace_string_length, 2);
> > +/* NameSpaceStringOffset */
> > +build_append_int_noprefix(table_data, f->namespace_string_offset, 2);
> > +/* NamespaceString[] */
> > +g_array_append_vals(table_data, name, f->namespace_string_length);
> >
> Is it possible to check the revision here and add new fields only if the
> revision supports it? ARM maintainers are better to comment but IMO, we
> better keep ARM's SPCR in the same current version since I don't know
> how consumers like linux (and other OSs) react to the change.
Hi Sunil, there is only one prebuilt SPCR binary. By doing this, the qtest
will fail. I think I will let ARM maintainer to comment.
> 
> Thanks!
> Sunil
> >  acpi_table_end(linker, &table);
> >  }
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index 6a1bde61ce..cb345e8659 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -428,11 +428,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >
> >  /*
> >   * Serial Port Console Redirection Table (SPCR)
> > - * Rev: 1.07
> > + * Rev: 1.10
> >   */
> >  static void
> >  spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> >  {
> > +const char name[] = ".";
> >  AcpiSpcrData serial = {
> >  .interface_type = 3,   /* ARM PL011 UART */
> >  .base_addr.id = AML_AS_SYSTEM_MEMORY,
> > @@ -456,9 +457,14 @@ spcr_setup(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >  .pci_function = 0,
> >  .pci_flags = 0,
> >  .pci_segment = 0,
> > +.uart_clk_freq = 0,
> > +.precise_baudrate = 0,
> > +.namespace_string_length = sizeof(name),
> > +.namespace_string_offset = 88,
> >  };
> >
> > -build_spcr(table_data, linker, &serial, 2, vms->oem_id, 
> > vms->oem_table_id);
> > +build_spcr(table_data, linker, &serial, 4, vms->oem_id, 
> > vms->oem_table_id,
> > +   name);
> >  }
> >
> >  /*
> > diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> > index 0925528160..5fa3942491 100644
> > --- a/hw/riscv/virt-acpi-build.c
> > +++ b/hw/riscv/virt-acpi-build.c
> > @@ -176,14 +176,15 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
> > *uart_memmap,
> >
> >  /*
> >   * Serial Port Console Redirection Table (SPCR)
> > - * Rev: 1.07

RE: [PATCH v2 2/3] hw/acpi: Upgrade ACPI SPCR table to support SPCR table version 4 format

2024-05-14 Thread JeeHeng Sia



> -Original Message-
> From: Michael S. Tsirkin 
> Sent: Monday, May 13, 2024 2:31 PM
> To: JeeHeng Sia 
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; qemu-ri...@nongnu.org; 
> imamm...@redhat.com; anisi...@redhat.com;
> peter.mayd...@linaro.org; shannon.zha...@gmail.com; suni...@ventanamicro.com; 
> pal...@dabbelt.com; alistair.fran...@wdc.com;
> bin.m...@windriver.com; liwei1...@gmail.com; dbarb...@ventanamicro.com; 
> zhiwei_...@linux.alibaba.com
> Subject: Re: [PATCH v2 2/3] hw/acpi: Upgrade ACPI SPCR table to support SPCR 
> table version 4 format
> 
> On Mon, May 06, 2024 at 10:22:11PM -0700, Sia Jee Heng wrote:
> > Update the SPCR table to accommodate the SPCR Table version 4 [1].
> > The SPCR table has been modified to adhere to the version 4 format [2].
> >
> > [1]: 
> > https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
> > [2]: https://github.com/acpica/acpica/pull/931
> >
> > Signed-off-by: Sia Jee Heng 
> 
> What does this achieve? We don't normally change unless it gets
> us some useful feature.
The changes in Table 4 primarily include the addition of RISC-V support
and modifications to the Interrupt Type field. Additionally, new fields
added are Precise Baud Rate, NamespaceStringLength, NamespaceStringOffset,
and NamespaceString[].
> 
> 
> > ---
> >  hw/acpi/aml-build.c | 14 +++---
> >  hw/arm/virt-acpi-build.c| 10 --
> >  hw/riscv/virt-acpi-build.c  | 12 +---
> >  include/hw/acpi/acpi-defs.h |  7 +--
> >  include/hw/acpi/aml-build.h |  2 +-
> >  5 files changed, 34 insertions(+), 11 deletions(-)
> >
> > diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
> > index 6d4517cfbe..7c43573eef 100644
> > --- a/hw/acpi/aml-build.c
> > +++ b/hw/acpi/aml-build.c
> > @@ -1996,7 +1996,7 @@ static void build_processor_hierarchy_node(GArray 
> > *tbl, uint32_t flags,
> >
> >  void build_spcr(GArray *table_data, BIOSLinker *linker,
> >  const AcpiSpcrData *f, const uint8_t rev,
> > -const char *oem_id, const char *oem_table_id)
> > +const char *oem_id, const char *oem_table_id, const char 
> > *name)
> >  {
> >  AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
> >  .oem_table_id = oem_table_id };
> > @@ -2042,8 +2042,16 @@ void build_spcr(GArray *table_data, BIOSLinker 
> > *linker,
> >  build_append_int_noprefix(table_data, f->pci_flags, 4);
> >  /* PCI Segment */
> >  build_append_int_noprefix(table_data, f->pci_segment, 1);
> > -/* Reserved */
> > -build_append_int_noprefix(table_data, 0, 4);
> > +/* UartClkFreq */
> > +build_append_int_noprefix(table_data, f->uart_clk_freq, 4);
> > +/* PreciseBaudrate */
> > +build_append_int_noprefix(table_data, f->precise_baudrate, 4);
> > +/* NameSpaceStringLength */
> > +build_append_int_noprefix(table_data, f->namespace_string_length, 2);
> > +/* NameSpaceStringOffset */
> > +build_append_int_noprefix(table_data, f->namespace_string_offset, 2);
> > +/* NamespaceString[] */
> > +g_array_append_vals(table_data, name, f->namespace_string_length);
> >
> >  acpi_table_end(linker, &table);
> >  }
> > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> > index 6a1bde61ce..cb345e8659 100644
> > --- a/hw/arm/virt-acpi-build.c
> > +++ b/hw/arm/virt-acpi-build.c
> > @@ -428,11 +428,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >
> >  /*
> >   * Serial Port Console Redirection Table (SPCR)
> > - * Rev: 1.07
> > + * Rev: 1.10
> >   */
> >  static void
> >  spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> >  {
> > +const char name[] = ".";
> >  AcpiSpcrData serial = {
> >  .interface_type = 3,   /* ARM PL011 UART */
> >  .base_addr.id = AML_AS_SYSTEM_MEMORY,
> > @@ -456,9 +457,14 @@ spcr_setup(GArray *table_data, BIOSLinker *linker, 
> > VirtMachineState *vms)
> >  .pci_function = 0,
> >  .pci_flags = 0,
> >  .pci_segment = 0,
> > +.uart_clk_freq = 0,
> > +.precise_baudrate = 0,
> > +.namespace_string_length = sizeof(name),
> > +.namespace_string_offset = 88,
> >  };
> >
> > -build_spcr(table_data, linker, &serial, 2, vms->oem_id, 
> > vms->oem_table_id);
> > +build_spcr(table_data, linker, &serial, 4, vms->oem_id, 
> > vms->oem_table_id,
> > +   name);
> >  }
> >
> >  /*
> > diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> > index 0925528160..5fa3942491 100644
> > --- a/hw/riscv/virt-acpi-build.c
> > +++ b/hw/riscv/virt-acpi-build.c
> > @@ -176,14 +176,15 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
> > *uart_memmap,
> >
> >  /*
> >   * Serial Port Console Redirection Table (SPCR)
> > - * Rev: 1.07
> > + * Rev: 1.10
> >   */
> >
> >  static void
> >  spcr_setup(GArray *table_data, BIOSLinker *li

Re: [PATCH v5 10/10] vfio: Extend vfio_set_migration_error() with Error* argument

2024-05-14 Thread Cédric Le Goater

On 5/13/24 16:26, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


vfio_set_migration_error() sets the 'return' error on the migration
stream if a migration is in progress. To improve error reporting, add
a new Error* argument to also set the Error object on the migration
stream, if a migration is progress.

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

  Changes in v5:

  - Rebased on 20c64c8a51a4 ("migration: migration_file_set_error")

  hw/vfio/common.c | 37 ++---
  1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
c3d82a9d6e434e33f361e4b96157bf912d5c3a2f..4cf3e13a8439bd1b9a032e9d4e75df676eba457b
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -147,10 +147,10 @@ bool vfio_viommu_preset(VFIODevice *vbasedev)
  return vbasedev->bcontainer->space->as != &address_space_memory;
  }

-static void vfio_set_migration_error(int err)
+static void vfio_set_migration_error(int ret, Error *err)
  {
  if (migration_is_setup_or_active()) {
-    migration_file_set_error(err, NULL);
+    migration_file_set_error(ret, err);
  }
  }

@@ -295,9 +295,10 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  iova, iova + iotlb->addr_mask);

  if (iotlb->target_as != &address_space_memory) {
-    error_report("Wrong target AS \"%s\", only system memory is allowed",
- iotlb->target_as->name ? iotlb->target_as->name : "none");
-    vfio_set_migration_error(-EINVAL);
+    error_setg(&local_err,
+   "Wrong target AS \"%s\", only system memory is allowed",
+   iotlb->target_as->name ? iotlb->target_as->name : "none");
+    vfio_set_migration_error(-EINVAL, local_err);
  return;
  }

@@ -330,11 +331,12 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  ret = vfio_container_dma_unmap(bcontainer, iova,
 iotlb->addr_mask + 1, iotlb);
  if (ret) {
-    error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
- "0x%"HWADDR_PRIx") = %d (%s)",
- bcontainer, iova,
- iotlb->addr_mask + 1, ret, strerror(-ret));
-    vfio_set_migration_error(ret);
+    error_setg(&local_err,
+   "vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
+   "0x%"HWADDR_PRIx") = %d (%s)",
+   bcontainer, iova,
+   iotlb->addr_mask + 1, ret, strerror(-ret));


Use error_setg_errno()?


sure.




+    vfio_set_migration_error(ret, local_err);


Now dma unmap errors (and also the error before it) are not reported if they 
happen not during migration.

This makes me think, maybe vfio_set_migration_error() is redundant and can be 
replaced by migration_file_set_error()?



yes. Good suggestion. I would like to get rid of vfio_set_migration_error(),
so that's a good start.

Thanks,

C.
 

Thanks.


  }
  }
  out:
@@ -1108,8 +1110,7 @@ static void vfio_listener_log_global_stop(MemoryListener 
*listener)
  if (ret) {
  error_prepend(&local_err,
    "vfio: Could not stop dirty page tracking - ");
-    error_report_err(local_err);
-    vfio_set_migration_error(ret);
+    vfio_set_migration_error(ret, local_err);
  }
  }

@@ -1226,14 +1227,14 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier 
*n, IOMMUTLBEntry *iotlb)
  trace_vfio_iommu_map_dirty_notify(iova, iova + iotlb->addr_mask);

  if (iotlb->target_as != &address_space_memory) {
-    error_report("Wrong target AS \"%s\", only system memory is allowed",
- iotlb->target_as->name ? iotlb->target_as->name : "none");
+    error_setg(&local_err,
+   "Wrong target AS \"%s\", only system memory is allowed",
+   iotlb->target_as->name ? iotlb->target_as->name : "none");
  goto out;
  }

  rcu_read_lock();
  if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) 
{
-    error_report_err(local_err);
  goto out_lock;
  }

@@ -1244,7 +1245,6 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
    "vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", "
    "0x%"HWADDR_PRIx") failed - ", bcontainer, iova,
    iotlb->addr_mask + 1);
-    error_report_err(local_err);
  }

  out_lock:
@@ -1252,7 +1252,7 @@ out_lock:

  out:
  if (ret) {
-    vfio_set_migration_error(ret);
+    vfio_set_migration_error(ret, local_err);
  }
  }

@@ -1372,8 +1372,7 @@ static void vfio_listener_log_sync(MemoryListener 
*listener,
  if (vfio_devices_all_dirty_trackin

Re: [PATCH v2] target/riscv: Remove experimental prefix from "B" extension

2024-05-14 Thread Daniel Henrique Barboza




On 5/14/24 08:02, Rob Bradford wrote:

This extension has now been ratified:
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
removed.

Since this is now a ratified extension add it to the list of extensions
included in the "max" CPU variant.

Signed-off-by: Rob Bradford 
Reviewed-by: Andrew Jones 
---


Reviewed-by: Daniel Henrique Barboza 


  target/riscv/cpu.c | 2 +-
  target/riscv/tcg/tcg-cpu.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index eb1a2e7d6d..861d9f4350 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1396,7 +1396,7 @@ static const MISAExtInfo misa_ext_info_arr[] = {
  MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
  MISA_EXT_INFO(RVV, "v", "Vector operations"),
  MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
-MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
+MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
  };
  
  static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 40054a391a..164a13ad0f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1281,7 +1281,7 @@ static void riscv_init_max_cpu_extensions(Object *obj)
  const RISCVCPUMultiExtConfig *prop;
  
  /* Enable RVG, RVJ and RVV that are disabled by default */

-riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
+riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
  
  for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {

  isa_ext_update_enabled(cpu, prop->offset, true);




[PATCH] tests/libqos: Add loongarch virt machine node

2024-05-14 Thread Bibo Mao
Add loongarch virt machine to the graph. It is a modified copy of
the existing riscv virtmachine in riscv-virt-machine.c

It contains a generic-pcihost controller, and an extra function
loongarch_config_qpci_bus() to configure GPEX pci host controller
information, such as ecam and pio_base addresses.

Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is
added on loongarch virt machine, since virtio_mmu_pci device requires
it.

Signed-off-by: Bibo Mao 
---
 hw/loongarch/virt.c |   2 +
 tests/qtest/libqos/loongarch-virt-machine.c | 114 
 tests/qtest/libqos/meson.build  |   1 +
 3 files changed, 117 insertions(+)
 create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index db43b2fe4b..7f5ef87be4 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -45,6 +45,7 @@
 #include "sysemu/tpm.h"
 #include "sysemu/block-backend.h"
 #include "hw/block/flash.h"
+#include "hw/virtio/virtio-iommu.h"
 #include "qemu/error-report.h"
 
 static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
@@ -1212,6 +1213,7 @@ static HotplugHandler 
*virt_get_hotplug_handler(MachineState *machine,
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 
 if (device_is_dynamic_sysbus(mc, dev) ||
+object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
 memhp_type_supported(dev)) {
 return HOTPLUG_HANDLER(machine);
 }
diff --git a/tests/qtest/libqos/loongarch-virt-machine.c 
b/tests/qtest/libqos/loongarch-virt-machine.c
new file mode 100644
index 00..c12089c015
--- /dev/null
+++ b/tests/qtest/libqos/loongarch-virt-machine.c
@@ -0,0 +1,114 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu/osdep.h"
+#include "../libqtest.h"
+#include "qemu/module.h"
+#include "libqos-malloc.h"
+#include "qgraph.h"
+#include "virtio-mmio.h"
+#include "generic-pcihost.h"
+#include "hw/pci/pci_regs.h"
+
+#define LOONGARCH_PAGE_SIZE   0x1000
+#define LOONGARCH_VIRT_RAM_ADDR   0x10
+#define LOONGARCH_VIRT_RAM_SIZE   0xFF0
+
+#define LOONGARCH_VIRT_PIO_BASE   0x1800
+#define LOONGARCH_VIRT_PCIE_PIO_OFFSET0x4000
+#define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x1
+#define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x2000
+#define LOONGARCH_VIRT_PCIE_MMIO32_BASE   0x4000
+#define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT  0x8000
+
+typedef struct QVirtMachine QVirtMachine;
+
+struct QVirtMachine {
+QOSGraphObject obj;
+QGuestAllocator alloc;
+QVirtioMMIODevice virtio_mmio;
+QGenericPCIHost bridge;
+};
+
+static void virt_destructor(QOSGraphObject *obj)
+{
+QVirtMachine *machine = (QVirtMachine *) obj;
+alloc_destroy(&machine->alloc);
+}
+
+static void *virt_get_driver(void *object, const char *interface)
+{
+QVirtMachine *machine = object;
+if (!g_strcmp0(interface, "memory")) {
+return &machine->alloc;
+}
+
+fprintf(stderr, "%s not present in loongarch/virtio\n", interface);
+g_assert_not_reached();
+}
+
+static QOSGraphObject *virt_get_device(void *obj, const char *device)
+{
+QVirtMachine *machine = obj;
+if (!g_strcmp0(device, "generic-pcihost")) {
+return &machine->bridge.obj;
+} else if (!g_strcmp0(device, "virtio-mmio")) {
+return &machine->virtio_mmio.obj;
+}
+
+fprintf(stderr, "%s not present in loongarch/virt\n", device);
+g_assert_not_reached();
+}
+
+static void loongarch_config_qpci_bus(QGenericPCIBus *qpci)
+{
+qpci->gpex_pio_base = LOONGARCH_VIRT_PIO_BASE;
+qpci->bus.pio_alloc_ptr = LOONGARCH_VIRT_PCIE_PIO_OFFSET;
+qpci->bus.pio_limit = LOONGARCH_VIRT_PCIE_PIO_LIMIT;
+qpci->bus.mmio_alloc_ptr = LOONGARCH_VIRT_PCIE_MMIO32_BASE;
+qpci->bus.mmio_limit = LOONGARCH_VIRT_PCIE_MMIO32_LIMIT;
+qpci->ecam_alloc_ptr = LOONGARCH_VIRT_PCIE_ECAM_BASE;
+}
+
+static void *qos_create_machine_loongarch_virt(QTestState *qts)
+{
+QVirtMachine *machine = g_new0(QVirtMachine, 1);
+
+alloc_init(&machine->alloc, 0,
+   LOONGARCH_VIRT_RAM_ADDR,
+   LOONGARCH_VIRT_RAM_ADDR + LOONGARCH_VIRT_RAM_SIZE,
+   LOONGARCH_PAGE_SIZE);
+
+qos_create_generic_pcihost(&machine->bridge, qts, &machine->alloc);
+loongarch_c

Re: [PATCH 1/2] copy-before-write: allow specifying minimum cluster size

2024-05-14 Thread Markus Armbruster
Fiona Ebner  writes:

> Am 26.03.24 um 10:06 schrieb Markus Armbruster:
>>> @@ -365,7 +368,13 @@ BlockCopyState *block_copy_state_new(BdrvChild 
>>> *source, BdrvChild *target,
>>>  
>>>  GLOBAL_STATE_CODE();
>>>  
>>> -cluster_size = block_copy_calculate_cluster_size(target->bs, errp);
>>> +if (min_cluster_size && !is_power_of_2(min_cluster_size)) {
>> 
>> min_cluster_size is int64_t, is_power_of_2() takes uint64_t.  Bad if
>> min_cluster_size is negative.  Could this happen?
>
> No, because it comes in as a uint32_t via the QAPI (the internal caller
> added by patch 2/2 from the backup code also gets the value via QAPI and
> there uint32_t is used too).

Good.

Is there a practical way to tweak the types so it's more obvious?

>>> +error_setg(errp, "min-cluster-size needs to be a power of 2");
>>> +return NULL;
>>> +}
>>> +
>>> +cluster_size = block_copy_calculate_cluster_size(target->bs,
>>> + min_cluster_size, 
>>> errp);
>>>  if (cluster_size < 0) {
>>>  return NULL;
>>>  }
>
> ---snip---
>
>>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>>> index 0a72c590a8..85c8f88f6e 100644
>>> --- a/qapi/block-core.json
>>> +++ b/qapi/block-core.json
>>> @@ -4625,12 +4625,18 @@
>>>  # @on-cbw-error parameter will decide how this failure is handled.
>>>  # Default 0. (Since 7.1)
>>>  #
>>> +# @min-cluster-size: Minimum size of blocks used by copy-before-write
>>> +# operations.  Has to be a power of 2.  No effect if smaller than
>>> +# the maximum of the target's cluster size and 64 KiB.  Default 0.
>>> +# (Since 9.0)
>>> +#
>>>  # Since: 6.2
>>>  ##
>>>  { 'struct': 'BlockdevOptionsCbw',
>>>'base': 'BlockdevOptionsGenericFormat',
>>>'data': { 'target': 'BlockdevRef', '*bitmap': 'BlockDirtyBitmap',
>>> -'*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32' } }
>>> +'*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32',
>>> +'*min-cluster-size': 'uint32' } }
>> 
>> Elsewhere in the schema, we use either 'int' or 'size' for cluster-size.
>> Why the difference?
>
> The motivation was to disallow negative values up front and have it work
> with block_copy_calculate_cluster_size(), whose result is an int64_t.

Let's see whether I understand.

cbw_open() passes the new member @min-cluster-size to
block_copy_state_new().

block_copy_state_new() checks it, and passes it on to
block_copy_calculate_cluster_size().  This is the C code shown above.

block_copy_calculate_cluster_size() uses it like

return MAX(min_cluster_size, BLOCK_COPY_CLUSTER_SIZE_DEFAULT);

and

return MAX(min_cluster_size,
   MAX(BLOCK_COPY_CLUSTER_SIZE_DEFAULT, bdi.cluster_size));

BLOCK_COPY_CLUSTER_SIZE_DEFAULT and bdi.cluster_size are int.  The
return type is int64_t.

Correct?

I don't like mixing signed and unsigned in MAX() like this.  Figuring
out whether it's safe takes a C language lawyer.  I'd rather avoid such
subtle code.  Can we please compute these maxima entirely in the
destination type int64_t?

>   If
> I go with 'int', I'll have to add a check to disallow negative values.
> If I go with 'size', I'll have to add a check for to disallow too large
> values.
>
> Which approach should I go with?

For me, reducing the need for manual checking is important, but
cleanliness of the external interface trumps it.  I'd use 'size'.

Not the first time I see friction between QAPI 'size' or 'uint64' and
the block layer's use of int64_t.

The block layer likes to use int64_t even when the value must not be
negative.  There are good reasons for that.

Perhaps a QAPI type for "non-negative int64_t" could be useful.  Weird,
but useful.




Re: [RFC PATCH] target/loongarch/kvm: Add pmu support

2024-05-14 Thread maobibo




On 2024/5/14 下午5:46, Song Gao wrote:

This patch adds PMU support, We just sets some cpucfg6 default value
to PMU config on kvm mode, and then check the PMU config with kvm ioctl
KVM_GET_DEVICE_ATTR.
   e.g
 '...  -cpu max,pmu=on,pmnum=[1-16]';
 '...  -cpu max,pmu=on' (default pmnum = 4);

Do we need expose interface pmnum to user?
The default PMU number is 4 on la464/la664, it should equal to real HW.
There is no much meaning with pmnum == 1 although it supports.


 '...  -cpu max,pmu=off' (disable PMU)

Signed-off-by: Song Gao 
---

This patch adds the 'RFC' heading because it requires
the kernel to merge into patch[1] first

[1]: https://lore.kernel.org/all/20240507120140.3119714-1-gaos...@loongson.cn/


  target/loongarch/cpu.h|  2 +
  target/loongarch/cpu.c| 64 +++
  target/loongarch/kvm/kvm.c| 55 ++-
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  4 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 6c41fafb70..d834649106 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -184,6 +184,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4)
  FIELD(CPUCFG6, PMBITS, 8, 6)
  FIELD(CPUCFG6, UPM, 14, 1)
  
+#define PMNUM_MAX 16

+
  /* cpucfg[16] bits */
  FIELD(CPUCFG16, L1_IUPRE, 0, 1)
  FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index a0cad53676..c78ee3f0b1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -8,6 +8,7 @@
  #include "qemu/osdep.h"
  #include "qemu/log.h"
  #include "qemu/qemu-print.h"
+#include "qemu/error-report.h"
  #include "qapi/error.h"
  #include "qemu/module.h"
  #include "sysemu/qtest.h"
@@ -19,6 +20,7 @@
  #include "internals.h"
  #include "fpu/softfloat-helpers.h"
  #include "cpu-csr.h"
+#include "qapi/visitor.h"
  #ifndef CONFIG_USER_ONLY
  #include "sysemu/reset.h"
  #endif
@@ -421,6 +423,14 @@ static void loongarch_la464_initfn(Object *obj)
  data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1);
  env->cpucfg[5] = data;
  
+if (kvm_enabled()) {

+data = 0;
+data = FIELD_DP32(data, CPUCFG6, PMP, 1);
+data = FIELD_DP32(data, CPUCFG6, PMNUM, 3);
+data = FIELD_DP32(data, CPUCFG6, PMBITS, 63);
+env->cpucfg[6] = data;
+}
+
  data = 0;
  data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1);
  data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1);
@@ -643,6 +653,48 @@ static void loongarch_set_lasx(Object *obj, bool value, 
Error **errp)
  }
  }
  
+static bool loongarch_get_pmu(Object *obj, Error **errp)

+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+return  !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP));
+}
+
+static void loongarch_set_pmu(Object *obj, bool value,  Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value);
+}
+
+static void loongarch_get_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM);
+
+visit_type_uint32(v, name, &value, errp);
+}
+
+static void loongarch_set_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t *value= opaque;
+
+if (!visit_type_uint32(v, name, value, errp)) {
+return;
+}
+if ((*value <= PMNUM_MAX) && (*value > 0)) {
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 
*value -1);
+} else {
+error_report("Performance counter number need be in [1- %d]\n", 
PMNUM_MAX);
+exit(EXIT_FAILURE);
+}
+}
+
  void loongarch_cpu_post_init(Object *obj)
  {
  LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -655,6 +707,18 @@ void loongarch_cpu_post_init(Object *obj)
  object_property_add_bool(obj, "lasx", loongarch_get_lasx,
   loongarch_set_lasx);
  }
+
+if (kvm_enabled()) {
+object_property_add_bool(obj, "pmu", loongarch_get_pmu,
+ loongarch_set_pmu);
+if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) {
+uint32_t value = 4;
+object_property_add(obj, "pmnum", "uint32",
+loongarch_get_pmnum,
+loongarch_set_pmnum, NULL,
+(void *)&value);
+}
+}
  }
  
  static void loongarch_cpu_init(Object *obj)

diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index bc75552d0f..a9f9020071 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -556,6 +556,53 @@ static int kvm_check_cpucfg2(CPUState *cs)
  return 

Re: [PATCH] target/loongarch/kvm: fpu save the vreg registers high 192bit

2024-05-14 Thread maobibo

Reviewed-by: Bibo Mao 

On 2024/5/14 下午7:07, Song Gao wrote:

On kvm side, get_fpu/set_fpu save the vreg registers high 192bits,
but QEMU missing.

Signed-off-by: Song Gao 
---
  target/loongarch/kvm/kvm.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index a9f9020071..0b5dbb7ed8 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs)
  env->fcsr0 = fpu.fcsr;
  for (i = 0; i < 32; i++) {
  env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
+env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
+env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
+env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
  }
  for (i = 0; i < 8; i++) {
  env->cf[i] = fpu.fcc & 0xFF;
@@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
  fpu.fcc = 0;
  for (i = 0; i < 32; i++) {
  fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
+fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
+fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
+fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
  }
  
  for (i = 0; i < 8; i++) {







Re: [RFC PATCH v3 3/5] KVM: x86: Add notifications for Heki policy configuration and violation

2024-05-14 Thread Mickaël Salaün
On Tue, May 07, 2024 at 09:16:06AM -0700, Sean Christopherson wrote:
> On Tue, May 07, 2024, Mickaël Salaün wrote:
> > > Actually, potential bad/crazy idea.  Why does the _host_ need to define 
> > > policy?
> > > Linux already knows what assets it wants to (un)protect and when.  What's 
> > > missing
> > > is a way for the guest kernel to effectively deprivilege and 
> > > re-authenticate
> > > itself as needed.  We've been tossing around the idea of paired VMs+vCPUs 
> > > to
> > > support VTLs and SEV's VMPLs, what if we usurped/piggybacked those ideas, 
> > > with a
> > > bit of pKVM mixed in?
> > > 
> > > Borrowing VTL terminology, where VTL0 is the least privileged, userspace 
> > > launches
> > > the VM at VTL0.  At some point, the guest triggers the deprivileging 
> > > sequence and
> > > userspace creates VTL1.  Userpace also provides a way for VTL0 restrict 
> > > access to
> > > its memory, e.g. to effectively make the page tables for the kernel's 
> > > direct map
> > > writable only from VTL1, to make kernel text RO (or XO), etc.  And VTL0 
> > > could then
> > > also completely remove its access to code that changes CR0/CR4.
> > > 
> > > It would obviously require a _lot_ more upfront work, e.g. to isolate the 
> > > kernel
> > > text that modifies CR0/CR4 so that it can be removed from VTL0, but that 
> > > should
> > > be doable with annotations, e.g. tag relevant functions with __magic or 
> > > whatever,
> > > throw them in a dedicated section, and then free/protect the section(s) 
> > > at the
> > > appropriate time.
> > > 
> > > KVM would likely need to provide the ability to switch VTLs (or whatever 
> > > they get
> > > called), and host userspace would need to provide a decent amount of the 
> > > backend
> > > mechanisms and "core" policies, e.g. to manage VTL0 memory, teardown 
> > > (turn off?)
> > > VTL1 on kexec(), etc.  But everything else could live in the guest kernel 
> > > itself.
> > > E.g. to have CR pinning play nice with kexec(), toss the relevant kexec() 
> > > code into
> > > VTL1.  That way VTL1 can verify the kexec() target and tear itself down 
> > > before
> > > jumping into the new kernel. 
> > > 
> > > This is very off the cuff and have-wavy, e.g. I don't have much of an 
> > > idea what
> > > it would take to harden kernel text patching, but keeping the policy in 
> > > the guest
> > > seems like it'd make everything more tractable than trying to define an 
> > > ABI
> > > between Linux and a VMM that is rich and flexible enough to support all 
> > > the
> > > fancy things Linux does (and will do in the future).
> > 
> > Yes, we agree that the guest needs to manage its own policy.  That's why
> > we implemented Heki for KVM this way, but without VTLs because KVM
> > doesn't support them.
> > 
> > To sum up, is the VTL approach the only one that would be acceptable for
> > KVM?  
> 
> Heh, that's not a question you want to be asking.  You're effectively asking 
> me
> to make an authorative, "final" decision on a topic which I am only passingly
> familiar with.
> 
> But since you asked it... :-)  Probably?
> 
> I see a lot of advantages to a VTL/VSM-like approach:
> 
>  1. Provides Linux-as-a guest the flexibility it needs to meaningfully advance
> its security, with the least amount of policy built into the guest/host 
> ABI.
> 
>  2. Largely decouples guest policy from the host, i.e. should allow the guest 
> to
> evolve/update it's policy without needing to coordinate changes with the 
> host.
> 
>  3. The KVM implementation can be generic enough to be reusable for other 
> features.
> 
>  4. Other groups are already working on VTL-like support in KVM, e.g. for VSM
> itself, and potentially for VMPL/SVSM support.
> 
> IMO, #2 is a *huge* selling point.  Not having to coordinate changes across
> multiple code bases and/or organizations and/or maintainers is a big win for
> velocity, long term maintenance, and probably the very viability of HEKI.

Agree, this is our goal.

> 
> Providing the guest with the tools to define and implement its own policy 
> means
> end users don't have to way for some third party, e.g. CSPs, to deploy the
> accompanying host-side changes, because there are no host-side changes.
> 
> And encapsulating everything in the guest drastically reduces the friction 
> with
> changes in the kernel that interact with hardening, both from a technical and 
> a
> social perspective.  I.e. giving the kernel (near) complete control over its
> destiny minimizes the number of moving parts, and will be far, far easier to 
> sell
> to maintainers.  I would expect maintainers to react much more favorably to 
> being
> handed tools to harden the kernel, as opposed to being presented a set of APIs
> that can be used to make the kernel compliant with _someone else's_ vision of
> what kernel hardening should look like.
> 
> E.g. imagine a new feature comes along that requires overriding CR0/CR4 
> pinning
> in a way that doesn't fit into existi

Re: [RFC PATCH v3 3/5] KVM: x86: Add notifications for Heki policy configuration and violation

2024-05-14 Thread Mickaël Salaün
On Fri, May 10, 2024 at 10:07:00AM +, Nicolas Saenz Julienne wrote:
> On Tue May 7, 2024 at 4:16 PM UTC, Sean Christopherson wrote:
> > > If yes, that would indeed require a *lot* of work for something we're not
> > > sure will be accepted later on.
> >
> > Yes and no.  The AWS folks are pursuing VSM support in KVM+QEMU, and SVSM 
> > support
> > is trending toward the paired VM+vCPU model.  IMO, it's entirely feasible to
> > design KVM support such that much of the development load can be shared 
> > between
> > the projects.  And having 2+ use cases for a feature (set) makes it _much_ 
> > more
> > likely that the feature(s) will be accepted.
> 
> Since Sean mentioned our VSM efforts, a small update. We were able to
> validate the concept of one KVM VM per VTL as discussed in LPC. Right
> now only for single CPU guests, but are in the late stages of bringing
> up MP support. The resulting KVM code is small, and most will be
> uncontroversial (I hope). If other obligations allow it, we plan on
> having something suitable for review in the coming months.

Looks good!

> 
> Our implementation aims to implement all the VSM spec necessary to run
> with Microsoft Credential Guard. But note that some aspects necessary
> for HVCI are not covered, especially the ones that depend on MBEC
> support, or some categories of secure intercepts.

We already implemented support for MBEC, so that should not be an issue.
We just need to find the best interface to configure it.

> 
> Development happens
> https://github.com/vianpl/{linux,qemu,kvm-unit-tests} and the vsm-next
> branch, but I'd advice against looking into it until we add some order
> to the rework. Regardless, feel free to get in touch.

Thanks for the update.

Could we schedule a PUCK meeting to synchronize and help each other?
What about June 12?



[PULL 02/11] dockerfiles: add 'MAKE' env variable to remaining containers

2024-05-14 Thread Thomas Huth
From: Daniel P. Berrangé 

All the lcitool generated containers define a "MAKE" env. It will be
convenient for later patches if all containers do this.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20240513111551.488088-2-berra...@redhat.com>
Signed-off-by: Thomas Huth 
---
 tests/docker/dockerfiles/debian-all-test-cross.docker| 1 +
 tests/docker/dockerfiles/debian-hexagon-cross.docker | 1 +
 tests/docker/dockerfiles/debian-legacy-test-cross.docker | 1 +
 tests/docker/dockerfiles/debian-loongarch-cross.docker   | 1 +
 tests/docker/dockerfiles/debian-tricore-cross.docker | 1 +
 tests/docker/dockerfiles/debian-xtensa-cross.docker  | 1 +
 tests/docker/dockerfiles/fedora-cris-cross.docker| 1 +
 7 files changed, 7 insertions(+)

diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker 
b/tests/docker/dockerfiles/debian-all-test-cross.docker
index 2cc7a24d4d..6cc38a3633 100644
--- a/tests/docker/dockerfiles/debian-all-test-cross.docker
+++ b/tests/docker/dockerfiles/debian-all-test-cross.docker
@@ -68,6 +68,7 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
 ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
 ENV DEF_TARGET_LIST 
aarch64-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sparc64-linux-user
 # As a final step configure the user (if env is defined)
+ENV MAKE /usr/bin/make
 ARG USER
 ARG UID
 RUN if [ "${USER}" ]; then \
diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker 
b/tests/docker/dockerfiles/debian-hexagon-cross.docker
index 60bd8faa20..f2d40f2dee 100644
--- a/tests/docker/dockerfiles/debian-hexagon-cross.docker
+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker
@@ -45,6 +45,7 @@ ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
 
 RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL"
 ENV PATH $PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin
+ENV MAKE /usr/bin/make
 # As a final step configure the user (if env is defined)
 ARG USER
 ARG UID
diff --git a/tests/docker/dockerfiles/debian-legacy-test-cross.docker 
b/tests/docker/dockerfiles/debian-legacy-test-cross.docker
index 8cc68bc912..d75e0b85e2 100644
--- a/tests/docker/dockerfiles/debian-legacy-test-cross.docker
+++ b/tests/docker/dockerfiles/debian-legacy-test-cross.docker
@@ -42,6 +42,7 @@ RUN /usr/bin/pip3 install tomli
 
 ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
 ENV DEF_TARGET_LIST alpha-linux-user,sh4-linux-user
+ENV MAKE /usr/bin/make
 # As a final step configure the user (if env is defined)
 ARG USER
 ARG UID
diff --git a/tests/docker/dockerfiles/debian-loongarch-cross.docker 
b/tests/docker/dockerfiles/debian-loongarch-cross.docker
index b25e779a2c..6a9197528b 100644
--- a/tests/docker/dockerfiles/debian-loongarch-cross.docker
+++ b/tests/docker/dockerfiles/debian-loongarch-cross.docker
@@ -44,6 +44,7 @@ ENV LD_LIBRARY_PATH 
/opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-li
 
 ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
 ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch-softmmu
+ENV MAKE /usr/bin/make
 
 # As a final step configure the user (if env is defined)
 ARG USER
diff --git a/tests/docker/dockerfiles/debian-tricore-cross.docker 
b/tests/docker/dockerfiles/debian-tricore-cross.docker
index c597f8e16b..16276aa21d 100644
--- a/tests/docker/dockerfiles/debian-tricore-cross.docker
+++ b/tests/docker/dockerfiles/debian-tricore-cross.docker
@@ -44,6 +44,7 @@ RUN curl -#SL 
https://github.com/bkoppelmann/package_940/releases/download/trico
 # This image can only build a very minimal QEMU as well as the tests
 ENV DEF_TARGET_LIST tricore-softmmu
 ENV QEMU_CONFIGURE_OPTS --disable-user --disable-tools --disable-fdt
+ENV MAKE /usr/bin/make
 # As a final step configure the user (if env is defined)
 ARG USER
 ARG UID
diff --git a/tests/docker/dockerfiles/debian-xtensa-cross.docker 
b/tests/docker/dockerfiles/debian-xtensa-cross.docker
index 72c25d63d9..413881899b 100644
--- a/tests/docker/dockerfiles/debian-xtensa-cross.docker
+++ b/tests/docker/dockerfiles/debian-xtensa-cross.docker
@@ -27,6 +27,7 @@ RUN for cpu in $CPU_LIST; do \
 done
 
 ENV PATH 
$PATH:/opt/$TOOLCHAIN_RELEASE/xtensa-dc232b-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dc233c-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-de233_fpu-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dsp3400-elf/bin
+ENV MAKE /usr/bin/make
 # As a final step configure the user (if env is defined)
 ARG USER
 ARG UID
diff --git a/tests/docker/dockerfiles/fedora-cris-cross.docker 
b/tests/docker/dockerfiles/fedora-cris-cross.docker
index f2899af410..97c9d37ede 100644
--- a/tests/docker/dockerfiles/fedora-cris-cross.docker
+++ b/tests/docker/dockerfiles/fedora-cris-cross.docker
@@ -4,

[PULL 00/11] gitlab CI fix and glib update

2024-05-14 Thread Thomas Huth
The following changes since commit 9360070196789cc8b9404b2efaf319384e64b107:

  Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging 
(2024-05-12 13:41:26 +0200)

are available in the Git repository at:

  https://gitlab.com/thuth/qemu.git tags/pull-request-2024-05-14

for you to fetch changes up to da79537e0c8cef007d30298343d05acb0ba8b427:

  util/uri: Remove the old URI parsing code (2024-05-14 12:46:46 +0200)


* Fix the "tsan-build" CI job on the shared gitlab CI runners
* Bump minimum glib version and use URI code from the newer glib
* Fix error message from "configure" when C compiler is not working


Daniel P. Berrangé (3):
  dockerfiles: add 'MAKE' env variable to remaining containers
  gitlab: use $MAKE instead of 'make'
  gitlab: use 'setarch -R' to workaround tsan bug

Thomas Huth (8):
  configure: Fix error message when C compiler is not working
  Bump minimum glib version to v2.66
  Remove glib compatibility code that is not required anymore
  block/gluster: Use URI parsing code from glib
  block/nbd: Use URI parsing code from glib
  block/nfs: Use URI parsing code from glib
  block/ssh: Use URI parsing code from glib
  util/uri: Remove the old URI parsing code

 configure  |   11 +-
 meson.build|   16 +-
 include/glib-compat.h  |   27 +-
 include/qemu/uri.h |   99 --
 block/gluster.c|   69 +-
 block/nbd.c|   76 +-
 block/nfs.c|  110 +-
 block/ssh.c|   75 +-
 qga/commands-posix-ssh.c   |   12 +-
 util/error-report.c|   10 -
 util/uri.c | 1466 
 .gitlab-ci.d/buildtest-template.yml|6 +-
 .gitlab-ci.d/buildtest.yml |3 +
 .../dockerfiles/debian-all-test-cross.docker   |1 +
 .../docker/dockerfiles/debian-hexagon-cross.docker |1 +
 .../dockerfiles/debian-legacy-test-cross.docker|1 +
 .../dockerfiles/debian-loongarch-cross.docker  |1 +
 .../docker/dockerfiles/debian-tricore-cross.docker |1 +
 .../docker/dockerfiles/debian-xtensa-cross.docker  |1 +
 tests/docker/dockerfiles/fedora-cris-cross.docker  |1 +
 util/meson.build   |2 +-
 21 files changed, 194 insertions(+), 1795 deletions(-)
 delete mode 100644 include/qemu/uri.h
 delete mode 100644 util/uri.c




[PULL 05/11] Bump minimum glib version to v2.66

2024-05-14 Thread Thomas Huth
Now that we dropped support for CentOS 8 and Ubuntu 20.04, we can
look into bumping the glib version to a new minimum for further
clean-ups. According to repology.org, available versions are:

 CentOS Stream 9:   2.66.7
 Debian 11: 2.66.8
 Fedora 38: 2.74.1
 Freebsd:   2.78.4
 Homebrew:  2.80.0
 Openbsd:   2.78.4
 OpenSuse leap 15.5:2.70.5
 pkgsrc_current:2.78.4
 Ubuntu 22.04:  2.72.1

Thus it should be safe to bump the minimum glib version to 2.66 now.
Version 2.66 comes with new functions for URI parsing which will
allow further clean-ups in the following patches.

Reviewed-by: Daniel P. Berrangé 
Message-ID: <20240418101056.302103-8-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 meson.build  | 16 +---
 include/glib-compat.h| 27 ++-
 qga/commands-posix-ssh.c |  4 ++--
 3 files changed, 5 insertions(+), 42 deletions(-)

diff --git a/meson.build b/meson.build
index 9c14192514..a9de71d450 100644
--- a/meson.build
+++ b/meson.build
@@ -869,7 +869,7 @@ have_xen_pci_passthrough = 
get_option('xen_pci_passthrough') \
 
 # When bumping glib minimum version, please check also whether to increase
 # the _WIN32_WINNT setting in osdep.h according to the value from glib
-glib_req_ver = '>=2.56.0'
+glib_req_ver = '>=2.66.0'
 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
 method: 'pkg-config')
 glib_cflags = []
@@ -910,20 +910,6 @@ if not cc.compiles('''
 to the right pkg-config files for your build target.''')
 endif
 
-# Silence clang warnings triggered by glib < 2.57.2
-if not cc.compiles('''
-  #include 
-  typedef struct Foo {
-int i;
-  } Foo;
-  static void foo_free(Foo *f)
-  {
-g_free(f);
-  }
-  G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
-  int main(void) { return 0; }''', dependencies: glib_pc, args: 
['-Wunused-function', '-Werror'])
-  glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
-endif
 glib = declare_dependency(dependencies: [glib_pc, gmodule],
   compile_args: glib_cflags,
   version: glib_pc.version())
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 43a562974d..86be439ba0 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -19,12 +19,12 @@
 /* Ask for warnings for anything that was marked deprecated in
  * the defined version, or before. It is a candidate for rewrite.
  */
-#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_56
+#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_66
 
 /* Ask for warnings if code tries to use function that did not
  * exist in the defined version. These risk breaking builds
  */
-#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_56
+#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_66
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -105,29 +105,6 @@ static inline gpointer g_memdup2_qemu(gconstpointer mem, 
gsize byte_size)
 }
 #define g_memdup2(m, s) g_memdup2_qemu(m, s)
 
-#if defined(G_OS_UNIX)
-/*
- * Note: The fallback implementation is not MT-safe, and it returns a copy of
- * the libc passwd (must be g_free() after use) but not the content. Because of
- * these important differences the caller must be aware of, it's not #define 
for
- * GLib API substitution.
- */
-static inline struct passwd *
-g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error)
-{
-#if GLIB_CHECK_VERSION(2, 64, 0)
-return g_unix_get_passwd_entry(user_name, error);
-#else
-struct passwd *p = getpwnam(user_name);
-if (!p) {
-g_set_error_literal(error, G_UNIX_ERROR, 0, g_strerror(errno));
-return NULL;
-}
-return (struct passwd *)g_memdup(p, sizeof(*p));
-#endif
-}
-#endif /* G_OS_UNIX */
-
 static inline bool
 qemu_g_test_slow(void)
 {
diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
index dd2ecb453a..866afe6741 100644
--- a/qga/commands-posix-ssh.c
+++ b/qga/commands-posix-ssh.c
@@ -36,7 +36,7 @@ test_get_passwd_entry(const gchar *user_name, GError **error)
 return p;
 }
 
-#define g_unix_get_passwd_entry_qemu(username, err) \
+#define g_unix_get_passwd_entry(username, err) \
test_get_passwd_entry(username, err)
 #endif
 
@@ -46,7 +46,7 @@ get_passwd_entry(const char *username, Error **errp)
 g_autoptr(GError) err = NULL;
 struct passwd *p;
 
-p = g_unix_get_passwd_entry_qemu(username, &err);
+p = g_unix_get_passwd_entry(username, &err);
 if (p == NULL) {
 error_setg(errp, "failed to lookup user '%s': %s",
username, err->message);
-- 
2.45.0




[PULL 09/11] block/nfs: Use URI parsing code from glib

2024-05-14 Thread Thomas Huth
Since version 2.66, glib has useful URI parsing functions, too.
Use those instead of the QEMU-internal ones to be finally able
to get rid of the latter.

While we're at it, slightly rephrase one of the error messages:
Use "Invalid value..." instead of "Illegal value..." since the
latter rather sounds like the users were breaking a law here.

Reviewed-by: Eric Blake 
Message-ID: <20240418101056.302103-12-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 block/nfs.c | 110 ++--
 1 file changed, 54 insertions(+), 56 deletions(-)

diff --git a/block/nfs.c b/block/nfs.c
index f737e19cd3..60240a8733 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -38,7 +38,6 @@
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
-#include "qemu/uri.h"
 #include "qemu/cutils.h"
 #include "sysemu/replay.h"
 #include "qapi/qapi-visit-block-core.h"
@@ -79,77 +78,76 @@ typedef struct NFSRPC {
 
 static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
 {
-URI *uri = NULL;
-QueryParams *qp = NULL;
-int ret = -EINVAL, i;
+g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
+GUriParamsIter qp;
+const char *uri_server, *uri_path, *uri_query;
+char *qp_name, *qp_value;
+GError *gerror = NULL;
 
-uri = uri_parse(filename);
 if (!uri) {
 error_setg(errp, "Invalid URI specified");
-goto out;
+return -EINVAL;
 }
-if (g_strcmp0(uri->scheme, "nfs") != 0) {
+if (!g_str_equal(g_uri_get_scheme(uri), "nfs")) {
 error_setg(errp, "URI scheme must be 'nfs'");
-goto out;
+return -EINVAL;
 }
 
-if (!uri->server) {
+uri_server = g_uri_get_host(uri);
+if (!uri_server || !uri_server[0]) {
 error_setg(errp, "missing hostname in URI");
-goto out;
+return -EINVAL;
 }
 
-if (!uri->path) {
+uri_path = g_uri_get_path(uri);
+if (!uri_path || !uri_path[0]) {
 error_setg(errp, "missing file path in URI");
-goto out;
-}
-
-qp = query_params_parse(uri->query);
-if (!qp) {
-error_setg(errp, "could not parse query parameters");
-goto out;
+return -EINVAL;
 }
 
-qdict_put_str(options, "server.host", uri->server);
+qdict_put_str(options, "server.host", uri_server);
 qdict_put_str(options, "server.type", "inet");
-qdict_put_str(options, "path", uri->path);
-
-for (i = 0; i < qp->n; i++) {
-uint64_t val;
-if (!qp->p[i].value) {
-error_setg(errp, "Value for NFS parameter expected: %s",
-   qp->p[i].name);
-goto out;
-}
-if (parse_uint_full(qp->p[i].value, 0, &val)) {
-error_setg(errp, "Illegal value for NFS parameter: %s",
-   qp->p[i].name);
-goto out;
-}
-if (!strcmp(qp->p[i].name, "uid")) {
-qdict_put_str(options, "user", qp->p[i].value);
-} else if (!strcmp(qp->p[i].name, "gid")) {
-qdict_put_str(options, "group", qp->p[i].value);
-} else if (!strcmp(qp->p[i].name, "tcp-syncnt")) {
-qdict_put_str(options, "tcp-syn-count", qp->p[i].value);
-} else if (!strcmp(qp->p[i].name, "readahead")) {
-qdict_put_str(options, "readahead-size", qp->p[i].value);
-} else if (!strcmp(qp->p[i].name, "pagecache")) {
-qdict_put_str(options, "page-cache-size", qp->p[i].value);
-} else if (!strcmp(qp->p[i].name, "debug")) {
-qdict_put_str(options, "debug", qp->p[i].value);
-} else {
-error_setg(errp, "Unknown NFS parameter name: %s",
-   qp->p[i].name);
-goto out;
+qdict_put_str(options, "path", uri_path);
+
+uri_query = g_uri_get_query(uri);
+if (uri_query) {
+g_uri_params_iter_init(&qp, uri_query, -1, "&", G_URI_PARAMS_NONE);
+while (g_uri_params_iter_next(&qp, &qp_name, &qp_value, &gerror)) {
+uint64_t val;
+if (!qp_name || gerror) {
+error_setg(errp, "Failed to parse NFS parameter");
+return -EINVAL;
+}
+if (!qp_value) {
+error_setg(errp, "Value for NFS parameter expected: %s",
+   qp_name);
+return -EINVAL;
+}
+if (parse_uint_full(qp_value, 0, &val)) {
+error_setg(errp, "Invalid value for NFS parameter: %s",
+   qp_name);
+return -EINVAL;
+}
+if (g_str_equal(qp_name, "uid")) {
+qdict_put_str(options, "user", qp_value);
+} else if (g_str_equal(qp_name, "gid")) {
+qdict_put_str(options, "group", qp_value);
+} else if (g_str_equal(qp_name, "tcp-syncnt")) {
+qdict_put_str(options, "tcp-syn-count", qp_value);
+} els

[PULL 07/11] block/gluster: Use URI parsing code from glib

2024-05-14 Thread Thomas Huth
Since version 2.66, glib has useful URI parsing functions, too.
Use those instead of the QEMU-internal ones to be finally able
to get rid of the latter.

Since g_uri_get_path() returns a const pointer, we also need to
tweak the parameter of parse_volume_options() (where we use the
result of g_uri_get_path() as input).

Reviewed-by: Eric Blake 
Reviewed-by: Daniel P. Berrangé 
Message-Id: <20240418101056.302103-10-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 block/gluster.c | 69 -
 1 file changed, 34 insertions(+), 35 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 4253c8db5e..d003df 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -17,7 +17,6 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
-#include "qemu/uri.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
@@ -289,9 +288,9 @@ static void glfs_clear_preopened(glfs_t *fs)
 }
 }
 
-static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
+static int parse_volume_options(BlockdevOptionsGluster *gconf, const char 
*path)
 {
-char *p, *q;
+const char *p, *q;
 
 if (!path) {
 return -EINVAL;
@@ -349,13 +348,13 @@ static int parse_volume_options(BlockdevOptionsGluster 
*gconf, char *path)
 static int qemu_gluster_parse_uri(BlockdevOptionsGluster *gconf,
   const char *filename)
 {
+g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
+g_autoptr(GHashTable) qp = NULL;
 SocketAddress *gsconf;
-URI *uri;
-QueryParams *qp = NULL;
 bool is_unix = false;
-int ret = 0;
+const char *uri_scheme, *uri_query, *uri_server;
+int uri_port, ret;
 
-uri = uri_parse(filename);
 if (!uri) {
 return -EINVAL;
 }
@@ -364,54 +363,54 @@ static int qemu_gluster_parse_uri(BlockdevOptionsGluster 
*gconf,
 QAPI_LIST_PREPEND(gconf->server, gsconf);
 
 /* transport */
-if (!uri->scheme || !strcmp(uri->scheme, "gluster")) {
+uri_scheme = g_uri_get_scheme(uri);
+if (!uri_scheme || !strcmp(uri_scheme, "gluster")) {
 gsconf->type = SOCKET_ADDRESS_TYPE_INET;
-} else if (!strcmp(uri->scheme, "gluster+tcp")) {
+} else if (!strcmp(uri_scheme, "gluster+tcp")) {
 gsconf->type = SOCKET_ADDRESS_TYPE_INET;
-} else if (!strcmp(uri->scheme, "gluster+unix")) {
+} else if (!strcmp(uri_scheme, "gluster+unix")) {
 gsconf->type = SOCKET_ADDRESS_TYPE_UNIX;
 is_unix = true;
 } else {
-ret = -EINVAL;
-goto out;
+return -EINVAL;
 }
 
-ret = parse_volume_options(gconf, uri->path);
+ret = parse_volume_options(gconf, g_uri_get_path(uri));
 if (ret < 0) {
-goto out;
+return ret;
 }
 
-qp = query_params_parse(uri->query);
-if (qp->n > 1 || (is_unix && !qp->n) || (!is_unix && qp->n)) {
-ret = -EINVAL;
-goto out;
+uri_query = g_uri_get_query(uri);
+if (uri_query) {
+qp = g_uri_parse_params(uri_query, -1, "&", G_URI_PARAMS_NONE, NULL);
+if (!qp) {
+return -EINVAL;
+}
+ret = g_hash_table_size(qp);
+if (ret > 1 || (is_unix && !ret) || (!is_unix && ret)) {
+return -EINVAL;
+}
 }
 
+uri_server = g_uri_get_host(uri);
+uri_port = g_uri_get_port(uri);
+
 if (is_unix) {
-if (uri->server || uri->port) {
-ret = -EINVAL;
-goto out;
-}
-if (strcmp(qp->p[0].name, "socket")) {
-ret = -EINVAL;
-goto out;
+char *uri_socket = g_hash_table_lookup(qp, "socket");
+if (uri_server || uri_port != -1 || !uri_socket) {
+return -EINVAL;
 }
-gsconf->u.q_unix.path = g_strdup(qp->p[0].value);
+gsconf->u.q_unix.path = g_strdup(uri_socket);
 } else {
-gsconf->u.inet.host = g_strdup(uri->server ? uri->server : 
"localhost");
-if (uri->port) {
-gsconf->u.inet.port = g_strdup_printf("%d", uri->port);
+gsconf->u.inet.host = g_strdup(uri_server ? uri_server : "localhost");
+if (uri_port > 0) {
+gsconf->u.inet.port = g_strdup_printf("%d", uri_port);
 } else {
 gsconf->u.inet.port = g_strdup_printf("%d", GLUSTER_DEFAULT_PORT);
 }
 }
 
-out:
-if (qp) {
-query_params_free(qp);
-}
-uri_free(uri);
-return ret;
+return 0;
 }
 
 static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
-- 
2.45.0




[PULL 08/11] block/nbd: Use URI parsing code from glib

2024-05-14 Thread Thomas Huth
Since version 2.66, glib has useful URI parsing functions, too.
Use those instead of the QEMU-internal ones to be finally able
to get rid of the latter. The g_uri_get_host() also takes care
of removing the square brackets from IPv6 addresses, so we can
drop that part of the QEMU code now, too.

Reviewed-by: Richard W.M. Jones 
Reviewed-by: Eric Blake 
Message-ID: <20240418101056.302103-11-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 block/nbd.c | 76 ++---
 1 file changed, 37 insertions(+), 39 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index ef05f7cdfd..589d28af83 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -31,7 +31,6 @@
 #include "qemu/osdep.h"
 
 #include "trace.h"
-#include "qemu/uri.h"
 #include "qemu/option.h"
 #include "qemu/cutils.h"
 #include "qemu/main-loop.h"
@@ -1514,30 +1513,31 @@ static void nbd_client_close(BlockDriverState *bs)
 
 static int nbd_parse_uri(const char *filename, QDict *options)
 {
-URI *uri;
+g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
+g_autoptr(GHashTable) qp = NULL;
 const char *p;
-QueryParams *qp = NULL;
-int ret = 0;
+int qp_n;
 bool is_unix;
+const char *uri_scheme, *uri_query, *uri_server;
+int uri_port;
 
-uri = uri_parse(filename);
 if (!uri) {
 return -EINVAL;
 }
 
 /* transport */
-if (!g_strcmp0(uri->scheme, "nbd")) {
+uri_scheme = g_uri_get_scheme(uri);
+if (!g_strcmp0(uri_scheme, "nbd")) {
 is_unix = false;
-} else if (!g_strcmp0(uri->scheme, "nbd+tcp")) {
+} else if (!g_strcmp0(uri_scheme, "nbd+tcp")) {
 is_unix = false;
-} else if (!g_strcmp0(uri->scheme, "nbd+unix")) {
+} else if (!g_strcmp0(uri_scheme, "nbd+unix")) {
 is_unix = true;
 } else {
-ret = -EINVAL;
-goto out;
+return -EINVAL;
 }
 
-p = uri->path ? uri->path : "";
+p = g_uri_get_path(uri) ?: "";
 if (p[0] == '/') {
 p++;
 }
@@ -1545,52 +1545,50 @@ static int nbd_parse_uri(const char *filename, QDict 
*options)
 qdict_put_str(options, "export", p);
 }
 
-qp = query_params_parse(uri->query);
-if (qp->n > 1 || (is_unix && !qp->n) || (!is_unix && qp->n)) {
-ret = -EINVAL;
-goto out;
+uri_query = g_uri_get_query(uri);
+if (uri_query) {
+qp = g_uri_parse_params(uri_query, -1, "&", G_URI_PARAMS_NONE, NULL);
+if (!qp) {
+return -EINVAL;
+}
+qp_n = g_hash_table_size(qp);
+if (qp_n > 1 || (is_unix && !qp_n) || (!is_unix && qp_n)) {
+return -EINVAL;
+}
+ }
+
+uri_server = g_uri_get_host(uri);
+if (uri_server && !uri_server[0]) {
+uri_server = NULL;
 }
+uri_port = g_uri_get_port(uri);
 
 if (is_unix) {
 /* nbd+unix:///export?socket=path */
-if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) {
-ret = -EINVAL;
-goto out;
+const char *uri_socket = g_hash_table_lookup(qp, "socket");
+if (uri_server || uri_port != -1 || !uri_socket) {
+return -EINVAL;
 }
 qdict_put_str(options, "server.type", "unix");
-qdict_put_str(options, "server.path", qp->p[0].value);
+qdict_put_str(options, "server.path", uri_socket);
 } else {
-QString *host;
 char *port_str;
 
 /* nbd[+tcp]://host[:port]/export */
-if (!uri->server) {
-ret = -EINVAL;
-goto out;
-}
-
-/* strip braces from literal IPv6 address */
-if (uri->server[0] == '[') {
-host = qstring_from_substr(uri->server, 1,
-   strlen(uri->server) - 1);
-} else {
-host = qstring_from_str(uri->server);
+if (!uri_server) {
+return -EINVAL;
 }
 
 qdict_put_str(options, "server.type", "inet");
-qdict_put(options, "server.host", host);
+qdict_put_str(options, "server.host", uri_server);
 
-port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
+port_str = g_strdup_printf("%d", uri_port > 0 ? uri_port
+  : NBD_DEFAULT_PORT);
 qdict_put_str(options, "server.port", port_str);
 g_free(port_str);
 }
 
-out:
-if (qp) {
-query_params_free(qp);
-}
-uri_free(uri);
-return ret;
+return 0;
 }
 
 static bool nbd_has_filename_options_conflict(QDict *options, Error **errp)
-- 
2.45.0




[PULL 03/11] gitlab: use $MAKE instead of 'make'

2024-05-14 Thread Thomas Huth
From: Daniel P. Berrangé 

The lcitool generated containers have '$MAKE' set to the path
of the right 'make' binary. Using the env variable makes it
possible to override the choice per job.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Thomas Huth 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20240513111551.488088-3-berra...@redhat.com>
Signed-off-by: Thomas Huth 
---
 .gitlab-ci.d/buildtest-template.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitlab-ci.d/buildtest-template.yml 
b/.gitlab-ci.d/buildtest-template.yml
index 22045add80..278a5ea966 100644
--- a/.gitlab-ci.d/buildtest-template.yml
+++ b/.gitlab-ci.d/buildtest-template.yml
@@ -26,10 +26,10 @@
   then
 pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
   fi || exit 1;
-- make -j"$JOBS"
+- $MAKE -j"$JOBS"
 - if test -n "$MAKE_CHECK_ARGS";
   then
-make -j"$JOBS" $MAKE_CHECK_ARGS ;
+$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
   fi
 - ccache --show-stats
 
@@ -60,7 +60,7 @@
 - cd build
 - find . -type f -exec touch {} +
 # Avoid recompiling by hiding ninja with NINJA=":"
-- make NINJA=":" $MAKE_CHECK_ARGS
+- $MAKE NINJA=":" $MAKE_CHECK_ARGS
 
 .native_test_job_template:
   extends: .common_test_job_template
-- 
2.45.0




[PULL 06/11] Remove glib compatibility code that is not required anymore

2024-05-14 Thread Thomas Huth
Now that we bumped the minimum glib version to 2.66, we can drop
the old code.

Suggested-by: Paolo Bonzini 
Reviewed-by: Daniel P. Berrangé 
Message-ID: <20240418101056.302103-9-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 qga/commands-posix-ssh.c |  8 
 util/error-report.c  | 10 --
 2 files changed, 18 deletions(-)

diff --git a/qga/commands-posix-ssh.c b/qga/commands-posix-ssh.c
index 866afe6741..246171d323 100644
--- a/qga/commands-posix-ssh.c
+++ b/qga/commands-posix-ssh.c
@@ -243,7 +243,6 @@ qmp_guest_ssh_get_authorized_keys(const char *username, 
Error **errp)
 }
 
 #ifdef QGA_BUILD_UNIT_TEST
-#if GLIB_CHECK_VERSION(2, 60, 0)
 static const strList test_key2 = {
 .value = (char *)"algo key2 comments"
 };
@@ -439,11 +438,4 @@ int main(int argc, char *argv[])
 
 return g_test_run();
 }
-#else
-int main(int argc, char *argv[])
-{
-g_test_message("test skipped, needs glib >= 2.60");
-return 0;
-}
-#endif /* GLIB_2_60 */
 #endif /* BUILD_UNIT_TEST */
diff --git a/util/error-report.c b/util/error-report.c
index 6e44a55732..1b17c11de1 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -172,18 +172,8 @@ static void print_loc(void)
 static char *
 real_time_iso8601(void)
 {
-#if GLIB_CHECK_VERSION(2,62,0)
 g_autoptr(GDateTime) dt = g_date_time_new_now_utc();
-/* ignore deprecation warning, since GLIB_VERSION_MAX_ALLOWED is 2.56 */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 return g_date_time_format_iso8601(dt);
-#pragma GCC diagnostic pop
-#else
-GTimeVal tv;
-g_get_current_time(&tv);
-return g_time_val_to_iso8601(&tv);
-#endif
 }
 
 /*
-- 
2.45.0




[PULL 04/11] gitlab: use 'setarch -R' to workaround tsan bug

2024-05-14 Thread Thomas Huth
From: Daniel P. Berrangé 

The TSAN job started failing when gitlab rolled out their latest
release. The root cause is a change in the Google COS version used
on shared runners. This brings a kernel running with

 vm.mmap_rnd_bits = 31

which is incompatible with TSAN in LLVM < 18, which only supports
upto '28'. LLVM 18 can support upto '30', and failing that will
re-exec itself to turn off VA randomization.

Our LLVM is too old for now, but we can run with 'setarch -R make ..'
to turn off VA randomization ourselves.

Signed-off-by: Daniel P. Berrangé 
Reviewed-by: Thomas Huth 
Message-ID: <20240513111551.488088-4-berra...@redhat.com>
Signed-off-by: Thomas Huth 
---
 .gitlab-ci.d/buildtest.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 372404fc85..91c57efded 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -575,6 +575,9 @@ tsan-build:
 CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++
   --enable-trace-backends=ust --disable-slirp
 TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
+# Remove when we switch to a distro with clang >= 18
+# https://github.com/google/sanitizers/issues/1716
+MAKE: setarch -R make
 
 # gcov is a GCC features
 gcov:
-- 
2.45.0




[PULL 01/11] configure: Fix error message when C compiler is not working

2024-05-14 Thread Thomas Huth
If you try to run the configure script on a system without a working
C compiler, you get a very misleading error message:

 ERROR: Unrecognized host OS (uname -s reports 'Linux')

Some people already opened bug tickets because of this problem:

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

We should rather tell the user that we were not able to use the C
compiler instead, otherwise they will have a hard time to figure
out what was going wrong.

While we're at it, let's also suppress the "unrecognized host CPU"
message in this case since it is rather misleading than helpful.

Fixes: 264b803721 ("configure: remove compiler sanity check")
Message-ID: <20240513114010.51608-1-th...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Thomas Huth 
---
 configure | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 330664786d..38ee257701 100755
--- a/configure
+++ b/configure
@@ -411,7 +411,9 @@ else
   # Using uname is really broken, but it is just a fallback for architectures
   # that are going to use TCI anyway
   cpu=$(uname -m)
-  echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output 
'$cpu'"
+  if test "$host_os" != "bogus"; then
+echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output 
'$cpu'"
+  fi
 fi
 
 # Normalise host CPU name to the values used by Meson cross files and in source
@@ -894,6 +896,13 @@ EOF
 exit 0
 fi
 
+# Now that we are sure that the user did not only want to print the --help
+# information, we should double-check that the C compiler really works:
+write_c_skeleton
+if ! compile_object ; then
+error_exit "C compiler \"$cc\" either does not exist or does not work."
+fi
+
 # Remove old dependency files to make sure that they get properly regenerated
 rm -f ./*/config-devices.mak.d
 
-- 
2.45.0




Re: [PATCH] scripts/simpletrace: Mark output with unstable timestamp as WARN

2024-05-14 Thread Stefan Hajnoczi
On Tue, May 14, 2024, 03:57 Zhao Liu  wrote:

> Hi Stefan,
>
> > QEMU uses clock_gettime(CLOCK_MONOTONIC) on Linux hosts. The man page
> > says:
> >
> >   All CLOCK_MONOTONIC variants guarantee that the time returned by
> >   consecutive  calls  will  not go backwards, but successive calls
> >   may—depending  on  the  architecture—return  identical  (not-in‐
> >   creased) time values.
> >
> > trace_record_start() calls clock_gettime(CLOCK_MONOTONIC) so trace events
> > should have monotonically increasing timestamps.
> >
> > I don't see a scenario where trace record A's timestamp is greater than
> > trace record B's timestamp unless the clock is non-monotonic.
> >
> > Which host CPU architecture and operating system are you running?
>
> I tested on these 2 machines:
> * CML (intel 10th) with Ubuntu 22.04 + kernel v6.5.0-28
> * MTL (intel 14th) with Ubuntu 22.04.2 + kernel v6.9.0
>
> > Please attach to the QEMU process with gdb and print out the value of
> > the use_rt_clock variable or add a printf in init_get_clock(). The value
> > should be 1.
>
> Thanks, on both above machines, use_rt_clock is 1 and there're both
> timestamp reversal issues with the following debug print:
>
> diff --git a/include/qemu/timer.h b/include/qemu/timer.h
> index 9a366e551fb3..7657785c27dc 100644
> --- a/include/qemu/timer.h
> +++ b/include/qemu/timer.h
> @@ -831,10 +831,17 @@ extern int use_rt_clock;
>
>  static inline int64_t get_clock(void)
>  {
> +static int64_t clock = 0;
>

Please try with a thread local variable (__thread) to check whether this
happens within a single thread.

If it only happens with a global variable then we'd need to look more
closely at race conditions in the patch below. I don't think the patch is a
reliable way to detect non-monotonic timestamps in a multi-threaded program.

 if (use_rt_clock) {
>  struct timespec ts;
>  clock_gettime(CLOCK_MONOTONIC, &ts);
> -return ts.tv_sec * 10LL + ts.tv_nsec;
> +int64_t tmp = ts.tv_sec * 10LL + ts.tv_nsec;
> +if (tmp <= clock) {
> +printf("get_clock: strange, clock: %ld, tmp: %ld\n", clock,
> tmp);
> +}
> +assert(tmp > clock);
> +clock = tmp;
> +return clock;
>  } else {
>  /* XXX: using gettimeofday leads to problems if the date
> changes, so it should be avoided. */
> diff --git a/util/qemu-timer-common.c b/util/qemu-timer-common.c
> index cc1326f72646..3bf06eb4a4ce 100644
> --- a/util/qemu-timer-common.c
> +++ b/util/qemu-timer-common.c
> @@ -59,5 +59,6 @@ static void __attribute__((constructor))
> init_get_clock(void)
>  use_rt_clock = 1;
>  }
>  clock_start = get_clock();
> +printf("init_get_clock: use_rt_clock: %d\n", use_rt_clock);
>  }
>  #endif
>
> ---
> The timestamp interval is very small, for example:
> get_clock: strange, clock: 3302130503505, tmp: 3302130503503
>
> or
>
> get_clock: strange, clock: 2761577819846455, tmp: 2761577819846395
>
> I also tried to use CLOCK_MONOTONIC_RAW, but there's still the reversal
> issue.
>
> Thanks,
> Zhao
>
>


[PULL 10/11] block/ssh: Use URI parsing code from glib

2024-05-14 Thread Thomas Huth
Since version 2.66, glib has useful URI parsing functions, too.
Use those instead of the QEMU-internal ones to be finally able
to get rid of the latter.

While we're at it, also emit a warning when encountering unknown
parameters in the URI, so that the users have a chance to detect
their typos or other mistakes.

Reviewed-by: Richard W.M. Jones 
Message-ID: <20240418101056.302103-13-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 block/ssh.c | 75 -
 1 file changed, 40 insertions(+), 35 deletions(-)

diff --git a/block/ssh.c b/block/ssh.c
index 2748253d4a..a88171d4b5 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -37,7 +37,6 @@
 #include "qemu/ctype.h"
 #include "qemu/cutils.h"
 #include "qemu/sockets.h"
-#include "qemu/uri.h"
 #include "qapi/qapi-visit-sockets.h"
 #include "qapi/qapi-visit-block-core.h"
 #include "qapi/qmp/qdict.h"
@@ -181,65 +180,71 @@ static void sftp_error_trace(BDRVSSHState *s, const char 
*op)
 
 static int parse_uri(const char *filename, QDict *options, Error **errp)
 {
-URI *uri = NULL;
-QueryParams *qp;
+g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
+const char *uri_host, *uri_path, *uri_user, *uri_query;
 char *port_str;
-int i;
+int port;
+g_autoptr(GError) gerror = NULL;
+char *qp_name, *qp_value;
+GUriParamsIter qp;
 
-uri = uri_parse(filename);
 if (!uri) {
 return -EINVAL;
 }
 
-if (g_strcmp0(uri->scheme, "ssh") != 0) {
+if (g_strcmp0(g_uri_get_scheme(uri), "ssh") != 0) {
 error_setg(errp, "URI scheme must be 'ssh'");
-goto err;
+return -EINVAL;
 }
 
-if (!uri->server || strcmp(uri->server, "") == 0) {
+uri_host = g_uri_get_host(uri);
+if (!uri_host || g_str_equal(uri_host, "")) {
 error_setg(errp, "missing hostname in URI");
-goto err;
+return -EINVAL;
 }
 
-if (!uri->path || strcmp(uri->path, "") == 0) {
+uri_path = g_uri_get_path(uri);
+if (!uri_path || g_str_equal(uri_path, "")) {
 error_setg(errp, "missing remote path in URI");
-goto err;
-}
-
-qp = query_params_parse(uri->query);
-if (!qp) {
-error_setg(errp, "could not parse query parameters");
-goto err;
+return -EINVAL;
 }
 
-if(uri->user && strcmp(uri->user, "") != 0) {
-qdict_put_str(options, "user", uri->user);
+uri_user = g_uri_get_user(uri);
+if (uri_user && !g_str_equal(uri_user, "")) {
+qdict_put_str(options, "user", uri_user);
 }
 
-qdict_put_str(options, "server.host", uri->server);
+qdict_put_str(options, "server.host", uri_host);
 
-port_str = g_strdup_printf("%d", uri->port ?: 22);
+port = g_uri_get_port(uri);
+port_str = g_strdup_printf("%d", port > 0 ? port : 22);
 qdict_put_str(options, "server.port", port_str);
 g_free(port_str);
 
-qdict_put_str(options, "path", uri->path);
-
-/* Pick out any query parameters that we understand, and ignore
- * the rest.
- */
-for (i = 0; i < qp->n; ++i) {
-if (strcmp(qp->p[i].name, "host_key_check") == 0) {
-qdict_put_str(options, "host_key_check", qp->p[i].value);
+qdict_put_str(options, "path", uri_path);
+
+uri_query = g_uri_get_query(uri);
+if (uri_query) {
+g_uri_params_iter_init(&qp, uri_query, -1, "&", G_URI_PARAMS_NONE);
+while (g_uri_params_iter_next(&qp, &qp_name, &qp_value, &gerror)) {
+if (!qp_name || !qp_value || gerror) {
+warn_report("Failed to parse SSH URI parameters '%s'",
+uri_query);
+break;
+}
+/*
+ * Pick out the query parameters that we understand, and ignore
+ * (or rather warn about) the rest.
+ */
+if (g_str_equal(qp_name, "host_key_check")) {
+qdict_put_str(options, "host_key_check", qp_value);
+} else {
+warn_report("Unsupported parameter '%s' in URI", qp_name);
+}
 }
 }
 
-query_params_free(qp);
-uri_free(uri);
 return 0;
-
- err:
-uri_free(uri);
-return -EINVAL;
 }
 
 static bool ssh_has_filename_options_conflict(QDict *options, Error **errp)
-- 
2.45.0




[PULL 11/11] util/uri: Remove the old URI parsing code

2024-05-14 Thread Thomas Huth
Now that we switched all consumers of the URI code to use the URI
parsing functions from glib instead, we can remove our internal
URI parsing code since it is not used anymore.

Reviewed-by: Eric Blake 
Message-ID: <20240418101056.302103-14-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 include/qemu/uri.h |   99 ---
 util/uri.c | 1466 
 util/meson.build   |2 +-
 3 files changed, 1 insertion(+), 1566 deletions(-)
 delete mode 100644 include/qemu/uri.h
 delete mode 100644 util/uri.c

diff --git a/include/qemu/uri.h b/include/qemu/uri.h
deleted file mode 100644
index 255e61f452..00
--- a/include/qemu/uri.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * Summary: library of generic URI related routines
- * Description: library of generic URI related routines
- *  Implements RFC 2396
- *
- * Copyright (C) 1998-2003 Daniel Veillard.  All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
- * DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of Daniel Veillard shall not
- * be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from him.
- *
- * Author: Daniel Veillard
- **
- * Copyright (C) 2007 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see 
.
- *
- * Authors:
- *Richard W.M. Jones 
- *
- * Utility functions to help parse and assemble query strings.
- */
-
-#ifndef QEMU_URI_H
-#define QEMU_URI_H
-
-/**
- * URI:
- *
- * A parsed URI reference. This is a struct containing the various fields
- * as described in RFC 2396 but separated for further processing.
- */
-typedef struct URI {
-char *scheme;  /* the URI scheme */
-char *opaque;  /* opaque part */
-char *authority;   /* the authority part */
-char *server;  /* the server part */
-char *user;/* the user part */
-int port;  /* the port number */
-char *path;/* the path string */
-char *fragment;/* the fragment identifier */
-int cleanup;   /* parsing potentially unclean URI */
-char *query;   /* the query string (as it appears in the URI) */
-} URI;
-
-URI *uri_new(void);
-URI *uri_parse(const char *str);
-URI *uri_parse_raw(const char *str, int raw);
-int uri_parse_into(URI *uri, const char *str);
-char *uri_to_string(URI *uri);
-void uri_free(URI *uri);
-
-/* Single web service query parameter 'name=value'. */
-typedef struct QueryParam {
-  char *name;  /* Name (unescaped). */
-  char *value; /* Value (unescaped). */
-  int ignore;  /* Ignore this field in qparam_get_query */
-} QueryParam;
-
-/* Set of parameters. */
-typedef struct QueryParams {
-  int n;   /* number of parameters used */
-  int alloc;   /* allocated space */
-  QueryParam *p;   /* array of parameters */
-} QueryParams;
-
-QueryParams *query_params_new(int init_alloc);
-QueryParams *query_params_parse(const char *query);
-void query_params_free(QueryParams *ps);
-
-#endif /* QEMU_URI_H */
diff --git a/util/uri.c b/util/uri.c
deleted file mode 100644
index 573174bf47..00
--- a/util/uri.c
+++ /dev/null
@@ -1,1466 +0,0 @@
-/**
- * uri.c: set of generic URI related routines
- *
- * Reference: RFCs 3986, 2732 and 2373
- *
- * Copyright (C

Re: [PATCH v2 3/4] virtio-gpu: add x-vmstate-version

2024-05-14 Thread Peter Xu
On Tue, May 14, 2024 at 11:25:26AM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Tue, May 14, 2024 at 8:35 AM Peter Xu  wrote:
> >
> > Hey, Marc-Andre,
> >
> > On Mon, May 13, 2024 at 11:19:04AM +0400, marcandre.lur...@redhat.com wrote:
> > > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > > index ae831b6b3e..7f9fb5eacc 100644
> > > --- a/hw/display/virtio-gpu.c
> > > +++ b/hw/display/virtio-gpu.c
> > > @@ -1234,7 +1234,8 @@ static int virtio_gpu_save(QEMUFile *f, void 
> > > *opaque, size_t size,
> > >  }
> > >  qemu_put_be32(f, 0); /* end of list */
> > >
> > > -return vmstate_save_state(f, &vmstate_virtio_gpu_scanouts, g, NULL);
> > > +return vmstate_save_state_v(f, &vmstate_virtio_gpu_scanouts, g,
> > > +NULL, g->vmstate_version, NULL);
> > >  }
> > >
> > >  static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
> > > @@ -1339,7 +1340,7 @@ static int virtio_gpu_load(QEMUFile *f, void 
> > > *opaque, size_t size,
> > >  }
> > >
> > >  /* load & apply scanout state */
> > > -vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
> > > +vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 
> > > g->vmstate_version);
> >
> > [sorry for a late response; attending a conf, and will reply to the v1
> >  thread later for the other discussions..]
> >
> > These two changes shouldn't be needed if we go with the .field_exists()
> > approach, am I right?  IIUC in that case we can keep the version 1 here and
> > don't boost anything, because we relied on the machine versions.
> >
> > IIUC this might be the reason why we found 9.0 mahines are broken on
> > migration.  E.g, IIUC my original patch should work for 9.0<->9.0 too.
> >
> 
> Indeed, but for consistency, shouldn't it use the x-vmstate-version
> value for the top-level VMSD save/load ?
> 
> Otherwise, it feels a bit odd that this x-vmstate-version is only used
> for the nested "virtio-gpu-one-scanout" version.
> 
> Or perhaps we should rename it to x-scanout-vmstate-version ? wdyt

Makes sense to me.  In another place I used to have a field called
preempt_pre_7_2.. which is pretty wierd but it would be more accurate I
suppose if the field name reflects how that was defined, especially
differenciate that v.s. VMSD versioning as they're confusing indeed when
used together.

So if a rename I suppose we can even "vmstate-version".  I just wished VMSD
versioning could work with bi-directional migration already then we save
all the fuss... we used to have the chance before introducing
field_exists() (I suppose this one came later), but we didn't care or
notice at that time, sign.  We'll just need a handshake between src/dst so
that when src sees dst uses VMSD v1 it sends v1-only fields even if it
knows as far as v2.

For the long run we may be able to have some small helper so we fetch the
machine type globally, then maybe we can in the future pass in the test
function as:

bool test_function (void *opaque)
{
  return MACHINE_TYPE_BEFORE(8, 2);
}

Then it'll also avoid even introducing a variable.  Maybe we can provide
this test_function() directly too, one for each release.

Thanks,

> 
> 
> > Thanks,
> >
> > >
> > >  return 0;
> > >  }
> > > @@ -1659,6 +1660,7 @@ static Property virtio_gpu_properties[] = {
> > >  DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
> > >  VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
> > >  DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
> > > +DEFINE_PROP_UINT8("x-vmstate-version", VirtIOGPU, vmstate_version, 
> > > 1),
> > >  DEFINE_PROP_END_OF_LIST(),
> > >  };
> > >
> > > --
> > > 2.41.0.28.gd7d8841f67
> > >
> >
> > --
> > Peter Xu
> >
> 

-- 
Peter Xu




Re: [PATCH 1/3] qga-win32: Improve guest-set-user-password, guest-file-open errors

2024-05-14 Thread Philippe Mathieu-Daudé

On 14/5/24 12:58, Markus Armbruster wrote:

When guest-set-user-password's argument @password can't be converted
from UTF-8 to UTF-16, we report something like

 Guest agent command failed, error was 'Invalid sequence in conversion 
input'

Improve this to

 can't convert 'password' to UTF-16: Invalid sequence in conversion input

Likewise for argument @username, and guest-file-open argument @path,
even though I'm not sure you can actually get invalid input past the
QMP core there.

Signed-off-by: Markus Armbruster 
---
  qga/commands-win32.c | 17 +
  1 file changed, 9 insertions(+), 8 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH 3/3] qerror: QERR_QGA_COMMAND_FAILED is no longer used, drop

2024-05-14 Thread Philippe Mathieu-Daudé

On 14/5/24 12:58, Markus Armbruster wrote:

Signed-off-by: Markus Armbruster 
---
  include/qapi/qmp/qerror.h | 3 ---
  1 file changed, 3 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 





[PULL 01/11] Allow UNIX socket option for VNC websocket

2024-05-14 Thread marcandre . lureau
From: Sergii Zasenko 

- Remove unix socket option limitation for VNC websocket
- Reflect websocket option changes in documentation

Signed-off-by: Sergii Zasenko 
Reviewed-by: Marc-André Lureau 
Message-Id: <20230724100353.16628-1-ser...@zasenko.name>
---
 ui/vnc.c| 5 -
 qemu-options.hx | 4 
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index b3fd78022b..dd530f04e5 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3734,11 +3734,6 @@ static int vnc_display_get_address(const char *addrstr,
 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
 addr->u.q_unix.path = g_strdup(addrstr + 5);
 
-if (websocket) {
-error_setg(errp, "UNIX sockets not supported with websock");
-goto cleanup;
-}
-
 if (to) {
 error_setg(errp, "Port range not support with UNIX socket");
 goto cleanup;
diff --git a/qemu-options.hx b/qemu-options.hx
index f5c01eeeb4..4d19660336 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2516,6 +2516,10 @@ SRST
 host. It is possible to control the websocket listen address
 independently, using the syntax ``websocket``\ =host:port.
 
+Websocket could be allowed over UNIX domain socket, using the syntax
+``websocket``\ =unix:path, where path is the location of a unix socket
+to listen for connections on.
+
 If no TLS credentials are provided, the websocket connection
 runs in unencrypted mode. If TLS credentials are provided, the
 websocket connection requires encrypted client connections.
-- 
2.41.0.28.gd7d8841f67




Re: [PATCH 2/3] qga: Shorten several error messages

2024-05-14 Thread Philippe Mathieu-Daudé

On 14/5/24 13:02, Markus Armbruster wrote:

Markus Armbruster  writes:


Some, but not all error messages are of the form

 Guest agent command failed, error was ''

For instance, command guest-exec can fail with an error message like

 Guest agent command failed, error was 'Failed to execute child process 
“/bin/invalid-cmd42” (No such file or directory)'

Shorten this to just just the actual error message.  The guest-exec
example becomes

 Failed to execute child process “/bin/invalid-cmd42” (No such file or 
directory)

Signed-off-by: Markus Armbruster 


[...]

To be squashed into the patch:

diff --git a/qga/commands.c b/qga/commands.c
index 27b16313ea..5a5fad31f8 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -15,7 +15,6 @@
  #include "guest-agent-core.h"
  #include "qga-qapi-commands.h"
  #include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
  #include "qemu/base64.h"
  #include "qemu/cutils.h"
  #include "commands-common.h"



Reviewed-by: Philippe Mathieu-Daudé 




[PULL 08/11] ui/console: move QemuDmaBuf struct def to dmabuf.c

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

To complete privatizing process of QemuDmaBuf, QemuDmaBuf struct def
is moved to dmabuf.c

Suggested-by: Marc-André Lureau 
Reviewed-by: Marc-André Lureau 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-7-dongwon@intel.com>
---
 include/ui/dmabuf.h | 19 +--
 ui/dmabuf.c | 19 +++
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h
index 4198cdf85a..dc74ba895a 100644
--- a/include/ui/dmabuf.h
+++ b/include/ui/dmabuf.h
@@ -10,24 +10,7 @@
 #ifndef DMABUF_H
 #define DMABUF_H
 
-typedef struct QemuDmaBuf {
-int   fd;
-uint32_t  width;
-uint32_t  height;
-uint32_t  stride;
-uint32_t  fourcc;
-uint64_t  modifier;
-uint32_t  texture;
-uint32_t  x;
-uint32_t  y;
-uint32_t  backing_width;
-uint32_t  backing_height;
-bool  y0_top;
-void  *sync;
-int   fence_fd;
-bool  allow_fences;
-bool  draw_submitted;
-} QemuDmaBuf;
+typedef struct QemuDmaBuf QemuDmaBuf;
 
 QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height,
 uint32_t stride, uint32_t x,
diff --git a/ui/dmabuf.c b/ui/dmabuf.c
index e047d5ca26..df7a09703f 100644
--- a/ui/dmabuf.c
+++ b/ui/dmabuf.c
@@ -10,6 +10,25 @@
 #include "qemu/osdep.h"
 #include "ui/dmabuf.h"
 
+struct QemuDmaBuf {
+int   fd;
+uint32_t  width;
+uint32_t  height;
+uint32_t  stride;
+uint32_t  fourcc;
+uint64_t  modifier;
+uint32_t  texture;
+uint32_t  x;
+uint32_t  y;
+uint32_t  backing_width;
+uint32_t  backing_height;
+bool  y0_top;
+void  *sync;
+int   fence_fd;
+bool  allow_fences;
+bool  draw_submitted;
+};
+
 QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height,
 uint32_t stride, uint32_t x,
 uint32_t y, uint32_t backing_width,
-- 
2.41.0.28.gd7d8841f67




[PULL 09/11] ui/gtk: Add gd_motion_event trace event

2024-05-14 Thread marcandre . lureau
From: hikalium 

Add gd_motion_event trace event for making it easy to debug
gd_motion_event related issues.

Signed-off-by: hikalium 
Reviewed-by: Marc-André Lureau 
Message-Id: <20240512111435.30121-2-hikal...@hikalium.com>
---
 ui/gtk.c| 2 ++
 ui/trace-events | 1 +
 2 files changed, 3 insertions(+)

diff --git a/ui/gtk.c b/ui/gtk.c
index 3a6832eb1b..7ce73b0798 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -915,6 +915,8 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 x = (motion->x - mx) / vc->gfx.scale_x * ws;
 y = (motion->y - my) / vc->gfx.scale_y * ws;
 
+trace_gd_motion_event(ww, wh, gtk_widget_get_scale_factor(widget), x, y);
+
 if (qemu_input_is_absolute(vc->gfx.dcl.con)) {
 if (x < 0 || y < 0 ||
 x >= surface_width(vc->gfx.ds) ||
diff --git a/ui/trace-events b/ui/trace-events
index e6a2894303..69ff22955d 100644
--- a/ui/trace-events
+++ b/ui/trace-events
@@ -28,6 +28,7 @@ gd_ungrab(const char *tab, const char *device) "tab=%s, 
dev=%s"
 gd_keymap_windowing(const char *name) "backend=%s"
 gd_gl_area_create_context(void *ctx, int major, int minor) "ctx=%p, major=%d, 
minor=%d"
 gd_gl_area_destroy_context(void *ctx, void *current_ctx) "ctx=%p, 
current_ctx=%p"
+gd_motion_event(int ww, int wh, int ws, int x, int y) "ww=%d, wh=%d, ws=%d, 
x=%d, y=%d"
 
 # vnc-auth-sasl.c
 # vnc-auth-vencrypt.c
-- 
2.41.0.28.gd7d8841f67




[PULL 02/11] ui/gtk: Draw guest frame at refresh cycle

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

Draw routine needs to be manually invoked in the next refresh
if there is a scanout blob from the guest. This is to prevent
a situation where there is a scheduled draw event but it won't
happen bacause the window is currently in inactive state
(minimized or tabified). If draw is not done for a long time,
gl_block timeout and/or fence timeout (on the guest) will happen
eventually.

v2: Use gd_gl_area_draw(vc) in gtk-gl-area.c

Suggested-by: Vivek Kasireddy 
Cc: Gerd Hoffmann 
Cc: Marc-André Lureau 
Cc: Daniel P. Berrangé 
Signed-off-by: Dongwon Kim 
Acked-by: Marc-André Lureau 
Message-Id: <20240426225059.3871283-1-dongwon@intel.com>
---
 ui/gtk-egl.c | 1 +
 ui/gtk-gl-area.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 3af5ac5bcf..75f6b9011a 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -150,6 +150,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl)
 vc, vc->window ? vc->window : vc->gfx.drawing_area);
 
 if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) {
+gd_egl_draw(vc);
 return;
 }
 
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 52dcac161e..4fff957c3f 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -126,6 +126,7 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl)
 gd_update_monitor_refresh_rate(vc, vc->window ? vc->window : 
vc->gfx.drawing_area);
 
 if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) {
+gd_gl_area_draw(vc);
 return;
 }
 
-- 
2.41.0.28.gd7d8841f67




[PULL 03/11] ui/gtk: Check if fence_fd is equal to or greater than 0

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

'fence_fd' needs to be validated always before being referenced
And the passing condition should include '== 0' as 0 is a valid
value for the file descriptor.

Suggested-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-2-dongwon@intel.com>
---
 ui/gtk-egl.c |  2 +-
 ui/gtk-gl-area.c |  2 +-
 ui/gtk.c | 10 ++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 75f6b9011a..bceeeb0352 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -99,7 +99,7 @@ void gd_egl_draw(VirtualConsole *vc)
 #ifdef CONFIG_GBM
 if (dmabuf) {
 egl_dmabuf_create_fence(dmabuf);
-if (dmabuf->fence_fd > 0) {
+if (dmabuf->fence_fd >= 0) {
 qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, 
vc);
 return;
 }
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 4fff957c3f..b490727402 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -86,7 +86,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
 #ifdef CONFIG_GBM
 if (dmabuf) {
 egl_dmabuf_create_fence(dmabuf);
-if (dmabuf->fence_fd > 0) {
+if (dmabuf->fence_fd >= 0) {
 qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, 
vc);
 return;
 }
diff --git a/ui/gtk.c b/ui/gtk.c
index 810d7fc796..7819a86321 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -597,10 +597,12 @@ void gd_hw_gl_flushed(void *vcon)
 VirtualConsole *vc = vcon;
 QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 
-qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
-close(dmabuf->fence_fd);
-dmabuf->fence_fd = -1;
-graphic_hw_gl_block(vc->gfx.dcl.con, false);
+if (dmabuf->fence_fd >= 0) {
+qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
+close(dmabuf->fence_fd);
+dmabuf->fence_fd = -1;
+graphic_hw_gl_block(vc->gfx.dcl.con, false);
+}
 }
 
 /** DisplayState Callbacks (opengl version) **/
-- 
2.41.0.28.gd7d8841f67




[PULL 06/11] ui/console: Use qemu_dmabuf_set_..() helpers instead

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

This commit updates all occurrences where these fields were
set directly have been updated to utilize helper functions.

v7: removed prefix, "dpy_gl_" from all helpers

v8: Introduction of helpers was removed as those were already added
by the previous commit

Suggested-by: Marc-André Lureau 
Reviewed-by: Marc-André Lureau 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-5-dongwon@intel.com>
---
 ui/egl-helpers.c | 16 +---
 ui/gtk-egl.c |  4 ++--
 ui/gtk-gl-area.c |  4 ++--
 ui/gtk.c |  6 +++---
 4 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 3f96e63d25..99b2ebbe23 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -348,8 +348,8 @@ void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf)
 return;
 }
 
-glGenTextures(1, &dmabuf->texture);
-texture = qemu_dmabuf_get_texture(dmabuf);
+glGenTextures(1, &texture);
+qemu_dmabuf_set_texture(dmabuf, texture);
 glBindTexture(GL_TEXTURE_2D, texture);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -368,7 +368,7 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf)
 }
 
 glDeleteTextures(1, &texture);
-dmabuf->texture = 0;
+qemu_dmabuf_set_texture(dmabuf, 0);
 }
 
 void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf)
@@ -382,7 +382,7 @@ void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf)
 sync = eglCreateSyncKHR(qemu_egl_display,
 EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
 if (sync != EGL_NO_SYNC_KHR) {
-dmabuf->sync = sync;
+qemu_dmabuf_set_sync(dmabuf, sync);
 }
 }
 }
@@ -390,12 +390,14 @@ void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf)
 void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf)
 {
 void *sync = qemu_dmabuf_get_sync(dmabuf);
+int fence_fd;
 
 if (sync) {
-dmabuf->fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display,
-  sync);
+fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display,
+  sync);
+qemu_dmabuf_set_fence_fd(dmabuf, fence_fd);
 eglDestroySyncKHR(qemu_egl_display, sync);
-dmabuf->sync = NULL;
+qemu_dmabuf_set_sync(dmabuf, NULL);
 }
 }
 
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 5d7744ae4d..0473f689c9 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -87,7 +87,7 @@ void gd_egl_draw(VirtualConsole *vc)
 if (!qemu_dmabuf_get_draw_submitted(dmabuf)) {
 return;
 } else {
-dmabuf->draw_submitted = false;
+qemu_dmabuf_set_draw_submitted(dmabuf, false);
 }
 }
 #endif
@@ -382,7 +382,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,
 if (vc->gfx.guest_fb.dmabuf &&
 !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
 graphic_hw_gl_block(vc->gfx.dcl.con, true);
-vc->gfx.guest_fb.dmabuf->draw_submitted = true;
+qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true);
 gtk_egl_set_scanout_mode(vc, true);
 gtk_widget_queue_draw_area(area, x, y, w, h);
 return;
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 86360fe79b..b628b35451 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -63,7 +63,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
 if (!qemu_dmabuf_get_draw_submitted(dmabuf)) {
 return;
 } else {
-dmabuf->draw_submitted = false;
+qemu_dmabuf_set_draw_submitted(dmabuf, false);
 }
 }
 #endif
@@ -292,7 +292,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
 if (vc->gfx.guest_fb.dmabuf &&
 !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) {
 graphic_hw_gl_block(vc->gfx.dcl.con, true);
-vc->gfx.guest_fb.dmabuf->draw_submitted = true;
+qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true);
 gtk_gl_area_set_scanout_mode(vc, true);
 }
 gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
diff --git a/ui/gtk.c b/ui/gtk.c
index 237c913b26..3a6832eb1b 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -598,11 +598,11 @@ void gd_hw_gl_flushed(void *vcon)
 QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 int fence_fd;
 
-if (dmabuf->fence_fd >= 0) {
-fence_fd = qemu_dmabuf_get_fence_fd(dmabuf);
+fence_fd = qemu_dmabuf_get_fence_fd(dmabuf);
+if (fence_fd >= 0) {
 qemu_set_fd_handler(fence_fd, NULL, NULL, NULL);
 close(fence_fd);
-dmabuf->fence_fd = -1;
+qemu_dmabuf_set_fence_fd(dmabuf, -1);
 graphic_hw_gl_block(vc->gfx.dcl.con, false);
 }
 }
-- 
2.41.0.28.gd7d8841f67




[PULL 10/11] ui/gtk: Fix mouse/motion event scaling issue with GTK display backend

2024-05-14 Thread marcandre . lureau
From: hikalium 

Remove gtk_widget_get_scale_factor() usage from the calculation of
the motion events in the GTK backend to make it work correctly on
environments that have `gtk_widget_get_scale_factor() != 1`.

This scale factor usage had been introduced in the commit f14aab420c and
at that time the window size was used for calculating the things and it
was working correctly. However, in the commit 2f31663ed4 the logic
switched to use the widget size instead of window size and because of
the change the usage of scale factor becomes invalid (since widgets use
`vc->gfx.scale_{x, y}` for scaling).

Tested on Crostini on ChromeOS (15823.51.0) with an external display.

Fixes: 2f31663ed4 ("ui/gtk: use widget size for cursor motion event")
Fixes: f14aab420c ("ui: fix incorrect pointer position on highdpi with
gtk")

Signed-off-by: hikalium 
Acked-by: Marc-André Lureau 
Message-Id: <20240512111435.30121-3-hikal...@hikalium.com>
---
 ui/gtk.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 7ce73b0798..93b13b7a30 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -891,7 +891,7 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 int x, y;
 int mx, my;
 int fbh, fbw;
-int ww, wh, ws;
+int ww, wh;
 
 if (!vc->gfx.ds) {
 return TRUE;
@@ -899,11 +899,15 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 
 fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
 fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
-
 ww = gtk_widget_get_allocated_width(widget);
 wh = gtk_widget_get_allocated_height(widget);
-ws = gtk_widget_get_scale_factor(widget);
 
+/*
+ * `widget` may not have the same size with the frame buffer.
+ * In such cases, some paddings are needed around the `vc`.
+ * To achieve that, `vc` will be displayed at (mx, my)
+ * so that it is displayed at the center of the widget.
+ */
 mx = my = 0;
 if (ww > fbw) {
 mx = (ww - fbw) / 2;
@@ -912,8 +916,12 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 my = (wh - fbh) / 2;
 }
 
-x = (motion->x - mx) / vc->gfx.scale_x * ws;
-y = (motion->y - my) / vc->gfx.scale_y * ws;
+/*
+ * `motion` is reported in `widget` coordinates
+ * so translating it to the coordinates in `vc`.
+ */
+x = (motion->x - mx) / vc->gfx.scale_x;
+y = (motion->y - my) / vc->gfx.scale_y;
 
 trace_gd_motion_event(ww, wh, gtk_widget_get_scale_factor(widget), x, y);
 
-- 
2.41.0.28.gd7d8841f67




[PULL 07/11] ui/console: Use qemu_dmabuf_new() and free() helpers instead

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

This commit introduces utility functions for the creation and deallocation
of QemuDmaBuf instances. Additionally, it updates all relevant sections
of the codebase to utilize these new utility functions.

v7: remove prefix, "dpy_gl_" from all helpers
qemu_dmabuf_free() returns without doing anything if input is null
(Daniel P. Berrangé )
call G_DEFINE_AUTOPTR_CLEANUP_FUNC for qemu_dmabuf_free()
(Daniel P. Berrangé )

v8: Introduction of helpers was removed as those were already added
by the previous commit

v9: set dmabuf->allow_fences to 'true' when dmabuf is created in
virtio_gpu_create_dmabuf()/virtio-gpu-udmabuf.c

removed unnecessary spaces were accidently added in the patch,
'ui/console: Use qemu_dmabuf_new() a...'

v11: Calling qemu_dmabuf_close was removed as closing dmabuf->fd will be
 done in qemu_dmabuf_free anyway.
 (Daniel P. Berrangé )

v12: --- Calling qemu_dmabuf_close separately as qemu_dmabuf_free doesn't
 do it.

 --- 'dmabuf' is now allocated space so it should be freed at the end of
 dbus_scanout_texture

v13: --- Immediately free dmabuf after it is released to prevent possible
 leaking of the ptr
 (Marc-André Lureau )

 --- Use g_autoptr macro to define *dmabuf for auto clean up instead of
 calling qemu_dmabuf_free
 (Marc-André Lureau )

v14: --- (vhost-user-gpu) Change qemu_dmabuf_free back to g_clear_pointer
 as it was done because of some misunderstanding (v13).

 --- (vhost-user-gpu) g->dmabuf[m->scanout_id] needs to be set to NULL
 to prevent freed dmabuf to be accessed again in case if(fd==-1)break;
 happens (before new dmabuf is allocated). Otherwise, it would cause
 invalid memory access when the same function is executed. Also NULL
 check should be done before qemu_dmabuf_close (it asserts 
dmabuf!=NULL.).
 (Marc-André Lureau )

Suggested-by: Marc-André Lureau 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-6-dongwon@intel.com>
---
 include/hw/vfio/vfio-common.h   |  2 +-
 include/hw/virtio/virtio-gpu.h  |  4 ++--
 hw/display/vhost-user-gpu.c | 31 +++
 hw/display/virtio-gpu-udmabuf.c | 24 +---
 hw/vfio/display.c   | 26 --
 ui/dbus-listener.c  | 28 
 6 files changed, 55 insertions(+), 60 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index b9da6c08ef..d66e27db02 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -148,7 +148,7 @@ typedef struct VFIOGroup {
 } VFIOGroup;
 
 typedef struct VFIODMABuf {
-QemuDmaBuf buf;
+QemuDmaBuf *buf;
 uint32_t pos_x, pos_y, pos_updates;
 uint32_t hot_x, hot_y, hot_updates;
 int dmabuf_id;
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index ed44cdad6b..56d6e821bf 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -169,7 +169,7 @@ struct VirtIOGPUBaseClass {
 DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800)
 
 typedef struct VGPUDMABuf {
-QemuDmaBuf buf;
+QemuDmaBuf *buf;
 uint32_t scanout_id;
 QTAILQ_ENTRY(VGPUDMABuf) next;
 } VGPUDMABuf;
@@ -238,7 +238,7 @@ struct VhostUserGPU {
 VhostUserBackend *vhost;
 int vhost_gpu_fd; /* closed by the chardev */
 CharBackend vhost_chr;
-QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
+QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
 bool backend_blocked;
 };
 
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 454e5afcff..e4b398d26c 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -249,6 +249,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, 
VhostUserGpuMsg *msg)
 case VHOST_USER_GPU_DMABUF_SCANOUT: {
 VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout;
 int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr);
+uint64_t modifier = 0;
 QemuDmaBuf *dmabuf;
 
 if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
@@ -261,27 +262,33 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, 
VhostUserGpuMsg *msg)
 
 g->parent_obj.enable = 1;
 con = g->parent_obj.scanout[m->scanout_id].con;
-dmabuf = &g->dmabuf[m->scanout_id];
-qemu_dmabuf_close(dmabuf);
-dpy_gl_release_dmabuf(con, dmabuf);
+dmabuf = g->dmabuf[m->scanout_id];
+
+if (dmabuf) {
+qemu_dmabuf_close(dmabuf);
+dpy_gl_release_dmabuf(con, dmabuf);
+g_clear_pointer(&dmabuf, qemu_dmabuf_free);
+}
+
 if (fd == -1) {
 dpy_gl_scanout_disable(con);
+g->dmabuf[m->scanout_id] = NULL;
 break;
 }
-*dmabuf = (QemuDmaBuf) {
-.fd

[PULL 04/11] ui/console: new dmabuf.h and dmabuf.c for QemuDmaBuf struct and helpers

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

New header and source files are added for containing QemuDmaBuf struct
definition and newly introduced helpers for creating/freeing the struct
and accessing its data.

v10: Change the license type for both dmabuf.h and dmabuf.c from MIT to
 GPL to be in line with QEMU's default license

v11: -- Added new helpers, qemu_dmabuf_close for closing dmabuf->fd,
qemu_dmabuf_dup_fd for duplicating dmabuf->fd
(Daniel P. Berrangé )

 -- Let qemu_dmabuf_fee to call qemu_dmabuf_close before freeing
the struct to make sure fd is closed.
(Daniel P. Berrangé )

v12: Not closing fd in qemu_dmabuf_free because there are cases fd
 should still be available even after the struct is destroyed
 (e.g. virtio-gpu: res->dmabuf_fd).

Suggested-by: Marc-André Lureau 
Reviewed-by: Marc-André Lureau 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-3-dongwon@intel.com>
---
 include/ui/console.h |  20 +
 include/ui/dmabuf.h  |  66 ++
 ui/dmabuf.c  | 210 +++
 ui/meson.build   |   1 +
 4 files changed, 278 insertions(+), 19 deletions(-)
 create mode 100644 include/ui/dmabuf.h
 create mode 100644 ui/dmabuf.c

diff --git a/include/ui/console.h b/include/ui/console.h
index 0bc7a00ac0..a208a68b88 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -7,6 +7,7 @@
 #include "qapi/qapi-types-ui.h"
 #include "ui/input.h"
 #include "ui/surface.h"
+#include "ui/dmabuf.h"
 
 #define TYPE_QEMU_CONSOLE "qemu-console"
 OBJECT_DECLARE_TYPE(QemuConsole, QemuConsoleClass, QEMU_CONSOLE)
@@ -185,25 +186,6 @@ struct QEMUGLParams {
 int minor_ver;
 };
 
-typedef struct QemuDmaBuf {
-int   fd;
-uint32_t  width;
-uint32_t  height;
-uint32_t  stride;
-uint32_t  fourcc;
-uint64_t  modifier;
-uint32_t  texture;
-uint32_t  x;
-uint32_t  y;
-uint32_t  backing_width;
-uint32_t  backing_height;
-bool  y0_top;
-void  *sync;
-int   fence_fd;
-bool  allow_fences;
-bool  draw_submitted;
-} QemuDmaBuf;
-
 enum display_scanout {
 SCANOUT_NONE,
 SCANOUT_SURFACE,
diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h
new file mode 100644
index 00..4198cdf85a
--- /dev/null
+++ b/include/ui/dmabuf.h
@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * QemuDmaBuf struct and helpers used for accessing its data
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef DMABUF_H
+#define DMABUF_H
+
+typedef struct QemuDmaBuf {
+int   fd;
+uint32_t  width;
+uint32_t  height;
+uint32_t  stride;
+uint32_t  fourcc;
+uint64_t  modifier;
+uint32_t  texture;
+uint32_t  x;
+uint32_t  y;
+uint32_t  backing_width;
+uint32_t  backing_height;
+bool  y0_top;
+void  *sync;
+int   fence_fd;
+bool  allow_fences;
+bool  draw_submitted;
+} QemuDmaBuf;
+
+QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height,
+uint32_t stride, uint32_t x,
+uint32_t y, uint32_t backing_width,
+uint32_t backing_height, uint32_t fourcc,
+uint64_t modifier, int dmabuf_fd,
+bool allow_fences, bool y0_top);
+void qemu_dmabuf_free(QemuDmaBuf *dmabuf);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free);
+
+int qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf);
+int qemu_dmabuf_dup_fd(QemuDmaBuf *dmabuf);
+void qemu_dmabuf_close(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_height(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_stride(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_fourcc(QemuDmaBuf *dmabuf);
+uint64_t qemu_dmabuf_get_modifier(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_texture(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_x(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_y(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_backing_width(QemuDmaBuf *dmabuf);
+uint32_t qemu_dmabuf_get_backing_height(QemuDmaBuf *dmabuf);
+bool qemu_dmabuf_get_y0_top(QemuDmaBuf *dmabuf);
+void *qemu_dmabuf_get_sync(QemuDmaBuf *dmabuf);
+int32_t qemu_dmabuf_get_fence_fd(QemuDmaBuf *dmabuf);
+bool qemu_dmabuf_get_allow_fences(QemuDmaBuf *dmabuf);
+bool qemu_dmabuf_get_draw_submitted(QemuDmaBuf *dmabuf);
+void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture);
+void qemu_dmabuf_set_fence_fd(QemuDmaBuf *dmabuf, int32_t fence_fd);
+void qemu_dmabuf_set_sync(QemuDmaBuf *dmabuf, void *sync);
+void qemu_dmabuf_set_draw_submitted(QemuDmaBuf *dmabuf, bool draw_submitted);
+void qemu_dmabuf_set_fd(QemuDmaBuf *dmabuf, int32_t fd);
+
+#endif
diff --git a/ui/dmabuf.c b/ui/dmabuf.c
new file mode 100

[PULL 05/11] ui/console: Use qemu_dmabuf_get_..() helpers instead

2024-05-14 Thread marcandre . lureau
From: Dongwon Kim 

This commit updates all instances where fields within the QemuDmaBuf
struct are directly accessed, replacing them with calls to these new
helper functions.

v6: fix typos in helper names in ui/spice-display.c

v7: removed prefix, "dpy_gl_" from all helpers

v8: Introduction of helpers was removed as those were already added
by the previous commit

v11: -- Use new qemu_dmabuf_close() instead of close(qemu_dmabuf_get_fd()).
(Daniel P. Berrangé )
 -- Use new qemu_dmabuf_dup_fd() instead of dup(qemu_dmabuf_get_fd()).
(Daniel P. Berrangé )

Suggested-by: Marc-André Lureau 
Reviewed-by: Marc-André Lureau 
Cc: Philippe Mathieu-Daudé 
Cc: Daniel P. Berrangé 
Cc: Vivek Kasireddy 
Signed-off-by: Dongwon Kim 
Message-Id: <20240508175403.3399895-4-dongwon@intel.com>
---
 hw/display/vhost-user-gpu.c |  5 +---
 hw/display/virtio-gpu-udmabuf.c |  7 +++--
 hw/vfio/display.c   | 12 +---
 ui/console.c|  4 +--
 ui/dbus-console.c   |  9 --
 ui/dbus-listener.c  | 43 +---
 ui/egl-headless.c   | 23 ++-
 ui/egl-helpers.c| 47 ++-
 ui/gtk-egl.c| 48 ---
 ui/gtk-gl-area.c| 37 
 ui/gtk.c|  6 ++--
 ui/spice-display.c  | 50 +++--
 12 files changed, 181 insertions(+), 110 deletions(-)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 709c8a02a1..454e5afcff 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -262,10 +262,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, 
VhostUserGpuMsg *msg)
 g->parent_obj.enable = 1;
 con = g->parent_obj.scanout[m->scanout_id].con;
 dmabuf = &g->dmabuf[m->scanout_id];
-if (dmabuf->fd >= 0) {
-close(dmabuf->fd);
-dmabuf->fd = -1;
-}
+qemu_dmabuf_close(dmabuf);
 dpy_gl_release_dmabuf(con, dmabuf);
 if (fd == -1) {
 dpy_gl_scanout_disable(con);
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c
index d51184d658..c90eba281e 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-udmabuf.c
@@ -206,6 +206,7 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
 {
 struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id];
 VGPUDMABuf *new_primary, *old_primary = NULL;
+uint32_t width, height;
 
 new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb, r);
 if (!new_primary) {
@@ -216,10 +217,10 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g,
 old_primary = g->dmabuf.primary[scanout_id];
 }
 
+width = qemu_dmabuf_get_width(&new_primary->buf);
+height = qemu_dmabuf_get_height(&new_primary->buf);
 g->dmabuf.primary[scanout_id] = new_primary;
-qemu_console_resize(scanout->con,
-new_primary->buf.width,
-new_primary->buf.height);
+qemu_console_resize(scanout->con, width, height);
 dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf);
 
 if (old_primary) {
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 1aa440c663..7784502b53 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -260,8 +260,9 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice 
*vdev,
 static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf)
 {
 QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next);
+
+qemu_dmabuf_close(&dmabuf->buf);
 dpy_gl_release_dmabuf(dpy->con, &dmabuf->buf);
-close(dmabuf->buf.fd);
 g_free(dmabuf);
 }
 
@@ -286,6 +287,7 @@ static void vfio_display_dmabuf_update(void *opaque)
 VFIOPCIDevice *vdev = opaque;
 VFIODisplay *dpy = vdev->dpy;
 VFIODMABuf *primary, *cursor;
+uint32_t width, height;
 bool free_bufs = false, new_cursor = false;
 
 primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY);
@@ -296,10 +298,12 @@ static void vfio_display_dmabuf_update(void *opaque)
 return;
 }
 
+width = qemu_dmabuf_get_width(&primary->buf);
+height = qemu_dmabuf_get_height(&primary->buf);
+
 if (dpy->dmabuf.primary != primary) {
 dpy->dmabuf.primary = primary;
-qemu_console_resize(dpy->con,
-primary->buf.width, primary->buf.height);
+qemu_console_resize(dpy->con, width, height);
 dpy_gl_scanout_dmabuf(dpy->con, &primary->buf);
 free_bufs = true;
 }
@@ -328,7 +332,7 @@ static void vfio_display_dmabuf_update(void *opaque)
 cursor->pos_updates = 0;
 }
 
-dpy_gl_update(dpy->con, 0, 0, primary->buf.width, primary->buf.height);
+dpy_gl_update(dpy->con, 0, 0, width, height);
 
 if (free_bufs) {
 vfio_display_free_dmabufs(vdev);
diff --git a/ui/console.c b/ui/console.

[PULL 00/11] Ui patches

2024-05-14 Thread marcandre . lureau
From: Marc-André Lureau 

The following changes since commit 9360070196789cc8b9404b2efaf319384e64b107:

  Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging 
(2024-05-12 13:41:26 +0200)

are available in the Git repository at:

  https://gitlab.com/marcandre.lureau/qemu.git tags/ui-pull-request

for you to fetch changes up to 2e701e6785cd8cc048c608751c6e4f6253c67ab6:

  ui/sdl2: Allow host to power down screen (2024-05-14 17:14:13 +0400)


UI: small fixes and improvements



Bernhard Beschow (1):
  ui/sdl2: Allow host to power down screen

Dongwon Kim (7):
  ui/gtk: Draw guest frame at refresh cycle
  ui/gtk: Check if fence_fd is equal to or greater than 0
  ui/console: new dmabuf.h and dmabuf.c for QemuDmaBuf struct and
helpers
  ui/console: Use qemu_dmabuf_get_..() helpers instead
  ui/console: Use qemu_dmabuf_set_..() helpers instead
  ui/console: Use qemu_dmabuf_new() and free() helpers instead
  ui/console: move QemuDmaBuf struct def to dmabuf.c

Sergii Zasenko (1):
  Allow UNIX socket option for VNC websocket

hikalium (2):
  ui/gtk: Add gd_motion_event trace event
  ui/gtk: Fix mouse/motion event scaling issue with GTK display backend

 include/hw/vfio/vfio-common.h   |   2 +-
 include/hw/virtio/virtio-gpu.h  |   4 +-
 include/ui/console.h|  20 +--
 include/ui/dmabuf.h |  49 +++
 hw/display/vhost-user-gpu.c |  32 +++--
 hw/display/virtio-gpu-udmabuf.c |  27 ++--
 hw/vfio/display.c   |  32 ++---
 ui/console.c|   4 +-
 ui/dbus-console.c   |   9 +-
 ui/dbus-listener.c  |  71 +-
 ui/dmabuf.c | 229 
 ui/egl-headless.c   |  23 +++-
 ui/egl-helpers.c|  59 
 ui/gtk-egl.c|  53 +---
 ui/gtk-gl-area.c|  42 --
 ui/gtk.c|  32 +++--
 ui/sdl2.c   |   1 +
 ui/spice-display.c  |  50 ---
 ui/vnc.c|   5 -
 qemu-options.hx |   4 +
 ui/meson.build  |   1 +
 ui/trace-events |   1 +
 22 files changed, 547 insertions(+), 203 deletions(-)
 create mode 100644 include/ui/dmabuf.h
 create mode 100644 ui/dmabuf.c

-- 
2.41.0.28.gd7d8841f67




[PULL 11/11] ui/sdl2: Allow host to power down screen

2024-05-14 Thread marcandre . lureau
From: Bernhard Beschow 

By default, SDL disables the screen saver which prevents the host from powering
down the screen even if the screen is locked. This results in draining the
battery needlessly when the host isn't connected to a wall charger. Fix that by
enabling the screen saver.

Signed-off-by: Bernhard Beschow 
Acked-by: Marc-André Lureau 
Message-ID: <20240512095945.1879-1-shen...@gmail.com>
---
 ui/sdl2.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ui/sdl2.c b/ui/sdl2.c
index 4971963f00..0a0eb5a42d 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -874,6 +874,7 @@ static void sdl2_display_init(DisplayState *ds, 
DisplayOptions *o)
 SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0");
 #endif
 SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
+SDL_EnableScreenSaver();
 memset(&info, 0, sizeof(info));
 SDL_VERSION(&info.version);
 
-- 
2.41.0.28.gd7d8841f67




Re: CPR/liveupdate: test results using prior bug fix

2024-05-14 Thread Michael Galaxy

Steve,

OK, so it does not look like this bugfix you wrote was included in 8.2.4 
(which was released yesterday). Unfortunately, that means that anyone 
using CPR in that release will still (eventually) encounter the bug like 
I did.


I would recommend that y'all consider cherry-picking, perhaps, the 
relevant commits for a possible 8.2.5 ?


- Michael

On 5/13/24 20:15, Michael Galaxy wrote:

Hi Steve,

Thanks for the response.

It looks like literally *just today* 8.2.4 was released. I'll go check 
it out.


- Michael

On 5/13/24 15:10, Steven Sistare wrote:

Hi Michael,
  No surprise here, I did see some of the same failure messages and they
prompted me to submit the fix.  They are all symptoms of "the 
possibility of

ram and device state being out of sync" as mentioned in the commit.

I am not familiar with the process for maintaining old releases for 
qemu.

Perhaps someone on this list can comment on 8.2.3.

- Steve

On 5/13/2024 2:22 PM, Michael Galaxy wrote:

Hi Steve,

We found that this specific change in particular ("migration: stop 
vm for cpr") fixes a bug that we've identified in testing 
back-to-back live updates in a lab environment.


More specifically, *without* this change (which is not available in 
8.2.2, but *is* available in 9.0.0) causes the metadata save file to 
be corrupted when doing live updates one after another. Typically we 
see a corrupted save file somewhere in between 20 and 30 live 
updates and while doing a git bisect, we found that this change 
makes the problem go away.


Were you aware? Is there any plan in place to cherry pick this for 
8.2.3, perhaps or a plan to release 8.2.3 at some point?


Here are some examples of how the bug manifests in different 
locations of the QEMU metadata save file:


2024-04-26T13:28:53Z qemu-system-x86_64: Failed to load mtrr_var:base
2024-04-26T13:28:53Z qemu-system-x86_64: Failed to load 
cpu:env.mtrr_var
2024-04-26T13:28:53Z qemu-system-x86_64: error while loading state 
for instance 0x1b of device 'cpu'
2024-04-26T13:28:53Z qemu-system-x86_64: load of migration failed: 
Input/output error


And another:

2024-04-17T16:09:47Z qemu-system-x86_64: check_section_footer: Read 
section footer failed: -5
2024-04-17T16:09:47Z qemu-system-x86_64: load of migration failed: 
Invalid argument


And another:

2024-04-30T21:53:29Z qemu-system-x86_64: Unable to read ID string 
for section 163
2024-04-30T21:53:29Z qemu-system-x86_64: load of migration failed: 
Invalid argument


And another:

2024-05-01T16:01:44Z qemu-system-x86_64: Unable to read ID string 
for section 164
2024-05-01T16:01:44Z qemu-system-x86_64: load of migration failed: 
Invalid argument


As you can see, they occur quite randomly, but generally it takes at 
least 20-30+ live updates before the problem occurs.


- Michael

On 2/27/24 23:13, pet...@redhat.com wrote:

From: Steve Sistare

When migration for cpr is initiated, stop the vm and set state
RUN_STATE_FINISH_MIGRATE before ram is saved.  This eliminates the
possibility of ram and device state being out of sync, and guarantees
that a guest in the suspended state remains suspended, because 
qmp_cont

rejects a cont command in the RUN_STATE_FINISH_MIGRATE state.

Signed-off-by: Steve Sistare
Reviewed-by: Peter Xu
Link:https://urldefense.com/v3/__https://lore.kernel.org/r/1708622920-68779-11-git-send-email-steven.sistare@oracle.com__;!!GjvTz_vk!QLsFOCX-x2U9bzAo98SdidKlomHrmf_t0UmQKtgudoIcaDVoAJOPm39ZqaNP_nT5I8QqVfSgwhDZmg$ 
Signed-off-by: Peter Xu

---
  include/migration/misc.h |  1 +
  migration/migration.h    |  2 --
  migration/migration.c    | 51 


  3 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/include/migration/misc.h b/include/migration/misc.h
index e4933b815b..5d1aa593ed 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -60,6 +60,7 @@ void migration_object_init(void);
  void migration_shutdown(void);
  bool migration_is_idle(void);
  bool migration_is_active(MigrationState *);
+bool migrate_mode_is_cpr(MigrationState *);
    typedef enum MigrationEventType {
  MIG_EVENT_PRECOPY_SETUP,
diff --git a/migration/migration.h b/migration/migration.h
index aef8afbe1f..65c0b61cbd 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -541,6 +541,4 @@ int migration_rp_wait(MigrationState *s);
   */
  void migration_rp_kick(MigrationState *s);
  -int migration_stop_vm(RunState state);
-
  #endif
diff --git a/migration/migration.c b/migration/migration.c
index 37c836b0b0..90a90947fb 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -167,11 +167,19 @@ static gint 
page_request_addr_cmp(gconstpointer ap, gconstpointer bp)

  return (a > b) - (a < b);
  }
  -int migration_stop_vm(RunState state)
+static int migration_stop_vm(MigrationState *s, RunState state)
  {
-    int ret = vm_stop_force_state(state);
+    int ret;
+
+    migration_downtime_start(s);
+
+    s->vm_old_state = runstate_get();
+    global_stat

Re: [PATCH v2 01/45] target/hppa: Move cpu_get_tb_cpu_state out of line

2024-05-14 Thread Helge Deller

On 5/13/24 09:46, Richard Henderson wrote:

Signed-off-by: Richard Henderson 


Reviewed-by: Helge Deller 


---
  target/hppa/cpu.h | 43 ++-
  target/hppa/cpu.c | 42 ++
  2 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index fb2e4c4a98..61f1353133 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -314,47 +314,8 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr);
  #define TB_FLAG_PRIV_SHIFT  8
  #define TB_FLAG_UNALIGN 0x400

-static inline void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
-uint64_t *cs_base, uint32_t *pflags)
-{
-uint32_t flags = env->psw_n * PSW_N;
-
-/* TB lookup assumes that PC contains the complete virtual address.
-   If we leave space+offset separate, we'll get ITLB misses to an
-   incomplete virtual address.  This also means that we must separate
-   out current cpu privilege from the low bits of IAOQ_F.  */
-#ifdef CONFIG_USER_ONLY
-*pc = env->iaoq_f & -4;
-*cs_base = env->iaoq_b & -4;
-flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
-#else
-/* ??? E, T, H, L, B bits need to be here, when implemented.  */
-flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
-flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
-
-*pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
-env->iaoq_f & -4);
-*cs_base = env->iasq_f;
-
-/* Insert a difference between IAOQ_B and IAOQ_F within the otherwise zero
-   low 32-bits of CS_BASE.  This will succeed for all direct branches,
-   which is the primary case we care about -- using goto_tb within a page.
-   Failure is indicated by a zero difference.  */
-if (env->iasq_f == env->iasq_b) {
-target_long diff = env->iaoq_b - env->iaoq_f;
-if (diff == (int32_t)diff) {
-*cs_base |= (uint32_t)diff;
-}
-}
-if ((env->sr[4] == env->sr[5])
-& (env->sr[4] == env->sr[6])
-& (env->sr[4] == env->sr[7])) {
-flags |= TB_FLAG_SR_SAME;
-}
-#endif
-
-*pflags = flags;
-}
+void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
+  uint64_t *cs_base, uint32_t *pflags);

  target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
  void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 393a81988d..582036b31e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -43,6 +43,48 @@ static vaddr hppa_cpu_get_pc(CPUState *cs)
  return cpu->env.iaoq_f;
  }

+void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
+  uint64_t *cs_base, uint32_t *pflags)
+{
+uint32_t flags = env->psw_n * PSW_N;
+
+/* TB lookup assumes that PC contains the complete virtual address.
+   If we leave space+offset separate, we'll get ITLB misses to an
+   incomplete virtual address.  This also means that we must separate
+   out current cpu privilege from the low bits of IAOQ_F.  */
+#ifdef CONFIG_USER_ONLY
+*pc = env->iaoq_f & -4;
+*cs_base = env->iaoq_b & -4;
+flags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
+#else
+/* ??? E, T, H, L, B bits need to be here, when implemented.  */
+flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
+flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
+
+*pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
+env->iaoq_f & -4);
+*cs_base = env->iasq_f;
+
+/* Insert a difference between IAOQ_B and IAOQ_F within the otherwise zero
+   low 32-bits of CS_BASE.  This will succeed for all direct branches,
+   which is the primary case we care about -- using goto_tb within a page.
+   Failure is indicated by a zero difference.  */
+if (env->iasq_f == env->iasq_b) {
+target_long diff = env->iaoq_b - env->iaoq_f;
+if (diff == (int32_t)diff) {
+*cs_base |= (uint32_t)diff;
+}
+}
+if ((env->sr[4] == env->sr[5])
+& (env->sr[4] == env->sr[6])
+& (env->sr[4] == env->sr[7])) {
+flags |= TB_FLAG_SR_SAME;
+}
+#endif
+
+*pflags = flags;
+}
+
  static void hppa_cpu_synchronize_from_tb(CPUState *cs,
   const TranslationBlock *tb)
  {





Re: CPR/liveupdate: test results using prior bug fix

2024-05-14 Thread Michael Tokarev

On 5/14/24 16:39, Michael Galaxy wrote:

Steve,

OK, so it does not look like this bugfix you wrote was included in 8.2.4 
(which was released yesterday). Unfortunately, that means that anyone 
using CPR in that release will still (eventually) encounter the bug like 
I did.


8.2.4 is basically a "bugfix" release for 8.2.3 which I somewhat
screwed up (in a minor way), plus a few currently (at the time)
queued up changes.   8.2.3 was a big release though.

I would recommend that y'all consider cherry-picking, perhaps, the 
relevant commits for a possible 8.2.5 ?


Please Cc changes which are relevant for -stable to, well,
qemu-sta...@nongnu.org :)

Which changes needs to be picked up?

Thanks,

/mjt



Re: [PATCH v2 00/45] target/hppa: Misc improvements

2024-05-14 Thread Helge Deller

On 5/13/24 09:46, Richard Henderson wrote:

Most of the patches lead up to implementing CF_PCREL.
Along the way there is a grab bag of code updates (TCG_COND_TST*),
bug fixes (space changes during branch-in-branch-delay-slot),
and implementation of features (PSW bits B, X, T, H, L).

Sven reported that PSW L tripped up HP/UX, so possibly there's
something wrong there, but that's right at the end of the patch set.
So I'd like some feedback on the rest leading up to that too.


I do see the PSW_L issue as well (32-bit machine when starting HP-UX 11).
When leaving out patches 42-45 ("target/hppa: Implement PSW_T" and following)
I can boot 32-bit HP-UX 10 and 11.

Will review the patches now individually, but maybe you should
push the patches 1-41 first and we take the PSWT/L patches later?

Helge



Changes for v2:
   - Rebase and update for tcg_cflags_set.


r~


Richard Henderson (45):
   target/hppa: Move cpu_get_tb_cpu_state out of line
   target/hppa: Use hppa_form_gva_psw in hppa_cpu_get_pc
   target/hppa: Move constant destination check into use_goto_tb
   target/hppa: Pass displacement to do_dbranch
   target/hppa: Allow prior nullification in do_ibranch
   target/hppa: Use CF_BP_PAGE instead of cpu_breakpoint_test
   target/hppa: Add install_iaq_entries
   target/hppa: Add install_link
   target/hppa: Delay computation of IAQ_Next
   target/hppa: Skip nullified insns in unconditional dbranch path
   target/hppa: Simplify TB end
   target/hppa: Add IASQ entries to DisasContext
   target/hppa: Add space arguments to install_iaq_entries
   target/hppa: Add space argument to do_ibranch
   target/hppa: Use umax in do_ibranch_priv
   target/hppa: Always make a copy in do_ibranch_priv
   target/hppa: Introduce and use DisasIAQE for branch management
   target/hppa: Use displacements in DisasIAQE
   target/hppa: Rename cond_make_* helpers
   target/hppa: Use TCG_COND_TST* in do_cond
   target/hppa: Use TCG_COND_TST* in do_log_cond
   target/hppa: Use TCG_COND_TST* in do_unit_zero_cond
   target/hppa: Use TCG_COND_TST* in do_unit_addsub
   target/hppa: Use TCG_COND_TST* in trans_bb_imm
   target/hppa: Use registerfields.h for FPSR
   target/hppa: Use TCG_COND_TST* in trans_ftest
   target/hppa: Remove cond_free
   target/hppa: Introduce DisasDelayException
   target/hppa: Use delay_excp for conditional traps
   target/hppa: Use delay_excp for conditional trap on overflow
   linux-user/hppa: Force all code addresses to PRIV_USER
   target/hppa: Store full iaoq_f and page offset of iaoq_b in TB
   target/hppa: Do not mask in copy_iaoq_entry
   target/hppa: Improve hppa_cpu_dump_state
   target/hppa: Split PSW X and B into their own field
   target/hppa: Manage PSW_X and PSW_B in translator
   target/hppa: Implement PSW_B
   target/hppa: Implement PSW_X
   target/hppa: Drop tlb_entry return from hppa_get_physical_address
   target/hppa: Adjust priv for B,GATE at runtime
   target/hppa: Implement CF_PCREL
   target/hppa: Implement PSW_T
   target/hppa: Implement PSW_H, PSW_L
   target/hppa: Log cpu state at interrupt
   target/hppa: Log cpu state on return-from-interrupt

  linux-user/hppa/target_cpu.h |4 +-
  target/hppa/cpu.h|   80 +--
  target/hppa/helper.h |3 +-
  linux-user/elfload.c |4 +-
  linux-user/hppa/cpu_loop.c   |   14 +-
  linux-user/hppa/signal.c |6 +-
  target/hppa/cpu.c|   92 ++-
  target/hppa/fpu_helper.c |   26 +-
  target/hppa/gdbstub.c|6 +
  target/hppa/helper.c |   66 +-
  target/hppa/int_helper.c |   33 +-
  target/hppa/mem_helper.c |   99 +--
  target/hppa/op_helper.c  |   17 +-
  target/hppa/sys_helper.c |   12 +
  target/hppa/translate.c  | 1232 ++
  15 files changed, 947 insertions(+), 747 deletions(-)






Re: [PATCH v2 02/45] target/hppa: Use hppa_form_gva_psw in hppa_cpu_get_pc

2024-05-14 Thread Helge Deller
* Richard Henderson :
> This function is for log_pc(), which needs to produce a
> similar result to cpu_get_tb_cpu_state().
> 
> Signed-off-by: Richard Henderson 


Reviewed-by: Helge Deller 

---
> ---
>  target/hppa/cpu.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
> index 582036b31e..be8c558014 100644
> --- a/target/hppa/cpu.c
> +++ b/target/hppa/cpu.c
> @@ -38,9 +38,10 @@ static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
>  
>  static vaddr hppa_cpu_get_pc(CPUState *cs)
>  {
> -HPPACPU *cpu = HPPA_CPU(cs);
> +CPUHPPAState *env = cpu_env(cs);
>  
> -return cpu->env.iaoq_f;
> +return hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
> + env->iaoq_f & -4);
>  }
>  
>  void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
> @@ -61,8 +62,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
>  flags |= env->psw & (PSW_W | PSW_C | PSW_D | PSW_P);
>  flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
>  
> -*pc = hppa_form_gva_psw(env->psw, (env->psw & PSW_C ? env->iasq_f : 0),
> -env->iaoq_f & -4);
> +*pc = hppa_cpu_get_pc(env_cpu(env));
>  *cs_base = env->iasq_f;
>  
>  /* Insert a difference between IAOQ_B and IAOQ_F within the otherwise 
> zero
> -- 
> 2.34.1
> 



Re: [PATCH v2 03/45] target/hppa: Move constant destination check into use_goto_tb

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Share this check between gen_goto_tb and hppa_tr_translate_insn.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 6d45611888..398803981c 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -662,9 +662,10 @@ static bool gen_illegal(DisasContext *ctx)
>  } while (0)
>  #endif
>  
> -static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
> +static bool use_goto_tb(DisasContext *ctx, uint64_t bofs, uint64_t nofs)
>  {
> -return translator_use_goto_tb(&ctx->base, dest);
> +return (bofs != -1 && nofs != -1 &&
> +translator_use_goto_tb(&ctx->base, bofs));
>  }
>  
>  /* If the next insn is to be nullified, and it's on the same page,
> @@ -678,16 +679,16 @@ static bool use_nullify_skip(DisasContext *ctx)
>  }
>  
>  static void gen_goto_tb(DisasContext *ctx, int which,
> -uint64_t f, uint64_t b)
> +uint64_t b, uint64_t n)
>  {
> -if (f != -1 && b != -1 && use_goto_tb(ctx, f)) {
> +if (use_goto_tb(ctx, b, n)) {
>  tcg_gen_goto_tb(which);
> -copy_iaoq_entry(ctx, cpu_iaoq_f, f, NULL);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, b, NULL);
> +copy_iaoq_entry(ctx, cpu_iaoq_f, b, NULL);
> +copy_iaoq_entry(ctx, cpu_iaoq_b, n, NULL);
>  tcg_gen_exit_tb(ctx->base.tb, which);
>  } else {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, f, cpu_iaoq_b);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, b, ctx->iaoq_n_var);
> +copy_iaoq_entry(ctx, cpu_iaoq_f, b, cpu_iaoq_b);
> +copy_iaoq_entry(ctx, cpu_iaoq_b, n, ctx->iaoq_n_var);
>  tcg_gen_lookup_and_goto_ptr();
>  }
>  }
> @@ -4744,8 +4745,7 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  /* Advance the insn queue.  Note that this check also detects
> a priority change within the instruction queue.  */
>  if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
> -if (ctx->iaoq_b != -1 && ctx->iaoq_n != -1
> -&& use_goto_tb(ctx, ctx->iaoq_b)
> +if (use_goto_tb(ctx, ctx->iaoq_b, ctx->iaoq_n)
>  && (ctx->null_cond.c == TCG_COND_NEVER
>  || ctx->null_cond.c == TCG_COND_ALWAYS)) {
>  nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
> -- 
> 2.34.1
> 



Re: [PATCH v2 04/45] target/hppa: Pass displacement to do_dbranch

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Pass a displacement instead of an absolute value.
> 
> In trans_be, remove the user-only do_dbranch case.  The branch we are
> attempting to optimize is to the zero page, which is perforce on a
> different page than the code currently executing, which means that
> we will *not* use a goto_tb.  Use a plain indirect branch instead,
> which is what we got out of the attempted direct branch anyway.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 33 +
>  1 file changed, 9 insertions(+), 24 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 398803981c..4c42b518c5 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -1766,9 +1766,11 @@ static bool do_fop_dedd(DisasContext *ctx, unsigned rt,
>  
>  /* Emit an unconditional branch to a direct target, which may or may not
> have already had nullification handled.  */
> -static bool do_dbranch(DisasContext *ctx, uint64_t dest,
> +static bool do_dbranch(DisasContext *ctx, int64_t disp,
> unsigned link, bool is_n)
>  {
> +uint64_t dest = iaoq_dest(ctx, disp);
> +
>  if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
>  if (link != 0) {
>  copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> @@ -1815,10 +1817,7 @@ static bool do_cbranch(DisasContext *ctx, int64_t 
> disp, bool is_n,
>  
>  /* Handle TRUE and NEVER as direct branches.  */
>  if (c == TCG_COND_ALWAYS) {
> -return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
> -}
> -if (c == TCG_COND_NEVER) {
> -return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
> +return do_dbranch(ctx, disp, 0, is_n && disp >= 0);
>  }
>  
>  taken = gen_new_label();
> @@ -3914,22 +3913,6 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  {
>  TCGv_i64 tmp;
>  
> -#ifdef CONFIG_USER_ONLY
> -/* ??? It seems like there should be a good way of using
> -   "be disp(sr2, r0)", the canonical gateway entry mechanism
> -   to our advantage.  But that appears to be inconvenient to
> -   manage along side branch delay slots.  Therefore we handle
> -   entry into the gateway page via absolute address.  */
> -/* Since we don't implement spaces, just branch.  Do notice the special
> -   case of "be disp(*,r0)" using a direct branch to disp, so that we can
> -   goto_tb to the TB containing the syscall.  */
> -if (a->b == 0) {
> -return do_dbranch(ctx, a->disp, a->l, a->n);
> -}
> -#else
> -nullify_over(ctx);
> -#endif
> -
>  tmp = tcg_temp_new_i64();
>  tcg_gen_addi_i64(tmp, load_gpr(ctx, a->b), a->disp);
>  tmp = do_ibranch_priv(ctx, tmp);
> @@ -3939,6 +3922,8 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  #else
>  TCGv_i64 new_spc = tcg_temp_new_i64();
>  
> +nullify_over(ctx);
> +
>  load_spr(ctx, new_spc, a->sp);
>  if (a->l) {
>  copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
> @@ -3968,7 +3953,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  
>  static bool trans_bl(DisasContext *ctx, arg_bl *a)
>  {
> -return do_dbranch(ctx, iaoq_dest(ctx, a->disp), a->l, a->n);
> +return do_dbranch(ctx, a->disp, a->l, a->n);
>  }
>  
>  static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
> @@ -4022,7 +4007,7 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate 
> *a)
>  save_gpr(ctx, a->l, tmp);
>  }
>  
> -return do_dbranch(ctx, dest, 0, a->n);
> +return do_dbranch(ctx, dest - iaoq_dest(ctx, 0), 0, a->n);
>  }
>  
>  static bool trans_blr(DisasContext *ctx, arg_blr *a)
> @@ -4035,7 +4020,7 @@ static bool trans_blr(DisasContext *ctx, arg_blr *a)
>  return do_ibranch(ctx, tmp, a->l, a->n);
>  } else {
>  /* BLR R0,RX is a good way to load PC+8 into RX.  */
> -return do_dbranch(ctx, ctx->iaoq_f + 8, a->l, a->n);
> +return do_dbranch(ctx, 0, a->l, a->n);
>  }
>  }
>  
> -- 
> 2.34.1
> 



RE: [PATCH v6 6/7] migration/multifd: implement qpl compression and decompression

2024-05-14 Thread Fabiano Rosas
"Liu, Yuan1"  writes:

>> -Original Message-
>> From: Fabiano Rosas 
>> Sent: Monday, May 13, 2024 11:14 PM
>> To: Liu, Yuan1 ; pet...@redhat.com
>> Cc: qemu-devel@nongnu.org; Liu, Yuan1 ; Zou, Nanhai
>> 
>> Subject: Re: [PATCH v6 6/7] migration/multifd: implement qpl compression
>> and decompression
>> 
>> Yuan Liu  writes:
>> 
>> > each qpl job is used to (de)compress a normal page and it can
>> > be processed independently by the IAA hardware. All qpl jobs
>> > are submitted to the hardware at once, and wait for all jobs
>> > completion. If hardware path(IAA) is not available, use software
>> > for compression and decompression.
>> >
>> > Signed-off-by: Yuan Liu 
>> > Reviewed-by: Nanhai Zou 
>> > ---
>> >  migration/multifd-qpl.c | 284 +++-
>> >  1 file changed, 280 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/migration/multifd-qpl.c b/migration/multifd-qpl.c
>> > index 89fa51091a..9a1fddbdd0 100644
>> > --- a/migration/multifd-qpl.c
>> > +++ b/migration/multifd-qpl.c
>> > @@ -13,6 +13,7 @@
>> >  #include "qemu/osdep.h"
>> >  #include "qemu/module.h"
>> >  #include "qapi/error.h"
>> > +#include "exec/ramblock.h"
>> >  #include "migration.h"
>> >  #include "multifd.h"
>> >  #include "qpl/qpl.h"
>> > @@ -204,6 +205,139 @@ static void
>> multifd_qpl_send_cleanup(MultiFDSendParams *p, Error **errp)
>> >  p->iov = NULL;
>> >  }
>> >
>> > +/**
>> > + * multifd_qpl_prepare_job: prepare a compression or decompression job
>> > + *
>> > + * Prepare a compression or decompression job and configure job
>> attributes
>> > + * including job compression level and flags.
>> > + *
>> > + * @job: pointer to the QplData structure
>> 
>> qpl_job structure
>
> Thanks for the comment, I will fix this next version.
>
>> > + * @is_compression: compression or decompression indication
>> > + * @input: pointer to the input data buffer
>> > + * @input_len: the length of the input data
>> > + * @output: pointer to the output data buffer
>> > + * @output_len: the size of the output data buffer
>> > + */
>> > +static void multifd_qpl_prepare_job(qpl_job *job, bool is_compression,
>> > +uint8_t *input, uint32_t input_len,
>> > +uint8_t *output, uint32_t
>> output_len)
>> > +{
>> > +job->op = is_compression ? qpl_op_compress : qpl_op_decompress;
>> > +job->next_in_ptr = input;
>> > +job->next_out_ptr = output;
>> > +job->available_in = input_len;
>> > +job->available_out = output_len;
>> > +job->flags = QPL_FLAG_FIRST | QPL_FLAG_LAST | QPL_FLAG_OMIT_VERIFY;
>> > +/* only supports one compression level */
>> > +job->level = 1;
>> > +}
>> > +
>> > +/**
>> > + * multifd_qpl_build_packet: build a qpl compressed data packet
>> > + *
>> > + * The qpl compressed data packet consists of two parts, one part
>> stores
>> > + * the compressed length of each page, and the other part is the
>> compressed
>> > + * data of each page. The zbuf_hdr stores the compressed length of all
>> pages,
>> > + * and use a separate IOV to store the compressed data of each page.
>> > + *
>> > + * @qpl: pointer to the QplData structure
>> > + * @p: Params for the channel that we are using
>> > + * @idx: The index of the compressed length array
>> > + * @addr: pointer to the compressed data
>> > + * @len: The length of the compressed data
>> > + */
>> > +static void multifd_qpl_build_packet(QplData *qpl, MultiFDSendParams
>> *p,
>> > + uint32_t idx, uint8_t *addr,
>> uint32_t len)
>> > +{
>> > +qpl->zbuf_hdr[idx] = cpu_to_be32(len);
>> > +p->iov[p->iovs_num].iov_base = addr;
>> > +p->iov[p->iovs_num].iov_len = len;
>> > +p->iovs_num++;
>> > +p->next_packet_size += len;
>> > +}
>> > +
>> > +/**
>> > + * multifd_qpl_compress_pages: compress normal pages
>> > + *
>> > + * Each normal page will be compressed independently, and the
>> compression jobs
>> > + * will be submitted to the IAA hardware in non-blocking mode, waiting
>> for all
>> > + * jobs to be completed and filling the compressed length and data into
>> the
>> > + * sending IOVs. If IAA device is not available, the software path is
>> used.
>> > + *
>> > + * Returns 0 for success or -1 for error
>> > + *
>> > + * @p: Params for the channel that we are using
>> > + * @errp: pointer to an error
>> > + */
>> > +static int multifd_qpl_compress_pages(MultiFDSendParams *p, Error
>> **errp)
>> > +{
>> > +qpl_status status;
>> > +QplData *qpl = p->compress_data;
>> > +MultiFDPages_t *pages = p->pages;
>> > +uint8_t *zbuf = qpl->zbuf;
>> > +uint8_t *host = pages->block->host;
>> > +uint32_t job_num = pages->normal_num;
>> 
>> A bit misleading because job_num is used in the previous patch as a
>> synonym for page_count. We could change the previous patch to:
>> multifd_qpl_init(uint32_t page_count, ...
>
> Yes, I will replace job_num with page_count for multifd_qpl_init next versi

Re: [PATCH v2 05/45] target/hppa: Allow prior nullification in do_ibranch

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Simplify the function by not attempting a conditional move
> on the branch destination -- just use nullify_over normally.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 73 +++--
>  1 file changed, 20 insertions(+), 53 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 4c42b518c5..140dfb747a 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -1871,17 +1871,15 @@ static bool do_cbranch(DisasContext *ctx, int64_t 
> disp, bool is_n,
>  static bool do_ibranch(DisasContext *ctx, TCGv_i64 dest,
> unsigned link, bool is_n)
>  {
> -TCGv_i64 a0, a1, next, tmp;
> -TCGCond c;
> +TCGv_i64 next;
>  
> -assert(ctx->null_lab == NULL);
> +if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
> +next = tcg_temp_new_i64();
> +tcg_gen_mov_i64(next, dest);
>  
> -if (ctx->null_cond.c == TCG_COND_NEVER) {
>  if (link != 0) {
>  copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
>  }
> -next = tcg_temp_new_i64();
> -tcg_gen_mov_i64(next, dest);
>  if (is_n) {
>  if (use_nullify_skip(ctx)) {
>  copy_iaoq_entry(ctx, cpu_iaoq_f, -1, next);
> @@ -1895,60 +1893,29 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 
> dest,
>  }
>  ctx->iaoq_n = -1;
>  ctx->iaoq_n_var = next;
> -} else if (is_n && use_nullify_skip(ctx)) {
> -/* The (conditional) branch, B, nullifies the next insn, N,
> -   and we're allowed to skip execution N (no single-step or
> -   tracepoint in effect).  Since the goto_ptr that we must use
> -   for the indirect branch consumes no special resources, we
> -   can (conditionally) skip B and continue execution.  */
> -/* The use_nullify_skip test implies we have a known control path.  
> */
> -tcg_debug_assert(ctx->iaoq_b != -1);
> -tcg_debug_assert(ctx->iaoq_n != -1);
> +return true;
> +}
>  
> -/* We do have to handle the non-local temporary, DEST, before
> -   branching.  Since IOAQ_F is not really live at this point, we
> -   can simply store DEST optimistically.  Similarly with IAOQ_B.  */
> +nullify_over(ctx);
> +
> +if (is_n && use_nullify_skip(ctx)) {
>  copy_iaoq_entry(ctx, cpu_iaoq_f, -1, dest);
>  next = tcg_temp_new_i64();
>  tcg_gen_addi_i64(next, dest, 4);
>  copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
> -
> -nullify_over(ctx);
> -if (link != 0) {
> -copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
> -tcg_gen_lookup_and_goto_ptr();
> -return nullify_end(ctx);
> +nullify_set(ctx, 0);
>  } else {
> -c = ctx->null_cond.c;
> -a0 = ctx->null_cond.a0;
> -a1 = ctx->null_cond.a1;
> -
> -tmp = tcg_temp_new_i64();
> -next = tcg_temp_new_i64();
> -
> -copy_iaoq_entry(ctx, tmp, ctx->iaoq_n, ctx->iaoq_n_var);
> -tcg_gen_movcond_i64(c, next, a0, a1, tmp, dest);
> -ctx->iaoq_n = -1;
> -ctx->iaoq_n_var = next;
> -
> -if (link != 0) {
> -tcg_gen_movcond_i64(c, cpu_gr[link], a0, a1, cpu_gr[link], tmp);
> -}
> -
> -if (is_n) {
> -/* The branch nullifies the next insn, which means the state of N
> -   after the branch is the inverse of the state of N that applied
> -   to the branch.  */
> -tcg_gen_setcond_i64(tcg_invert_cond(c), cpu_psw_n, a0, a1);
> -cond_free(&ctx->null_cond);
> -ctx->null_cond = cond_make_n();
> -ctx->psw_n_nonzero = true;
> -} else {
> -cond_free(&ctx->null_cond);
> -}
> +copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
> +copy_iaoq_entry(ctx, cpu_iaoq_b, -1, dest);
> +nullify_set(ctx, is_n);
>  }
> -return true;
> +if (link != 0) {
> +copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> +}
> +
> +tcg_gen_lookup_and_goto_ptr();
> +ctx->base.is_jmp = DISAS_NORETURN;
> +return nullify_end(ctx);
>  }
>  
>  /* Implement
> -- 
> 2.34.1
> 



Re: [PATCH 4/9] migration: Add direct-io parameter

2024-05-14 Thread Markus Armbruster
Peter Xu  writes:

> On Fri, May 03, 2024 at 05:49:32PM -0300, Fabiano Rosas wrote:
>> Peter Xu  writes:
>> 
>> > On Fri, Apr 26, 2024 at 11:20:37AM -0300, Fabiano Rosas wrote:
>> >> Add the direct-io migration parameter that tells the migration code to
>> >> use O_DIRECT when opening the migration stream file whenever possible.
>> >> 
>> >> This is currently only used with the mapped-ram migration that has a
>> >> clear window guaranteed to perform aligned writes.
>> >> 
>> >> Acked-by: Markus Armbruster 
>> >> Signed-off-by: Fabiano Rosas 
>> >> ---
>> >>  include/qemu/osdep.h   |  2 ++
>> >>  migration/migration-hmp-cmds.c | 11 +++
>> >>  migration/options.c| 30 ++
>> >>  migration/options.h|  1 +
>> >>  qapi/migration.json| 18 +++---
>> >>  util/osdep.c   |  9 +
>> >>  6 files changed, 68 insertions(+), 3 deletions(-)
>> >> 
>> >> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
>> >> index c7053cdc2b..645c14a65d 100644
>> >> --- a/include/qemu/osdep.h
>> >> +++ b/include/qemu/osdep.h
>> >> @@ -612,6 +612,8 @@ int qemu_lock_fd_test(int fd, int64_t start, int64_t 
>> >> len, bool exclusive);
>> >>  bool qemu_has_ofd_lock(void);
>> >>  #endif
>> >>  
>> >> +bool qemu_has_direct_io(void);
>> >> +
>> >>  #if defined(__HAIKU__) && defined(__i386__)
>> >>  #define FMT_pid "%ld"
>> >>  #elif defined(WIN64)
>> >> diff --git a/migration/migration-hmp-cmds.c 
>> >> b/migration/migration-hmp-cmds.c
>> >> index 7e96ae6ffd..8496a2b34e 100644
>> >> --- a/migration/migration-hmp-cmds.c
>> >> +++ b/migration/migration-hmp-cmds.c
>> >> @@ -397,6 +397,13 @@ void hmp_info_migrate_parameters(Monitor *mon, const 
>> >> QDict *qdict)
>> >>  monitor_printf(mon, "%s: %s\n",
>> >>  MigrationParameter_str(MIGRATION_PARAMETER_MODE),
>> >>  qapi_enum_lookup(&MigMode_lookup, params->mode));
>> >> +
>> >> +if (params->has_direct_io) {
>> >> +monitor_printf(mon, "%s: %s\n",
>> >> +   MigrationParameter_str(
>> >> +   MIGRATION_PARAMETER_DIRECT_IO),
>> >> +   params->direct_io ? "on" : "off");
>> >> +}
>> >
>> > This will be the first parameter to optionally display here.  I think it's
>> > a sign of misuse of has_direct_io field..

Yes.  For similar existing parameters, we do

   assert(params->has_FOO);
   monitor_printf(mon, "%s: '%s'\n",
  MigrationParameter_str(MIGRATION_PARAMETER_FOO),
  ... params->FOO as string ...)

>> > IMHO has_direct_io should be best to be kept as "whether direct_io field is
>> > valid" and that's all of it.  It hopefully shouldn't contain more
>> > information than that, or otherwise it'll be another small challenge we
>> > need to overcome when we can remove all these has_* fields, and can also be
>> > easily overlooked.
>> 
>> I don't think I understand why we have those has_* fields. I thought my
>> usage of 'params->has_direct_io = qemu_has_direct_io()' was the correct
>> one, i.e. checking whether QEMU has any support for that parameter. Can
>> you help me out here?
>
> Here params is the pointer to "struct MigrationParameters", which is
> defined in qapi/migration.json.  And we have had "has_*" only because we
> allow optional fields with asterisks:
>
>   { 'struct': 'MigrationParameters',
> 'data': { '*announce-initial': 'size',
>   ...
>   } }
>
> So that's why it better only means "whether this field existed", because
> it's how it is defined.
>
> IIRC we (or say, Markus) used to have some attempts deduplicates those
> *MigrationParameter* things, and if success we have chance to drop has_*
> fields (in which case we simply always have them; that "has_" makes more
> sense only if in a QMP session to allow user only specify one or more
> things if not all).

qapi/migration.json:

##
# @MigrationParameters:
#
--> # The optional members aren't actually optional.
#

In other words, the has_FOO generated for the members of
MigrationParameters must all be true.

These members became optional when we attempted to de-duplicate
MigrationParameters and MigrateSetParameters, but failed (see commit
de63ab61241 "migrate: Share common MigrationParameters struct" and
commit 1bda8b3c695 "migration: Unshare MigrationParameters struct for
now").




Re: [PATCH v2 06/45] target/hppa: Use CF_BP_PAGE instead of cpu_breakpoint_test

2024-05-14 Thread Helge Deller
* Richard Henderson :
> The generic tcg driver will have already checked for breakpoints.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 140dfb747a..d272be0e6e 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -674,8 +674,9 @@ static bool use_goto_tb(DisasContext *ctx, uint64_t bofs, 
> uint64_t nofs)
> executing a TB that merely branches to the next TB.  */
>  static bool use_nullify_skip(DisasContext *ctx)
>  {
> -return (((ctx->iaoq_b ^ ctx->iaoq_f) & TARGET_PAGE_MASK) == 0
> -&& !cpu_breakpoint_test(ctx->cs, ctx->iaoq_b, BP_ANY));
> +return (!(tb_cflags(ctx->base.tb) & CF_BP_PAGE)
> +&& ctx->iaoq_b != -1
> +&& is_same_page(&ctx->base, ctx->iaoq_b));
>  }
>  
>  static void gen_goto_tb(DisasContext *ctx, int which,
> -- 
> 2.34.1
> 



Re: [PATCH v2 07/45] target/hppa: Add install_iaq_entries

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Instead of two separate cpu_iaoq_entry calls, use one call to update
> both IAQ_Front and IAQ_Back.  Simplify with an argument combination
> that automatically handles a simple increment from Front to Back.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 64 +
>  1 file changed, 33 insertions(+), 31 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index d272be0e6e..08d5e2a4bc 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -617,6 +617,23 @@ static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 
> dest,
>  }
>  }
>  
> +static void install_iaq_entries(DisasContext *ctx, uint64_t bi, TCGv_i64 bv,
> +uint64_t ni, TCGv_i64 nv)
> +{
> +copy_iaoq_entry(ctx, cpu_iaoq_f, bi, bv);
> +
> +/* Allow ni variable, with nv null, to indicate a trivial advance. */
> +if (ni != -1 || nv) {
> +copy_iaoq_entry(ctx, cpu_iaoq_b, ni, nv);
> +} else if (bi != -1) {
> +copy_iaoq_entry(ctx, cpu_iaoq_b, bi + 4, NULL);
> +} else {
> +tcg_gen_addi_i64(cpu_iaoq_b, cpu_iaoq_f, 4);
> +tcg_gen_andi_i64(cpu_iaoq_b, cpu_iaoq_b,
> + gva_offset_mask(ctx->tb_flags));
> +}
> +}
> +
>  static inline uint64_t iaoq_dest(DisasContext *ctx, int64_t disp)
>  {
>  return ctx->iaoq_f + disp + 8;
> @@ -629,8 +646,7 @@ static void gen_excp_1(int exception)
>  
>  static void gen_excp(DisasContext *ctx, int exception)
>  {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
> +install_iaq_entries(ctx, ctx->iaoq_f, cpu_iaoq_f, ctx->iaoq_b, 
> cpu_iaoq_b);
>  nullify_save(ctx);
>  gen_excp_1(exception);
>  ctx->base.is_jmp = DISAS_NORETURN;
> @@ -684,12 +700,10 @@ static void gen_goto_tb(DisasContext *ctx, int which,
>  {
>  if (use_goto_tb(ctx, b, n)) {
>  tcg_gen_goto_tb(which);
> -copy_iaoq_entry(ctx, cpu_iaoq_f, b, NULL);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, n, NULL);
> +install_iaq_entries(ctx, b, NULL, n, NULL);
>  tcg_gen_exit_tb(ctx->base.tb, which);
>  } else {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, b, cpu_iaoq_b);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, n, ctx->iaoq_n_var);
> +install_iaq_entries(ctx, b, cpu_iaoq_b, n, ctx->iaoq_n_var);
>  tcg_gen_lookup_and_goto_ptr();
>  }
>  }
> @@ -1883,9 +1897,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 dest,
>  }
>  if (is_n) {
>  if (use_nullify_skip(ctx)) {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, -1, next);
> -tcg_gen_addi_i64(next, next, 4);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
> +install_iaq_entries(ctx, -1, next, -1, NULL);
>  nullify_set(ctx, 0);
>  ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
>  return true;
> @@ -1900,14 +1912,10 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 
> dest,
>  nullify_over(ctx);
>  
>  if (is_n && use_nullify_skip(ctx)) {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, -1, dest);
> -next = tcg_temp_new_i64();
> -tcg_gen_addi_i64(next, dest, 4);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
> +install_iaq_entries(ctx, -1, dest, -1, NULL);
>  nullify_set(ctx, 0);
>  } else {
> -copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, dest);
> +install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, dest);
>  nullify_set(ctx, is_n);
>  }
>  if (link != 0) {
> @@ -1998,9 +2006,7 @@ static void do_page_zero(DisasContext *ctx)
>  tcg_gen_st_i64(cpu_gr[26], tcg_env, offsetof(CPUHPPAState, cr[27]));
>  tmp = tcg_temp_new_i64();
>  tcg_gen_ori_i64(tmp, cpu_gr[31], 3);
> -copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
> -tcg_gen_addi_i64(tmp, tmp, 4);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
> +install_iaq_entries(ctx, -1, tmp, -1, NULL);
>  ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
>  break;
>  
> @@ -2744,8 +2750,8 @@ static bool trans_or(DisasContext *ctx, arg_rrr_cf_d *a)
>  nullify_over(ctx);
>  
>  /* Advance the instruction queue.  */
> -copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
> -copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
> +install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b,
> +ctx->iaoq_n, ctx->iaoq_n_var);
>  nullify_set(ctx, 0);
>  
>  /* Tell the qemu main loop to halt until this cpu has work.  */
> @@ -3898,18 +3904,15 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  tcg_gen_mov_i64(cp

Re: [PATCH v3 2/2] vhost-user: fix lost reconnect again

2024-05-14 Thread Raphael Norwitz
Code looks good. Just a question on the error case you're trying to fix.

On Tue, May 14, 2024 at 2:12 AM Li Feng  wrote:
>
> When the vhost-user is reconnecting to the backend, and if the vhost-user 
> fails
> at the get_features in vhost_dev_init(), then the reconnect will fail
> and it will not be retriggered forever.
>
> The reason is:
> When the vhost-user fail at get_features, the vhost_dev_cleanup will be called
> immediately.
>
> vhost_dev_cleanup calls 'memset(hdev, 0, sizeof(struct vhost_dev))'.
>
> The reconnect path is:
> vhost_user_blk_event
>vhost_user_async_close(.. vhost_user_blk_disconnect ..)
>  qemu_chr_fe_set_handlers <- clear the notifier callback
>schedule vhost_user_async_close_bh
>
> The vhost->vdev is null, so the vhost_user_blk_disconnect will not be
> called, then the event fd callback will not be reinstalled.
>
> With this patch, the vhost_user_blk_disconnect will call the
> vhost_dev_cleanup() again, it's safe.
>
> In addition, the CLOSE event may occur in a scenario where connected is false.
> At this time, the event handler will be cleared. We need to ensure that the
> event handler can remain installed.

Following on from the prior patch, why would "connected" be false when
a CLOSE event happens?

>
> All vhost-user devices have this issue, including vhost-user-blk/scsi.
>
> Fixes: 71e076a07d ("hw/virtio: generalise CHR_EVENT_CLOSED handling")
>
> Signed-off-by: Li Feng 
> ---
>  hw/block/vhost-user-blk.c   |  3 ++-
>  hw/scsi/vhost-user-scsi.c   |  3 ++-
>  hw/virtio/vhost-user-base.c |  3 ++-
>  hw/virtio/vhost-user.c  | 10 +-
>  4 files changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index 41d1ac3a5a..c6842ced48 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -353,7 +353,7 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
>  VHostUserBlk *s = VHOST_USER_BLK(vdev);
>
>  if (!s->connected) {
> -return;
> +goto done;
>  }
>  s->connected = false;
>
> @@ -361,6 +361,7 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
>
>  vhost_dev_cleanup(&s->dev);
>
> +done:
>  /* Re-instate the event handler for new connections */
>  qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
>   NULL, dev, NULL, true);
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index 48a59e020e..b49a11d23b 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -181,7 +181,7 @@ static void vhost_user_scsi_disconnect(DeviceState *dev)
>  VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
>
>  if (!s->connected) {
> -return;
> +goto done;
>  }
>  s->connected = false;
>
> @@ -189,6 +189,7 @@ static void vhost_user_scsi_disconnect(DeviceState *dev)
>
>  vhost_dev_cleanup(&vsc->dev);
>
> +done:
>  /* Re-instate the event handler for new connections */
>  qemu_chr_fe_set_handlers(&vs->conf.chardev, NULL, NULL,
>   vhost_user_scsi_event, NULL, dev, NULL, true);
> diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
> index 4b54255682..11e72b1e3b 100644
> --- a/hw/virtio/vhost-user-base.c
> +++ b/hw/virtio/vhost-user-base.c
> @@ -225,13 +225,14 @@ static void vub_disconnect(DeviceState *dev)
>  VHostUserBase *vub = VHOST_USER_BASE(vdev);
>
>  if (!vub->connected) {
> -return;
> +goto done;
>  }
>  vub->connected = false;
>
>  vub_stop(vdev);
>  vhost_dev_cleanup(&vub->vhost_dev);
>
> +done:
>  /* Re-instate the event handler for new connections */
>  qemu_chr_fe_set_handlers(&vub->chardev,
>   NULL, NULL, vub_event,
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index c929097e87..c407ea8939 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -2781,16 +2781,8 @@ typedef struct {
>  static void vhost_user_async_close_bh(void *opaque)
>  {
>  VhostAsyncCallback *data = opaque;
> -struct vhost_dev *vhost = data->vhost;
>
> -/*
> - * If the vhost_dev has been cleared in the meantime there is
> - * nothing left to do as some other path has completed the
> - * cleanup.
> - */
> -if (vhost->vdev) {
> -data->cb(data->dev);
> -}
> +data->cb(data->dev);
>
>  g_free(data);
>  }
> --
> 2.45.0
>



Re: [PATCH v3 1/2] Revert "vhost-user: fix lost reconnect"

2024-05-14 Thread Raphael Norwitz
The code for these two patches looks fine. Just some questions on the
failure case you're trying to fix.


On Tue, May 14, 2024 at 2:12 AM Li Feng  wrote:
>
> This reverts commit f02a4b8e6431598612466f76aac64ab492849abf.
>
> Since the current patch cannot completely fix the lost reconnect
> problem, there is a scenario that is not considered:
> - When the virtio-blk driver is removed from the guest os,
>   s->connected has no chance to be set to false, resulting in

Why would the virtio-blk driver being removed (unloaded?) in the guest
effect s->connected? Isn't this variable just tracking whether Qemu is
connected to the backend process? What does it have to do with the
guest driver state?

>   subsequent reconnection not being executed.
>
> The next patch will completely fix this issue with a better approach.
>
> Signed-off-by: Li Feng 
> ---
>  hw/block/vhost-user-blk.c  |  2 +-
>  hw/scsi/vhost-user-scsi.c  |  3 +--
>  hw/virtio/vhost-user-base.c|  2 +-
>  hw/virtio/vhost-user.c | 10 ++
>  include/hw/virtio/vhost-user.h |  3 +--
>  5 files changed, 6 insertions(+), 14 deletions(-)
>
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index 9e6bbc6950..41d1ac3a5a 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -384,7 +384,7 @@ static void vhost_user_blk_event(void *opaque, 
> QEMUChrEvent event)
>  case CHR_EVENT_CLOSED:
>  /* defer close until later to avoid circular close */
>  vhost_user_async_close(dev, &s->chardev, &s->dev,
> -   vhost_user_blk_disconnect, 
> vhost_user_blk_event);
> +   vhost_user_blk_disconnect);
>  break;
>  case CHR_EVENT_BREAK:
>  case CHR_EVENT_MUX_IN:
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index a63b1f4948..48a59e020e 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -214,8 +214,7 @@ static void vhost_user_scsi_event(void *opaque, 
> QEMUChrEvent event)
>  case CHR_EVENT_CLOSED:
>  /* defer close until later to avoid circular close */
>  vhost_user_async_close(dev, &vs->conf.chardev, &vsc->dev,
> -   vhost_user_scsi_disconnect,
> -   vhost_user_scsi_event);
> +   vhost_user_scsi_disconnect);
>  break;
>  case CHR_EVENT_BREAK:
>  case CHR_EVENT_MUX_IN:
> diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
> index a83167191e..4b54255682 100644
> --- a/hw/virtio/vhost-user-base.c
> +++ b/hw/virtio/vhost-user-base.c
> @@ -254,7 +254,7 @@ static void vub_event(void *opaque, QEMUChrEvent event)
>  case CHR_EVENT_CLOSED:
>  /* defer close until later to avoid circular close */
>  vhost_user_async_close(dev, &vub->chardev, &vub->vhost_dev,
> -   vub_disconnect, vub_event);
> +   vub_disconnect);
>  break;
>  case CHR_EVENT_BREAK:
>  case CHR_EVENT_MUX_IN:
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index cdf9af4a4b..c929097e87 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -2776,7 +2776,6 @@ typedef struct {
>  DeviceState *dev;
>  CharBackend *cd;
>  struct vhost_dev *vhost;
> -IOEventHandler *event_cb;
>  } VhostAsyncCallback;
>
>  static void vhost_user_async_close_bh(void *opaque)
> @@ -2791,10 +2790,7 @@ static void vhost_user_async_close_bh(void *opaque)
>   */
>  if (vhost->vdev) {
>  data->cb(data->dev);
> -} else if (data->event_cb) {
> -qemu_chr_fe_set_handlers(data->cd, NULL, NULL, data->event_cb,
> - NULL, data->dev, NULL, true);
> -   }
> +}
>
>  g_free(data);
>  }
> @@ -2806,8 +2802,7 @@ static void vhost_user_async_close_bh(void *opaque)
>   */
>  void vhost_user_async_close(DeviceState *d,
>  CharBackend *chardev, struct vhost_dev *vhost,
> -vu_async_close_fn cb,
> -IOEventHandler *event_cb)
> +vu_async_close_fn cb)
>  {
>  if (!runstate_check(RUN_STATE_SHUTDOWN)) {
>  /*
> @@ -2823,7 +2818,6 @@ void vhost_user_async_close(DeviceState *d,
>  data->dev = d;
>  data->cd = chardev;
>  data->vhost = vhost;
> -data->event_cb = event_cb;
>
>  /* Disable any further notifications on the chardev */
>  qemu_chr_fe_set_handlers(chardev,
> diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
> index d7c09ffd34..324cd8663a 100644
> --- a/include/hw/virtio/vhost-user.h
> +++ b/include/hw/virtio/vhost-user.h
> @@ -108,7 +108,6 @@ typedef void (*vu_async_close_fn)(DeviceState *cb);
>
>  void vhost_user_async_close(DeviceState *d,
>  CharBackend *chardev, struct vhost_dev *vhost

Re: [PATCH v5 10/10] vfio: Extend vfio_set_migration_error() with Error* argument

2024-05-14 Thread Cédric Le Goater

On 5/14/24 13:20, Cédric Le Goater wrote:

On 5/13/24 16:26, Avihai Horon wrote:


On 06/05/2024 12:20, Cédric Le Goater wrote:

External email: Use caution opening links or attachments


vfio_set_migration_error() sets the 'return' error on the migration
stream if a migration is in progress. To improve error reporting, add
a new Error* argument to also set the Error object on the migration
stream, if a migration is progress.

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

  Changes in v5:

  - Rebased on 20c64c8a51a4 ("migration: migration_file_set_error")

  hw/vfio/common.c | 37 ++---
  1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
c3d82a9d6e434e33f361e4b96157bf912d5c3a2f..4cf3e13a8439bd1b9a032e9d4e75df676eba457b
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -147,10 +147,10 @@ bool vfio_viommu_preset(VFIODevice *vbasedev)
  return vbasedev->bcontainer->space->as != &address_space_memory;
  }

-static void vfio_set_migration_error(int err)
+static void vfio_set_migration_error(int ret, Error *err)
  {
  if (migration_is_setup_or_active()) {
-    migration_file_set_error(err, NULL);
+    migration_file_set_error(ret, err);
  }
  }

@@ -295,9 +295,10 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  iova, iova + iotlb->addr_mask);

  if (iotlb->target_as != &address_space_memory) {
-    error_report("Wrong target AS \"%s\", only system memory is allowed",
- iotlb->target_as->name ? iotlb->target_as->name : "none");
-    vfio_set_migration_error(-EINVAL);
+    error_setg(&local_err,
+   "Wrong target AS \"%s\", only system memory is allowed",
+   iotlb->target_as->name ? iotlb->target_as->name : "none");
+    vfio_set_migration_error(-EINVAL, local_err);
  return;
  }

@@ -330,11 +331,12 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
  ret = vfio_container_dma_unmap(bcontainer, iova,
 iotlb->addr_mask + 1, iotlb);
  if (ret) {
-    error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
- "0x%"HWADDR_PRIx") = %d (%s)",
- bcontainer, iova,
- iotlb->addr_mask + 1, ret, strerror(-ret));
-    vfio_set_migration_error(ret);
+    error_setg(&local_err,
+   "vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", "
+   "0x%"HWADDR_PRIx") = %d (%s)",
+   bcontainer, iova,
+   iotlb->addr_mask + 1, ret, strerror(-ret));


Use error_setg_errno()?


sure.




+    vfio_set_migration_error(ret, local_err);


Now dma unmap errors (and also the error before it) are not reported if they 
happen not during migration.

This makes me think, maybe vfio_set_migration_error() is redundant and can be 
replaced by migration_file_set_error()?



yes. Good suggestion. I would like to get rid of vfio_set_migration_error(),
so that's a good start.


After taking a closer look, I will drop this patch from v6 because
it needs further splitting and some rework.

Thanks,

C.






Re: [PATCH v2 08/45] target/hppa: Add install_link

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Add a common routine for writing the return address.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 54 +++--
>  1 file changed, 31 insertions(+), 23 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 08d5e2a4bc..f816b337ee 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -634,6 +634,23 @@ static void install_iaq_entries(DisasContext *ctx, 
> uint64_t bi, TCGv_i64 bv,
>  }
>  }
>  
> +static void install_link(DisasContext *ctx, unsigned link, bool with_sr0)
> +{
> +tcg_debug_assert(ctx->null_cond.c == TCG_COND_NEVER);
> +if (link) {

Just wondering:
Doesn't it makes it easier to write here:
if (!link) {
return;
}
and then don't indent the few following lines?

> +if (ctx->iaoq_b == -1) {
> +tcg_gen_addi_i64(cpu_gr[link], cpu_iaoq_b, 4);
> +} else {
> +tcg_gen_movi_i64(cpu_gr[link], ctx->iaoq_b + 4);
> +}
> +#ifndef CONFIG_USER_ONLY
> +if (with_sr0) {
> +tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
> +}
> +#endif
> +}
> +}
> +
>  static inline uint64_t iaoq_dest(DisasContext *ctx, int64_t disp)
>  {
>  return ctx->iaoq_f + disp + 8;
> @@ -1787,9 +1804,7 @@ static bool do_dbranch(DisasContext *ctx, int64_t disp,
>  uint64_t dest = iaoq_dest(ctx, disp);
>  
>  if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
> -if (link != 0) {
> -copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
> +install_link(ctx, link, false);
>  ctx->iaoq_n = dest;
>  if (is_n) {
>  ctx->null_cond.c = TCG_COND_ALWAYS;
> @@ -1797,10 +1812,7 @@ static bool do_dbranch(DisasContext *ctx, int64_t disp,
>  } else {
>  nullify_over(ctx);
>  
> -if (link != 0) {
> -copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
> -
> +install_link(ctx, link, false);
>  if (is_n && use_nullify_skip(ctx)) {
>  nullify_set(ctx, 0);
>  gen_goto_tb(ctx, 0, dest, dest + 4);
> @@ -1892,9 +1904,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 dest,
>  next = tcg_temp_new_i64();
>  tcg_gen_mov_i64(next, dest);
>  
> -if (link != 0) {
> -copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
> +install_link(ctx, link, false);
>  if (is_n) {
>  if (use_nullify_skip(ctx)) {
>  install_iaq_entries(ctx, -1, next, -1, NULL);
> @@ -1911,16 +1921,17 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 
> dest,
>  
>  nullify_over(ctx);
>  
> +next = tcg_temp_new_i64();
> +tcg_gen_mov_i64(next, dest);
> +
> +install_link(ctx, link, false);
>  if (is_n && use_nullify_skip(ctx)) {
> -install_iaq_entries(ctx, -1, dest, -1, NULL);
> +install_iaq_entries(ctx, -1, next, -1, NULL);
>  nullify_set(ctx, 0);
>  } else {
> -install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, dest);
> +install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, next);
>  nullify_set(ctx, is_n);
>  }
> -if (link != 0) {
> -copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
>  
>  tcg_gen_lookup_and_goto_ptr();
>  ctx->base.is_jmp = DISAS_NORETURN;
> @@ -3899,10 +3910,7 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  nullify_over(ctx);
>  
>  load_spr(ctx, new_spc, a->sp);
> -if (a->l) {
> -copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
> -tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
> -}
> +install_link(ctx, a->l, true);
>  if (a->n && use_nullify_skip(ctx)) {
>  install_iaq_entries(ctx, -1, tmp, -1, NULL);
>  tcg_gen_mov_i64(cpu_iasq_f, new_spc);
> @@ -4019,16 +4027,16 @@ static bool trans_bve(DisasContext *ctx, arg_bve *a)
>  return do_ibranch(ctx, dest, a->l, a->n);
>  #else
>  nullify_over(ctx);
> -dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
> +dest = tcg_temp_new_i64();
> +tcg_gen_mov_i64(dest, load_gpr(ctx, a->b));
> +dest = do_ibranch_priv(ctx, dest);
>  
> +install_link(ctx, a->l, false);
>  install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, dest);
>  if (ctx->iaoq_b == -1) {
>  tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
>  }
>  tcg_gen_mov_i64(cpu_iasq_b, space_select(ctx, 0, dest));
> -if (a->l) {
> -copy_iaoq_entry(ctx, cpu_gr[a->l], ctx->iaoq_n, ctx->iaoq_n_var);
> -}
>  nullify_set(ctx, a->n);
>  tcg_gen_lookup_and_goto_ptr();
>  ctx->base.is_jmp = DISAS_NORETURN;
> -- 
> 2.34.1
> 



Re: [PATCH v2 09/45] target/hppa: Delay computation of IAQ_Next

2024-05-14 Thread Helge Deller
* Richard Henderson :
> We no longer have to allocate a temp and perform an
> addition before translation of the rest of the insn.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 26 ++
>  1 file changed, 10 insertions(+), 16 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index f816b337ee..a9196050dc 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -1806,6 +1806,7 @@ static bool do_dbranch(DisasContext *ctx, int64_t disp,
>  if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
>  install_link(ctx, link, false);
>  ctx->iaoq_n = dest;
> +ctx->iaoq_n_var = NULL;
>  if (is_n) {
>  ctx->null_cond.c = TCG_COND_ALWAYS;
>  }
> @@ -1862,11 +1863,6 @@ static bool do_cbranch(DisasContext *ctx, int64_t 
> disp, bool is_n,
>  ctx->null_lab = NULL;
>  }
>  nullify_set(ctx, n);
> -if (ctx->iaoq_n == -1) {
> -/* The temporary iaoq_n_var died at the branch above.
> -   Regenerate it here instead of saving it.  */
> -tcg_gen_addi_i64(ctx->iaoq_n_var, cpu_iaoq_b, 4);
> -}
>  gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
>  }
>  
> @@ -4630,8 +4626,6 @@ static void hppa_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  ctx->iaoq_f = (ctx->base.pc_first & ~iasq_f) + ctx->privilege;
>  ctx->iaoq_b = (diff ? ctx->iaoq_f + diff : -1);
>  #endif
> -ctx->iaoq_n = -1;
> -ctx->iaoq_n_var = NULL;
>  
>  ctx->zero = tcg_constant_i64(0);
>  
> @@ -4683,14 +4677,8 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  
>  /* Set up the IA queue for the next insn.
> This will be overwritten by a branch.  */
> -if (ctx->iaoq_b == -1) {
> -ctx->iaoq_n = -1;
> -ctx->iaoq_n_var = tcg_temp_new_i64();
> -tcg_gen_addi_i64(ctx->iaoq_n_var, cpu_iaoq_b, 4);
> -} else {
> -ctx->iaoq_n = ctx->iaoq_b + 4;
> -ctx->iaoq_n_var = NULL;
> -}
> +ctx->iaoq_n_var = NULL;
> +ctx->iaoq_n = ctx->iaoq_b == -1 ? -1 : ctx->iaoq_b + 4;
>  
>  if (unlikely(ctx->null_cond.c == TCG_COND_ALWAYS)) {
>  ctx->null_cond.c = TCG_COND_NEVER;
> @@ -4741,7 +4729,13 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  ? DISAS_EXIT
>  : DISAS_IAQ_N_UPDATED);
>  } else if (ctx->iaoq_b == -1) {
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
> +if (ctx->iaoq_n_var) {
> +copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
> +} else {
> +tcg_gen_addi_i64(cpu_iaoq_b, cpu_iaoq_b, 4);
> +tcg_gen_andi_i64(cpu_iaoq_b, cpu_iaoq_b,
> + gva_offset_mask(ctx->tb_flags));
> +}
>  }
>  break;
>  
> -- 
> 2.34.1
> 



Re: [PATCH v2 10/45] target/hppa: Skip nullified insns in unconditional dbranch path

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index a9196050dc..ca979f4137 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -1805,11 +1805,17 @@ static bool do_dbranch(DisasContext *ctx, int64_t 
> disp,
>  
>  if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
>  install_link(ctx, link, false);
> -ctx->iaoq_n = dest;
> -ctx->iaoq_n_var = NULL;
>  if (is_n) {
> +if (use_nullify_skip(ctx)) {
> +nullify_set(ctx, 0);
> +gen_goto_tb(ctx, 0, dest, dest + 4);
> +ctx->base.is_jmp = DISAS_NORETURN;
> +return true;
> +}
>  ctx->null_cond.c = TCG_COND_ALWAYS;
>  }
> +ctx->iaoq_n = dest;
> +ctx->iaoq_n_var = NULL;
>  } else {
>  nullify_over(ctx);
>  
> -- 
> 2.34.1
> 



Re: [PATCH v2 11/45] target/hppa: Simplify TB end

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Minimize the amount of code in hppa_tr_translate_insn advancing the
> insn queue for the next insn.  Move the goto_tb path to hppa_tr_tb_stop.
> 
> Signed-off-by: Richard Henderson 

Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 109 +---
>  1 file changed, 57 insertions(+), 52 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index ca979f4137..13a48d1b6c 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -4699,54 +4699,31 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  }
>  }
>  
> -/* Advance the insn queue.  Note that this check also detects
> -   a priority change within the instruction queue.  */
> -if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
> -if (use_goto_tb(ctx, ctx->iaoq_b, ctx->iaoq_n)
> -&& (ctx->null_cond.c == TCG_COND_NEVER
> -|| ctx->null_cond.c == TCG_COND_ALWAYS)) {
> -nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
> -gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
> -ctx->base.is_jmp = ret = DISAS_NORETURN;
> -} else {
> -ctx->base.is_jmp = ret = DISAS_IAQ_N_STALE;
> -}
> +/* If the TranslationBlock must end, do so. */
> +ctx->base.pc_next += 4;
> +if (ret != DISAS_NEXT) {
> +return;
>  }
> +/* Note this also detects a priority change. */
> +if (ctx->iaoq_b != ctx->iaoq_f + 4) {
> +ctx->base.is_jmp = DISAS_IAQ_N_STALE;
> +return;
> +}
> +
> +/*
> + * Advance the insn queue.
> + * The only exit now is DISAS_TOO_MANY from the translator loop.
> + */
>  ctx->iaoq_f = ctx->iaoq_b;
>  ctx->iaoq_b = ctx->iaoq_n;
> -ctx->base.pc_next += 4;
> -
> -switch (ret) {
> -case DISAS_NORETURN:
> -case DISAS_IAQ_N_UPDATED:
> -break;
> -
> -case DISAS_NEXT:
> -case DISAS_IAQ_N_STALE:
> -case DISAS_IAQ_N_STALE_EXIT:
> -if (ctx->iaoq_f == -1) {
> -install_iaq_entries(ctx, -1, cpu_iaoq_b,
> -ctx->iaoq_n, ctx->iaoq_n_var);
> -#ifndef CONFIG_USER_ONLY
> -tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
> -#endif
> -nullify_save(ctx);
> -ctx->base.is_jmp = (ret == DISAS_IAQ_N_STALE_EXIT
> -? DISAS_EXIT
> -: DISAS_IAQ_N_UPDATED);
> -} else if (ctx->iaoq_b == -1) {
> -if (ctx->iaoq_n_var) {
> -copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
> -} else {
> -tcg_gen_addi_i64(cpu_iaoq_b, cpu_iaoq_b, 4);
> -tcg_gen_andi_i64(cpu_iaoq_b, cpu_iaoq_b,
> - gva_offset_mask(ctx->tb_flags));
> -}
> +if (ctx->iaoq_b == -1) {
> +if (ctx->iaoq_n_var) {
> +copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
> +} else {
> +tcg_gen_addi_i64(cpu_iaoq_b, cpu_iaoq_b, 4);
> +tcg_gen_andi_i64(cpu_iaoq_b, cpu_iaoq_b,
> + gva_offset_mask(ctx->tb_flags));
>  }
> -break;
> -
> -default:
> -g_assert_not_reached();
>  }
>  }
>  
> @@ -4754,23 +4731,51 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cs)
>  {
>  DisasContext *ctx = container_of(dcbase, DisasContext, base);
>  DisasJumpType is_jmp = ctx->base.is_jmp;
> +uint64_t fi, bi;
> +TCGv_i64 fv, bv;
> +TCGv_i64 fs;
> +
> +/* Assume the insn queue has not been advanced. */
> +fi = ctx->iaoq_b;
> +fv = cpu_iaoq_b;
> +fs = fi == -1 ? cpu_iasq_b : NULL;
> +bi = ctx->iaoq_n;
> +bv = ctx->iaoq_n_var;
>  
>  switch (is_jmp) {
>  case DISAS_NORETURN:
>  break;
>  case DISAS_TOO_MANY:
> -case DISAS_IAQ_N_STALE:
> -case DISAS_IAQ_N_STALE_EXIT:
> -install_iaq_entries(ctx, ctx->iaoq_f, cpu_iaoq_f,
> -ctx->iaoq_b, cpu_iaoq_b);
> -nullify_save(ctx);
> +/* The insn queue has not been advanced. */
> +bi = fi;
> +bv = fv;
> +fi = ctx->iaoq_f;
> +fv = NULL;
> +fs = NULL;
>  /* FALLTHRU */
> -case DISAS_IAQ_N_UPDATED:
> -if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
> -tcg_gen_lookup_and_goto_ptr();
> +case DISAS_IAQ_N_STALE:
> +if (use_goto_tb(ctx, fi, bi)
> +&& (ctx->null_cond.c == TCG_COND_NEVER
> +|| ctx->null_cond.c == TCG_COND_ALWAYS)) {
> +nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
> +gen_goto_tb(ctx, 0, fi, bi);
>  break;
>  }
>  /* FALLTHRU */
> +case DISAS_IAQ_N_STALE_EXIT:
> +install_iaq_entries(ctx, fi, fv, bi, bv);
> +if (fs) {
> +tcg_gen_mov_i64(c

Re: [PATCH-for-9.1 v2 2/3] migration: Remove RDMA protocol handling

2024-05-14 Thread Yu Zhang
Hello Peter and all,

I did a comparison of the VM live-migration speeds between RDMA and
TCP/IP on our servers
and plotted the results to get an initial impression. Unfortunately,
the Ethernet NICs are not the
recent ones, therefore, it may not make much sense. I can do it on
servers with more recent Ethernet
NICs and keep you updated.

It seems that the benefits of RDMA becomes obviously when the VM has
large memory and is
running memory-intensive workload.

Best regards,
Yu Zhang @ IONOS Cloud

On Thu, May 9, 2024 at 4:14 PM Peter Xu  wrote:
>
> On Thu, May 09, 2024 at 04:58:34PM +0800, Zheng Chuan via wrote:
> > That's a good news to see the socket abstraction for RDMA!
> > When I was developed the series above, the most pain is the RDMA migration 
> > has no QIOChannel abstraction and i need to take a 'fake channel'
> > for it which is awkward in code implementation.
> > So, as far as I know, we can do this by
> > i. the first thing is that we need to evaluate the rsocket is good enough 
> > to satisfy our QIOChannel fundamental abstraction
> > ii. if it works right, then we will continue to see if it can give us 
> > opportunity to hide the detail of rdma protocol
> > into rsocket by remove most of code in rdma.c and also some hack in 
> > migration main process.
> > iii. implement the advanced features like multi-fd and multi-uri for rdma 
> > migration.
> >
> > Since I am not familiar with rsocket, I need some times to look at it and 
> > do some quick verify with rdma migration based on rsocket.
> > But, yes, I am willing to involved in this refactor work and to see if we 
> > can make this migration feature more better:)
>
> Based on what we have now, it looks like we'd better halt the deprecation
> process a bit, so I think we shouldn't need to rush it at least in 9.1
> then, and we'll need to see how it goes on the refactoring.
>
> It'll be perfect if rsocket works, otherwise supporting multifd with little
> overhead / exported APIs would also be a good thing in general with
> whatever approach.  And obviously all based on the facts that we can get
> resources from companies to support this feature first.
>
> Note that so far nobody yet compared with rdma v.s. nic perf, so I hope if
> any of us can provide some test results please do so.  Many people are
> saying RDMA is better, but I yet didn't see any numbers comparing it with
> modern TCP networks.  I don't want to have old impressions floating around
> even if things might have changed..  When we have consolidated results, we
> should share them out and also reflect that in QEMU's migration docs when a
> rdma document page is ready.
>
> Chuan, please check the whole thread discussion, it may help to understand
> what we are looking for on rdma migrations [1].  Meanwhile please feel free
> to sync with Jinpu's team and see how to move forward with such a project.
>
> [1] https://lore.kernel.org/qemu-devel/87frwatp7n@suse.de/
>
> Thanks,
>
> --
> Peter Xu
>


Re: [PATCH v2 12/45] target/hppa: Add IASQ entries to DisasContext

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Add variable to track space changes to IAQ.  So far, no such changes
> are introduced, but the new checks vs ctx->iasq_b may eliminate an
> unnecessary copy to cpu_iasq_f with e.g. BLR.
> 
> Signed-off-by: Richard Henderson 


Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 39 ++-
>  1 file changed, 30 insertions(+), 9 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index 13a48d1b6c..d24220c60f 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -50,6 +50,13 @@ typedef struct DisasContext {
>  uint64_t iaoq_b;
>  uint64_t iaoq_n;
>  TCGv_i64 iaoq_n_var;
> +/*
> + * Null when IASQ_Back unchanged from IASQ_Front,
> + * or cpu_iasq_b, when IASQ_Back has been changed.
> + */
> +TCGv_i64 iasq_b;
> +/* Null when IASQ_Next unchanged from IASQ_Back, or set by branch. */
> +TCGv_i64 iasq_n;
>  
>  DisasCond null_cond;
>  TCGLabel *null_lab;
> @@ -3916,12 +3923,12 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  if (a->n && use_nullify_skip(ctx)) {
>  install_iaq_entries(ctx, -1, tmp, -1, NULL);
>  tcg_gen_mov_i64(cpu_iasq_f, new_spc);
> -tcg_gen_mov_i64(cpu_iasq_b, cpu_iasq_f);
> +tcg_gen_mov_i64(cpu_iasq_b, new_spc);
>  nullify_set(ctx, 0);
>  } else {
>  install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, tmp);
> -if (ctx->iaoq_b == -1) {
> -tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
> +if (ctx->iasq_b) {
> +tcg_gen_mov_i64(cpu_iasq_f, ctx->iasq_b);
>  }
>  tcg_gen_mov_i64(cpu_iasq_b, new_spc);
>  nullify_set(ctx, a->n);
> @@ -4035,8 +4042,8 @@ static bool trans_bve(DisasContext *ctx, arg_bve *a)
>  
>  install_link(ctx, a->l, false);
>  install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, dest);
> -if (ctx->iaoq_b == -1) {
> -tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
> +if (ctx->iasq_b) {
> +tcg_gen_mov_i64(cpu_iasq_f, ctx->iasq_b);
>  }
>  tcg_gen_mov_i64(cpu_iasq_b, space_select(ctx, 0, dest));
>  nullify_set(ctx, a->n);
> @@ -4617,6 +4624,7 @@ static void hppa_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  ctx->mmu_idx = MMU_USER_IDX;
>  ctx->iaoq_f = ctx->base.pc_first | ctx->privilege;
>  ctx->iaoq_b = ctx->base.tb->cs_base | ctx->privilege;
> +ctx->iasq_b = NULL;
>  ctx->unalign = (ctx->tb_flags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
>  #else
>  ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
> @@ -4631,6 +4639,7 @@ static void hppa_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  
>  ctx->iaoq_f = (ctx->base.pc_first & ~iasq_f) + ctx->privilege;
>  ctx->iaoq_b = (diff ? ctx->iaoq_f + diff : -1);
> +ctx->iasq_b = (diff ? NULL : cpu_iasq_b);
>  #endif
>  
>  ctx->zero = tcg_constant_i64(0);
> @@ -4683,6 +4692,7 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  
>  /* Set up the IA queue for the next insn.
> This will be overwritten by a branch.  */
> +ctx->iasq_n = NULL;
>  ctx->iaoq_n_var = NULL;
>  ctx->iaoq_n = ctx->iaoq_b == -1 ? -1 : ctx->iaoq_b + 4;
>  
> @@ -4705,7 +4715,7 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>  return;
>  }
>  /* Note this also detects a priority change. */
> -if (ctx->iaoq_b != ctx->iaoq_f + 4) {
> +if (ctx->iaoq_b != ctx->iaoq_f + 4 || ctx->iasq_b) {
>  ctx->base.is_jmp = DISAS_IAQ_N_STALE;
>  return;
>  }
> @@ -4725,6 +4735,10 @@ static void hppa_tr_translate_insn(DisasContextBase 
> *dcbase, CPUState *cs)
>   gva_offset_mask(ctx->tb_flags));
>  }
>  }
> +if (ctx->iasq_n) {
> +tcg_gen_mov_i64(cpu_iasq_b, ctx->iasq_n);
> +ctx->iasq_b = cpu_iasq_b;
> +}
>  }
>  
>  static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
> @@ -4733,14 +4747,15 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cs)
>  DisasJumpType is_jmp = ctx->base.is_jmp;
>  uint64_t fi, bi;
>  TCGv_i64 fv, bv;
> -TCGv_i64 fs;
> +TCGv_i64 fs, bs;
>  
>  /* Assume the insn queue has not been advanced. */
>  fi = ctx->iaoq_b;
>  fv = cpu_iaoq_b;
> -fs = fi == -1 ? cpu_iasq_b : NULL;
> +fs = ctx->iasq_b;
>  bi = ctx->iaoq_n;
>  bv = ctx->iaoq_n_var;
> +bs = ctx->iasq_n;
>  
>  switch (is_jmp) {
>  case DISAS_NORETURN:
> @@ -4749,12 +4764,15 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, 
> CPUState *cs)
>  /* The insn queue has not been advanced. */
>  bi = fi;
>  bv = fv;
> +bs = fs;
>  fi = ctx->iaoq_f;
>  fv = NULL;
>  fs = NULL;
>  /* FALLTHRU */
>  case DISAS_IAQ_N_STALE:
> - 

Re: [PATCH v2 13/45] target/hppa: Add space arguments to install_iaq_entries

2024-05-14 Thread Helge Deller
* Richard Henderson :
> Move space assighments to a central location.
> 
> Signed-off-by: Richard Henderson 


Reviewed-by: Helge Deller 

> ---
>  target/hppa/translate.c | 58 +++--
>  1 file changed, 27 insertions(+), 31 deletions(-)
> 
> diff --git a/target/hppa/translate.c b/target/hppa/translate.c
> index d24220c60f..05383dcd04 100644
> --- a/target/hppa/translate.c
> +++ b/target/hppa/translate.c
> @@ -624,8 +624,9 @@ static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 
> dest,
>  }
>  }
>  
> -static void install_iaq_entries(DisasContext *ctx, uint64_t bi, TCGv_i64 bv,
> -uint64_t ni, TCGv_i64 nv)
> +static void install_iaq_entries(DisasContext *ctx,
> +uint64_t bi, TCGv_i64 bv, TCGv_i64 bs,
> +uint64_t ni, TCGv_i64 nv, TCGv_i64 ns)
>  {
>  copy_iaoq_entry(ctx, cpu_iaoq_f, bi, bv);
>  
> @@ -639,6 +640,12 @@ static void install_iaq_entries(DisasContext *ctx, 
> uint64_t bi, TCGv_i64 bv,
>  tcg_gen_andi_i64(cpu_iaoq_b, cpu_iaoq_b,
>   gva_offset_mask(ctx->tb_flags));
>  }
> +if (bs) {
> +tcg_gen_mov_i64(cpu_iasq_f, bs);
> +}
> +if (ns || bs) {
> +tcg_gen_mov_i64(cpu_iasq_b, ns ? ns : bs);
> +}
>  }
>  
>  static void install_link(DisasContext *ctx, unsigned link, bool with_sr0)
> @@ -670,7 +677,8 @@ static void gen_excp_1(int exception)
>  
>  static void gen_excp(DisasContext *ctx, int exception)
>  {
> -install_iaq_entries(ctx, ctx->iaoq_f, cpu_iaoq_f, ctx->iaoq_b, 
> cpu_iaoq_b);
> +install_iaq_entries(ctx, ctx->iaoq_f, cpu_iaoq_f, NULL,
> +ctx->iaoq_b, cpu_iaoq_b, NULL);
>  nullify_save(ctx);
>  gen_excp_1(exception);
>  ctx->base.is_jmp = DISAS_NORETURN;
> @@ -724,10 +732,11 @@ static void gen_goto_tb(DisasContext *ctx, int which,
>  {
>  if (use_goto_tb(ctx, b, n)) {
>  tcg_gen_goto_tb(which);
> -install_iaq_entries(ctx, b, NULL, n, NULL);
> +install_iaq_entries(ctx, b, NULL, NULL, n, NULL, NULL);
>  tcg_gen_exit_tb(ctx->base.tb, which);
>  } else {
> -install_iaq_entries(ctx, b, cpu_iaoq_b, n, ctx->iaoq_n_var);
> +install_iaq_entries(ctx, b, cpu_iaoq_b, ctx->iasq_b,
> +n, ctx->iaoq_n_var, ctx->iasq_n);
>  tcg_gen_lookup_and_goto_ptr();
>  }
>  }
> @@ -1916,7 +1925,7 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 dest,
>  install_link(ctx, link, false);
>  if (is_n) {
>  if (use_nullify_skip(ctx)) {
> -install_iaq_entries(ctx, -1, next, -1, NULL);
> +install_iaq_entries(ctx, -1, next, NULL, -1, NULL, NULL);
>  nullify_set(ctx, 0);
>  ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
>  return true;
> @@ -1935,10 +1944,11 @@ static bool do_ibranch(DisasContext *ctx, TCGv_i64 
> dest,
>  
>  install_link(ctx, link, false);
>  if (is_n && use_nullify_skip(ctx)) {
> -install_iaq_entries(ctx, -1, next, -1, NULL);
> +install_iaq_entries(ctx, -1, next, NULL, -1, NULL, NULL);
>  nullify_set(ctx, 0);
>  } else {
> -install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, -1, next);
> +install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, ctx->iasq_b,
> +-1, next, NULL);
>  nullify_set(ctx, is_n);
>  }
>  
> @@ -2026,7 +2036,7 @@ static void do_page_zero(DisasContext *ctx)
>  tcg_gen_st_i64(cpu_gr[26], tcg_env, offsetof(CPUHPPAState, cr[27]));
>  tmp = tcg_temp_new_i64();
>  tcg_gen_ori_i64(tmp, cpu_gr[31], 3);
> -install_iaq_entries(ctx, -1, tmp, -1, NULL);
> +install_iaq_entries(ctx, -1, tmp, NULL, -1, NULL, NULL);
>  ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
>  break;
>  
> @@ -2770,8 +2780,8 @@ static bool trans_or(DisasContext *ctx, arg_rrr_cf_d *a)
>  nullify_over(ctx);
>  
>  /* Advance the instruction queue.  */
> -install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b,
> -ctx->iaoq_n, ctx->iaoq_n_var);
> +install_iaq_entries(ctx, ctx->iaoq_b, cpu_iaoq_b, ctx->iasq_b,
> +ctx->iaoq_n, ctx->iaoq_n_var, ctx->iasq_n);
>  nullify_set(ctx, 0);
>  
>  /* Tell the qemu main loop to halt until this cpu has work.  */
> @@ -3921,16 +3931,11 @@ static bool trans_be(DisasContext *ctx, arg_be *a)
>  load_spr(ctx, new_spc, a->sp);
>  install_link(ctx, a->l, true);
>  if (a->n && use_nullify_skip(ctx)) {
> -install_iaq_entries(ctx, -1, tmp, -1, NULL);
> -tcg_gen_mov_i64(cpu_iasq_f, new_spc);
> -tcg_gen_mov_i64(cpu_iasq_b, new_spc);
> +install_iaq_entries(ctx, -1, tmp, new_spc, -1, NULL, new_spc);
>  nullify_set(ctx, 0);
>  } else {
> -instal

[PATCH v6 1/9] vfio: Add Error** argument to .set_dirty_page_tracking() handler

2024-05-14 Thread Cédric Le Goater
We will use the Error object to improve error reporting in the
.log_global*() handlers of VFIO. Add documentation while at it.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---
 Changes in v5:

 - Fixed typo in set_dirty_page_tracking documentation
 
 include/hw/vfio/vfio-container-base.h | 18 --
 hw/vfio/common.c  |  4 ++--
 hw/vfio/container-base.c  |  4 ++--
 hw/vfio/container.c   |  6 +++---
 4 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
3582d5f97a37877b2adfc0d0b06996c82403f8b7..326ceea52a2030eec9dad289a9845866c4a8c090
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -82,7 +82,7 @@ int vfio_container_add_section_window(VFIOContainerBase 
*bcontainer,
 void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);
 int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
   VFIOBitmap *vbmap,
   hwaddr iova, hwaddr size);
@@ -121,9 +121,23 @@ struct VFIOIOMMUClass {
 int (*attach_device)(const char *name, VFIODevice *vbasedev,
  AddressSpace *as, Error **errp);
 void (*detach_device)(VFIODevice *vbasedev);
+
 /* migration feature */
+
+/**
+ * @set_dirty_page_tracking
+ *
+ * Start or stop dirty pages tracking on VFIO container
+ *
+ * @bcontainer: #VFIOContainerBase on which to de/activate dirty
+ *  page tracking
+ * @start: indicates whether to start or stop dirty pages tracking
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns zero to indicate success and negative for error
+ */
 int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
-   bool start);
+   bool start, Error **errp);
 int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer,
   VFIOBitmap *vbmap,
   hwaddr iova, hwaddr size);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
8f9cbdc0264044ce587877a7d19d14b28527291b..485e53916491f1164d29e739fb7106c0c77df737
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1076,7 +1076,7 @@ static bool vfio_listener_log_global_start(MemoryListener 
*listener,
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
 ret = vfio_devices_dma_logging_start(bcontainer);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, true);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, true, NULL);
 }
 
 if (ret) {
@@ -1096,7 +1096,7 @@ static void vfio_listener_log_global_stop(MemoryListener 
*listener)
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
 vfio_devices_dma_logging_stop(bcontainer);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, false);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, false, NULL);
 }
 
 if (ret) {
diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 
913ae49077c4f09b7b27517c1231cfbe4befb7fb..7c0764121d24b02b6c4e66e368d7dff78a6d65aa
 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -53,14 +53,14 @@ void vfio_container_del_section_window(VFIOContainerBase 
*bcontainer,
 }
 
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
-   bool start)
+   bool start, Error **errp)
 {
 if (!bcontainer->dirty_pages_supported) {
 return 0;
 }
 
 g_assert(bcontainer->ops->set_dirty_page_tracking);
-return bcontainer->ops->set_dirty_page_tracking(bcontainer, start);
+return bcontainer->ops->set_dirty_page_tracking(bcontainer, start, errp);
 }
 
 int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
77bdec276ec49cb9cd767c0de42ec801b4421572..c35221fbe7dc5453050f97cd186fc958e24f28f7
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -209,7 +209,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase 
*bcontainer, hwaddr iova,
 
 static int
 vfio_legacy_set_dirty_page_tracking(const VFIOContainerBase *bcontainer,
-bool start)
+bool start, Error **errp)
 {
 const VFIOContainer *container = container_of(bcontainer, VFI

  1   2   >