Skip to content

Commit 3536049

Browse files
committed
Merge tag 'vfio-v6.16-rc1' of https://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Remove an outdated DMA unmap optimization that relies on a feature only implemented in AMDv1 page tables. (Jason Gunthorpe) - Fix various migration issues in the hisi_acc_vfio_pci variant driver, including use of a wrong DMA address requiring an update to the migration data structure, resending task completion interrupt after migration to re-sync queues, fixing a write-back cache sequencing issue, fixing a driver unload issue, behaving correctly when the guest driver is not loaded, and avoiding to squash errors from sub-functions. (Longfang Liu) - mlx5-vfio-pci variant driver update to make use of the new two-step DMA API for migration, using a page array directly rather than using a page list mapped across a scatter list. (Leon Romanovsky) - Fix an incorrect loop index used when unwinding allocation of dirty page bitmaps on error, resulting in temporary failure in freeing unused bitmaps. (Li RongQing) * tag 'vfio-v6.16-rc1' of https://github.com/awilliam/linux-vfio: vfio/type1: Fix error unwind in migration dirty bitmap allocation vfio/mlx5: Enable the DMA link API vfio/mlx5: Rewrite create mkey flow to allow better code reuse vfio/mlx5: Explicitly use number of pages instead of allocated length hisi_acc_vfio_pci: update function return values. hisi_acc_vfio_pci: bugfix live migration function without VF device driver hisi_acc_vfio_pci: bugfix the problem of uninstalling driver hisi_acc_vfio_pci: bugfix cache write-back issue hisi_acc_vfio_pci: add eq and aeq interruption restore hisi_acc_vfio_pci: fix XQE dma address error vfio/type1: Remove Fine Grained Superpages detection
2 parents 02897f5 + 4518e5a commit 3536049

File tree

6 files changed

+338
-341
lines changed

6 files changed

+338
-341
lines changed

drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

Lines changed: 89 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ static int qm_set_regs(struct hisi_qm *qm, struct acc_vf_data *vf_data)
190190
int ret;
191191

192192
/* Check VF state */
193-
if (unlikely(hisi_qm_wait_mb_ready(qm))) {
193+
ret = hisi_qm_wait_mb_ready(qm);
194+
if (unlikely(ret)) {
194195
dev_err(&qm->pdev->dev, "QM device is not ready to write\n");
195-
return -EBUSY;
196+
return ret;
196197
}
197198

198199
ret = qm_write_regs(qm, QM_VF_AEQ_INT_MASK, &vf_data->aeq_int_mask, 1);
@@ -325,13 +326,15 @@ static void qm_dev_cmd_init(struct hisi_qm *qm)
325326
static int vf_qm_cache_wb(struct hisi_qm *qm)
326327
{
327328
unsigned int val;
329+
int ret;
328330

329331
writel(0x1, qm->io_base + QM_CACHE_WB_START);
330-
if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
332+
ret = readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
331333
val, val & BIT(0), MB_POLL_PERIOD_US,
332-
MB_POLL_TIMEOUT_US)) {
334+
MB_POLL_TIMEOUT_US);
335+
if (ret) {
333336
dev_err(&qm->pdev->dev, "vf QM writeback sqc cache fail\n");
334-
return -EINVAL;
337+
return ret;
335338
}
336339

337340
return 0;
@@ -350,6 +353,32 @@ static int vf_qm_func_stop(struct hisi_qm *qm)
350353
return hisi_qm_mb(qm, QM_MB_CMD_PAUSE_QM, 0, 0, 0);
351354
}
352355

