* [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; 5+ 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] 5+ 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-03 2:42 ` sashiko-bot 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; 5+ 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] 5+ 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-03 2:42 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-08-03 2:42 UTC (permalink / raw) To: Longfang Liu; +Cc: kvm Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] The patch fails to prevent a Use-After-Free because `pf_qm` becomes a dangling pointer (not NULL) when the PF driver is unbound. - [High] `set_reset_flag` is never cleared, causing spurious lock release during subsequent failed resets. -- --- Patch [1]: [PATCH 1/2] hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough --- commit 2cccd4c0444989d0fd451c1227c40bde4c25acb2 Author: Longfang Liu <liulongfang@huawei.com> Subject: hisi_acc_vfio_pci: fix live migration enable conditions for PF passthrough This commit attempts to fix a calltrace exception triggered when a user unbinds the PF device driver from the host and directly passes it through to a VM, then attempts live migration. It adds checks across operations that depend on PF driver commands to ensure the PF's QM structure is available. > diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > index 86362ec424a50..36490be7a61aa 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) { [Severity: High] This isn't a bug introduced by this patch, but since the patch attempts to fix it here, does this check fully prevent a Use-After-Free? When the PF driver is unbound while a VF is assigned to a VM, pci_disable_sriov() warns but doesn't prevent the driver's remove callback from executing, causing the PF's qm structure to be freed via devres. This leaves hisi_acc_vdev->pf_qm as a dangling pointer rather than NULL. Will the !pf_qm check fail to catch this, leading to a UAF read when accessing 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); [ ... ] > @@ -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); [Severity: High] This is a pre-existing issue, but should the set_reset_flag be cleared after releasing this lock? If hisi_acc_vf_pci_reset_prepare() successfully acquires the lock, it sets set_reset_flag = true. However, when hisi_acc_vf_pci_aer_reset_done() clears the lock here, it doesn't appear to reset the flag back to false. If a subsequent reset occurs and reset_prepare() fails to acquire the lock (e.g., due to a timeout because another VF or the PF holds it), won't this function erroneously clear the QM_RESETTING lock that is actively held by another context? > + else > + dev_err(&pdev->dev, "PF QM not available for reset done\n"); > + } > > if (!hisi_acc_vdev->core_device.vdev.mig_ops) > return; -- Sashiko AI review · https://sashiko.dev/#/patchset/20260803021857.2370179-1-liulongfang@huawei.com?part=1 ^ permalink raw reply [flat|nested] 5+ 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-03 2:27 ` sashiko-bot 1 sibling, 1 reply; 5+ 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] 5+ 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-03 2:27 ` sashiko-bot 0 siblings, 0 replies; 5+ messages in thread From: sashiko-bot @ 2026-08-03 2:27 UTC (permalink / raw) To: Longfang Liu; +Cc: kvm Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Critical] Guest memory-mapping of BAR2 allows direct access to sensitive migration control registers, bypassing software isolation. -- --- Patch [2]: [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size --- commit 6249c89b3b40e6c3a5627d170614fe16d3e815bf Author: Longfang Liu <liulongfang@huawei.com> hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size This commit aligns the BAR2 functional region mmap boundaries to PAGE_SIZE. This is intended to prevent guest mmap operations from being rejected on 64KB page size kernels when the functional region is smaller. > diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c > index 36490be7a61aa..44b3e7d8fef5c 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; [Severity: Critical] Does this change allow an untrusted guest or userspace process to bypass software isolation and gain direct access to migration control registers? By rounding dev_len up to PAGE_SIZE in hisi_acc_vfio_pci_mmap(), the boundary check intended to prevent mapping of the hardware migration registers is circumvented. If a guest running on a 64KB page host requests an mmap of the BAR2 functional region, the code rounds dev_len up to PAGE_SIZE. This allows the request to be validated and passed to vfio_pci_core_mmap(), mapping the full 64KB physical page into the guest's stage-2 page tables. If the functional region is 32KB and the migration registers reside in the upper 32KB of the same physical page, the guest would gain unmediated read/write access to the migration control registers via direct memory load/store instructions. This appears to bypass the kernel's read/write interception and the hisi_acc_pci_rw_access_check() boundary checks. -- Sashiko AI review · https://sashiko.dev/#/patchset/20260803021857.2370179-1-liulongfang@huawei.com?part=2 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-03 2:42 UTC | newest] Thread overview: 5+ 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-03 2:42 ` sashiko-bot 2026-08-03 2:18 ` [PATCH 2/2] hisi_acc_vfio_pci: fix VF BAR2 mmap on 64KB page size Longfang Liu 2026-08-03 2:27 ` sashiko-bot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox