Commit 0fce55e5 authored by Xin Zeng's avatar Xin Zeng Committed by Herbert Xu
Browse files

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: default avatarXin Zeng <xin.zeng@intel.com>
Reviewed-by: default avatarGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent bbfdde7d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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

+10 −0
Original line number Diff line number Diff line
/* 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
+130 −0
Original line number Diff line number Diff line
// 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);
+31 −0
Original line number Diff line number Diff line
/* 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_*/