Re: [PATCH 6/7] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-23 Thread Cédric Le Goater

On 5/22/24 19:01, Cédric Le Goater wrote:

From: Zhenzhong Duan 

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a file 
handle")
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/ccw.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
a468fa2342b97e0ee36bd5fb8443025cc90a0453..36f2677a448c5e31523dcc3de7d973ec70e4a13c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  }
  
  if (!vfio_device_get_name(vbasedev, errp)) {

-return;
+goto out_unrealize;
  }
  
  if (!vfio_attach_device(cdev->mdevid, vbasedev,

@@ -631,6 +631,7 @@ out_region_err:
  vfio_detach_device(vbasedev);
  out_attach_dev_err:
  g_free(vbasedev->name);
+out_unrealize:
  if (cdc->unrealize) {
  cdc->unrealize(cdev);
  }





[PATCH 3/7] hw/s390x/ccw: Remove local Error variable from s390_ccw_realize()

2024-05-22 Thread Cédric Le Goater
Use the 'Error **errp' argument of s390_ccw_realize() instead and
remove the error_propagate() call.

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/s390-ccw.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
4b8ede701df90949720262b6fc1b65f4e505e34d..b3d14c61d732880a651edcf28a040ca723cb9f5b
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -115,13 +115,12 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 DeviceState *parent = DEVICE(ccw_dev);
 SubchDev *sch;
 int ret;
-Error *err = NULL;
 
-if (!s390_ccw_get_dev_info(cdev, sysfsdev, )) {
-goto out_err_propagate;
+if (!s390_ccw_get_dev_info(cdev, sysfsdev, errp)) {
+return;
 }
 
-sch = css_create_sch(ccw_dev->devno, );
+sch = css_create_sch(ccw_dev->devno, errp);
 if (!sch) {
 goto out_mdevid_free;
 }
@@ -132,12 +131,12 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 ccw_dev->sch = sch;
 ret = css_sch_build_schib(sch, >hostid);
 if (ret) {
-error_setg_errno(, -ret, "%s: Failed to build initial schib",
+error_setg_errno(errp, -ret, "%s: Failed to build initial schib",
  __func__);
 goto out_err;
 }
 
-if (!ck->realize(ccw_dev, )) {
+if (!ck->realize(ccw_dev, errp)) {
 goto out_err;
 }
 
@@ -151,8 +150,6 @@ out_err:
 g_free(sch);
 out_mdevid_free:
 g_free(cdev->mdevid);
-out_err_propagate:
-error_propagate(errp, err);
 }
 
 static void s390_ccw_unrealize(S390CCWDevice *cdev)
-- 
2.45.1




[PATCH 6/7] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a file 
handle")
Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/ccw.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
a468fa2342b97e0ee36bd5fb8443025cc90a0453..36f2677a448c5e31523dcc3de7d973ec70e4a13c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 }
 
 if (!vfio_device_get_name(vbasedev, errp)) {
-return;
+goto out_unrealize;
 }
 
 if (!vfio_attach_device(cdev->mdevid, vbasedev,
@@ -631,6 +631,7 @@ out_region_err:
 vfio_detach_device(vbasedev);
 out_attach_dev_err:
 g_free(vbasedev->name);
+out_unrealize:
 if (cdc->unrealize) {
 cdc->unrealize(cdev);
 }
-- 
2.45.1




[PATCH 7/7] vfio/{ap, ccw}: Use warn_report_err() for IRQ notifier registration errors

2024-05-22 Thread Cédric Le Goater
vfio_ccw_register_irq_notifier() and vfio_ap_register_irq_notifier()
errors are currently reported using error_report_err(). Since they are
not considered as failing conditions, using warn_report_err() is more
appropriate.

Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ap.c  | 2 +-
 hw/vfio/ccw.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
c12531a7886a2fe87598be0861fba5923bd2c206..0c4354e3e70169ec072e16da0919936647d1d351
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -172,7 +172,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
  */
-error_report_err(err);
+warn_report_err(err);
 }
 
 return;
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
36f2677a448c5e31523dcc3de7d973ec70e4a13c..1f8e1272c7555cd0a770481d1ae92988f6e2e62e
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -616,7 +616,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
  */
-error_report_err(err);
+warn_report_err(err);
 }
 
 return;
-- 
2.45.1




[PATCH 4/7] s390x/css: Make S390CCWDeviceClass::realize return bool

2024-05-22 Thread Cédric Le Goater
Since the realize() handler of S390CCWDeviceClass takes an 'Error **'
argument, best practices suggest to return a bool. See the api/error.h
Rules section. While at it, modify the call in vfio_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 include/hw/s390x/s390-ccw.h | 2 +-
 hw/s390x/s390-ccw.c | 7 ---
 hw/vfio/ccw.c   | 3 +--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/hw/s390x/s390-ccw.h b/include/hw/s390x/s390-ccw.h
index 
2c807ee3a1ae8d85460fe65be8a62c64f212fe4b..2e0a70998132070996d6b0d083b8ddba5b9b87dc
 100644
--- a/include/hw/s390x/s390-ccw.h
+++ b/include/hw/s390x/s390-ccw.h
@@ -31,7 +31,7 @@ struct S390CCWDevice {
 
 struct S390CCWDeviceClass {
 CCWDeviceClass parent_class;
-void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
+bool (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
 void (*unrealize)(S390CCWDevice *dev);
 IOInstEnding (*handle_request) (SubchDev *sch);
 int (*handle_halt) (SubchDev *sch);
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
b3d14c61d732880a651edcf28a040ca723cb9f5b..3c0975055089c3629dd76ce2e1484a4ef66d8d41
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -108,7 +108,7 @@ static bool s390_ccw_get_dev_info(S390CCWDevice *cdev,
 return true;
 }
 
-static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
+static bool s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
 {
 CcwDevice *ccw_dev = CCW_DEVICE(cdev);
 CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
@@ -117,7 +117,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 int ret;
 
 if (!s390_ccw_get_dev_info(cdev, sysfsdev, errp)) {
-return;
+return false;
 }
 
 sch = css_create_sch(ccw_dev->devno, errp);
@@ -142,7 +142,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 
 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
   parent->hotplugged, 1);
-return;
+return true;
 
 out_err:
 css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
@@ -150,6 +150,7 @@ out_err:
 g_free(sch);
 out_mdevid_free:
 g_free(cdev->mdevid);
+return false;
 }
 
 static void s390_ccw_unrealize(S390CCWDevice *cdev)
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
2600e62e37238779800dc2b3a0bd315d7633017b..9a8e052711fe2f7c067c52808b2af30d0ebfee0c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -582,8 +582,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
-cdc->realize(cdev, vcdev->vdev.sysfsdev, );
-if (err) {
+if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, )) {
 goto out_err_propagate;
 }
 }
-- 
2.45.1




[PATCH 5/7] vfio/ccw: Use the 'Error **errp' argument of vfio_ccw_realize()

2024-05-22 Thread Cédric Le Goater
The local error variable is kept for vfio_ccw_register_irq_notifier()
because it is not considered as a failing condition. We will change
how error reporting is done in following changes.

Remove the error_propagate() call.

Cc: Zhenzhong Duan 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
9a8e052711fe2f7c067c52808b2af30d0ebfee0c..a468fa2342b97e0ee36bd5fb8443025cc90a0453
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -582,8 +582,8 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
-if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, )) {
-goto out_err_propagate;
+if (!cdc->realize(cdev, vcdev->vdev.sysfsdev, errp)) {
+return;
 }
 }
 
@@ -596,17 +596,17 @@ static void vfio_ccw_realize(DeviceState *dev, Error 
**errp)
 goto out_attach_dev_err;
 }
 
-if (!vfio_ccw_get_region(vcdev, )) {
+if (!vfio_ccw_get_region(vcdev, errp)) {
 goto out_region_err;
 }
 
-if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, )) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, errp)) {
 goto out_io_notifier_err;
 }
 
 if (vcdev->crw_region) {
 if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
-)) {
+errp)) {
 goto out_irq_notifier_err;
 }
 }
@@ -634,8 +634,6 @@ out_attach_dev_err:
 if (cdc->unrealize) {
 cdc->unrealize(cdev);
 }
-out_err_propagate:
-error_propagate(errp, err);
 }
 
 static void vfio_ccw_unrealize(DeviceState *dev)
-- 
2.45.1




[PATCH 0/7] s390x/ccw: Error reporting cleanups

2024-05-22 Thread Cédric Le Goater
Hello,

The first patches of this series simply apply the practices described
in the Rules section of the qapi/error.h file for routines taking an
'Error **' argument. The remaining patches are a fixup in the error
path of vfio_ccw_realize() and some error reporting adjustements.

Applies on top of this vfio PR :

  https://lore.kernel.org/qemu-devel/20240522095442.195243-1-...@redhat.com

Thanks,

C.

Cédric Le Goater (6):
  hw/s390x/ccw: Make s390_ccw_get_dev_info() return a bool
  s390x/css: Make CCWDeviceClass::realize return bool
  hw/s390x/ccw: Remove local Error variable from s390_ccw_realize()
  s390x/css: Make S390CCWDeviceClass::realize return bool
  vfio/ccw: Use the 'Error **errp' argument of vfio_ccw_realize()
  vfio/{ap,ccw}: Use warn_report_err() for IRQ notifier registration
errors

Zhenzhong Duan (1):
  vfio/ccw: Fix the missed unrealize() call in error path

 hw/s390x/ccw-device.h   |  2 +-
 include/hw/s390x/s390-ccw.h |  2 +-
 hw/s390x/ccw-device.c   |  3 ++-
 hw/s390x/s390-ccw.c | 29 +
 hw/vfio/ap.c|  2 +-
 hw/vfio/ccw.c   | 18 --
 6 files changed, 26 insertions(+), 30 deletions(-)

-- 
2.45.1




[PATCH 1/7] hw/s390x/ccw: Make s390_ccw_get_dev_info() return a bool

2024-05-22 Thread Cédric Le Goater
Since s390_ccw_get_dev_info() takes an 'Error **' argument, best
practices suggest to return a bool. See the qapi/error.h Rules
section. While at it, modify the call in s390_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/s390-ccw.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
5261e66724f1cc3157b9413b0d5fdf5289c92503..a06e91dfb318e3500324851488c56806fa46c08d
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -71,7 +71,7 @@ IOInstEnding s390_ccw_store(SubchDev *sch)
 return ret;
 }
 
-static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
+static bool s390_ccw_get_dev_info(S390CCWDevice *cdev,
   char *sysfsdev,
   Error **errp)
 {
@@ -84,12 +84,12 @@ static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
 error_setg(errp, "No host device provided");
 error_append_hint(errp,
   "Use -device vfio-ccw,sysfsdev=PATH_TO_DEVICE\n");
-return;
+return false;
 }
 
 if (!realpath(sysfsdev, dev_path)) {
 error_setg_errno(errp, errno, "Host device '%s' not found", sysfsdev);
-return;
+return false;
 }
 
 cdev->mdevid = g_path_get_basename(dev_path);
@@ -98,13 +98,14 @@ static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
 tmp = g_path_get_basename(tmp_dir);
 if (sscanf(tmp, "%2x.%1x.%4x", , , ) != 3) {
 error_setg_errno(errp, errno, "Failed to read %s", tmp);
-return;
+return false;
 }
 
 cdev->hostid.cssid = cssid;
 cdev->hostid.ssid = ssid;
 cdev->hostid.devid = devid;
 cdev->hostid.valid = true;
+return true;
 }
 
 static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
@@ -116,8 +117,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 int ret;
 Error *err = NULL;
 
-s390_ccw_get_dev_info(cdev, sysfsdev, );
-if (err) {
+if (!s390_ccw_get_dev_info(cdev, sysfsdev, )) {
 goto out_err_propagate;
 }
 
-- 
2.45.1




[PATCH 2/7] s390x/css: Make CCWDeviceClass::realize return bool

2024-05-22 Thread Cédric Le Goater
Since the realize() handler of CCWDeviceClass takes an 'Error **'
argument, best practices suggest to return a bool. See the api/error.h
Rules section. While at it, modify the call in s390_ccw_realize().

Signed-off-by: Cédric Le Goater 
---
 hw/s390x/ccw-device.h | 2 +-
 hw/s390x/ccw-device.c | 3 ++-
 hw/s390x/s390-ccw.c   | 3 +--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h
index 
6dff95225df11c63f9b66975019026b215c8c448..5feeb0ee7a268b8709043b5bbc56b06e707a448d
 100644
--- a/hw/s390x/ccw-device.h
+++ b/hw/s390x/ccw-device.h
@@ -36,7 +36,7 @@ extern const VMStateDescription vmstate_ccw_dev;
 struct CCWDeviceClass {
 DeviceClass parent_class;
 void (*unplug)(HotplugHandler *, DeviceState *, Error **);
-void (*realize)(CcwDevice *, Error **);
+bool (*realize)(CcwDevice *, Error **);
 void (*refill_ids)(CcwDevice *);
 };
 
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
index 
fb8c1acc64d5002c861a4913f292d8346dbef192..a7d682e5af9ce90e7e2fad8c24b30e39328c7cf4
 100644
--- a/hw/s390x/ccw-device.c
+++ b/hw/s390x/ccw-device.c
@@ -31,9 +31,10 @@ static void ccw_device_refill_ids(CcwDevice *dev)
 dev->subch_id.valid = true;
 }
 
-static void ccw_device_realize(CcwDevice *dev, Error **errp)
+static bool ccw_device_realize(CcwDevice *dev, Error **errp)
 {
 ccw_device_refill_ids(dev);
+return true;
 }
 
 static Property ccw_device_properties[] = {
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index 
a06e91dfb318e3500324851488c56806fa46c08d..4b8ede701df90949720262b6fc1b65f4e505e34d
 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -137,8 +137,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char 
*sysfsdev, Error **errp)
 goto out_err;
 }
 
-ck->realize(ccw_dev, );
-if (err) {
+if (!ck->realize(ccw_dev, )) {
 goto out_err;
 }
 
-- 
2.45.1




[PULL 30/47] vfio/display: Fix error path in call site of ramfb_setup()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

vfio_display_dmabuf_init() and vfio_display_region_init() calls
ramfb_setup() without checking its return value.

So we may run into a situation that vfio_display_probe() succeed
but errp is set. This is risky and may lead to assert failure in
error_setv().

Cc: Gerd Hoffmann 
Fixes: b290659fc3d ("hw/vfio/display: add ramfb support")
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/display.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 
fe624a6c9b86e7204e2763ab62ef60903f19d350..d28b724102d5970cb2b9dc7464dc7575b6f441d9
 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -361,6 +361,9 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, 
Error **errp)
   vdev);
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
 }
 vfio_display_edid_init(vdev);
 return 0;
@@ -488,6 +491,9 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, 
Error **errp)
   vdev);
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
 }
 return 0;
 }
-- 
2.45.1




[PULL 24/47] vfio/container: Make vfio_connect_container() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/container.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
f2e9560a1906c4151535260e3488ee80ca90e78b..802828ddff061fef25b8e4c997a68348d4be9892
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -536,8 +536,8 @@ static bool vfio_legacy_setup(VFIOContainerBase 
*bcontainer, Error **errp)
 return true;
 }
 
-static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
-  Error **errp)
+static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as,
+   Error **errp)
 {
 VFIOContainer *container;
 VFIOContainerBase *bcontainer;
@@ -589,19 +589,18 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 error_report("vfio: error disconnecting group %d from"
  " container", group->groupid);
 }
-return ret;
+return false;
 }
 group->container = container;
 QLIST_INSERT_HEAD(>group_list, group, container_next);
 vfio_kvm_device_add_group(group);
-return 0;
+return true;
 }
 }
 
 fd = qemu_open_old("/dev/vfio/vfio", O_RDWR);
 if (fd < 0) {
 error_setg_errno(errp, errno, "failed to open /dev/vfio/vfio");
-ret = -errno;
 goto put_space_exit;
 }
 
@@ -609,7 +608,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 if (ret != VFIO_API_VERSION) {
 error_setg(errp, "supported vfio version: %d, "
"reported version: %d", VFIO_API_VERSION, ret);
-ret = -EINVAL;
 goto close_fd_exit;
 }
 
@@ -636,7 +634,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 assert(bcontainer->ops->setup);
 
 if (!bcontainer->ops->setup(bcontainer, errp)) {
-ret = -EINVAL;
 goto enable_discards_exit;
 }
 
@@ -652,7 +649,6 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 memory_listener_register(>listener, bcontainer->space->as);
 
 if (bcontainer->error) {
-ret = -1;
 error_propagate_prepend(errp, bcontainer->error,
 "memory listener initialization failed: ");
 goto listener_release_exit;
@@ -660,7 +656,7 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 
 bcontainer->initialized = true;
 
-return 0;
+return true;
 listener_release_exit:
 QLIST_REMOVE(group, container_next);
 QLIST_REMOVE(bcontainer, next);
@@ -685,7 +681,7 @@ close_fd_exit:
 put_space_exit:
 vfio_put_address_space(space);
 
-return ret;
+return false;
 }
 
 static void vfio_disconnect_container(VFIOGroup *group)
@@ -772,7 +768,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace 
*as, Error **errp)
 group->groupid = groupid;
 QLIST_INIT(>device_list);
 
-if (vfio_connect_container(group, as, errp)) {
+if (!vfio_connect_container(group, as, errp)) {
 error_prepend(errp, "failed to setup container for group %d: ",
   groupid);
 goto close_fd_exit;
-- 
2.45.1




[PULL 45/47] vfio/pci-quirks: Make vfio_add_*_cap() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Include below functions:
vfio_add_virt_caps()
vfio_add_nv_gpudirect_cap()
vfio_add_vmd_shadow_cap()

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h|  2 +-
 hw/vfio/pci-quirks.c | 42 +++---
 hw/vfio/pci.c|  3 +--
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
f1586810726584ecfc35ef685646faacabefbec0..bf67df2fbc09b3d0fd97d25dfaa5290ab33b03ea
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -212,7 +212,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
 void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
 void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
 void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
-int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
 void vfio_quirk_reset(VFIOPCIDevice *vdev);
 VFIOQuirk *vfio_quirk_alloc(int nr_mem);
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 
ca27917159785f760f688c8db0a9ac492080d74b..39dae72497e0315eeb580dbcd5255c58bc38c8ed
 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1536,7 +1536,7 @@ static bool is_valid_std_cap_offset(uint8_t pos)
 pos <= (PCI_CFG_SPACE_SIZE - PCI_CAP_SIZEOF));
 }
 
-static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
 {
 ERRP_GUARD();
 PCIDevice *pdev = >pdev;
@@ -1545,18 +1545,18 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
 uint8_t tmp;
 
 if (vdev->nv_gpudirect_clique == 0xFF) {
-return 0;
+return true;
 }
 
 if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid device vendor");
-return -EINVAL;
+return false;
 }
 
 if (pci_get_byte(pdev->config + PCI_CLASS_DEVICE + 1) !=
 PCI_BASE_CLASS_DISPLAY) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: unsupported PCI class");
-return -EINVAL;
+return false;
 }
 
 /*
@@ -1572,7 +1572,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
 vdev->config_offset + PCI_CAPABILITY_LIST);
 if (ret != 1 || !is_valid_std_cap_offset(tmp)) {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: error getting cap list");
-return -EINVAL;
+return false;
 }
 
 do {
@@ -1590,13 +1590,13 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
 pos = 0xD4;
 } else {
 error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid config space");
-return -EINVAL;
+return false;
 }
 
 ret = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, 8, errp);
 if (ret < 0) {
 error_prepend(errp, "Failed to add NVIDIA GPUDirect cap: ");
-return ret;
+return false;
 }
 
 memset(vdev->emulated_config_bits + pos, 0xFF, 8);
@@ -1608,7 +1608,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
 pci_set_byte(pdev->config + pos++, vdev->nv_gpudirect_clique << 3);
 pci_set_byte(pdev->config + pos, 0);
 
-return 0;
+return true;
 }
 
 /*
@@ -1629,7 +1629,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
  */
 #define VMD_SHADOW_CAP_VER 1
 #define VMD_SHADOW_CAP_LEN 24
-static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
 {
 ERRP_GUARD();
 uint8_t membar_phys[16];
@@ -1639,7 +1639,7 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x467F) ||
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x4C3D) ||
   vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x9A0B))) {
-return 0;
+return true;
 }
 
 ret = pread(vdev->vbasedev.fd, membar_phys, 16,
@@ -1647,14 +1647,14 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
 if (ret != 16) {
 error_report("VMD %s cannot read MEMBARs (%d)",
  vdev->vbasedev.name, ret);
-return -EFAULT;
+return false;
 }
 
 ret = pci_add_capability(>pdev, PCI_CAP_ID_VNDR, pos,
  VMD_SHADOW_CAP_LEN, errp);
 if (ret < 0) {
 error_prepend(errp, "Failed to add VMD MEMBAR Shadow cap: ");
-return ret;
+return false;
 }
 
 memset(v

[PULL 46/47] vfio: Use g_autofree in all call site of vfio_get_region_info()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

There are some exceptions when pointer to vfio_region_info is reused.
In that case, the pointed memory is freed manually.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/helpers.c |  7 ++-
 hw/vfio/igd.c |  5 ++---
 hw/vfio/pci.c | 13 +++--
 3 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
4b079dc383683a71d1d96507a0fb66a4bc3ba923..27ea26aa48f67e6518f871ac651ab8d2703cc611
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -343,7 +343,7 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion 
*region,
 int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
   int index, const char *name)
 {
-struct vfio_region_info *info;
+g_autofree struct vfio_region_info *info = NULL;
 int ret;
 
 ret = vfio_get_region_info(vbasedev, index, );
@@ -376,8 +376,6 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, 
VFIORegion *region,
 }
 }
 
-g_free(info);
-
 trace_vfio_region_setup(vbasedev->name, index, name,
 region->flags, region->fd_offset, region->size);
 return 0;
@@ -594,14 +592,13 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, 
uint32_t type,
 
 bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type)
 {
-struct vfio_region_info *info = NULL;
+g_autofree struct vfio_region_info *info = NULL;
 bool ret = false;
 
 if (!vfio_get_region_info(vbasedev, region, )) {
 if (vfio_get_region_info_cap(info, cap_type)) {
 ret = true;
 }
-g_free(info);
 }
 
 return ret;
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
402fc5ce1da966fda1340f328e0611cb1a2a0635..1e79202f2bd136b0bafd4f08c2f1407e467e0d65
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -367,8 +367,8 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
 
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 {
-struct vfio_region_info *rom = NULL, *opregion = NULL,
-*host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *rom = NULL;
+struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
 VFIOQuirk *quirk;
 VFIOIGDQuirk *igd;
 PCIDevice *lpc_bridge;
@@ -609,7 +609,6 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
 
 out:
-g_free(rom);
 g_free(opregion);
 g_free(host);
 g_free(lpc);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
35ad9b582f6b99510a812edab5c2855c697a1da2..74a79bdf61f9aeb4860d532b6c076dd3491dd0ab
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -879,7 +879,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev)
 
 static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
 {
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 uint64_t size;
 off_t off = 0;
 ssize_t bytes;
@@ -897,8 +897,6 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
 vdev->rom_size = size = reg_info->size;
 vdev->rom_offset = reg_info->offset;
 
-g_free(reg_info);
-
 if (!vdev->rom_size) {
 vdev->rom_read_failed = true;
 error_report("vfio-pci: Cannot read device rom at "
@@ -2668,7 +2666,7 @@ static VFIODeviceOps vfio_pci_ops = {
 bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 int ret;
 
 ret = vfio_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, _info);
@@ -2685,7 +2683,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 error_setg(errp, "unexpected VGA info, flags 0x%lx, size 0x%lx",
(unsigned long)reg_info->flags,
(unsigned long)reg_info->size);
-g_free(reg_info);
 return false;
 }
 
@@ -2694,8 +2691,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 vdev->vga->fd_offset = reg_info->offset;
 vdev->vga->fd = vdev->vbasedev.fd;
 
-g_free(reg_info);
-
 vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
 vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
 QLIST_INIT(>vga->region[QEMU_PCI_VGA_MEM].quirks);
@@ -2736,7 +2731,7 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
 struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
 int i, ret = -1;
 
@@ -27

[PULL 16/47] vfio/migration: Emit VFIO migration QAPI event

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

Emit VFIO migration QAPI event when a VFIO device changes its migration
state. This can be used by management applications to get updates on the
current state of the VFIO device for their own purposes.

A new per VFIO device capability, "migration-events", is added so events
can be enabled only for the required devices. It is disabled by default.

Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  1 +
 hw/vfio/migration.c   | 59 +--
 hw/vfio/pci.c |  2 ++
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b6ac24953667bc5f72f28480a6bf0f4722069cb9..878e34a12874f63fcb8bbc8dc8ca3d2dfa84fdb4
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -115,6 +115,7 @@ typedef struct VFIODevice {
 bool no_mmap;
 bool ram_block_discard_allowed;
 OnOffAuto enable_migration;
+bool migration_events;
 VFIODeviceOps *ops;
 unsigned int num_irqs;
 unsigned int num_regions;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
c4403a38ddb5e7e09fbcde0ad4132653ecaf0d24..af579b868d7caa726fde1eeb73c832ebc3136a7a
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -24,6 +24,7 @@
 #include "migration/register.h"
 #include "migration/blocker.h"
 #include "qapi/error.h"
+#include "qapi/qapi-events-vfio.h"
 #include "exec/ramlist.h"
 #include "exec/ram_addr.h"
 #include "pci.h"
@@ -80,6 +81,58 @@ static const char *mig_state_to_str(enum 
vfio_device_mig_state state)
 }
 }
 
+static VfioMigrationState
+mig_state_to_qapi_state(enum vfio_device_mig_state state)
+{
+switch (state) {
+case VFIO_DEVICE_STATE_STOP:
+return QAPI_VFIO_MIGRATION_STATE_STOP;
+case VFIO_DEVICE_STATE_RUNNING:
+return QAPI_VFIO_MIGRATION_STATE_RUNNING;
+case VFIO_DEVICE_STATE_STOP_COPY:
+return QAPI_VFIO_MIGRATION_STATE_STOP_COPY;
+case VFIO_DEVICE_STATE_RESUMING:
+return QAPI_VFIO_MIGRATION_STATE_RESUMING;
+case VFIO_DEVICE_STATE_RUNNING_P2P:
+return QAPI_VFIO_MIGRATION_STATE_RUNNING_P2P;
+case VFIO_DEVICE_STATE_PRE_COPY:
+return QAPI_VFIO_MIGRATION_STATE_PRE_COPY;
+case VFIO_DEVICE_STATE_PRE_COPY_P2P:
+return QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P;
+default:
+g_assert_not_reached();
+}
+}
+
+static void vfio_migration_send_event(VFIODevice *vbasedev)
+{
+VFIOMigration *migration = vbasedev->migration;
+DeviceState *dev = vbasedev->dev;
+g_autofree char *qom_path = NULL;
+Object *obj;
+
+if (!vbasedev->migration_events) {
+return;
+}
+
+g_assert(vbasedev->ops->vfio_get_object);
+obj = vbasedev->ops->vfio_get_object(vbasedev);
+g_assert(obj);
+qom_path = object_get_canonical_path(obj);
+
+qapi_event_send_vfio_migration(
+dev->id, qom_path, mig_state_to_qapi_state(migration->device_state));
+}
+
+static void vfio_migration_set_device_state(VFIODevice *vbasedev,
+enum vfio_device_mig_state state)
+{
+VFIOMigration *migration = vbasedev->migration;
+
+migration->device_state = state;
+vfio_migration_send_event(vbasedev);
+}
+
 static int vfio_migration_set_state(VFIODevice *vbasedev,
 enum vfio_device_mig_state new_state,
 enum vfio_device_mig_state recover_state,
@@ -131,12 +184,12 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 goto reset_device;
 }
 
-migration->device_state = recover_state;
+vfio_migration_set_device_state(vbasedev, recover_state);
 
 return ret;
 }
 
-migration->device_state = new_state;
+vfio_migration_set_device_state(vbasedev, new_state);
 if (mig_state->data_fd != -1) {
 if (migration->data_fd != -1) {
 /*
@@ -162,7 +215,7 @@ reset_device:
  strerror(errno));
 }
 
-migration->device_state = VFIO_DEVICE_STATE_RUNNING;
+vfio_migration_set_device_state(vbasedev, VFIO_DEVICE_STATE_RUNNING);
 
 return ret;
 }
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
4789d43c0f9cc7ef94b73adc815377f7222d8c57..b5d1d398b120076c85cdd92d61793393f65e8554
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3388,6 +3388,8 @@ static Property vfio_pci_dev_properties[] = {
 VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
 DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
 vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
+DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
+ vbasedev.migration_

[PULL 21/47] vfio: Make VFIOIOMMUClass::attach_device() and its wrapper return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Make VFIOIOMMUClass::attach_device() and its wrapper function
vfio_attach_device() return bool.

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  4 ++--
 include/hw/vfio/vfio-container-base.h |  4 ++--
 hw/vfio/ap.c  |  6 ++
 hw/vfio/ccw.c |  6 ++
 hw/vfio/common.c  |  4 ++--
 hw/vfio/container.c   | 14 +++---
 hw/vfio/iommufd.c | 11 +--
 hw/vfio/pci.c |  5 ++---
 hw/vfio/platform.c|  7 +++
 9 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
878e34a12874f63fcb8bbc8dc8ca3d2dfa84fdb4..e85817e65e65317d08bc2b17b738449198784796
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -222,8 +222,8 @@ void vfio_region_exit(VFIORegion *region);
 void vfio_region_finalize(VFIORegion *region);
 void vfio_reset_handler(void *opaque);
 struct vfio_device_info *vfio_get_device_info(int fd);
-int vfio_attach_device(char *name, VFIODevice *vbasedev,
-   AddressSpace *as, Error **errp);
+bool vfio_attach_device(char *name, VFIODevice *vbasedev,
+AddressSpace *as, Error **errp);
 void vfio_detach_device(VFIODevice *vbasedev);
 
 int vfio_kvm_device_add_fd(int fd, Error **errp);
diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
b04057ad1aff73d974ecec718d0fe45f7a930b59..44927ca8c3583246145defe043ac34da604d39bf
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -117,8 +117,8 @@ struct VFIOIOMMUClass {
 int (*dma_unmap)(const VFIOContainerBase *bcontainer,
  hwaddr iova, ram_addr_t size,
  IOMMUTLBEntry *iotlb);
-int (*attach_device)(const char *name, VFIODevice *vbasedev,
- AddressSpace *as, Error **errp);
+bool (*attach_device)(const char *name, VFIODevice *vbasedev,
+  AddressSpace *as, Error **errp);
 void (*detach_device)(VFIODevice *vbasedev);
 
 /* migration feature */
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
8bb024e2fde4a1d72346dee4b662d762374326b9..ba653ef70f08ebdf482009baafc62eb33ebda9a8
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -154,7 +154,6 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
 static void vfio_ap_realize(DeviceState *dev, Error **errp)
 {
 ERRP_GUARD();
-int ret;
 Error *err = NULL;
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 VFIODevice *vbasedev = >vdev;
@@ -163,9 +162,8 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-ret = vfio_attach_device(vbasedev->name, vbasedev,
- _space_memory, errp);
-if (ret) {
+if (!vfio_attach_device(vbasedev->name, vbasedev,
+_space_memory, errp)) {
 goto error;
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
1c630f6e9abe93ae0c2b5615d4409669f096c8c9..89bb98016764e65cf826183d7a38c59d429f6eeb
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -579,7 +579,6 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
 VFIODevice *vbasedev = >vdev;
 Error *err = NULL;
-int ret;
 
 /* Call the class init function for subchannel. */
 if (cdc->realize) {
@@ -593,9 +592,8 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-ret = vfio_attach_device(cdev->mdevid, vbasedev,
- _space_memory, errp);
-if (ret) {
+if (!vfio_attach_device(cdev->mdevid, vbasedev,
+_space_memory, errp)) {
 goto out_attach_dev_err;
 }
 
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
1fbd10801d35079341a833fa68a43de2b758cde0..c04a259ffd7cfcfba480335bea1ddff787f47bdc
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1523,8 +1523,8 @@ retry:
 return info;
 }
 
-int vfio_attach_device(char *name, VFIODevice *vbasedev,
-   AddressSpace *as, Error **errp)
+bool vfio_attach_device(char *name, VFIODevice *vbasedev,
+AddressSpace *as, Error **errp)
 {
 const VFIOIOMMUClass *ops =
 VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY));
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
9534120d4ac835bb58e37667dad8d39205404c08..e7c416774791d506cc7c4696fb6a6d94dc809c8e
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -910,8 +910,8 @@ static in

[PULL 22/47] vfio: Make VFIOIOMMUClass::setup() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-container-base.h |  2 +-
 hw/vfio/container.c   | 10 +-
 hw/vfio/spapr.c   | 12 +---
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
44927ca8c3583246145defe043ac34da604d39bf..202e23cb6b800983b036bf3808c0ec38b1c363d0
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -110,7 +110,7 @@ struct VFIOIOMMUClass {
 InterfaceClass parent_class;
 
 /* basic feature */
-int (*setup)(VFIOContainerBase *bcontainer, Error **errp);
+bool (*setup)(VFIOContainerBase *bcontainer, Error **errp);
 int (*dma_map)(const VFIOContainerBase *bcontainer,
hwaddr iova, ram_addr_t size,
void *vaddr, bool readonly);
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
e7c416774791d506cc7c4696fb6a6d94dc809c8e..f2e9560a1906c4151535260e3488ee80ca90e78b
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -507,7 +507,7 @@ static void vfio_get_iommu_info_migration(VFIOContainer 
*container,
 }
 }
 
-static int vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
+static bool vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
 {
 VFIOContainer *container = container_of(bcontainer, VFIOContainer,
 bcontainer);
@@ -517,7 +517,7 @@ static int vfio_legacy_setup(VFIOContainerBase *bcontainer, 
Error **errp)
 ret = vfio_get_iommu_info(container, );
 if (ret) {
 error_setg_errno(errp, -ret, "Failed to get VFIO IOMMU info");
-return ret;
+return false;
 }
 
 if (info->flags & VFIO_IOMMU_INFO_PGSIZES) {
@@ -533,7 +533,7 @@ static int vfio_legacy_setup(VFIOContainerBase *bcontainer, 
Error **errp)
 vfio_get_info_iova_range(info, bcontainer);
 
 vfio_get_iommu_info_migration(container, info);
-return 0;
+return true;
 }
 
 static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
@@ -635,8 +635,8 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 
 assert(bcontainer->ops->setup);
 
-ret = bcontainer->ops->setup(bcontainer, errp);
-if (ret) {
+if (!bcontainer->ops->setup(bcontainer, errp)) {
+ret = -EINVAL;
 goto enable_discards_exit;
 }
 
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 
0d949bb728212534a7e2296e491aa8d95f45945d..148b257c9ca6a0f957115f8060ddb50e377dfcb8
 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -458,8 +458,8 @@ static void vfio_spapr_container_release(VFIOContainerBase 
*bcontainer)
 }
 }
 
-static int vfio_spapr_container_setup(VFIOContainerBase *bcontainer,
-  Error **errp)
+static bool vfio_spapr_container_setup(VFIOContainerBase *bcontainer,
+   Error **errp)
 {
 VFIOContainer *container = container_of(bcontainer, VFIOContainer,
 bcontainer);
@@ -480,7 +480,7 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 ret = ioctl(fd, VFIO_IOMMU_ENABLE);
 if (ret) {
 error_setg_errno(errp, errno, "failed to enable container");
-return -errno;
+return false;
 }
 } else {
 scontainer->prereg_listener = vfio_prereg_listener;
@@ -488,7 +488,6 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 memory_listener_register(>prereg_listener,
  _space_memory);
 if (bcontainer->error) {
-ret = -1;
 error_propagate_prepend(errp, bcontainer->error,
 "RAM memory listener initialization failed: ");
 goto listener_unregister_exit;
@@ -500,7 +499,6 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
 if (ret) {
 error_setg_errno(errp, errno,
  "VFIO_IOMMU_SPAPR_TCE_GET_INFO failed");
-ret = -errno;
 goto listener_unregister_exit;
 }
 
@@ -527,13 +525,13 @@ static int vfio_spapr_container_setup(VFIOContainerBase 
*bcontainer,
   0x1000);
 }
 
-return 0;
+return true;
 
 listener_unregister_exit:
 if (v2) {
 memory_listener_unregister(>prereg_listener);
 }
-return ret;
+return false;
 }
 
 static void vfio_iommu_spapr_class_init(ObjectClass *klass, void *data)
-- 
2.45.1




[PULL 27/47] vfio/iommufd: Make iommufd_cdev_*() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

The changed functions include:

iommufd_cdev_kvm_device_add
iommufd_cdev_connect_and_bind
iommufd_cdev_attach_ioas_hwpt
iommufd_cdev_detach_ioas_hwpt
iommufd_cdev_attach_container
iommufd_cdev_get_info_iova_range

After the change, all functions in hw/vfio/iommufd.c follows the
standand.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/iommufd.c | 88 +--
 1 file changed, 39 insertions(+), 49 deletions(-)

diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
4c6992fca11969bc8fe26c11e902e2521d6bff7a..84c86b970e756d34b202d5b18ae51c30c730e092
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -49,9 +49,9 @@ static int iommufd_cdev_unmap(const VFIOContainerBase 
*bcontainer,
  container->ioas_id, iova, size);
 }
 
-static int iommufd_cdev_kvm_device_add(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_kvm_device_add(VFIODevice *vbasedev, Error **errp)
 {
-return vfio_kvm_device_add_fd(vbasedev->fd, errp);
+return !vfio_kvm_device_add_fd(vbasedev->fd, errp);
 }
 
 static void iommufd_cdev_kvm_device_del(VFIODevice *vbasedev)
@@ -63,18 +63,16 @@ static void iommufd_cdev_kvm_device_del(VFIODevice 
*vbasedev)
 }
 }
 
-static int iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
 {
 IOMMUFDBackend *iommufd = vbasedev->iommufd;
 struct vfio_device_bind_iommufd bind = {
 .argsz = sizeof(bind),
 .flags = 0,
 };
-int ret;
 
-ret = iommufd_backend_connect(iommufd, errp);
-if (ret) {
-return ret;
+if (iommufd_backend_connect(iommufd, errp)) {
+return false;
 }
 
 /*
@@ -82,15 +80,13 @@ static int iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
  * in KVM. Especially for some emulated devices, it requires
  * to have kvm information in the device open.
  */
-ret = iommufd_cdev_kvm_device_add(vbasedev, errp);
-if (ret) {
+if (!iommufd_cdev_kvm_device_add(vbasedev, errp)) {
 goto err_kvm_device_add;
 }
 
 /* Bind device to iommufd */
 bind.iommufd = iommufd->fd;
-ret = ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, );
-if (ret) {
+if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, )) {
 error_setg_errno(errp, errno, "error bind device fd=%d to iommufd=%d",
  vbasedev->fd, bind.iommufd);
 goto err_bind;
@@ -99,12 +95,12 @@ static int iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
 vbasedev->devid = bind.out_devid;
 trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name,
 vbasedev->fd, vbasedev->devid);
-return ret;
+return true;
 err_bind:
 iommufd_cdev_kvm_device_del(vbasedev);
 err_kvm_device_add:
 iommufd_backend_disconnect(iommufd);
-return ret;
+return false;
 }
 
 static void iommufd_cdev_unbind_and_disconnect(VFIODevice *vbasedev)
@@ -176,10 +172,10 @@ out:
 return ret;
 }
 
-static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
+static bool iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
  Error **errp)
 {
-int ret, iommufd = vbasedev->iommufd->fd;
+int iommufd = vbasedev->iommufd->fd;
 struct vfio_device_attach_iommufd_pt attach_data = {
 .argsz = sizeof(attach_data),
 .flags = 0,
@@ -187,38 +183,38 @@ static int iommufd_cdev_attach_ioas_hwpt(VFIODevice 
*vbasedev, uint32_t id,
 };
 
 /* Attach device to an IOAS or hwpt within iommufd */
-ret = ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, _data);
-if (ret) {
+if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, _data)) {
 error_setg_errno(errp, errno,
  "[iommufd=%d] error attach %s (%d) to id=%d",
  iommufd, vbasedev->name, vbasedev->fd, id);
-} else {
-trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
-vbasedev->fd, id);
+return false;
 }
-return ret;
+
+trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
+vbasedev->fd, id);
+return true;
 }
 
