mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky:
"There are a couple of new things for s390 with this merge request:
- a new scheduling domain "drawer" is added to reflect the unusual
topology found on z13 machines. Performance tests showed up to 8
percent gain with the additional domain.
- the new crc-32 checksum crypto module uses the vector-galois-field
multiply and sum SIMD instruction to speed up crc-32 and crc-32c.
- proper __ro_after_init support, this requires RO_AFTER_INIT_DATA in
the generic vmlinux.lds linker script definitions.
- kcov instrumentation support. A prerequisite for that is the
inline assembly basic block cleanup, which is the reason for the
net/iucv/iucv.c change.
- support for 2GB pages is added to the hugetlbfs backend.
Then there are two removals:
- the oprofile hardware sampling support is dead code and is removed.
The oprofile user space uses the perf interface nowadays.
- the ETR clock synchronization is removed, this has been superseeded
be the STP clock synchronization. And it always has been
"interesting" code..
And the usual bug fixes and cleanups"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (82 commits)
s390/pci: Delete an unnecessary check before the function call "pci_dev_put"
s390/smp: clean up a condition
s390/cio/chp : Remove deprecated create_singlethread_workqueue
s390/chsc: improve channel path descriptor determination
s390/chsc: sanitize fmt check for chp_desc determination
s390/cio: make fmt1 channel path descriptor optional
s390/chsc: fix ioctl CHSC_INFO_CU command
s390/cio/device_ops: fix kernel doc
s390/cio: allow to reset channel measurement block
s390/console: Make preferred console handling more consistent
s390/mm: fix gmap tlb flush issues
s390/mm: add support for 2GB hugepages
s390: have unique symbol for __switch_to address
s390/cpuinfo: show maximum thread id
s390/ptrace: clarify bits in the per_struct
s390: stack address vs thread_info
s390: remove pointless load within __switch_to
s390: enable kcov support
s390/cpumf: use basic block for ecctr inline assembly
s390/hypfs: use basic block for diag inline assembly
...
This commit is contained in:
commit
015cd867e5
111 files changed
+2858
-3958
No files matched your search
@@ -20,48 +20,70 @@ to /proc/cpuinfo output of some architectures:
|
||||
identifier (rather than the kernel's). The actual value is
|
||||
architecture and platform dependent.
|
||||
|
||||
4) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
|
||||
4) /sys/devices/system/cpu/cpuX/topology/drawer_id:
|
||||
|
||||
the drawer ID of cpuX. Typically it is the hardware platform's
|
||||
identifier (rather than the kernel's). The actual value is
|
||||
architecture and platform dependent.
|
||||
|
||||
5) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
|
||||
|
||||
internal kernel map of cpuX's hardware threads within the same
|
||||
core as cpuX.
|
||||
|
||||
5) /sys/devices/system/cpu/cpuX/topology/thread_siblings_list:
|
||||
6) /sys/devices/system/cpu/cpuX/topology/thread_siblings_list:
|
||||
|
||||
human-readable list of cpuX's hardware threads within the same
|
||||
core as cpuX.
|
||||
|
||||
6) /sys/devices/system/cpu/cpuX/topology/core_siblings:
|
||||
7) /sys/devices/system/cpu/cpuX/topology/core_siblings:
|
||||
|
||||
internal kernel map of cpuX's hardware threads within the same
|
||||
physical_package_id.
|
||||
|
||||
7) /sys/devices/system/cpu/cpuX/topology/core_siblings_list:
|
||||
8) /sys/devices/system/cpu/cpuX/topology/core_siblings_list:
|
||||
|
||||
human-readable list of cpuX's hardware threads within the same
|
||||
physical_package_id.
|
||||
|
||||
8) /sys/devices/system/cpu/cpuX/topology/book_siblings:
|
||||
9) /sys/devices/system/cpu/cpuX/topology/book_siblings:
|
||||
|
||||
internal kernel map of cpuX's hardware threads within the same
|
||||
book_id.
|
||||
|
||||
9) /sys/devices/system/cpu/cpuX/topology/book_siblings_list:
|
||||
10) /sys/devices/system/cpu/cpuX/topology/book_siblings_list:
|
||||
|
||||
human-readable list of cpuX's hardware threads within the same
|
||||
book_id.
|
||||
|
||||
11) /sys/devices/system/cpu/cpuX/topology/drawer_siblings:
|
||||
|
||||
internal kernel map of cpuX's hardware threads within the same
|
||||
drawer_id.
|
||||
|
||||
12) /sys/devices/system/cpu/cpuX/topology/drawer_siblings_list:
|
||||
|
||||
human-readable list of cpuX's hardware threads within the same
|
||||
drawer_id.
|
||||
|
||||
To implement it in an architecture-neutral way, a new source file,
|
||||
drivers/base/topology.c, is to export the 6 or 9 attributes. The three book
|
||||
related sysfs files will only be created if CONFIG_SCHED_BOOK is selected.
|
||||
drivers/base/topology.c, is to export the 6 to 12 attributes. The book
|
||||
and drawer related sysfs files will only be created if CONFIG_SCHED_BOOK
|
||||
and CONFIG_SCHED_DRAWER are selected.
|
||||
|
||||
CONFIG_SCHED_BOOK and CONFIG_DRAWER are currently only used on s390, where
|
||||
they reflect the cpu and cache hierarchy.
|
||||
|
||||
For an architecture to support this feature, it must define some of
|
||||
these macros in include/asm-XXX/topology.h:
|
||||
#define topology_physical_package_id(cpu)
|
||||
#define topology_core_id(cpu)
|
||||
#define topology_book_id(cpu)
|
||||
#define topology_drawer_id(cpu)
|
||||
#define topology_sibling_cpumask(cpu)
|
||||
#define topology_core_cpumask(cpu)
|
||||
#define topology_book_cpumask(cpu)
|
||||
#define topology_drawer_cpumask(cpu)
|
||||
|
||||
The type of **_id macros is int.
|
||||
The type of **_cpumask macros is (const) struct cpumask *. The latter
|
||||
@@ -78,6 +100,8 @@ not defined by include/asm-XXX/topology.h:
|
||||
|
||||
For architectures that don't support books (CONFIG_SCHED_BOOK) there are no
|
||||
default definitions for topology_book_id() and topology_book_cpumask().
|
||||
For architectures that don't support drawes (CONFIG_SCHED_DRAWER) there are
|
||||
no default definitions for topology_drawer_id() and topology_drawer_cpumask().
|
||||
|
||||
Additionally, CPU topology information is provided under
|
||||
/sys/devices/system/cpu and includes these files. The internal
|
||||
|
||||
@@ -2794,8 +2794,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
timer: [X86] Force use of architectural NMI
|
||||
timer mode (see also oprofile.timer
|
||||
for generic hr timer mode)
|
||||
[s390] Force legacy basic mode sampling
|
||||
(report cpu_type "timer")
|
||||
|
||||
oops=panic Always panic on oopses. Default is to just kill the
|
||||
process, but there is a small probability of
|
||||
|
||||
@@ -405,7 +405,7 @@ Example:
|
||||
|
||||
> ls /sys/kernel/debug/s390dbf/dasd
|
||||
flush hex_ascii level pages raw
|
||||
> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort +1
|
||||
> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort -k2,2 -s
|
||||
00 00974733272:680099 2 - 02 0006ad7e 07 ea 4a 90 | ....
|
||||
00 00974733272:682210 2 - 02 0006ade6 46 52 45 45 | FREE
|
||||
00 00974733272:682213 2 - 02 0006adf6 07 ea 4a 90 | ....
|
||||
|
||||
+6
-10
@@ -72,6 +72,7 @@ config S390
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select ARCH_INLINE_READ_LOCK
|
||||
@@ -163,6 +164,7 @@ config S390
|
||||
select NO_BOOTMEM
|
||||
select OLD_SIGACTION
|
||||
select OLD_SIGSUSPEND3
|
||||
select SPARSE_IRQ
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select TTY
|
||||
select VIRT_CPU_ACCOUNTING
|
||||
@@ -477,6 +479,9 @@ config SCHED_MC
|
||||
config SCHED_BOOK
|
||||
def_bool n
|
||||
|
||||
config SCHED_DRAWER
|
||||
def_bool n
|
||||
|
||||
config SCHED_TOPOLOGY
|
||||
def_bool y
|
||||
prompt "Topology scheduler support"
|
||||
@@ -484,6 +489,7 @@ config SCHED_TOPOLOGY
|
||||
select SCHED_SMT
|
||||
select SCHED_MC
|
||||
select SCHED_BOOK
|
||||
select SCHED_DRAWER
|
||||
help
|
||||
Topology scheduler support improves the CPU scheduler's decision
|
||||
making when dealing with machines that have multi-threading,
|
||||
@@ -605,16 +611,6 @@ config PCI_NR_FUNCTIONS
|
||||
This allows you to specify the maximum number of PCI functions which
|
||||
this kernel will support.
|
||||
|
||||
config PCI_NR_MSI
|
||||
int "Maximum number of MSI interrupts (64-32768)"
|
||||
range 64 32768
|
||||
default "256"
|
||||
help
|
||||
This defines the number of virtual interrupts the kernel will
|
||||
provide for MSI interrupts. If you configure your system to have
|
||||
too few drivers will fail to allocate MSI interrupts for all
|
||||
PCI devices.
|
||||
|
||||
source "drivers/pci/Kconfig"
|
||||
|
||||
endif # PCI
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# create a compressed vmlinux image from the original vmlinux
|
||||
#
|
||||
|
||||
KCOV_INSTRUMENT := n
|
||||
|
||||
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
|
||||
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
|
||||
targets += misc.o piggy.o sizes.h head.o
|
||||
|
||||
@@ -678,6 +678,7 @@ CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_CRYPTO_CRC32_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
|
||||
@@ -616,6 +616,7 @@ CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_CRYPTO_CRC32_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
|
||||
@@ -615,6 +615,7 @@ CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_GHASH_S390=m
|
||||
CONFIG_CRYPTO_CRC32_S390=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
|
||||
CONFIG_X509_CERTIFICATE_PARSER=m
|
||||
|
||||
@@ -9,3 +9,6 @@ obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
|
||||
obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
|
||||
obj-$(CONFIG_S390_PRNG) += prng.o
|
||||
obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
|
||||
obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o
|
||||
|
||||
crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Crypto-API module for CRC-32 algorithms implemented with the
|
||||
* z/Architecture Vector Extension Facility.
|
||||
*
|
||||
* Copyright IBM Corp. 2015
|
||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
*/
|
||||
#define KMSG_COMPONENT "crc32-vx"
|
||||
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/cpufeature.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <asm/fpu/api.h>
|
||||
|
||||
|
||||
#define CRC32_BLOCK_SIZE 1
|
||||
#define CRC32_DIGEST_SIZE 4
|
||||
|
||||
#define VX_MIN_LEN 64
|
||||
#define VX_ALIGNMENT 16L
|
||||
#define VX_ALIGN_MASK (VX_ALIGNMENT - 1)
|
||||
|
||||
struct crc_ctx {
|
||||
u32 key;
|
||||
};
|
||||
|
||||
struct crc_desc_ctx {
|
||||
u32 crc;
|
||||
};
|
||||
|
||||
/* Prototypes for functions in assembly files */
|
||||
u32 crc32_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
|
||||
u32 crc32_be_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
|
||||
u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
|
||||
|
||||
/*
|
||||
* DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
|
||||
*
|
||||
* Creates a function to perform a particular CRC-32 computation. Depending
|
||||
* on the message buffer, the hardware-accelerated or software implementation
|
||||
* is used. Note that the message buffer is aligned to improve fetch
|
||||
* operations of VECTOR LOAD MULTIPLE instructions.
|
||||
*
|
||||
*/
|
||||
#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw) \
|
||||
static u32 __pure ___fname(u32 crc, \
|
||||
unsigned char const *data, size_t datalen) \
|
||||
{ \
|
||||
struct kernel_fpu vxstate; \
|
||||
unsigned long prealign, aligned, remaining; \
|
||||
\
|
||||
if ((unsigned long)data & VX_ALIGN_MASK) { \
|
||||
prealign = VX_ALIGNMENT - \
|
||||
((unsigned long)data & VX_ALIGN_MASK); \
|
||||
datalen -= prealign; \
|
||||
crc = ___crc32_sw(crc, data, prealign); \
|
||||
data = (void *)((unsigned long)data + prealign); \
|
||||
} \
|
||||
\
|
||||
if (datalen < VX_MIN_LEN) \
|
||||
return ___crc32_sw(crc, data, datalen); \
|
||||
\
|
||||
aligned = datalen & ~VX_ALIGN_MASK; \
|
||||
remaining = datalen & VX_ALIGN_MASK; \
|
||||
\
|
||||
kernel_fpu_begin(&vxstate, KERNEL_VXR_LOW); \
|
||||
crc = ___crc32_vx(crc, data, aligned); \
|
||||
kernel_fpu_end(&vxstate); \
|
||||
\
|
||||
if (remaining) \
|
||||
crc = ___crc32_sw(crc, data + aligned, remaining); \
|
||||
\
|
||||
return crc; \
|
||||
}
|
||||
|
||||
DEFINE_CRC32_VX(crc32_le_vx, crc32_le_vgfm_16, crc32_le)
|
||||
DEFINE_CRC32_VX(crc32_be_vx, crc32_be_vgfm_16, crc32_be)
|
||||
DEFINE_CRC32_VX(crc32c_le_vx, crc32c_le_vgfm_16, __crc32c_le)
|
||||
|
||||
|
||||
static int crc32_vx_cra_init_zero(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
mctx->key = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32_vx_cra_init_invert(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crc_ctx *mctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
mctx->key = ~0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32_vx_init(struct shash_desc *desc)
|
||||
{
|
||||
struct crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
|
||||
struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
ctx->crc = mctx->key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
|
||||
unsigned int newkeylen)
|
||||
{
|
||||
struct crc_ctx *mctx = crypto_shash_ctx(tfm);
|
||||
|
||||
if (newkeylen != sizeof(mctx->key)) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
mctx->key = le32_to_cpu(*(__le32 *)newkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32be_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
|
||||
unsigned int newkeylen)
|
||||
{
|
||||
struct crc_ctx *mctx = crypto_shash_ctx(tfm);
|
||||
|
||||
if (newkeylen != sizeof(mctx->key)) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
mctx->key = be32_to_cpu(*(__be32 *)newkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32le_vx_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
*(__le32 *)out = cpu_to_le32p(&ctx->crc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32be_vx_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
*(__be32 *)out = cpu_to_be32p(&ctx->crc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crc32c_vx_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct crc_desc_ctx *ctx = shash_desc_ctx(desc);
|
||||
|
||||
/*
|
||||
* Perform a final XOR with 0xFFFFFFFF to be in sync
|
||||
* with the generic crc32c shash implementation.
|
||||
*/
|
||||
*(__le32 *)out = ~cpu_to_le32p(&ctx->crc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __crc32le_vx_finup(u32 *crc, const u8 *data, unsigned int len,
|
||||
u8 *out)
|
||||
{
|
||||
*(__le32 *)out = cpu_to_le32(crc32_le_vx(*crc, data, len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __crc32be_vx_finup(u32 *crc, const u8 *data, unsigned int len,
|
||||
u8 *out)
|
||||
{
|
||||
*(__be32 *)out = cpu_to_be32(crc32_be_vx(*crc, data, len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __crc32c_vx_finup(u32 *crc, const u8 *data, unsigned int len,
|
||||
u8 *out)
|
||||
{
|
||||
/*
|
||||
* Perform a final XOR with 0xFFFFFFFF to be in sync
|
||||
* with the generic crc32c shash implementation.
|
||||
*/
|
||||
*(__le32 *)out = ~cpu_to_le32(crc32c_le_vx(*crc, data, len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define CRC32_VX_FINUP(alg, func) \
|
||||
static int alg ## _vx_finup(struct shash_desc *desc, const u8 *data, \
|
||||
unsigned int datalen, u8 *out) \
|
||||
{ \
|
||||
return __ ## alg ## _vx_finup(shash_desc_ctx(desc), \
|
||||
data, datalen, out); \
|
||||
}
|
||||
|
||||
CRC32_VX_FINUP(crc32le, crc32_le_vx)
|
||||
CRC32_VX_FINUP(crc32be, crc32_be_vx)
|
||||
CRC32_VX_FINUP(crc32c, crc32c_le_vx)
|
||||
|
||||
#define CRC32_VX_DIGEST(alg, func) \
|
||||
static int alg ## _vx_digest(struct shash_desc *desc, const u8 *data, \
|
||||
unsigned int len, u8 *out) \
|
||||
{ \
|
||||
return __ ## alg ## _vx_finup(crypto_shash_ctx(desc->tfm), \
|
||||
data, len, out); \
|
||||
}
|
||||
|
||||
CRC32_VX_DIGEST(crc32le, crc32_le_vx)
|
||||
CRC32_VX_DIGEST(crc32be, crc32_be_vx)
|
||||
CRC32_VX_DIGEST(crc32c, crc32c_le_vx)
|
||||
|
||||
#define CRC32_VX_UPDATE(alg, func) \
|
||||
static int alg ## _vx_update(struct shash_desc *desc, const u8 *data, \
|
||||
unsigned int datalen) \
|
||||
{ \
|
||||
struct crc_desc_ctx *ctx = shash_desc_ctx(desc); \
|
||||
ctx->crc = func(ctx->crc, data, datalen); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
CRC32_VX_UPDATE(crc32le, crc32_le_vx)
|
||||
CRC32_VX_UPDATE(crc32be, crc32_be_vx)
|
||||
CRC32_VX_UPDATE(crc32c, crc32c_le_vx)
|
||||
|
||||
|
||||
static struct shash_alg crc32_vx_algs[] = {
|
||||
/* CRC-32 LE */
|
||||
{
|
||||
.init = crc32_vx_init,
|
||||
.setkey = crc32_vx_setkey,
|
||||
.update = crc32le_vx_update,
|
||||
.final = crc32le_vx_final,
|
||||
.finup = crc32le_vx_finup,
|
||||
.digest = crc32le_vx_digest,
|
||||
.descsize = sizeof(struct crc_desc_ctx),
|
||||
.digestsize = CRC32_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32",
|
||||
.cra_driver_name = "crc32-vx",
|
||||
.cra_priority = 200,
|
||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = crc32_vx_cra_init_zero,
|
||||
},
|
||||
},
|
||||
/* CRC-32 BE */
|
||||
{
|
||||
.init = crc32_vx_init,
|
||||
.setkey = crc32be_vx_setkey,
|
||||
.update = crc32be_vx_update,
|
||||
.final = crc32be_vx_final,
|
||||
.finup = crc32be_vx_finup,
|
||||
.digest = crc32be_vx_digest,
|
||||
.descsize = sizeof(struct crc_desc_ctx),
|
||||
.digestsize = CRC32_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32be",
|
||||
.cra_driver_name = "crc32be-vx",
|
||||
.cra_priority = 200,
|
||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = crc32_vx_cra_init_zero,
|
||||
},
|
||||
},
|
||||
/* CRC-32C LE */
|
||||
{
|
||||
.init = crc32_vx_init,
|
||||
.setkey = crc32_vx_setkey,
|
||||
.update = crc32c_vx_update,
|
||||
.final = crc32c_vx_final,
|
||||
.finup = crc32c_vx_finup,
|
||||
.digest = crc32c_vx_digest,
|
||||
.descsize = sizeof(struct crc_desc_ctx),
|
||||
.digestsize = CRC32_DIGEST_SIZE,
|
||||
.base = {
|
||||
.cra_name = "crc32c",
|
||||
.cra_driver_name = "crc32c-vx",
|
||||
.cra_priority = 200,
|
||||
.cra_blocksize = CRC32_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct crc_ctx),
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = crc32_vx_cra_init_invert,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int __init crc_vx_mod_init(void)
|
||||
{
|
||||
return crypto_register_shashes(crc32_vx_algs,
|
||||
ARRAY_SIZE(crc32_vx_algs));
|
||||
}
|
||||
|
||||
static void __exit crc_vx_mod_exit(void)
|
||||
{
|
||||
crypto_unregister_shashes(crc32_vx_algs, ARRAY_SIZE(crc32_vx_algs));
|
||||
}
|
||||
|
||||
module_cpu_feature_match(VXRS, crc_vx_mod_init);
|
||||
module_exit(crc_vx_mod_exit);
|
||||
|
||||
MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_ALIAS_CRYPTO("crc32");
|
||||
MODULE_ALIAS_CRYPTO("crc32-vx");
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
MODULE_ALIAS_CRYPTO("crc32c-vx");
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Hardware-accelerated CRC-32 variants for Linux on z Systems
|
||||
*
|
||||
* Use the z/Architecture Vector Extension Facility to accelerate the
|
||||
* computing of CRC-32 checksums.
|
||||
*
|
||||
* This CRC-32 implementation algorithm processes the most-significant
|
||||
* bit first (BE).
|
||||
*
|
||||
* Copyright IBM Corp. 2015
|
||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/vx-insn.h>
|
||||
|
||||
/* Vector register range containing CRC-32 constants */
|
||||
#define CONST_R1R2 %v9
|
||||
#define CONST_R3R4 %v10
|
||||
#define CONST_R5 %v11
|
||||
#define CONST_R6 %v12
|
||||
#define CONST_RU_POLY %v13
|
||||
#define CONST_CRC_POLY %v14
|
||||
|
||||
.data
|
||||
.align 8
|
||||
|
||||
/*
|
||||
* The CRC-32 constant block contains reduction constants to fold and
|
||||
* process particular chunks of the input data stream in parallel.
|
||||
*
|
||||
* For the CRC-32 variants, the constants are precomputed according to
|
||||
* these defintions:
|
||||
*
|
||||
* R1 = x4*128+64 mod P(x)
|
||||
* R2 = x4*128 mod P(x)
|
||||
* R3 = x128+64 mod P(x)
|
||||
* R4 = x128 mod P(x)
|
||||
* R5 = x96 mod P(x)
|
||||
* R6 = x64 mod P(x)
|
||||
*
|
||||
* Barret reduction constant, u, is defined as floor(x**64 / P(x)).
|
||||
*
|
||||
* where P(x) is the polynomial in the normal domain and the P'(x) is the
|
||||
* polynomial in the reversed (bitreflected) domain.
|
||||
*
|
||||
* Note that the constant definitions below are extended in order to compute
|
||||
* intermediate results with a single VECTOR GALOIS FIELD MULTIPLY instruction.
|
||||
* The righmost doubleword can be 0 to prevent contribution to the result or
|
||||
* can be multiplied by 1 to perform an XOR without the need for a separate
|
||||
* VECTOR EXCLUSIVE OR instruction.
|
||||
*
|
||||
* CRC-32 (IEEE 802.3 Ethernet, ...) polynomials:
|
||||
*
|
||||
* P(x) = 0x04C11DB7
|
||||
* P'(x) = 0xEDB88320
|
||||
*/
|
||||
|
||||
.Lconstants_CRC_32_BE:
|
||||
.quad 0x08833794c, 0x0e6228b11 # R1, R2
|
||||
.quad 0x0c5b9cd4c, 0x0e8a45605 # R3, R4
|
||||
.quad 0x0f200aa66, 1 << 32 # R5, x32
|
||||
.quad 0x0490d678d, 1 # R6, 1
|
||||
.quad 0x104d101df, 0 # u
|
||||
.quad 0x104C11DB7, 0 # P(x)
|
||||
|
||||
.previous
|
||||
|
||||
.text
|
||||
/*
|
||||
* The CRC-32 function(s) use these calling conventions:
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* %r2: Initial CRC value, typically ~0; and final CRC (return) value.
|
||||
* %r3: Input buffer pointer, performance might be improved if the
|
||||
* buffer is on a doubleword boundary.
|
||||
* %r4: Length of the buffer, must be 64 bytes or greater.
|
||||
*
|
||||
* Register usage:
|
||||
*
|
||||
* %r5: CRC-32 constant pool base pointer.
|
||||
* V0: Initial CRC value and intermediate constants and results.
|
||||
* V1..V4: Data for CRC computation.
|
||||
* V5..V8: Next data chunks that are fetched from the input buffer.
|
||||
*
|
||||
* V9..V14: CRC-32 constants.
|
||||
*/
|
||||
ENTRY(crc32_be_vgfm_16)
|
||||
/* Load CRC-32 constants */
|
||||
larl %r5,.Lconstants_CRC_32_BE
|
||||
VLM CONST_R1R2,CONST_CRC_POLY,0,%r5
|
||||
|
||||
/* Load the initial CRC value into the leftmost word of V0. */
|
||||
VZERO %v0
|
||||
VLVGF %v0,%r2,0
|
||||
|
||||
/* Load a 64-byte data chunk and XOR with CRC */
|
||||
VLM %v1,%v4,0,%r3 /* 64-bytes into V1..V4 */
|
||||
VX %v1,%v0,%v1 /* V1 ^= CRC */
|
||||
aghi %r3,64 /* BUF = BUF + 64 */
|
||||
aghi %r4,-64 /* LEN = LEN - 64 */
|
||||
|
||||
/* Check remaining buffer size and jump to proper folding method */
|
||||
cghi %r4,64
|
||||
jl .Lless_than_64bytes
|
||||
|
||||
.Lfold_64bytes_loop:
|
||||
/* Load the next 64-byte data chunk into V5 to V8 */
|
||||
VLM %v5,%v8,0,%r3
|
||||
|
||||
/*
|
||||
* Perform a GF(2) multiplication of the doublewords in V1 with
|
||||
* the reduction constants in V0. The intermediate result is
|
||||
* then folded (accumulated) with the next data chunk in V5 and
|
||||
* stored in V1. Repeat this step for the register contents
|
||||
* in V2, V3, and V4 respectively.
|
||||
*/
|
||||
VGFMAG %v1,CONST_R1R2,%v1,%v5
|
||||
VGFMAG %v2,CONST_R1R2,%v2,%v6
|
||||
VGFMAG %v3,CONST_R1R2,%v3,%v7
|
||||
VGFMAG %v4,CONST_R1R2,%v4,%v8
|
||||
|
||||
/* Adjust buffer pointer and length for next loop */
|
||||
aghi %r3,64 /* BUF = BUF + 64 */
|
||||
aghi %r4,-64 /* LEN = LEN - 64 */
|
||||
|
||||
cghi %r4,64
|
||||
jnl .Lfold_64bytes_loop
|
||||
|
||||
.Lless_than_64bytes:
|
||||
/* Fold V1 to V4 into a single 128-bit value in V1 */
|
||||
VGFMAG %v1,CONST_R3R4,%v1,%v2
|
||||
VGFMAG %v1,CONST_R3R4,%v1,%v3
|
||||
VGFMAG %v1,CONST_R3R4,%v1,%v4
|
||||
|
||||
/* Check whether to continue with 64-bit folding */
|
||||
cghi %r4,16
|
||||
jl .Lfinal_fold
|
||||
|
||||
.Lfold_16bytes_loop:
|
||||
|
||||
VL %v2,0,,%r3 /* Load next data chunk */
|
||||
VGFMAG %v1,CONST_R3R4,%v1,%v2 /* Fold next data chunk */
|
||||
|
||||
/* Adjust buffer pointer and size for folding next data chunk */
|
||||
aghi %r3,16
|
||||
aghi %r4,-16
|
||||
|
||||
/* Process remaining data chunks */
|
||||
cghi %r4,16
|
||||
jnl .Lfold_16bytes_loop
|
||||
|
||||
.Lfinal_fold:
|
||||
/*
|
||||
* The R5 constant is used to fold a 128-bit value into an 96-bit value
|
||||
* that is XORed with the next 96-bit input data chunk. To use a single
|
||||
* VGFMG instruction, multiply the rightmost 64-bit with x^32 (1<<32) to
|
||||
* form an intermediate 96-bit value (with appended zeros) which is then
|
||||
* XORed with the intermediate reduction result.
|
||||
*/
|
||||
VGFMG %v1,CONST_R5,%v1
|
||||
|
||||
/*
|
||||
* Further reduce the remaining 96-bit value to a 64-bit value using a
|
||||
* single VGFMG, the rightmost doubleword is multiplied with 0x1. The
|
||||
* intermediate result is then XORed with the product of the leftmost
|
||||
* doubleword with R6. The result is a 64-bit value and is subject to
|
||||
* the Barret reduction.
|
||||
*/
|
||||
VGFMG %v1,CONST_R6,%v1
|
||||
|
||||
/*
|
||||
* The input values to the Barret reduction are the degree-63 polynomial
|
||||
* in V1 (R(x)), degree-32 generator polynomial, and the reduction
|
||||
* constant u. The Barret reduction result is the CRC value of R(x) mod
|
||||
* P(x).
|
||||
*
|
||||
* The Barret reduction algorithm is defined as:
|
||||
*
|
||||
* 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u
|
||||
* 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x)
|
||||
* 3. C(x) = R(x) XOR T2(x) mod x^32
|
||||
*
|
||||
* Note: To compensate the division by x^32, use the vector unpack
|
||||
* instruction to move the leftmost word into the leftmost doubleword
|
||||
* of the vector register. The rightmost doubleword is multiplied
|
||||
* with zero to not contribute to the intermedate results.
|
||||
*/
|
||||
|
||||
/* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
|
||||
VUPLLF %v2,%v1
|
||||
VGFMG %v2,CONST_RU_POLY,%v2
|
||||
|
||||
/*
|
||||
* Compute the GF(2) product of the CRC polynomial in VO with T1(x) in
|
||||
* V2 and XOR the intermediate result, T2(x), with the value in V1.
|
||||
* The final result is in the rightmost word of V2.
|
||||
*/
|
||||
VUPLLF %v2,%v2
|
||||
VGFMAG %v2,CONST_CRC_POLY,%v2,%v1
|
||||
|
||||
.Ldone:
|
||||
VLGVF %r2,%v2,3
|
||||
br %r14
|
||||
|
||||
.previous
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Hardware-accelerated CRC-32 variants for Linux on z Systems
|
||||
*
|
||||
* Use the z/Architecture Vector Extension Facility to accelerate the
|
||||
* computing of bitreflected CRC-32 checksums for IEEE 802.3 Ethernet
|
||||
* and Castagnoli.
|
||||
*
|
||||
* This CRC-32 implementation algorithm is bitreflected and processes
|
||||
* the least-significant bit first (Little-Endian).
|
||||
*
|
||||
* Copyright IBM Corp. 2015
|
||||
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/vx-insn.h>
|
||||
|
||||
/* Vector register range containing CRC-32 constants */
|
||||
#define CONST_PERM_LE2BE %v9
|
||||
#define CONST_R2R1 %v10
|
||||
#define CONST_R4R3 %v11
|
||||
#define CONST_R5 %v12
|
||||
#define CONST_RU_POLY %v13
|
||||
#define CONST_CRC_POLY %v14
|
||||
|
||||
.data
|
||||
.align 8
|
||||
|
||||
/*
|
||||
* The CRC-32 constant block contains reduction constants to fold and
|
||||
* process particular chunks of the input data stream in parallel.
|
||||
*
|
||||
* For the CRC-32 variants, the constants are precomputed according to
|
||||
* these definitions:
|
||||
*
|
||||
* R1 = [(x4*128+32 mod P'(x) << 32)]' << 1
|
||||
* R2 = [(x4*128-32 mod P'(x) << 32)]' << 1
|
||||
* R3 = [(x128+32 mod P'(x) << 32)]' << 1
|
||||
* R4 = [(x128-32 mod P'(x) << 32)]' << 1
|
||||
* R5 = [(x64 mod P'(x) << 32)]' << 1
|
||||
* R6 = [(x32 mod P'(x) << 32)]' << 1
|
||||
*
|
||||
* The bitreflected Barret reduction constant, u', is defined as
|
||||
* the bit reversal of floor(x**64 / P(x)).
|
||||
*
|
||||
* where P(x) is the polynomial in the normal domain and the P'(x) is the
|
||||
* polynomial in the reversed (bitreflected) domain.
|
||||
*
|
||||
* CRC-32 (IEEE 802.3 Ethernet, ...) polynomials:
|
||||
*
|
||||
* P(x) = 0x04C11DB7
|
||||
* P'(x) = 0xEDB88320
|
||||
*
|
||||
* CRC-32C (Castagnoli) polynomials:
|
||||
*
|
||||
* P(x) = 0x1EDC6F41
|
||||
* P'(x) = 0x82F63B78
|
||||
*/
|
||||
|
||||
.Lconstants_CRC_32_LE:
|
||||
.octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask
|
||||
.quad 0x1c6e41596, 0x154442bd4 # R2, R1
|
||||
.quad 0x0ccaa009e, 0x1751997d0 # R4, R3
|
||||
.octa 0x163cd6124 # R5
|
||||
.octa 0x1F7011641 # u'
|
||||
.octa 0x1DB710641 # P'(x) << 1
|
||||
|
||||
.Lconstants_CRC_32C_LE:
|
||||
.octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask
|
||||
.quad 0x09e4addf8, 0x740eef02 # R2, R1
|
||||
.quad 0x14cd00bd6, 0xf20c0dfe # R4, R3
|
||||
.octa 0x0dd45aab8 # R5
|
||||
.octa 0x0dea713f1 # u'
|
||||
.octa 0x105ec76f0 # P'(x) << 1
|
||||
|
||||
.previous
|
||||
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* The CRC-32 functions use these calling conventions:
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* %r2: Initial CRC value, typically ~0; and final CRC (return) value.
|
||||
* %r3: Input buffer pointer, performance might be improved if the
|
||||
* buffer is on a doubleword boundary.
|
||||
* %r4: Length of the buffer, must be 64 bytes or greater.
|
||||
*
|
||||
* Register usage:
|
||||
*
|
||||
* %r5: CRC-32 constant pool base pointer.
|
||||
* V0: Initial CRC value and intermediate constants and results.
|
||||
* V1..V4: Data for CRC computation.
|
||||
* V5..V8: Next data chunks that are fetched from the input buffer.
|
||||
* V9: Constant for BE->LE conversion and shift operations
|
||||
*
|
||||
* V10..V14: CRC-32 constants.
|
||||
*/
|
||||
|
||||
ENTRY(crc32_le_vgfm_16)
|
||||
larl %r5,.Lconstants_CRC_32_LE
|
||||
j crc32_le_vgfm_generic
|
||||
|
||||
ENTRY(crc32c_le_vgfm_16)
|
||||
larl %r5,.Lconstants_CRC_32C_LE
|
||||
j crc32_le_vgfm_generic
|
||||
|
||||
|
||||
crc32_le_vgfm_generic:
|
||||
/* Load CRC-32 constants */
|
||||
VLM CONST_PERM_LE2BE,CONST_CRC_POLY,0,%r5
|
||||
|
||||
/*
|
||||
* Load the initial CRC value.
|
||||
*
|
||||
* The CRC value is loaded into the rightmost word of the
|
||||
* vector register and is later XORed with the LSB portion
|
||||
* of the loaded input data.
|
||||
*/
|
||||
VZERO %v0 /* Clear V0 */
|
||||
VLVGF %v0,%r2,3 /* Load CRC into rightmost word */
|
||||
|
||||
/* Load a 64-byte data chunk and XOR with CRC */
|
||||
VLM %v1,%v4,0,%r3 /* 64-bytes into V1..V4 */
|
||||
VPERM %v1,%v1,%v1,CONST_PERM_LE2BE
|
||||
VPERM %v2,%v2,%v2,CONST_PERM_LE2BE
|
||||
VPERM %v3,%v3,%v3,CONST_PERM_LE2BE
|
||||
VPERM %v4,%v4,%v4,CONST_PERM_LE2BE
|
||||
|
||||
VX %v1,%v0,%v1 /* V1 ^= CRC */
|
||||
aghi %r3,64 /* BUF = BUF + 64 */
|
||||
aghi %r4,-64 /* LEN = LEN - 64 */
|
||||
|
||||
cghi %r4,64
|
||||
jl .Lless_than_64bytes
|
||||
|
||||
.Lfold_64bytes_loop:
|
||||
/* Load the next 64-byte data chunk into V5 to V8 */
|
||||
VLM %v5,%v8,0,%r3
|
||||
VPERM %v5,%v5,%v5,CONST_PERM_LE2BE
|
||||
VPERM %v6,%v6,%v6,CONST_PERM_LE2BE
|
||||
VPERM %v7,%v7,%v7,CONST_PERM_LE2BE
|
||||
VPERM %v8,%v8,%v8,CONST_PERM_LE2BE
|
||||
|
||||
/*
|
||||
* Perform a GF(2) multiplication of the doublewords in V1 with
|
||||
* the R1 and R2 reduction constants in V0. The intermediate result
|
||||
* is then folded (accumulated) with the next data chunk in V5 and
|
||||
* stored in V1. Repeat this step for the register contents
|
||||
* in V2, V3, and V4 respectively.
|
||||
*/
|
||||
VGFMAG %v1,CONST_R2R1,%v1,%v5
|
||||
VGFMAG %v2,CONST_R2R1,%v2,%v6
|
||||
VGFMAG %v3,CONST_R2R1,%v3,%v7
|
||||
VGFMAG %v4,CONST_R2R1,%v4,%v8
|
||||
|
||||
aghi %r3,64 /* BUF = BUF + 64 */
|
||||
aghi %r4,-64 /* LEN = LEN - 64 */
|
||||
|
||||
cghi %r4,64
|
||||
jnl .Lfold_64bytes_loop
|
||||
|
||||
.Lless_than_64bytes:
|
||||
/*
|
||||
* Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3
|
||||
* and R4 and accumulating the next 128-bit chunk until a single 128-bit
|
||||
* value remains.
|
||||
*/
|
||||
VGFMAG %v1,CONST_R4R3,%v1,%v2
|
||||
VGFMAG %v1,CONST_R4R3,%v1,%v3
|
||||
VGFMAG %v1,CONST_R4R3,%v1,%v4
|
||||
|
||||
cghi %r4,16
|
||||
jl .Lfinal_fold
|
||||
|
||||
.Lfold_16bytes_loop:
|
||||
|
||||
VL %v2,0,,%r3 /* Load next data chunk */
|
||||
VPERM %v2,%v2,%v2,CONST_PERM_LE2BE
|
||||
VGFMAG %v1,CONST_R4R3,%v1,%v2 /* Fold next data chunk */
|
||||
|
||||
aghi %r3,16
|
||||
aghi %r4,-16
|
||||
|
||||
cghi %r4,16
|
||||
jnl .Lfold_16bytes_loop
|
||||
|
||||
.Lfinal_fold:
|
||||
/*
|
||||
* Set up a vector register for byte shifts. The shift value must
|
||||
* be loaded in bits 1-4 in byte element 7 of a vector register.
|
||||
* Shift by 8 bytes: 0x40
|
||||
* Shift by 4 bytes: 0x20
|
||||
*/
|
||||
VLEIB %v9,0x40,7
|
||||
|
||||
/*
|
||||
* Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes
|
||||
* to move R4 into the rightmost doubleword and set the leftmost
|
||||
* doubleword to 0x1.
|
||||
*/
|
||||
VSRLB %v0,CONST_R4R3,%v9
|
||||
VLEIG %v0,1,0
|
||||
|
||||
/*
|
||||
* Compute GF(2) product of V1 and V0. The rightmost doubleword
|
||||
* of V1 is multiplied with R4. The leftmost doubleword of V1 is
|
||||
* multiplied by 0x1 and is then XORed with rightmost product.
|
||||
* Implicitly, the intermediate leftmost product becomes padded
|
||||
*/
|
||||
VGFMG %v1,%v0,%v1
|
||||
|
||||
/*
|
||||
* Now do the final 32-bit fold by multiplying the rightmost word
|
||||
* in V1 with R5 and XOR the result with the remaining bits in V1.
|
||||
*
|
||||
* To achieve this by a single VGFMAG, right shift V1 by a word
|
||||
* and store the result in V2 which is then accumulated. Use the
|
||||
* vector unpack instruction to load the rightmost half of the
|
||||
* doubleword into the rightmost doubleword element of V1; the other
|
||||
* half is loaded in the leftmost doubleword.
|
||||
* The vector register with CONST_R5 contains the R5 constant in the
|
||||
* rightmost doubleword and the leftmost doubleword is zero to ignore
|
||||
* the leftmost product of V1.
|
||||
*/
|
||||
VLEIB %v9,0x20,7 /* Shift by words */
|
||||
VSRLB %v2,%v1,%v9 /* Store remaining bits in V2 */
|
||||
VUPLLF %v1,%v1 /* Split rightmost doubleword */
|
||||
VGFMAG %v1,CONST_R5,%v1,%v2 /* V1 = (V1 * R5) XOR V2 */
|
||||
|
||||
/*
|
||||
* Apply a Barret reduction to compute the final 32-bit CRC value.
|
||||
*
|
||||
* The input values to the Barret reduction are the degree-63 polynomial
|
||||
* in V1 (R(x)), degree-32 generator polynomial, and the reduction
|
||||
* constant u. The Barret reduction result is the CRC value of R(x) mod
|
||||
* P(x).
|
||||
*
|
||||
* The Barret reduction algorithm is defined as:
|
||||
*
|
||||
* 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u
|
||||
* 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x)
|
||||
* 3. C(x) = R(x) XOR T2(x) mod x^32
|
||||
*
|
||||
* Note: The leftmost doubleword of vector register containing
|
||||
* CONST_RU_POLY is zero and, thus, the intermediate GF(2) product
|
||||
* is zero and does not contribute to the final result.
|
||||
*/
|
||||
|
||||
/* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
|
||||
VUPLLF %v2,%v1
|
||||
VGFMG %v2,CONST_RU_POLY,%v2
|
||||
|
||||
/*
|
||||
* Compute the GF(2) product of the CRC polynomial with T1(x) in
|
||||
* V2 and XOR the intermediate result, T2(x), with the value in V1.
|
||||
* The final result is stored in word element 2 of V2.
|
||||
*/
|
||||
VUPLLF %v2,%v2
|
||||
VGFMAG %v2,CONST_CRC_POLY,%v2,%v1
|
||||
|
||||
.Ldone:
|
||||
VLGVF %r2,%v2,2
|
||||
br %r14
|
||||
|
||||
.previous
|
||||
@@ -225,12 +225,16 @@ CONFIG_CRYPTO_DEFLATE=m
|
||||
CONFIG_CRYPTO_LZ4=m
|
||||
CONFIG_CRYPTO_LZ4HC=m
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=m
|
||||
CONFIG_CRYPTO_USER_API_HASH=m
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=m
|
||||
CONFIG_CRYPTO_USER_API_RNG=m
|
||||
CONFIG_ZCRYPT=m
|
||||
CONFIG_CRYPTO_SHA1_S390=m
|
||||
CONFIG_CRYPTO_SHA256_S390=m
|
||||
CONFIG_CRYPTO_SHA512_S390=m
|
||||
CONFIG_CRYPTO_DES_S390=m
|
||||
CONFIG_CRYPTO_AES_S390=m
|
||||
CONFIG_CRYPTO_CRC32_S390=m
|
||||
CONFIG_CRC7=m
|
||||
# CONFIG_XZ_DEC_X86 is not set
|
||||
# CONFIG_XZ_DEC_POWERPC is not set
|
||||
|
||||
@@ -337,25 +337,27 @@ static inline __u64 phys_cpu__ctidx(enum diag204_format type, void *hdr)
|
||||
|
||||
/* Diagnose 204 functions */
|
||||
|
||||
static inline int __diag204(unsigned long subcode, unsigned long size, void *addr)
|
||||
static inline int __diag204(unsigned long *subcode, unsigned long size, void *addr)
|
||||
{
|
||||
register unsigned long _subcode asm("0") = subcode;
|
||||
register unsigned long _subcode asm("0") = *subcode;
|
||||
register unsigned long _size asm("1") = size;
|
||||
|
||||
asm volatile(
|
||||
" diag %2,%0,0x204\n"
|
||||
"0:\n"
|
||||
"0: nopr %%r7\n"
|
||||
EX_TABLE(0b,0b)
|
||||
: "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory");
|
||||
if (_subcode)
|
||||
return -1;
|
||||
*subcode = _subcode;
|
||||
return _size;
|
||||
}
|
||||
|
||||
static int diag204(unsigned long subcode, unsigned long size, void *addr)
|
||||
{
|
||||
diag_stat_inc(DIAG_STAT_X204);
|
||||
return __diag204(subcode, size, addr);
|
||||
size = __diag204(&subcode, size, addr);
|
||||
if (subcode)
|
||||
return -1;
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,7 +70,7 @@ static int diag2fc(int size, char* query, void *addr)
|
||||
diag_stat_inc(DIAG_STAT_X2FC);
|
||||
asm volatile(
|
||||
" diag %0,%1,0x2fc\n"
|
||||
"0:\n"
|
||||
"0: nopr %%r7\n"
|
||||
EX_TABLE(0b,0b)
|
||||
: "=d" (residual_cnt), "+d" (rc) : "0" (&parm_list) : "memory");
|
||||
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#define L1_CACHE_SHIFT 8
|
||||
#define NET_SKB_PAD 32
|
||||
|
||||
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
|
||||
|
||||
/* Read-only memory is marked before mark_rodata_ro() is called. */
|
||||
#define __ro_after_init __read_mostly
|
||||
#define __read_mostly __section(.data..read_mostly)
|
||||
|
||||
#endif
|
||||
@@ -320,7 +320,7 @@ struct cio_iplinfo {
|
||||
extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);
|
||||
|
||||
/* Function from drivers/s390/cio/chsc.c */
|
||||
int chsc_sstpc(void *page, unsigned int op, u16 ctrl);
|
||||
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
|
||||
int chsc_sstpi(void *page, void *result, size_t size);
|
||||
|
||||
#endif
|
||||
@@ -169,16 +169,27 @@ static inline int lcctl(u64 ctl)
|
||||
}
|
||||
|
||||
/* Extract CPU counter */
|
||||
static inline int ecctr(u64 ctr, u64 *val)
|
||||
static inline int __ecctr(u64 ctr, u64 *content)
|
||||
{
|
||||
register u64 content asm("4") = 0;
|
||||
register u64 _content asm("4") = 0;
|
||||
int cc;
|
||||
|
||||
asm volatile (
|
||||
" .insn rre,0xb2e40000,%0,%2\n"
|
||||
" ipm %1\n"
|
||||
" srl %1,28\n"
|
||||
: "=d" (content), "=d" (cc) : "d" (ctr) : "cc");
|
||||
: "=d" (_content), "=d" (cc) : "d" (ctr) : "cc");
|
||||
*content = _content;
|
||||
return cc;
|
||||
}
|
||||
|
||||
/* Extract CPU counter */
|
||||
static inline int ecctr(u64 ctr, u64 *val)
|
||||
{
|
||||
u64 content;
|
||||
int cc;
|
||||
|
||||
cc = __ecctr(ctr, &content);
|
||||
if (!cc)
|
||||
*val = content;
|
||||
return cc;
|
||||
|
||||
@@ -49,7 +49,7 @@ static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
|
||||
diag_stat_inc(DIAG_STAT_X010);
|
||||
asm volatile(
|
||||
"0: diag %0,%1,0x10\n"
|
||||
"1:\n"
|
||||
"1: nopr %%r7\n"
|
||||
EX_TABLE(0b, 1b)
|
||||
EX_TABLE(1b, 1b)
|
||||
: : "a" (start_addr), "a" (end_addr));
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
|
||||
*/
|
||||
#ifndef __S390_ETR_H
|
||||
#define __S390_ETR_H
|
||||
|
||||
/* ETR attachment control register */
|
||||
struct etr_eacr {
|
||||
unsigned int e0 : 1; /* port 0 stepping control */
|
||||
unsigned int e1 : 1; /* port 1 stepping control */
|
||||
unsigned int _pad0 : 5; /* must be 00100 */
|
||||
unsigned int dp : 1; /* data port control */
|
||||
unsigned int p0 : 1; /* port 0 change recognition control */
|
||||
unsigned int p1 : 1; /* port 1 change recognition control */
|
||||
unsigned int _pad1 : 3; /* must be 000 */
|
||||
unsigned int ea : 1; /* ETR alert control */
|
||||
unsigned int es : 1; /* ETR sync check control */
|
||||
unsigned int sl : 1; /* switch to local control */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Port state returned by steai */
|
||||
enum etr_psc {
|
||||
etr_psc_operational = 0,
|
||||
etr_psc_semi_operational = 1,
|
||||
etr_psc_protocol_error = 4,
|
||||
etr_psc_no_symbols = 8,
|
||||
etr_psc_no_signal = 12,
|
||||
etr_psc_pps_mode = 13
|
||||
};
|
||||
|
||||
/* Logical port state returned by stetr */
|
||||
enum etr_lpsc {
|
||||
etr_lpsc_operational_step = 0,
|
||||
etr_lpsc_operational_alt = 1,
|
||||
etr_lpsc_semi_operational = 2,
|
||||
etr_lpsc_protocol_error = 4,
|
||||
etr_lpsc_no_symbol_sync = 8,
|
||||
etr_lpsc_no_signal = 12,
|
||||
etr_lpsc_pps_mode = 13
|
||||
};
|
||||
|
||||
/* ETR status words */
|
||||
struct etr_esw {
|
||||
struct etr_eacr eacr; /* attachment control register */
|
||||
unsigned int y : 1; /* stepping mode */
|
||||
unsigned int _pad0 : 5; /* must be 00000 */
|
||||
unsigned int p : 1; /* stepping port number */
|
||||
unsigned int q : 1; /* data port number */
|
||||
unsigned int psc0 : 4; /* port 0 state code */
|
||||
unsigned int psc1 : 4; /* port 1 state code */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Second level data register status word */
|
||||
struct etr_slsw {
|
||||
unsigned int vv1 : 1; /* copy of validity bit data frame 1 */
|
||||
unsigned int vv2 : 1; /* copy of validity bit data frame 2 */
|
||||
unsigned int vv3 : 1; /* copy of validity bit data frame 3 */
|
||||
unsigned int vv4 : 1; /* copy of validity bit data frame 4 */
|
||||
unsigned int _pad0 : 19; /* must by all zeroes */
|
||||
unsigned int n : 1; /* EAF port number */
|
||||
unsigned int v1 : 1; /* validity bit ETR data frame 1 */
|
||||
unsigned int v2 : 1; /* validity bit ETR data frame 2 */
|
||||
unsigned int v3 : 1; /* validity bit ETR data frame 3 */
|
||||
unsigned int v4 : 1; /* validity bit ETR data frame 4 */
|
||||
unsigned int _pad1 : 4; /* must be 0000 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* ETR data frames */
|
||||
struct etr_edf1 {
|
||||
unsigned int u : 1; /* untuned bit */
|
||||
unsigned int _pad0 : 1; /* must be 0 */
|
||||
unsigned int r : 1; /* service request bit */
|
||||
unsigned int _pad1 : 4; /* must be 0000 */
|
||||
unsigned int a : 1; /* time adjustment bit */
|
||||
unsigned int net_id : 8; /* ETR network id */
|
||||
unsigned int etr_id : 8; /* id of ETR which sends data frames */
|
||||
unsigned int etr_pn : 8; /* port number of ETR output port */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf2 {
|
||||
unsigned int etv : 32; /* Upper 32 bits of TOD. */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf3 {
|
||||
unsigned int rc : 8; /* failure reason code */
|
||||
unsigned int _pad0 : 3; /* must be 000 */
|
||||
unsigned int c : 1; /* ETR coupled bit */
|
||||
unsigned int tc : 4; /* ETR type code */
|
||||
unsigned int blto : 8; /* biased local time offset */
|
||||
/* (blto - 128) * 15 = minutes */
|
||||
unsigned int buo : 8; /* biased utc offset */
|
||||
/* (buo - 128) = leap seconds */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct etr_edf4 {
|
||||
unsigned int ed : 8; /* ETS device dependent data */
|
||||
unsigned int _pad0 : 1; /* must be 0 */
|
||||
unsigned int buc : 5; /* biased ut1 correction */
|
||||
/* (buc - 16) * 0.1 seconds */
|
||||
unsigned int em : 6; /* ETS error magnitude */
|
||||
unsigned int dc : 6; /* ETS drift code */
|
||||
unsigned int sc : 6; /* ETS steering code */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* ETR attachment information block, two formats
|
||||
* format 1 has 4 reserved words with a size of 64 bytes
|
||||
* format 2 has 16 reserved words with a size of 96 bytes
|
||||
*/
|
||||
struct etr_aib {
|
||||
struct etr_esw esw;
|
||||
struct etr_slsw slsw;
|
||||
unsigned long long tsp;
|
||||
struct etr_edf1 edf1;
|
||||
struct etr_edf2 edf2;
|
||||
struct etr_edf3 edf3;
|
||||
struct etr_edf4 edf4;
|
||||
unsigned int reserved[16];
|
||||
} __attribute__ ((packed,aligned(8)));
|
||||
|
||||
/* ETR interruption parameter */
|
||||
struct etr_irq_parm {
|
||||
unsigned int _pad0 : 8;
|
||||
unsigned int pc0 : 1; /* port 0 state change */
|
||||
unsigned int pc1 : 1; /* port 1 state change */
|
||||
unsigned int _pad1 : 3;
|
||||
unsigned int eai : 1; /* ETR alert indication */
|
||||
unsigned int _pad2 : 18;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Query TOD offset result */
|
||||
struct etr_ptff_qto {
|
||||
unsigned long long physical_clock;
|
||||
unsigned long long tod_offset;
|
||||
unsigned long long logical_tod_offset;
|
||||
unsigned long long tod_epoch_difference;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Inline assembly helper functions */
|
||||
static inline int etr_setr(struct etr_eacr *ctrl)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2160000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*ctrl));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Stores a format 1 aib with 64 bytes */
|
||||
static inline int etr_stetr(struct etr_aib *aib)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2170000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*aib));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Stores a format 2 aib with 96 bytes for specified port */
|
||||
static inline int etr_steai(struct etr_aib *aib, unsigned int func)
|
||||
{
|
||||
register unsigned int reg0 asm("0") = func;
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .insn s,0xb2b30000,%1\n"
|
||||
"0: la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "+d" (rc) : "Q" (*aib), "d" (reg0));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Function codes for the steai instruction. */
|
||||
#define ETR_STEAI_STEPPING_PORT 0x10
|
||||
#define ETR_STEAI_ALTERNATE_PORT 0x11
|
||||
#define ETR_STEAI_PORT_0 0x12
|
||||
#define ETR_STEAI_PORT_1 0x13
|
||||
|
||||
static inline int etr_ptff(void *ptff_block, unsigned int func)
|
||||
{
|
||||
register unsigned int reg0 asm("0") = func;
|
||||
register unsigned long reg1 asm("1") = (unsigned long) ptff_block;
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
asm volatile(
|
||||
" .word 0x0104\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28\n"
|
||||
: "=d" (rc), "=m" (ptff_block)
|
||||
: "d" (reg0), "d" (reg1), "m" (ptff_block) : "cc");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Function codes for the ptff instruction. */
|
||||
#define ETR_PTFF_QAF 0x00 /* query available functions */
|
||||
#define ETR_PTFF_QTO 0x01 /* query tod offset */
|
||||
#define ETR_PTFF_QSI 0x02 /* query steering information */
|
||||
#define ETR_PTFF_ATO 0x40 /* adjust tod offset */
|
||||
#define ETR_PTFF_STO 0x41 /* set tod offset */
|
||||
#define ETR_PTFF_SFS 0x42 /* set fine steering rate */
|
||||
#define ETR_PTFF_SGS 0x43 /* set gross steering rate */
|
||||
|
||||
/* Functions needed by the machine check handler */
|
||||
int etr_switch_to_local(void);
|
||||
int etr_sync_check(void);
|
||||
void etr_queue_work(void);
|
||||
|
||||
/* notifier for syncs */
|
||||
extern struct atomic_notifier_head s390_epoch_delta_notifier;
|
||||
|
||||
/* STP interruption parameter */
|
||||
struct stp_irq_parm {
|
||||
unsigned int _pad0 : 14;
|
||||
unsigned int tsc : 1; /* Timing status change */
|
||||
unsigned int lac : 1; /* Link availability change */
|
||||
unsigned int tcpc : 1; /* Time control parameter change */
|
||||
unsigned int _pad2 : 15;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define STP_OP_SYNC 1
|
||||
#define STP_OP_CTRL 3
|
||||
|
||||
struct stp_sstpi {
|
||||
unsigned int rsvd0;
|
||||
unsigned int rsvd1 : 8;
|
||||
unsigned int stratum : 8;
|
||||
unsigned int vbits : 16;
|
||||
unsigned int leaps : 16;
|
||||
unsigned int tmd : 4;
|
||||
unsigned int ctn : 4;
|
||||
unsigned int rsvd2 : 3;
|
||||
unsigned int c : 1;
|
||||
unsigned int tst : 4;
|
||||
unsigned int tzo : 16;
|
||||
unsigned int dsto : 16;
|
||||
unsigned int ctrl : 16;
|
||||
unsigned int rsvd3 : 16;
|
||||
unsigned int tto;
|
||||
unsigned int rsvd4;
|
||||
unsigned int ctnid[3];
|
||||
unsigned int rsvd5;
|
||||
unsigned int todoff[4];
|
||||
unsigned int rsvd6[48];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Functions needed by the machine check handler */
|
||||
int stp_sync_check(void);
|
||||
int stp_island_check(void);
|
||||
void stp_queue_work(void);
|
||||
|
||||
#endif /* __S390_ETR_H */
|
||||
Loaded 20 of 111 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user