* [PATCH 0/2] fix two issues related to the driver.
@ 2026-08-03 2:18 Longfang Liu
2026-08-03 2:18 ` [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough Longfang Liu
2026-08-03 2:18 ` [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size Longfang Liu
0 siblings, 2 replies; 8+ messages in thread
From: Longfang Liu @ 2026-08-03 2:18 UTC (permalink / raw)
To: alex.williamson, jgg; +Cc: kvm, linux-kernel, liulongfang
This series fixes two issues in the HiSilicon ACC VFIO migration
driver: a calltrace when a PF is passed through to a VM and migrated,
guarded by NULL pf_qm checks and pdev->is_virtfn selection; and VF
BAR2 mmap rejection on 64KB-page kernels, fixed by aligning the mmap
boundary to PAGE_SIZE while keeping byte-granular read/write
truncation. Build-tested and functionally verified.
Longfang Liu (2):
hisi_acc_vfio_pci: fix live migration enable conditions for PF
passthrough
hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 61 +++++++++++++++----
1 file changed, 50 insertions(+), 11 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough
2026-08-03 2:18 [PATCH 0/2] fix two issues related to the driver Longfang Liu
@ 2026-08-03 2:18 ` Longfang Liu
2026-08-04 19:28 ` Alex Williamson
2026-08-03 2:18 ` [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size Longfang Liu
1 sibling, 1 reply; 8+ messages in thread
From: Longfang Liu @ 2026-08-03 2:18 UTC (permalink / raw)
To: alex.williamson, jgg; +Cc: kvm, linux-kernel, liulongfang
In the previous implementation of live migration support for
Hisilicon accelerator devices, there was insufficient consideration
for the fact that PFs cannot support virtualization live migration.
If a user unbinds the PF device driver from the host and directly
passes it through to a VM, then attempts a live migration operation,
it will trigger a calltrace exception.
To address this, we conducted a detailed analysis of potential
failure points. We added checks for all operations that depend on
PF driver commands and incorporated relevant conditional judgments
to prevent system calltrace exceptions when users attempt live
migration after passing PFs through to VMs.
Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
Signed-off-by: Longfang Liu <liulongfang@huawei.com>
---
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 48 +++++++++++++++----
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
index 86362ec424a5..36490be7a61a 100644
--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
@@ -378,6 +378,11 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
return 0;
+ if (!pf_qm || !pf_qm->io_base) {
+ dev_err(dev, "failed to match check for PF QM migration\n");
+ return -ENODEV;
+ }
+
ret = vf_qm_version_check(vf_data, dev);
if (ret) {
dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
@@ -423,10 +428,15 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
struct acc_vf_data *vf_data)
{
struct hisi_qm *pf_qm = hisi_acc_vdev->pf_qm;
- struct device *dev = &pf_qm->pdev->dev;
+ struct device *dev = &hisi_acc_vdev->vf_dev->dev;
int vf_id = hisi_acc_vdev->vf_id;
int ret;
+ if (!pf_qm || !pf_qm->io_base) {
+ dev_err(dev, "failed to check PF QM available!\n");
+ return -ENODEV;
+ }
+
vf_data->acc_magic = ACC_DEV_MAGIC_V2;
vf_data->major_ver = ACC_DRV_MAJOR_VER;
vf_data->minor_ver = ACC_DRV_MINOR_VER;
@@ -601,9 +611,14 @@ hisi_acc_check_int_state(struct hisi_acc_vf_core_device *hisi_acc_vdev)
struct hisi_qm *vfqm = &hisi_acc_vdev->vf_qm;
struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
struct pci_dev *vf_pdev = hisi_acc_vdev->vf_dev;
- struct device *dev = &qm->pdev->dev;
+ struct device *dev = &vf_pdev->dev;
u32 state;
+ if (!qm || !qm->io_base) {
+ dev_err(dev, "failed to interrupt state check for PF QM!\n");
+ return -ENODEV;
+ }
+
/* Check RAS state */
state = qm_check_reg_state(qm, QM_ABNORMAL_INT_STATUS);
if (state) {
@@ -1154,9 +1169,14 @@ static void hisi_acc_vf_pci_reset_prepare(struct pci_dev *pdev)
{
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
- struct device *dev = &qm->pdev->dev;
+ struct device *dev = &pdev->dev;
u32 delay = 0;
+ if (!qm || !qm->io_base) {
+ dev_err(dev, "PF QM not available for reset\n");
+ return;
+ }
+
/* All reset requests need to be queued for processing */
while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
msleep(1);
@@ -1174,8 +1194,12 @@ static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
- if (hisi_acc_vdev->set_reset_flag)
- clear_bit(QM_RESETTING, &qm->misc_ctl);
+ if (hisi_acc_vdev->set_reset_flag) {
+ if (qm && qm->io_base)
+ clear_bit(QM_RESETTING, &qm->misc_ctl);
+ else
+ dev_err(&pdev->dev, "PF QM not available for reset done\n");
+ }
if (!hisi_acc_vdev->core_device.vdev.mig_ops)
return;
@@ -1193,6 +1217,11 @@ static int hisi_acc_vf_qm_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)
struct pci_dev *vf_dev = vdev->pdev;
u32 val;
+ if (!pf_qm || !pf_qm->io_base) {
+ dev_err(&vf_dev->dev, "PF QM not available for init\n");
+ return -ENODEV;
+ }
+
val = readl(pf_qm->io_base + QM_MIG_REGION_SEL);
if (pf_qm->ver > QM_HW_V3 && (val & QM_MIG_REGION_EN))
hisi_acc_vdev->drv_mode = HW_ACC_MIG_PF_CTRL;
@@ -1565,6 +1594,11 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
struct pci_dev *pdev = to_pci_dev(core_vdev->dev);
struct hisi_qm *pf_qm = hisi_acc_get_pf_qm(pdev);
+ if (!pf_qm) {
+ dev_err(&pdev->dev, "PF driver not loaded, cannot enable migration\n");
+ return -ENODEV;
+ }
+
hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
hisi_acc_vdev->pf_qm = pf_qm;
hisi_acc_vdev->vf_dev = pdev;
@@ -1670,13 +1704,11 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
struct hisi_acc_vf_core_device *hisi_acc_vdev;
const struct vfio_device_ops *ops = &hisi_acc_vfio_pci_ops;
struct hisi_qm *pf_qm;
- int vf_id;
int ret;
pf_qm = hisi_acc_get_pf_qm(pdev);
if (pf_qm && pf_qm->ver >= QM_HW_V3) {
- vf_id = pci_iov_vf_id(pdev);
- if (vf_id >= 0)
+ if (pdev->is_virtfn)
ops = &hisi_acc_vfio_pci_migrn_ops;
else
pci_warn(pdev, "migration support failed, continue with generic interface\n");
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size
2026-08-03 2:18 [PATCH 0/2] fix two issues related to the driver Longfang Liu
2026-08-03 2:18 ` [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough Longfang Liu
@ 2026-08-03 2:18 ` Longfang Liu
2026-08-04 19:27 ` Alex Williamson
1 sibling, 1 reply; 8+ messages in thread
From: Longfang Liu @ 2026-08-03 2:18 UTC (permalink / raw)
To: alex.williamson, jgg; +Cc: kvm, linux-kernel, liulongfang
On HW_ACC_MIG_VF_CTRL hardware, VF BAR2 is split into functional
and migration register regions. When kernel page size exceeds the
functional region size (e.g. 64KB pages vs 32KB functional region),
guest mmap operations get rounded up to page size, causing the VMA
to exceed functional boundaries and fail validation.
The solution aligns mmap boundaries to page size while maintaining
byte-granularity access control through hisi_acc_pci_rw_access_check()
for read/write operations and accurate region size reporting via
hisi_acc_vfio_ioctl_get_region(), ensuring migration registers remain
protected from non-mmap access while resolving compatibility issues.
Signed-off-by: Longfang Liu <liulongfang@huawei.com>
---
drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
index 36490be7a61a..44b3e7d8fef5 100644
--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
@@ -1355,14 +1355,21 @@ static int hisi_acc_vfio_pci_mmap(struct vfio_device *core_vdev,
index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
if (index == VFIO_PCI_BAR2_REGION_INDEX) {
u64 req_len, pgoff, req_start;
- resource_size_t end;
+ resource_size_t end, dev_len;
- end = hisi_acc_get_resource_len(vdev, index);
+ dev_len = hisi_acc_get_resource_len(vdev, index);
req_len = vma->vm_end - vma->vm_start;
pgoff = vma->vm_pgoff &
((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
req_start = pgoff << PAGE_SHIFT;
-
+ /*
+ * The BAR2 functional region (dev_len) may be smaller than the
+ * kernel page size. Align it to PAGE_SIZE so a page-rounded
+ * guest mmap is not rejected, which would make the VF unusable.
+ * The read/write path still truncates at the real functional
+ * boundary, keeping the migration registers inaccessible.
+ */
+ end = PAGE_ALIGN(dev_len);
if (req_start + req_len > end)
return -EINVAL;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size
2026-08-03 2:18 ` [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size Longfang Liu
@ 2026-08-04 19:27 ` Alex Williamson
2026-08-05 2:54 ` liulongfang
0 siblings, 1 reply; 8+ messages in thread
From: Alex Williamson @ 2026-08-04 19:27 UTC (permalink / raw)
To: Longfang Liu; +Cc: alex.williamson, jgg, kvm, linux-kernel, alex
On Mon, 3 Aug 2026 10:18:57 +0800
Longfang Liu <liulongfang@huawei.com> wrote:
> On HW_ACC_MIG_VF_CTRL hardware, VF BAR2 is split into functional
> and migration register regions. When kernel page size exceeds the
> functional region size (e.g. 64KB pages vs 32KB functional region),
> guest mmap operations get rounded up to page size, causing the VMA
> to exceed functional boundaries and fail validation.
> The solution aligns mmap boundaries to page size while maintaining
> byte-granularity access control through hisi_acc_pci_rw_access_check()
> for read/write operations and accurate region size reporting via
> hisi_acc_vfio_ioctl_get_region(), ensuring migration registers remain
> protected from non-mmap access while resolving compatibility issues.
>
> Signed-off-by: Longfang Liu <liulongfang@huawei.com>
> ---
> drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> index 36490be7a61a..44b3e7d8fef5 100644
> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> @@ -1355,14 +1355,21 @@ static int hisi_acc_vfio_pci_mmap(struct vfio_device *core_vdev,
> index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
> if (index == VFIO_PCI_BAR2_REGION_INDEX) {
> u64 req_len, pgoff, req_start;
> - resource_size_t end;
> + resource_size_t end, dev_len;
>
> - end = hisi_acc_get_resource_len(vdev, index);
> + dev_len = hisi_acc_get_resource_len(vdev, index);
> req_len = vma->vm_end - vma->vm_start;
> pgoff = vma->vm_pgoff &
> ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
> req_start = pgoff << PAGE_SHIFT;
> -
> + /*
> + * The BAR2 functional region (dev_len) may be smaller than the
> + * kernel page size. Align it to PAGE_SIZE so a page-rounded
> + * guest mmap is not rejected, which would make the VF unusable.
> + * The read/write path still truncates at the real functional
> + * boundary, keeping the migration registers inaccessible.
> + */
> + end = PAGE_ALIGN(dev_len);
> if (req_start + req_len > end)
> return -EINVAL;
> }
You may still be restricting read/write access into the migration
range of the BAR, but doesn't this give the user full access to that
extended range through the mmap? It seems they only need to access
beyond the advertised region length through the mmap to bypass
hisi_acc_pci_rw_access_check().
If they can do that, what are we even still protecting?
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough
2026-08-03 2:18 ` [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough Longfang Liu
@ 2026-08-04 19:28 ` Alex Williamson
2026-08-05 2:19 ` liulongfang
0 siblings, 1 reply; 8+ messages in thread
From: Alex Williamson @ 2026-08-04 19:28 UTC (permalink / raw)
To: Longfang Liu; +Cc: alex.williamson, jgg, kvm, linux-kernel, alex
On Mon, 3 Aug 2026 10:18:56 +0800
Longfang Liu <liulongfang@huawei.com> wrote:
> In the previous implementation of live migration support for
> Hisilicon accelerator devices, there was insufficient consideration
> for the fact that PFs cannot support virtualization live migration.
> If a user unbinds the PF device driver from the host and directly
> passes it through to a VM, then attempts a live migration operation,
> it will trigger a calltrace exception.
>
> To address this, we conducted a detailed analysis of potential
> failure points. We added checks for all operations that depend on
> PF driver commands and incorporated relevant conditional judgments
> to prevent system calltrace exceptions when users attempt live
> migration after passing PFs through to VMs.
I don't understand your core premise here. hisi_acc_vfio_pci_probe()
sets the default ops to hisi_acc_vfio_pci_ops. This ops structure uses
vfio-pci-core callbacks for everything except .open_device, for which it
uses hisi_acc_vfio_pci_open_device(). This function has exactly one
migration related branch, which is entered only when core_vdev->mig_ops
is set, but mig_ops is only set in the .init callback of the ops
structure supporting migration.
In order to get the migration ops structure, hisi_acc_get_pf_qm() must
return a pf_qm, the version of that object must be at least QM_HW_V3,
and the vf_id must be valid. hisi_acc_get_pf_qm()'s very first action
is:
if (!pdev->is_virtfn)
return NULL;
Therefore, how is a PF ever getting associated to the migration ops
structure?
> Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
> Signed-off-by: Longfang Liu <liulongfang@huawei.com>
> ---
> .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 48 +++++++++++++++----
> 1 file changed, 40 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> index 86362ec424a5..36490be7a61a 100644
> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> @@ -378,6 +378,11 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
> if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
> return 0;
>
> + if (!pf_qm || !pf_qm->io_base) {
> + dev_err(dev, "failed to match check for PF QM migration\n");
> + return -ENODEV;
> + }
> +
This function is called by hisi_acc_vf_resume_write(), which is part of
hisi_acc_vf_resume_fops, which is set as the file ops for the migration file created in hisi_acc_vf_pci_resume(). The call path is:
hisi_acc_vfio_pci_migrn_state_ops.migration_set_state (hisi_acc_vfio_pci_set_device_state())
hisi_acc_vf_set_device_state()
hisi_acc_vf_pci_resume()
hisi_acc_vfio_pci_migrn_state_ops is mig_ops. It's never set for a PF!
> ret = vf_qm_version_check(vf_data, dev);
> if (ret) {
> dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
> @@ -423,10 +428,15 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
> struct acc_vf_data *vf_data)
> {
> struct hisi_qm *pf_qm = hisi_acc_vdev->pf_qm;
> - struct device *dev = &pf_qm->pdev->dev;
> + struct device *dev = &hisi_acc_vdev->vf_dev->dev;
> int vf_id = hisi_acc_vdev->vf_id;
> int ret;
>
> + if (!pf_qm || !pf_qm->io_base) {
> + dev_err(dev, "failed to check PF QM available!\n");
> + return -ENODEV;
> + }
> +
> vf_data->acc_magic = ACC_DEV_MAGIC_V2;
> vf_data->major_ver = ACC_DRV_MAJOR_VER;
> vf_data->minor_ver = ACC_DRV_MINOR_VER;
This is called from opening the migration save file. Prove how a PF
can get here.
> @@ -601,9 +611,14 @@ hisi_acc_check_int_state(struct hisi_acc_vf_core_device *hisi_acc_vdev)
> struct hisi_qm *vfqm = &hisi_acc_vdev->vf_qm;
> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
> struct pci_dev *vf_pdev = hisi_acc_vdev->vf_dev;
> - struct device *dev = &qm->pdev->dev;
> + struct device *dev = &vf_pdev->dev;
> u32 state;
>
> + if (!qm || !qm->io_base) {
> + dev_err(dev, "failed to interrupt state check for PF QM!\n");
> + return -ENODEV;
> + }
> +
> /* Check RAS state */
> state = qm_check_reg_state(qm, QM_ABNORMAL_INT_STATUS);
> if (state) {
This is called from hisi_acc_vf_stop_device(), the same set_device path
as above. A PF cannot get here!
> @@ -1154,9 +1169,14 @@ static void hisi_acc_vf_pci_reset_prepare(struct pci_dev *pdev)
> {
> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
> - struct device *dev = &qm->pdev->dev;
> + struct device *dev = &pdev->dev;
> u32 delay = 0;
>
> + if (!qm || !qm->io_base) {
> + dev_err(dev, "PF QM not available for reset\n");
> + return;
> + }
> +
> /* All reset requests need to be queued for processing */
> while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
> msleep(1);
Finally, something that matches the fix this patch claims, a function
reachable by the PF!
Is this actually the issue you're trying to fix, not a migration
induced fault, migration isn't reachable by a PF, but an error handling
bug?
> @@ -1174,8 +1194,12 @@ static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
>
> - if (hisi_acc_vdev->set_reset_flag)
> - clear_bit(QM_RESETTING, &qm->misc_ctl);
> + if (hisi_acc_vdev->set_reset_flag) {
> + if (qm && qm->io_base)
> + clear_bit(QM_RESETTING, &qm->misc_ctl);
> + else
> + dev_err(&pdev->dev, "PF QM not available for reset done\n");
> + }
>
> if (!hisi_acc_vdev->core_device.vdev.mig_ops)
> return;
Another, but notice you've already accounted for the non-migration case
here. Can they be combined?
> @@ -1193,6 +1217,11 @@ static int hisi_acc_vf_qm_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)
> struct pci_dev *vf_dev = vdev->pdev;
> u32 val;
>
> + if (!pf_qm || !pf_qm->io_base) {
> + dev_err(&vf_dev->dev, "PF QM not available for init\n");
> + return -ENODEV;
> + }
> +
> val = readl(pf_qm->io_base + QM_MIG_REGION_SEL);
> if (pf_qm->ver > QM_HW_V3 && (val & QM_MIG_REGION_EN))
> hisi_acc_vdev->drv_mode = HW_ACC_MIG_PF_CTRL;
Unreachable by PF.
> @@ -1565,6 +1594,11 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
> struct pci_dev *pdev = to_pci_dev(core_vdev->dev);
> struct hisi_qm *pf_qm = hisi_acc_get_pf_qm(pdev);
>
> + if (!pf_qm) {
> + dev_err(&pdev->dev, "PF driver not loaded, cannot enable migration\n");
> + return -ENODEV;
> + }
> +
> hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
> hisi_acc_vdev->pf_qm = pf_qm;
> hisi_acc_vdev->vf_dev = pdev;
Unreachable by PF.
> @@ -1670,13 +1704,11 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
> struct hisi_acc_vf_core_device *hisi_acc_vdev;
> const struct vfio_device_ops *ops = &hisi_acc_vfio_pci_ops;
> struct hisi_qm *pf_qm;
> - int vf_id;
> int ret;
>
> pf_qm = hisi_acc_get_pf_qm(pdev);
> if (pf_qm && pf_qm->ver >= QM_HW_V3) {
> - vf_id = pci_iov_vf_id(pdev);
> - if (vf_id >= 0)
> + if (pdev->is_virtfn)
> ops = &hisi_acc_vfio_pci_migrn_ops;
> else
> pci_warn(pdev, "migration support failed, continue with generic interface\n");
Redundant to the test in hisi_acc_get_pf_pm() which would have returned
NULL, so we can't even get here.
Please do better. Thanks,
Alex
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough
2026-08-04 19:28 ` Alex Williamson
@ 2026-08-05 2:19 ` liulongfang
2026-08-05 3:15 ` Alex Williamson
0 siblings, 1 reply; 8+ messages in thread
From: liulongfang @ 2026-08-05 2:19 UTC (permalink / raw)
To: Alex Williamson; +Cc: alex.williamson, jgg, kvm, linux-kernel
On 2026/8/5 3:28, Alex Williamson wrote:
> On Mon, 3 Aug 2026 10:18:56 +0800
> Longfang Liu <liulongfang@huawei.com> wrote:
>
>> In the previous implementation of live migration support for
>> Hisilicon accelerator devices, there was insufficient consideration
>> for the fact that PFs cannot support virtualization live migration.
>> If a user unbinds the PF device driver from the host and directly
>> passes it through to a VM, then attempts a live migration operation,
>> it will trigger a calltrace exception.
>>
>> To address this, we conducted a detailed analysis of potential
>> failure points. We added checks for all operations that depend on
>> PF driver commands and incorporated relevant conditional judgments
>> to prevent system calltrace exceptions when users attempt live
>> migration after passing PFs through to VMs.
>
> I don't understand your core premise here. hisi_acc_vfio_pci_probe()
> sets the default ops to hisi_acc_vfio_pci_ops. This ops structure uses
> vfio-pci-core callbacks for everything except .open_device, for which it
> uses hisi_acc_vfio_pci_open_device(). This function has exactly one
> migration related branch, which is entered only when core_vdev->mig_ops
> is set, but mig_ops is only set in the .init callback of the ops
> structure supporting migration.
>
> In order to get the migration ops structure, hisi_acc_get_pf_qm() must
> return a pf_qm, the version of that object must be at least QM_HW_V3,
> and the vf_id must be valid. hisi_acc_get_pf_qm()'s very first action
> is:
>
> if (!pdev->is_virtfn)
> return NULL;
>
> Therefore, how is a PF ever getting associated to the migration ops
> structure?
>
This Hisilicon live migration driver actually utilizes two hardware-related
configuration functions. The first is the PF control function, obtained directly
through hisi_acc_get_pf_qm, which handles mailbox command operations, device health
status checks, device reset verification, device stop commands, and other device
control processes. The second is the VF configuration function, which is passed
through via VFIO direct assignment and serves as the main entity for device live
migration, responsible for current service device data migration and recovery operations.
The aforementioned issue occurs when users incorrectly pass the PF directly to this
driver through driver_override. In this scenario, the vf_dev in the driver structure
erroneously points to this PF. When the PF attempts to migrate itself, it will directly
cause exceptions. Therefore, it's necessary to add pdev checks here.
Thanks.
Longfang.
>> Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
>> Signed-off-by: Longfang Liu <liulongfang@huawei.com>
>> ---
>> .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 48 +++++++++++++++----
>> 1 file changed, 40 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> index 86362ec424a5..36490be7a61a 100644
>> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> @@ -378,6 +378,11 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
>> if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
>> return 0;
>>
>> + if (!pf_qm || !pf_qm->io_base) {
>> + dev_err(dev, "failed to match check for PF QM migration\n");
>> + return -ENODEV;
>> + }
>> +
>
> This function is called by hisi_acc_vf_resume_write(), which is part of
> hisi_acc_vf_resume_fops, which is set as the file ops for the migration file created in hisi_acc_vf_pci_resume(). The call path is:
>
> hisi_acc_vfio_pci_migrn_state_ops.migration_set_state (hisi_acc_vfio_pci_set_device_state())
> hisi_acc_vf_set_device_state()
> hisi_acc_vf_pci_resume()
>
> hisi_acc_vfio_pci_migrn_state_ops is mig_ops. It's never set for a PF!
>
>> ret = vf_qm_version_check(vf_data, dev);
>> if (ret) {
>> dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
>> @@ -423,10 +428,15 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
>> struct acc_vf_data *vf_data)
>> {
>> struct hisi_qm *pf_qm = hisi_acc_vdev->pf_qm;
>> - struct device *dev = &pf_qm->pdev->dev;
>> + struct device *dev = &hisi_acc_vdev->vf_dev->dev;
>> int vf_id = hisi_acc_vdev->vf_id;
>> int ret;
>>
>> + if (!pf_qm || !pf_qm->io_base) {
>> + dev_err(dev, "failed to check PF QM available!\n");
>> + return -ENODEV;
>> + }
>> +
>> vf_data->acc_magic = ACC_DEV_MAGIC_V2;
>> vf_data->major_ver = ACC_DRV_MAJOR_VER;
>> vf_data->minor_ver = ACC_DRV_MINOR_VER;
>
> This is called from opening the migration save file. Prove how a PF
> can get here.
>
>
>> @@ -601,9 +611,14 @@ hisi_acc_check_int_state(struct hisi_acc_vf_core_device *hisi_acc_vdev)
>> struct hisi_qm *vfqm = &hisi_acc_vdev->vf_qm;
>> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
>> struct pci_dev *vf_pdev = hisi_acc_vdev->vf_dev;
>> - struct device *dev = &qm->pdev->dev;
>> + struct device *dev = &vf_pdev->dev;
>> u32 state;
>>
>> + if (!qm || !qm->io_base) {
>> + dev_err(dev, "failed to interrupt state check for PF QM!\n");
>> + return -ENODEV;
>> + }
>> +
>> /* Check RAS state */
>> state = qm_check_reg_state(qm, QM_ABNORMAL_INT_STATUS);
>> if (state) {
>
> This is called from hisi_acc_vf_stop_device(), the same set_device path
> as above. A PF cannot get here!
>
>> @@ -1154,9 +1169,14 @@ static void hisi_acc_vf_pci_reset_prepare(struct pci_dev *pdev)
>> {
>> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
>> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
>> - struct device *dev = &qm->pdev->dev;
>> + struct device *dev = &pdev->dev;
>> u32 delay = 0;
>>
>> + if (!qm || !qm->io_base) {
>> + dev_err(dev, "PF QM not available for reset\n");
>> + return;
>> + }
>> +
>> /* All reset requests need to be queued for processing */
>> while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
>> msleep(1);
>
> Finally, something that matches the fix this patch claims, a function
> reachable by the PF!
>
> Is this actually the issue you're trying to fix, not a migration
> induced fault, migration isn't reachable by a PF, but an error handling
> bug?
>
>> @@ -1174,8 +1194,12 @@ static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
>> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
>> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
>>
>> - if (hisi_acc_vdev->set_reset_flag)
>> - clear_bit(QM_RESETTING, &qm->misc_ctl);
>> + if (hisi_acc_vdev->set_reset_flag) {
>> + if (qm && qm->io_base)
>> + clear_bit(QM_RESETTING, &qm->misc_ctl);
>> + else
>> + dev_err(&pdev->dev, "PF QM not available for reset done\n");
>> + }
>>
>> if (!hisi_acc_vdev->core_device.vdev.mig_ops)
>> return;
>
> Another, but notice you've already accounted for the non-migration case
> here. Can they be combined?
>
>> @@ -1193,6 +1217,11 @@ static int hisi_acc_vf_qm_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)
>> struct pci_dev *vf_dev = vdev->pdev;
>> u32 val;
>>
>> + if (!pf_qm || !pf_qm->io_base) {
>> + dev_err(&vf_dev->dev, "PF QM not available for init\n");
>> + return -ENODEV;
>> + }
>> +
>> val = readl(pf_qm->io_base + QM_MIG_REGION_SEL);
>> if (pf_qm->ver > QM_HW_V3 && (val & QM_MIG_REGION_EN))
>> hisi_acc_vdev->drv_mode = HW_ACC_MIG_PF_CTRL;
>
> Unreachable by PF.
>
>> @@ -1565,6 +1594,11 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
>> struct pci_dev *pdev = to_pci_dev(core_vdev->dev);
>> struct hisi_qm *pf_qm = hisi_acc_get_pf_qm(pdev);
>>
>> + if (!pf_qm) {
>> + dev_err(&pdev->dev, "PF driver not loaded, cannot enable migration\n");
>> + return -ENODEV;
>> + }
>> +
>> hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
>> hisi_acc_vdev->pf_qm = pf_qm;
>> hisi_acc_vdev->vf_dev = pdev;
>
> Unreachable by PF.
>
>> @@ -1670,13 +1704,11 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
>> struct hisi_acc_vf_core_device *hisi_acc_vdev;
>> const struct vfio_device_ops *ops = &hisi_acc_vfio_pci_ops;
>> struct hisi_qm *pf_qm;
>> - int vf_id;
>> int ret;
>>
>> pf_qm = hisi_acc_get_pf_qm(pdev);
>> if (pf_qm && pf_qm->ver >= QM_HW_V3) {
>> - vf_id = pci_iov_vf_id(pdev);
>> - if (vf_id >= 0)
>> + if (pdev->is_virtfn)
>> ops = &hisi_acc_vfio_pci_migrn_ops;
>> else
>> pci_warn(pdev, "migration support failed, continue with generic interface\n");
>
> Redundant to the test in hisi_acc_get_pf_pm() which would have returned
> NULL, so we can't even get here.
>
> Please do better. Thanks,
>
> Alex
> .
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size
2026-08-04 19:27 ` Alex Williamson
@ 2026-08-05 2:54 ` liulongfang
0 siblings, 0 replies; 8+ messages in thread
From: liulongfang @ 2026-08-05 2:54 UTC (permalink / raw)
To: Alex Williamson; +Cc: alex.williamson, jgg, kvm, linux-kernel
On 2026/8/5 3:27, Alex Williamson wrote:
> On Mon, 3 Aug 2026 10:18:57 +0800
> Longfang Liu <liulongfang@huawei.com> wrote:
>
>> On HW_ACC_MIG_VF_CTRL hardware, VF BAR2 is split into functional
>> and migration register regions. When kernel page size exceeds the
>> functional region size (e.g. 64KB pages vs 32KB functional region),
>> guest mmap operations get rounded up to page size, causing the VMA
>> to exceed functional boundaries and fail validation.
>> The solution aligns mmap boundaries to page size while maintaining
>> byte-granularity access control through hisi_acc_pci_rw_access_check()
>> for read/write operations and accurate region size reporting via
>> hisi_acc_vfio_ioctl_get_region(), ensuring migration registers remain
>> protected from non-mmap access while resolving compatibility issues.
>>
>> Signed-off-by: Longfang Liu <liulongfang@huawei.com>
>> ---
>> drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 13 ++++++++++---
>> 1 file changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> index 36490be7a61a..44b3e7d8fef5 100644
>> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
>> @@ -1355,14 +1355,21 @@ static int hisi_acc_vfio_pci_mmap(struct vfio_device *core_vdev,
>> index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
>> if (index == VFIO_PCI_BAR2_REGION_INDEX) {
>> u64 req_len, pgoff, req_start;
>> - resource_size_t end;
>> + resource_size_t end, dev_len;
>>
>> - end = hisi_acc_get_resource_len(vdev, index);
>> + dev_len = hisi_acc_get_resource_len(vdev, index);
>> req_len = vma->vm_end - vma->vm_start;
>> pgoff = vma->vm_pgoff &
>> ((1U << (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT)) - 1);
>> req_start = pgoff << PAGE_SHIFT;
>> -
>> + /*
>> + * The BAR2 functional region (dev_len) may be smaller than the
>> + * kernel page size. Align it to PAGE_SIZE so a page-rounded
>> + * guest mmap is not rejected, which would make the VF unusable.
>> + * The read/write path still truncates at the real functional
>> + * boundary, keeping the migration registers inaccessible.
>> + */
>> + end = PAGE_ALIGN(dev_len);
>> if (req_start + req_len > end)
>> return -EINVAL;
>> }
>
> You may still be restricting read/write access into the migration
> range of the BAR, but doesn't this give the user full access to that
> extended range through the mmap? It seems they only need to access
> beyond the advertised region length through the mmap to bypass
> hisi_acc_pci_rw_access_check().
>
> If they can do that, what are we even still protecting?
>
> Alex
> .
>
Yes, the issue you mentioned is indeed a serious problem. We need to prevent this
type of security vulnerability where memory segments intended only for kernel access
are exposed to VM users.
Thanks.
Longfang.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough
2026-08-05 2:19 ` liulongfang
@ 2026-08-05 3:15 ` Alex Williamson
0 siblings, 0 replies; 8+ messages in thread
From: Alex Williamson @ 2026-08-05 3:15 UTC (permalink / raw)
To: liulongfang; +Cc: alex.williamson, jgg, kvm, linux-kernel, alex
On Wed, 5 Aug 2026 10:19:35 +0800
liulongfang <liulongfang@huawei.com> wrote:
> On 2026/8/5 3:28, Alex Williamson wrote:
> > On Mon, 3 Aug 2026 10:18:56 +0800
> > Longfang Liu <liulongfang@huawei.com> wrote:
> >
> >> In the previous implementation of live migration support for
> >> Hisilicon accelerator devices, there was insufficient consideration
> >> for the fact that PFs cannot support virtualization live migration.
> >> If a user unbinds the PF device driver from the host and directly
> >> passes it through to a VM, then attempts a live migration operation,
> >> it will trigger a calltrace exception.
> >>
> >> To address this, we conducted a detailed analysis of potential
> >> failure points. We added checks for all operations that depend on
> >> PF driver commands and incorporated relevant conditional judgments
> >> to prevent system calltrace exceptions when users attempt live
> >> migration after passing PFs through to VMs.
> >
> > I don't understand your core premise here. hisi_acc_vfio_pci_probe()
> > sets the default ops to hisi_acc_vfio_pci_ops. This ops structure uses
> > vfio-pci-core callbacks for everything except .open_device, for which it
> > uses hisi_acc_vfio_pci_open_device(). This function has exactly one
> > migration related branch, which is entered only when core_vdev->mig_ops
> > is set, but mig_ops is only set in the .init callback of the ops
> > structure supporting migration.
> >
> > In order to get the migration ops structure, hisi_acc_get_pf_qm() must
> > return a pf_qm, the version of that object must be at least QM_HW_V3,
> > and the vf_id must be valid. hisi_acc_get_pf_qm()'s very first action
> > is:
> >
> > if (!pdev->is_virtfn)
> > return NULL;
> >
> > Therefore, how is a PF ever getting associated to the migration ops
> > structure?
> >
>
> This Hisilicon live migration driver actually utilizes two hardware-related
> configuration functions. The first is the PF control function, obtained directly
> through hisi_acc_get_pf_qm, which handles mailbox command operations, device health
> status checks, device reset verification, device stop commands, and other device
> control processes. The second is the VF configuration function, which is passed
> through via VFIO direct assignment and serves as the main entity for device live
> migration, responsible for current service device data migration and recovery operations.
>
> The aforementioned issue occurs when users incorrectly pass the PF directly to this
> driver through driver_override. In this scenario, the vf_dev in the driver structure
> erroneously points to this PF. When the PF attempts to migrate itself, it will directly
> cause exceptions. Therefore, it's necessary to add pdev checks here.
This doesn't answer the question. How does binding the PF to the
driver pass the existing is_virtfn test in hisi_acc_get_pf_qm() in
order to map the migration ops structure to the device rather than the
default vfio-pci-core wrapper ops structure?
vf_dev is ONLY set in hisi_acc_vfio_pci_migrn_init_dev(), which is
called through the migration ops structure. If the PF is not mapped to
the migration ops structure it CANNOT set vf_dev.
Your own patch below gates the mapping of the migration ops on
is_virtfn, so we know this field is correct for the PF. Therefore
hisi_acc_get_pf_qm() already returns NULL for the PF. Therefore the
vfio-pci-core wrapper ops are used for the PF. Therefore vf_dev is
never set and most of the functions being modified in the name of
correcting falsely advertised migration support on the PF (which seems
untrue) are not reachable.
Alex
> >> Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
> >> Signed-off-by: Longfang Liu <liulongfang@huawei.com>
> >> ---
> >> .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 48 +++++++++++++++----
> >> 1 file changed, 40 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> >> index 86362ec424a5..36490be7a61a 100644
> >> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> >> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> >> @@ -378,6 +378,11 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
> >> if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
> >> return 0;
> >>
> >> + if (!pf_qm || !pf_qm->io_base) {
> >> + dev_err(dev, "failed to match check for PF QM migration\n");
> >> + return -ENODEV;
> >> + }
> >> +
> >
> > This function is called by hisi_acc_vf_resume_write(), which is part of
> > hisi_acc_vf_resume_fops, which is set as the file ops for the migration file created in hisi_acc_vf_pci_resume(). The call path is:
> >
> > hisi_acc_vfio_pci_migrn_state_ops.migration_set_state (hisi_acc_vfio_pci_set_device_state())
> > hisi_acc_vf_set_device_state()
> > hisi_acc_vf_pci_resume()
> >
> > hisi_acc_vfio_pci_migrn_state_ops is mig_ops. It's never set for a PF!
> >
> >> ret = vf_qm_version_check(vf_data, dev);
> >> if (ret) {
> >> dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
> >> @@ -423,10 +428,15 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
> >> struct acc_vf_data *vf_data)
> >> {
> >> struct hisi_qm *pf_qm = hisi_acc_vdev->pf_qm;
> >> - struct device *dev = &pf_qm->pdev->dev;
> >> + struct device *dev = &hisi_acc_vdev->vf_dev->dev;
> >> int vf_id = hisi_acc_vdev->vf_id;
> >> int ret;
> >>
> >> + if (!pf_qm || !pf_qm->io_base) {
> >> + dev_err(dev, "failed to check PF QM available!\n");
> >> + return -ENODEV;
> >> + }
> >> +
> >> vf_data->acc_magic = ACC_DEV_MAGIC_V2;
> >> vf_data->major_ver = ACC_DRV_MAJOR_VER;
> >> vf_data->minor_ver = ACC_DRV_MINOR_VER;
> >
> > This is called from opening the migration save file. Prove how a PF
> > can get here.
> >
> >
> >> @@ -601,9 +611,14 @@ hisi_acc_check_int_state(struct hisi_acc_vf_core_device *hisi_acc_vdev)
> >> struct hisi_qm *vfqm = &hisi_acc_vdev->vf_qm;
> >> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
> >> struct pci_dev *vf_pdev = hisi_acc_vdev->vf_dev;
> >> - struct device *dev = &qm->pdev->dev;
> >> + struct device *dev = &vf_pdev->dev;
> >> u32 state;
> >>
> >> + if (!qm || !qm->io_base) {
> >> + dev_err(dev, "failed to interrupt state check for PF QM!\n");
> >> + return -ENODEV;
> >> + }
> >> +
> >> /* Check RAS state */
> >> state = qm_check_reg_state(qm, QM_ABNORMAL_INT_STATUS);
> >> if (state) {
> >
> > This is called from hisi_acc_vf_stop_device(), the same set_device path
> > as above. A PF cannot get here!
> >
> >> @@ -1154,9 +1169,14 @@ static void hisi_acc_vf_pci_reset_prepare(struct pci_dev *pdev)
> >> {
> >> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
> >> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
> >> - struct device *dev = &qm->pdev->dev;
> >> + struct device *dev = &pdev->dev;
> >> u32 delay = 0;
> >>
> >> + if (!qm || !qm->io_base) {
> >> + dev_err(dev, "PF QM not available for reset\n");
> >> + return;
> >> + }
> >> +
> >> /* All reset requests need to be queued for processing */
> >> while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
> >> msleep(1);
> >
> > Finally, something that matches the fix this patch claims, a function
> > reachable by the PF!
> >
> > Is this actually the issue you're trying to fix, not a migration
> > induced fault, migration isn't reachable by a PF, but an error handling
> > bug?
> >
> >> @@ -1174,8 +1194,12 @@ static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
> >> struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_drvdata(pdev);
> >> struct hisi_qm *qm = hisi_acc_vdev->pf_qm;
> >>
> >> - if (hisi_acc_vdev->set_reset_flag)
> >> - clear_bit(QM_RESETTING, &qm->misc_ctl);
> >> + if (hisi_acc_vdev->set_reset_flag) {
> >> + if (qm && qm->io_base)
> >> + clear_bit(QM_RESETTING, &qm->misc_ctl);
> >> + else
> >> + dev_err(&pdev->dev, "PF QM not available for reset done\n");
> >> + }
> >>
> >> if (!hisi_acc_vdev->core_device.vdev.mig_ops)
> >> return;
> >
> > Another, but notice you've already accounted for the non-migration case
> > here. Can they be combined?
> >
> >> @@ -1193,6 +1217,11 @@ static int hisi_acc_vf_qm_init(struct hisi_acc_vf_core_device *hisi_acc_vdev)
> >> struct pci_dev *vf_dev = vdev->pdev;
> >> u32 val;
> >>
> >> + if (!pf_qm || !pf_qm->io_base) {
> >> + dev_err(&vf_dev->dev, "PF QM not available for init\n");
> >> + return -ENODEV;
> >> + }
> >> +
> >> val = readl(pf_qm->io_base + QM_MIG_REGION_SEL);
> >> if (pf_qm->ver > QM_HW_V3 && (val & QM_MIG_REGION_EN))
> >> hisi_acc_vdev->drv_mode = HW_ACC_MIG_PF_CTRL;
> >
> > Unreachable by PF.
> >
> >> @@ -1565,6 +1594,11 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
> >> struct pci_dev *pdev = to_pci_dev(core_vdev->dev);
> >> struct hisi_qm *pf_qm = hisi_acc_get_pf_qm(pdev);
> >>
> >> + if (!pf_qm) {
> >> + dev_err(&pdev->dev, "PF driver not loaded, cannot enable migration\n");
> >> + return -ENODEV;
> >> + }
> >> +
> >> hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
> >> hisi_acc_vdev->pf_qm = pf_qm;
> >> hisi_acc_vdev->vf_dev = pdev;
> >
> > Unreachable by PF.
> >
> >> @@ -1670,13 +1704,11 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
> >> struct hisi_acc_vf_core_device *hisi_acc_vdev;
> >> const struct vfio_device_ops *ops = &hisi_acc_vfio_pci_ops;
> >> struct hisi_qm *pf_qm;
> >> - int vf_id;
> >> int ret;
> >>
> >> pf_qm = hisi_acc_get_pf_qm(pdev);
> >> if (pf_qm && pf_qm->ver >= QM_HW_V3) {
> >> - vf_id = pci_iov_vf_id(pdev);
> >> - if (vf_id >= 0)
> >> + if (pdev->is_virtfn)
> >> ops = &hisi_acc_vfio_pci_migrn_ops;
> >> else
> >> pci_warn(pdev, "migration support failed, continue with generic interface\n");
> >
> > Redundant to the test in hisi_acc_get_pf_pm() which would have returned
> > NULL, so we can't even get here.
> >
> > Please do better. Thanks,
> >
> > Alex
> > .
> >
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-05 3:15 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 2:18 [PATCH 0/2] fix two issues related to the driver Longfang Liu
2026-08-03 2:18 ` [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough Longfang Liu
2026-08-04 19:28 ` Alex Williamson
2026-08-05 2:19 ` liulongfang
2026-08-05 3:15 ` Alex Williamson
2026-08-03 2:18 ` [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size Longfang Liu
2026-08-04 19:27 ` Alex Williamson
2026-08-05 2:54 ` liulongfang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox