mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-02 03:37:39 -04:00
crypto: qat - add anti-rollback support for GEN6 devices
Anti-Rollback (ARB) is a QAT GEN6 hardware feature that prevents loading firmware with a Security Version Number (SVN) lower than an authorized minimum. This protects against downgrade attacks by ensuring that only firmware at or above a committed SVN can run on the acceleration device. During firmware loading, the driver checks the SVN validation status via a hardware CSR. If the check reports a failure, firmware authentication is aborted. If it reports a retry status, the driver reissues the authentication command up to a maximum number of retries. Extend the firmware admin interface with two new messages, ICP_QAT_FW_SVN_READ and ICP_QAT_FW_SVN_COMMIT, to query and commit the SVN, respectively. Integrate the SVN check into the firmware authentication path in qat_uclo.c so the driver can react to anti-rollback status during device bring-up. Expose SVN information to userspace via a new sysfs attribute group, qat_svn, under the PCI device directory. The group provides read-only attributes for the active, enforced minimum, and permanent minimum SVN values, as well as a write-only commit attribute that allows a system administrator to commit the currently active SVN as the new authorized minimum. This is based on earlier work by Ciunas Bennett. Signed-off-by: Suman Kumar Chakraborty <suman.kumar.chakraborty@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:
committed by
Herbert Xu
parent
177730a273
commit
6ac142bf26
114
Documentation/ABI/testing/sysfs-driver-qat_svn
Normal file
114
Documentation/ABI/testing/sysfs-driver-qat_svn
Normal file
@@ -0,0 +1,114 @@
|
||||
What: /sys/bus/pci/devices/<BDF>/qat_svn/
|
||||
Date: June 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: qat-linux@intel.com
|
||||
Description: Directory containing Security Version Number (SVN) attributes for
|
||||
the Anti-Rollback (ARB) feature. The ARB feature prevents downloading
|
||||
older firmware versions to the acceleration device.
|
||||
|
||||
What: /sys/bus/pci/devices/<BDF>/qat_svn/enforced_min
|
||||
Date: June 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: qat-linux@intel.com
|
||||
Description:
|
||||
(RO) Reports the minimum allowed firmware SVN.
|
||||
|
||||
Returns an integer greater than zero. Firmware with SVN lower than
|
||||
this value is rejected.
|
||||
|
||||
A write to qat_svn/commit will update this value. The update is not
|
||||
persistent across reboot; on reboot, this value is reset from
|
||||
qat_svn/permanent_min.
|
||||
|
||||
Example usage::
|
||||
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/enforced_min
|
||||
2
|
||||
|
||||
This attribute is available only on devices that support
|
||||
Anti-Rollback.
|
||||
|
||||
What: /sys/bus/pci/devices/<BDF>/qat_svn/permanent_min
|
||||
Date: June 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: qat-linux@intel.com
|
||||
Description:
|
||||
(RO) Reports the persistent minimum SVN used to initialize
|
||||
qat_svn/enforced_min on each reboot.
|
||||
|
||||
Returns an integer greater than zero. A write to qat_svn/commit
|
||||
may update this value, depending on platform/BIOS settings.
|
||||
|
||||
Example usage::
|
||||
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/permanent_min
|
||||
3
|
||||
|
||||
This attribute is available only on devices that support
|
||||
Anti-Rollback.
|
||||
|
||||
What: /sys/bus/pci/devices/<BDF>/qat_svn/active
|
||||
Date: June 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: qat-linux@intel.com
|
||||
Description:
|
||||
(RO) Reports the SVN of the currently active firmware image.
|
||||
|
||||
Returns an integer greater than zero.
|
||||
|
||||
Example usage::
|
||||
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/active
|
||||
2
|
||||
|
||||
This attribute is available only on devices that support
|
||||
Anti-Rollback.
|
||||
|
||||
What: /sys/bus/pci/devices/<BDF>/qat_svn/commit
|
||||
Date: June 2026
|
||||
KernelVersion: 7.1
|
||||
Contact: qat-linux@intel.com
|
||||
Description:
|
||||
(WO) Commits the currently active SVN as the minimum allowed SVN.
|
||||
|
||||
Writing 1 sets qat_svn/enforced_min to the value of qat_svn/active,
|
||||
preventing future firmware loads with lower SVN.
|
||||
|
||||
Depending on platform/BIOS settings, a commit may also update
|
||||
qat_svn/permanent_min.
|
||||
|
||||
Note that on reboot, qat_svn/enforced_min reverts to
|
||||
qat_svn/permanent_min.
|
||||
|
||||
It is advisable to use this attribute with caution, only when
|
||||
it is necessary to set a new minimum SVN for the firmware.
|
||||
|
||||
Before committing the SVN update, it is crucial to check the
|
||||
current values of qat_svn/active, qat_svn/enforced_min and
|
||||
qat_svn/permanent_min. This verification helps ensure that the
|
||||
commit operation aligns with the intended outcome.
|
||||
|
||||
While writing to the file, any value other than '1' will result
|
||||
in an error and have no effect.
|
||||
|
||||
Example usage::
|
||||
|
||||
## Read current values
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/enforced_min
|
||||
2
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/permanent_min
|
||||
2
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/active
|
||||
3
|
||||
|
||||
## Commit active SVN
|
||||
# echo 1 > /sys/bus/pci/devices/<BDF>/qat_svn/commit
|
||||
|
||||
## Read updated values
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/enforced_min
|
||||
3
|
||||
# cat /sys/bus/pci/devices/<BDF>/qat_svn/permanent_min
|
||||
3
|
||||
|
||||
This attribute is available only on devices that support
|
||||
Anti-Rollback.
|
||||
@@ -462,6 +462,21 @@ static int reset_ring_pair(void __iomem *csr, u32 bank_number)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool adf_anti_rb_enabled(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
|
||||
|
||||
return !!(hw_data->fuses[0] & ADF_GEN6_ANTI_RB_FUSE_BIT);
|
||||
}
|
||||
|
||||
static void adf_gen6_init_anti_rb(struct adf_anti_rb_hw_data *anti_rb_data)
|
||||
{
|
||||
anti_rb_data->anti_rb_enabled = adf_anti_rb_enabled;
|
||||
anti_rb_data->svncheck_offset = ADF_GEN6_SVNCHECK_CSR_MSG;
|
||||
anti_rb_data->svncheck_retry = 0;
|
||||
anti_rb_data->sysfs_added = false;
|
||||
}
|
||||
|
||||
static int ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number)
|
||||
{
|
||||
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
|
||||
@@ -1024,6 +1039,7 @@ void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data)
|
||||
adf_gen6_init_ras_ops(&hw_data->ras_ops);
|
||||
adf_gen6_init_tl_data(&hw_data->tl_data);
|
||||
adf_gen6_init_rl_data(&hw_data->rl_data);
|
||||
adf_gen6_init_anti_rb(&hw_data->anti_rb_data);
|
||||
}
|
||||
|
||||
void adf_clean_hw_data_6xxx(struct adf_hw_device_data *hw_data)
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
#define ADF_GEN6_ADMINMSGLR_OFFSET 0x500578
|
||||
#define ADF_GEN6_MAILBOX_BASE_OFFSET 0x600970
|
||||
|
||||
/* Anti-rollback */
|
||||
#define ADF_GEN6_SVNCHECK_CSR_MSG 0x640004
|
||||
|
||||
/* Fuse bits */
|
||||
#define ADF_GEN6_ANTI_RB_FUSE_BIT BIT(24)
|
||||
|
||||
/*
|
||||
* Watchdog timers
|
||||
* Timeout is in cycles. Clock speed may vary across products but this
|
||||
|
||||
@@ -4,6 +4,7 @@ ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE='"CRYPTO_QAT"'
|
||||
intel_qat-y := adf_accel_engine.o \
|
||||
adf_admin.o \
|
||||
adf_aer.o \
|
||||
adf_anti_rb.o \
|
||||
adf_bank_state.o \
|
||||
adf_cfg.o \
|
||||
adf_cfg_services.o \
|
||||
@@ -29,6 +30,7 @@ intel_qat-y := adf_accel_engine.o \
|
||||
adf_rl_admin.o \
|
||||
adf_rl.o \
|
||||
adf_sysfs.o \
|
||||
adf_sysfs_anti_rb.o \
|
||||
adf_sysfs_ras_counters.o \
|
||||
adf_sysfs_rl.o \
|
||||
adf_timer.o \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/qat/qat_mig_dev.h>
|
||||
#include <linux/wordpart.h>
|
||||
#include "adf_anti_rb.h"
|
||||
#include "adf_cfg_common.h"
|
||||
#include "adf_dc.h"
|
||||
#include "adf_rl.h"
|
||||
@@ -328,6 +329,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 adf_anti_rb_hw_data anti_rb_data;
|
||||
struct qat_migdev_ops vfmig_ops;
|
||||
const char *fw_name;
|
||||
const char *fw_mmp_name;
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include "adf_accel_devices.h"
|
||||
#include "adf_admin.h"
|
||||
#include "adf_anti_rb.h"
|
||||
#include "adf_common_drv.h"
|
||||
#include "adf_cfg.h"
|
||||
#include "adf_heartbeat.h"
|
||||
@@ -19,6 +21,7 @@
|
||||
#define ADF_ADMIN_POLL_DELAY_US 20
|
||||
#define ADF_ADMIN_POLL_TIMEOUT_US (5 * USEC_PER_SEC)
|
||||
#define ADF_ONE_AE 1
|
||||
#define ADF_ADMIN_RETRY_MAX 60
|
||||
|
||||
static const u8 const_tab[1024] __aligned(1024) = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -536,6 +539,73 @@ int adf_send_admin_tl_stop(struct adf_accel_dev *accel_dev)
|
||||
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
|
||||
}
|
||||
|
||||
static int adf_send_admin_retry(struct adf_accel_dev *accel_dev, u8 cmd_id,
|
||||
struct icp_qat_fw_init_admin_resp *resp,
|
||||
unsigned int sleep_ms)
|
||||
{
|
||||
u32 admin_ae_mask = GET_HW_DATA(accel_dev)->admin_ae_mask;
|
||||
struct icp_qat_fw_init_admin_req req = { };
|
||||
unsigned int retries = ADF_ADMIN_RETRY_MAX;
|
||||
int ret;
|
||||
|
||||
req.cmd_id = cmd_id;
|
||||
|
||||
do {
|
||||
ret = adf_send_admin(accel_dev, &req, resp, admin_ae_mask);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
if (resp->status != ICP_QAT_FW_INIT_RESP_STATUS_RETRY)
|
||||
return ret;
|
||||
|
||||
msleep(sleep_ms);
|
||||
} while (--retries);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int adf_send_admin_svn(struct adf_accel_dev *accel_dev, u8 cmd_id,
|
||||
struct icp_qat_fw_init_admin_resp *resp)
|
||||
{
|
||||
return adf_send_admin_retry(accel_dev, cmd_id, resp, ADF_SVN_RETRY_MS);
|
||||
}
|
||||
|
||||
int adf_send_admin_arb_query(struct adf_accel_dev *accel_dev, int cmd, u8 *svn)
|
||||
{
|
||||
struct icp_qat_fw_init_admin_resp resp = { };
|
||||
int ret;
|
||||
|
||||
ret = adf_send_admin_svn(accel_dev, ICP_QAT_FW_SVN_READ, &resp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (cmd) {
|
||||
case ARB_ENFORCED_MIN_SVN:
|
||||
*svn = resp.enforced_min_svn;
|
||||
break;
|
||||
case ARB_PERMANENT_MIN_SVN:
|
||||
*svn = resp.permanent_min_svn;
|
||||
break;
|
||||
case ARB_ACTIVE_SVN:
|
||||
*svn = resp.active_svn;
|
||||
break;
|
||||
default:
|
||||
*svn = 0;
|
||||
dev_err(&GET_DEV(accel_dev),
|
||||
"Unknown secure version number request\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adf_send_admin_arb_commit(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
struct icp_qat_fw_init_admin_resp resp = { };
|
||||
|
||||
return adf_send_admin_svn(accel_dev, ICP_QAT_FW_SVN_COMMIT, &resp);
|
||||
}
|
||||
|
||||
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
struct adf_admin_comms *admin;
|
||||
|
||||
@@ -27,5 +27,7 @@ int adf_send_admin_tl_start(struct adf_accel_dev *accel_dev,
|
||||
dma_addr_t tl_dma_addr, size_t layout_sz, u8 *rp_indexes,
|
||||
struct icp_qat_fw_init_admin_slice_cnt *slice_count);
|
||||
int adf_send_admin_tl_stop(struct adf_accel_dev *accel_dev);
|
||||
int adf_send_admin_arb_query(struct adf_accel_dev *accel_dev, int cmd, u8 *svn);
|
||||
int adf_send_admin_arb_commit(struct adf_accel_dev *accel_dev);
|
||||
|
||||
#endif
|
||||
|
||||
66
drivers/crypto/intel/qat/qat_common/adf_anti_rb.c
Normal file
66
drivers/crypto/intel/qat/qat_common/adf_anti_rb.c
Normal file
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2026 Intel Corporation */
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kstrtox.h>
|
||||
|
||||
#include "adf_accel_devices.h"
|
||||
#include "adf_admin.h"
|
||||
#include "adf_anti_rb.h"
|
||||
#include "adf_common_drv.h"
|
||||
#include "icp_qat_fw_init_admin.h"
|
||||
|
||||
#define ADF_SVN_RETRY_MAX 60
|
||||
|
||||
int adf_anti_rb_commit(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
return adf_send_admin_arb_commit(accel_dev);
|
||||
}
|
||||
|
||||
int adf_anti_rb_query(struct adf_accel_dev *accel_dev, enum anti_rb cmd, u8 *svn)
|
||||
{
|
||||
return adf_send_admin_arb_query(accel_dev, cmd, svn);
|
||||
}
|
||||
|
||||
int adf_anti_rb_check(struct pci_dev *pdev)
|
||||
{
|
||||
struct adf_anti_rb_hw_data *anti_rb;
|
||||
u32 svncheck_sts, cfc_svncheck_sts;
|
||||
struct adf_accel_dev *accel_dev;
|
||||
void __iomem *pmisc_addr;
|
||||
|
||||
accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
|
||||
if (!accel_dev)
|
||||
return -EINVAL;
|
||||
|
||||
anti_rb = GET_ANTI_RB_DATA(accel_dev);
|
||||
if (!anti_rb->anti_rb_enabled || !anti_rb->anti_rb_enabled(accel_dev))
|
||||
return 0;
|
||||
|
||||
pmisc_addr = adf_get_pmisc_base(accel_dev);
|
||||
|
||||
cfc_svncheck_sts = ADF_CSR_RD(pmisc_addr, anti_rb->svncheck_offset);
|
||||
|
||||
svncheck_sts = FIELD_GET(ADF_SVN_STS_MASK, cfc_svncheck_sts);
|
||||
switch (svncheck_sts) {
|
||||
case ADF_SVN_NO_STS:
|
||||
return 0;
|
||||
case ADF_SVN_PASS_STS:
|
||||
anti_rb->svncheck_retry = 0;
|
||||
return 0;
|
||||
case ADF_SVN_FAIL_STS:
|
||||
dev_err(&GET_DEV(accel_dev), "Security Version Number failure\n");
|
||||
return -EIO;
|
||||
case ADF_SVN_RETRY_STS:
|
||||
if (anti_rb->svncheck_retry++ >= ADF_SVN_RETRY_MAX) {
|
||||
anti_rb->svncheck_retry = 0;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
msleep(ADF_SVN_RETRY_MS);
|
||||
return -EAGAIN;
|
||||
default:
|
||||
dev_err(&GET_DEV(accel_dev), "Invalid SVN check status\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
37
drivers/crypto/intel/qat/qat_common/adf_anti_rb.h
Normal file
37
drivers/crypto/intel/qat/qat_common/adf_anti_rb.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright(c) 2026 Intel Corporation */
|
||||
#ifndef ADF_ANTI_RB_H_
|
||||
#define ADF_ANTI_RB_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define GET_ANTI_RB_DATA(accel_dev) (&(accel_dev)->hw_device->anti_rb_data)
|
||||
|
||||
#define ADF_SVN_NO_STS 0x00
|
||||
#define ADF_SVN_PASS_STS 0x01
|
||||
#define ADF_SVN_RETRY_STS 0x02
|
||||
#define ADF_SVN_FAIL_STS 0x03
|
||||
#define ADF_SVN_RETRY_MS 250
|
||||
#define ADF_SVN_STS_MASK GENMASK(7, 0)
|
||||
|
||||
enum anti_rb {
|
||||
ARB_ENFORCED_MIN_SVN,
|
||||
ARB_PERMANENT_MIN_SVN,
|
||||
ARB_ACTIVE_SVN,
|
||||
};
|
||||
|
||||
struct adf_accel_dev;
|
||||
struct pci_dev;
|
||||
|
||||
struct adf_anti_rb_hw_data {
|
||||
bool (*anti_rb_enabled)(struct adf_accel_dev *accel_dev);
|
||||
u32 svncheck_offset;
|
||||
u32 svncheck_retry;
|
||||
bool sysfs_added;
|
||||
};
|
||||
|
||||
int adf_anti_rb_commit(struct adf_accel_dev *accel_dev);
|
||||
int adf_anti_rb_query(struct adf_accel_dev *accel_dev, enum anti_rb cmd, u8 *svn);
|
||||
int adf_anti_rb_check(struct pci_dev *pdev);
|
||||
|
||||
#endif /* ADF_ANTI_RB_H_ */
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "adf_dbgfs.h"
|
||||
#include "adf_heartbeat.h"
|
||||
#include "adf_rl.h"
|
||||
#include "adf_sysfs_anti_rb.h"
|
||||
#include "adf_sysfs_ras_counters.h"
|
||||
#include "adf_telemetry.h"
|
||||
|
||||
@@ -263,6 +264,7 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev)
|
||||
|
||||
adf_dbgfs_add(accel_dev);
|
||||
adf_sysfs_start_ras(accel_dev);
|
||||
adf_sysfs_start_arb(accel_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -292,6 +294,7 @@ static void adf_dev_stop(struct adf_accel_dev *accel_dev)
|
||||
adf_rl_stop(accel_dev);
|
||||
adf_dbgfs_rm(accel_dev);
|
||||
adf_sysfs_stop_ras(accel_dev);
|
||||
adf_sysfs_stop_arb(accel_dev);
|
||||
|
||||
clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
|
||||
clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
|
||||
|
||||
133
drivers/crypto/intel/qat/qat_common/adf_sysfs_anti_rb.c
Normal file
133
drivers/crypto/intel/qat/qat_common/adf_sysfs_anti_rb.c
Normal file
@@ -0,0 +1,133 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2026 Intel Corporation */
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "adf_anti_rb.h"
|
||||
#include "adf_common_drv.h"
|
||||
#include "adf_sysfs_anti_rb.h"
|
||||
|
||||
static ssize_t enforced_min_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct adf_accel_dev *accel_dev;
|
||||
int err;
|
||||
u8 svn;
|
||||
|
||||
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
||||
if (!accel_dev)
|
||||
return -EINVAL;
|
||||
|
||||
err = adf_anti_rb_query(accel_dev, ARB_ENFORCED_MIN_SVN, &svn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sysfs_emit(buf, "%u\n", svn);
|
||||
}
|
||||
static DEVICE_ATTR_RO(enforced_min);
|
||||
|
||||
static ssize_t active_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct adf_accel_dev *accel_dev;
|
||||
int err;
|
||||
u8 svn;
|
||||
|
||||
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
||||
if (!accel_dev)
|
||||
return -EINVAL;
|
||||
|
||||
err = adf_anti_rb_query(accel_dev, ARB_ACTIVE_SVN, &svn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sysfs_emit(buf, "%u\n", svn);
|
||||
}
|
||||
static DEVICE_ATTR_RO(active);
|
||||
|
||||
static ssize_t permanent_min_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct adf_accel_dev *accel_dev;
|
||||
int err;
|
||||
u8 svn;
|
||||
|
||||
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
||||
if (!accel_dev)
|
||||
return -EINVAL;
|
||||
|
||||
err = adf_anti_rb_query(accel_dev, ARB_PERMANENT_MIN_SVN, &svn);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return sysfs_emit(buf, "%u\n", svn);
|
||||
}
|
||||
static DEVICE_ATTR_RO(permanent_min);
|
||||
|
||||
static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct adf_accel_dev *accel_dev;
|
||||
bool val;
|
||||
int err;
|
||||
|
||||
accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
|
||||
if (!accel_dev)
|
||||
return -EINVAL;
|
||||
|
||||
err = kstrtobool(buf, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
err = adf_anti_rb_commit(accel_dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_WO(commit);
|
||||
|
||||
static struct attribute *qat_svn_attrs[] = {
|
||||
&dev_attr_commit.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_enforced_min.attr,
|
||||
&dev_attr_permanent_min.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group qat_svn_group = {
|
||||
.attrs = qat_svn_attrs,
|
||||
.name = "qat_svn",
|
||||
};
|
||||
|
||||
void adf_sysfs_start_arb(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
struct adf_anti_rb_hw_data *anti_rb = GET_ANTI_RB_DATA(accel_dev);
|
||||
|
||||
if (!anti_rb->anti_rb_enabled || !anti_rb->anti_rb_enabled(accel_dev))
|
||||
return;
|
||||
|
||||
if (device_add_group(&GET_DEV(accel_dev), &qat_svn_group)) {
|
||||
dev_warn(&GET_DEV(accel_dev),
|
||||
"Failed to create qat_svn attribute group\n");
|
||||
return;
|
||||
}
|
||||
|
||||
anti_rb->sysfs_added = true;
|
||||
}
|
||||
|
||||
void adf_sysfs_stop_arb(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
struct adf_anti_rb_hw_data *anti_rb = GET_ANTI_RB_DATA(accel_dev);
|
||||
|
||||
if (!anti_rb->sysfs_added)
|
||||
return;
|
||||
|
||||
device_remove_group(&GET_DEV(accel_dev), &qat_svn_group);
|
||||
|
||||
anti_rb->sysfs_added = false;
|
||||
anti_rb->svncheck_retry = 0;
|
||||
}
|
||||
11
drivers/crypto/intel/qat/qat_common/adf_sysfs_anti_rb.h
Normal file
11
drivers/crypto/intel/qat/qat_common/adf_sysfs_anti_rb.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright(c) 2026 Intel Corporation */
|
||||
#ifndef ADF_SYSFS_ANTI_RB_H_
|
||||
#define ADF_SYSFS_ANTI_RB_H_
|
||||
|
||||
struct adf_accel_dev;
|
||||
|
||||
void adf_sysfs_start_arb(struct adf_accel_dev *accel_dev);
|
||||
void adf_sysfs_stop_arb(struct adf_accel_dev *accel_dev);
|
||||
|
||||
#endif /* ADF_SYSFS_ANTI_RB_H_ */
|
||||
@@ -31,11 +31,15 @@ enum icp_qat_fw_init_admin_cmd_id {
|
||||
ICP_QAT_FW_RL_REMOVE = 136,
|
||||
ICP_QAT_FW_TL_START = 137,
|
||||
ICP_QAT_FW_TL_STOP = 138,
|
||||
ICP_QAT_FW_SVN_READ = 146,
|
||||
ICP_QAT_FW_SVN_COMMIT = 147,
|
||||
};
|
||||
|
||||
enum icp_qat_fw_init_admin_resp_status {
|
||||
ICP_QAT_FW_INIT_RESP_STATUS_SUCCESS = 0,
|
||||
ICP_QAT_FW_INIT_RESP_STATUS_FAIL
|
||||
ICP_QAT_FW_INIT_RESP_STATUS_FAIL = 1,
|
||||
ICP_QAT_FW_INIT_RESP_STATUS_RETRY = 2,
|
||||
ICP_QAT_FW_INIT_RESP_STATUS_UNSUPPORTED = 4,
|
||||
};
|
||||
|
||||
struct icp_qat_fw_init_admin_tl_rp_indexes {
|
||||
@@ -159,6 +163,15 @@ struct icp_qat_fw_init_admin_resp {
|
||||
};
|
||||
struct icp_qat_fw_init_admin_slice_cnt slices;
|
||||
__u16 fw_capabilities;
|
||||
struct {
|
||||
__u8 enforced_min_svn;
|
||||
__u8 permanent_min_svn;
|
||||
__u8 active_svn;
|
||||
__u8 resrvd9;
|
||||
__u16 svn_status;
|
||||
__u16 resrvd10;
|
||||
__u64 resrvd11;
|
||||
};
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/wordpart.h>
|
||||
#include "adf_accel_devices.h"
|
||||
#include "adf_anti_rb.h"
|
||||
#include "adf_common_drv.h"
|
||||
#include "icp_qat_uclo.h"
|
||||
#include "icp_qat_hal.h"
|
||||
@@ -1230,10 +1231,11 @@ static int qat_uclo_map_suof(struct icp_qat_fw_loader_handle *handle,
|
||||
static int qat_uclo_auth_fw(struct icp_qat_fw_loader_handle *handle,
|
||||
struct icp_qat_fw_auth_desc *desc)
|
||||
{
|
||||
u32 fcu_sts, retry = 0;
|
||||
unsigned int retries = FW_AUTH_MAX_RETRY;
|
||||
u32 fcu_ctl_csr, fcu_sts_csr;
|
||||
u32 fcu_dram_hi_csr, fcu_dram_lo_csr;
|
||||
u64 bus_addr;
|
||||
u32 fcu_sts;
|
||||
|
||||
bus_addr = ADD_ADDR(desc->css_hdr_high, desc->css_hdr_low)
|
||||
- sizeof(struct icp_qat_auth_chunk);
|
||||
@@ -1248,17 +1250,32 @@ static int qat_uclo_auth_fw(struct icp_qat_fw_loader_handle *handle,
|
||||
SET_CAP_CSR(handle, fcu_ctl_csr, FCU_CTRL_CMD_AUTH);
|
||||
|
||||
do {
|
||||
int arb_ret;
|
||||
|
||||
msleep(FW_AUTH_WAIT_PERIOD);
|
||||
fcu_sts = GET_CAP_CSR(handle, fcu_sts_csr);
|
||||
|
||||
arb_ret = adf_anti_rb_check(handle->pci_dev);
|
||||
if (arb_ret == -EAGAIN) {
|
||||
if ((fcu_sts & FCU_AUTH_STS_MASK) == FCU_STS_VERI_FAIL) {
|
||||
SET_CAP_CSR(handle, fcu_ctl_csr, FCU_CTRL_CMD_AUTH);
|
||||
continue;
|
||||
}
|
||||
} else if (arb_ret) {
|
||||
goto auth_fail;
|
||||
}
|
||||
|
||||
if ((fcu_sts & FCU_AUTH_STS_MASK) == FCU_STS_VERI_FAIL)
|
||||
goto auth_fail;
|
||||
|
||||
if (((fcu_sts >> FCU_STS_AUTHFWLD_POS) & 0x1))
|
||||
if ((fcu_sts & FCU_AUTH_STS_MASK) == FCU_STS_VERI_DONE)
|
||||
return 0;
|
||||
} while (retry++ < FW_AUTH_MAX_RETRY);
|
||||
} while (--retries);
|
||||
|
||||
auth_fail:
|
||||
pr_err("authentication error (FCU_STATUS = 0x%x),retry = %d\n",
|
||||
fcu_sts & FCU_AUTH_STS_MASK, retry);
|
||||
pr_err("authentication error (FCU_STATUS = 0x%x)\n", fcu_sts & FCU_AUTH_STS_MASK);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user