Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,19 @@
config CRYPTO_DEV_IAA_CRYPTO
tristate "Support for Intel(R) IAA Compression Accelerator"
depends on CRYPTO_DEFLATE
depends on INTEL_IDXD
default n
help
This driver supports acceleration for compression and
decompression with the Intel Analytics Accelerator (IAA)
hardware using the cryptographic API. If you choose 'M'
here, the module will be called iaa_crypto.
config CRYPTO_DEV_IAA_CRYPTO_STATS
bool "Enable Intel(R) IAA Compression Accelerator Statistics"
depends on CRYPTO_DEV_IAA_CRYPTO
default n
help
Enable statistics for the IAA compression accelerator.
These include per-device and per-workqueue statistics in
addition to global driver statistics.
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for IAA crypto device drivers
#
ccflags-y += -I $(srctree)/drivers/dma/idxd -DDEFAULT_SYMBOL_NAMESPACE='"IDXD"'
obj-$(CONFIG_CRYPTO_DEV_IAA_CRYPTO) := iaa_crypto.o
iaa_crypto-y := iaa_crypto_main.o iaa_crypto_comp_fixed.o
iaa_crypto-$(CONFIG_CRYPTO_DEV_IAA_CRYPTO_STATS) += iaa_crypto_stats.o
@@ -0,0 +1,148 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
#ifndef __IAA_CRYPTO_H__
#define __IAA_CRYPTO_H__
#include <linux/crypto.h>
#include <linux/idxd.h>
#include <uapi/linux/idxd.h>
#define IDXD_SUBDRIVER_NAME "crypto"
#define IAA_DECOMP_ENABLE BIT(0)
#define IAA_DECOMP_FLUSH_OUTPUT BIT(1)
#define IAA_DECOMP_CHECK_FOR_EOB BIT(2)
#define IAA_DECOMP_STOP_ON_EOB BIT(3)
#define IAA_DECOMP_SUPPRESS_OUTPUT BIT(9)
#define IAA_COMP_FLUSH_OUTPUT BIT(1)
#define IAA_COMP_APPEND_EOB BIT(2)
#define IAA_COMPLETION_TIMEOUT 1000000
#define IAA_ANALYTICS_ERROR 0x0a
#define IAA_ERROR_DECOMP_BUF_OVERFLOW 0x0b
#define IAA_ERROR_COMP_BUF_OVERFLOW 0x19
#define IAA_ERROR_WATCHDOG_EXPIRED 0x24
#define IAA_COMP_MODES_MAX 2
#define FIXED_HDR 0x2
#define FIXED_HDR_SIZE 3
#define IAA_COMP_FLAGS (IAA_COMP_FLUSH_OUTPUT | \
IAA_COMP_APPEND_EOB)
#define IAA_DECOMP_FLAGS (IAA_DECOMP_ENABLE | \
IAA_DECOMP_FLUSH_OUTPUT | \
IAA_DECOMP_CHECK_FOR_EOB | \
IAA_DECOMP_STOP_ON_EOB)
/* Representation of IAA workqueue */
struct iaa_wq {
struct list_head list;
struct idxd_wq *wq;
int ref;
bool remove;
struct iaa_device *iaa_device;
atomic64_t comp_calls;
atomic64_t comp_bytes;
atomic64_t decomp_calls;
atomic64_t decomp_bytes;
};
struct iaa_device_compression_mode {
const char *name;
struct aecs_comp_table_record *aecs_comp_table;
dma_addr_t aecs_comp_table_dma_addr;
};
/* Representation of IAA device with wqs, populated by probe */
struct iaa_device {
struct list_head list;
struct idxd_device *idxd;
struct iaa_device_compression_mode *compression_modes[IAA_COMP_MODES_MAX];
int n_wq;
struct list_head wqs;
atomic64_t comp_calls;
atomic64_t comp_bytes;
atomic64_t decomp_calls;
atomic64_t decomp_bytes;
};
struct wq_table_entry {
struct idxd_wq **wqs;
int max_wqs;
int n_wqs;
int cur_wq;
};
#define IAA_AECS_ALIGN 32
/*
* Analytics Engine Configuration and State (AECS) contains parameters and
* internal state of the analytics engine.
*/
struct aecs_comp_table_record {
u32 crc;
u32 xor_checksum;
u32 reserved0[5];
u32 num_output_accum_bits;
u8 output_accum[256];
u32 ll_sym[286];
u32 reserved1;
u32 reserved2;
u32 d_sym[30];
u32 reserved_padding[2];
} __packed;
int iaa_aecs_init_fixed(void);
void iaa_aecs_cleanup_fixed(void);
typedef int (*iaa_dev_comp_init_fn_t) (struct iaa_device_compression_mode *mode);
typedef int (*iaa_dev_comp_free_fn_t) (struct iaa_device_compression_mode *mode);
struct iaa_compression_mode {
const char *name;
u32 *ll_table;
int ll_table_size;
u32 *d_table;
int d_table_size;
iaa_dev_comp_init_fn_t init;
iaa_dev_comp_free_fn_t free;
};
int add_iaa_compression_mode(const char *name,
const u32 *ll_table,
int ll_table_size,
const u32 *d_table,
int d_table_size,
iaa_dev_comp_init_fn_t init,
iaa_dev_comp_free_fn_t free);
void remove_iaa_compression_mode(const char *name);
enum iaa_mode {
IAA_MODE_FIXED,
};
struct iaa_compression_ctx {
enum iaa_mode mode;
bool verify_compress;
bool async_mode;
bool use_irq;
};
extern struct list_head iaa_devices;
extern struct mutex iaa_devices_lock;
#endif
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
#include "idxd.h"
#include "iaa_crypto.h"
/*
* Fixed Huffman tables the IAA hardware requires to implement RFC-1951.
*/
static const u32 fixed_ll_sym[286] = {
0x40030, 0x40031, 0x40032, 0x40033, 0x40034, 0x40035, 0x40036, 0x40037,
0x40038, 0x40039, 0x4003A, 0x4003B, 0x4003C, 0x4003D, 0x4003E, 0x4003F,
0x40040, 0x40041, 0x40042, 0x40043, 0x40044, 0x40045, 0x40046, 0x40047,
0x40048, 0x40049, 0x4004A, 0x4004B, 0x4004C, 0x4004D, 0x4004E, 0x4004F,
0x40050, 0x40051, 0x40052, 0x40053, 0x40054, 0x40055, 0x40056, 0x40057,
0x40058, 0x40059, 0x4005A, 0x4005B, 0x4005C, 0x4005D, 0x4005E, 0x4005F,
0x40060, 0x40061, 0x40062, 0x40063, 0x40064, 0x40065, 0x40066, 0x40067,
0x40068, 0x40069, 0x4006A, 0x4006B, 0x4006C, 0x4006D, 0x4006E, 0x4006F,
0x40070, 0x40071, 0x40072, 0x40073, 0x40074, 0x40075, 0x40076, 0x40077,
0x40078, 0x40079, 0x4007A, 0x4007B, 0x4007C, 0x4007D, 0x4007E, 0x4007F,
0x40080, 0x40081, 0x40082, 0x40083, 0x40084, 0x40085, 0x40086, 0x40087,
0x40088, 0x40089, 0x4008A, 0x4008B, 0x4008C, 0x4008D, 0x4008E, 0x4008F,
0x40090, 0x40091, 0x40092, 0x40093, 0x40094, 0x40095, 0x40096, 0x40097,
0x40098, 0x40099, 0x4009A, 0x4009B, 0x4009C, 0x4009D, 0x4009E, 0x4009F,
0x400A0, 0x400A1, 0x400A2, 0x400A3, 0x400A4, 0x400A5, 0x400A6, 0x400A7,
0x400A8, 0x400A9, 0x400AA, 0x400AB, 0x400AC, 0x400AD, 0x400AE, 0x400AF,
0x400B0, 0x400B1, 0x400B2, 0x400B3, 0x400B4, 0x400B5, 0x400B6, 0x400B7,
0x400B8, 0x400B9, 0x400BA, 0x400BB, 0x400BC, 0x400BD, 0x400BE, 0x400BF,
0x48190, 0x48191, 0x48192, 0x48193, 0x48194, 0x48195, 0x48196, 0x48197,
0x48198, 0x48199, 0x4819A, 0x4819B, 0x4819C, 0x4819D, 0x4819E, 0x4819F,
0x481A0, 0x481A1, 0x481A2, 0x481A3, 0x481A4, 0x481A5, 0x481A6, 0x481A7,
0x481A8, 0x481A9, 0x481AA, 0x481AB, 0x481AC, 0x481AD, 0x481AE, 0x481AF,
0x481B0, 0x481B1, 0x481B2, 0x481B3, 0x481B4, 0x481B5, 0x481B6, 0x481B7,
0x481B8, 0x481B9, 0x481BA, 0x481BB, 0x481BC, 0x481BD, 0x481BE, 0x481BF,
0x481C0, 0x481C1, 0x481C2, 0x481C3, 0x481C4, 0x481C5, 0x481C6, 0x481C7,
0x481C8, 0x481C9, 0x481CA, 0x481CB, 0x481CC, 0x481CD, 0x481CE, 0x481CF,
0x481D0, 0x481D1, 0x481D2, 0x481D3, 0x481D4, 0x481D5, 0x481D6, 0x481D7,
0x481D8, 0x481D9, 0x481DA, 0x481DB, 0x481DC, 0x481DD, 0x481DE, 0x481DF,
0x481E0, 0x481E1, 0x481E2, 0x481E3, 0x481E4, 0x481E5, 0x481E6, 0x481E7,
0x481E8, 0x481E9, 0x481EA, 0x481EB, 0x481EC, 0x481ED, 0x481EE, 0x481EF,
0x481F0, 0x481F1, 0x481F2, 0x481F3, 0x481F4, 0x481F5, 0x481F6, 0x481F7,
0x481F8, 0x481F9, 0x481FA, 0x481FB, 0x481FC, 0x481FD, 0x481FE, 0x481FF,
0x38000, 0x38001, 0x38002, 0x38003, 0x38004, 0x38005, 0x38006, 0x38007,
0x38008, 0x38009, 0x3800A, 0x3800B, 0x3800C, 0x3800D, 0x3800E, 0x3800F,
0x38010, 0x38011, 0x38012, 0x38013, 0x38014, 0x38015, 0x38016, 0x38017,
0x400C0, 0x400C1, 0x400C2, 0x400C3, 0x400C4, 0x400C5
};
static const u32 fixed_d_sym[30] = {
0x28000, 0x28001, 0x28002, 0x28003, 0x28004, 0x28005, 0x28006, 0x28007,
0x28008, 0x28009, 0x2800A, 0x2800B, 0x2800C, 0x2800D, 0x2800E, 0x2800F,
0x28010, 0x28011, 0x28012, 0x28013, 0x28014, 0x28015, 0x28016, 0x28017,
0x28018, 0x28019, 0x2801A, 0x2801B, 0x2801C, 0x2801D
};
static int init_fixed_mode(struct iaa_device_compression_mode *mode)
{
struct aecs_comp_table_record *comp_table = mode->aecs_comp_table;
u32 bfinal = 1;
u32 offset;
/* Configure aecs table using fixed Huffman table */
comp_table->crc = 0;
comp_table->xor_checksum = 0;
offset = comp_table->num_output_accum_bits / 8;
comp_table->output_accum[offset] = FIXED_HDR | bfinal;
comp_table->num_output_accum_bits = FIXED_HDR_SIZE;
return 0;
}
int iaa_aecs_init_fixed(void)
{
int ret;
ret = add_iaa_compression_mode("fixed",
fixed_ll_sym,
sizeof(fixed_ll_sym),
fixed_d_sym,
sizeof(fixed_d_sym),
init_fixed_mode, NULL);
if (!ret)
pr_debug("IAA fixed compression mode initialized\n");
return ret;
}
void iaa_aecs_cleanup_fixed(void)
{
remove_iaa_compression_mode("fixed");
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,280 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/highmem.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <uapi/linux/idxd.h>
#include <linux/idxd.h>
#include <linux/dmaengine.h>
#include "../../dma/idxd/idxd.h"
#include <linux/debugfs.h>
#include <crypto/internal/acompress.h>
#include "iaa_crypto.h"
#include "iaa_crypto_stats.h"
static atomic64_t total_comp_calls;
static atomic64_t total_decomp_calls;
static atomic64_t total_sw_comp_calls;
static atomic64_t total_sw_decomp_calls;
static atomic64_t total_comp_bytes_out;
static atomic64_t total_decomp_bytes_in;
static atomic64_t total_completion_einval_errors;
static atomic64_t total_completion_timeout_errors;
static atomic64_t total_completion_comp_buf_overflow_errors;
static struct dentry *iaa_crypto_debugfs_root;
void update_total_comp_calls(void)
{
atomic64_inc(&total_comp_calls);
}
void update_total_comp_bytes_out(int n)
{
atomic64_add(n, &total_comp_bytes_out);
}
void update_total_decomp_calls(void)
{
atomic64_inc(&total_decomp_calls);
}
void update_total_sw_comp_calls(void)
{
atomic64_inc(&total_sw_comp_calls);
}
void update_total_sw_decomp_calls(void)
{
atomic64_inc(&total_sw_decomp_calls);
}
void update_total_decomp_bytes_in(int n)
{
atomic64_add(n, &total_decomp_bytes_in);
}
void update_completion_einval_errs(void)
{
atomic64_inc(&total_completion_einval_errors);
}
void update_completion_timeout_errs(void)
{
atomic64_inc(&total_completion_timeout_errors);
}
void update_completion_comp_buf_overflow_errs(void)
{
atomic64_inc(&total_completion_comp_buf_overflow_errors);
}
void update_wq_comp_calls(struct idxd_wq *idxd_wq)
{
struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
atomic64_inc(&wq->comp_calls);
atomic64_inc(&wq->iaa_device->comp_calls);
}
void update_wq_comp_bytes(struct idxd_wq *idxd_wq, int n)
{
struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
atomic64_add(n, &wq->comp_bytes);
atomic64_add(n, &wq->iaa_device->comp_bytes);
}
void update_wq_decomp_calls(struct idxd_wq *idxd_wq)
{
struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
atomic64_inc(&wq->decomp_calls);
atomic64_inc(&wq->iaa_device->decomp_calls);
}
void update_wq_decomp_bytes(struct idxd_wq *idxd_wq, int n)
{
struct iaa_wq *wq = idxd_wq_get_private(idxd_wq);
atomic64_add(n, &wq->decomp_bytes);
atomic64_add(n, &wq->iaa_device->decomp_bytes);
}
static void reset_iaa_crypto_stats(void)
{
atomic64_set(&total_comp_calls, 0);
atomic64_set(&total_decomp_calls, 0);
atomic64_set(&total_sw_comp_calls, 0);
atomic64_set(&total_sw_decomp_calls, 0);
atomic64_set(&total_comp_bytes_out, 0);
atomic64_set(&total_decomp_bytes_in, 0);
atomic64_set(&total_completion_einval_errors, 0);
atomic64_set(&total_completion_timeout_errors, 0);
atomic64_set(&total_completion_comp_buf_overflow_errors, 0);
}
static void reset_wq_stats(struct iaa_wq *wq)
{
atomic64_set(&wq->comp_calls, 0);
atomic64_set(&wq->comp_bytes, 0);
atomic64_set(&wq->decomp_calls, 0);
atomic64_set(&wq->decomp_bytes, 0);
}
static void reset_device_stats(struct iaa_device *iaa_device)
{
struct iaa_wq *iaa_wq;
atomic64_set(&iaa_device->comp_calls, 0);
atomic64_set(&iaa_device->comp_bytes, 0);
atomic64_set(&iaa_device->decomp_calls, 0);
atomic64_set(&iaa_device->decomp_bytes, 0);
list_for_each_entry(iaa_wq, &iaa_device->wqs, list)
reset_wq_stats(iaa_wq);
}
static void wq_show(struct seq_file *m, struct iaa_wq *iaa_wq)
{
seq_printf(m, " name: %s\n", iaa_wq->wq->name);
seq_printf(m, " comp_calls: %llu\n",
atomic64_read(&iaa_wq->comp_calls));
seq_printf(m, " comp_bytes: %llu\n",
atomic64_read(&iaa_wq->comp_bytes));
seq_printf(m, " decomp_calls: %llu\n",
atomic64_read(&iaa_wq->decomp_calls));
seq_printf(m, " decomp_bytes: %llu\n\n",
atomic64_read(&iaa_wq->decomp_bytes));
}
static void device_stats_show(struct seq_file *m, struct iaa_device *iaa_device)
{
struct iaa_wq *iaa_wq;
seq_puts(m, "iaa device:\n");
seq_printf(m, " id: %d\n", iaa_device->idxd->id);
seq_printf(m, " n_wqs: %d\n", iaa_device->n_wq);
seq_printf(m, " comp_calls: %llu\n",
atomic64_read(&iaa_device->comp_calls));
seq_printf(m, " comp_bytes: %llu\n",
atomic64_read(&iaa_device->comp_bytes));
seq_printf(m, " decomp_calls: %llu\n",
atomic64_read(&iaa_device->decomp_calls));
seq_printf(m, " decomp_bytes: %llu\n",
atomic64_read(&iaa_device->decomp_bytes));
seq_puts(m, " wqs:\n");
list_for_each_entry(iaa_wq, &iaa_device->wqs, list)
wq_show(m, iaa_wq);
}
static int global_stats_show(struct seq_file *m, void *v)
{
seq_puts(m, "global stats:\n");
seq_printf(m, " total_comp_calls: %llu\n",
atomic64_read(&total_comp_calls));
seq_printf(m, " total_decomp_calls: %llu\n",
atomic64_read(&total_decomp_calls));
seq_printf(m, " total_sw_comp_calls: %llu\n",
atomic64_read(&total_sw_comp_calls));
seq_printf(m, " total_sw_decomp_calls: %llu\n",
atomic64_read(&total_sw_decomp_calls));
seq_printf(m, " total_comp_bytes_out: %llu\n",
atomic64_read(&total_comp_bytes_out));
seq_printf(m, " total_decomp_bytes_in: %llu\n",
atomic64_read(&total_decomp_bytes_in));
seq_printf(m, " total_completion_einval_errors: %llu\n",
atomic64_read(&total_completion_einval_errors));
seq_printf(m, " total_completion_timeout_errors: %llu\n",
atomic64_read(&total_completion_timeout_errors));
seq_printf(m, " total_completion_comp_buf_overflow_errors: %llu\n\n",
atomic64_read(&total_completion_comp_buf_overflow_errors));
return 0;
}
static int wq_stats_show(struct seq_file *m, void *v)
{
struct iaa_device *iaa_device;
mutex_lock(&iaa_devices_lock);
list_for_each_entry(iaa_device, &iaa_devices, list)
device_stats_show(m, iaa_device);
mutex_unlock(&iaa_devices_lock);
return 0;
}
static int iaa_crypto_stats_reset(void *data, u64 value)
{
struct iaa_device *iaa_device;
reset_iaa_crypto_stats();
mutex_lock(&iaa_devices_lock);
list_for_each_entry(iaa_device, &iaa_devices, list)
reset_device_stats(iaa_device);
mutex_unlock(&iaa_devices_lock);
return 0;
}
static int wq_stats_open(struct inode *inode, struct file *file)
{
return single_open(file, wq_stats_show, file);
}
static const struct file_operations wq_stats_fops = {
.open = wq_stats_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int global_stats_open(struct inode *inode, struct file *file)
{
return single_open(file, global_stats_show, file);
}
static const struct file_operations global_stats_fops = {
.open = global_stats_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
DEFINE_DEBUGFS_ATTRIBUTE(wq_stats_reset_fops, NULL, iaa_crypto_stats_reset, "%llu\n");
int __init iaa_crypto_debugfs_init(void)
{
if (!debugfs_initialized())
return -ENODEV;
iaa_crypto_debugfs_root = debugfs_create_dir("iaa_crypto", NULL);
debugfs_create_file("global_stats", 0644, iaa_crypto_debugfs_root, NULL,
&global_stats_fops);
debugfs_create_file("wq_stats", 0644, iaa_crypto_debugfs_root, NULL,
&wq_stats_fops);
debugfs_create_file("stats_reset", 0644, iaa_crypto_debugfs_root, NULL,
&wq_stats_reset_fops);
return 0;
}
void __exit iaa_crypto_debugfs_cleanup(void)
{
debugfs_remove_recursive(iaa_crypto_debugfs_root);
}
MODULE_LICENSE("GPL");
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
#ifndef __CRYPTO_DEV_IAA_CRYPTO_STATS_H__
#define __CRYPTO_DEV_IAA_CRYPTO_STATS_H__
#if defined(CONFIG_CRYPTO_DEV_IAA_CRYPTO_STATS)
int iaa_crypto_debugfs_init(void);
void iaa_crypto_debugfs_cleanup(void);
void update_total_comp_calls(void);
void update_total_comp_bytes_out(int n);
void update_total_decomp_calls(void);
void update_total_sw_comp_calls(void);
void update_total_sw_decomp_calls(void);
void update_total_decomp_bytes_in(int n);
void update_completion_einval_errs(void);
void update_completion_timeout_errs(void);
void update_completion_comp_buf_overflow_errs(void);
void update_wq_comp_calls(struct idxd_wq *idxd_wq);
void update_wq_comp_bytes(struct idxd_wq *idxd_wq, int n);
void update_wq_decomp_calls(struct idxd_wq *idxd_wq);
void update_wq_decomp_bytes(struct idxd_wq *idxd_wq, int n);
#else
static inline int iaa_crypto_debugfs_init(void) { return 0; }
static inline void iaa_crypto_debugfs_cleanup(void) {}
static inline void update_total_comp_calls(void) {}
static inline void update_total_comp_bytes_out(int n) {}
static inline void update_total_decomp_calls(void) {}
static inline void update_total_sw_comp_calls(void) {}
static inline void update_total_sw_decomp_calls(void) {}
static inline void update_total_decomp_bytes_in(int n) {}
static inline void update_completion_einval_errs(void) {}
static inline void update_completion_timeout_errs(void) {}
static inline void update_completion_comp_buf_overflow_errs(void) {}
static inline void update_wq_comp_calls(struct idxd_wq *idxd_wq) {}
static inline void update_wq_comp_bytes(struct idxd_wq *idxd_wq, int n) {}
static inline void update_wq_decomp_calls(struct idxd_wq *idxd_wq) {}
static inline void update_wq_decomp_bytes(struct idxd_wq *idxd_wq, int n) {}
#endif // CONFIG_CRYPTO_DEV_IAA_CRYPTO_STATS
#endif