-static int iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
 {
-int ret, iommufd = vbasedev->iommufd->fd;
+int iommufd = vbasedev->iommufd->fd;
 struct vfio_device_detach_iommufd_pt detach_data

[PULL 29/47] backends/iommufd: Make iommufd_backend_*() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

The changed functions include:

iommufd_backend_connect
iommufd_backend_alloc_ioas

By this chance, simplify the functions a bit by avoiding duplicate
recordings, e.g., log through either error interface or trace, not
both.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/sysemu/iommufd.h |  6 +++---
 backends/iommufd.c   | 29 +
 hw/vfio/iommufd.c|  5 ++---
 backends/trace-events|  4 ++--
 4 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
index 
9af27ebd6ccb78ca8e16aa3c62629aab9f7f31e4..293bfbe967215381532b8267227dde61fa9157b7
 100644
--- a/include/sysemu/iommufd.h
+++ b/include/sysemu/iommufd.h
@@ -23,11 +23,11 @@ struct IOMMUFDBackend {
 /*< public >*/
 };
 
-int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
 void iommufd_backend_disconnect(IOMMUFDBackend *be);
 
-int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
-   Error **errp);
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+Error **errp);
 void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
 int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
 ram_addr_t size, void *vaddr, bool readonly);
diff --git a/backends/iommufd.c b/backends/iommufd.c
index 
76a0204852f73466a9f31492a08d89d468bff7c0..c506afbdac4beddb7dac88f74f10544f7a083e58
 100644
--- a/backends/iommufd.c
+++ b/backends/iommufd.c
@@ -72,24 +72,22 @@ static void iommufd_backend_class_init(ObjectClass *oc, 
void *data)
 object_class_property_add_str(oc, "fd", NULL, iommufd_backend_set_fd);
 }
 
-int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
 {
-int fd, ret = 0;
+int fd;
 
 if (be->owned && !be->users) {
 fd = qemu_open_old("/dev/iommu", O_RDWR);
 if (fd < 0) {
 error_setg_errno(errp, errno, "/dev/iommu opening failed");
-ret = fd;
-goto out;
+return false;
 }
 be->fd = fd;
 }
 be->users++;
-out:
-trace_iommufd_backend_connect(be->fd, be->owned,
-  be->users, ret);
-return ret;
+
+trace_iommufd_backend_connect(be->fd, be->owned, be->users);
+return true;
 }
 
 void iommufd_backend_disconnect(IOMMUFDBackend *be)
@@ -106,25 +104,24 @@ out:
 trace_iommufd_backend_disconnect(be->fd, be->users);
 }
 
-int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
-   Error **errp)
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+Error **errp)
 {
-int ret, fd = be->fd;
+int fd = be->fd;
 struct iommu_ioas_alloc alloc_data  = {
 .size = sizeof(alloc_data),
 .flags = 0,
 };
 
-ret = ioctl(fd, IOMMU_IOAS_ALLOC, _data);
-if (ret) {
+if (ioctl(fd, IOMMU_IOAS_ALLOC, _data)) {
 error_setg_errno(errp, errno, "Failed to allocate ioas");
-return ret;
+return false;
 }
 
 *ioas_id = alloc_data.out_ioas_id;
-trace_iommufd_backend_alloc_ioas(fd, *ioas_id, ret);
+trace_iommufd_backend_alloc_ioas(fd, *ioas_id);
 
-return ret;
+return true;
 }
 
 void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id)
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
6a446b16dcd64838dc9ebb6150cd5ed85ec6fef3..554f9a6292454f51015ab3a56df3fab6a482ccb7
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -71,7 +71,7 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice 
*vbasedev, Error **errp)
 .flags = 0,
 };
 
-if (iommufd_backend_connect(iommufd, errp)) {
+if (!iommufd_backend_connect(iommufd, errp)) {
 return false;
 }
 
@@ -346,8 +346,7 @@ static bool iommufd_cdev_attach(const char *name, 
VFIODevice *vbasedev,
 }
 
 /* Need to allocate a new dedicated container */
-ret = iommufd_backend_alloc_ioas(vbasedev->iommufd, _id, errp);
-if (ret < 0) {
+if (!iommufd_backend_alloc_ioas(vbasedev->iommufd, _id, errp)) {
 goto err_alloc_ioas;
 }
 
diff --git a/backends/trace-events b/backends/trace-events
index 
d45c6e31a67ed66d94787f60eb08a525cf6ff68b..211e6f374adcef25be0409ce3e42cbed6f31b744
 100644
--- a/backends/trace-events
+++ b/backends/trace-events
@@ -7,11 +7,11 @@ dbus_vmstate_loading(const char *id) "id: %s"
 dbus_vmstate_saving(const char *id) "

[PULL 13/47] vfio/ccw: Make vfio_ccw_register_irq_notifier() return a bool

2024-05-22 Thread Cédric Le Goater
Since vfio_ccw_register_irq_notifier() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h Rules
section.

Reviewed-by: Markus Armbruster 
Reviewed-by: Eric Farman 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
6764388bc47a970329fce2233626ccb8178e0165..1c630f6e9abe93ae0c2b5615d4409669f096c8c9
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -379,7 +379,7 @@ read_err:
 css_inject_io_interrupt(sch);
 }
 
-static void vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
+static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev,
unsigned int irq,
Error **errp)
 {
@@ -405,13 +405,13 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 break;
 default:
 error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
-return;
+return false;
 }
 
 if (vdev->num_irqs < irq + 1) {
 error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
irq, vdev->num_irqs);
-return;
+return false;
 }
 
 argsz = sizeof(*irq_info);
@@ -421,14 +421,14 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
   irq_info) < 0 || irq_info->count < 1) {
 error_setg_errno(errp, errno, "vfio: Error getting irq info");
-return;
+return false;
 }
 
 if (event_notifier_init(notifier, 0)) {
 error_setg_errno(errp, errno,
  "vfio: Unable to init event notifier for irq (%d)",
  irq);
-return;
+return false;
 }
 
 fd = event_notifier_get_fd(notifier);
@@ -439,6 +439,8 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 qemu_set_fd_handler(fd, NULL, NULL, vcdev);
 event_notifier_cleanup(notifier);
 }
+
+return true;
 }
 
 static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
@@ -602,20 +604,18 @@ static void vfio_ccw_realize(DeviceState *dev, Error 
**errp)
 goto out_region_err;
 }
 
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, )) {
 goto out_io_notifier_err;
 }
 
 if (vcdev->crw_region) {
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
+)) {
 goto out_irq_notifier_err;
 }
 }
 
-vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, );
-if (err) {
+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, )) {
 /*
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
-- 
2.45.1




[PULL 47/47] vfio/igd: Use g_autofree in vfio_probe_igd_bar4_quirk()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Pointer opregion, host and lpc are allocated and freed in
vfio_probe_igd_bar4_quirk(). Use g_autofree to automatically
free them.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/igd.c | 27 ---
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
1e79202f2bd136b0bafd4f08c2f1407e467e0d65..d320d032a7f3b19df0d055178f6fefe4bdfd8668
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -368,7 +368,9 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
 void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 {
 g_autofree struct vfio_region_info *rom = NULL;
-struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *opregion = NULL;
+g_autofree struct vfio_region_info *host = NULL;
+g_autofree struct vfio_region_info *lpc = NULL;
 VFIOQuirk *quirk;
 VFIOIGDQuirk *igd;
 PCIDevice *lpc_bridge;
@@ -426,7 +428,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if ((ret || !rom->size) && !vdev->pdev.romfile) {
 error_report("IGD device %s has no ROM, legacy mode disabled",
  vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /*
@@ -437,7 +439,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 error_report("IGD device %s hotplugged, ROM disabled, "
  "legacy mode disabled", vdev->vbasedev.name);
 vdev->rom_read_failed = true;
-goto out;
+return;
 }
 
 /*
@@ -450,7 +452,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support OpRegion access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 ret = vfio_get_dev_region_info(>vbasedev,
@@ -459,7 +461,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support host bridge access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 ret = vfio_get_dev_region_info(>vbasedev,
@@ -468,7 +470,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s does not support LPC bridge access,"
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 gmch = vfio_pci_read_config(>pdev, IGD_GMCH, 4);
@@ -482,7 +484,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 error_report("IGD device %s failed to enable VGA access, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Create our LPC/ISA bridge */
@@ -490,7 +492,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 if (ret) {
 error_report("IGD device %s failed to create LPC bridge, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Stuff some host values into the VM PCI host bridge */
@@ -498,14 +500,14 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
nr)
 if (ret) {
 error_report("IGD device %s failed to modify host bridge, "
  "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Setup OpRegion access */
 if (!vfio_pci_igd_opregion_init(vdev, opregion, )) {
 error_append_hint(, "IGD legacy mode disabled\n");
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
-goto out;
+return;
 }
 
 /* Setup our quirk to munge GTT addresses to the VM allocated buffer */
@@ -607,9 +609,4 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 }
 
 trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
-
-out:
-g_free(opregion);
-g_free(host);
-g_free(lpc);
 }
-- 
2.45.1




[PULL 03/47] migration: Extend migration_file_set_error() with Error* argument

2024-05-22 Thread Cédric Le Goater
Use it to update the current error of the migration stream if
available and if not, simply print out the error. Next changes will
update with an error to report.

Reviewed-by: Avihai Horon 
Acked-by: Fabiano Rosas 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 include/migration/misc.h | 2 +-
 hw/vfio/common.c | 4 ++--
 hw/vfio/migration.c  | 4 ++--
 migration/migration.c| 6 --
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/include/migration/misc.h b/include/migration/misc.h
index 
bf7339cc1e6430226127fb6a878d06b458170858..bfadc5613bac614a316e5aed7da95d8c7845cf42
 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -97,7 +97,7 @@ void migration_add_notifier_mode(NotifierWithReturn *notify,
 
 void migration_remove_notifier(NotifierWithReturn *notify);
 bool migration_is_running(void);
-void migration_file_set_error(int err);
+void migration_file_set_error(int ret, Error *err);
 
 /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
 bool migration_in_incoming_postcopy(void);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
b5102f54a6474a50c6366e8fbce23812d55e384e..2c97de6c730d963d961bf81c0831326c0e25afa7
 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 != _space_memory;
 }
 
-static void vfio_set_migration_error(int err)
+static void vfio_set_migration_error(int ret)
 {
 if (migration_is_setup_or_active()) {
-migration_file_set_error(err);
+migration_file_set_error(ret, NULL);
 }
 }
 
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
06ae40969b6c19037e190008e14f28be646278cd..bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -726,7 +726,7 @@ static void vfio_vmstate_change_prepare(void *opaque, bool 
running,
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change_prepare(vbasedev->name, running,
@@ -756,7 +756,7 @@ static void vfio_vmstate_change(void *opaque, bool running, 
RunState state)
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
diff --git a/migration/migration.c b/migration/migration.c
index 
e88b24f1e6cbe82dad3f890c00e264d2ab6ad355..70d66a441bf04761decf91dbe57ce52c57fde58f
 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2994,13 +2994,15 @@ static MigThrError postcopy_pause(MigrationState *s)
 }
 }
 
-void migration_file_set_error(int err)
+void migration_file_set_error(int ret, Error *err)
 {
 MigrationState *s = current_migration;
 
 WITH_QEMU_LOCK_GUARD(>qemu_file_lock) {
 if (s->to_dst_file) {
-qemu_file_set_error(s->to_dst_file, err);
+qemu_file_set_error_obj(s->to_dst_file, ret, err);
+} else if (err) {
+error_report_err(err);
 }
 }
 }
-- 
2.45.1




[PULL 01/47] vfio: Add Error** argument to .set_dirty_page_tracking() handler

2024-05-22 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 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 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(bcon

[PULL 18/47] vfio/migration: Enhance VFIO migration state tracing

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

Move trace_vfio_migration_set_state() to the top of the function, add
recover_state to it, and add a new trace event to
vfio_migration_set_device_state().

This improves tracing of device state changes as state changes are now
also logged when vfio_migration_set_state() fails (covering recover
state and device reset transitions) and in no-op state transitions to
the same state.

Suggested-by: Cédric Le Goater 
Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c  | 8 ++--
 hw/vfio/trace-events | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
56edffaf6251e28e39ef32991394697abb1b9e55..34d4be2ce1b13626a8690d4787366ee41a9ebe1e
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -129,6 +129,9 @@ static void vfio_migration_set_device_state(VFIODevice 
*vbasedev,
 {
 VFIOMigration *migration = vbasedev->migration;
 
+trace_vfio_migration_set_device_state(vbasedev->name,
+  mig_state_to_str(state));
+
 migration->device_state = state;
 vfio_migration_send_event(vbasedev);
 }
@@ -150,6 +153,9 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 g_strdup_printf("%s: Failed setting device state to %s.",
 vbasedev->name, mig_state_to_str(new_state));
 
+trace_vfio_migration_set_state(vbasedev->name, mig_state_to_str(new_state),
+   mig_state_to_str(recover_state));
+
 if (new_state == migration->device_state) {
 return 0;
 }
@@ -209,8 +215,6 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 migration->data_fd = mig_state->data_fd;
 }
 
-trace_vfio_migration_set_state(vbasedev->name, 
mig_state_to_str(new_state));
-
 return 0;
 
 reset_device:
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 
f0474b244bf04d044e8327c88bf49aef349afcca..64161bf6f44cffd73851a90b70694120a5fb2a82
 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -152,7 +152,8 @@ vfio_load_device_config_state(const char *name) " (%s)"
 vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64
 vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " 
(%s) size 0x%"PRIx64" ret %d"
 vfio_migration_realize(const char *name) " (%s)"
-vfio_migration_set_state(const char *name, const char *state) " (%s) state %s"
+vfio_migration_set_device_state(const char *name, const char *state) " (%s) 
state %s"
+vfio_migration_set_state(const char *name, const char *new_state, const char 
*recover_state) " (%s) new state %s, recover state %s"
 vfio_migration_state_notifier(const char *name, int state) " (%s) state %d"
 vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
 vfio_save_cleanup(const char *name) " (%s)"
-- 
2.45.1




[PULL 05/47] vfio/migration: Add Error** argument to .vfio_save_config() handler

2024-05-22 Thread Cédric Le Goater
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é 
Reviewed-by: Eric Auger 
Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h | 25 -
 hw/vfio/migration.c   | 25 ++---
 hw/vfio/pci.c |  5 +++--
 3 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
d66e27db02a4db8329204f88d02a204eedf1caa1..3ff633ad3b395e953a55683f5f0308bca50af3dd
 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 
43fed0dbdbe3415ae2dd68fbe45b302b85a80fa4..5d91364f3bbc34060d84b4b4b1823eadbc7b12bf
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -193,21 +193,30 @@ 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);
 
 trace_vfio_save_device_config_state(vbasedev->name);
 
-return qemu_file_get_error(f);
+ret = qemu_file_get_error(f);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Failed to save state");
+}
+return ret;
 }
 
 static int vfio_load_device_config_state(QEMUFile *f, void *opaque)
@@ -592,13 +601,15 @@ 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, _err);
 if (ret) {
-error_report("%s: Failed to save device config space",
- vbasedev->name);
-qemu_file_set_error(f, ret);
+error_prepend(_err,
+  "vfio: Failed to save device config space of %s - ",
+  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, _vfio_pci_config, vdev, NULL);
+return vmstate_save_state_with_err(f, _vfio_pci_config, vdev, NULL,
+   errp);
 }
 
 static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
-- 
2.45.1




[PULL 33/47] vfio/helpers: Make vfio_set_irq_signaling() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  4 ++--
 hw/vfio/ap.c  |  8 +++
 hw/vfio/ccw.c |  8 +++
 hw/vfio/helpers.c | 18 ++--
 hw/vfio/pci.c | 40 ++-
 hw/vfio/platform.c| 18 +++-
 6 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b7bb4f5304addcdb03c971f27f99e5350ad0940a..b712799caffdc950b593a87d569d7f5281976e2f
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -207,8 +207,8 @@ void vfio_spapr_container_deinit(VFIOContainer *container);
 void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
 void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
 void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp);
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp);
 void vfio_region_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size);
 uint64_t vfio_region_read(void *opaque,
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
ba653ef70f08ebdf482009baafc62eb33ebda9a8..d8a9615feec065e98f53831912087d9878fdff9c
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -117,8 +117,8 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 fd = event_notifier_get_fd(notifier);
 qemu_set_fd_handler(fd, fd_read, NULL, vapdev);
 
-if (vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
-   errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
+errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vapdev);
 event_notifier_cleanup(notifier);
 }
@@ -141,8 +141,8 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
 return;
 }
 
-if (vfio_set_irq_signaling(>vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name);
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
89bb98016764e65cf826183d7a38c59d429f6eeb..1f578a3c75d975e12bbac52b3683e6fd193801cb
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -434,8 +434,8 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 fd = event_notifier_get_fd(notifier);
 qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
 
-if (vfio_set_irq_signaling(vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vcdev);
 event_notifier_cleanup(notifier);
 }
@@ -464,8 +464,8 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
 return;
 }
 
-if (vfio_set_irq_signaling(>vdev, irq, 0,
-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
 }
 
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
1f3bdd9bf059beec186d87ba4772f2f6e34bc7d4..9edbc966884de12e7248af8d50d87f26c8cd2764
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -107,12 +107,12 @@ static const char *index_to_str(VFIODevice *vbasedev, int 
index)
 }
 }
 
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp)
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp)
 {
 ERRP_GUARD();
 g_autofree struct vfio_irq_set *irq_set = NULL;
-int argsz, ret = 0;
+int argsz;
 const char *name;
 int32_t *pfd;
 
@@ -127,15 +127,11 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int 
index, int subindex,
 pfd = (int32_t *)_set->data;
 *pfd = fd;
 
-if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
-ret = -errno;
+if (!ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+return true;
 }
 
-if (!ret) {
-return 0;
-}
-
-error_setg_errno(errp, 

[PULL 26/47] vfio/container: Make vfio_get_device() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/container.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
e330b2897423b97fee467884f4237669ceff4756..53649e397cab94f8a2b61e6d66f21d635556e04e
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -802,8 +802,8 @@ static void vfio_put_group(VFIOGroup *group)
 g_free(group);
 }
 
-static int vfio_get_device(VFIOGroup *group, const char *name,
-   VFIODevice *vbasedev, Error **errp)
+static bool vfio_get_device(VFIOGroup *group, const char *name,
+VFIODevice *vbasedev, Error **errp)
 {
 g_autofree struct vfio_device_info *info = NULL;
 int fd;
@@ -815,14 +815,14 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 error_append_hint(errp,
   "Verify all devices in group %d are bound to vfio- "
   "or pci-stub and not already in use\n", group->groupid);
-return fd;
+return false;
 }
 
 info = vfio_get_device_info(fd);
 if (!info) {
 error_setg_errno(errp, errno, "error getting device info");
 close(fd);
-return -1;
+return false;
 }
 
 /*
@@ -837,7 +837,7 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 error_setg(errp, "Inconsistent setting of support for discarding "
"RAM (e.g., balloon) within group");
 close(fd);
-return -1;
+return false;
 }
 
 if (!group->ram_block_discard_allowed) {
@@ -858,7 +858,7 @@ static int vfio_get_device(VFIOGroup *group, const char 
*name,
 
 vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
 
-return 0;
+return true;
 }
 
 static void vfio_put_base_device(VFIODevice *vbasedev)
@@ -911,7 +911,6 @@ static bool vfio_legacy_attach_device(const char *name, 
VFIODevice *vbasedev,
 VFIODevice *vbasedev_iter;
 VFIOGroup *group;
 VFIOContainerBase *bcontainer;
-int ret;
 
 if (groupid < 0) {
 return false;
@@ -931,8 +930,7 @@ static bool vfio_legacy_attach_device(const char *name, 
VFIODevice *vbasedev,
 return false;
 }
 }
-ret = vfio_get_device(group, name, vbasedev, errp);
-if (ret) {
+if (!vfio_get_device(group, name, vbasedev, errp)) {
 vfio_put_group(group);
 return false;
 }
-- 
2.45.1




[PULL 40/47] vfio/pci: Make vfio_intx_enable() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
46d3c618596d95266543e9a0ebc65c04d9a7cc5d..7f35cb8a29176840412652afe5ab31cd52a1bf06
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -261,7 +261,7 @@ static void vfio_irqchip_change(Notifier *notify, void 
*data)
 vfio_intx_update(vdev, >intx.route);
 }
 
-static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
 {
 uint8_t pin = vfio_pci_read_config(>pdev, PCI_INTERRUPT_PIN, 1);
 Error *err = NULL;
@@ -270,7 +270,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 
 
 if (!pin) {
-return 0;
+return true;
 }
 
 vfio_disable_interrupts(vdev);
@@ -292,7 +292,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 ret = event_notifier_init(>intx.interrupt, 0);
 if (ret) {
 error_setg_errno(errp, -ret, "event_notifier_init failed");
-return ret;
+return false;
 }
 fd = event_notifier_get_fd(>intx.interrupt);
 qemu_set_fd_handler(fd, vfio_intx_interrupt, NULL, vdev);
@@ -301,7 +301,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
 qemu_set_fd_handler(fd, NULL, NULL, vdev);
 event_notifier_cleanup(>intx.interrupt);
-return -errno;
+return false;
 }
 
 if (!vfio_intx_enable_kvm(vdev, )) {
@@ -311,7 +311,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 vdev->interrupt = VFIO_INT_INTx;
 
 trace_vfio_intx_enable(vdev->vbasedev.name);
-return 0;
+return true;
 }
 
 static void vfio_intx_disable(VFIOPCIDevice *vdev)
@@ -836,8 +836,7 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev)
 vfio_disable_irqindex(>vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
 
 vfio_msi_disable_common(vdev);
-vfio_intx_enable(vdev, );
-if (err) {
+if (!vfio_intx_enable(vdev, )) {
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
@@ -2450,8 +2449,7 @@ void vfio_pci_post_reset(VFIOPCIDevice *vdev)
 Error *err = NULL;
 int nr;
 
-vfio_intx_enable(vdev, );
-if (err) {
+if (!vfio_intx_enable(vdev, )) {
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
@@ -3194,8 +3192,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  vfio_intx_routing_notifier);
 vdev->irqchip_change_notifier.notify = vfio_irqchip_change;
 kvm_irqchip_add_change_notifier(>irqchip_change_notifier);
-ret = vfio_intx_enable(vdev, errp);
-if (ret) {
+if (!vfio_intx_enable(vdev, errp)) {
 goto out_deregister;
 }
 }
-- 
2.45.1




[PULL 20/47] vfio/pci: Use g_autofree in iommufd_cdev_get_info_iova_range()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer info is freed before return from
iommufd_cdev_get_info_iova_range().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/iommufd.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
8827ffe636e2aba1551ba794bf666a7a214590b7..c6441279728fcede1dde2a099c076ad04c464a1f
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -258,7 +258,7 @@ static int 
iommufd_cdev_get_info_iova_range(VFIOIOMMUFDContainer *container,
 uint32_t ioas_id, Error **errp)
 {
 VFIOContainerBase *bcontainer = >bcontainer;
-struct iommu_ioas_iova_ranges *info;
+g_autofree struct iommu_ioas_iova_ranges *info = NULL;
 struct iommu_iova_range *iova_ranges;
 int ret, sz, fd = container->be->fd;
 
@@ -291,12 +291,10 @@ static int 
iommufd_cdev_get_info_iova_range(VFIOIOMMUFDContainer *container,
 }
 bcontainer->pgsizes = info->out_iova_alignment;
 
-g_free(info);
 return 0;
 
 error:
 ret = -errno;
-g_free(info);
 error_setg_errno(errp, errno, "Cannot get IOVA ranges");
 return ret;
 }
-- 
2.45.1




[PULL 19/47] vfio/pci: Use g_autofree in vfio_realize

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer name is allocated before vfio_attach_device() call
and freed after the call.

Same for tmp when calling realpath().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
b5d1d398b120076c85cdd92d61793393f65e8554..84f7bff664fd7595b75cce1f6974068144f0d42d
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2972,12 +2972,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 ERRP_GUARD();
 VFIOPCIDevice *vdev = VFIO_PCI(pdev);
 VFIODevice *vbasedev = >vbasedev;
-char *tmp, *subsys;
+char *subsys;
 Error *err = NULL;
 int i, ret;
 bool is_mdev;
 char uuid[UUID_STR_LEN];
-char *name;
+g_autofree char *name = NULL;
+g_autofree char *tmp = NULL;
 
 if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
 if (!(~vdev->host.domain || ~vdev->host.bus ||
@@ -3008,7 +3009,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  */
 tmp = g_strdup_printf("%s/subsystem", vbasedev->sysfsdev);
 subsys = realpath(tmp, NULL);
-g_free(tmp);
 is_mdev = subsys && (strcmp(subsys, "/sys/bus/mdev") == 0);
 free(subsys);
 
@@ -3029,7 +3029,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 
 ret = vfio_attach_device(name, vbasedev,
  pci_device_iommu_address_space(pdev), errp);
-g_free(name);
 if (ret) {
 goto error;
 }
-- 
2.45.1




[PULL 34/47] vfio/helpers: Make vfio_device_get_name() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h | 2 +-
 hw/vfio/ap.c  | 2 +-
 hw/vfio/ccw.c | 2 +-
 hw/vfio/helpers.c | 8 
 hw/vfio/pci.c | 2 +-
 hw/vfio/platform.c| 5 ++---
 6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
b712799caffdc950b593a87d569d7f5281976e2f..4cb1ab8645dcdf604f3c2bb29328668fd5eb7284
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -279,7 +279,7 @@ int vfio_get_dirty_bitmap(const VFIOContainerBase 
*bcontainer, uint64_t iova,
   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);
+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
 void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp);
 void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops,
   DeviceState *dev, bool ram_discard);
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
d8a9615feec065e98f53831912087d9878fdff9c..c12531a7886a2fe87598be0861fba5923bd2c206
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -158,7 +158,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 VFIODevice *vbasedev = >vdev;
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
1f578a3c75d975e12bbac52b3683e6fd193801cb..8850ca17c84632d278e27819cd52e104ed436d6c
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 }
 }
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
9edbc966884de12e7248af8d50d87f26c8cd2764..4b079dc383683a71d1d96507a0fb66a4bc3ba923
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -607,7 +607,7 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, 
uint16_t cap_type)
 return ret;
 }
 
-int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 {
 ERRP_GUARD();
 struct stat st;
@@ -616,7 +616,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 if (stat(vbasedev->sysfsdev, ) < 0) {
 error_setg_errno(errp, errno, "no such host device");
 error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev);
-return -errno;
+return false;
 }
 /* User may specify a name, e.g: VFIO platform device */
 if (!vbasedev->name) {
@@ -625,7 +625,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 } else {
 if (!vbasedev->iommufd) {
 error_setg(errp, "Use FD passing only with iommufd backend");
-return -EINVAL;
+return false;
 }
 /*
  * Give a name with fd so any function printing out vbasedev->name
@@ -636,7 +636,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
 }
 }
 
-return 0;
+return true;
 }
 
 void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
358da4497b8ab9b58b4f36252d1857279efbe521..aad012c34885ff2a5a39039777962236b41b
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2999,7 +2999,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 vdev->host.slot, vdev->host.function);
 }
 
-if (vfio_device_get_name(vbasedev, errp) < 0) {
+if (!vfio_device_get_name(vbasedev, errp)) {
 return;
 }
 
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 
3233ca86918a22b69265b83a1a9dec8b6b59380f..e1a32863d919fe09a743f5fb108f9787984d4378
 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -545,9 +545,8 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
  vbasedev->name);
 }
 
-ret = vfio_device_get_name(vbasedev, errp);
-if (ret) {
-return ret;
+if (!vfio_device_get_name(vbasedev, errp)) {
+return -EINVAL;
 }
 
 if (!vfio_attach_device(vbasedev->name, vbasedev,
-- 
2.45.1




[PULL 32/47] vfio/helpers: Use g_autofree in vfio_set_irq_signaling()

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Local pointer irq_set is freed before return from
vfio_set_irq_signaling().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/helpers.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 
47b4096c05ee8915c42b763fa18754c425aa00f6..1f3bdd9bf059beec186d87ba4772f2f6e34bc7d4
 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -111,7 +111,7 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
int action, int fd, Error **errp)
 {
 ERRP_GUARD();
-struct vfio_irq_set *irq_set;
+g_autofree struct vfio_irq_set *irq_set = NULL;
 int argsz, ret = 0;
 const char *name;
 int32_t *pfd;
@@ -130,7 +130,6 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
 if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
 ret = -errno;
 }
-g_free(irq_set);
 
 if (!ret) {
 return 0;
-- 
2.45.1




[PULL 43/47] vfio/pci: Use g_autofree for vfio_region_info pointer

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Pointer opregion is freed after vfio_pci_igd_opregion_init().
Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
c3323912dd773e80ad2dbbefc5d833e8a33cd147..8379d2284a20bed0c0bd24e46bbb39e321dc9767
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3143,7 +3143,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 
 if (!vdev->igd_opregion &&
 vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
-struct vfio_region_info *opregion;
+g_autofree struct vfio_region_info *opregion = NULL;
 
 if (vdev->pdev.qdev.hotplugged) {
 error_setg(errp,
@@ -3162,7 +3162,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 }
 
 ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);
-g_free(opregion);
 if (ret) {
 goto out_teardown;
 }
-- 
2.45.1




[PULL 23/47] vfio: Make VFIOIOMMUClass::add_window() and its wrapper return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Make VFIOIOMMUClass::add_window() and its wrapper function
vfio_container_add_section_window() return bool.

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-container-base.h | 12 ++--
 hw/vfio/common.c  |  2 +-
 hw/vfio/container-base.c  |  8 
 hw/vfio/spapr.c   | 16 
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/hw/vfio/vfio-container-base.h 
b/include/hw/vfio/vfio-container-base.h
index 
202e23cb6b800983b036bf3808c0ec38b1c363d0..2776481fc97ef5720b10a4e3b3e6deaa075ece75
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -76,9 +76,9 @@ int vfio_container_dma_map(VFIOContainerBase *bcontainer,
 int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
  hwaddr iova, ram_addr_t size,
  IOMMUTLBEntry *iotlb);
-int vfio_container_add_section_window(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp);
+bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp);
 void vfio_container_del_section_window(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer,
@@ -156,9 +156,9 @@ struct VFIOIOMMUClass {
 int (*pci_hot_reset)(VFIODevice *vbasedev, bool single);
 
 /* SPAPR specific */
-int (*add_window)(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp);
+bool (*add_window)(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp);
 void (*del_window)(VFIOContainerBase *bcontainer,
MemoryRegionSection *section);
 void (*release)(VFIOContainerBase *bcontainer);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
c04a259ffd7cfcfba480335bea1ddff787f47bdc..f9619a1dfbc689b10d70a60ce21b9b018f32391f
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -588,7 +588,7 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 return;
 }
 
-if (vfio_container_add_section_window(bcontainer, section, )) {
+if (!vfio_container_add_section_window(bcontainer, section, )) {
 goto fail;
 }
 
diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c
index 
26f4bb464a720c9895b35c7c9e01c84d6322c3c9..760d9d0622b2e847ecb3368c88df772efb06043f
 100644
--- a/hw/vfio/container-base.c
+++ b/hw/vfio/container-base.c
@@ -31,12 +31,12 @@ int vfio_container_dma_unmap(VFIOContainerBase *bcontainer,
 return bcontainer->ops->dma_unmap(bcontainer, iova, size, iotlb);
 }
 
-int vfio_container_add_section_window(VFIOContainerBase *bcontainer,
-  MemoryRegionSection *section,
-  Error **errp)
+bool vfio_container_add_section_window(VFIOContainerBase *bcontainer,
+   MemoryRegionSection *section,
+   Error **errp)
 {
 if (!bcontainer->ops->add_window) {
-return 0;
+return true;
 }
 
 return bcontainer->ops->add_window(bcontainer, section, errp);
diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c
index 
148b257c9ca6a0f957115f8060ddb50e377dfcb8..47b040f1bcca7dd0b5cf052d941b43541e98a3c5
 100644
--- a/hw/vfio/spapr.c
+++ b/hw/vfio/spapr.c
@@ -323,7 +323,7 @@ static int vfio_spapr_create_window(VFIOContainer 
*container,
 return 0;
 }
 
-static int
+static bool
 vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer,
 MemoryRegionSection *section,
 Error **errp)
@@ -351,13 +351,13 @@ vfio_spapr_container_add_section_window(VFIOContainerBase 
*bcontainer,
 error_setg(errp, "Container %p can't map guest IOVA region"
" 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container,
iova, end);
-return -EINVAL;
+return false;
 }
-return 0;
+return true;
 }
 
 if (container->iommu_type != VFIO_SPAPR_TCE_v2_IOMMU) {
-return 0;
+return true;
 }
 
 /* For now intersections are not allowed, we may relax this later */
@@ -373,14 +373,14 @@ vfio_spapr_container_add_section_window(VFIOContainerBase 
*bcontainer,
  

[PULL 15/47] qapi/vfio: Add VFIO migration QAPI event

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

Add a new QAPI event for VFIO migration. This event will be emitted when
a VFIO device changes its migration state, for example, during migration
or when stopping/starting the guest.

This event can be used by management applications to get updates on the
current state of the VFIO device for their own purposes.

Note that this new event is introduced since VFIO devices have a unique
set of migration states which cannot be described as accurately by other
existing events such as run state or migration status.

Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 MAINTAINERS   |  1 +
 qapi/qapi-schema.json |  1 +
 qapi/vfio.json| 67 +++
 qapi/meson.build  |  1 +
 4 files changed, 70 insertions(+)
 create mode 100644 qapi/vfio.json

diff --git a/MAINTAINERS b/MAINTAINERS
index 
1b79767d61960189eaa9d3d736e77722b8d5d9f0..448dc951c50913e7111d3bb6833a00acea7f50f1
 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2164,6 +2164,7 @@ F: hw/vfio/*
 F: include/hw/vfio/
 F: docs/igd-assign.txt
 F: docs/devel/migration/vfio.rst
+F: qapi/vfio.json
 
 vfio-ccw
 M: Eric Farman 
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 
5e33da7228f22abd20fa49f32c95e6a381ababd1..b1581988e4eba99cbe9ca53501918dd2d9bcfe44
 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -78,5 +78,6 @@
 { 'include': 'pci.json' }
 { 'include': 'stats.json' }
 { 'include': 'virtio.json' }
+{ 'include': 'vfio.json' }
 { 'include': 'cryptodev.json' }
 { 'include': 'cxl.json' }
diff --git a/qapi/vfio.json b/qapi/vfio.json
new file mode 100644
index 
..a0e5013188a4d16d842c8463d6e4c33742e06a97
--- /dev/null
+++ b/qapi/vfio.json
@@ -0,0 +1,67 @@
+# -*- Mode: Python -*-
+# vim: filetype=python
+#
+
+##
+# = VFIO devices
+##
+
+##
+# @VfioMigrationState:
+#
+# An enumeration of the VFIO device migration states.
+#
+# @stop: The device is stopped.
+#
+# @running: The device is running.
+#
+# @stop-copy: The device is stopped and its internal state is available
+# for reading.
+#
+# @resuming: The device is stopped and its internal state is available
+# for writing.
+#
+# @running-p2p: The device is running in the P2P quiescent state.
+#
+# @pre-copy: The device is running, tracking its internal state and its
+# internal state is available for reading.
+#
+# @pre-copy-p2p: The device is running in the P2P quiescent state,
+# tracking its internal state and its internal state is available
+# for reading.
+#
+# Since: 9.1
+##
+{ 'enum': 'VfioMigrationState',
+  'data': [ 'stop', 'running', 'stop-copy', 'resuming', 'running-p2p',
+'pre-copy', 'pre-copy-p2p' ],
+  'prefix': 'QAPI_VFIO_MIGRATION_STATE' }
+
+##
+# @VFIO_MIGRATION:
+#
+# This event is emitted when a VFIO device migration state is changed.
+#
+# @device-id: The device's id, if it has one.
+#
+# @qom-path: The device's QOM path.
+#
+# @device-state: The new changed device migration state.
+#
+# Since: 9.1
+#
+# Example:
+#
+# <- { "timestamp": { "seconds": 1713771323, "microseconds": 212268 },
+#  "event": "VFIO_MIGRATION",
+#  "data": {
+#  "device-id": "vfio_dev1",
+#  "qom-path": "/machine/peripheral/vfio_dev1",
+#  "device-state": "stop" } }
+##
+{ 'event': 'VFIO_MIGRATION',
+  'data': {
+  'device-id': 'str',
+  'qom-path': 'str',
+  'device-state': 'VfioMigrationState'
+  } }
diff --git a/qapi/meson.build b/qapi/meson.build
index 
c92af6e063a1b13ec3cce18e0572a859779b2ce4..e7bc54e5d047090aa2cdb823ef9ff4b892adb614
 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -52,6 +52,7 @@ qapi_all_modules = [
   'stats',
   'trace',
   'transaction',
+  'vfio',
   'virtio',
   'yank',
 ]
-- 
2.45.1




[PULL 14/47] vfio/pci: migration: Skip config space check for Vendor Specific Information in VSC during restore/load

2024-05-22 Thread Cédric Le Goater
From: Vinayak Kale 

In case of migration, during restore operation, qemu checks config space of the
pci device with the config space in the migration stream captured during save
operation. In case of config space data mismatch, restore operation is failed.

config space check is done in function get_pci_config_device(). By default VSC
(vendor-specific-capability) in config space is checked.

Due to qemu's config space check for VSC, live migration is broken across NVIDIA
vGPU devices in situation where source and destination host driver is different.
In this situation, Vendor Specific Information in VSC varies on the destination
to ensure vGPU feature capabilities exposed to the guest driver are compatible
with destination host.

If a vfio-pci device is migration capable and vfio-pci vendor driver is OK with
volatile Vendor Specific Info in VSC then qemu should exempt config space check
for Vendor Specific Info. It is vendor driver's responsibility to ensure that
VSC is consistent across migration. Here consistency could mean that VSC format
should be same on source and destination, however actual Vendor Specific Info
may not be byte-to-byte identical.

This patch skips the check for Vendor Specific Information in VSC for VFIO-PCI
device by clearing pdev->cmask[] offsets. Config space check is still enforced
for 3 byte VSC header. If cmask[] is not set for an offset, then qemu skips
config space check for that offset.

VSC check is skipped for machine types >= 9.1. The check would be enforced on
older machine types (<= 9.0).

Cc: Alex Williamson 
Cc: Michael S. Tsirkin 
Cc: Cédric Le Goater 
Signed-off-by: Vinayak Kale 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h |  1 +
 hw/core/machine.c |  1 +
 hw/vfio/pci.c | 26 ++
 3 files changed, 28 insertions(+)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
6e64a2654e690af11b72710530a41135b726e96f..92cd62d1159dbd47d878454f201f9c18112a7692
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -177,6 +177,7 @@ struct VFIOPCIDevice {
 OnOffAuto ramfb_migrate;
 bool defer_kvm_irq_routing;
 bool clear_parent_atomics_on_exit;
+bool skip_vsc_check;
 VFIODisplay *dpy;
 Notifier irqchip_change_notifier;
 };
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 
c7ceb1150147eb2bdd5f7ef583d00cee88f306cd..3442f31f9458c4e1bdde366aa40bfe3ad8b321a8
 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -35,6 +35,7 @@
 
 GlobalProperty hw_compat_9_0[] = {
 {"arm-cpu", "backcompat-cntfrq", "true" },
+{"vfio-pci", "skip-vsc-check", "false" },
 };
 const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
 
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
fc6e54e871508bb0e2a3ac9079a195c086531f21..4789d43c0f9cc7ef94b73adc815377f7222d8c57
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2134,6 +2134,28 @@ static void vfio_check_af_flr(VFIOPCIDevice *vdev, 
uint8_t pos)
 }
 }
 
+static int vfio_add_vendor_specific_cap(VFIOPCIDevice *vdev, int pos,
+uint8_t size, Error **errp)
+{
+PCIDevice *pdev = >pdev;
+
+pos = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, size, errp);
+if (pos < 0) {
+return pos;
+}
+
+/*
+ * Exempt config space check for Vendor Specific Information during
+ * restore/load.
+ * Config space check is still enforced for 3 byte VSC header.
+ */
+if (vdev->skip_vsc_check && size > 3) {
+memset(pdev->cmask + pos + 3, 0, size - 3);
+}
+
+return pos;
+}
+
 static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos, Error **errp)
 {
 ERRP_GUARD();
@@ -2202,6 +2224,9 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t 
pos, Error **errp)
 vfio_check_af_flr(vdev, pos);
 ret = pci_add_capability(pdev, cap_id, pos, size, errp);
 break;
+case PCI_CAP_ID_VNDR:
+ret = vfio_add_vendor_specific_cap(vdev, pos, size, errp);
+break;
 default:
 ret = pci_add_capability(pdev, cap_id, pos, size, errp);
 break;
@@ -3391,6 +3416,7 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
  TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
 #endif
+DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.45.1




[PULL 17/47] vfio/migration: Don't emit STOP_COPY VFIO migration QAPI event twice

2024-05-22 Thread Cédric Le Goater
From: Avihai Horon 

When migrating a VFIO device that supports pre-copy, it is transitioned
to STOP_COPY twice: once in vfio_vmstate_change() and second time in
vfio_save_complete_precopy().

The second transition is harmless, as it's a STOP_COPY->STOP_COPY no-op
transition. However, with the newly added VFIO migration QAPI event, the
STOP_COPY event is undesirably emitted twice.

Prevent this by returning early in vfio_migration_set_state() if
new_state is the same as current device state.

Note that the STOP_COPY transition in vfio_save_complete_precopy() is
essential for VFIO devices that don't support pre-copy, for migrating an
already stopped guest and for snapshots.

Signed-off-by: Avihai Horon 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
af579b868d7caa726fde1eeb73c832ebc3136a7a..56edffaf6251e28e39ef32991394697abb1b9e55
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -150,6 +150,10 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 g_strdup_printf("%s: Failed setting device state to %s.",
 vbasedev->name, mig_state_to_str(new_state));
 
+if (new_state == migration->device_state) {
+return 0;
+}
+
 feature->argsz = sizeof(buf);
 feature->flags =
 VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE;
-- 
2.45.1




[PULL 39/47] vfio/pci: Make vfio_populate_device() return a bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Since vfio_populate_device() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

By this chance, pass errp directly to vfio_populate_device() to
avoid calling error_propagate().

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
4fb5fd0c9f61627c402164fc4bed1868540350e0..46d3c618596d95266543e9a0ebc65c04d9a7cc5d
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2740,7 +2740,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 return 0;
 }
 
-static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
 struct vfio_region_info *reg_info;
@@ -2750,18 +2750,18 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 /* Sanity check device */
 if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PCI)) {
 error_setg(errp, "this isn't a PCI device");
-return;
+return false;
 }
 
 if (vbasedev->num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
 error_setg(errp, "unexpected number of io regions %u",
vbasedev->num_regions);
-return;
+return false;
 }
 
 if (vbasedev->num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {
 error_setg(errp, "unexpected number of irqs %u", vbasedev->num_irqs);
-return;
+return false;
 }
 
 for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) {
@@ -2773,7 +2773,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 
 if (ret) {
 error_setg_errno(errp, -ret, "failed to get region %d info", i);
-return;
+return false;
 }
 
 QLIST_INIT(>bars[i].quirks);
@@ -2783,7 +2783,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
VFIO_PCI_CONFIG_REGION_INDEX, _info);
 if (ret) {
 error_setg_errno(errp, -ret, "failed to get config info");
-return;
+return false;
 }
 
 trace_vfio_populate_device_config(vdev->vbasedev.name,
@@ -2804,7 +2804,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 if (ret) {
 error_append_hint(errp, "device does not support "
   "requested feature x-vga\n");
-return;
+return false;
 }
 }
 
@@ -2821,6 +2821,8 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 "Could not enable error recovery for the device",
 vbasedev->name);
 }
+
+return true;
 }
 
 static void vfio_pci_put_device(VFIOPCIDevice *vdev)
@@ -2977,7 +2979,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 VFIOPCIDevice *vdev = VFIO_PCI(pdev);
 VFIODevice *vbasedev = >vbasedev;
 char *subsys;
-Error *err = NULL;
 int i, ret;
 bool is_mdev;
 char uuid[UUID_STR_LEN];
@@ -3036,9 +3037,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 goto error;
 }
 
-vfio_populate_device(vdev, );
-if (err) {
-error_propagate(errp, err);
+if (!vfio_populate_device(vdev, errp)) {
 goto error;
 }
 
-- 
2.45.1




[PULL 38/47] vfio/pci: Make vfio_pci_relocate_msix() and vfio_msix_early_setup() return a bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Since vfio_pci_relocate_msix() and vfio_msix_early_setup() takes
an 'Error **' argument, best practices suggest to return a bool.
See the qapi/error.h Rules section.

By this chance, pass errp directly to vfio_msix_early_setup() to avoid
calling error_propagate().

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
12fb534d796f52724f365746c9c8c2491265f03d..4fb5fd0c9f61627c402164fc4bed1868540350e0
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1450,13 +1450,13 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice 
*vdev)
 }
 }
 
-static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)
 {
 int target_bar = -1;
 size_t msix_sz;
 
 if (!vdev->msix || vdev->msix_relo == OFF_AUTOPCIBAR_OFF) {
-return;
+return true;
 }
 
 /* The actual minimum size of MSI-X structures */
@@ -1479,7 +1479,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
 if (target_bar < 0) {
 error_setg(errp, "No automatic MSI-X relocation available for "
"device %04x:%04x", vdev->vendor_id, vdev->device_id);
-return;
+return false;
 }
 } else {
 target_bar = (int)(vdev->msix_relo - OFF_AUTOPCIBAR_BAR0);
@@ -1489,7 +1489,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
 if (vdev->bars[target_bar].ioport) {
 error_setg(errp, "Invalid MSI-X relocation BAR %d, "
"I/O port BAR", target_bar);
-return;
+return false;
 }
 
 /* Cannot use a BAR in the "shadow" of a 64-bit BAR */
@@ -1497,7 +1497,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  target_bar > 0 && vdev->bars[target_bar - 1].mem64) {
 error_setg(errp, "Invalid MSI-X relocation BAR %d, "
"consumed by 64-bit BAR %d", target_bar, target_bar - 1);
-return;
+return false;
 }
 
 /* 2GB max size for 32-bit BARs, cannot double if already > 1G */
@@ -1505,7 +1505,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
 !vdev->bars[target_bar].mem64) {
 error_setg(errp, "Invalid MSI-X relocation BAR %d, "
"no space to extend 32-bit BAR", target_bar);
-return;
+return false;
 }
 
 /*
@@ -1540,6 +1540,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
 
 trace_vfio_msix_relo(vdev->vbasedev.name,
  vdev->msix->table_bar, vdev->msix->table_offset);
+return true;
 }
 
 /*
@@ -1550,7 +1551,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  * need to first look for where the MSI-X table lives.  So we
  * unfortunately split MSI-X setup across two functions.
  */
-static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
 {
 uint8_t pos;
 uint16_t ctrl;
@@ -1562,25 +1563,25 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
 
 pos = pci_find_capability(>pdev, PCI_CAP_ID_MSIX);
 if (!pos) {
-return;
+return true;
 }
 
 if (pread(fd, , sizeof(ctrl),
   vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
 error_setg_errno(errp, errno, "failed to read PCI MSIX FLAGS");
-return;
+return false;
 }
 
 if (pread(fd, , sizeof(table),
   vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) {
 error_setg_errno(errp, errno, "failed to read PCI MSIX TABLE");
-return;
+return false;
 }
 
 if (pread(fd, , sizeof(pba),
   vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) {
 error_setg_errno(errp, errno, "failed to read PCI MSIX PBA");
-return;
+return false;
 }
 
 ctrl = le16_to_cpu(ctrl);
@@ -1598,7 +1599,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
 if (ret < 0) {
 error_setg_errno(errp, -ret, "failed to get MSI-X irq info");
 g_free(msix);
-return;
+return false;
 }
 
 msix->noresize = !!(irq_info.flags & VFIO_IRQ_INFO_NORESIZE);
@@ -1630,7 +1631,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
 error_setg(errp, "hardware reports invalid configuration, "
"

[PULL 36/47] vfio/ccw: Make vfio_ccw_get_region() return a bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Since vfio_populate_device() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
8850ca17c84632d278e27819cd52e104ed436d6c..2600e62e37238779800dc2b3a0bd315d7633017b
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -474,7 +474,7 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
 event_notifier_cleanup(notifier);
 }
 
-static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
+static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
 {
 VFIODevice *vdev = >vdev;
 struct vfio_region_info *info;
@@ -483,7 +483,7 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error 
**errp)
 /* Sanity check device */
 if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
 error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
-return;
+return false;
 }
 
 /*
@@ -493,13 +493,13 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, 
Error **errp)
 if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
 error_setg(errp, "vfio: too few regions (%u), expected at least %u",
vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
-return;
+return false;
 }
 
 ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, );
 if (ret) {
 error_setg_errno(errp, -ret, "vfio: Error getting config info");
-return;
+return false;
 }
 
 vcdev->io_region_size = info->size;
@@ -553,7 +553,7 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error 
**errp)
 g_free(info);
 }
 
-return;
+return true;
 
 out_err:
 g_free(vcdev->crw_region);
@@ -561,7 +561,7 @@ out_err:
 g_free(vcdev->async_cmd_region);
 g_free(vcdev->io_region);
 g_free(info);
-return;
+return false;
 }
 
 static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
@@ -597,8 +597,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
 goto out_attach_dev_err;
 }
 
-vfio_ccw_get_region(vcdev, );
-if (err) {
+if (!vfio_ccw_get_region(vcdev, )) {
 goto out_region_err;
 }
 
-- 
2.45.1




[PULL 07/47] memory: Add Error** argument to memory_get_xlat_addr()

2024-05-22 Thread Cédric Le Goater
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 
Reviewed-by: Eric Auger 
Reviewed-by: Avihai Horon 
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 
d417d7f363dbbca6553c449582a93d5da73cca40..9cdd64e9c69b63f9d27cebc2e8cb366e22ed7577
 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 address
+ * @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 
c7f274fb5c851e4c44498552891265018d2c5313..7313043f1d161ed0326b5ba3fa1085608eaf6740
 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,
-   _has_discard_manager);
+   _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, , NULL, _only)) {
+if (!vfio_get_xlat_addr(iotlb, , NULL, _only, _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, _addr, NULL)) {
+if (!vfio_get_xlat_addr(iotlb, NULL, _addr, NULL, _err)) {
+error_report_err(local_err);
 goto out_unlock;
 }
 
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 != _space_memory) {
 error_report("Wrong target AS \"%s\", only system memory is allowed",
@@ -227,7 +228,9 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, 
IOMMUTLBEntry *iotlb)
 if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
 bool read_only;
 
-if (!memory_get_xlat_addr(iot

[PULL 12/47] vfio/ccw: Use g_autofree variable in vfio_ccw_register_irq_notifier()

2024-05-22 Thread Cédric Le Goater
Reviewed-by: Markus Armbruster 
Reviewed-by: Eric Farman 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ccw.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 
90e4a534371684c08e112364e1537eb8979f73f4..6764388bc47a970329fce2233626ccb8178e0165
 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -384,7 +384,7 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
Error **errp)
 {
 VFIODevice *vdev = >vdev;
-struct vfio_irq_info *irq_info;
+g_autofree struct vfio_irq_info *irq_info = NULL;
 size_t argsz;
 int fd;
 EventNotifier *notifier;
@@ -421,14 +421,14 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
   irq_info) < 0 || irq_info->count < 1) {
 error_setg_errno(errp, errno, "vfio: Error getting irq info");
-goto out_free_info;
+return;
 }
 
 if (event_notifier_init(notifier, 0)) {
 error_setg_errno(errp, errno,
  "vfio: Unable to init event notifier for irq (%d)",
  irq);
-goto out_free_info;
+return;
 }
 
 fd = event_notifier_get_fd(notifier);
@@ -439,9 +439,6 @@ static void vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
 qemu_set_fd_handler(fd, NULL, NULL, vcdev);
 event_notifier_cleanup(notifier);
 }
-
-out_free_info:
-g_free(irq_info);
 }
 
 static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev,
-- 
2.45.1




[PULL 37/47] vfio/pci: Make vfio_intx_enable_kvm() return a bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

Since vfio_intx_enable_kvm() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
aad012c34885ff2a5a39039777962236b41b..12fb534d796f52724f365746c9c8c2491265f03d
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -116,7 +116,7 @@ static void vfio_intx_eoi(VFIODevice *vbasedev)
 vfio_unmask_single_irqindex(vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
 }
 
-static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
 {
 #ifdef CONFIG_KVM
 int irq_fd = event_notifier_get_fd(>intx.interrupt);
@@ -124,7 +124,7 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error 
**errp)
 if (vdev->no_kvm_intx || !kvm_irqfds_enabled() ||
 vdev->intx.route.mode != PCI_INTX_ENABLED ||
 !kvm_resamplefds_enabled()) {
-return;
+return true;
 }
 
 /* Get to a known interrupt state */
@@ -161,7 +161,7 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error 
**errp)
 
 trace_vfio_intx_enable_kvm(vdev->vbasedev.name);
 
-return;
+return true;
 
 fail_vfio:
 kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, >intx.interrupt,
@@ -171,6 +171,9 @@ fail_irqfd:
 fail:
 qemu_set_fd_handler(irq_fd, vfio_intx_interrupt, NULL, vdev);
 vfio_unmask_single_irqindex(>vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
+return false;
+#else
+return true;
 #endif
 }
 
@@ -226,8 +229,7 @@ static void vfio_intx_update(VFIOPCIDevice *vdev, 
PCIINTxRoute *route)
 return;
 }
 
-vfio_intx_enable_kvm(vdev, );
-if (err) {
+if (!vfio_intx_enable_kvm(vdev, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
@@ -302,8 +304,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
 return -errno;
 }
 
-vfio_intx_enable_kvm(vdev, );
-if (err) {
+if (!vfio_intx_enable_kvm(vdev, )) {
 warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 }
 
-- 
2.45.1




[PULL 42/47] vfio/pci: Make capability related functions return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

The functions operating on capability don't have a consistent return style.

Below functions are in bool-valued functions style:
vfio_msi_setup()
vfio_msix_setup()
vfio_add_std_cap()
vfio_add_capabilities()

Below two are integer-valued functions:
vfio_add_vendor_specific_cap()
vfio_setup_pcie_cap()

But the returned integer is only used for check succeed/failure.
Change them all to return bool so now all capability related
functions follow the coding standand in qapi/error.h to return
bool.

Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.c | 77 ---
 1 file changed, 36 insertions(+), 41 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
ab8f74299eab85e224a02f45d4b506e860b514f9..c3323912dd773e80ad2dbbefc5d833e8a33cd147
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1339,7 +1339,7 @@ static void vfio_disable_interrupts(VFIOPCIDevice *vdev)
 }
 }
 
-static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
+static bool vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
 {
 uint16_t ctrl;
 bool msi_64bit, msi_maskbit;
@@ -1349,7 +1349,7 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, 
Error **errp)
 if (pread(vdev->vbasedev.fd, , sizeof(ctrl),
   vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
 error_setg_errno(errp, errno, "failed reading MSI PCI_CAP_FLAGS");
-return -errno;
+return false;
 }
 ctrl = le16_to_cpu(ctrl);
 
@@ -1362,14 +1362,14 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, 
Error **errp)
 ret = msi_init(>pdev, pos, entries, msi_64bit, msi_maskbit, );
 if (ret < 0) {
 if (ret == -ENOTSUP) {
-return 0;
+return true;
 }
 error_propagate_prepend(errp, err, "msi_init failed: ");
-return ret;
+return false;
 }
 vdev->msi_cap_size = 0xa + (msi_maskbit ? 0xa : 0) + (msi_64bit ? 0x4 : 0);
 
-return 0;
+return true;
 }
 
 static void vfio_pci_fixup_msix_region(VFIOPCIDevice *vdev)
@@ -1644,7 +1644,7 @@ static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
 return vfio_pci_relocate_msix(vdev, errp);
 }
 
