crypto: qat - add interface for live migration

Extend the driver with a new interface to be used for VF live migration.
This allows to create and destroy a qat_mig_dev object that contains
a set of methods to allow to save and restore the state of QAT VF.
This interface will be used by the qat-vfio-pci module.

Signed-off-by: Xin Zeng <xin.zeng@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Xin Zeng 2024-03-06 21:58:53 +08:00 committed by Herbert Xu
parent bbfdde7d19
commit 0fce55e533
5 changed files with 189 additions and 1 deletions

View File

@ -54,6 +54,6 @@ intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o \
intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \
adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \
adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \
adf_gen2_pfvf.o adf_gen4_pfvf.o
adf_gen2_pfvf.o adf_gen4_pfvf.o qat_mig_dev.o
intel_qat-$(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION) += adf_heartbeat_inject.o

View File

@ -9,6 +9,7 @@
#include <linux/pci.h>
#include <linux/ratelimit.h>
#include <linux/types.h>
#include <linux/qat/qat_mig_dev.h>
#include "adf_cfg_common.h"
#include "adf_rl.h"
#include "adf_telemetry.h"
@ -258,6 +259,20 @@ struct adf_dc_ops {
void (*build_deflate_ctx)(void *ctx);
};
struct qat_migdev_ops {
int (*init)(struct qat_mig_dev *mdev);
void (*cleanup)(struct qat_mig_dev *mdev);
void (*reset)(struct qat_mig_dev *mdev);
int (*open)(struct qat_mig_dev *mdev);
void (*close)(struct qat_mig_dev *mdev);
int (*suspend)(struct qat_mig_dev *mdev);
int (*resume)(struct qat_mig_dev *mdev);
int (*save_state)(struct qat_mig_dev *mdev);
int (*save_setup)(struct qat_mig_dev *mdev);
int (*load_state)(struct qat_mig_dev *mdev);
int (*load_setup)(struct qat_mig_dev *mdev, int size);
};
struct adf_dev_err_mask {
u32 cppagentcmdpar_mask;
u32 parerr_ath_cph_mask;
@ -325,6 +340,7 @@ struct adf_hw_device_data {
struct adf_dev_err_mask dev_err_mask;
struct adf_rl_hw_data rl_data;
struct adf_tl_hw_data tl_data;
struct qat_migdev_ops vfmig_ops;
const char *fw_name;
const char *fw_mmp_name;
u32 fuses;
@ -381,6 +397,7 @@ struct adf_hw_device_data {
#define GET_CSR_OPS(accel_dev) (&(accel_dev)->hw_device->csr_ops)
#define GET_PFVF_OPS(accel_dev) (&(accel_dev)->hw_device->pfvf_ops)
#define GET_DC_OPS(accel_dev) (&(accel_dev)->hw_device->dc_ops)
#define GET_VFMIG_OPS(accel_dev) (&(accel_dev)->hw_device->vfmig_ops)
#define GET_TL_DATA(accel_dev) GET_HW_DATA(accel_dev)->tl_data
#define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev

View File

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright(c) 2024 Intel Corporation */
#ifndef ADF_GEN4_VF_MIG_H_
#define ADF_GEN4_VF_MIG_H_
#include "adf_accel_devices.h"
void adf_gen4_init_vf_mig_ops(struct qat_migdev_ops *vfmig_ops);
#endif

View File

@ -0,0 +1,130 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2024 Intel Corporation */
#include <linux/dev_printk.h>
#include <linux/export.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <linux/qat/qat_mig_dev.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
struct qat_mig_dev *qat_vfmig_create(struct pci_dev *pdev, int vf_id)
{
struct adf_accel_dev *accel_dev;
struct qat_migdev_ops *ops;
struct qat_mig_dev *mdev;
accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
if (!accel_dev)
return ERR_PTR(-ENODEV);
ops = GET_VFMIG_OPS(accel_dev);
if (!ops || !ops->init || !ops->cleanup || !ops->reset || !ops->open ||
!ops->close || !ops->suspend || !ops->resume || !ops->save_state ||
!ops->load_state || !ops->save_setup || !ops->load_setup)
return ERR_PTR(-EINVAL);
mdev = kmalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return ERR_PTR(-ENOMEM);
mdev->vf_id = vf_id;
mdev->parent_accel_dev = accel_dev;
return mdev;
}
EXPORT_SYMBOL_GPL(qat_vfmig_create);
int qat_vfmig_init(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->init(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_init);
void qat_vfmig_cleanup(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->cleanup(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_cleanup);
void qat_vfmig_reset(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->reset(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_reset);
int qat_vfmig_open(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->open(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_open);
void qat_vfmig_close(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
GET_VFMIG_OPS(accel_dev)->close(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_close);
int qat_vfmig_suspend(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->suspend(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_suspend);
int qat_vfmig_resume(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->resume(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_resume);
int qat_vfmig_save_state(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->save_state(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_save_state);
int qat_vfmig_save_setup(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->save_setup(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_save_setup);
int qat_vfmig_load_state(struct qat_mig_dev *mdev)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->load_state(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_load_state);
int qat_vfmig_load_setup(struct qat_mig_dev *mdev, int size)
{
struct adf_accel_dev *accel_dev = mdev->parent_accel_dev;
return GET_VFMIG_OPS(accel_dev)->load_setup(mdev, size);
}
EXPORT_SYMBOL_GPL(qat_vfmig_load_setup);
void qat_vfmig_destroy(struct qat_mig_dev *mdev)
{
kfree(mdev);
}
EXPORT_SYMBOL_GPL(qat_vfmig_destroy);

View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright(c) 2024 Intel Corporation */
#ifndef QAT_MIG_DEV_H_
#define QAT_MIG_DEV_H_
struct pci_dev;
struct qat_mig_dev {
void *parent_accel_dev;
u8 *state;
u32 setup_size;
u32 remote_setup_size;
u32 state_size;
s32 vf_id;
};
struct qat_mig_dev *qat_vfmig_create(struct pci_dev *pdev, int vf_id);
int qat_vfmig_init(struct qat_mig_dev *mdev);
void qat_vfmig_cleanup(struct qat_mig_dev *mdev);
void qat_vfmig_reset(struct qat_mig_dev *mdev);
int qat_vfmig_open(struct qat_mig_dev *mdev);
void qat_vfmig_close(struct qat_mig_dev *mdev);
int qat_vfmig_suspend(struct qat_mig_dev *mdev);
int qat_vfmig_resume(struct qat_mig_dev *mdev);
int qat_vfmig_save_state(struct qat_mig_dev *mdev);
int qat_vfmig_save_setup(struct qat_mig_dev *mdev);
int qat_vfmig_load_state(struct qat_mig_dev *mdev);
int qat_vfmig_load_setup(struct qat_mig_dev *mdev, int size);
void qat_vfmig_destroy(struct qat_mig_dev *mdev);
#endif /*QAT_MIG_DEV_H_*/