* [PATCH 1/2] crypto: qat - remove unused character device and IOCTLs
From: Giovanni Cabiddu @ 2026-05-08 9:18 UTC (permalink / raw)
To: herbert
Cc: linux-crypto, qat-linux, wangzhi, byu, w15303746062, vdronov,
Giovanni Cabiddu, stable, Ahsan Atta
In-Reply-To: <20260508091912.206913-1-giovanni.cabiddu@intel.com>
The QAT driver exposes a character device (qat_adf_ctl) with IOCTLs
for device configuration, start, stop, status query and enumeration.
These IOCTLs are not part of any public uAPI header and have no known
in-tree or out-of-tree users. Device lifecycle is already managed via
sysfs.
The ioctl interface also increases the attack surface and is the
subject of a number of bug reports.
Remove the character device, the IOCTL definitions, and the related
data structures (adf_dev_status_info, adf_user_cfg_key_val,
adf_user_cfg_section, adf_user_cfg_ctl_data). Drop the now-unused
adf_cfg_user.h header and strip adf_ctl_drv.c down to the minimal
module_init/module_exit hooks for workqueue, AER, and crypto/compression
algorithm registration.
Additionally, drop the entry associated to QAT IOCTLs in
ioctl-number.rst.
Cc: stable@vger.kernel.org
Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
Reported-by: Zhi Wang <wangzhi@stu.xidian.edu.cn>
Reported-by: Bin Yu <byu@xidian.edu.cn>
Reported-by: MingYu Wang <w15303746062@163.com>
Closes: https://lore.kernel.org/all/61d6d499.ab89.19b9b7f3186.Coremail.wangzhi_xd@stu.xidian.edu.cn/
Link: https://lore.kernel.org/all/20260508034841.256794-1-w15303746062@163.com/
Link: https://lore.kernel.org/all/20260508023542.256299-1-w15303746062@163.com/
Link: https://lore.kernel.org/all/20260504025120.98242-1-w15303746062@163.com/
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
---
.../userspace-api/ioctl/ioctl-number.rst | 1 -
.../intel/qat/qat_common/adf_cfg_common.h | 27 --
.../intel/qat/qat_common/adf_cfg_user.h | 38 --
.../crypto/intel/qat/qat_common/adf_ctl_drv.c | 404 +-----------------
4 files changed, 1 insertion(+), 469 deletions(-)
delete mode 100644 drivers/crypto/intel/qat/qat_common/adf_cfg_user.h
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 331223761fff..29a08bc059dd 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -229,7 +229,6 @@ Code Seq# Include File Comments
<mailto:gregkh@linuxfoundation.org>
'a' all linux/atm*.h, linux/sonet.h ATM on linux
<http://lrcwww.epfl.ch/>
-'a' 00-0F drivers/crypto/qat/qat_common/adf_cfg_common.h conflict! qat driver
'b' 00-FF conflict! bit3 vme host bridge
<mailto:natalia@nikhefk.nikhef.nl>
'b' 00-0F linux/dma-buf.h conflict!
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
index 81e9e9d7eccd..88afca32fbe8 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_common.h
@@ -4,7 +4,6 @@
#define ADF_CFG_COMMON_H_
#include <linux/types.h>
-#include <linux/ioctl.h>
#define ADF_CFG_MAX_STR_LEN 64
#define ADF_CFG_MAX_KEY_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
@@ -15,7 +14,6 @@
#define ADF_CFG_ALL_DEVICES 0xFE
#define ADF_CFG_NO_DEVICE 0xFF
#define ADF_CFG_AFFINITY_WHATEVER 0xFF
-#define MAX_DEVICE_NAME_SIZE 32
#define ADF_MAX_DEVICES (32 * 32)
#define ADF_DEVS_ARRAY_SIZE BITS_TO_LONGS(ADF_MAX_DEVICES)
@@ -51,29 +49,4 @@ enum adf_device_type {
DEV_420XX,
DEV_6XXX,
};
-
-struct adf_dev_status_info {
- enum adf_device_type type;
- __u32 accel_id;
- __u32 instance_id;
- __u8 num_ae;
- __u8 num_accel;
- __u8 num_logical_accel;
- __u8 banks_per_accel;
- __u8 state;
- __u8 bus;
- __u8 dev;
- __u8 fun;
- char name[MAX_DEVICE_NAME_SIZE];
-};
-
-#define ADF_CTL_IOC_MAGIC 'a'
-#define IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS _IOW(ADF_CTL_IOC_MAGIC, 0, \
- struct adf_user_cfg_ctl_data)
-#define IOCTL_STOP_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 1, \
- struct adf_user_cfg_ctl_data)
-#define IOCTL_START_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 2, \
- struct adf_user_cfg_ctl_data)
-#define IOCTL_STATUS_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 3, __u32)
-#define IOCTL_GET_NUM_DEVICES _IOW(ADF_CTL_IOC_MAGIC, 4, __s32)
#endif
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_user.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_user.h
deleted file mode 100644
index 421f4fb8b4dd..000000000000
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_user.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
-/* Copyright(c) 2014 - 2020 Intel Corporation */
-#ifndef ADF_CFG_USER_H_
-#define ADF_CFG_USER_H_
-
-#include "adf_cfg_common.h"
-#include "adf_cfg_strings.h"
-
-struct adf_user_cfg_key_val {
- char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
- char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
- union {
- struct adf_user_cfg_key_val *next;
- __u64 padding3;
- };
- enum adf_cfg_val_type type;
-} __packed;
-
-struct adf_user_cfg_section {
- char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
- union {
- struct adf_user_cfg_key_val *params;
- __u64 padding1;
- };
- union {
- struct adf_user_cfg_section *next;
- __u64 padding3;
- };
-} __packed;
-
-struct adf_user_cfg_ctl_data {
- union {
- struct adf_user_cfg_section *config_section;
- __u64 padding;
- };
- __u8 device_id;
-} __packed;
-#endif
diff --git a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
index c2e6f0cb7480..f01f2946de6e 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
@@ -2,410 +2,13 @@
/* Copyright(c) 2014 - 2020 Intel Corporation */
#include <crypto/algapi.h>
+#include <linux/errno.h>
#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/cdev.h>
-#include <linux/uaccess.h>
-#include "adf_accel_devices.h"
#include "adf_common_drv.h"
-#include "adf_cfg.h"
-#include "adf_cfg_common.h"
-#include "adf_cfg_user.h"
-
-#define ADF_CFG_MAX_SECTION 512
-#define ADF_CFG_MAX_KEY_VAL 256
-
-#define DEVICE_NAME "qat_adf_ctl"
-
-static DEFINE_MUTEX(adf_ctl_lock);
-static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
-
-static const struct file_operations adf_ctl_ops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = adf_ctl_ioctl,
- .compat_ioctl = compat_ptr_ioctl,
-};
-
-static const struct class adf_ctl_class = {
- .name = DEVICE_NAME,
-};
-
-struct adf_ctl_drv_info {
- unsigned int major;
- struct cdev drv_cdev;
-};
-
-static struct adf_ctl_drv_info adf_ctl_drv;
-
-static void adf_chr_drv_destroy(void)
-{
- device_destroy(&adf_ctl_class, MKDEV(adf_ctl_drv.major, 0));
- cdev_del(&adf_ctl_drv.drv_cdev);
- class_unregister(&adf_ctl_class);
- unregister_chrdev_region(MKDEV(adf_ctl_drv.major, 0), 1);
-}
-
-static int adf_chr_drv_create(void)
-{
- dev_t dev_id;
- struct device *drv_device;
- int ret;
-
- if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
- pr_err("QAT: unable to allocate chrdev region\n");
- return -EFAULT;
- }
-
- ret = class_register(&adf_ctl_class);
- if (ret)
- goto err_chrdev_unreg;
-
- adf_ctl_drv.major = MAJOR(dev_id);
- cdev_init(&adf_ctl_drv.drv_cdev, &adf_ctl_ops);
- if (cdev_add(&adf_ctl_drv.drv_cdev, dev_id, 1)) {
- pr_err("QAT: cdev add failed\n");
- goto err_class_destr;
- }
-
- drv_device = device_create(&adf_ctl_class, NULL,
- MKDEV(adf_ctl_drv.major, 0),
- NULL, DEVICE_NAME);
- if (IS_ERR(drv_device)) {
- pr_err("QAT: failed to create device\n");
- goto err_cdev_del;
- }
- return 0;
-err_cdev_del:
- cdev_del(&adf_ctl_drv.drv_cdev);
-err_class_destr:
- class_unregister(&adf_ctl_class);
-err_chrdev_unreg:
- unregister_chrdev_region(dev_id, 1);
- return -EFAULT;
-}
-
-static struct adf_user_cfg_ctl_data *adf_ctl_alloc_resources(unsigned long arg)
-{
- struct adf_user_cfg_ctl_data *cfg_data;
-
- cfg_data = memdup_user((void __user *)arg, sizeof(*cfg_data));
- if (IS_ERR(cfg_data))
- pr_err("QAT: failed to copy from user cfg_data.\n");
- return cfg_data;
-}
-
-static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
- const char *section,
- const struct adf_user_cfg_key_val *key_val)
-{
- if (key_val->type == ADF_HEX) {
- long *ptr = (long *)key_val->val;
- long val = *ptr;
-
- if (adf_cfg_add_key_value_param(accel_dev, section,
- key_val->key, (void *)val,
- key_val->type)) {
- dev_err(&GET_DEV(accel_dev),
- "failed to add hex keyvalue.\n");
- return -EFAULT;
- }
- } else {
- if (adf_cfg_add_key_value_param(accel_dev, section,
- key_val->key, key_val->val,
- key_val->type)) {
- dev_err(&GET_DEV(accel_dev),
- "failed to add keyvalue.\n");
- return -EFAULT;
- }
- }
- return 0;
-}
-
-static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
- struct adf_user_cfg_ctl_data *ctl_data)
-{
- struct adf_user_cfg_key_val key_val;
- struct adf_user_cfg_key_val *params_head;
- struct adf_user_cfg_section section, *section_head;
- int i, j;
-
- section_head = ctl_data->config_section;
-
- for (i = 0; section_head && i < ADF_CFG_MAX_SECTION; i++) {
- if (copy_from_user(§ion, (void __user *)section_head,
- sizeof(*section_head))) {
- dev_err(&GET_DEV(accel_dev),
- "failed to copy section info\n");
- goto out_err;
- }
-
- if (adf_cfg_section_add(accel_dev, section.name)) {
- dev_err(&GET_DEV(accel_dev),
- "failed to add section.\n");
- goto out_err;
- }
-
- params_head = section.params;
-
- for (j = 0; params_head && j < ADF_CFG_MAX_KEY_VAL; j++) {
- if (copy_from_user(&key_val, (void __user *)params_head,
- sizeof(key_val))) {
- dev_err(&GET_DEV(accel_dev),
- "Failed to copy keyvalue.\n");
- goto out_err;
- }
- if (adf_add_key_value_data(accel_dev, section.name,
- &key_val)) {
- goto out_err;
- }
- params_head = key_val.next;
- }
- section_head = section.next;
- }
- return 0;
-out_err:
- adf_cfg_del_all(accel_dev);
- return -EFAULT;
-}
-
-static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- struct adf_user_cfg_ctl_data *ctl_data;
- struct adf_accel_dev *accel_dev;
- int ret = 0;
-
- ctl_data = adf_ctl_alloc_resources(arg);
- if (IS_ERR(ctl_data))
- return PTR_ERR(ctl_data);
-
- accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
- if (!accel_dev) {
- ret = -EFAULT;
- goto out;
- }
-
- if (adf_dev_started(accel_dev)) {
- ret = -EFAULT;
- goto out;
- }
-
- if (adf_copy_key_value_data(accel_dev, ctl_data)) {
- ret = -EFAULT;
- goto out;
- }
- set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
-out:
- kfree(ctl_data);
- return ret;
-}
-
-static int adf_ctl_is_device_in_use(int id)
-{
- struct adf_accel_dev *dev;
-
- list_for_each_entry(dev, adf_devmgr_get_head(), list) {
- if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
- if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
- dev_info(&GET_DEV(dev),
- "device qat_dev%d is busy\n",
- dev->accel_id);
- return -EBUSY;
- }
- }
- }
- return 0;
-}
-
-static void adf_ctl_stop_devices(u32 id)
-{
- struct adf_accel_dev *accel_dev;
-
- list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
- if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
- if (!adf_dev_started(accel_dev))
- continue;
-
- /* First stop all VFs */
- if (!accel_dev->is_vf)
- continue;
-
- adf_dev_down(accel_dev);
- }
- }
-
- list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
- if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
- if (!adf_dev_started(accel_dev))
- continue;
-
- adf_dev_down(accel_dev);
- }
- }
-}
-
-static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- int ret;
- struct adf_user_cfg_ctl_data *ctl_data;
-
- ctl_data = adf_ctl_alloc_resources(arg);
- if (IS_ERR(ctl_data))
- return PTR_ERR(ctl_data);
-
- if (adf_devmgr_verify_id(ctl_data->device_id)) {
- pr_err("QAT: Device %d not found\n", ctl_data->device_id);
- ret = -ENODEV;
- goto out;
- }
-
- ret = adf_ctl_is_device_in_use(ctl_data->device_id);
- if (ret)
- goto out;
-
- if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
- pr_info("QAT: Stopping all acceleration devices.\n");
- else
- pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
- ctl_data->device_id);
-
- adf_ctl_stop_devices(ctl_data->device_id);
-
-out:
- kfree(ctl_data);
- return ret;
-}
-
-static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- int ret;
- struct adf_user_cfg_ctl_data *ctl_data;
- struct adf_accel_dev *accel_dev;
-
- ctl_data = adf_ctl_alloc_resources(arg);
- if (IS_ERR(ctl_data))
- return PTR_ERR(ctl_data);
-
- ret = -ENODEV;
- accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
- if (!accel_dev)
- goto out;
-
- dev_info(&GET_DEV(accel_dev),
- "Starting acceleration device qat_dev%d.\n",
- ctl_data->device_id);
-
- ret = adf_dev_up(accel_dev, false);
-
- if (ret) {
- dev_err(&GET_DEV(accel_dev), "Failed to start qat_dev%d\n",
- ctl_data->device_id);
- adf_dev_down(accel_dev);
- }
-out:
- kfree(ctl_data);
- return ret;
-}
-
-static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- u32 num_devices = 0;
-
- adf_devmgr_get_num_dev(&num_devices);
- if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
- return -EFAULT;
-
- return 0;
-}
-
-static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
- unsigned long arg)
-{
- struct adf_hw_device_data *hw_data;
- struct adf_dev_status_info dev_info;
- struct adf_accel_dev *accel_dev;
-
- if (copy_from_user(&dev_info, (void __user *)arg,
- sizeof(struct adf_dev_status_info))) {
- pr_err("QAT: failed to copy from user.\n");
- return -EFAULT;
- }
-
- accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
- if (!accel_dev)
- return -ENODEV;
-
- hw_data = accel_dev->hw_device;
- dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
- dev_info.num_ae = hw_data->get_num_aes(hw_data);
- dev_info.num_accel = hw_data->get_num_accels(hw_data);
- dev_info.num_logical_accel = hw_data->num_logical_accel;
- dev_info.banks_per_accel = hw_data->num_banks
- / hw_data->num_logical_accel;
- strscpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
- dev_info.instance_id = hw_data->instance_id;
- dev_info.type = hw_data->dev_class->type;
- dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
- dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
- dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
-
- if (copy_to_user((void __user *)arg, &dev_info,
- sizeof(struct adf_dev_status_info))) {
- dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
- return -EFAULT;
- }
- return 0;
-}
-
-static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- if (mutex_lock_interruptible(&adf_ctl_lock))
- return -EFAULT;
-
- switch (cmd) {
- case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
- ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
- break;
-
- case IOCTL_STOP_ACCEL_DEV:
- ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
- break;
-
- case IOCTL_START_ACCEL_DEV:
- ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
- break;
-
- case IOCTL_GET_NUM_DEVICES:
- ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
- break;
-
- case IOCTL_STATUS_ACCEL_DEV:
- ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
- break;
- default:
- pr_err_ratelimited("QAT: Invalid ioctl %d\n", cmd);
- ret = -EFAULT;
- break;
- }
- mutex_unlock(&adf_ctl_lock);
- return ret;
-}
static int __init adf_register_ctl_device_driver(void)
{
- if (adf_chr_drv_create())
- goto err_chr_dev;
-
if (adf_init_misc_wq())
goto err_misc_wq;
@@ -437,15 +40,11 @@ static int __init adf_register_ctl_device_driver(void)
err_aer:
adf_exit_misc_wq();
err_misc_wq:
- adf_chr_drv_destroy();
-err_chr_dev:
- mutex_destroy(&adf_ctl_lock);
return -EFAULT;
}
static void __exit adf_unregister_ctl_device_driver(void)
{
- adf_chr_drv_destroy();
adf_exit_misc_wq();
adf_exit_aer();
adf_exit_vf_wq();
@@ -453,7 +52,6 @@ static void __exit adf_unregister_ctl_device_driver(void)
qat_crypto_unregister();
qat_compression_unregister();
adf_clean_vf_map(false);
- mutex_destroy(&adf_ctl_lock);
}
module_init(adf_register_ctl_device_driver);
--
2.54.0
^ permalink raw reply related
* [PATCH 0/2] crypto: qat - remove unused ioctl interface
From: Giovanni Cabiddu @ 2026-05-08 9:18 UTC (permalink / raw)
To: herbert
Cc: linux-crypto, qat-linux, wangzhi, byu, w15303746062, vdronov,
Giovanni Cabiddu
The QAT driver exposes a character device (qat_adf_ctl) with IOCTLs for
device configuration, start, stop, status query and enumeration. These
IOCTLs are not part of any public uAPI header and have no known in-tree
or out-of-tree users.
This ioctl interface increases the attack surface and is the subject of a
number of bug reports. Remove it entirely.
Patch 1 removes the character device, the IOCTL definitions, the related
data structures and headers. It strips adf_ctl_drv.c down to the
minimal module_init/module_exit hooks. This is marked for stable.
Patch 2 renames the now-minimal adf_ctl_drv.c to adf_module.c and
adjusts function names to match the new file name. This is not marked
for stable as it is a pure rename.
Giovanni Cabiddu (2):
crypto: qat - remove unused character device and IOCTLs
crypto: qat - rename adf_ctl_drv.c to adf_module.c
.../userspace-api/ioctl/ioctl-number.rst | 1 -
drivers/crypto/intel/qat/qat_common/Makefile | 2 +-
.../intel/qat/qat_common/adf_cfg_common.h | 27 -
.../intel/qat/qat_common/adf_cfg_user.h | 38 --
.../crypto/intel/qat/qat_common/adf_ctl_drv.c | 466 ------------------
.../crypto/intel/qat/qat_common/adf_module.c | 64 +++
6 files changed, 65 insertions(+), 533 deletions(-)
delete mode 100644 drivers/crypto/intel/qat/qat_common/adf_cfg_user.h
delete mode 100644 drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
create mode 100644 drivers/crypto/intel/qat/qat_common/adf_module.c
base-commit: c9e14a7f54e4552968e3103fa871b1380ca23208
--
2.54.0
^ permalink raw reply
* [PATCH] crypto: safexcel - Fix potential memory leak in safexcel_pci_probe()
From: Abdun Nihaal @ 2026-05-08 9:03 UTC (permalink / raw)
To: atenart
Cc: Abdun Nihaal, herbert, davem, linux-crypto, linux-kernel,
pvanleeuwen
The memory allocated for priv in safexcel_pci_probe() is not freed in the
error paths, as well as in the PCI remove function. Fix this by using
device managed allocation.
Fixes: 625f269a5a7a ("crypto: inside-secure - add support for PCI based FPGA development board")
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
---
Compile tested only. Issue found using static analysis.
drivers/crypto/inside-secure/safexcel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index fb4936e7afa2..2bd8641a07b3 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -1893,7 +1893,7 @@ static int safexcel_pci_probe(struct pci_dev *pdev,
ent->vendor, ent->device, ent->subvendor,
ent->subdevice, ent->driver_data);
- priv = kzalloc_obj(*priv);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
--
2.43.0
^ permalink raw reply related
* [PATCH] crypto: amlogic - avoid double cleanup in meson_crypto_probe()
From: Dawei Feng @ 2026-05-08 4:24 UTC (permalink / raw)
To: clabbe
Cc: herbert, davem, linux-crypto, linux-amlogic, linux-kernel,
jianhao.xu, Dawei Feng, stable, Zilin Guan
When meson_allocate_chanlist() fails after a partial allocation, it already
unwinds the allocated chanlist state through its local error path.
meson_crypto_probe() then jump to error_flow and calls
meson_free_chanlist() again, causing the same per-flow resources to be torn
down twice. In the reproduced failure path, the second teardown
re-entered crypto_engine_exit() on an already destroyed worker and KASAN
reported a slab-use-after-free in kthread_destroy_worker().
Prevent double-free by handling partial allocation failures locally within
meson_allocate_chanlist() and skipping the outer cleanup path.
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available.
The bug was reproduced in a QEMU x86_64 guest booted with KASAN on v7.1,
using the reproducer under tools/testing/meson_crypto_probe. The reproducer
forces the second dma_alloc_attrs() call in the gxl-crypto probe path to
return NULL, making meson_allocate_chanlist() fail after partial
initialization. On the unpatched kernel this reliably triggered a
slab-use-after-free. With this fix applied, the same reproducer no longer
emits any KASAN report and the probe fails cleanly with -ENOMEM.
==================================================================
BUG: KASAN: slab-use-after-free in kthread_destroy_worker+0xb2/0xd0
Read of size 8 at addr ff1100010c057a68 by task insmod/265
CPU: 1 UID: 0 PID: 265 Comm: insmod Tainted: G O 7.1.0-rc2-00376-g810af9adc907-dirty #10 PREEMPT(lazy)
Tainted: [O]=OOT_MODULE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x68/0xa0
print_report+0xcb/0x5e0
? __virt_addr_valid+0x21d/0x3f0
? kthread_destroy_worker+0xb2/0xd0
? kthread_destroy_worker+0xb2/0xd0
kasan_report+0xca/0x100
? kthread_destroy_worker+0xb2/0xd0
kthread_destroy_worker+0xb2/0xd0
meson_crypto_probe+0x4d0/0xc10 [amlogic_gxl_crypto]
platform_probe+0x99/0x140
really_probe+0x1c6/0x6a0
? __pfx___device_attach_driver+0x10/0x10
__driver_probe_device+0x248/0x310
? acpi_driver_match_device+0xb0/0x100
driver_probe_device+0x48/0x210
? __pfx___device_attach_driver+0x10/0x10
__device_attach_driver+0x160/0x320
bus_for_each_drv+0x104/0x190
? __pfx_bus_for_each_drv+0x10/0x10
? _raw_spin_unlock_irqrestore+0x2c/0x50
__device_attach+0x19d/0x3b0
? __pfx___device_attach+0x10/0x10
? do_raw_spin_unlock+0x53/0x220
device_initial_probe+0x78/0xa0
bus_probe_device+0x5b/0x130
device_add+0xcfd/0x1430
? __pfx_device_add+0x10/0x10
? insert_resource+0x34/0x50
? lock_release+0xc9/0x290
platform_device_add+0x24e/0x590
? __pfx_meson_crypto_probe_repro_init+0x10/0x10 [meson_crypto_probe_repro]
meson_crypto_probe_repro_init+0x330/0xff0 [meson_crypto_probe_repro]
do_one_initcall+0xc0/0x450
? __pfx_do_one_initcall+0x10/0x10
? _raw_spin_unlock_irqrestore+0x2c/0x50
? __create_object+0x59/0x80
? kasan_unpoison+0x27/0x60
do_init_module+0x27b/0x7d0
? __pfx_do_init_module+0x10/0x10
? kasan_quarantine_put+0x84/0x1d0
? kfree+0x32c/0x510
? load_module+0x561e/0x5ff0
load_module+0x54fe/0x5ff0
? __pfx_load_module+0x10/0x10
? security_file_permission+0x20/0x40
? kernel_read_file+0x23d/0x6e0
? mmap_region+0x235/0x4a0
? __pfx_kernel_read_file+0x10/0x10
? __file_has_perm+0x2c0/0x3e0
init_module_from_file+0x158/0x180
? __pfx_init_module_from_file+0x10/0x10
? __lock_acquire+0x45a/0x1ba0
? idempotent_init_module+0x315/0x610
? lock_release+0xc9/0x290
? lockdep_init_map_type+0x4b/0x220
? do_raw_spin_unlock+0x53/0x220
idempotent_init_module+0x330/0x610
? __pfx_idempotent_init_module+0x10/0x10
? __pfx_cred_has_capability.isra.0+0x10/0x10
? ksys_mmap_pgoff+0x385/0x520
__x64_sys_finit_module+0xbe/0x120
do_syscall_64+0x115/0x690
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f7d6d31690d
Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d f3 b4 0f 00 f7 d8 >
RSP: 002b:00007fffc027ac68 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
RAX: ffffffffffffffda RBX: 000055f7b81967c0 RCX: 00007f7d6d31690d
RDX: 0000000000000000 RSI: 000055f79a0d6cd2 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000003 R11: 0000000000000246 R12: 000055f79a0d6cd2
R13: 000055f7b8196790 R14: 000055f79a0d5888 R15: 000055f7b81968e0
</TASK>
Fixes: 48fe583fe541 ("crypto: amlogic - Add crypto accelerator for amlogic GXL")
Cc: stable@vger.kernel.org
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
---
drivers/crypto/amlogic/amlogic-gxl-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 1c18a5b8470e..6cb33949915f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -291,8 +291,8 @@ static int meson_crypto_probe(struct platform_device *pdev)
return 0;
error_alg:
meson_unregister_algs(mc);
-error_flow:
meson_free_chanlist(mc, MAXFLOW - 1);
+error_flow:
clk_disable_unprepare(mc->busclk);
return err;
}
--
2.34.1
^ permalink raw reply related
* [PATCH] crypto: qat - remove noisy error prints in ioctl paths to prevent DoS
From: w15303746062 @ 2026-05-08 3:48 UTC (permalink / raw)
To: giovanni.cabiddu, herbert, davem
Cc: thorsten.blum, qat-linux, linux-crypto, linux-kernel, Mingyu Wang
From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
A Local Denial of Service (DoS) vulnerability was observed in the QAT
driver. A malicious user or a fuzzing tool can repeatedly issue various
QAT ioctls with invalid user-space pointers or unknown commands.
Currently, failures in memdup_user() and copy_from_user() trigger
unconditional pr_err() and dev_err() messages. Similarly, invalid
ioctl commands trigger an unconditional print. In environments
with slow serial consoles (e.g., console=ttyS0), this creates a massive
printk storm. This forces the CPU into a lengthy spin with interrupts
disabled, leading to RCU stalls, multi-core soft lockups, and ultimately
triggering the system watchdog panic.
It is a well-known kernel anti-pattern to allow user-space to spam the
kernel log buffer simply by passing invalid arguments to an ioctl.
Fix this by removing these useless error prints from the user-copy
failure paths and the default ioctl switch case. The kernel correctly
returns -EFAULT or -ENOTTY, which is entirely sufficient for user-space
to understand the failure, without exhausting kernel logging resources.
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
---
drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
index c2e6f0cb7480..546ef1ac82dc 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
@@ -94,8 +94,6 @@ static struct adf_user_cfg_ctl_data *adf_ctl_alloc_resources(unsigned long arg)
struct adf_user_cfg_ctl_data *cfg_data;
cfg_data = memdup_user((void __user *)arg, sizeof(*cfg_data));
- if (IS_ERR(cfg_data))
- pr_err("QAT: failed to copy from user cfg_data.\n");
return cfg_data;
}
@@ -139,8 +137,6 @@ static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
for (i = 0; section_head && i < ADF_CFG_MAX_SECTION; i++) {
if (copy_from_user(§ion, (void __user *)section_head,
sizeof(*section_head))) {
- dev_err(&GET_DEV(accel_dev),
- "failed to copy section info\n");
goto out_err;
}
@@ -155,8 +151,6 @@ static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
for (j = 0; params_head && j < ADF_CFG_MAX_KEY_VAL; j++) {
if (copy_from_user(&key_val, (void __user *)params_head,
sizeof(key_val))) {
- dev_err(&GET_DEV(accel_dev),
- "Failed to copy keyvalue.\n");
goto out_err;
}
if (adf_add_key_value_data(accel_dev, section.name,
@@ -335,7 +329,6 @@ static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
if (copy_from_user(&dev_info, (void __user *)arg,
sizeof(struct adf_dev_status_info))) {
- pr_err("QAT: failed to copy from user.\n");
return -EFAULT;
}
@@ -359,7 +352,6 @@ static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
if (copy_to_user((void __user *)arg, &dev_info,
sizeof(struct adf_dev_status_info))) {
- dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
return -EFAULT;
}
return 0;
@@ -393,8 +385,7 @@ static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
break;
default:
- pr_err_ratelimited("QAT: Invalid ioctl %d\n", cmd);
- ret = -EFAULT;
+ ret = -ENOTTY; /* ENOTTY is the standard POSIX error for invalid ioctls */
break;
}
mutex_unlock(&adf_ctl_lock);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] crypto: acomp - fix dst-folio branch setting src instead of dst in acomp_virt_to_sg
From: Herbert Xu @ 2026-05-08 2:51 UTC (permalink / raw)
To: Aaron Esau; +Cc: linux-crypto, davem, stable, linux-kernel
In-Reply-To: <CADucPGTSNG3m=v9HuyZ=qr_-Qycccc9jjKU5K7O3LrHdEXgRaA@mail.gmail.com>
On Thu, May 07, 2026 at 09:49:08PM -0500, Aaron Esau wrote:
>
> The patch was generated against v6.15-rc6 (82f2b0b97). The buggy line
> is at crypto/acompress.c:240 in that tag, and the index hash
> f7a3fbe54 matched (I just checked again).
>
> Could you double-check?
We're currently at v7.0 heading towards v7.1. The bug that you're
reporting does not exist in v7.0.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] crypto: acomp - fix dst-folio branch setting src instead of dst in acomp_virt_to_sg
From: Aaron Esau @ 2026-05-08 2:49 UTC (permalink / raw)
To: Herbert Xu; +Cc: linux-crypto, davem, stable, linux-kernel
In-Reply-To: <af1K4d8cxGOvlJxY@gondor.apana.org.au>
Hi Herbert,
The patch was generated against v6.15-rc6 (82f2b0b97). The buggy line
is at crypto/acompress.c:240 in that tag, and the index hash
f7a3fbe54 matched (I just checked again).
Could you double-check?
Thanks,
Aaron
^ permalink raw reply
* [PATCH] crypto: qat - fix Use-After-Free in adf_ctl_ioctl_dev_start()
From: w15303746062 @ 2026-05-08 2:35 UTC (permalink / raw)
To: giovanni.cabiddu, herbert, davem
Cc: thorsten.blum, kees, qat-linux, linux-crypto, linux-kernel,
Mingyu Wang
From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
A severe Use-After-Free (UAF) vulnerability, which KASAN detects as a
slab-out-of-bounds access, was identified in the QAT driver's ioctl path.
When handling commands like IOCTL_START_ACCEL_DEV, various functions
retrieve the acceleration device using adf_devmgr_get_dev_by_id().
Currently, this lookup function iterates over the accel_table under
the table_lock. However, once the target device is found, the lock is
dropped and a bare pointer is returned without bumping the device's
reference count.
This creates a critical race condition. If a concurrent thread removes
the device (e.g., via device stop operations or PCIe hotplug) by calling
adf_devmgr_rm_dev(), the device is removed from the list and its memory
is subsequently freed. When the original ioctl thread resumes and attempts
to acquire accel_dev->state_lock inside adf_dev_up(), it triggers a
KASAN panic.
Fix this by acquiring the reference count inside adf_devmgr_get_dev_by_id()
via adf_dev_get() while the table_lock is still held. If adf_dev_get()
fails (e.g., the module is unloading), we safely break the loop and treat
the device as not found. All callers of adf_devmgr_get_dev_by_id() are then
updated to properly release the reference using adf_dev_put() when done.
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
---
.../crypto/intel/qat/qat_common/adf_ctl_drv.c | 16 ++++++++++++++++
.../crypto/intel/qat/qat_common/adf_dev_mgr.c | 18 +++++++++++++++---
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
index c2e6f0cb7480..0519cc02e634 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c
@@ -201,6 +201,10 @@ static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
}
set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
out:
+ /* Release the reference acquired by adf_devmgr_get_dev_by_id() */
+ if (accel_dev)
+ adf_dev_put(accel_dev);
+
kfree(ctl_data);
return ret;
}
@@ -278,6 +282,10 @@ static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
adf_ctl_stop_devices(ctl_data->device_id);
out:
+ /* Release the reference acquired by adf_devmgr_get_dev_by_id() */
+ if (accel_dev)
+ adf_dev_put(accel_dev);
+
kfree(ctl_data);
return ret;
}
@@ -310,6 +318,10 @@ static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
adf_dev_down(accel_dev);
}
out:
+ /* Release the reference acquired by adf_devmgr_get_dev_by_id() */
+ if (accel_dev)
+ adf_dev_put(accel_dev);
+
kfree(ctl_data);
return ret;
}
@@ -360,8 +372,12 @@ static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
if (copy_to_user((void __user *)arg, &dev_info,
sizeof(struct adf_dev_status_info))) {
dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
+ adf_dev_put(accel_dev);
return -EFAULT;
}
+ /* Release the reference acquired by adf_devmgr_get_dev_by_id() */
+ adf_dev_put(accel_dev);
+
return 0;
}
diff --git a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c
index e050de16ab5d..5e9313d8bacf 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c
@@ -320,8 +320,14 @@ struct adf_accel_dev *adf_devmgr_get_dev_by_id(u32 id)
struct adf_accel_dev *ptr =
list_entry(itr, struct adf_accel_dev, list);
if (ptr->accel_id == id) {
- mutex_unlock(&table_lock);
- return ptr;
+ /* Increment refcount to prevent UAF during removal.
+ * If adf_dev_get() fails, the module is unloading.
+ */
+ if (adf_dev_get(ptr) == 0) {
+ mutex_unlock(&table_lock);
+ return ptr;
+ }
+ break;
}
}
unlock:
@@ -331,11 +337,17 @@ struct adf_accel_dev *adf_devmgr_get_dev_by_id(u32 id)
int adf_devmgr_verify_id(u32 id)
{
+ struct adf_accel_dev *accel_dev;
+
if (id == ADF_CFG_ALL_DEVICES)
return 0;
- if (adf_devmgr_get_dev_by_id(id))
+ accel_dev = adf_devmgr_get_dev_by_id(id);
+ if (accel_dev) {
+ /* Release the reference immediately as we only verify existence */
+ adf_dev_put(accel_dev);
return 0;
+ }
return -ENODEV;
}
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] crypto: acomp - fix dst-folio branch setting src instead of dst in acomp_virt_to_sg
From: Herbert Xu @ 2026-05-08 2:30 UTC (permalink / raw)
To: Aaron Esau; +Cc: linux-crypto, davem, stable, linux-kernel
In-Reply-To: <20260507233748.327004-1-aaron1esau@gmail.com>
On Thu, May 07, 2026 at 06:37:48PM -0500, Aaron Esau wrote:
>
> diff --git a/crypto/acompress.c b/crypto/acompress.c
> index f7a3fbe54..5a8b0cf3a 100644
> --- a/crypto/acompress.c
> +++ b/crypto/acompress.c
> @@ -237,7 +237,7 @@ static void acomp_virt_to_sg(struct acomp_req *req)
> sg_init_table(&state->dsg, 1);
> sg_set_page(&state->dsg, folio_page(folio, off / PAGE_SIZE),
> dlen, off % PAGE_SIZE);
> - acomp_request_set_src_sg(req, &state->dsg, dlen);
> + acomp_request_set_dst_sg(req, &state->dsg, dlen);
> }
> }
This patch doesn't apply against mainline. In fact the code
that you're referencing does not exist on mainline.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] talitos: use devm_platform_ioremap_resource()
From: Rosen Penev @ 2026-05-07 23:44 UTC (permalink / raw)
To: linux-crypto; +Cc: Herbert Xu, David S. Miller, open list
platform_get_resource and devm_ioremap effectively open codes this.
The return type of devm_platform_ioremap_resource() is also nice as it
has multiple errors that it can return.
Because it internally calls devm_request_mem_region(), reg values and
sizes cannot overlap. This was manually verified to be the case for all
talitos users.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/crypto/talitos.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bd4cc06ee13c..bdf7549fdf0a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3412,7 +3412,6 @@ static int talitos_probe(struct platform_device *ofdev)
unsigned int num_channels;
int i, err;
int stride;
- struct resource *res;
if (of_property_read_u32(np, "fsl,num-channels", &num_channels))
return -EINVAL;
@@ -3431,13 +3430,10 @@ static int talitos_probe(struct platform_device *ofdev)
spin_lock_init(&priv->reg_lock);
- res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENXIO;
- priv->reg = devm_ioremap(dev, res->start, resource_size(res));
- if (!priv->reg) {
+ priv->reg = devm_platform_ioremap_resource(ofdev, 0);
+ if (IS_ERR(priv->reg)) {
dev_err(dev, "failed to of_iomap\n");
- err = -ENOMEM;
+ err = PTR_ERR(priv->reg);
goto err_out;
}
--
2.54.0
^ permalink raw reply related
* [PATCH] crypto: acomp - fix dst-folio branch setting src instead of dst in acomp_virt_to_sg
From: Aaron Esau @ 2026-05-07 23:37 UTC (permalink / raw)
To: linux-crypto; +Cc: herbert, davem, stable, linux-kernel, Aaron Esau
In acomp_virt_to_sg(), the dst_isfolio branch calls
acomp_request_set_src_sg() instead of acomp_request_set_dst_sg(). This
overwrites req->src with the destination folio SG and leaves req->dst
holding a raw struct folio pointer (via the src/dst union). The
algorithm then reads from the wrong buffer and dereferences the stale
folio pointer as a scatterlist.
The bug is reachable from UBIFS decompression on systems with a hardware
compression accelerator (HiSilicon ZIP, Intel IAA, Intel QAT), where
crypto_alloc_acomp() selects the hardware driver over scompress.
Software scompress backends are unaffected because they set
CRYPTO_ALG_REQ_CHAIN and bypass acomp_virt_to_sg() entirely.
Fixes: 8a6771cda3f4 ("crypto: acomp - Add support for folios")
Cc: stable@vger.kernel.org
Signed-off-by: Aaron Esau <aaron1esau@gmail.com>
---
crypto/acompress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/acompress.c b/crypto/acompress.c
index f7a3fbe54..5a8b0cf3a 100644
--- a/crypto/acompress.c
+++ b/crypto/acompress.c
@@ -237,7 +237,7 @@ static void acomp_virt_to_sg(struct acomp_req *req)
sg_init_table(&state->dsg, 1);
sg_set_page(&state->dsg, folio_page(folio, off / PAGE_SIZE),
dlen, off % PAGE_SIZE);
- acomp_request_set_src_sg(req, &state->dsg, dlen);
+ acomp_request_set_dst_sg(req, &state->dsg, dlen);
}
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v7 00/10] Reintroduce Hornet LSM
From: Paul Moore @ 2026-05-07 22:22 UTC (permalink / raw)
To: Eric Biggers
Cc: Blaise Boscaccy, linux-crypto, Jonathan Corbet, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260507215841.GA440717@google.com>
On Thu, May 7, 2026 at 5:58 PM Eric Biggers <ebiggers@kernel.org> wrote:
> On Thu, May 07, 2026 at 04:57:35PM -0400, Paul Moore wrote:
> > On Thu, May 7, 2026 at 3:14 PM Blaise Boscaccy
> > <bboscaccy@linux.microsoft.com> wrote:
> > >
> > > This patch series introduces the next iteration of the Hornet LSM.
> > > Hornet’s goal is to provide a secure and extensible in-kernel
> > > signature verification mechanism for eBPF programs.
> > >
> > > Hornet addresses concerns from users who require strict audit trails and
> > > verification guarantees for eBPF programs, especially in
> > > security-sensitive environments. Many production systems need assurance
> > > that only authorized, unmodified eBPF programs are loaded into the
> > > kernel. Hornet provides this assurance through cryptographic signature
> > > verification.
> > >
> > > The currently accepted loader-plus-map signature verification scheme,
> > > mandated by Alexei and KP, is simple to implement and generally
> > > acceptable if users and administrators are satisfied with it. However,
> > > verifying both the loader and the maps offers additional benefits
> > > beyond verifying the loader alone:
> > >
> > > 1. Security and Audit Integrity
> > >
> > > A key advantage is that the LSM hook for authorizing BPF program loads
> > > can operate after signature verification. This ensures:
> > >
> > > * Access control decisions are based on verified signature status.
> > > * Accurate system state measurement and logging.
> > > * Log entries claiming a verified signature are truthful, avoiding
> > > misleading records where only the loader was verified while the actual
> > > BPF program verification occurs later without logging.
> > >
> > > 2. TOCTOU Attack Prevention
> > >
> > > The current map hash implementation may be vulnerable to a TOCTOU
> > > attack because it allows unfrozen maps to cache a previously
> > > calculated hash. The accepted “trusted loader” scheme cannot detect
> > > this and may permit loading altered maps.
> > >
> > > 3. Supply Chain Integrity
> > >
> > > Verify that eBPF programs and their associated map data have not been
> > > modified since they were built and signed, in the kernel proper, may
> > > aid in protecting against supply chain attacks.
> > >
> > > This approach addresses concerns from users who require strict audit
> > > trails and verification guarantees, especially in security-sensitive
> > > environments. Map hashes for extended verification are passed via the
> > > existing PKCS#7 UAPI and verified by the crypto subsystem. Hornet then
> > > calculates the program’s verification state. Hornet itself does not
> > > enforce a policy on whether unsigned or partially signed programs
> > > should be rejected. It delegates that decision to downstream LSMs
> > > hook, making it a composable building block in a larger security
> > > architecture.
> >
> > [NOTE: trimmed changelog for brevity]
> >
> > > Blaise Boscaccy (6):
> > > lsm: security: Add additional enum values for bpf integrity checks
> > > security: Hornet LSM
> > > hornet: Introduce gen_sig
> > > hornet: Add a light skeleton data extractor scripts
> > > selftests/hornet: Add a selftest for the Hornet LSM
> > > ipe: Add BPF program load policy enforcement via Hornet integration
> > >
> > > James Bottomley (3):
> > > crypto: pkcs7: add flag for validated trust on a signed info block
> > > crypto: pkcs7: add ability to extract signed attributes by OID
> > > crypto: pkcs7: add tests for pkcs7_get_authattr
> > >
> > > Paul Moore (1):
> > > lsm: framework for BPF integrity verification
> > >
> > > Documentation/admin-guide/LSM/Hornet.rst | 323 +++++++++++++++
> > > Documentation/admin-guide/LSM/index.rst | 1 +
> > > Documentation/admin-guide/LSM/ipe.rst | 162 +++++++-
> > > Documentation/security/ipe.rst | 68 ++++
> > > MAINTAINERS | 9 +
> > > certs/system_keyring.c | 1 +
> > > crypto/asymmetric_keys/Makefile | 4 +-
> > > crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 +
> > > crypto/asymmetric_keys/pkcs7_key_type.c | 44 +-
> > > crypto/asymmetric_keys/pkcs7_parser.c | 81 ++++
> > > crypto/asymmetric_keys/pkcs7_parser.h | 1 +
> > > crypto/asymmetric_keys/pkcs7_trust.c | 1 +
> > > include/crypto/pkcs7.h | 4 +
> > > include/linux/lsm_hook_defs.h | 5 +
> > > include/linux/oid_registry.h | 3 +
> > > include/linux/security.h | 28 ++
> > > include/uapi/linux/lsm.h | 1 +
> > > scripts/Makefile | 1 +
> > > scripts/hornet/Makefile | 5 +
> > > scripts/hornet/extract-insn.sh | 27 ++
> > > scripts/hornet/extract-map.sh | 27 ++
> > > scripts/hornet/extract-skel.sh | 27 ++
> > > scripts/hornet/gen_sig.c | 401 +++++++++++++++++++
> > > scripts/hornet/write-sig.sh | 27 ++
> > > security/Kconfig | 3 +-
> > > security/Makefile | 1 +
> > > security/hornet/Kconfig | 13 +
> > > security/hornet/Makefile | 7 +
> > > security/hornet/hornet.asn1 | 12 +
> > > security/hornet/hornet_lsm.c | 352 ++++++++++++++++
> > > security/ipe/Kconfig | 15 +
> > > security/ipe/audit.c | 15 +
> > > security/ipe/eval.c | 93 ++++-
> > > security/ipe/eval.h | 11 +
> > > security/ipe/hooks.c | 63 +++
> > > security/ipe/hooks.h | 15 +
> > > security/ipe/ipe.c | 14 +
> > > security/ipe/ipe.h | 3 +
> > > security/ipe/policy.h | 14 +
> > > security/ipe/policy_parser.c | 27 ++
> > > security/security.c | 75 +++-
> > > tools/testing/selftests/Makefile | 1 +
> > > tools/testing/selftests/hornet/Makefile | 63 +++
> > > tools/testing/selftests/hornet/loader.c | 21 +
> > > tools/testing/selftests/hornet/trivial.bpf.c | 33 ++
> > > 45 files changed, 2112 insertions(+), 8 deletions(-)
> > > create mode 100644 Documentation/admin-guide/LSM/Hornet.rst
> > > create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1
> > > create mode 100644 scripts/hornet/Makefile
> > > create mode 100755 scripts/hornet/extract-insn.sh
> > > create mode 100755 scripts/hornet/extract-map.sh
> > > create mode 100755 scripts/hornet/extract-skel.sh
> > > create mode 100644 scripts/hornet/gen_sig.c
> > > create mode 100755 scripts/hornet/write-sig.sh
> > > create mode 100644 security/hornet/Kconfig
> > > create mode 100644 security/hornet/Makefile
> > > create mode 100644 security/hornet/hornet.asn1
> > > create mode 100644 security/hornet/hornet_lsm.c
> > > create mode 100644 tools/testing/selftests/hornet/Makefile
> > > create mode 100644 tools/testing/selftests/hornet/loader.c
> > > create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c
> >
> > [NOTE: added the linux-crypto list to the To/CC lines]
> >
> > Hi crypto folks,
> >
> > You'll notice there are three patches from James Bottomley in this
> > patchset that touch crypto code and I'd appreciate it if you could
> > take a look and either ACK the patches or let James and Blaise know
> > what you would like changed. James did send these patches to you for
> > review some time ago, so they aren't necessarily new, but I wanted to
> > make sure you saw them again.
> >
> > Unfortunately, it doesn't look like the crypto list was CC'd on this
> > patchset, so here is a lore link to the patchset as a whole:
> >
> > https://lore.kernel.org/linux-security-module/20260507191416.2984054-1-bboscaccy@linux.microsoft.com
> >
> > ... and here are lore links to the three crypto patches:
>
> We discussed before how the actual signature check seemed to have been
> overlooked in some cases, due to the complexities of PKCS#7
> (https://lore.kernel.org/r/20260305185016.GC2796@quark/). Looks like
> that was fixed. It is really hard to do any meaningful review of a
> PKCS#7 based system, though. And it sounds like this one is proceeding
> anyway due to some requirement to be compatible with an existing PKCS#7
> based system. So I'm not sure what you're looking for.
Ideally an ACK that you approve of merging those three crypto patches
via the LSM tree, or a quick comment if you happen to see anything
that needs changing.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v7 00/10] Reintroduce Hornet LSM
From: Eric Biggers @ 2026-05-07 21:58 UTC (permalink / raw)
To: Paul Moore
Cc: Blaise Boscaccy, linux-crypto, Jonathan Corbet, James Morris,
Serge E. Hallyn, Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <CAHC9VhR0Abikk+2=DWtVu1cEkcwkudKFRJH51BFOh0Qt01wLJw@mail.gmail.com>
On Thu, May 07, 2026 at 04:57:35PM -0400, Paul Moore wrote:
> On Thu, May 7, 2026 at 3:14 PM Blaise Boscaccy
> <bboscaccy@linux.microsoft.com> wrote:
> >
> > This patch series introduces the next iteration of the Hornet LSM.
> > Hornet’s goal is to provide a secure and extensible in-kernel
> > signature verification mechanism for eBPF programs.
> >
> > Hornet addresses concerns from users who require strict audit trails and
> > verification guarantees for eBPF programs, especially in
> > security-sensitive environments. Many production systems need assurance
> > that only authorized, unmodified eBPF programs are loaded into the
> > kernel. Hornet provides this assurance through cryptographic signature
> > verification.
> >
> > The currently accepted loader-plus-map signature verification scheme,
> > mandated by Alexei and KP, is simple to implement and generally
> > acceptable if users and administrators are satisfied with it. However,
> > verifying both the loader and the maps offers additional benefits
> > beyond verifying the loader alone:
> >
> > 1. Security and Audit Integrity
> >
> > A key advantage is that the LSM hook for authorizing BPF program loads
> > can operate after signature verification. This ensures:
> >
> > * Access control decisions are based on verified signature status.
> > * Accurate system state measurement and logging.
> > * Log entries claiming a verified signature are truthful, avoiding
> > misleading records where only the loader was verified while the actual
> > BPF program verification occurs later without logging.
> >
> > 2. TOCTOU Attack Prevention
> >
> > The current map hash implementation may be vulnerable to a TOCTOU
> > attack because it allows unfrozen maps to cache a previously
> > calculated hash. The accepted “trusted loader” scheme cannot detect
> > this and may permit loading altered maps.
> >
> > 3. Supply Chain Integrity
> >
> > Verify that eBPF programs and their associated map data have not been
> > modified since they were built and signed, in the kernel proper, may
> > aid in protecting against supply chain attacks.
> >
> > This approach addresses concerns from users who require strict audit
> > trails and verification guarantees, especially in security-sensitive
> > environments. Map hashes for extended verification are passed via the
> > existing PKCS#7 UAPI and verified by the crypto subsystem. Hornet then
> > calculates the program’s verification state. Hornet itself does not
> > enforce a policy on whether unsigned or partially signed programs
> > should be rejected. It delegates that decision to downstream LSMs
> > hook, making it a composable building block in a larger security
> > architecture.
>
> [NOTE: trimmed changelog for brevity]
>
> > Blaise Boscaccy (6):
> > lsm: security: Add additional enum values for bpf integrity checks
> > security: Hornet LSM
> > hornet: Introduce gen_sig
> > hornet: Add a light skeleton data extractor scripts
> > selftests/hornet: Add a selftest for the Hornet LSM
> > ipe: Add BPF program load policy enforcement via Hornet integration
> >
> > James Bottomley (3):
> > crypto: pkcs7: add flag for validated trust on a signed info block
> > crypto: pkcs7: add ability to extract signed attributes by OID
> > crypto: pkcs7: add tests for pkcs7_get_authattr
> >
> > Paul Moore (1):
> > lsm: framework for BPF integrity verification
> >
> > Documentation/admin-guide/LSM/Hornet.rst | 323 +++++++++++++++
> > Documentation/admin-guide/LSM/index.rst | 1 +
> > Documentation/admin-guide/LSM/ipe.rst | 162 +++++++-
> > Documentation/security/ipe.rst | 68 ++++
> > MAINTAINERS | 9 +
> > certs/system_keyring.c | 1 +
> > crypto/asymmetric_keys/Makefile | 4 +-
> > crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 +
> > crypto/asymmetric_keys/pkcs7_key_type.c | 44 +-
> > crypto/asymmetric_keys/pkcs7_parser.c | 81 ++++
> > crypto/asymmetric_keys/pkcs7_parser.h | 1 +
> > crypto/asymmetric_keys/pkcs7_trust.c | 1 +
> > include/crypto/pkcs7.h | 4 +
> > include/linux/lsm_hook_defs.h | 5 +
> > include/linux/oid_registry.h | 3 +
> > include/linux/security.h | 28 ++
> > include/uapi/linux/lsm.h | 1 +
> > scripts/Makefile | 1 +
> > scripts/hornet/Makefile | 5 +
> > scripts/hornet/extract-insn.sh | 27 ++
> > scripts/hornet/extract-map.sh | 27 ++
> > scripts/hornet/extract-skel.sh | 27 ++
> > scripts/hornet/gen_sig.c | 401 +++++++++++++++++++
> > scripts/hornet/write-sig.sh | 27 ++
> > security/Kconfig | 3 +-
> > security/Makefile | 1 +
> > security/hornet/Kconfig | 13 +
> > security/hornet/Makefile | 7 +
> > security/hornet/hornet.asn1 | 12 +
> > security/hornet/hornet_lsm.c | 352 ++++++++++++++++
> > security/ipe/Kconfig | 15 +
> > security/ipe/audit.c | 15 +
> > security/ipe/eval.c | 93 ++++-
> > security/ipe/eval.h | 11 +
> > security/ipe/hooks.c | 63 +++
> > security/ipe/hooks.h | 15 +
> > security/ipe/ipe.c | 14 +
> > security/ipe/ipe.h | 3 +
> > security/ipe/policy.h | 14 +
> > security/ipe/policy_parser.c | 27 ++
> > security/security.c | 75 +++-
> > tools/testing/selftests/Makefile | 1 +
> > tools/testing/selftests/hornet/Makefile | 63 +++
> > tools/testing/selftests/hornet/loader.c | 21 +
> > tools/testing/selftests/hornet/trivial.bpf.c | 33 ++
> > 45 files changed, 2112 insertions(+), 8 deletions(-)
> > create mode 100644 Documentation/admin-guide/LSM/Hornet.rst
> > create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1
> > create mode 100644 scripts/hornet/Makefile
> > create mode 100755 scripts/hornet/extract-insn.sh
> > create mode 100755 scripts/hornet/extract-map.sh
> > create mode 100755 scripts/hornet/extract-skel.sh
> > create mode 100644 scripts/hornet/gen_sig.c
> > create mode 100755 scripts/hornet/write-sig.sh
> > create mode 100644 security/hornet/Kconfig
> > create mode 100644 security/hornet/Makefile
> > create mode 100644 security/hornet/hornet.asn1
> > create mode 100644 security/hornet/hornet_lsm.c
> > create mode 100644 tools/testing/selftests/hornet/Makefile
> > create mode 100644 tools/testing/selftests/hornet/loader.c
> > create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c
>
> [NOTE: added the linux-crypto list to the To/CC lines]
>
> Hi crypto folks,
>
> You'll notice there are three patches from James Bottomley in this
> patchset that touch crypto code and I'd appreciate it if you could
> take a look and either ACK the patches or let James and Blaise know
> what you would like changed. James did send these patches to you for
> review some time ago, so they aren't necessarily new, but I wanted to
> make sure you saw them again.
>
> Unfortunately, it doesn't look like the crypto list was CC'd on this
> patchset, so here is a lore link to the patchset as a whole:
>
> https://lore.kernel.org/linux-security-module/20260507191416.2984054-1-bboscaccy@linux.microsoft.com
>
> ... and here are lore links to the three crypto patches:
We discussed before how the actual signature check seemed to have been
overlooked in some cases, due to the complexities of PKCS#7
(https://lore.kernel.org/r/20260305185016.GC2796@quark/). Looks like
that was fixed. It is really hard to do any meaningful review of a
PKCS#7 based system, though. And it sounds like this one is proceeding
anyway due to some requirement to be compatible with an existing PKCS#7
based system. So I'm not sure what you're looking for.
- Eric
^ permalink raw reply
* Re: [PATCH v7 00/10] Reintroduce Hornet LSM
From: Paul Moore @ 2026-05-07 20:57 UTC (permalink / raw)
To: Blaise Boscaccy, linux-crypto
Cc: Jonathan Corbet, James Morris, Serge E. Hallyn,
Mickaël Salaün, Günther Noack,
Dr. David Alan Gilbert, Andrew Morton, James.Bottomley, dhowells,
Fan Wu, Ryan Foster, Randy Dunlap, linux-security-module,
linux-doc, linux-kernel, bpf, Song Liu
In-Reply-To: <20260507191416.2984054-1-bboscaccy@linux.microsoft.com>
On Thu, May 7, 2026 at 3:14 PM Blaise Boscaccy
<bboscaccy@linux.microsoft.com> wrote:
>
> This patch series introduces the next iteration of the Hornet LSM.
> Hornet’s goal is to provide a secure and extensible in-kernel
> signature verification mechanism for eBPF programs.
>
> Hornet addresses concerns from users who require strict audit trails and
> verification guarantees for eBPF programs, especially in
> security-sensitive environments. Many production systems need assurance
> that only authorized, unmodified eBPF programs are loaded into the
> kernel. Hornet provides this assurance through cryptographic signature
> verification.
>
> The currently accepted loader-plus-map signature verification scheme,
> mandated by Alexei and KP, is simple to implement and generally
> acceptable if users and administrators are satisfied with it. However,
> verifying both the loader and the maps offers additional benefits
> beyond verifying the loader alone:
>
> 1. Security and Audit Integrity
>
> A key advantage is that the LSM hook for authorizing BPF program loads
> can operate after signature verification. This ensures:
>
> * Access control decisions are based on verified signature status.
> * Accurate system state measurement and logging.
> * Log entries claiming a verified signature are truthful, avoiding
> misleading records where only the loader was verified while the actual
> BPF program verification occurs later without logging.
>
> 2. TOCTOU Attack Prevention
>
> The current map hash implementation may be vulnerable to a TOCTOU
> attack because it allows unfrozen maps to cache a previously
> calculated hash. The accepted “trusted loader” scheme cannot detect
> this and may permit loading altered maps.
>
> 3. Supply Chain Integrity
>
> Verify that eBPF programs and their associated map data have not been
> modified since they were built and signed, in the kernel proper, may
> aid in protecting against supply chain attacks.
>
> This approach addresses concerns from users who require strict audit
> trails and verification guarantees, especially in security-sensitive
> environments. Map hashes for extended verification are passed via the
> existing PKCS#7 UAPI and verified by the crypto subsystem. Hornet then
> calculates the program’s verification state. Hornet itself does not
> enforce a policy on whether unsigned or partially signed programs
> should be rejected. It delegates that decision to downstream LSMs
> hook, making it a composable building block in a larger security
> architecture.
[NOTE: trimmed changelog for brevity]
> Blaise Boscaccy (6):
> lsm: security: Add additional enum values for bpf integrity checks
> security: Hornet LSM
> hornet: Introduce gen_sig
> hornet: Add a light skeleton data extractor scripts
> selftests/hornet: Add a selftest for the Hornet LSM
> ipe: Add BPF program load policy enforcement via Hornet integration
>
> James Bottomley (3):
> crypto: pkcs7: add flag for validated trust on a signed info block
> crypto: pkcs7: add ability to extract signed attributes by OID
> crypto: pkcs7: add tests for pkcs7_get_authattr
>
> Paul Moore (1):
> lsm: framework for BPF integrity verification
>
> Documentation/admin-guide/LSM/Hornet.rst | 323 +++++++++++++++
> Documentation/admin-guide/LSM/index.rst | 1 +
> Documentation/admin-guide/LSM/ipe.rst | 162 +++++++-
> Documentation/security/ipe.rst | 68 ++++
> MAINTAINERS | 9 +
> certs/system_keyring.c | 1 +
> crypto/asymmetric_keys/Makefile | 4 +-
> crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 +
> crypto/asymmetric_keys/pkcs7_key_type.c | 44 +-
> crypto/asymmetric_keys/pkcs7_parser.c | 81 ++++
> crypto/asymmetric_keys/pkcs7_parser.h | 1 +
> crypto/asymmetric_keys/pkcs7_trust.c | 1 +
> include/crypto/pkcs7.h | 4 +
> include/linux/lsm_hook_defs.h | 5 +
> include/linux/oid_registry.h | 3 +
> include/linux/security.h | 28 ++
> include/uapi/linux/lsm.h | 1 +
> scripts/Makefile | 1 +
> scripts/hornet/Makefile | 5 +
> scripts/hornet/extract-insn.sh | 27 ++
> scripts/hornet/extract-map.sh | 27 ++
> scripts/hornet/extract-skel.sh | 27 ++
> scripts/hornet/gen_sig.c | 401 +++++++++++++++++++
> scripts/hornet/write-sig.sh | 27 ++
> security/Kconfig | 3 +-
> security/Makefile | 1 +
> security/hornet/Kconfig | 13 +
> security/hornet/Makefile | 7 +
> security/hornet/hornet.asn1 | 12 +
> security/hornet/hornet_lsm.c | 352 ++++++++++++++++
> security/ipe/Kconfig | 15 +
> security/ipe/audit.c | 15 +
> security/ipe/eval.c | 93 ++++-
> security/ipe/eval.h | 11 +
> security/ipe/hooks.c | 63 +++
> security/ipe/hooks.h | 15 +
> security/ipe/ipe.c | 14 +
> security/ipe/ipe.h | 3 +
> security/ipe/policy.h | 14 +
> security/ipe/policy_parser.c | 27 ++
> security/security.c | 75 +++-
> tools/testing/selftests/Makefile | 1 +
> tools/testing/selftests/hornet/Makefile | 63 +++
> tools/testing/selftests/hornet/loader.c | 21 +
> tools/testing/selftests/hornet/trivial.bpf.c | 33 ++
> 45 files changed, 2112 insertions(+), 8 deletions(-)
> create mode 100644 Documentation/admin-guide/LSM/Hornet.rst
> create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1
> create mode 100644 scripts/hornet/Makefile
> create mode 100755 scripts/hornet/extract-insn.sh
> create mode 100755 scripts/hornet/extract-map.sh
> create mode 100755 scripts/hornet/extract-skel.sh
> create mode 100644 scripts/hornet/gen_sig.c
> create mode 100755 scripts/hornet/write-sig.sh
> create mode 100644 security/hornet/Kconfig
> create mode 100644 security/hornet/Makefile
> create mode 100644 security/hornet/hornet.asn1
> create mode 100644 security/hornet/hornet_lsm.c
> create mode 100644 tools/testing/selftests/hornet/Makefile
> create mode 100644 tools/testing/selftests/hornet/loader.c
> create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c
[NOTE: added the linux-crypto list to the To/CC lines]
Hi crypto folks,
You'll notice there are three patches from James Bottomley in this
patchset that touch crypto code and I'd appreciate it if you could
take a look and either ACK the patches or let James and Blaise know
what you would like changed. James did send these patches to you for
review some time ago, so they aren't necessarily new, but I wanted to
make sure you saw them again.
Unfortunately, it doesn't look like the crypto list was CC'd on this
patchset, so here is a lore link to the patchset as a whole:
https://lore.kernel.org/linux-security-module/20260507191416.2984054-1-bboscaccy@linux.microsoft.com
... and here are lore links to the three crypto patches:
https://lore.kernel.org/linux-security-module/20260507191416.2984054-2-bboscaccy@linux.microsoft.com
https://lore.kernel.org/linux-security-module/20260507191416.2984054-3-bboscaccy@linux.microsoft.com
https://lore.kernel.org/linux-security-module/20260507191416.2984054-4-bboscaccy@linux.microsoft.com
Thanks.
--
paul-moore.com
^ permalink raw reply
* [PATCH v2] crypto: ccp: sev-dev-tsm: bail out early when pdev->bus is NULL
From: Stepan Ionichev @ 2026-05-07 14:06 UTC (permalink / raw)
To: ashish.kalra
Cc: thomas.lendacky, aik, john.allen, herbert, davem, linux-crypto,
linux-kernel, Stepan Ionichev
In-Reply-To: <20260507023619.398-1-sozdayvek@gmail.com>
dsm_create() initially checks pdev->bus when computing segment_id:
u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
But the next two lines unconditionally dereference pdev->bus via
pcie_find_root_port() and especially pci_dev_id(pdev), which expands
to PCI_DEVID(dev->bus->number, dev->devfn). If pdev->bus is in fact
NULL, segment_id is initialised to 0 but the very next statement
crashes the kernel.
smatch flags this:
drivers/crypto/ccp/sev-dev-tsm.c:253 dsm_create() error: we
previously assumed 'pdev->bus' could be null (see line 251)
Make the NULL handling consistent: if pdev->bus is NULL the device
has no PCI context to work with and SEV TIO setup cannot proceed,
so return -ENODEV before any of the bus-dependent lookups. The
remaining initialisation now runs only on the path where pdev->bus
is known to be valid.
No change for callers where pdev->bus is non-NULL, which is the
only case where dsm_create() did meaningful work before this change.
Fixes: 4be423572da1 ("crypto/ccp: Implement SEV-TIO PCIe IDE (phase1)")
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
---
v2:
- Add Fixes: tag (suggested by Tom Lendacky).
- Cc Alexey Kardashevskiy (original author of the SEV-TIO code).
drivers/crypto/ccp/sev-dev-tsm.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c
index b07ae529b..f303d8f55 100644
--- a/drivers/crypto/ccp/sev-dev-tsm.c
+++ b/drivers/crypto/ccp/sev-dev-tsm.c
@@ -248,12 +248,19 @@ static void dsm_remove(struct pci_tsm *tsm)
static int dsm_create(struct tio_dsm *dsm)
{
struct pci_dev *pdev = dsm->tsm.base_tsm.pdev;
- u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
- struct pci_dev *rootport = pcie_find_root_port(pdev);
- u16 device_id = pci_dev_id(pdev);
+ struct pci_dev *rootport;
+ u8 segment_id;
+ u16 device_id;
u16 root_port_id;
u32 lnkcap = 0;
+ if (!pdev->bus)
+ return -ENODEV;
+
+ segment_id = pci_domain_nr(pdev->bus);
+ rootport = pcie_find_root_port(pdev);
+ device_id = pci_dev_id(pdev);
+
if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP,
&lnkcap))
return -ENODEV;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] crypto: atmel-ecc - replace min_t with min
From: David Laight @ 2026-05-07 14:50 UTC (permalink / raw)
To: Thorsten Blum
Cc: Herbert Xu, David S. Miller, Nicolas Ferre, Alexandre Belloni,
Claudiu Beznea, linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260507135525.331107-3-thorsten.blum@linux.dev>
On Thu, 7 May 2026 15:55:27 +0200
Thorsten Blum <thorsten.blum@linux.dev> wrote:
> Use the simpler min() macro since the values are all unsigned and
> compatible.
>
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
I'm all for nuking min_t(), so:
Reviewed-by: David Laight <david.laght.linux@gmail.com>
> ---
> drivers/crypto/atmel-ecc.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
> index b6a77c8d439c..2cf53f0b6742 100644
> --- a/drivers/crypto/atmel-ecc.c
> +++ b/drivers/crypto/atmel-ecc.c
> @@ -56,7 +56,7 @@ static void atmel_ecdh_done(struct atmel_i2c_work_data *work_data, void *areq,
> goto free_work_data;
>
> /* might want less than we've got */
> - n_sz = min_t(size_t, ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
> + n_sz = min(ATMEL_ECC_NIST_P256_N_SIZE, req->dst_len);
Not entirely related, but (to me) the arguments are in the wrong order.
>
> /* copy the shared secret */
> copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, n_sz),
> @@ -150,7 +150,7 @@ static int atmel_ecdh_generate_public_key(struct kpp_request *req)
> return -EINVAL;
>
> /* might want less than we've got */
> - nbytes = min_t(size_t, ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
> + nbytes = min(ATMEL_ECC_PUBKEY_SIZE, req->dst_len);
>
> /* public key was saved at private key generation */
> copied = sg_copy_from_buffer(req->dst,
>
^ permalink raw reply
* Re: [PATCH] crypto: ccp: sev-dev-tsm: bail out early when pdev->bus is NULL
From: Tom Lendacky @ 2026-05-07 14:43 UTC (permalink / raw)
To: Stepan Ionichev, Alexey Kardashevskiy
Cc: john.allen, herbert, davem, linux-crypto, linux-kernel,
ashish.kalra
In-Reply-To: <20260507023619.398-1-sozdayvek@gmail.com>
On 5/6/26 21:36, Stepan Ionichev wrote:
> dsm_create() initially checks pdev->bus when computing segment_id:
>
> u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
>
> But the next two lines unconditionally dereference pdev->bus via
> pcie_find_root_port() and especially pci_dev_id(pdev), which expands
> to PCI_DEVID(dev->bus->number, dev->devfn). If pdev->bus is in fact
> NULL, segment_id is initialised to 0 but the very next statement
> crashes the kernel.
>
> smatch flags this:
>
> drivers/crypto/ccp/sev-dev-tsm.c:253 dsm_create() error: we
> previously assumed 'pdev->bus' could be null (see line 251)
>
> Make the NULL handling consistent: if pdev->bus is NULL the device
> has no PCI context to work with and SEV TIO setup cannot proceed,
> so return -ENODEV before any of the bus-dependent lookups. The
> remaining initialisation now runs only on the path where pdev->bus
> is known to be valid.
>
> No change for callers where pdev->bus is non-NULL, which is the
> only case where dsm_create() did meaningful work before this change.
>
> Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
This should have a Fixes: tag, which would have then added the main author
of the file to the email, so adding Alexey Kardashevskiy manually.
@Alexey, please also submit a patch to make yourself a maintainer of the
TIO/TSM support.
Thanks,
Tom
> ---
> drivers/crypto/ccp/sev-dev-tsm.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c
> index b07ae529b..f303d8f55 100644
> --- a/drivers/crypto/ccp/sev-dev-tsm.c
> +++ b/drivers/crypto/ccp/sev-dev-tsm.c
> @@ -248,12 +248,19 @@ static void dsm_remove(struct pci_tsm *tsm)
> static int dsm_create(struct tio_dsm *dsm)
> {
> struct pci_dev *pdev = dsm->tsm.base_tsm.pdev;
> - u8 segment_id = pdev->bus ? pci_domain_nr(pdev->bus) : 0;
> - struct pci_dev *rootport = pcie_find_root_port(pdev);
> - u16 device_id = pci_dev_id(pdev);
> + struct pci_dev *rootport;
> + u8 segment_id;
> + u16 device_id;
> u16 root_port_id;
> u32 lnkcap = 0;
>
> + if (!pdev->bus)
> + return -ENODEV;
> +
> + segment_id = pci_domain_nr(pdev->bus);
> + rootport = pcie_find_root_port(pdev);
> + device_id = pci_dev_id(pdev);
> +
> if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP,
> &lnkcap))
> return -ENODEV;
^ permalink raw reply
* [PATCH v3 11/11] crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
The problem described in commit 655ef638a2bc ("crypto: talitos - fix
SEC1 32k ahash request limitation") also apply for the SEC2 hardware,
but with a limitation of 64k - 1 bytes.
Split ahash_done() into SEC1 and SEC2 paths: SEC1 continues to free the
whole descriptor list at once, while SEC2 now iterates through
descriptors one by one, submitting the next only after the previous
completes, which is required since SEC2 cannot chain descriptors in
hardware.
Cc: stable@vger.kernel.org
Fixes: c662b043cdca ("crypto: af_alg/hash: Support MSG_SPLICE_PAGES")
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 47 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 39 insertions(+), 8 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b4283b6c18ef..4b53b13f96d9 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1820,16 +1820,46 @@ static void ahash_done(struct device *dev,
struct talitos_edesc *edesc =
container_of(desc, struct talitos_edesc, desc);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ bool is_sec1 = has_ftr_sec1(dev_get_drvdata(dev));
+ struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+ struct talitos_edesc *next;
- if (!req_ctx->last_request && req_ctx->to_hash_later) {
- /* Position any partial block for next update/final/finup */
- req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
- req_ctx->nbuf = req_ctx->to_hash_later;
- }
+ if (is_sec1) {
+ if (!req_ctx->last_request && req_ctx->to_hash_later) {
+ /* Position any partial block for next update/final/finup */
+ req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
+ req_ctx->nbuf = req_ctx->to_hash_later;
+ }
+
+ free_edesc_list_from(areq, edesc);
+ ahash_request_complete(areq, err);
+ } else {
+ next = edesc->next_desc;
- free_edesc_list_from(areq, edesc);
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+ kfree(edesc);
- ahash_request_complete(areq, err);
+ if (err)
+ goto out;
+
+ if (next) {
+ err = talitos_submit(dev, ctx->ch, &next->desc,
+ ahash_done, areq);
+ if (err != -EINPROGRESS)
+ goto out;
+ return;
+ }
+out:
+ if (!req_ctx->last_request && req_ctx->to_hash_later) {
+ /* Position any partial block for next update/final/finup */
+ req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
+ req_ctx->nbuf = req_ctx->to_hash_later;
+ }
+ if (err && next)
+ free_edesc_list_from(areq, next);
+ ahash_request_complete(areq, err);
+ }
}
/*
@@ -1940,7 +1970,8 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
- size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN : SIZE_MAX;
+ size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN :
+ TALITOS2_MAX_DATA_LEN;
struct scatterlist tmp[2];
size_t to_hash_this_desc;
struct scatterlist *src;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 10/11] crypto: talitos/hash - remove useless wrapper
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
ahash_process_req() was a wrapper used in commit 655ef638a2bc ("crypto:
talitos - fix SEC1 32k ahash request limitation"). Rename
ahash_process_req_one() to ahash_process_req() and remove the wrapper.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6be42935068a..b4283b6c18ef 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2003,7 +2003,7 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
return first;
}
-static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes)
+static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
@@ -2084,11 +2084,6 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
return ret;
}
-static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
-{
- return ahash_process_req_one(areq, nbytes);
-}
-
static int ahash_init(struct ahash_request *areq)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
--
2.54.0
^ permalink raw reply related
* [PATCH v3 09/11] crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
In talitos_ahash_req_ctx and talitos_export_state, the fields
first_desc and last_desc describe request-level (not descriptor-level)
state. Rename them to first_request and last_request for clarity.
last_desc is also removed from talitos_ahash_req_ctx as it is no
longer used.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 1f497930800b..6be42935068a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -944,8 +944,7 @@ struct talitos_ahash_req_ctx {
u8 buf[2][HASH_MAX_BLOCK_SIZE];
int buf_idx;
unsigned int swinit;
- unsigned int first_desc;
- unsigned int last_desc;
+ unsigned int first_request;
unsigned int last_request;
unsigned int to_hash_later;
unsigned int nbuf;
@@ -957,8 +956,8 @@ struct talitos_export_state {
u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
u8 buf[HASH_MAX_BLOCK_SIZE];
unsigned int swinit;
- unsigned int first_desc;
- unsigned int last_desc;
+ unsigned int first_request;
+ unsigned int last_request;
unsigned int to_hash_later;
unsigned int nbuf;
};
@@ -1822,8 +1821,7 @@ static void ahash_done(struct device *dev,
container_of(desc, struct talitos_edesc, desc);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-
- if (!req_ctx->last_desc && req_ctx->to_hash_later) {
+ if (!req_ctx->last_request && req_ctx->to_hash_later) {
/* Position any partial block for next update/final/finup */
req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
req_ctx->nbuf = req_ctx->to_hash_later;
@@ -1872,7 +1870,7 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
/* first DWORD empty */
/* hash context in */
- if (!edesc->first || !req_ctx->first_desc || req_ctx->swinit) {
+ if (!edesc->first || !req_ctx->first_request || req_ctx->swinit) {
map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
req_ctx->hw_context_size,
req_ctx->hw_context,
@@ -1880,7 +1878,7 @@ static void common_nonsnoop_hash(struct talitos_edesc *edesc,
req_ctx->swinit = 0;
}
/* Indicate next op is not the first. */
- req_ctx->first_desc = 0;
+ req_ctx->first_request = 0;
/* HMAC key */
if (ctx->keylen)
@@ -1975,14 +1973,14 @@ ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
/* request SEC to INIT hash. */
- if (req_ctx->first_desc && edesc->first && !req_ctx->swinit)
+ if (req_ctx->first_request && edesc->first && !req_ctx->swinit)
edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
/*
* When the tfm context has a keylen, it's an HMAC.
* A first or last (ie. not middle) descriptor must request HMAC.
*/
- if (ctx->keylen && ((req_ctx->first_desc && edesc->first) ||
+ if (ctx->keylen && ((req_ctx->first_request && edesc->first) ||
(req_ctx->last_request && edesc->last)))
edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
@@ -2103,14 +2101,13 @@ static int ahash_init(struct ahash_request *areq)
/* Initialize the context */
req_ctx->buf_idx = 0;
req_ctx->nbuf = 0;
- req_ctx->first_desc = 1; /* first_desc indicates h/w must init its context */
+ req_ctx->first_request = 1;
req_ctx->swinit = 0; /* assume h/w init of context */
size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
req_ctx->hw_context_size = size;
req_ctx->last_request = 0;
- req_ctx->last_desc = 0;
dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
DMA_TO_DEVICE);
@@ -2202,8 +2199,8 @@ static int ahash_export(struct ahash_request *areq, void *out)
req_ctx->hw_context_size);
memcpy(export->buf, req_ctx->buf[req_ctx->buf_idx], req_ctx->nbuf);
export->swinit = req_ctx->swinit;
- export->first_desc = req_ctx->first_desc;
- export->last_desc = req_ctx->last_desc;
+ export->first_request = req_ctx->first_request;
+ export->last_request = req_ctx->last_request;
export->to_hash_later = req_ctx->to_hash_later;
export->nbuf = req_ctx->nbuf;
@@ -2228,8 +2225,8 @@ static int ahash_import(struct ahash_request *areq, const void *in)
memcpy(req_ctx->hw_context, export->hw_context, size);
memcpy(req_ctx->buf[0], export->buf, export->nbuf);
req_ctx->swinit = export->swinit;
- req_ctx->first_desc = export->first_desc;
- req_ctx->last_desc = export->last_desc;
+ req_ctx->first_request = export->first_request;
+ req_ctx->last_request = export->last_request;
req_ctx->to_hash_later = export->to_hash_later;
req_ctx->nbuf = export->nbuf;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 08/11] crypto: talitos/hash - drop workqueue mechanism for SEC1
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Now that SEC1 hash uses hardware descriptor chaining instead of a
workqueue to process requests exceeding TALITOS1_MAX_DATA_LEN, the
workqueue code is no longer needed.
Remove sec1_ahash_process_remaining(), the related fields from
talitos_ahash_req_ctx (request_bufsl, areq, request_sl,
remaining_ahash_request_bytes, current_ahash_request_bytes,
sec1_ahash_process_remaining), the dead code in ahash_done(), and
simplify ahash_process_req() to call ahash_process_req_one() directly
with the original areq->src and areq->nbytes.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 80 +++++-------------------------------------------
1 file changed, 7 insertions(+), 73 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 883115d66fc4..1f497930800b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -12,7 +12,6 @@
* All rights reserved.
*/
-#include <linux/workqueue.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
@@ -952,13 +951,6 @@ struct talitos_ahash_req_ctx {
unsigned int nbuf;
struct scatterlist bufsl[2];
struct scatterlist *psrc;
-
- struct scatterlist request_bufsl[2];
- struct ahash_request *areq;
- struct scatterlist *request_sl;
- unsigned int remaining_ahash_request_bytes;
- unsigned int current_ahash_request_bytes;
- struct work_struct sec1_ahash_process_remaining;
};
struct talitos_export_state {
@@ -1840,18 +1832,6 @@ static void ahash_done(struct device *dev,
free_edesc_list_from(areq, edesc);
ahash_request_complete(areq, err);
-
- return;
-
- req_ctx->remaining_ahash_request_bytes -=
- req_ctx->current_ahash_request_bytes;
-
- if (!req_ctx->remaining_ahash_request_bytes) {
- ahash_request_complete(areq, 0);
- return;
- }
-
- schedule_work(&req_ctx->sec1_ahash_process_remaining);
}
/*
@@ -2044,12 +2024,12 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <= blocksize)) {
/* Buffer up to one whole block */
- nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
+ nents = sg_nents_for_len(areq->src, nbytes);
if (nents < 0) {
dev_err(dev, "Invalid number of src SG.\n");
return nents;
}
- sg_copy_to_buffer(req_ctx->request_sl, nents,
+ sg_copy_to_buffer(areq->src, nents,
ctx_buf + req_ctx->nbuf, nbytes);
req_ctx->nbuf += nbytes;
return 0;
@@ -2076,18 +2056,18 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
sg_init_table(req_ctx->bufsl, nsg);
sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
if (nsg > 1)
- sg_chain(req_ctx->bufsl, 2, req_ctx->request_sl);
+ sg_chain(req_ctx->bufsl, 2, areq->src);
req_ctx->psrc = req_ctx->bufsl;
} else
- req_ctx->psrc = req_ctx->request_sl;
+ req_ctx->psrc = areq->src;
if (to_hash_later) {
- nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
+ nents = sg_nents_for_len(areq->src, nbytes);
if (nents < 0) {
dev_err(dev, "Invalid number of src SG.\n");
return nents;
}
- sg_pcopy_to_buffer(req_ctx->request_sl, nents,
+ sg_pcopy_to_buffer(areq->src, nents,
req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
to_hash_later,
nbytes - to_hash_later);
@@ -2106,54 +2086,9 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
return ret;
}
-static void sec1_ahash_process_remaining(struct work_struct *work)
-{
- struct talitos_ahash_req_ctx *req_ctx =
- container_of(work, struct talitos_ahash_req_ctx,
- sec1_ahash_process_remaining);
- int err = 0;
-
- req_ctx->request_sl = scatterwalk_ffwd(req_ctx->request_bufsl,
- req_ctx->request_sl, TALITOS1_MAX_DATA_LEN);
-
- if (req_ctx->remaining_ahash_request_bytes > TALITOS1_MAX_DATA_LEN)
- req_ctx->current_ahash_request_bytes = TALITOS1_MAX_DATA_LEN;
- else {
- req_ctx->current_ahash_request_bytes =
- req_ctx->remaining_ahash_request_bytes;
-
- if (req_ctx->last_request)
- req_ctx->last_desc = 1;
- }
-
- err = ahash_process_req_one(req_ctx->areq,
- req_ctx->current_ahash_request_bytes);
-
- if (err != -EINPROGRESS)
- ahash_request_complete(req_ctx->areq, err);
-}
-
static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
{
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
- struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
- struct device *dev = ctx->dev;
- struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
- struct talitos_private *priv = dev_get_drvdata(dev);
- bool is_sec1 = has_ftr_sec1(priv);
-
- req_ctx->areq = areq;
- req_ctx->request_sl = areq->src;
- req_ctx->remaining_ahash_request_bytes = nbytes;
-
- if (is_sec1) {
- if (req_ctx->last_request)
- req_ctx->last_desc = 1;
- }
-
- req_ctx->current_ahash_request_bytes = nbytes;
-
- return ahash_process_req_one(req_ctx->areq, nbytes);
+ return ahash_process_req_one(areq, nbytes);
}
static int ahash_init(struct ahash_request *areq)
@@ -2176,7 +2111,6 @@ static int ahash_init(struct ahash_request *areq)
req_ctx->hw_context_size = size;
req_ctx->last_request = 0;
req_ctx->last_desc = 0;
- INIT_WORK(&req_ctx->sec1_ahash_process_remaining, sec1_ahash_process_remaining);
dma = dma_map_single(dev, req_ctx->hw_context, req_ctx->hw_context_size,
DMA_TO_DEVICE);
--
2.54.0
^ permalink raw reply related
* [PATCH v3 07/11] crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Rework the SEC1 ahash implementation to build a chain of hardware
descriptors, replacing the previous approach of submitting one
descriptor at a time via a workqueue, introduced by commit 655ef638a2bc
("crypto: talitos - fix SEC1 32k ahash request limitation").
Introduce ahash_process_req_prepare() which iterates over the request
data, allocating enough descriptors to cover the entire ahash request.
The new fields (bufsl, src, first, last) are added to talitos_edesc for
this purpose.
common_nonsnoop_hash() no longer calls talitos_submit(); it only
maps and sets up the descriptor. Submission is now done by the caller
after the chain is built.
ahash_free_desc_list_from() takes over calling
common_nonsnoop_hash_unmap() for each descriptor during cleanup.
Compared to the workqueue based solution, request are slightly faster
since there is no more scheduling latency induced by the workqueue, and
only one interrupt is generated by the device at the end of a chain.
Commit 655ef638a2bc ("crypto: talitos - fix SEC1 32k ahash request
limitation") :
$ /usr/libexec/libkcapi/sha256sum ./test_5M.bin
013c5609d63c... ./test_5M.bin
real 0m 0.41s
user 0m 0.01s
sys 0m 0.07s
Now :
$ /usr/libexec/libkcapi/sha256sum ./test_5M.bin
013c5609d63c... ./test_5M.bin
real 0m 0.33s
user 0m 0.01s
sys 0m 0.20s
Tested on a system with an MPC885 SoC featuring the SEC1 Lite.
The increase in sys time is due to the fact that commit 37b5e8897eb5
("crypto: talitos - chain in buffered data for ahash on SEC1") can no
longer be applied.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 168 +++++++++++++++++++++++++++++------------------
drivers/crypto/talitos.h | 10 +++
2 files changed, 115 insertions(+), 63 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 0184982cb39b..883115d66fc4 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1791,12 +1791,12 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
- if (req_ctx->last_desc)
+ if (edesc->last && req_ctx->last_request)
memcpy(areq->result, req_ctx->hw_context,
crypto_ahash_digestsize(tfm));
- if (req_ctx->psrc)
- talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
+ if (edesc->src)
+ talitos_sg_unmap(dev, edesc, edesc->src, NULL, 0, 0);
/* When using hashctx-in, must unmap it. */
if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
@@ -1808,12 +1808,14 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
DMA_BIDIRECTIONAL);
}
-static void free_edesc_list_from(struct talitos_edesc *edesc)
+static void free_edesc_list_from(struct ahash_request *areq, struct talitos_edesc *edesc)
{
+ struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
struct talitos_edesc *next;
while (edesc) {
next = edesc->next_desc;
+ common_nonsnoop_hash_unmap(ctx->dev, edesc, areq);
kfree(edesc);
edesc = next;
}
@@ -1828,19 +1830,18 @@ static void ahash_done(struct device *dev,
container_of(desc, struct talitos_edesc, desc);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+
if (!req_ctx->last_desc && req_ctx->to_hash_later) {
/* Position any partial block for next update/final/finup */
req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
req_ctx->nbuf = req_ctx->to_hash_later;
}
- common_nonsnoop_hash_unmap(dev, edesc, areq);
- free_edesc_list_from(edesc);
+ free_edesc_list_from(areq, edesc);
- if (err) {
- ahash_request_complete(areq, err);
- return;
- }
+ ahash_request_complete(areq, err);
+
+ return;
req_ctx->remaining_ahash_request_bytes -=
req_ctx->current_ahash_request_bytes;
@@ -1874,18 +1875,15 @@ static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
(char *)padded_hash, DMA_TO_DEVICE);
}
-static int common_nonsnoop_hash(struct talitos_edesc *edesc,
- struct ahash_request *areq, unsigned int length,
- void (*callback) (struct device *dev,
- struct talitos_desc *desc,
- void *context, int error))
+static void common_nonsnoop_hash(struct talitos_edesc *edesc,
+ struct ahash_request *areq,
+ unsigned int length)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
struct device *dev = ctx->dev;
struct talitos_desc *desc = &edesc->desc;
- int ret;
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
@@ -1894,7 +1892,7 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
/* first DWORD empty */
/* hash context in */
- if (!req_ctx->first_desc || req_ctx->swinit) {
+ if (!edesc->first || !req_ctx->first_desc || req_ctx->swinit) {
map_single_talitos_ptr_nosync(dev, &desc->ptr[1],
req_ctx->hw_context_size,
req_ctx->hw_context,
@@ -1911,22 +1909,22 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
- sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
+ sg_copy_to_buffer(edesc->src, sg_count, edesc->buf, length);
else if (length)
- sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
- DMA_TO_DEVICE);
+ sg_count = dma_map_sg(dev, edesc->src, sg_count, DMA_TO_DEVICE);
+
/*
* data in
*/
- sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
- &desc->ptr[3], sg_count, 0, 0);
+ sg_count = talitos_sg_map(dev, edesc->src, length, edesc, &desc->ptr[3],
+ sg_count, 0, 0);
if (sg_count > 1)
sync_needed = true;
/* fifth DWORD empty */
/* hash/HMAC out -or- hash context out */
- if (req_ctx->last_desc)
+ if (edesc->last && req_ctx->last_request)
map_single_talitos_ptr(dev, &desc->ptr[5],
crypto_ahash_digestsize(tfm),
req_ctx->hw_context, DMA_FROM_DEVICE);
@@ -1944,30 +1942,89 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
if (sync_needed)
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
-
- ret = talitos_submit(dev, ctx->ch, desc, callback,
- areq);
- if (ret != -EINPROGRESS)
- goto err;
-
- return -EINPROGRESS;
-err:
- common_nonsnoop_hash_unmap(dev, edesc, areq);
- kfree(edesc);
- return ret;
}
static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
+ struct scatterlist *src,
unsigned int nbytes)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
- struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
- return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
+ return talitos_edesc_alloc(ctx->dev, src, NULL, NULL, 0,
nbytes, 0, 0, 0, areq->base.flags, false);
}
+static struct talitos_edesc *
+ahash_process_req_prepare(struct ahash_request *areq, unsigned int nbytes,
+ unsigned int blocksize, bool is_sec1)
+{
+ struct talitos_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+ struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+ struct talitos_edesc *first = NULL, *prev_edesc = NULL, *edesc;
+ size_t desc_max = is_sec1 ? TALITOS1_MAX_DATA_LEN : SIZE_MAX;
+ struct scatterlist tmp[2];
+ size_t to_hash_this_desc;
+ struct scatterlist *src;
+ size_t offset = 0;
+
+ do {
+ src = scatterwalk_ffwd(tmp, req_ctx->psrc, offset);
+
+ to_hash_this_desc =
+ min(nbytes, ALIGN_DOWN(desc_max, blocksize));
+
+ /* Allocate extended descriptor */
+ edesc = ahash_edesc_alloc(areq, src, to_hash_this_desc);
+ if (IS_ERR(edesc)) {
+ if (first)
+ free_edesc_list_from(areq, first);
+ return edesc;
+ }
+
+ edesc->src =
+ scatterwalk_ffwd(edesc->bufsl, req_ctx->psrc, offset);
+ edesc->desc.hdr = ctx->desc_hdr_template;
+ edesc->first = offset == 0;
+ edesc->last = nbytes - to_hash_this_desc == 0;
+
+ /* On last one, request SEC to pad; otherwise continue */
+ if (req_ctx->last_request && edesc->last)
+ edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
+ else
+ edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
+
+ /* request SEC to INIT hash. */
+ if (req_ctx->first_desc && edesc->first && !req_ctx->swinit)
+ edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
+
+ /*
+ * When the tfm context has a keylen, it's an HMAC.
+ * A first or last (ie. not middle) descriptor must request HMAC.
+ */
+ if (ctx->keylen && ((req_ctx->first_desc && edesc->first) ||
+ (req_ctx->last_request && edesc->last)))
+ edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
+
+ /* clear the DN bit */
+ if (is_sec1 && !edesc->last)
+ edesc->desc.hdr &= ~DESC_HDR_DONE_NOTIFY;
+
+ common_nonsnoop_hash(edesc, areq, to_hash_this_desc);
+
+ offset += to_hash_this_desc;
+ nbytes -= to_hash_this_desc;
+
+ if (!prev_edesc)
+ first = edesc;
+ else
+ prev_edesc->next_desc = edesc;
+ prev_edesc = edesc;
+ } while (nbytes);
+
+ return first;
+}
+
static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
@@ -1976,14 +2033,16 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
struct talitos_edesc *edesc;
unsigned int blocksize =
crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+ bool is_sec1 = has_ftr_sec1(dev_get_drvdata(ctx->dev));
unsigned int nbytes_to_hash;
unsigned int to_hash_later;
unsigned int nsg;
int nents;
struct device *dev = ctx->dev;
u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
+ int ret;
- if (!req_ctx->last_desc && (nbytes + req_ctx->nbuf <= blocksize)) {
+ if (!req_ctx->last_request && (nbytes + req_ctx->nbuf <= blocksize)) {
/* Buffer up to one whole block */
nents = sg_nents_for_len(req_ctx->request_sl, nbytes);
if (nents < 0) {
@@ -2000,7 +2059,7 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
nbytes_to_hash = nbytes + req_ctx->nbuf;
to_hash_later = nbytes_to_hash & (blocksize - 1);
- if (req_ctx->last_desc)
+ if (req_ctx->last_request)
to_hash_later = 0;
else if (to_hash_later)
/* There is a partial block. Hash the full block(s) now */
@@ -2035,30 +2094,16 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
}
req_ctx->to_hash_later = to_hash_later;
- /* Allocate extended descriptor */
- edesc = ahash_edesc_alloc(req_ctx->areq, nbytes_to_hash);
+ edesc = ahash_process_req_prepare(areq, nbytes_to_hash, blocksize,
+ is_sec1);
if (IS_ERR(edesc))
return PTR_ERR(edesc);
- edesc->desc.hdr = ctx->desc_hdr_template;
-
- /* On last one, request SEC to pad; otherwise continue */
- if (req_ctx->last_desc)
- edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD;
- else
- edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT;
-
- /* request SEC to INIT hash. */
- if (req_ctx->first_desc && !req_ctx->swinit)
- edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT;
-
- /* When the tfm context has a keylen, it's an HMAC.
- * A first or last (ie. not middle) descriptor must request HMAC.
- */
- if (ctx->keylen && (req_ctx->first_desc || req_ctx->last_desc))
- edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC;
+ ret = talitos_submit(dev, ctx->ch, &edesc->desc, ahash_done, areq);
+ if (ret != -EINPROGRESS)
+ free_edesc_list_from(areq, edesc);
- return common_nonsnoop_hash(edesc, req_ctx->areq, nbytes_to_hash, ahash_done);
+ return ret;
}
static void sec1_ahash_process_remaining(struct work_struct *work)
@@ -2102,16 +2147,13 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes)
req_ctx->remaining_ahash_request_bytes = nbytes;
if (is_sec1) {
- if (nbytes > TALITOS1_MAX_DATA_LEN)
- nbytes = TALITOS1_MAX_DATA_LEN;
- else if (req_ctx->last_request)
+ if (req_ctx->last_request)
req_ctx->last_desc = 1;
}
req_ctx->current_ahash_request_bytes = nbytes;
- return ahash_process_req_one(req_ctx->areq,
- req_ctx->current_ahash_request_bytes);
+ return ahash_process_req_one(req_ctx->areq, nbytes);
}
static int ahash_init(struct ahash_request *areq)
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 596f96bba3ef..11f0eb6a41db 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -44,6 +44,11 @@ struct talitos_desc {
/*
* talitos_edesc - s/w-extended descriptor
+ * @bufsl: scatterlist buffer
+ * @src: pointer to input scatterlist
+ * @first: first descriptor of a chain
+ * @last: last descriptor of a chain
+ *
* @src_nents: number of segments in input scatterlist
* @dst_nents: number of segments in output scatterlist
* @iv_dma: dma address of iv for checking continuity and link table
@@ -59,6 +64,11 @@ struct talitos_desc {
* of link_tbl data
*/
struct talitos_edesc {
+ struct scatterlist bufsl[2];
+ struct scatterlist *src;
+ int first;
+ int last;
+
int src_nents;
int dst_nents;
dma_addr_t iv_dma;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 06/11] crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Currently, when SEC1 has buffered data (nbuf != 0), the ahash code
creates an additional descriptor on the fly inside
common_nonsnoop_hash() to handle the remainder of the data. This
approach is incompatible with the arbitrary-length descriptor chaining
that follows.
Remove the "additional descriptor" logic from common_nonsnoop_hash()
and common_nonsnoop_hash_unmap().
Also remove the nbytes adjustment for SEC1 in ahash_edesc_alloc()
that subtracted nbuf.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 101 +++--------------------------------------------
1 file changed, 6 insertions(+), 95 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b808833d18ef..0184982cb39b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1788,15 +1788,9 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
struct talitos_desc *desc = &edesc->desc;
- struct talitos_desc *desc2;
-
- if (desc->next_desc)
- desc2 = &edesc->next_desc->desc;
unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
- if (desc->next_desc &&
- desc->ptr[5].ptr != desc2->ptr[5].ptr)
- unmap_single_talitos_ptr(dev, &desc2->ptr[5], DMA_FROM_DEVICE);
+
if (req_ctx->last_desc)
memcpy(areq->result, req_ctx->hw_context,
crypto_ahash_digestsize(tfm));
@@ -1808,13 +1802,6 @@ static void common_nonsnoop_hash_unmap(struct device *dev,
if (from_talitos_ptr_len(&desc->ptr[1], is_sec1))
unmap_single_talitos_ptr(dev, &desc->ptr[1],
DMA_TO_DEVICE);
- else if (desc->next_desc)
- unmap_single_talitos_ptr(dev, &desc2->ptr[1],
- DMA_TO_DEVICE);
-
- if (is_sec1 && req_ctx->nbuf)
- unmap_single_talitos_ptr(dev, &desc->ptr[3],
- DMA_TO_DEVICE);
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -1922,9 +1909,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
to_talitos_ptr(&desc->ptr[2], ctx->dma_key, ctx->keylen,
is_sec1);
- if (is_sec1 && req_ctx->nbuf)
- length -= req_ctx->nbuf;
-
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
@@ -1934,16 +1918,10 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
/*
* data in
*/
- if (is_sec1 && req_ctx->nbuf) {
- map_single_talitos_ptr(dev, &desc->ptr[3], req_ctx->nbuf,
- req_ctx->buf[req_ctx->buf_idx],
- DMA_TO_DEVICE);
- } else {
- sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
- &desc->ptr[3], sg_count, 0, 0);
- if (sg_count > 1)
- sync_needed = true;
- }
+ sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
+ &desc->ptr[3], sg_count, 0, 0);
+ if (sg_count > 1)
+ sync_needed = true;
/* fifth DWORD empty */
@@ -1963,49 +1941,6 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc,
if (is_sec1 && from_talitos_ptr_len(&desc->ptr[3], true) == 0)
talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
- if (is_sec1 && req_ctx->nbuf && length) {
- struct talitos_edesc *edesc2;
- struct talitos_desc *desc2;
-
- edesc2 = kzalloc(sizeof(*edesc2),
- areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
- GFP_KERNEL :
- GFP_ATOMIC);
- if (!edesc2) {
- ret = -ENOMEM;
- goto err;
- }
- edesc->next_desc = edesc2;
-
- desc2 = &edesc2->desc;
-
- desc2->hdr = desc->hdr;
- desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
- desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
- desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
- desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
-
- if (desc->ptr[1].ptr)
- copy_talitos_ptr(&desc2->ptr[1], &desc->ptr[1],
- is_sec1);
- else
- map_single_talitos_ptr_nosync(dev, &desc2->ptr[1],
- req_ctx->hw_context_size,
- req_ctx->hw_context,
- DMA_TO_DEVICE);
- copy_talitos_ptr(&desc2->ptr[2], &desc->ptr[2], is_sec1);
- sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
- &desc2->ptr[3], sg_count, 0, 0);
- if (sg_count > 1)
- sync_needed = true;
- copy_talitos_ptr(&desc2->ptr[5], &desc->ptr[5], is_sec1);
- if (req_ctx->last_desc)
- map_single_talitos_ptr_nosync(dev, &desc->ptr[5],
- req_ctx->hw_context_size,
- req_ctx->hw_context,
- DMA_FROM_DEVICE);
- }
-
if (sync_needed)
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);
@@ -2028,11 +1963,6 @@ static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq,
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
- struct talitos_private *priv = dev_get_drvdata(ctx->dev);
- bool is_sec1 = has_ftr_sec1(priv);
-
- if (is_sec1)
- nbytes -= req_ctx->nbuf;
return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, NULL, 0,
nbytes, 0, 0, 0, areq->base.flags, false);
@@ -2051,8 +1981,6 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
unsigned int nsg;
int nents;
struct device *dev = ctx->dev;
- struct talitos_private *priv = dev_get_drvdata(dev);
- bool is_sec1 = has_ftr_sec1(priv);
u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
if (!req_ctx->last_desc && (nbytes + req_ctx->nbuf <= blocksize)) {
@@ -2084,30 +2012,13 @@ static int ahash_process_req_one(struct ahash_request *areq, unsigned int nbytes
}
/* Chain in any previously buffered data */
- if (!is_sec1 && req_ctx->nbuf) {
+ if (req_ctx->nbuf) {
nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
sg_init_table(req_ctx->bufsl, nsg);
sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
if (nsg > 1)
sg_chain(req_ctx->bufsl, 2, req_ctx->request_sl);
req_ctx->psrc = req_ctx->bufsl;
- } else if (is_sec1 && req_ctx->nbuf && req_ctx->nbuf < blocksize) {
- int offset;
-
- if (nbytes_to_hash > blocksize)
- offset = blocksize - req_ctx->nbuf;
- else
- offset = nbytes_to_hash - req_ctx->nbuf;
- nents = sg_nents_for_len(req_ctx->request_sl, offset);
- if (nents < 0) {
- dev_err(dev, "Invalid number of src SG.\n");
- return nents;
- }
- sg_copy_to_buffer(req_ctx->request_sl, nents,
- ctx_buf + req_ctx->nbuf, offset);
- req_ctx->nbuf += offset;
- req_ctx->psrc = scatterwalk_ffwd(req_ctx->bufsl, req_ctx->request_sl,
- offset);
} else
req_ctx->psrc = req_ctx->request_sl;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 05/11] crypto: talitos - move code in current_desc_hdr() into a standalone function
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Previously added code in current_desc_hdr() in order to add support for
searching an offending descriptor inside a descriptor chain.
Move that code into a standalone function to improve readability.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 183d51fa9a4a..b808833d18ef 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -520,6 +520,24 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
+static __be32 search_desc_hdr_in_request(struct talitos_request *request,
+ dma_addr_t cur_desc, bool is_sec1)
+{
+ struct talitos_edesc *edesc;
+
+ if (request->dma_desc == cur_desc) {
+ return request->desc->hdr;
+ } else if (is_sec1) {
+ edesc = container_of(request->desc, struct talitos_edesc, desc);
+ while (edesc->next_desc) {
+ if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
+ return edesc->next_desc->desc.hdr1;
+ edesc = edesc->next_desc;
+ }
+ }
+ return 0;
+}
+
/*
* locate current (offending) descriptor
*/
@@ -528,7 +546,6 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
struct talitos_request *request;
- struct talitos_edesc *edesc;
int tail, iter;
dma_addr_t cur_desc;
__be32 hdr = 0;
@@ -546,21 +563,7 @@ static __be32 current_desc_hdr(struct device *dev, int ch)
do {
request = &priv->chan[ch].fifo[iter];
- if (request->dma_desc == cur_desc) {
- hdr = request->desc->hdr;
- } else if (is_sec1) {
- edesc = container_of(request->desc,
- struct talitos_edesc, desc);
- while (edesc->next_desc) {
- if (edesc->desc.next_desc ==
- cpu_to_be32(cur_desc)) {
- hdr = edesc->next_desc->desc.hdr1;
- break;
- }
- edesc = edesc->next_desc;
- }
- }
-
+ hdr = search_desc_hdr_in_request(request, cur_desc, is_sec1);
if (hdr)
break;
--
2.54.0
^ permalink raw reply related
* [PATCH v3 04/11] crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
From: Paul Louvel @ 2026-05-07 14:41 UTC (permalink / raw)
To: Herbert Xu, David S. Miller, Paolo Abeni, David Howells,
Kim Phillips, Christophe Leroy
Cc: linux-crypto, linux-kernel, Thomas Petazzoni, Herve Codina,
Paul Louvel, stable
In-Reply-To: <20260507-bootlin_test-7-1-rc1_sec_bugfix-v3-0-c98d7589b942@bootlin.com>
Previously added code to talitos_submit() in order to map an entire
descriptor chain.
Move that code into a standalone function to improve readability.
Cc: stable@vger.kernel.org
Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
---
drivers/crypto/talitos.c | 75 ++++++++++++++++++++++++++----------------------
1 file changed, 41 insertions(+), 34 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a98b40f566dd..183d51fa9a4a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -255,6 +255,46 @@ static int init_device(struct device *dev)
return 0;
}
+static void dma_map_request(struct device *dev, struct talitos_request *request,
+ struct talitos_desc *desc, bool is_sec1)
+{
+ struct talitos_edesc *edesc =
+ container_of(desc, struct talitos_edesc, desc);
+ dma_addr_t dma_desc, prev_dma_desc;
+ struct talitos_edesc *prev_edesc = NULL;
+
+ if (is_sec1) {
+ while (edesc) {
+ edesc->desc.hdr1 = edesc->desc.hdr;
+
+ dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
+ TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ if (!prev_edesc) {
+ request->dma_desc = dma_desc;
+ goto next;
+ }
+
+ /* Chain in any previous descriptors. */
+
+ prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
+
+ dma_sync_single_for_device(dev, prev_dma_desc,
+ TALITOS_DESC_SIZE,
+ DMA_TO_DEVICE);
+
+next:
+ prev_edesc = edesc;
+ prev_dma_desc = dma_desc;
+ edesc = edesc->next_desc;
+ }
+ } else {
+ request->dma_desc = dma_map_single(dev, desc, TALITOS_DESC_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
+}
+
/**
* talitos_submit - submits a descriptor to the device for processing
* @dev: the SEC device to be used
@@ -273,10 +313,7 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
void *context, int error),
void *context)
{
- struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
struct talitos_private *priv = dev_get_drvdata(dev);
- dma_addr_t dma_desc, prev_dma_desc;
- struct talitos_edesc *prev_edesc = NULL;
struct talitos_request *request;
unsigned long flags;
int head;
@@ -294,37 +331,7 @@ static int talitos_submit(struct device *dev, int ch, struct talitos_desc *desc,
request = &priv->chan[ch].fifo[head];
/* map descriptor and save caller data */
- if (is_sec1) {
- while (edesc) {
- edesc->desc.hdr1 = edesc->desc.hdr;
-
- dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
-
- if (!prev_edesc) {
- request->dma_desc = dma_desc;
- goto next;
- }
-
- /* Chain in any previous descriptors. */
-
- prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
-
- dma_sync_single_for_device(dev, prev_dma_desc,
- TALITOS_DESC_SIZE,
- DMA_TO_DEVICE);
-
-next:
- prev_edesc = edesc;
- prev_dma_desc = dma_desc;
- edesc = edesc->next_desc;
- }
- } else {
- request->dma_desc = dma_map_single(dev, desc,
- TALITOS_DESC_SIZE,
- DMA_BIDIRECTIONAL);
- }
+ dma_map_request(dev, request, desc, is_sec1);
request->callback = callback;
request->context = context;
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox