Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-05 Thread Cédric Le Goater

On 6/5/25 17:16, Steven Sistare wrote:

On 6/4/2025 11:02 PM, Duan, Zhenzhong wrote:

-Original Message-
From: Steven Sistare 
Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

On 6/3/2025 11:55 PM, Duan, Zhenzhong wrote:

-Original Message-
From: Steven Sistare 
Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:

-Original Message-
From: Steve Sistare 
Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

If vfio_realize fails after vfio_device_attach, it should call
vfio_device_detach during error recovery.  If it fails after
vfio_device_get_name, it should free vbasedev->name.  If it fails
after vfio_pci_config_setup, it should free vdev->msix.

To fix all, call vfio_pci_put_device().

Signed-off-by: Steve Sistare 
---
hw/vfio/pci.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a1bfdfe..7d3b9ff 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3296,6 +3296,7 @@ out_teardown:
   vfio_bars_exit(vdev);
error:
   error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
+    vfio_pci_put_device(vdev);


Double free, vfio_pci_put_device() is also called in vfio_instance_finalize().


Agreed, this line must be deleted.
Cedric, this must be fixed in vfio-next.



yes. It was not merged.

Thanks to you both for the analysis. I lacked the time.

C.





Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-05 Thread Steven Sistare

On 6/4/2025 11:02 PM, Duan, Zhenzhong wrote:

-Original Message-
From: Steven Sistare 
Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

On 6/3/2025 11:55 PM, Duan, Zhenzhong wrote:

-Original Message-
From: Steven Sistare 
Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:

-Original Message-
From: Steve Sistare 
Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

If vfio_realize fails after vfio_device_attach, it should call
vfio_device_detach during error recovery.  If it fails after
vfio_device_get_name, it should free vbasedev->name.  If it fails
after vfio_pci_config_setup, it should free vdev->msix.

To fix all, call vfio_pci_put_device().

Signed-off-by: Steve Sistare 
---
hw/vfio/pci.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a1bfdfe..7d3b9ff 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3296,6 +3296,7 @@ out_teardown:
   vfio_bars_exit(vdev);
error:
   error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
+vfio_pci_put_device(vdev);


Double free, vfio_pci_put_device() is also called in vfio_instance_finalize().


Agreed, this line must be deleted.
Cedric, this must be fixed in vfio-next.


If vfio_realize fails with an error, vfio_instance_finalize is not called.
I tested that.


Have you tried with hot plugged device?


Not before, but I just tried it now, thanks for the suggestion.
Same result -- vfio_instance_finalize is not called.


That's strange, I tried below change with hotplug a device through qmp, I see 
"vfio_instance_finalize called"

device_add vfio-pci,host=04:10.1,id=vfio0,bus=root0,iommufd=iommufd0

--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3167,6 +3167,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)

  trace_vfio_mdev(vbasedev->name, vbasedev->mdev);

+error_setg(errp, "faking error in vfio_realize");
+goto error;


Thank you, with this I see finalize being called.

In my test, I had injected an error as late as possible in realize, to verify 
all
state is unwound, and I did it wrong:

vfio_register_err_notifier(vdev);
vfio_register_req_notifier(vdev);
vfio_setup_resetfn_quirk(vdev);

error_setg(errp, "forced error");
goto out_deregister;

return;
  out_deregister:

and finalize is not called.  Probably some reference is taken in those last few
function calls, and is not released.

This is correct, and calls finalize:

error_setg(errp, "forced error");
goto out_deregister;

vfio_register_err_notifier(vdev);
vfio_register_req_notifier(vdev);
vfio_setup_resetfn_quirk(vdev);

return;
  out_deregister:

- Steve




RE: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-04 Thread Duan, Zhenzhong


>-Original Message-
>From: Steven Sistare 
>Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>
>On 6/3/2025 11:55 PM, Duan, Zhenzhong wrote:
>>> -Original Message-
>>> From: Steven Sistare 
>>> Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>>>
>>> On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:
>>>>> -Original Message-
>>>>> From: Steve Sistare 
>>>>> Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>>>>>
>>>>> If vfio_realize fails after vfio_device_attach, it should call
>>>>> vfio_device_detach during error recovery.  If it fails after
>>>>> vfio_device_get_name, it should free vbasedev->name.  If it fails
>>>>> after vfio_pci_config_setup, it should free vdev->msix.
>>>>>
>>>>> To fix all, call vfio_pci_put_device().
>>>>>
>>>>> Signed-off-by: Steve Sistare 
>>>>> ---
>>>>> hw/vfio/pci.c | 1 +
>>>>> 1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>>>>> index a1bfdfe..7d3b9ff 100644
>>>>> --- a/hw/vfio/pci.c
>>>>> +++ b/hw/vfio/pci.c
>>>>> @@ -3296,6 +3296,7 @@ out_teardown:
>>>>>   vfio_bars_exit(vdev);
>>>>> error:
>>>>>   error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
>>>>> +vfio_pci_put_device(vdev);
>>>>
>>>> Double free, vfio_pci_put_device() is also called in 
>>>> vfio_instance_finalize().
>>>
>>> If vfio_realize fails with an error, vfio_instance_finalize is not called.
>>> I tested that.
>>
>> Have you tried with hot plugged device?
>
>Not before, but I just tried it now, thanks for the suggestion.
>Same result -- vfio_instance_finalize is not called.

That's strange, I tried below change with hotplug a device through qmp, I see 
"vfio_instance_finalize called"

device_add vfio-pci,host=04:10.1,id=vfio0,bus=root0,iommufd=iommufd0

--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3167,6 +3167,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)

 trace_vfio_mdev(vbasedev->name, vbasedev->mdev);

+error_setg(errp, "faking error in vfio_realize");
+goto error;
+
 if (vbasedev->ram_block_discard_allowed && !vbasedev->mdev) {
 error_setg(errp, "x-balloon-allowed only potentially compatible "
"with mdev devices");
@@ -3301,6 +3304,8 @@ error:
 static void vfio_instance_finalize(Object *obj)
 {
 VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj);
+printf("vfio_instance_finalize called\n");
+exit(1);

 vfio_display_finalize(vdev);
 vfio_bars_finalize(vdev);


Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-04 Thread Steven Sistare

On 6/3/2025 11:55 PM, Duan, Zhenzhong wrote:

-Original Message-
From: Steven Sistare 
Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:

-Original Message-
From: Steve Sistare 
Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

If vfio_realize fails after vfio_device_attach, it should call
vfio_device_detach during error recovery.  If it fails after
vfio_device_get_name, it should free vbasedev->name.  If it fails
after vfio_pci_config_setup, it should free vdev->msix.

To fix all, call vfio_pci_put_device().

Signed-off-by: Steve Sistare 
---
hw/vfio/pci.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a1bfdfe..7d3b9ff 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3296,6 +3296,7 @@ out_teardown:
  vfio_bars_exit(vdev);
error:
  error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
+vfio_pci_put_device(vdev);


Double free, vfio_pci_put_device() is also called in vfio_instance_finalize().


If vfio_realize fails with an error, vfio_instance_finalize is not called.
I tested that.


Have you tried with hot plugged device?


Not before, but I just tried it now, thanks for the suggestion.
Same result -- vfio_instance_finalize is not called.

- Steve


Early free of vdev->vbasedev.name will also break something, e.g.,

trace_vfio_region_finalize(region->vbasedev->name, region->nr);

All unwinding and calling functions that might use the name is done in the
vfio_realize
failure path, and the very last operation is vfio_pci_put_device, and the last
operation
of that function is freeing the name string.

- Steve


static void vfio_instance_finalize(Object *obj)
--
1.8.3.1









RE: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-03 Thread Duan, Zhenzhong


>-Original Message-
>From: Steven Sistare 
>Subject: Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>
>On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:
>>> -Original Message-
>>> From: Steve Sistare 
>>> Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>>>
>>> If vfio_realize fails after vfio_device_attach, it should call
>>> vfio_device_detach during error recovery.  If it fails after
>>> vfio_device_get_name, it should free vbasedev->name.  If it fails
>>> after vfio_pci_config_setup, it should free vdev->msix.
>>>
>>> To fix all, call vfio_pci_put_device().
>>>
>>> Signed-off-by: Steve Sistare 
>>> ---
>>> hw/vfio/pci.c | 1 +
>>> 1 file changed, 1 insertion(+)
>>>
>>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>>> index a1bfdfe..7d3b9ff 100644
>>> --- a/hw/vfio/pci.c
>>> +++ b/hw/vfio/pci.c
>>> @@ -3296,6 +3296,7 @@ out_teardown:
>>>  vfio_bars_exit(vdev);
>>> error:
>>>  error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
>>> +vfio_pci_put_device(vdev);
>>
>> Double free, vfio_pci_put_device() is also called in 
>> vfio_instance_finalize().
>
>If vfio_realize fails with an error, vfio_instance_finalize is not called.
>I tested that.

Have you tried with hot plugged device?

>
>> Early free of vdev->vbasedev.name will also break something, e.g.,
>trace_vfio_region_finalize(region->vbasedev->name, region->nr);
>
>All unwinding and calling functions that might use the name is done in the
>vfio_realize
>failure path, and the very last operation is vfio_pci_put_device, and the last
>operation
>of that function is freeing the name string.
>
>- Steve
>
>>> static void vfio_instance_finalize(Object *obj)
>>> --
>>> 1.8.3.1
>>



Re: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-03 Thread Steven Sistare

On 6/3/2025 6:40 AM, Duan, Zhenzhong wrote:

-Original Message-
From: Steve Sistare 
Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

If vfio_realize fails after vfio_device_attach, it should call
vfio_device_detach during error recovery.  If it fails after
vfio_device_get_name, it should free vbasedev->name.  If it fails
after vfio_pci_config_setup, it should free vdev->msix.

To fix all, call vfio_pci_put_device().

Signed-off-by: Steve Sistare 
---
hw/vfio/pci.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index a1bfdfe..7d3b9ff 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3296,6 +3296,7 @@ out_teardown:
 vfio_bars_exit(vdev);
error:
 error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
+vfio_pci_put_device(vdev);


Double free, vfio_pci_put_device() is also called in vfio_instance_finalize().


If vfio_realize fails with an error, vfio_instance_finalize is not called.
I tested that.


Early free of vdev->vbasedev.name will also break something, e.g., 
trace_vfio_region_finalize(region->vbasedev->name, region->nr);


All unwinding and calling functions that might use the name is done in the 
vfio_realize
failure path, and the very last operation is vfio_pci_put_device, and the last 
operation
of that function is freeing the name string.

- Steve


static void vfio_instance_finalize(Object *obj)
--
1.8.3.1







RE: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure

2025-06-03 Thread Duan, Zhenzhong



>-Original Message-
>From: Steve Sistare 
>Subject: [PATCH V4 04/43] vfio/pci: vfio_pci_put_device on failure
>
>If vfio_realize fails after vfio_device_attach, it should call
>vfio_device_detach during error recovery.  If it fails after
>vfio_device_get_name, it should free vbasedev->name.  If it fails
>after vfio_pci_config_setup, it should free vdev->msix.
>
>To fix all, call vfio_pci_put_device().
>
>Signed-off-by: Steve Sistare 
>---
> hw/vfio/pci.c | 1 +
> 1 file changed, 1 insertion(+)
>
>diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>index a1bfdfe..7d3b9ff 100644
>--- a/hw/vfio/pci.c
>+++ b/hw/vfio/pci.c
>@@ -3296,6 +3296,7 @@ out_teardown:
> vfio_bars_exit(vdev);
> error:
> error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name);
>+vfio_pci_put_device(vdev);

Double free, vfio_pci_put_device() is also called in vfio_instance_finalize().
Early free of vdev->vbasedev.name will also break something, e.g., 
trace_vfio_region_finalize(region->vbasedev->name, region->nr);

> }
>
> static void vfio_instance_finalize(Object *obj)
>--
>1.8.3.1