-static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
+static bool vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
 {
 int ret;
 Error *err = NULL;
@@ -1660,11 +1660,11 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int 
pos, Error **errp)
 if (ret < 0) {
 if (ret == -ENOTSUP) {
 warn_report_err(err);
-return 0;
+return true;
 }
 
 error_propagate(errp, err);
-return ret;
+return false;
 }
 
 /*
@@ -1698,7 +1698,7 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, 
Error **errp)
 memory_region_set_enabled(>pdev.msix_table_mmio, false);
 }
 
-return 0;
+return true;
 }
 
 static void vfio_teardown_msi(VFIOPCIDevice *vdev)
@@ -1977,8 +1977,8 @@ static void vfio_pci_disable_rp_atomics(VFIOPCIDevice 
*vdev)
 }
 }
 
-static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
-   Error **errp)
+static bool vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
+Error **errp)
 {
 uint16_t flags;
 uint8_t type;
@@ -1992,7 +1992,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
 
 error_setg(errp, "assignment of PCIe type 0x%x "
"devices is not currently supported", type);
-return -EINVAL;
+return false;
 }
 
 if (!pci_bus_is_express(pci_get_bus(>pdev))) {
@@ -2025,7 +2025,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
 }
 
 if (pci_bus_is_express(bus)) {
-return 0;
+return true;
 }
 
 } else if (pci_bus_is_root(pci_get_bus(>pdev))) {
@@ -2063,7 +2063,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
  * Legacy endpoints don't belong on the root complex.  Windows
  * seems to be happier with devices if we skip the capability.
  */
-return 0;
+return true;
 }
 
 } else {
@@ -2099,12 +2099,12 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
 pos = pci_add_capability(>pdev, PCI_CAP_ID_EXP, pos, size,
  errp);
 if (pos < 0) {
-return pos;
+return false;
 }
 
 vdev->pdev.exp.exp_cap = pos;
 
-return pos;
+return true;
 }
 
 static void vfio_check_pcie_flr(VFIOPCIDevice *vdev, uint8_t pos)
@@ -2137,14 +2137,14 @@ static void vfio_check_af_flr(VFIOPCIDevi

[PULL 28/47] vfio/cpr: Make vfio_cpr_register_container() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h | 2 +-
 hw/vfio/container.c   | 3 +--
 hw/vfio/cpr.c | 4 ++--
 hw/vfio/iommufd.c | 3 +--
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
e85817e65e65317d08bc2b17b738449198784796..b7bb4f5304addcdb03c971f27f99e5350ad0940a
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -229,7 +229,7 @@ void vfio_detach_device(VFIODevice *vbasedev);
 int vfio_kvm_device_add_fd(int fd, Error **errp);
 int vfio_kvm_device_del_fd(int fd, Error **errp);
 
-int vfio_cpr_register_container(VFIOContainerBase *bcontainer, Error **errp);
+bool vfio_cpr_register_container(VFIOContainerBase *bcontainer, Error **errp);
 void vfio_cpr_unregister_container(VFIOContainerBase *bcontainer);
 
 extern const MemoryRegionOps vfio_region_ops;
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
53649e397cab94f8a2b61e6d66f21d635556e04e..096cc972586df14a4a68074b7038a9661b1558e2
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -618,8 +618,7 @@ static bool vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 goto free_container_exit;
 }
 
-ret = vfio_cpr_register_container(bcontainer, errp);
-if (ret) {
+if (!vfio_cpr_register_container(bcontainer, errp)) {
 goto free_container_exit;
 }
 
diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c
index 
392c2dd95d14664bade0ae74655e91bc839504c0..87e51fcee176fe1fa93349f08e9f9ca84b474729
 100644
--- a/hw/vfio/cpr.c
+++ b/hw/vfio/cpr.c
@@ -25,12 +25,12 @@ static int vfio_cpr_reboot_notifier(NotifierWithReturn 
*notifier,
 return 0;
 }
 
-int vfio_cpr_register_container(VFIOContainerBase *bcontainer, Error **errp)
+bool vfio_cpr_register_container(VFIOContainerBase *bcontainer, Error **errp)
 {
 migration_add_notifier_mode(>cpr_reboot_notifier,
 vfio_cpr_reboot_notifier,
 MIG_MODE_CPR_REBOOT);
-return 0;
+return true;
 }
 
 void vfio_cpr_unregister_container(VFIOContainerBase *bcontainer)
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 
84c86b970e756d34b202d5b18ae51c30c730e092..6a446b16dcd64838dc9ebb6150cd5ed85ec6fef3
 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -396,8 +396,7 @@ found_container:
 goto err_listener_register;
 }
 
-ret = vfio_cpr_register_container(bcontainer, errp);
-if (ret) {
+if (!vfio_cpr_register_container(bcontainer, errp)) {
 goto err_listener_register;
 }
 
-- 
2.45.1




[PULL 04/47] vfio/migration: Add an Error** argument to vfio_migration_set_state()

2024-05-22 Thread Cédric Le Goater
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.

Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c | 81 +
 1 file changed, 52 insertions(+), 29 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4..43fed0dbdbe3415ae2dd68fbe45b302b85a80fa4
 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) +
@@ -92,6 +93,9 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 struct vfio_device_feature_mig_state *mig_state =
 (struct vfio_device_feature_mig_state *)feature->data;
 int ret;
+g_autofree char *error_prefix =
+g_strdup_printf("%s: Failed setting device state to %s.",
+vbasedev->name, mig_state_to_str(new_state));
 
 feature->argsz = sizeof(buf);
 feature->flags =
@@ -102,22 +106,24 @@ 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 Recover state is ERROR. Resetting device",
+ error_prefix);
 
 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 Setting device in recover state %s",
+ error_prefix, mig_state_to_str(recover_state));
 
 mig_state->device_state = recover_state;
 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
 ret = -errno;
+/*
+ * If setting the device in recover state fails, report
+ * the error here and propagate the first error.
+ */
 error_report(
 "%s: Failed setting device in recover state, err: %s. 
Resetting device",
  vbasedev->name, strerror(errno));
@@ -137,7 +143,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 +174,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(vbasedev, new_state,
-VFIO_DEVICE_STATE_ERROR);
+VFIO_DEVICE_STATE_ERROR, errp);
 }
 
 static int vfio_load_buffer(QEMUFile *f, VFIODevice *vbasedev,
@@ -399,10 +406,8 @@ static int vfio_save_setup(QEMUFile *f, void *opaque, 
Error **errp)
 switch (migration->device_state) {
 case VFIO_DEVICE_STATE_RUNNING:
 ret = vfio_migration_set_state(vbasedev, 
VFIO_DEVICE_STATE_PRE_COPY,
-   VFIO_DEVICE_STATE_RUNNING);
+   VFIO_DEVICE_STATE_RUNNING, errp);
 if (ret) {
-error_setg(errp, "%s: Failed to set new PRE_COPY state",
-   vbase

[PULL 41/47] vfio/pci: Make vfio_populate_vga() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h |  2 +-
 hw/vfio/igd.c |  2 +-
 hw/vfio/pci.c | 11 +--
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
a5ac9efd4bb6d4070cac02f3eeb156d1018cd20f..7914f019d5ed563ae7b60be17033aedacaaa00ff
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -225,7 +225,7 @@ bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const 
char *name);
 int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
 struct vfio_pci_hot_reset_info **info_p);
 
-int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
 
 int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
struct vfio_region_info *info,
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
b31ee79c60b5e567f84f561cfb63849960648340..ffe57c5954e5d05a57a66b2a3f0cc44fef508126
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -478,7 +478,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  * try to enable it.  Probably shouldn't be using legacy mode without VGA,
  * but also no point in us enabling VGA if disabled in hardware.
  */
-if (!(gmch & 0x2) && !vdev->vga && vfio_populate_vga(vdev, )) {
+if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, )) {
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 error_report("IGD device %s failed to enable VGA access, "
  "legacy mode disabled", vdev->vbasedev.name);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
7f35cb8a29176840412652afe5ab31cd52a1bf06..ab8f74299eab85e224a02f45d4b506e860b514f9
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2670,7 +2670,7 @@ static VFIODeviceOps vfio_pci_ops = {
 .vfio_load_config = vfio_pci_load_config,
 };
 
-int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
+bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 {
 VFIODevice *vbasedev = >vbasedev;
 struct vfio_region_info *reg_info;
@@ -2681,7 +2681,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 error_setg_errno(errp, -ret,
  "failed getting region info for VGA region index %d",
  VFIO_PCI_VGA_REGION_INDEX);
-return ret;
+return false;
 }
 
 if (!(reg_info->flags & VFIO_REGION_INFO_FLAG_READ) ||
@@ -2691,7 +2691,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
(unsigned long)reg_info->flags,
(unsigned long)reg_info->size);
 g_free(reg_info);
-return -EINVAL;
+return false;
 }
 
 vdev->vga = g_new0(VFIOVGA, 1);
@@ -2735,7 +2735,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  >vga->region[QEMU_PCI_VGA_IO_LO].mem,
  >vga->region[QEMU_PCI_VGA_IO_HI].mem);
 
-return 0;
+return true;
 }
 
 static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
@@ -2798,8 +2798,7 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 g_free(reg_info);
 
 if (vdev->features & VFIO_FEATURE_ENABLE_VGA) {
-ret = vfio_populate_vga(vdev, errp);
-if (ret) {
+if (!vfio_populate_vga(vdev, errp)) {
 error_append_hint(errp, "device does not support "
   "requested feature x-vga\n");
 return false;
-- 
2.45.1




[PULL 35/47] vfio/platform: Make vfio_populate_device() and vfio_base_device_init() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/platform.c | 40 +---
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 
e1a32863d919fe09a743f5fb108f9787984d4378..a85c199c76aa25559acf931621b84dd3dac6184d
 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -441,7 +441,7 @@ static int vfio_platform_hot_reset_multi(VFIODevice 
*vbasedev)
  * @errp: error object
  *
  */
-static int vfio_populate_device(VFIODevice *vbasedev, Error **errp)
+static bool vfio_populate_device(VFIODevice *vbasedev, Error **errp)
 {
 VFIOINTp *intp, *tmp;
 int i, ret = -1;
@@ -450,7 +450,7 @@ static int vfio_populate_device(VFIODevice *vbasedev, Error 
**errp)
 
 if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PLATFORM)) {
 error_setg(errp, "this isn't a platform device");
-return ret;
+return false;
 }
 
 vdev->regions = g_new0(VFIORegion *, vbasedev->num_regions);
@@ -487,12 +487,11 @@ static int vfio_populate_device(VFIODevice *vbasedev, 
Error **errp)
 irq.flags);
 intp = vfio_init_intp(vbasedev, irq, errp);
 if (!intp) {
-ret = -1;
 goto irq_err;
 }
 }
 }
-return 0;
+return true;
 irq_err:
 timer_del(vdev->mmap_timer);
 QLIST_FOREACH_SAFE(intp, >intp_list, next, tmp) {
@@ -507,7 +506,7 @@ reg_error:
 g_free(vdev->regions[i]);
 }
 g_free(vdev->regions);
-return ret;
+return false;
 }
 
 /* specialized functions for VFIO Platform devices */
@@ -527,10 +526,8 @@ static VFIODeviceOps vfio_platform_ops = {
  * fd retrieval, resource query.
  * Precondition: the device name must be initialized
  */
-static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp)
+static bool vfio_base_device_init(VFIODevice *vbasedev, Error **errp)
 {
-int ret;
-
 /* @fd takes precedence over @sysfsdev which takes precedence over @host */
 if (vbasedev->fd < 0 && vbasedev->sysfsdev) {
 g_free(vbasedev->name);
@@ -538,7 +535,7 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
 } else if (vbasedev->fd < 0) {
 if (!vbasedev->name || strchr(vbasedev->name, '/')) {
 error_setg(errp, "wrong host device name");
-return -EINVAL;
+return false;
 }
 
 vbasedev->sysfsdev = g_strdup_printf("/sys/bus/platform/devices/%s",
@@ -546,20 +543,20 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
 }
 
 if (!vfio_device_get_name(vbasedev, errp)) {
-return -EINVAL;
+return false;
 }
 
 if (!vfio_attach_device(vbasedev->name, vbasedev,
 _space_memory, errp)) {
-return -EINVAL;
+return false;
 }
 
-ret = vfio_populate_device(vbasedev, errp);
-if (ret) {
-vfio_detach_device(vbasedev);
+if (vfio_populate_device(vbasedev, errp)) {
+return true;
 }
 
-return ret;
+vfio_detach_device(vbasedev);
+return false;
 }
 
 /**
@@ -576,7 +573,7 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
 VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
 SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
 VFIODevice *vbasedev = >vbasedev;
-int i, ret;
+int i;
 
 qemu_mutex_init(>intp_mutex);
 
@@ -584,9 +581,8 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
 vbasedev->sysfsdev : vbasedev->name,
 vdev->compat);
 
-ret = vfio_base_device_init(vbasedev, errp);
-if (ret) {
-goto out;
+if (!vfio_base_device_init(vbasedev, errp)) {
+goto init_err;
 }
 
 if (!vdev->compat) {
@@ -618,11 +614,9 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
 }
 sysbus_init_mmio(sbdev, vdev->regions[i]->mem);
 }
-out:
-if (!ret) {
-return;
-}
+return;
 
+init_err:
 if (vdev->vbasedev.name) {
 error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 } else {
-- 
2.45.1




[PULL 11/47] vfio/ap: Make vfio_ap_register_irq_notifier() return a bool

2024-05-22 Thread Cédric Le Goater
Since vfio_ap_register_irq_notifier() takes and 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h Rules
section.

Reviewed-by: Markus Armbruster 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ap.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
03f8ffaa5e2bf13cf8daa2f44aa4cf17809abd94..8bb024e2fde4a1d72346dee4b662d762374326b9
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -70,7 +70,7 @@ static void vfio_ap_req_notifier_handler(void *opaque)
 }
 }
 
-static void vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev,
+static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev,
   unsigned int irq, Error **errp)
 {
 int fd;
@@ -87,13 +87,13 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 break;
 default:
 error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
-return;
+return false;
 }
 
 if (vdev->num_irqs < irq + 1) {
 error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
irq, vdev->num_irqs);
-return;
+return false;
 }
 
 argsz = sizeof(*irq_info);
@@ -104,14 +104,14 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
   irq_info) < 0 || irq_info->count < 1) {
 error_setg_errno(errp, errno, "vfio: Error getting irq info");
-return;
+return false;
 }
 
 if (event_notifier_init(notifier, 0)) {
 error_setg_errno(errp, errno,
  "vfio: Unable to init event notifier for irq (%d)",
  irq);
-return;
+return false;
 }
 
 fd = event_notifier_get_fd(notifier);
@@ -122,6 +122,8 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 qemu_set_fd_handler(fd, NULL, NULL, vapdev);
 event_notifier_cleanup(notifier);
 }
+
+return true;
 }
 
 static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev,
@@ -167,8 +169,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 goto error;
 }
 
-vfio_ap_register_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX, );
-if (err) {
+if (!vfio_ap_register_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX, )) {
 /*
  * Report this error, but do not make it a failing condition.
  * Lack of this IRQ in the host does not prevent normal operation.
-- 
2.45.1




[PULL 10/47] vfio/ap: Use g_autofree variable in vfio_ap_register_irq_notifier()

2024-05-22 Thread Cédric Le Goater
Reviewed-by: Markus Armbruster 
Reviewed-by: Anthony Krowiak 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/ap.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
7c4caa5938636937680fec87e999249ac84a4498..03f8ffaa5e2bf13cf8daa2f44aa4cf17809abd94
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -77,7 +77,7 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 size_t argsz;
 IOHandler *fd_read;
 EventNotifier *notifier;
-struct vfio_irq_info *irq_info;
+g_autofree struct vfio_irq_info *irq_info = NULL;
 VFIODevice *vdev = >vdev;
 
 switch (irq) {
@@ -104,14 +104,14 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
   irq_info) < 0 || irq_info->count < 1) {
 error_setg_errno(errp, errno, "vfio: Error getting irq info");
-goto out_free_info;
+return;
 }
 
 if (event_notifier_init(notifier, 0)) {
 error_setg_errno(errp, errno,
  "vfio: Unable to init event notifier for irq (%d)",
  irq);
-goto out_free_info;
+return;
 }
 
 fd = event_notifier_get_fd(notifier);
@@ -122,10 +122,6 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
 qemu_set_fd_handler(fd, NULL, NULL, vapdev);
 event_notifier_cleanup(notifier);
 }
-
-out_free_info:
-g_free(irq_info);
-
 }
 
 static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev,
-- 
2.45.1




[PULL 08/47] vfio: Add Error** argument to .get_dirty_bitmap() handler

2024-05-22 Thread Cédric Le Goater
Let the callers do the error reporting. Add documentation while at it.

Reviewed-by: Eric Auger 
Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---
 include/hw/vfio/vfio-common.h |  5 +--
 include/hw/vfio/vfio-container-base.h | 19 +++--
 hw/vfio/common.c  | 60 +--
 hw/vfio/container-base.c  |  6 +--
 hw/vfio/container.c   | 14 ---
 5 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
3ff633ad3b395e953a55683f5f0308bca50af3dd..b6ac24953667bc5f72f28480a6bf0f4722069cb9
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -273,10 +273,9 @@ vfio_devices_all_running_and_mig_active(const 
VFIOContainerBase *bcontainer);
 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);
+VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
 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..b04057ad1aff73d974ecec718d0fe45f7a930b59
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -84,8 +84,7 @@ void vfio_container_del_section_window(VFIOContainerBase 
*bcontainer,
 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);
+   VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
 
 void vfio_container_init(VFIOContainerBase *bcontainer,
  VFIOAddressSpace *space,
@@ -138,9 +137,21 @@ struct VFIOIOMMUClass {
  */
 int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
bool start, Error **errp);
+/**
+ * @query_dirty_bitmap
+ *
+ * Get bitmap of dirty pages from container
+ *
+ * @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);
+VFIOBitmap *vbmap, 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 
7313043f1d161ed0326b5ba3fa1085608eaf6740..1fbd10801d35079341a833fa68a43de2b758cde0
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1140,8 +1140,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)
+ VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp)
 {
 VFIODevice *vbasedev;
 int ret;
@@ -1150,10 +1149,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 (%s)",
- vbasedev->name, iova, size, ret, strerror(-ret));
+error_setg_errno(errp, -ret,
+ "%s: Failed to get DMA logging report, iova: "
+ "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx,
+ vbasedev->name, iova, size);
 
 return ret;
 }
@@ -1163,7 +1162,7 @@ int vfio_devices_query_dirty_bitmap(const 
VFIOContainerBase *bcontainer,
 }

[PULL 44/47] vfio/pci-quirks: Make vfio_pci_igd_opregion_init() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h| 6 +++---
 hw/vfio/igd.c| 3 +--
 hw/vfio/pci-quirks.c | 8 
 hw/vfio/pci.c| 3 +--
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
7914f019d5ed563ae7b60be17033aedacaaa00ff..f1586810726584ecfc35ef685646faacabefbec0
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -227,9 +227,9 @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
 
 bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
 
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
-   struct vfio_region_info *info,
-   Error **errp);
+bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
+struct vfio_region_info *info,
+Error **errp);
 
 void vfio_display_reset(VFIOPCIDevice *vdev);
 bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 
ffe57c5954e5d05a57a66b2a3f0cc44fef508126..402fc5ce1da966fda1340f328e0611cb1a2a0635
 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -502,8 +502,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 }
 
 /* Setup OpRegion access */
-ret = vfio_pci_igd_opregion_init(vdev, opregion, );
-if (ret) {
+if (!vfio_pci_igd_opregion_init(vdev, opregion, )) {
 error_append_hint(, "IGD legacy mode disabled\n");
 error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
 goto out;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 
496fd1ee86bd2d53bf094860e330f4f0a5081365..ca27917159785f760f688c8db0a9ac492080d74b
 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1169,8 +1169,8 @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice 
*vdev, int nr)
  * the table and to write the base address of that memory to the ASLS register
  * of the IGD device.
  */
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
-   struct vfio_region_info *info, Error **errp)
+bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
+struct vfio_region_info *info, Error **errp)
 {
 int ret;
 
@@ -1181,7 +1181,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
 error_setg(errp, "failed to read IGD OpRegion");
 g_free(vdev->igd_opregion);
 vdev->igd_opregion = NULL;
-return -EINVAL;
+return false;
 }
 
 /*
@@ -1206,7 +1206,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
 pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
 pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
 
-return 0;
+return true;
 }
 
 /*
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
8379d2284a20bed0c0bd24e46bbb39e321dc9767..76a3931dba1da1a638ae574825fe9dfe1390b21f
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3161,8 +3161,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 goto out_teardown;
 }
 
-ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);
-if (ret) {
+if (!vfio_pci_igd_opregion_init(vdev, opregion, errp)) {
 goto out_teardown;
 }
 }
-- 
2.45.1




[PULL 31/47] vfio/display: Make vfio_display_*() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/pci.h |  2 +-
 hw/vfio/display.c | 20 ++--
 hw/vfio/pci.c |  3 +--
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 
92cd62d1159dbd47d878454f201f9c18112a7692..a5ac9efd4bb6d4070cac02f3eeb156d1018cd20f
 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -232,7 +232,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
Error **errp);
 
 void vfio_display_reset(VFIOPCIDevice *vdev);
-int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
 void vfio_display_finalize(VFIOPCIDevice *vdev);
 
 extern const VMStateDescription vfio_display_vmstate;
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 
d28b724102d5970cb2b9dc7464dc7575b6f441d9..661e921616f4b85613d5f6053c30348a4ee6cbd2
 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -348,11 +348,11 @@ static const GraphicHwOps vfio_display_dmabuf_ops = {
 .ui_info= vfio_display_edid_ui_info,
 };
 
-static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
 {
 if (!display_opengl) {
 error_setg(errp, "vfio-display-dmabuf: opengl not available");
-return -1;
+return false;
 }
 
 vdev->dpy = g_new0(VFIODisplay, 1);
@@ -362,11 +362,11 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, 
Error **errp)
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
 if (!vdev->dpy->ramfb) {
-return -EINVAL;
+return false;
 }
 }
 vfio_display_edid_init(vdev);
-return 0;
+return true;
 }
 
 static void vfio_display_dmabuf_exit(VFIODisplay *dpy)
@@ -483,7 +483,7 @@ static const GraphicHwOps vfio_display_region_ops = {
 .gfx_update = vfio_display_region_update,
 };
 
-static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
 {
 vdev->dpy = g_new0(VFIODisplay, 1);
 vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
@@ -492,10 +492,10 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, 
Error **errp)
 if (vdev->enable_ramfb) {
 vdev->dpy->ramfb = ramfb_setup(errp);
 if (!vdev->dpy->ramfb) {
-return -EINVAL;
+return false;
 }
 }
-return 0;
+return true;
 }
 
 static void vfio_display_region_exit(VFIODisplay *dpy)
@@ -510,7 +510,7 @@ static void vfio_display_region_exit(VFIODisplay *dpy)
 
 /* -- */
 
-int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
+bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
 {
 struct vfio_device_gfx_plane_info probe;
 int ret;
@@ -533,11 +533,11 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
 
 if (vdev->display == ON_OFF_AUTO_AUTO) {
 /* not an error in automatic mode */
-return 0;
+return true;
 }
 
 error_setg(errp, "vfio: device doesn't support any (known) display 
method");
-return -1;
+return false;
 }
 
 void vfio_display_finalize(VFIOPCIDevice *vdev)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 
c1adef5cf8fb241df510514610f05c8a0d51a9f9..a447013a1da90f534ab07409c6ca39263f7f6f88
 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3200,8 +3200,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 }
 
 if (vdev->display != ON_OFF_AUTO_OFF) {
-ret = vfio_display_probe(vdev, errp);
-if (ret) {
+if (!vfio_display_probe(vdev, errp)) {
 goto out_deregister;
 }
 }
-- 
2.45.1




[PULL 09/47] vfio: Also trace event failures in vfio_save_complete_precopy()

2024-05-22 Thread Cédric Le Goater
vfio_save_complete_precopy() currently returns before doing the trace
event. Change that.

Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
5d91364f3bbc34060d84b4b4b1823eadbc7b12bf..c4403a38ddb5e7e09fbcde0ad4132653ecaf0d24
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -589,9 +589,6 @@ static int vfio_save_complete_precopy(QEMUFile *f, void 
*opaque)
 
 qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
 ret = qemu_file_get_error(f);
-if (ret) {
-return ret;
-}
 
 trace_vfio_save_complete_precopy(vbasedev->name, ret);
 
-- 
2.45.1




[PULL 25/47] vfio/container: Make vfio_set_iommu() return bool

2024-05-22 Thread Cédric Le Goater
From: Zhenzhong Duan 

This is to follow the coding standand to return bool if 'Error **'
is used to pass error.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
Reviewed-by: Cédric Le Goater 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/container.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 
802828ddff061fef25b8e4c997a68348d4be9892..e330b2897423b97fee467884f4237669ceff4756
 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -393,21 +393,20 @@ static const VFIOIOMMUClass *vfio_get_iommu_class(int 
iommu_type, Error **errp)
 return VFIO_IOMMU_CLASS(klass);
 }
 
-static int vfio_set_iommu(VFIOContainer *container, int group_fd,
-  VFIOAddressSpace *space, Error **errp)
+static bool vfio_set_iommu(VFIOContainer *container, int group_fd,
+   VFIOAddressSpace *space, Error **errp)
 {
-int iommu_type, ret;
+int iommu_type;
 const VFIOIOMMUClass *vioc;
 
 iommu_type = vfio_get_iommu_type(container, errp);
 if (iommu_type < 0) {
-return iommu_type;
+return false;
 }
 
-ret = ioctl(group_fd, VFIO_GROUP_SET_CONTAINER, >fd);
-if (ret) {
+if (ioctl(group_fd, VFIO_GROUP_SET_CONTAINER, >fd)) {
 error_setg_errno(errp, errno, "Failed to set group container");
-return -errno;
+return false;
 }
 
 while (ioctl(container->fd, VFIO_SET_IOMMU, iommu_type)) {
@@ -422,7 +421,7 @@ static int vfio_set_iommu(VFIOContainer *container, int 
group_fd,
 continue;
 }
 error_setg_errno(errp, errno, "Failed to set iommu for container");
-return -errno;
+return false;
 }
 
 container->iommu_type = iommu_type;
@@ -430,11 +429,11 @@ static int vfio_set_iommu(VFIOContainer *container, int 
group_fd,
 vioc = vfio_get_iommu_class(iommu_type, errp);
 if (!vioc) {
 error_setg(errp, "No available IOMMU models");
-return -EINVAL;
+return false;
 }
 
 vfio_container_init(>bcontainer, space, vioc);
-return 0;
+return true;
 }
 
 static int vfio_get_iommu_info(VFIOContainer *container,
@@ -615,8 +614,7 @@ static bool vfio_connect_container(VFIOGroup *group, 
AddressSpace *as,
 container->fd = fd;
 bcontainer = >bcontainer;
 
-ret = vfio_set_iommu(container, group->fd, space, errp);
-if (ret) {
+if (!vfio_set_iommu(container, group->fd, space, errp)) {
 goto free_container_exit;
 }
 
-- 
2.45.1




[PULL 02/47] vfio: Add Error** argument to vfio_devices_dma_logging_start()

2024-05-22 Thread Cédric Le Goater
This allows to update the Error argument of the VFIO log_global_start()
handler. Errors for container based logging will also be propagated to
qemu_savevm_state_setup() when the ram save_setup() handler is executed.
Also, errors from vfio_container_set_dirty_page_tracking() are now
collected and reported.

The vfio_set_migration_error() call becomes redundant in
vfio_listener_log_global_start(). Remove it.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/common.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
485e53916491f1164d29e739fb7106c0c77df737..b5102f54a6474a50c6366e8fbce23812d55e384e
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1027,7 +1027,8 @@ static void vfio_device_feature_dma_logging_start_destroy(
 g_free(feature);
 }
 
-static int vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer)
+static int vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer,
+  Error **errp)
 {
 struct vfio_device_feature *feature;
 VFIODirtyRanges ranges;
@@ -1038,6 +1039,7 @@ static int 
vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer)
 feature = vfio_device_feature_dma_logging_start_create(bcontainer,
);
 if (!feature) {
+error_setg_errno(errp, errno, "Failed to prepare DMA logging");
 return -errno;
 }
 
@@ -1049,8 +1051,8 @@ static int 
vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer)
 ret = ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature);
 if (ret) {
 ret = -errno;
-error_report("%s: Failed to start DMA logging, err %d (%s)",
- vbasedev->name, ret, strerror(errno));
+error_setg_errno(errp, errno, "%s: Failed to start DMA logging",
+ vbasedev->name);
 goto out;
 }
 vbasedev->dirty_tracking = true;
@@ -1069,20 +1071,19 @@ out:
 static bool vfio_listener_log_global_start(MemoryListener *listener,
Error **errp)
 {
+ERRP_GUARD();
 VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase,
  listener);
 int ret;
 
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
-ret = vfio_devices_dma_logging_start(bcontainer);
+ret = vfio_devices_dma_logging_start(bcontainer, errp);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, true, NULL);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, true, errp);
 }
 
 if (ret) {
-error_report("vfio: Could not start dirty page tracking, err: %d (%s)",
- ret, strerror(-ret));
-vfio_set_migration_error(ret);
+error_prepend(errp, "vfio: Could not start dirty page tracking - ");
 }
 return !ret;
 }
@@ -1091,17 +1092,20 @@ static void 
vfio_listener_log_global_stop(MemoryListener *listener)
 {
 VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase,
  listener);
+Error *local_err = NULL;
 int ret = 0;
 
 if (vfio_devices_all_device_dirty_tracking(bcontainer)) {
 vfio_devices_dma_logging_stop(bcontainer);
 } else {
-ret = vfio_container_set_dirty_page_tracking(bcontainer, false, NULL);
+ret = vfio_container_set_dirty_page_tracking(bcontainer, false,
+ _err);
 }
 
 if (ret) {
-error_report("vfio: Could not stop dirty page tracking, err: %d (%s)",
- ret, strerror(-ret));
+error_prepend(_err,
+  "vfio: Could not stop dirty page tracking - ");
+error_report_err(local_err);
 vfio_set_migration_error(ret);
 }
 }
-- 
2.45.1




[PULL 06/47] vfio: Reverse test on vfio_get_xlat_addr()

2024-05-22 Thread Cédric Le Goater
It will simplify the changes coming after.

Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
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 
2c97de6c730d963d961bf81c0831326c0e25afa7..c7f274fb5c851e4c44498552891265018d2c5313
 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, _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, _addr, NULL)) {
+goto out_unlock;
 }
+
+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_unlock:
 rcu_read_unlock();
 
 out:
-- 
2.45.1




[PULL 00/47] vfio queue

2024-05-22 Thread Cédric Le Goater
The following changes since commit 85ef20f1673feaa083f4acab8cf054df77b0dbed:

  Merge tag 'pull-maintainer-may24-160524-2' of https://gitlab.com/stsquad/qemu 
into staging (2024-05-16 10:02:56 +0200)

are available in the Git repository at:

  https://github.com/legoater/qemu/ tags/pull-vfio-20240522

for you to fetch changes up to b4e1670c494165d4186930d56f692857f4fec89b:

  vfio/igd: Use g_autofree in vfio_probe_igd_bar4_quirk() (2024-05-22 10:04:22 
+0200)


vfio queue:

* Improvement of error reporting during migration
* Removed Vendor Specific Capability check on newer machine
* Addition of a VFIO migration QAPI event
* Changed prototype of routines using an error parameter to return bool
* Several cleanups regarding autofree variables


Avihai Horon (4):
  qapi/vfio: Add VFIO migration QAPI event
  vfio/migration: Emit VFIO migration QAPI event
  vfio/migration: Don't emit STOP_COPY VFIO migration QAPI event twice
  vfio/migration: Enhance VFIO migration state tracing

Cédric Le Goater (13):
  vfio: Add Error** argument to .set_dirty_page_tracking() handler
  vfio: Add Error** argument to vfio_devices_dma_logging_start()
  migration: Extend migration_file_set_error() with Error* argument
  vfio/migration: Add an Error** argument to vfio_migration_set_state()
  vfio/migration: Add Error** argument to .vfio_save_config() handler
  vfio: Reverse test on vfio_get_xlat_addr()
  memory: Add Error** argument to memory_get_xlat_addr()
  vfio: Add Error** argument to .get_dirty_bitmap() handler
  vfio: Also trace event failures in vfio_save_complete_precopy()
  vfio/ap: Use g_autofree variable in vfio_ap_register_irq_notifier()
  vfio/ap: Make vfio_ap_register_irq_notifier() return a bool
  vfio/ccw: Use g_autofree variable in vfio_ccw_register_irq_notifier()
  vfio/ccw: Make vfio_ccw_register_irq_notifier() return a bool

Vinayak Kale (1):
  vfio/pci: migration: Skip config space check for Vendor Specific 
Information in VSC during restore/load

Zhenzhong Duan (29):
  vfio/pci: Use g_autofree in vfio_realize
  vfio/pci: Use g_autofree in iommufd_cdev_get_info_iova_range()
  vfio: Make VFIOIOMMUClass::attach_device() and its wrapper return bool
  vfio: Make VFIOIOMMUClass::setup() return bool
  vfio: Make VFIOIOMMUClass::add_window() and its wrapper return bool
  vfio/container: Make vfio_connect_container() return bool
  vfio/container: Make vfio_set_iommu() return bool
  vfio/container: Make vfio_get_device() return bool
  vfio/iommufd: Make iommufd_cdev_*() return bool
  vfio/cpr: Make vfio_cpr_register_container() return bool
  backends/iommufd: Make iommufd_backend_*() return bool
  vfio/display: Fix error path in call site of ramfb_setup()
  vfio/display: Make vfio_display_*() return bool
  vfio/helpers: Use g_autofree in vfio_set_irq_signaling()
  vfio/helpers: Make vfio_set_irq_signaling() return bool
  vfio/helpers: Make vfio_device_get_name() return bool
  vfio/platform: Make vfio_populate_device() and vfio_base_device_init() 
return bool
  vfio/ccw: Make vfio_ccw_get_region() return a bool
  vfio/pci: Make vfio_intx_enable_kvm() return a bool
  vfio/pci: Make vfio_pci_relocate_msix() and vfio_msix_early_setup() 
return a bool
  vfio/pci: Make vfio_populate_device() return a bool
  vfio/pci: Make vfio_intx_enable() return bool
  vfio/pci: Make vfio_populate_vga() return bool
  vfio/pci: Make capability related functions return bool
  vfio/pci: Use g_autofree for vfio_region_info pointer
  vfio/pci-quirks: Make vfio_pci_igd_opregion_init() return bool
  vfio/pci-quirks: Make vfio_add_*_cap() return bool
  vfio: Use g_autofree in all call site of vfio_get_region_info()
  vfio/igd: Use g_autofree in vfio_probe_igd_bar4_quirk()

 MAINTAINERS   |   1 +
 qapi/qapi-schema.json |   1 +
 qapi/vfio.json|  67 
 hw/vfio/pci.h |  13 +-
 include/exec/memory.h |  15 +-
 include/hw/vfio/vfio-common.h |  43 --
 include/hw/vfio/vfio-container-base.h |  55 +--
 include/migration/misc.h  |   2 +-
 include/sysemu/iommufd.h  |   6 +-
 backends/iommufd.c|  29 ++--
 hw/core/machine.c |   1 +
 hw/vfio/ap.c  |  35 ++---
 hw/vfio/ccw.c |  56 +++
 hw/vfio/common.c  | 119 +--
 hw/vfio/container-base.c  |  18 +--
 hw/vfio/container.c   | 101 ++--
 hw/vfio/cpr.c |   4 +-
 hw/vfio/display.c |  22 ++-
 hw/vfio/helpers.c |  36 ++---
 hw/vfio/igd.c

Re: [PATCH v2 00/20] VFIO: misc cleanups part2

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:39, Zhenzhong Duan wrote:

Hi

This is the last round of cleanup series to change functions in hw/vfio/
to return bool when the error is passed through errp parameter.

The first round is at
https://lists.gnu.org/archive/html/qemu-devel/2024-05/msg01147.html

I see Cédric is also working on some migration stuff cleanup,
so didn't touch migration.c, but all other files in hw/vfio/ are cleanup now.

Patch1 and patch20 are fix patch, all others are cleanup patches.

Test done on x86 platform:
vfio device hotplug/unplug with different backend
reboot

This series is rebased to https://github.com/legoater/qemu/tree/vfio-next


Patches 01-18 applied to vfio-next.

Thanks,

C.






Re: [PATCH v2 20/20] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-22 Thread Cédric Le Goater

On 5/22/24 10:05, Duan, Zhenzhong wrote:

Hi Cédric,


-Original Message-
From: Cédric Le Goater 
Sent: Wednesday, May 22, 2024 3:52 PM
To: Duan, Zhenzhong ; qemu-
de...@nongnu.org
Cc: alex.william...@redhat.com; eric.au...@redhat.com; Peng, Chao P
; Eric Farman ; Matthew
Rosato ; Thomas Huth ;
open list:vfio-ccw 
Subject: Re: [PATCH v2 20/20] vfio/ccw: Fix the missed unrealize() call in
error path

On 5/22/24 06:40, Zhenzhong Duan wrote:

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a

file handle")

Signed-off-by: Zhenzhong Duan 


If the realize handler fails, the unrealize handler should be called.
See device_set_realized(). We should be fine without IMO.


Do you mean when vfio_ccw_realize() fails, vfio_ccw_unrealize() will be called?
Looked into device_set_realized(), I didn't see where vfio_ccw_unrealize() was 
called.
Do I misunderstand?


no, it's me. I thought it was called in the failure path :/ Anyhow, let's keep
this patch for a ccw series.


Thanks,

C.





Thanks
Zhenzhong




Thanks,

C.




---
   hw/vfio/ccw.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 168c9e5973..161704cd7b 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -589,7 +589,7 @@ static void vfio_ccw_realize(DeviceState *dev,

Error **errp)

   }

   if (!vfio_device_get_name(vbasedev, errp)) {
-return;
+goto out_unrealize;
   }

   if (!vfio_attach_device(cdev->mdevid, vbasedev,
@@ -633,6 +633,7 @@ out_region_err:
   vfio_detach_device(vbasedev);
   out_attach_dev_err:
   g_free(vbasedev->name);
+out_unrealize:
   if (cdc->unrealize) {
   cdc->unrealize(cdev);
   }







Re: [PATCH v2 20/20] vfio/ccw: Fix the missed unrealize() call in error path

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

When get name failed, we should call unrealize() so that
vfio_ccw_realize() is self contained.

Fixes: 909a6254eda ("vfio/ccw: Make vfio cdev pre-openable by passing a file 
handle")
Signed-off-by: Zhenzhong Duan 


If the realize handler fails, the unrealize handler should be called.
See device_set_realized(). We should be fine without IMO.


Thanks,

C.


 

---
  hw/vfio/ccw.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 168c9e5973..161704cd7b 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -589,7 +589,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  }
  
  if (!vfio_device_get_name(vbasedev, errp)) {

-return;
+goto out_unrealize;
  }
  
  if (!vfio_attach_device(cdev->mdevid, vbasedev,

@@ -633,6 +633,7 @@ out_region_err:
  vfio_detach_device(vbasedev);
  out_attach_dev_err:
  g_free(vbasedev->name);
+out_unrealize:
  if (cdc->unrealize) {
  cdc->unrealize(cdev);
  }





Re: [PATCH v2 19/20] vfio/ccw: Drop local @err in vfio_ccw_realize()

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

Use @errp to fetch error information directly and drop the local
variable @err.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 
---
  hw/vfio/ccw.c | 21 ++---
  1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 2600e62e37..168c9e5973 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -574,17 +574,17 @@ static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
  
  static void vfio_ccw_realize(DeviceState *dev, Error **errp)

  {
+ERRP_GUARD();
  S390CCWDevice *cdev = S390_CCW_DEVICE(dev);
  VFIOCCWDevice *vcdev = VFIO_CCW(cdev);
  S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(cdev);
  VFIODevice *vbasedev = >vdev;
-Error *err = NULL;
  
  /* Call the class init function for subchannel. */

  if (cdc->realize) {
-cdc->realize(cdev, vcdev->vdev.sysfsdev, );
-if (err) {
-goto out_err_propagate;
+cdc->realize(cdev, vcdev->vdev.sysfsdev, errp);
+if (*errp) {
+return;


We should change the realize() return value to bool also. this is more
work and it should be addressed in its own patchset I think and ...


  }
  }
  
@@ -597,27 +597,28 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)

  goto out_attach_dev_err;
  }
  
-if (!vfio_ccw_get_region(vcdev, )) {

+if (!vfio_ccw_get_region(vcdev, errp)) {
  goto out_region_err;
  }
  
-if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, )) {

+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX, errp)) {
  goto out_io_notifier_err;
  }
  
  if (vcdev->crw_region) {

  if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX,
-)) {
+errp)) {
  goto out_irq_notifier_err;
  }
  }
  
-if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, )) {

+if (!vfio_ccw_register_irq_notifier(vcdev, VFIO_CCW_REQ_IRQ_INDEX, errp)) {
  /*
   * Report this error, but do not make it a failing condition.
   * Lack of this IRQ in the host does not prevent normal operation.
   */
-error_report_err(err);
+error_report_err(*errp);


This should use a local Error variable and be a warn_report_err instead.

Let's address these changes in another series. I can take care of it
later if no one does.

Thanks,

C.




+*errp = NULL;
  }
  
  return;

@@ -635,8 +636,6 @@ out_attach_dev_err:
  if (cdc->unrealize) {
  cdc->unrealize(cdev);
  }
-out_err_propagate:
-error_propagate(errp, err);
  }
  
  static void vfio_ccw_unrealize(DeviceState *dev)





Re: [PATCH v2 17/20] vfio: Use g_autofree in all call site of vfio_get_region_info()

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

There are some exceptions when pointer to vfio_region_info is reused.
In that case, the pointed memory is freed manually.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/helpers.c |  7 ++-
  hw/vfio/igd.c |  5 ++---
  hw/vfio/pci.c | 13 +++--
  3 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 4b079dc383..27ea26aa48 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -343,7 +343,7 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion 
*region,
  int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
int index, const char *name)
  {
-struct vfio_region_info *info;
+g_autofree struct vfio_region_info *info = NULL;
  int ret;
  
  ret = vfio_get_region_info(vbasedev, index, );

@@ -376,8 +376,6 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, 
VFIORegion *region,
  }
  }
  
-g_free(info);

-
  trace_vfio_region_setup(vbasedev->name, index, name,
  region->flags, region->fd_offset, region->size);
  return 0;
@@ -594,14 +592,13 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, 
uint32_t type,
  
  bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type)

  {
-struct vfio_region_info *info = NULL;
+g_autofree struct vfio_region_info *info = NULL;
  bool ret = false;
  
  if (!vfio_get_region_info(vbasedev, region, )) {

  if (vfio_get_region_info_cap(info, cap_type)) {
  ret = true;
  }
-g_free(info);
  }
  
  return ret;

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 402fc5ce1d..1e79202f2b 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -367,8 +367,8 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
  
  void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)

  {
-struct vfio_region_info *rom = NULL, *opregion = NULL,
-*host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *rom = NULL;
+struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
  VFIOQuirk *quirk;
  VFIOIGDQuirk *igd;
  PCIDevice *lpc_bridge;
@@ -609,7 +609,6 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
  
  out:

-g_free(rom);
  g_free(opregion);
  g_free(host);
  g_free(lpc);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 35ad9b582f..74a79bdf61 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -879,7 +879,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev)
  
  static void vfio_pci_load_rom(VFIOPCIDevice *vdev)

  {
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
  uint64_t size;
  off_t off = 0;
  ssize_t bytes;
@@ -897,8 +897,6 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev)
  vdev->rom_size = size = reg_info->size;
  vdev->rom_offset = reg_info->offset;
  
-g_free(reg_info);

-
  if (!vdev->rom_size) {
  vdev->rom_read_failed = true;
  error_report("vfio-pci: Cannot read device rom at "
@@ -2668,7 +2666,7 @@ static VFIODeviceOps vfio_pci_ops = {
  bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  {
  VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
  int ret;
  
  ret = vfio_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, _info);

@@ -2685,7 +2683,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  error_setg(errp, "unexpected VGA info, flags 0x%lx, size 0x%lx",
 (unsigned long)reg_info->flags,
 (unsigned long)reg_info->size);
-g_free(reg_info);
  return false;
  }
  
@@ -2694,8 +2691,6 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)

  vdev->vga->fd_offset = reg_info->offset;
  vdev->vga->fd = vdev->vbasedev.fd;
  
-g_free(reg_info);

-
  vdev->vga->region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;
  vdev->vga->region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;
  QLIST_INIT(>vga->region[QEMU_PCI_VGA_MEM].quirks);
@@ -2736,7 +2731,7 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
  {
  VFIODevice *vbasedev = >vbasedev;
-struct vfio_region_info *reg_info;
+g_autofree struct vfio_region_info *reg_info = NULL;
  struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };
  int i, ret = -1;
  
@@ -2790,8 +2785,6 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

  

Re: [PATCH v2 18/20] vfio/igd: Use g_autofree in vfio_probe_igd_bar4_quirk()

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

Pointer opregion, host and lpc are allocated and freed in
vfio_probe_igd_bar4_quirk(). Use g_autofree to automatically
free them.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/igd.c | 27 ---
  1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 1e79202f2b..d320d032a7 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -368,7 +368,9 @@ static const MemoryRegionOps vfio_igd_index_quirk = {
  void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  {
  g_autofree struct vfio_region_info *rom = NULL;
-struct vfio_region_info *opregion = NULL, *host = NULL, *lpc = NULL;
+g_autofree struct vfio_region_info *opregion = NULL;
+g_autofree struct vfio_region_info *host = NULL;
+g_autofree struct vfio_region_info *lpc = NULL;
  VFIOQuirk *quirk;
  VFIOIGDQuirk *igd;
  PCIDevice *lpc_bridge;
@@ -426,7 +428,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  if ((ret || !rom->size) && !vdev->pdev.romfile) {
  error_report("IGD device %s has no ROM, legacy mode disabled",
   vdev->vbasedev.name);
-goto out;
+return;
  }
  
  /*

@@ -437,7 +439,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  error_report("IGD device %s hotplugged, ROM disabled, "
   "legacy mode disabled", vdev->vbasedev.name);
  vdev->rom_read_failed = true;
-goto out;
+return;
  }
  
  /*

@@ -450,7 +452,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  if (ret) {
  error_report("IGD device %s does not support OpRegion access,"
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  ret = vfio_get_dev_region_info(>vbasedev,

@@ -459,7 +461,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  if (ret) {
  error_report("IGD device %s does not support host bridge access,"
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  ret = vfio_get_dev_region_info(>vbasedev,

@@ -468,7 +470,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  if (ret) {
  error_report("IGD device %s does not support LPC bridge access,"
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  gmch = vfio_pci_read_config(>pdev, IGD_GMCH, 4);

@@ -482,7 +484,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  error_report("IGD device %s failed to enable VGA access, "
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  /* Create our LPC/ISA bridge */

@@ -490,7 +492,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  if (ret) {
  error_report("IGD device %s failed to create LPC bridge, "
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  /* Stuff some host values into the VM PCI host bridge */

@@ -498,14 +500,14 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
nr)
  if (ret) {
  error_report("IGD device %s failed to modify host bridge, "
   "legacy mode disabled", vdev->vbasedev.name);
-goto out;
+return;
  }
  
  /* Setup OpRegion access */

  if (!vfio_pci_igd_opregion_init(vdev, opregion, )) {
  error_append_hint(, "IGD legacy mode disabled\n");
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
-goto out;
+return;
  }
  
  /* Setup our quirk to munge GTT addresses to the VM allocated buffer */

@@ -607,9 +609,4 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  }
  
  trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);

-
-out:
-g_free(opregion);
-g_free(host);
-g_free(lpc);
  }





Re: [PATCH v2 10/20] vfio/pci: Make vfio_populate_device() return a bool

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

Since vfio_populate_device() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

By this chance, pass errp directly to vfio_populate_device() to
avoid calling error_propagate().

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 21 ++---
  1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 4fb5fd0c9f..46d3c61859 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2740,7 +2740,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  return 0;
  }
  
-static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
  {
  VFIODevice *vbasedev = >vbasedev;
  struct vfio_region_info *reg_info;
@@ -2750,18 +2750,18 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  /* Sanity check device */
  if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PCI)) {
  error_setg(errp, "this isn't a PCI device");
-return;
+return false;
  }
  
  if (vbasedev->num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {

  error_setg(errp, "unexpected number of io regions %u",
 vbasedev->num_regions);
-return;
+return false;
  }
  
  if (vbasedev->num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {

  error_setg(errp, "unexpected number of irqs %u", vbasedev->num_irqs);
-return;
+return false;
  }
  
  for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) {

@@ -2773,7 +2773,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  
  if (ret) {

  error_setg_errno(errp, -ret, "failed to get region %d info", i);
-return;
+return false;
  }
  
  QLIST_INIT(>bars[i].quirks);

@@ -2783,7 +2783,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 VFIO_PCI_CONFIG_REGION_INDEX, _info);
  if (ret) {
  error_setg_errno(errp, -ret, "failed to get config info");
-return;
+return false;
  }
  
  trace_vfio_populate_device_config(vdev->vbasedev.name,

@@ -2804,7 +2804,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  if (ret) {
  error_append_hint(errp, "device does not support "
"requested feature x-vga\n");
-return;
+return false;
  }
  }
  
@@ -2821,6 +2821,8 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

  "Could not enable error recovery for the device",
  vbasedev->name);
  }
+
+return true;
  }
  
  static void vfio_pci_put_device(VFIOPCIDevice *vdev)

@@ -2977,7 +2979,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  VFIOPCIDevice *vdev = VFIO_PCI(pdev);
  VFIODevice *vbasedev = >vbasedev;
  char *subsys;
-Error *err = NULL;
  int i, ret;
  bool is_mdev;
  char uuid[UUID_STR_LEN];
@@ -3036,9 +3037,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  goto error;
  }
  
-vfio_populate_device(vdev, );

-if (err) {
-error_propagate(errp, err);
+if (!vfio_populate_device(vdev, errp)) {
  goto error;
  }
  





Re: [PATCH v2 09/20] vfio/pci: Make vfio_pci_relocate_msix() and vfio_msix_early_setup() return a bool

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:40, Zhenzhong Duan wrote:

Since vfio_pci_relocate_msix() and vfio_msix_early_setup() takes
an 'Error **' argument, best practices suggest to return a bool.
See the qapi/error.h Rules section.

By this chance, pass errp directly to vfio_msix_early_setup() to avoid
calling error_propagate().

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 33 -
  1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 12fb534d79..4fb5fd0c9f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1450,13 +1450,13 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice 
*vdev)
  }
  }
  
-static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)
  {
  int target_bar = -1;
  size_t msix_sz;
  
  if (!vdev->msix || vdev->msix_relo == OFF_AUTOPCIBAR_OFF) {

-return;
+return true;
  }
  
  /* The actual minimum size of MSI-X structures */

@@ -1479,7 +1479,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  if (target_bar < 0) {
  error_setg(errp, "No automatic MSI-X relocation available for "
 "device %04x:%04x", vdev->vendor_id, vdev->device_id);
-return;
+return false;
  }
  } else {
  target_bar = (int)(vdev->msix_relo - OFF_AUTOPCIBAR_BAR0);
@@ -1489,7 +1489,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  if (vdev->bars[target_bar].ioport) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "I/O port BAR", target_bar);
-return;
+return false;
  }
  
  /* Cannot use a BAR in the "shadow" of a 64-bit BAR */

@@ -1497,7 +1497,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
   target_bar > 0 && vdev->bars[target_bar - 1].mem64) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "consumed by 64-bit BAR %d", target_bar, target_bar - 1);
-return;
+return false;
  }
  
  /* 2GB max size for 32-bit BARs, cannot double if already > 1G */

@@ -1505,7 +1505,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  !vdev->bars[target_bar].mem64) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "no space to extend 32-bit BAR", target_bar);
-return;
+return false;
  }
  
  /*

@@ -1540,6 +1540,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  
  trace_vfio_msix_relo(vdev->vbasedev.name,

   vdev->msix->table_bar, vdev->msix->table_offset);
+return true;
  }
  
  /*

@@ -1550,7 +1551,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
   * need to first look for where the MSI-X table lives.  So we
   * unfortunately split MSI-X setup across two functions.
   */
-static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
  {
  uint8_t pos;
  uint16_t ctrl;
@@ -1562,25 +1563,25 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  
  pos = pci_find_capability(>pdev, PCI_CAP_ID_MSIX);

  if (!pos) {
-return;
+return true;
  }
  
  if (pread(fd, , sizeof(ctrl),

vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX FLAGS");
-return;
+return false;
  }
  
  if (pread(fd, , sizeof(table),

vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX TABLE");
-return;
+return false;
  }
  
  if (pread(fd, , sizeof(pba),

vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX PBA");
-return;
+return false;
  }
  
  ctrl = le16_to_cpu(ctrl);

@@ -1598,7 +1599,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  if (ret < 0) {
  error_setg_errno(errp, -ret, "failed to get MSI-X irq info");
  g_free(msix);
-return;
+return false;
  }
  
  msix->noresize = !!(irq_info.flags & VFIO_IRQ_INFO_NORESIZE);

@@ -1630,7 +1631,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  error_setg(errp, "hardware reports invalid configuration, "
 

Re: [PATCH v2 03/20] vfio/helpers: Use g_autofree in vfio_set_irq_signaling()

2024-05-22 Thread Cédric Le Goater

On 5/22/24 06:39, Zhenzhong Duan wrote:

Local pointer irq_set is freed before return from
vfio_set_irq_signaling().

Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/helpers.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 47b4096c05..1f3bdd9bf0 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -111,7 +111,7 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
 int action, int fd, Error **errp)
  {
  ERRP_GUARD();
-struct vfio_irq_set *irq_set;
+g_autofree struct vfio_irq_set *irq_set = NULL;
  int argsz, ret = 0;
  const char *name;
  int32_t *pfd;
@@ -130,7 +130,6 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
  if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
  ret = -errno;
  }
-g_free(irq_set);
  
  if (!ret) {

  return 0;





Re: [PATCH 16/16] vfio/pci-quirks: Make vfio_add_*_cap() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Include below functions:
vfio_add_virt_caps()
vfio_add_nv_gpudirect_cap()
vfio_add_vmd_shadow_cap()

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.h|  2 +-
  hw/vfio/pci-quirks.c | 42 +++---
  hw/vfio/pci.c|  3 +--
  3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index f158681072..bf67df2fbc 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -212,7 +212,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
  void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
  void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
  void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
-int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
  void vfio_quirk_reset(VFIOPCIDevice *vdev);
  VFIOQuirk *vfio_quirk_alloc(int nr_mem);
  void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr);
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index ca27917159..39dae72497 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1536,7 +1536,7 @@ static bool is_valid_std_cap_offset(uint8_t pos)
  pos <= (PCI_CFG_SPACE_SIZE - PCI_CAP_SIZEOF));
  }
  
-static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
  {
  ERRP_GUARD();
  PCIDevice *pdev = >pdev;
@@ -1545,18 +1545,18 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
  uint8_t tmp;
  
  if (vdev->nv_gpudirect_clique == 0xFF) {

-return 0;
+return true;
  }
  
  if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) {

  error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid device vendor");
-return -EINVAL;
+return false;
  }
  
  if (pci_get_byte(pdev->config + PCI_CLASS_DEVICE + 1) !=

  PCI_BASE_CLASS_DISPLAY) {
  error_setg(errp, "NVIDIA GPUDirect Clique ID: unsupported PCI class");
-return -EINVAL;
+return false;
  }
  
  /*

@@ -1572,7 +1572,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
  vdev->config_offset + PCI_CAPABILITY_LIST);
  if (ret != 1 || !is_valid_std_cap_offset(tmp)) {
  error_setg(errp, "NVIDIA GPUDirect Clique ID: error getting cap 
list");
-return -EINVAL;
+return false;
  }
  
  do {

@@ -1590,13 +1590,13 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice 
*vdev, Error **errp)
  pos = 0xD4;
  } else {
  error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid config space");
-return -EINVAL;
+return false;
  }
  
  ret = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, 8, errp);

  if (ret < 0) {
  error_prepend(errp, "Failed to add NVIDIA GPUDirect cap: ");
-return ret;
+return false;
  }
  
  memset(vdev->emulated_config_bits + pos, 0xFF, 8);

@@ -1608,7 +1608,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
  pci_set_byte(pdev->config + pos++, vdev->nv_gpudirect_clique << 3);
  pci_set_byte(pdev->config + pos, 0);
  
-return 0;

+return true;
  }
  
  /*

@@ -1629,7 +1629,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, 
Error **errp)
   */
  #define VMD_SHADOW_CAP_VER 1
  #define VMD_SHADOW_CAP_LEN 24
-static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, Error **errp)
  {
  ERRP_GUARD();
  uint8_t membar_phys[16];
@@ -1639,7 +1639,7 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x467F) ||
vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x4C3D) ||
vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, 0x9A0B))) {
-return 0;
+return true;
  }
  
  ret = pread(vdev->vbasedev.fd, membar_phys, 16,

@@ -1647,14 +1647,14 @@ static int vfio_add_vmd_shadow_cap(VFIOPCIDevice *vdev, 
Error **errp)
  if (ret != 16) {
  error_report("VMD %s cannot read MEMBARs (%d)",
   vdev->vbasedev.name, ret);
-return -EFAULT;
+return false;
  }
  
  ret = pci_add_capability(>pdev, PCI_CAP_ID_VNDR, pos,

   VMD_SHADOW_CAP_LEN, errp);
  if (ret < 0) {
  error_prepend(errp, "Failed to add VMD MEMBAR Shadow cap: ");
-return ret;
+return false;
  }
  
  memset(vdev->emulated_config_bits + pos, 

Re: [PATCH 13/16] vfio/pci: Make capability related functions return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

The functions operating on capability don't have a consistent return style.

Below functions are in bool-valued functions style:
vfio_msi_setup()
vfio_msix_setup()
vfio_add_std_cap()
vfio_add_capabilities()

Below two are integer-valued functions:
vfio_add_vendor_specific_cap()
vfio_setup_pcie_cap()

But the returned integer is only used for check succeed/failure.
Change them all to return bool so now all capability related
functions follow the coding standand in qapi/error.h to return
bool.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 77 ---
  1 file changed, 36 insertions(+), 41 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 1922593253..ecfbb9619f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1339,7 +1339,7 @@ static void vfio_disable_interrupts(VFIOPCIDevice *vdev)
  }
  }
  
-static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)

+static bool vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
  {
  uint16_t ctrl;
  bool msi_64bit, msi_maskbit;
@@ -1349,7 +1349,7 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, 
Error **errp)
  if (pread(vdev->vbasedev.fd, , sizeof(ctrl),
vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
  error_setg_errno(errp, errno, "failed reading MSI PCI_CAP_FLAGS");
-return -errno;
+return false;
  }
  ctrl = le16_to_cpu(ctrl);
  
@@ -1362,14 +1362,14 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)

  ret = msi_init(>pdev, pos, entries, msi_64bit, msi_maskbit, );
  if (ret < 0) {
  if (ret == -ENOTSUP) {
-return 0;
+return true;
  }
  error_propagate_prepend(errp, err, "msi_init failed: ");
-return ret;
+return false;
  }
  vdev->msi_cap_size = 0xa + (msi_maskbit ? 0xa : 0) + (msi_64bit ? 0x4 : 
0);
  
