lib/crc/riscv/crc-clmul-template.h

Source file repositories/reference/linux-study-clean/lib/crc/riscv/crc-clmul-template.h

File Facts

System
Linux kernel
Corpus path
lib/crc/riscv/crc-clmul-template.h
Extension
.h
Size
8580 bytes
Lines
266
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <asm/byteorder.h>
#include <linux/minmax.h>

#define CRC_BITS	(8 * sizeof(crc_t))	/* a.k.a. 'n' */

static inline unsigned long clmul(unsigned long a, unsigned long b)
{
	unsigned long res;

	asm(".option push\n"
	    ".option arch,+zbc\n"
	    "clmul %0, %1, %2\n"
	    ".option pop\n"
	    : "=r" (res) : "r" (a), "r" (b));
	return res;
}

static inline unsigned long clmulh(unsigned long a, unsigned long b)
{
	unsigned long res;

	asm(".option push\n"
	    ".option arch,+zbc\n"
	    "clmulh %0, %1, %2\n"
	    ".option pop\n"
	    : "=r" (res) : "r" (a), "r" (b));
	return res;
}

static inline unsigned long clmulr(unsigned long a, unsigned long b)
{
	unsigned long res;

	asm(".option push\n"
	    ".option arch,+zbc\n"
	    "clmulr %0, %1, %2\n"
	    ".option pop\n"
	    : "=r" (res) : "r" (a), "r" (b));
	return res;
}

/*
 * crc_load_long() loads one "unsigned long" of aligned data bytes, producing a
 * polynomial whose bit order matches the CRC's bit order.
 */
#ifdef CONFIG_64BIT
#  if LSB_CRC
#    define crc_load_long(x)	le64_to_cpup(x)
#  else
#    define crc_load_long(x)	be64_to_cpup(x)
#  endif
#else
#  if LSB_CRC
#    define crc_load_long(x)	le32_to_cpup(x)
#  else
#    define crc_load_long(x)	be32_to_cpup(x)
#  endif
#endif

/* XOR @crc into the end of @msgpoly that represents the high-order terms. */
static inline unsigned long
crc_clmul_prep(crc_t crc, unsigned long msgpoly)
{
#if LSB_CRC
	return msgpoly ^ crc;
#else
	return msgpoly ^ ((unsigned long)crc << (BITS_PER_LONG - CRC_BITS));
#endif
}

/*
 * Multiply the long-sized @msgpoly by x^n (a.k.a. x^CRC_BITS) and reduce it
 * modulo the generator polynomial G.  This gives the CRC of @msgpoly.
 */
static inline crc_t
crc_clmul_long(unsigned long msgpoly, const struct crc_clmul_consts *consts)
{
	unsigned long tmp;

	/*
	 * First step of Barrett reduction with integrated multiplication by
	 * x^n: calculate floor((msgpoly * x^n) / G).  This is the value by
	 * which G needs to be multiplied to cancel out the x^n and higher terms
	 * of msgpoly * x^n.  Do it using the following formula:
	 *
	 * msb-first:
	 *    floor((msgpoly * floor(x^(BITS_PER_LONG-1+n) / G)) / x^(BITS_PER_LONG-1))
	 * lsb-first:
	 *    floor((msgpoly * floor(x^(BITS_PER_LONG-1+n) / G) * x) / x^BITS_PER_LONG)
	 *

Annotation

Implementation Notes