356+
static int vf_qm_version_check(struct acc_vf_data *vf_data, struct device *dev)
357+
{
358+
switch (vf_data->acc_magic) {
359+
case ACC_DEV_MAGIC_V2:
360+
if (vf_data->major_ver != ACC_DRV_MAJOR_VER) {
361+
dev_info(dev, "migration driver version<%u.%u> not match!\n",
362+
vf_data->major_ver, vf_data->minor_ver);
363+
return -EINVAL;
364+
}
365+
break;
366+
case ACC_DEV_MAGIC_V1:
367+
/* Correct dma address */
368+
vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
369+
vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
370+
vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
371+
vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
372+
vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
373+
vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
374+
break;
375+
default:
376+
return -EINVAL;
377+
}
378+
379+
return 0;
380+
}
381+
353382
static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
354383
struct hisi_acc_vf_migration_file *migf)
355384
{
@@ -363,9 +392,10 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
363392
if (migf->total_length < QM_MATCH_SIZE || hisi_acc_vdev->match_done)
364393
return 0;
365394

366-
if (vf_data->acc_magic != ACC_DEV_MAGIC) {
395+
ret = vf_qm_version_check(vf_data, dev);
396+
if (ret) {
367397
dev_err(dev, "failed to match ACC_DEV_MAGIC\n");
368-
return -EINVAL;
398+
return ret;
369399
}
370400

371401
if (vf_data->dev_id != hisi_acc_vdev->vf_dev->device) {
@@ -377,7 +407,7 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
377407
ret = qm_get_vft(vf_qm, &vf_qm->qp_base);
378408
if (ret <= 0) {
379409
dev_err(dev, "failed to get vft qp nums\n");
380-
return -EINVAL;
410+
return ret;
381411
}
382412

383413
if (ret != vf_data->qp_num) {
@@ -399,13 +429,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
399429
return -EINVAL;
400430
}
401431

402-
ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
403-
if (ret) {
404-
dev_err(dev, "failed to write QM_VF_STATE\n");
405-
return ret;
406-
}
407-
408-
hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
409432
hisi_acc_vdev->match_done = true;
410433
return 0;
411434
}
@@ -418,7 +441,9 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
418441
int vf_id = hisi_acc_vdev->vf_id;
419442
int ret;
420443

421-
vf_data->acc_magic = ACC_DEV_MAGIC;
444+
vf_data->acc_magic = ACC_DEV_MAGIC_V2;
445+
vf_data->major_ver = ACC_DRV_MAJOR_VER;
446+
vf_data->minor_ver = ACC_DRV_MINOR_VER;
422447
/* Save device id */
423448
vf_data->dev_id = hisi_acc_vdev->vf_dev->device;
424449

@@ -441,6 +466,19 @@ static int vf_qm_get_match_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
441466
return 0;
442467
}
443468

469+
static void vf_qm_xeqc_save(struct hisi_qm *qm,
470+
struct hisi_acc_vf_migration_file *migf)
471+
{
472+
struct acc_vf_data *vf_data = &migf->vf_data;
473+
u16 eq_head, aeq_head;
474+
475+
eq_head = vf_data->qm_eqc_dw[0] & 0xFFFF;
476+
qm_db(qm, 0, QM_DOORBELL_CMD_EQ, eq_head, 0);
477+
478+
aeq_head = vf_data->qm_aeqc_dw[0] & 0xFFFF;
479+
qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, aeq_head, 0);
480+
}
481+
444482
static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
445483
struct hisi_acc_vf_migration_file *migf)
446484
{
@@ -456,6 +494,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
456494
if (migf->total_length < sizeof(struct acc_vf_data))
457495
return -EINVAL;
458496

497+
if (!vf_data->eqe_dma || !vf_data->aeqe_dma ||
498+
!vf_data->sqc_dma || !vf_data->cqc_dma) {
499+
dev_info(dev, "resume dma addr is NULL!\n");
500+
hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
501+
return 0;
502+
}
503+
504+
ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
505+
if (ret) {
506+
dev_err(dev, "failed to write QM_VF_STATE\n");
507+
return ret;
508+
}
509+
hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
510+
459511
qm->eqe_dma = vf_data->eqe_dma;
460512
qm->aeqe_dma = vf_data->aeqe_dma;
461513
qm->sqc_dma = vf_data->sqc_dma;
@@ -493,27 +545,27 @@ static int vf_qm_read_data(struct hisi_qm *vf_qm, struct acc_vf_data *vf_data)
493545

494546
ret = qm_get_regs(vf_qm, vf_data);
495547
if (ret)
496-
return -EINVAL;
548+
return ret;
497549

498550
/* Every reg is 32 bit, the dma address is 64 bit. */
499-
vf_data->eqe_dma = vf_data->qm_eqc_dw[1];
551+
vf_data->eqe_dma = vf_data->qm_eqc_dw[QM_XQC_ADDR_HIGH];
500552
vf_data->eqe_dma <<= QM_XQC_ADDR_OFFSET;
501-
vf_data->eqe_dma |= vf_data->qm_eqc_dw[0];
502-
vf_data->aeqe_dma = vf_data->qm_aeqc_dw[1];
553+
vf_data->eqe_dma |= vf_data->qm_eqc_dw[QM_XQC_ADDR_LOW];
554+
vf_data->aeqe_dma = vf_data->qm_aeqc_dw[QM_XQC_ADDR_HIGH];
503555
vf_data->aeqe_dma <<= QM_XQC_ADDR_OFFSET;
504-
vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[0];
556+
vf_data->aeqe_dma |= vf_data->qm_aeqc_dw[QM_XQC_ADDR_LOW];
505557

506558
/* Through SQC_BT/CQC_BT to get sqc and cqc address */
507559
ret = qm_get_sqc(vf_qm, &vf_data->sqc_dma);
508560
if (ret) {
509561
dev_err(dev, "failed to read SQC addr!\n");
510-
return -EINVAL;
562+
return ret;
511563
}
512564

513565
ret = qm_get_cqc(vf_qm, &vf_data->cqc_dma);
514566
if (ret) {
515567
dev_err(dev, "failed to read CQC addr!\n");
516-
return -EINVAL;
568+
return ret;
517569
}
518570

519571
return 0;
@@ -524,7 +576,6 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
524576
{
525577
struct acc_vf_data *vf_data = &migf->vf_data;
526578
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
527-
struct device *dev = &vf_qm->pdev->dev;
528579
int ret;
529580

530581
if (unlikely(qm_wait_dev_not_ready(vf_qm))) {
@@ -538,17 +589,14 @@ static int vf_qm_state_save(struct hisi_acc_vf_core_device *hisi_acc_vdev,
538589
vf_data->vf_qm_state = QM_READY;
539590
hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
540591

541-
ret = vf_qm_cache_wb(vf_qm);
542-
if (ret) {
543-
dev_err(dev, "failed to writeback QM Cache!\n");
544-
return ret;
545-
}
546-
547592
ret = vf_qm_read_data(vf_qm, vf_data);
548593
if (ret)
549-
return -EINVAL;
594+
return ret;
550595

551596
migf->total_length = sizeof(struct acc_vf_data);
597+
/* Save eqc and aeqc interrupt information */
598+
vf_qm_xeqc_save(vf_qm, migf);
599+
552600
return 0;
553601
}
554602

@@ -967,6 +1015,13 @@ static int hisi_acc_vf_stop_device(struct hisi_acc_vf_core_device *hisi_acc_vdev
9671015
dev_err(dev, "failed to check QM INT state!\n");
9681016
return ret;
9691017
}
1018+
1019+
ret = vf_qm_cache_wb(vf_qm);
1020+
if (ret) {
1021+
dev_err(dev, "failed to writeback QM cache!\n");
1022+
return ret;
1023+
}
1024+
9701025
return 0;
9711026
}
9721027

@@ -1327,7 +1382,7 @@ static int hisi_acc_vf_debug_check(struct seq_file *seq, struct vfio_device *vde
13271382
ret = qm_wait_dev_not_ready(vf_qm);
13281383
if (ret) {
13291384
seq_puts(seq, "VF device not ready!\n");
1330-
return -EBUSY;
1385+
return ret;
13311386
}
13321387

13331388
return 0;
@@ -1463,6 +1518,7 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev)
14631518
struct hisi_acc_vf_core_device *hisi_acc_vdev = hisi_acc_get_vf_dev(core_vdev);
14641519
struct hisi_qm *vf_qm = &hisi_acc_vdev->vf_qm;
14651520

1521+
hisi_acc_vf_disable_fds(hisi_acc_vdev);
14661522
mutex_lock(&hisi_acc_vdev->open_mutex);
14671523
hisi_acc_vdev->dev_opened = false;
14681524
iounmap(vf_qm->io_base);
@@ -1485,6 +1541,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
14851541
hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
14861542
hisi_acc_vdev->pf_qm = pf_qm;
14871543
hisi_acc_vdev->vf_dev = pdev;
1544+
hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
14881545
mutex_init(&hisi_acc_vdev->state_mutex);
14891546
mutex_init(&hisi_acc_vdev->open_mutex);
14901547

drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
#define QM_REG_ADDR_OFFSET 0x0004
4040

4141
#define QM_XQC_ADDR_OFFSET 32U
42+
#define QM_XQC_ADDR_LOW 0x1
43+
#define QM_XQC_ADDR_HIGH 0x2
44+
4245
#define QM_VF_AEQ_INT_MASK 0x0004
4346
#define QM_VF_EQ_INT_MASK 0x000c
4447
#define QM_IFC_INT_SOURCE_V 0x0020
@@ -50,18 +53,25 @@
5053
#define QM_EQC_DW0 0X8000
5154
#define QM_AEQC_DW0 0X8020
5255

56+
#define ACC_DRV_MAJOR_VER 1
57+
#define ACC_DRV_MINOR_VER 0
58+
59+
#define ACC_DEV_MAGIC_V1 0XCDCDCDCDFEEDAACC
60+
#define ACC_DEV_MAGIC_V2 0xAACCFEEDDECADEDE
61+
5362
struct acc_vf_data {
5463
#define QM_MATCH_SIZE offsetofend(struct acc_vf_data, qm_rsv_state)
5564
/* QM match information */
56-
#define ACC_DEV_MAGIC 0XCDCDCDCDFEEDAACC
5765
u64 acc_magic;
5866
u32 qp_num;
5967
u32 dev_id;
6068
u32 que_iso_cfg;
6169
u32 qp_base;
6270
u32 vf_qm_state;
6371
/* QM reserved match information */
64-
u32 qm_rsv_state[3];
72+
u16 major_ver;
73+
u16 minor_ver;
74+
u32 qm_rsv_state[2];
6575

6676
/* QM RW regs */
6777
u32 aeq_int_mask;

0 commit comments

Comments
 (0)