-return 0;

+return true;
  }
  
  static void vfio_pci_fixup_msix_region(VFIOPCIDevice *vdev)

@@ -1644,7 +1644,7 @@ static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  return vfio_pci_relocate_msix(vdev, errp);
  }
  
-static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp)

+static bool vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
  {
  int ret;
  Error *err = NULL;
@@ -1660,11 +1660,11 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int 
pos, Error **errp)
  if (ret < 0) {
  if (ret == -ENOTSUP) {
  warn_report_err(err);
-return 0;
+return true;
  }
  
  error_propagate(errp, err);

-return ret;
+return false;
  }
  
  /*

@@ -1698,7 +1698,7 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, 
Error **errp)
  memory_region_set_enabled(>pdev.msix_table_mmio, false);
  }
  
-return 0;

+return true;
  }
  
  static void vfio_teardown_msi(VFIOPCIDevice *vdev)

@@ -1977,8 +1977,8 @@ static void vfio_pci_disable_rp_atomics(VFIOPCIDevice 
*vdev)
  }
  }
  
-static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,

-   Error **errp)
+static bool vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
+Error **errp)
  {
  uint16_t flags;
  uint8_t type;
@@ -1992,7 +1992,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
  
  error_setg(errp, "assignment of PCIe type 0x%x "

 "devices is not currently supported", type);
-return -EINVAL;
+return false;
  }
  
  if (!pci_bus_is_express(pci_get_bus(>pdev))) {

@@ -2025,7 +2025,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
  }
  
  if (pci_bus_is_express(bus)) {

-return 0;
+return true;
  }
  
  } else if (pci_bus_is_root(pci_get_bus(>pdev))) {

@@ -2063,7 +2063,7 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
   * Legacy endpoints don't belong on the root complex.  Windows
   * seems to be happier with devices if we skip the capability.
   */
-return 0;
+return true;
  }
  
  } else {

@@ -2099,12 +2099,12 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int 
pos, uint8_t size,
  pos = pci_add_capability(>pdev, PCI_CAP_ID_EXP, pos, size,
   errp);
  if (pos < 0) {
-return pos;
+return false;
  }
  
  vdev->pdev.exp.exp_cap = pos;
  
-return pos;

+return true;
  }
  
  static void vfio_check_pcie_flr(VFIOPCIDevice *vdev, uint8_t pos)

@@ -2137,14

Re: [PATCH 14/16] vfio/pci: Use g_autofree for vfio_region_info pointer

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

Pointer opregion is freed after vfio_pci_igd_opregion_init().
Use 'g_autofree' to avoid the g_free() calls.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index ecfbb9619f..be87478716 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3146,7 +3146,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  
  if (!vdev->igd_opregion &&

  vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
-struct vfio_region_info *opregion;
+g_autofree struct vfio_region_info *opregion = NULL;
  
  if (vdev->pdev.qdev.hotplugged) {

  error_setg(errp,
@@ -3165,7 +3165,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  }
  
  ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);

-g_free(opregion);
  if (ret) {
  goto out_teardown;
  }





Re: [PATCH 15/16] vfio/pci-quirks: Make vfio_pci_igd_opregion_init() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.h| 6 +++---
  hw/vfio/igd.c| 3 +--
  hw/vfio/pci-quirks.c | 8 
  hw/vfio/pci.c| 3 +--
  4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 7914f019d5..f158681072 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -227,9 +227,9 @@ int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
  
  bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
  
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,

-   struct vfio_region_info *info,
-   Error **errp);
+bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
+struct vfio_region_info *info,
+Error **errp);
  
  void vfio_display_reset(VFIOPCIDevice *vdev);

  bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index ffe57c5954..402fc5ce1d 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -502,8 +502,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
  }
  
  /* Setup OpRegion access */

-ret = vfio_pci_igd_opregion_init(vdev, opregion, );
-if (ret) {
+if (!vfio_pci_igd_opregion_init(vdev, opregion, )) {
  error_append_hint(, "IGD legacy mode disabled\n");
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  goto out;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 496fd1ee86..ca27917159 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1169,8 +1169,8 @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice 
*vdev, int nr)
   * the table and to write the base address of that memory to the ASLS register
   * of the IGD device.
   */
-int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
-   struct vfio_region_info *info, Error **errp)
+bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
+struct vfio_region_info *info, Error **errp)
  {
  int ret;
  
@@ -1181,7 +1181,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,

  error_setg(errp, "failed to read IGD OpRegion");
  g_free(vdev->igd_opregion);
  vdev->igd_opregion = NULL;
-return -EINVAL;
+return false;
  }
  
  /*

@@ -1206,7 +1206,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
  pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0);
  pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0);
  
-return 0;

+return true;
  }
  
  /*

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index be87478716..15823c359a 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3164,8 +3164,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  goto out_teardown;
  }
  
-ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);

-if (ret) {
+if (!vfio_pci_igd_opregion_init(vdev, opregion, errp)) {
  goto out_teardown;
  }
  }





Re: [PATCH 12/16] vfio/pci: Make vfio_populate_vga() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.h |  2 +-
  hw/vfio/igd.c |  2 +-
  hw/vfio/pci.c | 11 +--
  3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index a5ac9efd4b..7914f019d5 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -225,7 +225,7 @@ bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const 
char *name);
  int vfio_pci_get_pci_hot_reset_info(VFIOPCIDevice *vdev,
  struct vfio_pci_hot_reset_info **info_p);
  
-int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);

+bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
  
  int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,

 struct vfio_region_info *info,
diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index b31ee79c60..ffe57c5954 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -478,7 +478,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
   * try to enable it.  Probably shouldn't be using legacy mode without VGA,
   * but also no point in us enabling VGA if disabled in hardware.
   */
-if (!(gmch & 0x2) && !vdev->vga && vfio_populate_vga(vdev, )) {
+if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, )) {
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  error_report("IGD device %s failed to enable VGA access, "
   "legacy mode disabled", vdev->vbasedev.name);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index e2ca4507f8..1922593253 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2670,7 +2670,7 @@ static VFIODeviceOps vfio_pci_ops = {
  .vfio_load_config = vfio_pci_load_config,
  };
  
-int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)

+bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  {
  VFIODevice *vbasedev = >vbasedev;
  struct vfio_region_info *reg_info;
@@ -2681,7 +2681,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  error_setg_errno(errp, -ret,
   "failed getting region info for VGA region index %d",
   VFIO_PCI_VGA_REGION_INDEX);
-return ret;
+return false;
  }
  
  if (!(reg_info->flags & VFIO_REGION_INFO_FLAG_READ) ||

@@ -2691,7 +2691,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
 (unsigned long)reg_info->flags,
 (unsigned long)reg_info->size);
  g_free(reg_info);
-return -EINVAL;
+return false;
  }
  
  vdev->vga = g_new0(VFIOVGA, 1);

@@ -2735,7 +2735,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
   >vga->region[QEMU_PCI_VGA_IO_LO].mem,
   >vga->region[QEMU_PCI_VGA_IO_HI].mem);
  
-return 0;

+return true;
  }
  
  static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

@@ -2798,8 +2798,7 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  g_free(reg_info);
  
  if (vdev->features & VFIO_FEATURE_ENABLE_VGA) {

-ret = vfio_populate_vga(vdev, errp);
-if (ret) {
+if (!vfio_populate_vga(vdev, errp)) {
  error_append_hint(errp, "device does not support "
"requested feature x-vga\n");
  return false;





Re: [PATCH 11/16] vfio/pci: Make vfio_intx_enable() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 19 ---
  1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c091d21adf..e2ca4507f8 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -261,7 +261,7 @@ static void vfio_irqchip_change(Notifier *notify, void 
*data)
  vfio_intx_update(vdev, >intx.route);
  }
  
-static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
  {
  uint8_t pin = vfio_pci_read_config(>pdev, PCI_INTERRUPT_PIN, 1);
  Error *err = NULL;
@@ -270,7 +270,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
  
  
  if (!pin) {

-return 0;
+return true;
  }
  
  vfio_disable_interrupts(vdev);

@@ -292,7 +292,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
  ret = event_notifier_init(>intx.interrupt, 0);
  if (ret) {
  error_setg_errno(errp, -ret, "event_notifier_init failed");
-return ret;
+return false;
  }
  fd = event_notifier_get_fd(>intx.interrupt);
  qemu_set_fd_handler(fd, vfio_intx_interrupt, NULL, vdev);
@@ -301,7 +301,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
  VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
  qemu_set_fd_handler(fd, NULL, NULL, vdev);
  event_notifier_cleanup(>intx.interrupt);
-return -errno;
+return false;
  }
  
  if (!vfio_intx_enable_kvm(vdev, )) {

@@ -311,7 +311,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error 
**errp)
  vdev->interrupt = VFIO_INT_INTx;
  
  trace_vfio_intx_enable(vdev->vbasedev.name);

-return 0;
+return true;
  }
  
  static void vfio_intx_disable(VFIOPCIDevice *vdev)

@@ -836,8 +836,7 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev)
  vfio_disable_irqindex(>vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
  
  vfio_msi_disable_common(vdev);

-vfio_intx_enable(vdev, );
-if (err) {
+if (!vfio_intx_enable(vdev, )) {
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  }
  
@@ -2450,8 +2449,7 @@ void vfio_pci_post_reset(VFIOPCIDevice *vdev)

  Error *err = NULL;
  int nr;
  
-vfio_intx_enable(vdev, );

-if (err) {
+if (!vfio_intx_enable(vdev, )) {
  error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  }
  
@@ -3197,8 +3195,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)

   vfio_intx_routing_notifier);
  vdev->irqchip_change_notifier.notify = vfio_irqchip_change;
  kvm_irqchip_add_change_notifier(>irqchip_change_notifier);
-ret = vfio_intx_enable(vdev, errp);
-if (ret) {
+if (!vfio_intx_enable(vdev, errp)) {
  goto out_deregister;
  }
  }





Re: [PATCH 10/16] vfio/pci: Make vfio_populate_device() return a bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

Since vfio_populate_device() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

Signed-off-by: Zhenzhong Duan 
---
  hw/vfio/pci.c | 19 ++-
  1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 379cbad757..c091d21adf 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2740,7 +2740,7 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
  return 0;
  }
  
-static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
  {
  VFIODevice *vbasedev = >vbasedev;
  struct vfio_region_info *reg_info;
@@ -2750,18 +2750,18 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  /* Sanity check device */
  if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PCI)) {
  error_setg(errp, "this isn't a PCI device");
-return;
+return false;
  }
  
  if (vbasedev->num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {

  error_setg(errp, "unexpected number of io regions %u",
 vbasedev->num_regions);
-return;
+return false;
  }
  
  if (vbasedev->num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {

  error_setg(errp, "unexpected number of irqs %u", vbasedev->num_irqs);
-return;
+return false;
  }
  
  for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) {

@@ -2773,7 +2773,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  
  if (ret) {

  error_setg_errno(errp, -ret, "failed to get region %d info", i);
-return;
+return false;
  }
  
  QLIST_INIT(>bars[i].quirks);

@@ -2783,7 +2783,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
 VFIO_PCI_CONFIG_REGION_INDEX, _info);
  if (ret) {
  error_setg_errno(errp, -ret, "failed to get config info");
-return;
+return false;
  }
  
  trace_vfio_populate_device_config(vdev->vbasedev.name,

@@ -2804,7 +2804,7 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, 
Error **errp)
  if (ret) {
  error_append_hint(errp, "device does not support "
"requested feature x-vga\n");
-return;
+return false;
  }
  }
  
@@ -2821,6 +2821,8 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)

  "Could not enable error recovery for the device",
  vbasedev->name);
  }
+
+return true;
  }
  
  static void vfio_pci_put_device(VFIOPCIDevice *vdev)

@@ -3036,8 +3038,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  goto error;
  }
  
-vfio_populate_device(vdev, );

-if (err) {
+if (!vfio_populate_device(vdev, )) {


why not pass errp directly and avoid error_propagate() ?

Thanks,

C.



  error_propagate(errp, err);
  goto error;
  }





Re: [PATCH 09/16] vfio/pci: Make vfio_pci_relocate_msix() and vfio_msix_early_setup() return a bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

Since vfio_pci_relocate_msix() and vfio_msix_early_setup() takes
an 'Error **' argument, best practices suggest to return a bool.
See the qapi/error.h Rules section.

Signed-off-by: Zhenzhong Duan 
---
  hw/vfio/pci.c | 32 
  1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 12fb534d79..379cbad757 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1450,13 +1450,13 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice 
*vdev)
  }
  }
  
-static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_pci_relocate_msix(VFIOPCIDevice *vdev, Error **errp)
  {
  int target_bar = -1;
  size_t msix_sz;
  
  if (!vdev->msix || vdev->msix_relo == OFF_AUTOPCIBAR_OFF) {

-return;
+return true;
  }
  
  /* The actual minimum size of MSI-X structures */

@@ -1479,7 +1479,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  if (target_bar < 0) {
  error_setg(errp, "No automatic MSI-X relocation available for "
 "device %04x:%04x", vdev->vendor_id, vdev->device_id);
-return;
+return false;
  }
  } else {
  target_bar = (int)(vdev->msix_relo - OFF_AUTOPCIBAR_BAR0);
@@ -1489,7 +1489,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  if (vdev->bars[target_bar].ioport) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "I/O port BAR", target_bar);
-return;
+return false;
  }
  
  /* Cannot use a BAR in the "shadow" of a 64-bit BAR */

@@ -1497,7 +1497,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
   target_bar > 0 && vdev->bars[target_bar - 1].mem64) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "consumed by 64-bit BAR %d", target_bar, target_bar - 1);
-return;
+return false;
  }
  
  /* 2GB max size for 32-bit BARs, cannot double if already > 1G */

@@ -1505,7 +1505,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  !vdev->bars[target_bar].mem64) {
  error_setg(errp, "Invalid MSI-X relocation BAR %d, "
 "no space to extend 32-bit BAR", target_bar);
-return;
+return false;
  }
  
  /*

@@ -1540,6 +1540,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
  
  trace_vfio_msix_relo(vdev->vbasedev.name,

   vdev->msix->table_bar, vdev->msix->table_offset);
+return true;
  }
  
  /*

@@ -1550,7 +1551,7 @@ static void vfio_pci_relocate_msix(VFIOPCIDevice *vdev, 
Error **errp)
   * need to first look for where the MSI-X table lives.  So we
   * unfortunately split MSI-X setup across two functions.
   */
-static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
+static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
  {
  uint8_t pos;
  uint16_t ctrl;
@@ -1562,25 +1563,25 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  
  pos = pci_find_capability(>pdev, PCI_CAP_ID_MSIX);

  if (!pos) {
-return;
+return true;
  }
  
  if (pread(fd, , sizeof(ctrl),

vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX FLAGS");
-return;
+return false;
  }
  
  if (pread(fd, , sizeof(table),

vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX TABLE");
-return;
+return false;
  }
  
  if (pread(fd, , sizeof(pba),

vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) {
  error_setg_errno(errp, errno, "failed to read PCI MSIX PBA");
-return;
+return false;
  }
  
  ctrl = le16_to_cpu(ctrl);

@@ -1598,7 +1599,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  if (ret < 0) {
  error_setg_errno(errp, -ret, "failed to get MSI-X irq info");
  g_free(msix);
-return;
+return false;
  }
  
  msix->noresize = !!(irq_info.flags & VFIO_IRQ_INFO_NORESIZE);

@@ -1630,7 +1631,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, 
Error **errp)
  error_setg(errp, "hardware reports invalid configuration, "
 "MSIX PBA outside of specified BAR");
  g_free(msix);
-return;
+return false;
  }
  }
  
@@ -1641,7 +1642,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp)
  
  vfio_pci_fixup_msix_region(vdev);
  
-vfio_pci_relocate_msix(vdev, errp);

+return vfio_pci_relocate_msix(vdev, 

Re: [PATCH 08/16] vfio/pci: Make vfio_intx_enable_kvm() return a bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

Since vfio_intx_enable_kvm() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/pci.c | 15 ---
  1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index aad012c348..12fb534d79 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -116,7 +116,7 @@ static void vfio_intx_eoi(VFIODevice *vbasedev)
  vfio_unmask_single_irqindex(vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
  }
  
-static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp)
  {
  #ifdef CONFIG_KVM
  int irq_fd = event_notifier_get_fd(>intx.interrupt);
@@ -124,7 +124,7 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error 
**errp)
  if (vdev->no_kvm_intx || !kvm_irqfds_enabled() ||
  vdev->intx.route.mode != PCI_INTX_ENABLED ||
  !kvm_resamplefds_enabled()) {
-return;
+return true;
  }
  
  /* Get to a known interrupt state */

@@ -161,7 +161,7 @@ static void vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error 
**errp)
  
  trace_vfio_intx_enable_kvm(vdev->vbasedev.name);
  
-return;

+return true;
  
  fail_vfio:

  kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, >intx.interrupt,
@@ -171,6 +171,9 @@ fail_irqfd:
  fail:
  qemu_set_fd_handler(irq_fd, vfio_intx_interrupt, NULL, vdev);
  vfio_unmask_single_irqindex(>vbasedev, VFIO_PCI_INTX_IRQ_INDEX);
+return false;
+#else
+return true;
  #endif
  }
  
@@ -226,8 +229,7 @@ static void vfio_intx_update(VFIOPCIDevice *vdev, PCIINTxRoute *route)

  return;
  }
  
-vfio_intx_enable_kvm(vdev, );

-if (err) {
+if (!vfio_intx_enable_kvm(vdev, )) {
  warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  }
  
@@ -302,8 +304,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)

  return -errno;
  }
  
-vfio_intx_enable_kvm(vdev, );

-if (err) {
+if (!vfio_intx_enable_kvm(vdev, )) {
  warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  }
  





Re: [PATCH 07/16] vfio/ccw: Make vfio_ccw_get_region() return a bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

Since vfio_populate_device() takes an 'Error **' argument,
best practices suggest to return a bool. See the qapi/error.h
Rules section.

Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

One comment below


---
  hw/vfio/ccw.c | 15 +++
  1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 8850ca17c8..2600e62e37 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -474,7 +474,7 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
  event_notifier_cleanup(notifier);
  }
  
-static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)

+static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
  {
  VFIODevice *vdev = >vdev;
  struct vfio_region_info *info;
@@ -483,7 +483,7 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error 
**errp)
  /* Sanity check device */
  if (!(vdev->flags & VFIO_DEVICE_FLAGS_CCW)) {
  error_setg(errp, "vfio: Um, this isn't a vfio-ccw device");
-return;
+return false;
  }
  
  /*

@@ -493,13 +493,13 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, 
Error **errp)
  if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
  error_setg(errp, "vfio: too few regions (%u), expected at least %u",
 vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
-return;
+return false;
  }
  
  ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, );

  if (ret) {
  error_setg_errno(errp, -ret, "vfio: Error getting config info");
-return;
+return false;
  }
  
  vcdev->io_region_size = info->size;

@@ -553,7 +553,7 @@ static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error 
**errp)
  g_free(info);
  }
  
-return;

+return true;
  
  out_err:

  g_free(vcdev->crw_region);
@@ -561,7 +561,7 @@ out_err:
  g_free(vcdev->async_cmd_region);
  g_free(vcdev->io_region);
  g_free(info);
-return;
+return false;
  }
  
  static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)

@@ -597,8 +597,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)


vfio_ccw_realize() needs a little cleanup to avoid using the local
'Error *err' variable and the error_propagate() call at the end.

Thanks,

C.



  goto out_attach_dev_err;
  }
  
-vfio_ccw_get_region(vcdev, );

-if (err) {
+if (!vfio_ccw_get_region(vcdev, )) {
  goto out_region_err;
  }
  





Re: [PATCH 06/16] vfio/platform: Make vfio_populate_device() and vfio_base_device_init() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/platform.c | 40 +---
  1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index e1a32863d9..a85c199c76 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -441,7 +441,7 @@ static int vfio_platform_hot_reset_multi(VFIODevice 
*vbasedev)
   * @errp: error object
   *
   */
-static int vfio_populate_device(VFIODevice *vbasedev, Error **errp)
+static bool vfio_populate_device(VFIODevice *vbasedev, Error **errp)
  {
  VFIOINTp *intp, *tmp;
  int i, ret = -1;
@@ -450,7 +450,7 @@ static int vfio_populate_device(VFIODevice *vbasedev, Error 
**errp)
  
  if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PLATFORM)) {

  error_setg(errp, "this isn't a platform device");
-return ret;
+return false;
  }
  
  vdev->regions = g_new0(VFIORegion *, vbasedev->num_regions);

@@ -487,12 +487,11 @@ static int vfio_populate_device(VFIODevice *vbasedev, 
Error **errp)
  irq.flags);
  intp = vfio_init_intp(vbasedev, irq, errp);
  if (!intp) {
-ret = -1;
  goto irq_err;
  }
  }
  }
-return 0;
+return true;
  irq_err:
  timer_del(vdev->mmap_timer);
  QLIST_FOREACH_SAFE(intp, >intp_list, next, tmp) {
@@ -507,7 +506,7 @@ reg_error:
  g_free(vdev->regions[i]);
  }
  g_free(vdev->regions);
-return ret;
+return false;
  }
  
  /* specialized functions for VFIO Platform devices */

@@ -527,10 +526,8 @@ static VFIODeviceOps vfio_platform_ops = {
   * fd retrieval, resource query.
   * Precondition: the device name must be initialized
   */
-static int vfio_base_device_init(VFIODevice *vbasedev, Error **errp)
+static bool vfio_base_device_init(VFIODevice *vbasedev, Error **errp)
  {
-int ret;
-
  /* @fd takes precedence over @sysfsdev which takes precedence over @host 
*/
  if (vbasedev->fd < 0 && vbasedev->sysfsdev) {
  g_free(vbasedev->name);
@@ -538,7 +535,7 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
  } else if (vbasedev->fd < 0) {
  if (!vbasedev->name || strchr(vbasedev->name, '/')) {
  error_setg(errp, "wrong host device name");
-return -EINVAL;
+return false;
  }
  
  vbasedev->sysfsdev = g_strdup_printf("/sys/bus/platform/devices/%s",

@@ -546,20 +543,20 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
  }
  
  if (!vfio_device_get_name(vbasedev, errp)) {

-return -EINVAL;
+return false;
  }
  
  if (!vfio_attach_device(vbasedev->name, vbasedev,

  _space_memory, errp)) {
-return -EINVAL;
+return false;
  }
  
-ret = vfio_populate_device(vbasedev, errp);

-if (ret) {
-vfio_detach_device(vbasedev);
+if (vfio_populate_device(vbasedev, errp)) {
+return true;
  }
  
-return ret;

+vfio_detach_device(vbasedev);
+return false;
  }
  
  /**

@@ -576,7 +573,7 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
  VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
  SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
  VFIODevice *vbasedev = >vbasedev;
-int i, ret;
+int i;
  
  qemu_mutex_init(>intp_mutex);
  
@@ -584,9 +581,8 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp)

  vbasedev->sysfsdev : vbasedev->name,
  vdev->compat);
  
-ret = vfio_base_device_init(vbasedev, errp);

-if (ret) {
-goto out;
+if (!vfio_base_device_init(vbasedev, errp)) {
+goto init_err;
  }
  
  if (!vdev->compat) {

@@ -618,11 +614,9 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
  }
  sysbus_init_mmio(sbdev, vdev->regions[i]->mem);
  }
-out:
-if (!ret) {
-return;
-}
+return;
  
+init_err:

  if (vdev->vbasedev.name) {
  error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
  } else {





Re: [PATCH 05/16] vfio/helpers: Make vfio_device_get_name() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/hw/vfio/vfio-common.h | 2 +-
  hw/vfio/ap.c  | 2 +-
  hw/vfio/ccw.c | 2 +-
  hw/vfio/helpers.c | 8 
  hw/vfio/pci.c | 2 +-
  hw/vfio/platform.c| 5 ++---
  6 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index fdce13f0f2..d9891c796f 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -280,7 +280,7 @@ int vfio_get_dirty_bitmap(const VFIOContainerBase 
*bcontainer, uint64_t iova,
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);
+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp);
  void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp);
  void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops,
DeviceState *dev, bool ram_discard);
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index d8a9615fee..c12531a788 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -158,7 +158,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
  VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
  VFIODevice *vbasedev = >vdev;
  
-if (vfio_device_get_name(vbasedev, errp) < 0) {

+if (!vfio_device_get_name(vbasedev, errp)) {
  return;
  }
  
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c

index 1f578a3c75..8850ca17c8 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -588,7 +588,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp)
  }
  }
  
-if (vfio_device_get_name(vbasedev, errp) < 0) {

+if (!vfio_device_get_name(vbasedev, errp)) {
  return;
  }
  
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c

index 93e6fef6de..a69b4411e5 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -605,7 +605,7 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, 
uint16_t cap_type)
  return ret;
  }
  
-int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)

+bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
  {
  ERRP_GUARD();
  struct stat st;
@@ -614,7 +614,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
  if (stat(vbasedev->sysfsdev, ) < 0) {
  error_setg_errno(errp, errno, "no such host device");
  error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev);
-return -errno;
+return false;
  }
  /* User may specify a name, e.g: VFIO platform device */
  if (!vbasedev->name) {
@@ -623,7 +623,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
  } else {
  if (!vbasedev->iommufd) {
  error_setg(errp, "Use FD passing only with iommufd backend");
-return -EINVAL;
+return false;
  }
  /*
   * Give a name with fd so any function printing out vbasedev->name
@@ -634,7 +634,7 @@ int vfio_device_get_name(VFIODevice *vbasedev, Error **errp)
  }
  }
  
-return 0;

+return true;
  }
  
  void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 358da4497b..aad012c348 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2999,7 +2999,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  vdev->host.slot, vdev->host.function);
  }
  
-if (vfio_device_get_name(vbasedev, errp) < 0) {

+if (!vfio_device_get_name(vbasedev, errp)) {
  return;
  }
  
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c

index 3233ca8691..e1a32863d9 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -545,9 +545,8 @@ static int vfio_base_device_init(VFIODevice *vbasedev, 
Error **errp)
   vbasedev->name);
  }
  
-ret = vfio_device_get_name(vbasedev, errp);

-if (ret) {
-return ret;
+if (!vfio_device_get_name(vbasedev, errp)) {
+return -EINVAL;
  }
  
  if (!vfio_attach_device(vbasedev->name, vbasedev,





Re: [PATCH 04/16] vfio/helpers: Make vfio_set_irq_signaling() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  include/hw/vfio/vfio-common.h |  4 ++--
  hw/vfio/ap.c  |  8 +++
  hw/vfio/ccw.c |  8 +++
  hw/vfio/helpers.c | 18 ++--
  hw/vfio/pci.c | 40 ++-
  hw/vfio/platform.c| 18 +++-
  6 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 2d8da32df4..fdce13f0f2 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -207,8 +207,8 @@ void vfio_spapr_container_deinit(VFIOContainer *container);
  void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
  void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
  void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
-   int action, int fd, Error **errp);
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp);
  void vfio_region_write(void *opaque, hwaddr addr,
 uint64_t data, unsigned size);
  uint64_t vfio_region_read(void *opaque,
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index ba653ef70f..d8a9615fee 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -117,8 +117,8 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
  fd = event_notifier_get_fd(notifier);
  qemu_set_fd_handler(fd, fd_read, NULL, vapdev);
  
-if (vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,

-   errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
+errp)) {
  qemu_set_fd_handler(fd, NULL, NULL, vapdev);
  event_notifier_cleanup(notifier);
  }
@@ -141,8 +141,8 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice 
*vapdev,
  return;
  }
  
-if (vfio_set_irq_signaling(>vdev, irq, 0,

-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
  warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name);
  }
  
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c

index 89bb980167..1f578a3c75 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -434,8 +434,8 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice 
*vcdev,
  fd = event_notifier_get_fd(notifier);
  qemu_set_fd_handler(fd, fd_read, NULL, vcdev);
  
-if (vfio_set_irq_signaling(vdev, irq, 0,

-   VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
+if (!vfio_set_irq_signaling(vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
  qemu_set_fd_handler(fd, NULL, NULL, vcdev);
  event_notifier_cleanup(notifier);
  }
@@ -464,8 +464,8 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice 
*vcdev,
  return;
  }
  
-if (vfio_set_irq_signaling(>vdev, irq, 0,

-   VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
+if (!vfio_set_irq_signaling(>vdev, irq, 0,
+VFIO_IRQ_SET_ACTION_TRIGGER, -1, )) {
  warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
  }
  
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c

index 0bb7b40a6a..93e6fef6de 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -107,12 +107,12 @@ static const char *index_to_str(VFIODevice *vbasedev, int 
index)
  }
  }
  
-int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,

-   int action, int fd, Error **errp)
+bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,
+int action, int fd, Error **errp)
  {
  ERRP_GUARD();
  g_autofree struct vfio_irq_set *irq_set = NULL;
-int argsz, ret = 0;
+int argsz;
  const char *name;
  int32_t *pfd;
  
@@ -127,15 +127,11 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex,

  pfd = (int32_t *)_set->data;
  *pfd = fd;
  
-if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {

-ret = -errno;
+if (!ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
+return true;
  }
  
-if (!ret) {

-return 0;
-}
-
-error_setg_errno(errp, -ret, "VFIO_DEVICE_SET_IRQS failure");
+error_setg_errno(errp, errno, "VFIO_DEVICE_SET_IRQS failure");
  
  name = index_to_str(vbasedev, ind

Re: [PATCH 03/16] vfio/helpers: Use g_autofree in hw/vfio/helpers.c

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:
Changed functions include vfio_set_irq_signaling() 


this change looks fine


and vfio_region_setup().


I would prefer all users of vfio_get_region_info() to be changed.

Thanks,

C.





Signed-off-by: Zhenzhong Duan 
---
  hw/vfio/helpers.c | 7 ++-
  1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 47b4096c05..0bb7b40a6a 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -111,7 +111,7 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
 int action, int fd, Error **errp)
  {
  ERRP_GUARD();
-struct vfio_irq_set *irq_set;
+g_autofree struct vfio_irq_set *irq_set = NULL;
  int argsz, ret = 0;
  const char *name;
  int32_t *pfd;
@@ -130,7 +130,6 @@ int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, 
int subindex,
  if (ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
  ret = -errno;
  }
-g_free(irq_set);
  
  if (!ret) {

  return 0;
@@ -348,7 +347,7 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion 
*region,
  int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region,
int index, const char *name)
  {
-struct vfio_region_info *info;
+g_autofree struct vfio_region_info *info = NULL;
  int ret;
  
  ret = vfio_get_region_info(vbasedev, index, );

@@ -381,8 +380,6 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev, 
VFIORegion *region,
  }
  }
  
-g_free(info);

-
  trace_vfio_region_setup(vbasedev->name, index, name,
  region->flags, region->fd_offset, region->size);
  return 0;





Re: [PATCH 02/16] vfio/display: Make vfio_display_*() return bool

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

This is to follow the coding standand in qapi/error.h to return bool
for bool-valued functions.

Suggested-by: Cédric Le Goater 
Signed-off-by: Zhenzhong Duan 



Reviewed-by: Cédric Le Goater 

One comment below,


---
  hw/vfio/pci.h |  2 +-
  hw/vfio/display.c | 20 ++--
  hw/vfio/pci.c |  3 +--
  3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 92cd62d115..a5ac9efd4b 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -232,7 +232,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
 Error **errp);
  
  void vfio_display_reset(VFIOPCIDevice *vdev);

-int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
+bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
  void vfio_display_finalize(VFIOPCIDevice *vdev);
  
  extern const VMStateDescription vfio_display_vmstate;

diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 57c5ae0b2a..b562f4be74 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -346,11 +346,11 @@ static const GraphicHwOps vfio_display_dmabuf_ops = {
  .ui_info= vfio_display_edid_ui_info,
  };
  
-static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp)
  {
  if (!display_opengl) {
  error_setg(errp, "vfio-display-dmabuf: opengl not available");
-return -1;
+return false;
  }
  
  vdev->dpy = g_new0(VFIODisplay, 1);

@@ -360,11 +360,11 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, 
Error **errp)
  if (vdev->enable_ramfb) {
  vdev->dpy->ramfb = ramfb_setup(errp);
  if (!vdev->dpy->ramfb) {
-return -EINVAL;
+return false;
  }
  }
  vfio_display_edid_init(vdev);


vfio_display_edid_init() can fail for many reasons and does it silently.
It would be good to report the error in a future patch.

Thanks,

C.




-return 0;
+return true;
  }
  
  static void vfio_display_dmabuf_exit(VFIODisplay *dpy)

@@ -481,7 +481,7 @@ static const GraphicHwOps vfio_display_region_ops = {
  .gfx_update = vfio_display_region_update,
  };
  
-static int vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)

+static bool vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp)
  {
  vdev->dpy = g_new0(VFIODisplay, 1);
  vdev->dpy->con = graphic_console_init(DEVICE(vdev), 0,
@@ -490,10 +490,10 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, 
Error **errp)
  if (vdev->enable_ramfb) {
  vdev->dpy->ramfb = ramfb_setup(errp);
  if (!vdev->dpy->ramfb) {
-return -EINVAL;
+return false;
  }
  }
-return 0;
+return true;
  }
  
  static void vfio_display_region_exit(VFIODisplay *dpy)

@@ -508,7 +508,7 @@ static void vfio_display_region_exit(VFIODisplay *dpy)
  
  /* -- */
  
-int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)

+bool vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
  {
  struct vfio_device_gfx_plane_info probe;
  int ret;
@@ -531,11 +531,11 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)
  
  if (vdev->display == ON_OFF_AUTO_AUTO) {

  /* not an error in automatic mode */
-return 0;
+return true;
  }
  
  error_setg(errp, "vfio: device doesn't support any (known) display method");

-return -1;
+return false;
  }
  
  void vfio_display_finalize(VFIOPCIDevice *vdev)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c1adef5cf8..a447013a1d 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3200,8 +3200,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
  }
  
  if (vdev->display != ON_OFF_AUTO_OFF) {

-ret = vfio_display_probe(vdev, errp);
-if (ret) {
+if (!vfio_display_probe(vdev, errp)) {
  goto out_deregister;
  }
  }





Re: [PATCH 01/16] vfio/display: Fix error path in call site of ramfb_setup()

2024-05-21 Thread Cédric Le Goater

On 5/15/24 10:20, Zhenzhong Duan wrote:

vfio_display_dmabuf_init() and vfio_display_region_init() calls
ramfb_setup() without checking its return value.

So we may run into a situation that vfio_display_probe() succeed
but errp is set. This is risky and may lead to assert failure in
error_setv().

Cc: Gerd Hoffmann 
Fixes: b290659fc3d ("hw/vfio/display: add ramfb support")
Signed-off-by: Zhenzhong Duan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/vfio/display.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/hw/vfio/display.c b/hw/vfio/display.c
index 1aa440c663..57c5ae0b2a 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -359,6 +359,9 @@ static int vfio_display_dmabuf_init(VFIOPCIDevice *vdev, 
Error **errp)
vdev);
  if (vdev->enable_ramfb) {
  vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
  }
  vfio_display_edid_init(vdev);
  return 0;
@@ -486,6 +489,9 @@ static int vfio_display_region_init(VFIOPCIDevice *vdev, 
Error **errp)
vdev);
  if (vdev->enable_ramfb) {
  vdev->dpy->ramfb = ramfb_setup(errp);
+if (!vdev->dpy->ramfb) {
+return -EINVAL;
+}
  }
  return 0;
  }





Re: [PATCH 00/32] hw/sd: eMMC support

2024-05-21 Thread Cédric Le Goater

On 8/28/23 18:27, Cédric Le Goater wrote:

Hello,

On 7/3/23 15:24, Cédric Le Goater wrote:

Hello,

This series adds an extension for a new eMMC device using the
framework Philippe put in place to support various SD implementations.
Previous discussion on the same topic:

   http://patchwork.ozlabs.org/project/qemu-devel/list/?series=250563
   https://lore.kernel.org/qemu-devel/20220318132824.1134400-1-...@kaod.org/

patch 1-12
   - introduce SDProto structure
   - could be merged. They have been reviewed.
patch 13
   - adds a SPI variant model


I plan to include 1-13 in the next aspeed PR.


I plan to include the rest of this series in the next aspeed PR,
for QEMU 9.1


Thanks,

C.





Thanks,

C.


patch 14-27
   - adds eMMC support
   - need better commit logs
patch 28-32 (for later)

   - aspeed wiring

Please comment the core part, we can leave out the aspeed part for
now. I won't have much time to fix the issues unless it's about
compile and style issues. If someone is interested and could take
over the series, that would be nice.

Thanks,

C.

Cédric Le Goater (11):
   hw/sd: Introduce a "sd-card" SPI variant model
   hw/sd: Add emmc_cmd_SEND_OP_CMD() handler
   hw/sd: Add emmc_cmd_ALL_SEND_CID() handler
   hw/sd: Add emmc_cmd_SEND_RELATIVE_ADDR() handler
   hw/sd: Add emmc_cmd_APP_CMD() handler
   hw/sd: add emmc_cmd_SEND_TUNING_BLOCK() handler
   hw/sd: Add emmc_cmd_SEND_EXT_CSD() handler
   hw/sd: Fix SET_BLOCK_COUNT command argument
   hw/arm/aspeed: Add eMMC device
   hw/arm/aspeed: Load eMMC first boot area as a boot rom
   aspeed: Introduce a 'boot-emmc' property for AST2600 based machines

Joel Stanley (6):
   hw/sd: Add sd_cmd_SEND_TUNING_BLOCK() handler
   hw/sd: Support boot area in emmc image
   hw/sd: Subtract bootarea size from blk
   hw/sd: Add boot config support
   hw/arm/aspeed: Set boot device to emmc
   aspeed: Set bootconfig

Philippe Mathieu-Daudé (12):
   hw/sd: When card is in wrong state, log which state it is
   hw/sd: When card is in wrong state, log which spec version is used
   hw/sd: Move proto_name to SDProto structure
   hw/sd: Introduce sd_cmd_handler type
   hw/sd: Add sd_cmd_illegal() handler
   hw/sd: Add sd_cmd_unimplemented() handler
   hw/sd: Add sd_cmd_GO_IDLE_STATE() handler
   hw/sd: Add sd_cmd_SEND_OP_CMD() handler
   hw/sd: Add sd_cmd_ALL_SEND_CID() handler
   hw/sd: Add sd_cmd_SEND_RELATIVE_ADDR() handler
   hw/sd: Add sd_cmd_SET_BLOCK_COUNT() handler
   hw/sd: Basis for eMMC support

Sai Pavan Boddu (3):
   hw/sd: Add CMD21 tuning sequence
   hw/sd: Add mmc switch function support
   hw/sd: Update CMD1 definition for MMC

  docs/system/arm/aspeed.rst   |   2 +
  hw/sd/sdmmc-internal.h   |  97 +
  include/hw/arm/aspeed_soc.h  |   1 +
  include/hw/misc/aspeed_scu.h |   7 +
  include/hw/sd/sd.h   |  10 +
  hw/arm/aspeed.c  |  68 +++-
  hw/arm/aspeed_ast2600.c  |   1 +
  hw/arm/stellaris.c   |   3 +-
  hw/riscv/sifive_u.c  |   3 +-
  hw/sd/sd.c   | 702 ---
  hw/sd/sdmmc-internal.c   |   2 +-
  11 files changed, 748 insertions(+), 148 deletions(-)









Re: [PATCH v3 2/5] ppc/pnv: Extend SPI model

2024-05-21 Thread Cédric Le Goater

On 5/21/24 08:11, Chalapathi V wrote:


On 18-05-2024 01:24, Miles Glenn wrote:

Chalapathi,

I'm having trouble seeing the benefit of breaking this commit out from
patch 1/5.  It seems like the two should be merged into a single commit
responsible for adding the PNV SPI Controller model.

-Glenn

I thought combining this with patch 1/5 will make it big. Hence made a logical 
partition.


I think it is fine to have 2 patches. One for the high level HW interface
and one for the lowlevel operation sequencer. This makes the review easier.


Thanks,

C.






On Thu, 2024-05-16 at 11:33 -0500, Chalapathi V wrote:

In this commit SPI shift engine and sequencer logic is implemented.
Shift engine performs serialization and de-serialization according to
the
control by the sequencer and according to the setup defined in the
configuration registers. Sequencer implements the main control logic
and
FSM to handle data transmit and data receive control of the shift
engine.

Signed-off-by: Chalapathi V 
---
  include/hw/ssi/pnv_spi.h    |   28 +
  hw/ppc/pnv_spi_controller.c | 1074
+++
  hw/ppc/trace-events |   15 +
  3 files changed, 1117 insertions(+)

diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h
index 244ee1cfc0..6e2bceab3b 100644
--- a/include/hw/ssi/pnv_spi.h
+++ b/include/hw/ssi/pnv_spi.h
@@ -8,6 +8,14 @@
   * This model Supports a connection to a single SPI responder.
   * Introduced for P10 to provide access to SPI seeproms, TPM, flash
device
   * and an ADC controller.
+ *
+ * All SPI function control is mapped into the SPI register space to
enable
+ * full control by firmware.
+ *
+ * SPI Controller has sequencer and shift engine. The SPI shift
engine
+ * performs serialization and de-serialization according to the
control by
+ * the sequencer and according to the setup defined in the
configuration
+ * registers and the SPI sequencer implements the main control
logic.
   */
  #include "hw/ssi/ssi.h"
@@ -29,6 +37,25 @@ typedef struct PnvSpiController {
  MemoryRegion    xscom_spic_regs;
  /* SPI controller object number */
  uint32_t    spic_num;
+    uint8_t transfer_len;
+    uint8_t responder_select;
+    /* To verify if shift_n1 happens prior to shift_n2 */
+    bool    shift_n1_done;
+    /* Loop counter for branch operation opcode Ex/Fx */
+    uint8_t loop_counter_1;
+    uint8_t loop_counter_2;
+    /* N1/N2_bits specifies the size of the N1/N2 segment of a frame
in bits.*/
+    uint8_t N1_bits;
+    uint8_t N2_bits;
+    /* Number of bytes in a payload for the N1/N2 frame segment.*/
+    uint8_t N1_bytes;
+    uint8_t N2_bytes;
+    /* Number of N1/N2 bytes marked for transmit */
+    uint8_t N1_tx;
+    uint8_t N2_tx;
+    /* Number of N1/N2 bytes marked for receive */
+    uint8_t N1_rx;
+    uint8_t N2_rx;
  /* SPI Controller registers */
  uint64_t    error_reg;
@@ -40,5 +67,6 @@ typedef struct PnvSpiController {
  uint64_t    receive_data_reg;
  uint8_t sequencer_operation_reg[SPI_CONTROLLER_REG_SIZE]
;
  uint64_t    status_reg;
+
  } PnvSpiController;
  #endif /* PPC_PNV_SPI_CONTROLLER_H */
diff --git a/hw/ppc/pnv_spi_controller.c
b/hw/ppc/pnv_spi_controller.c
index 11b119cf0f..e87f583074 100644
--- a/hw/ppc/pnv_spi_controller.c
+++ b/hw/ppc/pnv_spi_controller.c
@@ -19,6 +19,1072 @@
  #include "hw/irq.h"
  #include "trace.h"
+/* PnvXferBuffer */
+typedef struct PnvXferBuffer {
+
+    uint32_t    len;
+    uint8_t    *data;
+
+} PnvXferBuffer;
+
+/* pnv_spi_xfer_buffer_methods */
+static PnvXferBuffer *pnv_spi_xfer_buffer_new(void)
+{
+    PnvXferBuffer *payload = g_malloc0(sizeof(*payload));
+
+    return payload;
+}
+
+static void pnv_spi_xfer_buffer_free(PnvXferBuffer *payload)
+{
+    free(payload->data);
+    free(payload);
+}
+
+static uint8_t *pnv_spi_xfer_buffer_write_ptr(PnvXferBuffer
*payload,
+    uint32_t offset, uint32_t length)
+{
+    if (payload->len < (offset + length)) {
+    payload->len = offset + length;
+    payload->data = g_realloc(payload->data, payload->len);
+    }
+    return >data[offset];
+}
+
+static bool does_rdr_match(PnvSpiController *s)
+{
+    /*
+ * According to spec, the mask bits that are 0 are compared and
the
+ * bits that are 1 are ignored.
+ */
+    uint16_t rdr_match_mask =
GETFIELD(MEMORY_MAPPING_REG_RDR_MATCH_MASK,
+    s->memory_mapping_reg);
+    uint16_t rdr_match_val =
GETFIELD(MEMORY_MAPPING_REG_RDR_MATCH_VAL,
+    s->memory_mapping_reg);
+
+    if ((~rdr_match_mask & rdr_match_val) == ((~rdr_match_mask) &
+    GETFIELD(PPC_BITMASK(48, 63), s->receive_data_reg))) {
+    return true;
+    }
+    return false;
+}
+
+static uint8_t get_from_offset(PnvSpiController *s, uint8_t offset)
+{
+    uint8_t byte;
+
+    /*
+

Re: [PATCH v3 5/5] tests/qtest: Add pnv-spi-seeprom qtest

2024-05-20 Thread Cédric Le Goater

On 5/15/24 19:41, Chalapathi V wrote:

In this commit Write a qtest pnv-spi-seeprom-test to check the
SPI transactions between spi controller and seeprom device.

Signed-off-by: Chalapathi V 
---
  tests/qtest/pnv-spi-seeprom-test.c | 129 +
  tests/qtest/meson.build|   1 +
  2 files changed, 130 insertions(+)
  create mode 100644 tests/qtest/pnv-spi-seeprom-test.c

diff --git a/tests/qtest/pnv-spi-seeprom-test.c 
b/tests/qtest/pnv-spi-seeprom-test.c
new file mode 100644
index 00..bfa57f3234
--- /dev/null
+++ b/tests/qtest/pnv-spi-seeprom-test.c
@@ -0,0 +1,129 @@
+/*
+ * QTest testcase for PowerNV 10 Seeprom Communications
+ *
+ * Copyright (c) 2024, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include 
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bswap.h"
+#include "hw/ssi/pnv_spi_regs.h"
+
+#define P10_XSCOM_BASE  0x000603fcull
+#define SPIC2_XSCOM_BASE0xc0040
+
+/* To transmit READ opcode and address */
+#define READ_OP_TDR_DATA0x03000100
+/*
+ * N1 shift - tx 4 bytes (transmit opcode and address)
+ * N2 shift - tx and rx 8 bytes.
+ */
+#define READ_OP_COUNTER_CONFIG  0x20402b00
+/* SEQ_OP_SELECT_RESPONDER - N1 Shift - N2 Shift * 5 - SEQ_OP_STOP */
+#define READ_OP_SEQUENCER   0x1130404040404010
+
+/* To transmit WREN(Set Write Enable Latch in status0 register) opcode */
+#define WRITE_OP_WREN   0x0600
+/* To transmit WRITE opcode, address and data */
+#define WRITE_OP_TDR_DATA   0x0300010012345678
+/* N1 shift - tx 8 bytes (transmit opcode, address and data) */
+#define WRITE_OP_COUNTER_CONFIG 0x40002000
+/* SEQ_OP_SELECT_RESPONDER - N1 Shift - SEQ_OP_STOP */
+#define WRITE_OP_SEQUENCER  0x11301000
+
+static uint64_t pnv_xscom_addr(uint32_t pcba)
+{
+return P10_XSCOM_BASE | ((uint64_t) pcba << 3);
+}



I would prefer if the test used the pnv_xscom_addr() definition from
tests/qtest/pnv-xscom.h.


+static uint64_t pnv_spi_seeprom_xscom_addr(uint32_t reg)
+{
+return pnv_xscom_addr(SPIC2_XSCOM_BASE + reg);
+}
+
+static void pnv_spi_controller_xscom_write(QTestState *qts, uint32_t reg,
+uint64_t val)
+{
+qtest_writeq(qts, pnv_spi_seeprom_xscom_addr(reg), val);
+}
+
+static uint64_t pnv_spi_controller_xscom_read(QTestState *qts, uint32_t reg)
+{
+return qtest_readq(qts, pnv_spi_seeprom_xscom_addr(reg));
+}
+
+static void spi_seeprom_transaction(QTestState *qts)
+{
+/* SPI transactions to SEEPROM to read from SEEPROM image */
+pnv_spi_controller_xscom_write(qts, COUNTER_CONFIG_REG,
+READ_OP_COUNTER_CONFIG);
+pnv_spi_controller_xscom_write(qts, SEQUENCER_OPERATION_REG,
+READ_OP_SEQUENCER);
+pnv_spi_controller_xscom_write(qts, TRANSMIT_DATA_REG, READ_OP_TDR_DATA);
+pnv_spi_controller_xscom_write(qts, TRANSMIT_DATA_REG, 0);
+/* Read 5*8 bytes from SEEPROM at 0x100 */
+uint64_t rdr_val = pnv_spi_controller_xscom_read(qts, RECEIVE_DATA_REG);
+printf("RDR READ = 0x%lx\n", rdr_val);
+rdr_val = pnv_spi_controller_xscom_read(qts, RECEIVE_DATA_REG);
+rdr_val = pnv_spi_controller_xscom_read(qts, RECEIVE_DATA_REG);
+rdr_val = pnv_spi_controller_xscom_read(qts, RECEIVE_DATA_REG);
+rdr_val = pnv_spi_controller_xscom_read(qts, RECEIVE_DATA_REG);
+printf("RDR READ = 0x%lx\n", rdr_val);
+
+/* SPI transactions to SEEPROM to write to SEEPROM image */
+pnv_spi_controller_xscom_write(qts, COUNTER_CONFIG_REG,
+WRITE_OP_COUNTER_CONFIG);
+/* Set Write Enable Latch bit of status0 register */
+pnv_spi_controller_xscom_write(qts, SEQUENCER_OPERATION_REG,
+WRITE_OP_SEQUENCER);
+pnv_spi_controller_xscom_write(qts, TRANSMIT_DATA_REG, WRITE_OP_WREN);
+/* write 8 bytes to SEEPROM at 0x100 */
+pnv_spi_controller_xscom_write(qts, SEQUENCER_OPERATION_REG,
+WRITE_OP_SEQUENCER);
+pnv_spi_controller_xscom_write(qts, TRANSMIT_DATA_REG, WRITE_OP_TDR_DATA);
+}
+
+/* Find complete path of in_file in the current working directory */
+static void find_file(const char *in_file, char *in_path)
+{
+g_autofree char *cwd = g_get_current_dir();
+char *filepath = g_build_filename(cwd, in_file, NULL);
+if (!access(filepath, F_OK)) {
+strcpy(in_path, filepath);
+} else {
+strcpy(in_path, "");
+printf("File %s not found within %s\n", in_file, cwd);
+}
+}
+
+static void test_spi_seeprom(void)
+{
+QTestState *qts = NULL;
+char seepromfile[500];
+find_file("sbe_measurement_seeprom.bin.ecc", seepromfile);


hmm, could you generate the contents instead ?


+if (strcmp(seepromfile, "")) {
+printf("Starting QEMU with seeprom file.\n");
+qts = qtest_initf("-m 2G -machine powernv10 -smp 2,cores=2,"
+

Re: [PATCH v3 4/5] hw/ppc: SPI controller wiring to P10 chip

2024-05-20 Thread Cédric Le Goater

+ Phil

On 5/15/24 19:41, Chalapathi V wrote:

In this commit, create SPI controller on p10 chip and connect cs irq.

The QOM tree of spi controller and seeprom are.
/machine (powernv10-machine)
   /chip[0] (power10_v2.0-pnv-chip)
 /pib_spic[2] (pnv-spi-controller)
   /pnv-spi-bus.2 (SSI)
   /xscom-spi-controller-regs[0] (memory-region)

/machine (powernv10-machine)
   /peripheral-anon (container)
 /device[0] (25csm04)
   /WP#[0] (irq)
   /ssi-gpio-cs[0] (irq)

(qemu) qom-get /machine/peripheral-anon /device[76] "parent_bus"
"/machine/chip[0]/pib_spic[2]/pnv-spi-bus.2"

Signed-off-by: Chalapathi V 
---
  include/hw/ppc/pnv_chip.h   |  3 +++
  hw/ppc/pnv.c| 21 -
  hw/ppc/pnv_spi_controller.c |  8 
  3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 8589f3291e..d464858f79 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -6,6 +6,7 @@
  #include "hw/ppc/pnv_core.h"
  #include "hw/ppc/pnv_homer.h"
  #include "hw/ppc/pnv_n1_chiplet.h"
+#include "hw/ssi/pnv_spi.h"
  #include "hw/ppc/pnv_lpc.h"
  #include "hw/ppc/pnv_occ.h"
  #include "hw/ppc/pnv_psi.h"
@@ -118,6 +119,8 @@ struct Pnv10Chip {
  PnvSBE   sbe;
  PnvHomer homer;
  PnvN1Chiplet n1_chiplet;
+#define PNV10_CHIP_MAX_PIB_SPIC 6
+PnvSpiController pib_spic[PNV10_CHIP_MAX_PIB_SPIC];
  
  uint32_t nr_quads;

  PnvQuad  *quads;
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6e3a5ccdec..6850592a85 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1829,6 +1829,11 @@ static void pnv_chip_power10_instance_init(Object *obj)
  for (i = 0; i < pcc->i2c_num_engines; i++) {
  object_initialize_child(obj, "i2c[*]", >i2c[i], TYPE_PNV_I2C);
  }
+
+for (i = 0; i < PNV10_CHIP_MAX_PIB_SPIC ; i++) {
+object_initialize_child(obj, "pib_spic[*]", >pib_spic[i],
+TYPE_PNV_SPI_CONTROLLER);
+}
  }
  
  static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp)

@@ -2043,7 +2048,21 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
qdev_get_gpio_in(DEVICE(>psi),
 PSIHB9_IRQ_SBE_I2C));
  }
-
+/* PIB SPI Controller */
+for (i = 0; i < PNV10_CHIP_MAX_PIB_SPIC; i++) {
+object_property_set_int(OBJECT(>pib_spic[i]), "spic_num",
+i, _fatal);
+/* pib_spic[2] connected to 25csm04 which implements 1 byte transfer */
+object_property_set_int(OBJECT(>pib_spic[i]), "transfer_len",
+(i == 2) ? 1 : 4, _fatal);
+if (!sysbus_realize(SYS_BUS_DEVICE(OBJECT
+(>pib_spic[i])), errp)) {
+return;
+}
+pnv_xscom_add_subregion(chip, PNV10_XSCOM_PIB_SPIC_BASE +
+i * PNV10_XSCOM_PIB_SPIC_SIZE,
+>pib_spic[i].xscom_spic_regs);
+}
  }
  
  static void pnv_rainier_i2c_init(PnvMachineState *pnv)

diff --git a/hw/ppc/pnv_spi_controller.c b/hw/ppc/pnv_spi_controller.c
index e87f583074..3d47e932de 100644
--- a/hw/ppc/pnv_spi_controller.c
+++ b/hw/ppc/pnv_spi_controller.c
@@ -1067,9 +1067,17 @@ static void operation_sequencer(PnvSpiController *s)
  static void do_reset(DeviceState *dev)
  {
  PnvSpiController *s = PNV_SPICONTROLLER(dev);
+DeviceState *ssi_dev;
  
  trace_pnv_spi_reset();
  
+/* Connect cs irq */

+ssi_dev = ssi_get_cs(s->ssi_bus, 0);
+if (ssi_dev) {
+qemu_irq cs_line = qdev_get_gpio_in_named(ssi_dev, SSI_GPIO_CS, 0);
+qdev_connect_gpio_out_named(DEVICE(s), "cs", 0, cs_line);
+}
+
  /* Reset all N1 and N2 counters, and other constants */
  s->N2_bits = 0;
  s->N2_bytes = 0;


Reviewed-by: Cédric Le Goater 

Thanks,

C.




Re: [PATCH v3 3/5] hw/block: Add Microchip's 25CSM04 to m25p80

2024-05-19 Thread Cédric Le Goater

On 5/15/24 19:41, Chalapathi V wrote:

Add Microchip's 25CSM04 Serial EEPROM to m25p80.  25CSM04 provides 4 Mbits
of Serial EEPROM utilizing the Serial Peripheral Interface (SPI) compatible
bus. The device is organized as 524288 bytes of 8 bits each (512Kbyte) and
is optimized for use in consumer and industrial applications where reliable
and dependable nonvolatile memory storage is essential.

Signed-off-by: Chalapathi V 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/block/m25p80.c | 3 +++
  hw/ppc/Kconfig| 1 +
  2 files changed, 4 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 8dec134832..824a6c5c60 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -357,6 +357,9 @@ static const FlashPartInfo known_devices[] = {
.sfdp_read = m25p80_sfdp_w25q512jv },
  { INFO("w25q01jvq",   0xef4021,  0,  64 << 10, 2048, ER_4K),
.sfdp_read = m25p80_sfdp_w25q01jvq },
+
+/* Microchip */
+{ INFO("25csm04",  0x29cc00,  0x100,  64 << 10,  8, 0) },
  };
  
  typedef enum {

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 6f9670b377..a93430b734 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -40,6 +40,7 @@ config POWERNV
  select PCA9552
  select PCA9554
  select SSI
+select SSI_M25P80
  
  config PPC405

  bool





Re: [PATCH v3 1/5] ppc/pnv: Add SPI controller model

2024-05-19 Thread Cédric Le Goater

On 5/15/24 19:41, Chalapathi V wrote:

SPI controller device model supports a connection to a single SPI responder.
This provide access to SPI seeproms, TPM, flash device and an ADC controller.

All SPI function control is mapped into the SPI register space to enable full
control by firmware. In this commit SPI configuration component is modelled
which contains all SPI configuration and status registers as well as the hold
registers for data to be sent or having been received.

An existing QEMU SSI framework is used and SSI_BUS is created.

Signed-off-by: Chalapathi V 
---
  include/hw/ppc/pnv_xscom.h|   3 +
  include/hw/ssi/pnv_spi.h  |  44 +++
  include/hw/ssi/pnv_spi_regs.h | 114 +
  hw/ppc/pnv_spi_controller.c   | 228 ++


The file names are not consistent.

Please rename hw/ppc/pnv_spi_controller.c to /hw/ssi/pnv_spi.c.



  hw/ppc/Kconfig|   1 +
  hw/ppc/meson.build|   1 +
  hw/ppc/trace-events   |   6 +
  7 files changed, 397 insertions(+)
  create mode 100644 include/hw/ssi/pnv_spi.h
  create mode 100644 include/hw/ssi/pnv_spi_regs.h
  create mode 100644 hw/ppc/pnv_spi_controller.c

diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 6209e18492..a77b97f9b1 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -194,6 +194,9 @@ struct PnvXScomInterfaceClass {
  #define PNV10_XSCOM_PEC_PCI_BASE   0x8010800 /* index goes upwards ... */
  #define PNV10_XSCOM_PEC_PCI_SIZE   0x200
  
+#define PNV10_XSCOM_PIB_SPIC_BASE 0xc

+#define PNV10_XSCOM_PIB_SPIC_SIZE 0x20
+
  void pnv_xscom_init(PnvChip *chip, uint64_t size, hwaddr addr);
  int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
   uint64_t xscom_base, uint64_t xscom_size,
diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h
new file mode 100644
index 00..244ee1cfc0
--- /dev/null
+++ b/include/hw/ssi/pnv_spi.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU PowerPC SPI Controller model
+ *
+ * Copyright (c) 2024, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This model Supports a connection to a single SPI responder.
+ * Introduced for P10 to provide access to SPI seeproms, TPM, flash device
+ * and an ADC controller.
+ */
+#include "hw/ssi/ssi.h"
+
+#ifndef PPC_PNV_SPI_CONTROLLER_H
+#define PPC_PNV_SPI_CONTROLLER_H
+
+#define TYPE_PNV_SPI_CONTROLLER "pnv-spi-controller"
+#define PNV_SPICONTROLLER(obj) \
+OBJECT_CHECK(PnvSpiController, (obj), TYPE_PNV_SPI_CONTROLLER)


OBJECT_DECLARE_SIMPLE_TYPE(PnvSpiController, PNV_SPI_CONTROLLER)

which means PNV_SPICONTROLLER -> PNV_SPI_CONTROLLER


+
+#define SPI_CONTROLLER_REG_SIZE 8


please add a PNV_ prefix : PNV_SPI_CONTROLLER_REG_SIZE


+
+#define TYPE_PNV_SPI_BUS "pnv-spi-bus"
+typedef struct PnvSpiController {
+SysBusDevice parent_obj;
+
+SSIBus *ssi_bus;
+qemu_irq *cs_line;
+MemoryRegionxscom_spic_regs;
+/* SPI controller object number */
+uint32_tspic_num;
+
+/* SPI Controller registers */
+uint64_terror_reg;
+uint64_tcounter_config_reg;
+uint64_tconfig_reg1;
+uint64_tclock_config_reset_control;
+uint64_tmemory_mapping_reg;
+uint64_ttransmit_data_reg;
+uint64_treceive_data_reg;
+uint8_t sequencer_operation_reg[SPI_CONTROLLER_REG_SIZE];
+uint64_tstatus_reg;


I don't think the _reg suffix are needed. This is minor.


+} PnvSpiController;
+#endif /* PPC_PNV_SPI_CONTROLLER_H */
diff --git a/include/hw/ssi/pnv_spi_regs.h b/include/hw/ssi/pnv_spi_regs.h
new file mode 100644
index 00..6f613aca5e
--- /dev/null
+++ b/include/hw/ssi/pnv_spi_regs.h
@@ -0,0 +1,114 @@
+/*
+ * QEMU PowerPC SPI Controller model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef SPI_CONTROLLER_REGS_H
+#define SPI_CONTROLLER_REGS_H


please add a PNV_ prefix


+
+/* Error Register */
+#define ERROR_REG   0x00
+
+/* counter_config_reg */
+#define COUNTER_CONFIG_REG  0x01
+#define COUNTER_CONFIG_REG_SHIFT_COUNT_N1   PPC_BITMASK(0, 7)
+#define COUNTER_CONFIG_REG_SHIFT_COUNT_N2   PPC_BITMASK(8, 15)
+#define COUNTER_CONFIG_REG_COUNT_COMPARE1   PPC_BITMASK(24, 31)
+#define COUNTER_CONFIG_REG_COUNT_COMPARE2   PPC_BITMASK(32, 39)
+#define COUNTER_CONFIG_REG_N1_COUNT_CONTROL PPC_BITMASK(48, 51)
+#define COUNTER_CONFIG_REG_N2_COUNT_CONTROL PPC_BITMASK(52, 55)
+
+/* config_reg */
+#define CONFIG_REG1 0x02
+
+/* clock_config_reset_control_ecc_enable_reg */
+#define CLOCK_CONFIG_REG0x03
+#define CLOCK_CONFIG_RESET_CONTROL_HARD_RESET   0x0084;
+#define CLOCK_CONFIG_REG_RESET_CONTROL  PPC_BITMASK(24, 27)
+#define CLOCK_CONFIG_REG_ECC_CONTROLPPC_BITMASK(28, 30)
+
+/* 

Re: [PATCH v3 12/16] aspeed/soc: Add AST2700 support

2024-05-17 Thread Cédric Le Goater

On 4/19/24 09:58, Jamin Lin wrote:

Hi Cedric,

On 4/16/24 11:18, Jamin Lin wrote:

Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35

CPU).


AST2700 SOC and its interrupt controller are too complex to handle in
the common Aspeed SoC framework. We introduce a new ast2700 class with
instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting start from u-boot stage.
Set SDMC controller unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is
connected to GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 


Before I forget, please see a little comment below regarding user creatable
devices.

The model looks fine. The interrupt controller part is more complex than the
previous SoCs so I will come back to it later when I have more time.

Thanks for your kindly support.

---
   hw/arm/aspeed_ast27x0.c | 554



   hw/arm/meson.build  |   1 +
   include/hw/arm/aspeed_soc.h |  26 +-
   3 files changed, 579 insertions(+), 2 deletions(-)
   create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c new
file mode 100644 index 00..754c963230
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,554 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from
+datasheet */ static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+

Re: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-17 Thread Cédric Le Goater

Hello Jamin

On 5/15/24 11:01, Jamin Lin wrote:

Hi Cedric,

Sorry reply you late.

Hello Jamin,

To handle the DMA DRAM Side Address High register, we should reintroduce an
"dram-base" property which I removed a while ago. Something like :



diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index
7f32e43ff6f3..6d8ef6bc968f 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -76,6 +76,7 @@ struct AspeedSMCState {
   AddressSpace flash_as;
   MemoryRegion *dram_mr;
   AddressSpace dram_as;
+uint64_t dram_base;

   AddressSpace wdt2_as;
   MemoryRegion *wdt2_mr;
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
38858e4fdec1..3417949ad8a3 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -500,6 +500,8 @@ static void aspeed_soc_ast2700_realize(DeviceState
*dev, Error **errp)
   }

   /* FMC, The number of CS is set at the board level */
+object_property_set_int(OBJECT(>fmc), "dram-base",
+sc->memmap[ASPEED_DEV_SDRAM],
+ _abort);
   object_property_set_link(OBJECT(>fmc), "dram",
OBJECT(s->dram_mr),
_abort);
   if (!sysbus_realize(SYS_BUS_DEVICE(>fmc), errp)) { diff --git
a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
3fa783578e9e..29ebfc0fd8c8 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1372,6 +1372,7 @@ static const VMStateDescription
vmstate_aspeed_smc = {

   static Property aspeed_smc_properties[] = {
   DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure,
false),
+DEFINE_PROP_UINT64("dram-base", AspeedSMCState, dram_base, 0),
   DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
TYPE_MEMORY_REGION, MemoryRegion *),
   DEFINE_PROP_LINK("wdt2", AspeedSMCState, wdt2_mr,



I appreciate your kindly support and thanks for your suggestion.
Will add it.


See my aspeed-9.1 branch, I did some changes, mostly in the last patch.

* aspeed_smc_dma_len()

  - can use QEMU_ALIGN_UP(). simpler.

* aspeed_smc_dma_rw():

  - dram_addr ->  dma_dram_offset
  - There is no need to protect updates of the R_DMA_DRAM_ADDR_HIGH
register with aspeed_smc_has_dma_dram_addr_high() since it is
already protected with MMIO accesses. Skip the check and update
always.

* aspeed_smc_dma_dram_addr()

  - same as above.

You can merge the changes in the respective patches if you agree.

Still on the TODO list :

  - GIC review
  - aspeed/soc: fix incorrect dram size for AST2700
  




Thanks,

C.







With that, see below for more comments,

On 4/16/24 11:18, Jamin Lin wrote:

AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM

Side

Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram address, new
features and update trace-event to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
   hw/ssi/aspeed_smc.c | 66

+++--

   hw/ssi/trace-events |  2 +-
   2 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
71abc7a2d8..a67cac3d0f 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
   #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary

1: alternate */

   #define   FMC_WDT2_CTRL_EN   BIT(0)

+/* DMA DRAM Side Address High Part (AST2700) */
+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
   /* DMA Control/Status Register */
   #define R_DMA_CTRL(0x80 / 4)
   #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
*   0x1FF: 32M bytes
*/
   #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
   #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
   #define DMA_LENGTH(val) ((val) & 0x01FF)

@@ -207,6 +211,7 @@ static const AspeedSegments

aspeed_2500_spi2_segments[];

   #define ASPEED_SMC_FEATURE_DMA   0x1
   #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
   #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08

   static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
   {
@@ -218,6 +223,11 @@ static inline bool

aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)

   return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
   }

+static inline bool aspeed_smc_has_dma_dram_addr_high(const
+AspeedSMCClass *asc) {
+return !!(asc->features &

ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);

+}
+
   #define aspeed_smc_error(fmt, ...)

\

   qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ##
__VA_ARGS__)

@@ -747,6 +757,9 @@ static uint64_t aspeed_smc_read(void *opaque,

hwaddr addr, unsigned int size)

   (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
   (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR)


Re: [PATCH] hw/intc/s390_flic: Fix crash that occurs when saving the machine state

2024-05-17 Thread Cédric Le Goater

On 5/17/24 08:15, Thomas Huth wrote:

adapter_info_so_needed() treats its "opaque" parameter as a S390FLICState,
but the function belongs to a VMStateDescription that is attached to a
TYPE_VIRTIO_CCW_BUS device. This is currently causing a crash when the
user tries to save or migrate the VM state. Fix it by using s390_get_flic()
to get the correct device here instead.

Reported-by: Marc Hartmayer 
Fixes: 9d1b0f5bf5 ("s390_flic: add migration-enabled property")
Signed-off-by: Thomas Huth 



Reviewed-by: Cédric Le Goater 

Thanks,

C.



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

diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 7f93080087..6771645699 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -459,7 +459,7 @@ type_init(qemu_s390_flic_register_types)
  
  static bool adapter_info_so_needed(void *opaque)

  {
-S390FLICState *fs = S390_FLIC_COMMON(opaque);
+S390FLICState *fs = s390_get_flic();
  
  return fs->migration_enabled;

  }





Re: [PATCH 00/16] VFIO: misc cleanups part2

2024-05-16 Thread Cédric Le Goater

Hello Zhenzhong,

On 5/15/24 10:20, Zhenzhong Duan wrote:

Hi

This is the last round of cleanup series to change functions in hw/vfio/
to return bool when the error is passed through errp parameter.

The first round is at 
https://lists.gnu.org/archive/html/qemu-devel/2024-05/msg01147.html

I see Cédric is also working on some migration stuff cleanup,
so didn't touch migration.c, but all other files in hw/vfio/ are cleanup now.

Patch1 is a fix patch, all others are cleanup patches.

Test done on x86 platform:
vfio device hotplug/unplug with different backend
reboot

This series is rebased to https://github.com/legoater/qemu/tree/vfio-next


I queued part 1 in vfio-next with other changes. part 2 is in vfio-9.1
for now and should reach vfio-next after reviews next week.

Then, we have to work on your v5 [1] which should have all my attention
again after the next vfio PR. You, Joao and Eric have followups series
that need a resync on top of v5, possibly others [2] and [3], not sent
AFAICT. Anyhow, we will need inputs from these people and IOMMU
stakeholders/maintainers.

Thanks,

C.

[1] [PATCH v5 00/19] Add a host IOMMU device abstraction to check with vIOMMU

https://lore.kernel.org/qemu-devel/20240507092043.1172717-1-zhenzhong.d...@intel.com/

[2] [PATCH ats_vtd v2 00/25] ATS support for VT-d

https://lore.kernel.org/all/20240515071057.33990-1-clement.mathieu--d...@eviden.com/

[3] Add Tegra241 (Grace) CMDQV Support
https://lore.kernel.org/all/cover.1712978212.git.nicol...@nvidia.com/
https://github.com/nicolinc/qemu/commits/wip/iommufd_vcmdq/





Thanks
Zhenzhong

Zhenzhong Duan (16):
   vfio/display: Fix error path in call site of ramfb_setup()
   vfio/display: Make vfio_display_*() return bool
   vfio/helpers: Use g_autofree in hw/vfio/helpers.c
   vfio/helpers: Make vfio_set_irq_signaling() return bool
   vfio/helpers: Make vfio_device_get_name() return bool
   vfio/platform: Make vfio_populate_device() and vfio_base_device_init()
 return bool
   vfio/ccw: Make vfio_ccw_get_region() return a bool
   vfio/pci: Make vfio_intx_enable_kvm() return a bool
   vfio/pci: Make vfio_pci_relocate_msix() and vfio_msix_early_setup()
 return a bool
   vfio/pci: Make vfio_populate_device() return a bool
   vfio/pci: Make vfio_intx_enable() return bool
   vfio/pci: Make vfio_populate_vga() return bool
   vfio/pci: Make capability related functions return bool
   vfio/pci: Use g_autofree for vfio_region_info pointer
   vfio/pci-quirks: Make vfio_pci_igd_opregion_init() return bool
   vfio/pci-quirks: Make vfio_add_*_cap() return bool

  hw/vfio/pci.h |  12 +-
  include/hw/vfio/vfio-common.h |   6 +-
  hw/vfio/ap.c  |  10 +-
  hw/vfio/ccw.c |  25 ++--
  hw/vfio/display.c |  22 ++--
  hw/vfio/helpers.c |  33 ++---
  hw/vfio/igd.c |   5 +-
  hw/vfio/pci-quirks.c  |  50 
  hw/vfio/pci.c | 227 --
  hw/vfio/platform.c|  61 -
  10 files changed, 213 insertions(+), 238 deletions(-)






Re: [PATCH v2 00/11] VFIO: misc cleanups

2024-05-16 Thread Cédric Le Goater

On 5/7/24 08:42, Zhenzhong Duan wrote:

Hi

This is a cleanup series to change functions in hw/vfio/ to return bool
when the error is passed through errp parameter, also some cleanup
with g_autofree.

See discussion at 
https://lists.gnu.org/archive/html/qemu-devel/2024-04/msg04782.html

This series processed below files:
hw/vfio/container.c
hw/vfio/iommufd.c
hw/vfio/cpr.c
backends/iommufd.c

So above files are clean now, there are still other files need processing
in hw/vfio.

Test done on x86 platform:
vfio device hotplug/unplug with different backend
reboot

Thanks
Zhenzhong

Changelog:
v2:
- split out g_autofree code as a patch (Cédric)
- add processing for more files

Zhenzhong Duan (11):
   vfio/pci: Use g_autofree in vfio_realize
   vfio/pci: Use g_autofree in iommufd_cdev_get_info_iova_range()
   vfio: Make VFIOIOMMUClass::attach_device() and its wrapper return bool
   vfio: Make VFIOIOMMUClass::setup() return bool
   vfio: Make VFIOIOMMUClass::add_window() and its wrapper return bool
   vfio/container: Make vfio_connect_container() return bool
   vfio/container: Make vfio_set_iommu() return bool
   vfio/container: Make vfio_get_device() return bool
   vfio/iommufd: Make iommufd_cdev_*() return bool
   vfio/cpr: Make vfio_cpr_register_container() return bool
   backends/iommufd: Make iommufd_backend_*() return bool



Applied to vfio-next.

Thanks,

C.




Re: [PATCH v3 0/4] qapi/vfio: Add VFIO migration QAPI event

2024-05-16 Thread Cédric Le Goater

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

Hello,

This series adds a new QAPI event for VFIO device migration state
change. This event will be emitted when a VFIO device changes its
state, for example, during migration or when stopping/starting the
guest.

This event can be used by management applications to get updates on the
current state of the VFIO device for their own purposes.

A new per VFIO device capability, "migration-events", is added so events
can be enabled only for the required devices. It is disabled by default.

Feedback/comments are appreciated,



Applied to vfio-next.

Thanks,

C.




Thanks.

Changes from v2 [2]:
* Added assert for vbasedev->ops->vfio_get_object and obj. (Cedric)
* Renamed set_state() to vfio_migration_set_device_state(). (Cedric)
* Enhanced tracing of device state change. (Cedric)
* Added Cedric's R-b.

Changes from v1 [1]:
* Added more info to patch #1 commit mesasge. (Markus)
* Renamed VFIODeviceMigState to VfioMigrationState and
   VFIO_DEVICE_MIG_STATE_CHANGED to VFIO_MIGRATION. (Joao, Markus)
* Added qom-path and qdev id to VFIO_MIGRATION event data. (Markus)
* Handled no-op state transitions in vfio_migration_set_state().
   (Cedric)
* Added helper to set VFIO state and emit VFIO event. (Peter)

[1]
https://lore.kernel.org/qemu-devel/20240430051621.19597-1-avih...@nvidia.com/

[2]
https://lore.kernel.org/qemu-devel/20240509090954.16447-1-avih...@nvidia.com/

Avihai Horon (4):
   qapi/vfio: Add VFIO migration QAPI event
   vfio/migration: Emit VFIO migration QAPI event
   vfio/migration: Don't emit STOP_COPY VFIO migration QAPI event twice
   vfio/migration: Enhance VFIO migration state tracing

  MAINTAINERS   |  1 +
  qapi/qapi-schema.json |  1 +
  qapi/vfio.json| 67 +
  include/hw/vfio/vfio-common.h |  1 +
  hw/vfio/migration.c   | 71 ---
  hw/vfio/pci.c |  2 +
  hw/vfio/trace-events  |  3 +-
  qapi/meson.build  |  1 +
  8 files changed, 141 insertions(+), 6 deletions(-)
  create mode 100644 qapi/vfio.json






Re: [PATCH v4] vfio/pci: migration: Skip config space check for Vendor Specific Information in VSC during restore/load

2024-05-16 Thread Cédric Le Goater

On 5/3/24 16:51, Vinayak Kale wrote:

In case of migration, during restore operation, qemu checks config space of the
pci device with the config space in the migration stream captured during save
operation. In case of config space data mismatch, restore operation is failed.

config space check is done in function get_pci_config_device(). By default VSC
(vendor-specific-capability) in config space is checked.

Due to qemu's config space check for VSC, live migration is broken across NVIDIA
vGPU devices in situation where source and destination host driver is different.
In this situation, Vendor Specific Information in VSC varies on the destination
to ensure vGPU feature capabilities exposed to the guest driver are compatible
with destination host.

If a vfio-pci device is migration capable and vfio-pci vendor driver is OK with
volatile Vendor Specific Info in VSC then qemu should exempt config space check
for Vendor Specific Info. It is vendor driver's responsibility to ensure that
VSC is consistent across migration. Here consistency could mean that VSC format
should be same on source and destination, however actual Vendor Specific Info
may not be byte-to-byte identical.

This patch skips the check for Vendor Specific Information in VSC for VFIO-PCI
device by clearing pdev->cmask[] offsets. Config space check is still enforced
for 3 byte VSC header. If cmask[] is not set for an offset, then qemu skips
config space check for that offset.

VSC check is skipped for machine types >= 9.1. The check would be enforced on
older machine types (<= 9.0).

Signed-off-by: Vinayak Kale 
Cc: Alex Williamson 
Cc: Michael S. Tsirkin 
Cc: Cédric Le Goater 




Applied to vfio-next.

Thanks,

C.



---
Version History
v3->v4:
 - VSC check is skipped for machine types >= 9.1. The check would be 
enforced
   on older machine types (<= 9.0).
v2->v3:
 - Config space check skipped only for Vendor Specific Info in VSC, check is
   still enforced for 3 byte VSC header.
 - Updated commit description with live migration failure scenario.
v1->v2:
 - Limited scope of change to vfio-pci devices instead of all pci devices.

  hw/core/machine.c |  1 +
  hw/vfio/pci.c | 26 ++
  hw/vfio/pci.h |  1 +
  3 files changed, 28 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 4ff60911e7..fc3eb5115f 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -35,6 +35,7 @@
  
  GlobalProperty hw_compat_9_0[] = {

  {"arm-cpu", "backcompat-cntfrq", "true" },
+{"vfio-pci", "skip-vsc-check", "false" },
  };
  const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0);
  
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c

index 64780d1b79..2ece9407cc 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2134,6 +2134,28 @@ static void vfio_check_af_flr(VFIOPCIDevice *vdev, 
uint8_t pos)
  }
  }
  
+static int vfio_add_vendor_specific_cap(VFIOPCIDevice *vdev, int pos,

+uint8_t size, Error **errp)
+{
+PCIDevice *pdev = >pdev;
+
+pos = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, size, errp);
+if (pos < 0) {
+return pos;
+}
+
+/*
+ * Exempt config space check for Vendor Specific Information during
+ * restore/load.
+ * Config space check is still enforced for 3 byte VSC header.
+ */
+if (vdev->skip_vsc_check && size > 3) {
+memset(pdev->cmask + pos + 3, 0, size - 3);
+}
+
+return pos;
+}
+
  static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos, Error **errp)
  {
  ERRP_GUARD();
@@ -2202,6 +2224,9 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t 
pos, Error **errp)
  vfio_check_af_flr(vdev, pos);
  ret = pci_add_capability(pdev, cap_id, pos, size, errp);
  break;
+case PCI_CAP_ID_VNDR:
+ret = vfio_add_vendor_specific_cap(vdev, pos, size, errp);
+break;
  default:
  ret = pci_add_capability(pdev, cap_id, pos, size, errp);
  break;
@@ -3390,6 +3415,7 @@ static Property vfio_pci_dev_properties[] = {
  DEFINE_PROP_LINK("iommufd", VFIOPCIDevice, vbasedev.iommufd,
   TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *),
  #endif
+DEFINE_PROP_BOOL("skip-vsc-check", VFIOPCIDevice, skip_vsc_check, true),
  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h

index 6e64a2654e..92cd62d115 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -177,6 +177,7 @@ struct VFIOPCIDevice {
  OnOffAuto ramfb_migrate;
  bool defer_kvm_irq_routing;
  bool clear_parent_atomics_on_exit;
+bool skip_vsc_check;
  VFIODisplay *dpy;
  Notifier irqchip_change_notifier;
  };





Re: [PATCH v2 1/4] vfio/ap: Use g_autofree variable in vfio_ap_register_irq_notifier()

2024-05-16 Thread Cédric Le Goater



Applied series to vfio-next.

Thanks,

C.

On 4/25/24 11:02, Cédric Le Goater wrote:

Signed-off-by: Cédric Le Goater 
---
  hw/vfio/ap.c | 10 +++---
  1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 
7c4caa5938636937680fec87e999249ac84a4498..03f8ffaa5e2bf13cf8daa2f44aa4cf17809abd94
 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -77,7 +77,7 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
  size_t argsz;
  IOHandler *fd_read;
  EventNotifier *notifier;
-struct vfio_irq_info *irq_info;
+g_autofree struct vfio_irq_info *irq_info = NULL;
  VFIODevice *vdev = >vdev;
  
  switch (irq) {

@@ -104,14 +104,14 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
  if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
irq_info) < 0 || irq_info->count < 1) {
  error_setg_errno(errp, errno, "vfio: Error getting irq info");
-goto out_free_info;
+return;
  }
  
  if (event_notifier_init(notifier, 0)) {

  error_setg_errno(errp, errno,
   "vfio: Unable to init event notifier for irq (%d)",
   irq);
-goto out_free_info;
+return;
  }
  
  fd = event_notifier_get_fd(notifier);

@@ -122,10 +122,6 @@ static void vfio_ap_register_irq_notifier(VFIOAPDevice 
*vapdev,
  qemu_set_fd_handler(fd, NULL, NULL, vapdev);
  event_notifier_cleanup(notifier);
  }
-
-out_free_info:
-g_free(irq_info);
-
  }
  
  static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev,





Re: [PATCH v7 0/9] vfio: Improve error reporting (part 2)

2024-05-16 Thread Cédric Le Goater

On 5/16/24 14:46, Cédric Le Goater wrote:

Hello,

The motivation behind these changes is to improve error reporting to
the upper management layer (libvirt) with a more detailed error, this
to let it decide, depending on the reported error, whether to try
migration again later. It would be useful in cases where migration
fails due to lack of HW resources on the host. For instance, some
adapters can only initiate a limited number of simultaneous dirty
tracking requests and this imposes a limit on the the number of VMs
that can be migrated simultaneously.

We are not quite ready for such a mechanism but what we can do first is
to cleanup the error reporting in the early save_setup sequence. This
is what the following changes propose, by adding an Error** argument to
various handlers and propagating it to the core migration subsystem.

The first part [1] of this series modifying the core migration
subsystem is now merged. This is the second part changing VFIO which
was already proposed in March. See [2].

Thanks,

C.

[1] [PATCH for-9.1 v5 00/14] migration: Improve error reporting
 https://lore.kernel.org/qemu-devel/20240320064911.545001-1-...@redhat.com/

[2] [PATCH v4 00/25] migration: Improve error reporting
 https://lore.kernel.org/qemu-devel/20240306133441.2351700-1-...@redhat.com/

Changes in v7:

  - Commit log improvements (Eric)
  - vfio_set_migration_error() : err -> ret rename (Eric)
  - vfio_migration_set_state() :
Introduced an error prefix to remove redundancy in error messages (Eric)
Commented error_report when setting the device in recover state fails (Eric)
  - vfio_migration_state_notifier() :
Remove useless assignment of local ret variable (Avihai)
Rephrased comment regarding MigrationNotifyFunc API (Avihai)
  - Fixed even more line wrapping of *dirty_bitmap() routines (Avihai)
  - vfio_sync_dirty_bitmap()
Fixed return when vfio_sync_ram_discard_listener_dirty_bitmap() is called 
(Avihai)


I fixed this last issue as commented in patch 8. Let's address other
issues, if minor, with followup patches.

Applied to vfio-next.

Thanks,

C.




Changes in v6:

  - Commit log improvements (Avihai)
  - Modified some titles (Avihai)
  - vfio_migration_set_state() : Dropped the error_setg_errno()
change when setting device in recover state fails  (Avihai)
  - vfio_migration_state_notifier() : report local error (Avihai)
  - vfio_save_device_config_state() : Set errp if the migration
stream is in error (Avihai)
  - vfio_save_state() : Changed error prefix  (Avihai)
  - vfio_iommu_map_dirty_notify() : Modified goto label  (Avihai)
  - Fixed memory_get_xlat_addr documentation (Avihai)
  - Fixed line wrapping (Avihai)
  - Fixed query_dirty_bitmap documentation (Avihai)
  - Dropped last patch from v5 :
vfio: Extend vfio_set_migration_error() with Error* argument

Changes in v5:

  - Rebased on 20c64c8a51a4 ("migration: migration_file_set_error")
  - Fixed typo in set_dirty_page_tracking documentation
  - Used error_setg_errno() in vfio_devices_dma_logging_start()
  - Replaced error_setg() by error_setg_errno() in vfio_migration_set_state()
  - 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()

Cédric Le Goater (9):
   vfio: Add Error** argument to .set_dirty_page_tracking() handler
   vfio: Add Error** argument to vfio_devices_dma_logging_start()
   migration: Extend migration_file_set_error() with Error* argument
   vfio/migration: Add an Error** argument to vfio_migration_set_state()
   vfio/migration: Add Error** argument to .vfio_save_config() handler
   vfio: Reverse test on vfio_get_xlat_addr()
   memory: Add Error** argument to memory_get_xlat_addr()
   vfio: Add Error** argument to .get_dirty_bitmap() handler
   vfio: Also trace event failures in vfio_save_complete_precopy()

  include/exec/memory.h |  15 +++-
  include/hw/vfio/vfio-common.h |  30 ++-
  include/hw/vfio/vfio-container-base.h |  37 +++--
  include/migration/misc.h  |   2 +-
  hw/vfio/common.c  | 113 --
  hw/vfio/container-base.c  |  10 +--
  hw/vfio/container.c   |  20 +++--
  hw/vfio/migration.c   | 109 -
  hw/vfio/pci.c |   5 +-
  hw/virtio/vhost-vdpa.c|   5 +-
  migration/migration.c |   6 +-
  system/memory.c   |  10 +--
  12 files changed, 246 insertions(+), 116 deletions(-)






Re: [PATCH v7 8/9] vfio: Add Error** argument to .get_dirty_bitmap() handler

2024-05-16 Thread Cédric Le Goater

On 5/16/24 14:46, Cédric Le Goater wrote:

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

Reviewed-by: Eric Auger 
Reviewed-by: Avihai Horon 
Signed-off-by: Cédric Le Goater 
---

  Changes in v7:
  
  - Fixed even more line wrapping of *dirty_bitmap() routines (Avihai)

  - vfio_sync_dirty_bitmap()
Fixed return when vfio_sync_ram_discard_listener_dirty_bitmap() is called 
(Avihai)

  include/hw/vfio/vfio-common.h |  5 +--

  include/hw/vfio/vfio-container-base.h | 19 +++--
  hw/vfio/common.c  | 60 +--
  hw/vfio/container-base.c  |  6 +--
  hw/vfio/container.c   | 14 ---
  5 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 
3ff633ad3b395e953a55683f5f0308bca50af3dd..b6ac24953667bc5f72f28480a6bf0f4722069cb9
 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -273,10 +273,9 @@ vfio_devices_all_running_and_mig_active(const 
VFIOContainerBase *bcontainer);
  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);
+VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
  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..b04057ad1aff73d974ecec718d0fe45f7a930b59
 100644
--- a/include/hw/vfio/vfio-container-base.h
+++ b/include/hw/vfio/vfio-container-base.h
@@ -84,8 +84,7 @@ void vfio_container_del_section_window(VFIOContainerBase 
*bcontainer,
  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);
+   VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp);
  
  void vfio_container_init(VFIOContainerBase *bcontainer,

   VFIOAddressSpace *space,
@@ -138,9 +137,21 @@ struct VFIOIOMMUClass {
   */
  int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer,
 bool start, Error **errp);
+/**
+ * @query_dirty_bitmap
+ *
+ * Get bitmap of dirty pages from container
+ *
+ * @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);
+VFIOBitmap *vbmap, 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 
7313043f1d161ed0326b5ba3fa1085608eaf6740..21910802c0c58a0efdb07d31c5a709660e89e328
 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1140,8 +1140,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)
+ VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp)
  {
  VFIODevice *vbasedev;
  int ret;
@@ -1150,10 +1149,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 (%s)",
- vbasedev->name, iova, size, ret, strerror(-ret));
+error_setg_errno(errp, -ret,
+ "%s: Failed to get DMA logging report, iova: "

[PATCH v7 3/9] migration: Extend migration_file_set_error() with Error* argument

2024-05-16 Thread Cédric Le Goater
Use it to update the current error of the migration stream if
available and if not, simply print out the error. Next changes will
update with an error to report.

Reviewed-by: Avihai Horon 
Acked-by: Fabiano Rosas 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---

 Changes in v7:

 - vfio_set_migration_error() err -> ret rename (Eric)
 
 include/migration/misc.h | 2 +-
 hw/vfio/common.c | 4 ++--
 hw/vfio/migration.c  | 4 ++--
 migration/migration.c| 6 --
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/include/migration/misc.h b/include/migration/misc.h
index 
bf7339cc1e6430226127fb6a878d06b458170858..bfadc5613bac614a316e5aed7da95d8c7845cf42
 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -97,7 +97,7 @@ void migration_add_notifier_mode(NotifierWithReturn *notify,
 
 void migration_remove_notifier(NotifierWithReturn *notify);
 bool migration_is_running(void);
-void migration_file_set_error(int err);
+void migration_file_set_error(int ret, Error *err);
 
 /* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
 bool migration_in_incoming_postcopy(void);
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 
b5102f54a6474a50c6366e8fbce23812d55e384e..2c97de6c730d963d961bf81c0831326c0e25afa7
 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 != _space_memory;
 }
 
-static void vfio_set_migration_error(int err)
+static void vfio_set_migration_error(int ret)
 {
 if (migration_is_setup_or_active()) {
-migration_file_set_error(err);
+migration_file_set_error(ret, NULL);
 }
 }
 
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
06ae40969b6c19037e190008e14f28be646278cd..bf2fd0759ba6e4fb103cc5c1a43edb180a3d0de4
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -726,7 +726,7 @@ static void vfio_vmstate_change_prepare(void *opaque, bool 
running,
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change_prepare(vbasedev->name, running,
@@ -756,7 +756,7 @@ static void vfio_vmstate_change(void *opaque, bool running, 
RunState state)
  * Migration should be aborted in this case, but vm_state_notify()
  * currently does not support reporting failures.
  */
-migration_file_set_error(ret);
+migration_file_set_error(ret, NULL);
 }
 
 trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
diff --git a/migration/migration.c b/migration/migration.c
index 
e88b24f1e6cbe82dad3f890c00e264d2ab6ad355..70d66a441bf04761decf91dbe57ce52c57fde58f
 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2994,13 +2994,15 @@ static MigThrError postcopy_pause(MigrationState *s)
 }
 }
 
-void migration_file_set_error(int err)
+void migration_file_set_error(int ret, Error *err)
 {
 MigrationState *s = current_migration;
 
 WITH_QEMU_LOCK_GUARD(>qemu_file_lock) {
 if (s->to_dst_file) {
-qemu_file_set_error(s->to_dst_file, err);
+qemu_file_set_error_obj(s->to_dst_file, ret, err);
+} else if (err) {
+error_report_err(err);
 }
 }
 }
-- 
2.45.0




[PATCH v7 9/9] vfio: Also trace event failures in vfio_save_complete_precopy()

2024-05-16 Thread Cédric Le Goater
vfio_save_complete_precopy() currently returns before doing the trace
event. Change that.

Reviewed-by: Avihai Horon 
Reviewed-by: Eric Auger 
Signed-off-by: Cédric Le Goater 
---
 hw/vfio/migration.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 
5d91364f3bbc34060d84b4b4b1823eadbc7b12bf..c4403a38ddb5e7e09fbcde0ad4132653ecaf0d24
 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -589,9 +589,6 @@ static int vfio_save_complete_precopy(QEMUFile *f, void 
*opaque)
 
 qemu_put_be64(f, VFIO_MIG_FLAG_END_OF_STATE);
 ret = qemu_file_get_error(f);
-if (ret) {
-return ret;
-}
 
 trace_vfio_save_complete_precopy(vbasedev->name, ret);
 
-- 
2.45.0




  1   2   3   4   5   6   7   8   9   10   >