Skip to content

Commit 611c9d8

Browse files
committed
Merge tag 'loongarch-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch updates from Huacai Chen: - Better backtraces for humanization - Relay BCE exceptions to userland as SIGSEGV - Provide kernel fpu functions - Optimize memory ops (memset/memcpy/memmove) - Optimize checksum and crc32(c) calculation - Add ARCH_HAS_FORTIFY_SOURCE selection - Add function error injection support - Add ftrace with direct call support - Add basic perf tools support * tag 'loongarch-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: (24 commits) tools/perf: Add basic support for LoongArch LoongArch: ftrace: Add direct call trampoline samples support LoongArch: ftrace: Add direct call support LoongArch: ftrace: Implement ftrace_find_callable_addr() to simplify code LoongArch: ftrace: Fix build error if DYNAMIC_FTRACE_WITH_REGS is not set LoongArch: ftrace: Abstract DYNAMIC_FTRACE_WITH_ARGS accesses LoongArch: Add support for function error injection LoongArch: Add ARCH_HAS_FORTIFY_SOURCE selection LoongArch: crypto: Add crc32 and crc32c hw acceleration LoongArch: Add checksum optimization for 64-bit system LoongArch: Optimize memory ops (memset/memcpy/memmove) LoongArch: Provide kernel fpu functions LoongArch: Relay BCE exceptions to userland as SIGSEGV with si_code=SEGV_BNDERR LoongArch: Tweak the BADV and CPUCFG.PRID lines in show_regs() LoongArch: Humanize the ESTAT line when showing registers LoongArch: Humanize the ECFG line when showing registers LoongArch: Humanize the EUEN line when showing registers LoongArch: Humanize the PRMD line when showing registers LoongArch: Humanize the CRMD line when showing registers LoongArch: Fix format of CSR lines during show_regs() ...
2 parents a1f749d + 2fa5ebe commit 611c9d8

55 files changed

Lines changed: 2337 additions & 298 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

arch/loongarch/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ config LOONGARCH
1010
select ARCH_ENABLE_MEMORY_HOTPLUG
1111
select ARCH_ENABLE_MEMORY_HOTREMOVE
1212
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
13+
select ARCH_HAS_FORTIFY_SOURCE
1314
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
1415
select ARCH_HAS_PTE_SPECIAL
1516
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
@@ -93,13 +94,15 @@ config LOONGARCH
9394
select HAVE_DMA_CONTIGUOUS
9495
select HAVE_DYNAMIC_FTRACE
9596
select HAVE_DYNAMIC_FTRACE_WITH_ARGS
97+
select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
9698
select HAVE_DYNAMIC_FTRACE_WITH_REGS
9799
select HAVE_EBPF_JIT
98100
select HAVE_EFFICIENT_UNALIGNED_ACCESS if !ARCH_STRICT_ALIGN
99101
select HAVE_EXIT_THREAD
100102
select HAVE_FAST_GUP
101103
select HAVE_FTRACE_MCOUNT_RECORD
102104
select HAVE_FUNCTION_ARG_ACCESS_API
105+
select HAVE_FUNCTION_ERROR_INJECTION
103106
select HAVE_FUNCTION_GRAPH_TRACER
104107
select HAVE_FUNCTION_TRACER
105108
select HAVE_GENERIC_VDSO
@@ -118,6 +121,8 @@ config LOONGARCH
118121
select HAVE_PERF_USER_STACK_DUMP
119122
select HAVE_REGS_AND_STACK_ACCESS_API
120123
select HAVE_RSEQ
124+
select HAVE_SAMPLE_FTRACE_DIRECT
125+
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
121126
select HAVE_SETUP_PER_CPU_AREA if NUMA
122127
select HAVE_STACKPROTECTOR
123128
select HAVE_SYSCALL_TRACEPOINTS

arch/loongarch/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ endif
115115
libs-y += arch/loongarch/lib/
116116
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
117117

118+
drivers-y += arch/loongarch/crypto/
119+
118120
# suspend and hibernation support
119121
drivers-$(CONFIG_PM) += arch/loongarch/power/
120122

arch/loongarch/crypto/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
menu "Accelerated Cryptographic Algorithms for CPU (loongarch)"
4+
5+
config CRYPTO_CRC32_LOONGARCH
6+
tristate "CRC32c and CRC32"
7+
select CRC32
8+
select CRYPTO_HASH
9+
help
10+
CRC32c and CRC32 CRC algorithms
11+
12+
Architecture: LoongArch with CRC32 instructions
13+
14+
endmenu

arch/loongarch/crypto/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Makefile for LoongArch crypto files..
4+
#
5+
6+
obj-$(CONFIG_CRYPTO_CRC32_LOONGARCH) += crc32-loongarch.o
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* crc32.c - CRC32 and CRC32C using LoongArch crc* instructions
4+
*
5+
* Module based on mips/crypto/crc32-mips.c
6+
*
7+
* Copyright (C) 2014 Linaro Ltd <yazen.ghannam@linaro.org>
8+
* Copyright (C) 2018 MIPS Tech, LLC
9+
* Copyright (C) 2020-2023 Loongson Technology Corporation Limited
10+
*/
11+
12+
#include <linux/module.h>
13+
#include <crypto/internal/hash.h>
14+
15+
#include <asm/cpu-features.h>
16+
#include <asm/unaligned.h>
17+
18+
#define _CRC32(crc, value, size, type) \
19+
do { \
20+
__asm__ __volatile__( \
21+
#type ".w." #size ".w" " %0, %1, %0\n\t"\
22+
: "+r" (crc) \
23+
: "r" (value) \
24+
: "memory"); \
25+
} while (0)
26+
27+
#define CRC32(crc, value, size) _CRC32(crc, value, size, crc)
28+
#define CRC32C(crc, value, size) _CRC32(crc, value, size, crcc)
29+
30+
static u32 crc32_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
31+
{
32+
u32 crc = crc_;
33+
34+
while (len >= sizeof(u64)) {
35+
u64 value = get_unaligned_le64(p);
36+
37+
CRC32(crc, value, d);
38+
p += sizeof(u64);
39+
len -= sizeof(u64);
40+
}
41+
42+
if (len & sizeof(u32)) {
43+
u32 value = get_unaligned_le32(p);
44+
45+
CRC32(crc, value, w);
46+
p += sizeof(u32);
47+
len -= sizeof(u32);
48+
}
49+
50+
if (len & sizeof(u16)) {
51+
u16 value = get_unaligned_le16(p);
52+
53+
CRC32(crc, value, h);
54+
p += sizeof(u16);
55+
}
56+
57+
if (len & sizeof(u8)) {
58+
u8 value = *p++;
59+
60+
CRC32(crc, value, b);
61+
}
62+
63+
return crc;
64+
}
65+
66+
static u32 crc32c_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
67+
{
68+
u32 crc = crc_;
69+
70+
while (len >= sizeof(u64)) {
71+
u64 value = get_unaligned_le64(p);
72+
73+
CRC32C(crc, value, d);
74+
p += sizeof(u64);
75+
len -= sizeof(u64);
76+
}
77+
78+
if (len & sizeof(u32)) {
79+
u32 value = get_unaligned_le32(p);
80+
81+
CRC32C(crc, value, w);
82+
p += sizeof(u32);
83+
len -= sizeof(u32);
84+
}
85+
86+
if (len & sizeof(u16)) {
87+
u16 value = get_unaligned_le16(p);
88+
89+
CRC32C(crc, value, h);
90+
p += sizeof(u16);
91+
}
92+
93+
if (len & sizeof(u8)) {
94+
u8 value = *p++;
95+
96+
CRC32C(crc, value, b);
97+
}
98+
99+
return crc;
100+
}
101+
102+
#define CHKSUM_BLOCK_SIZE 1
103+
#define CHKSUM_DIGEST_SIZE 4
104+
105+
struct chksum_ctx {
106+
u32 key;
107+
};
108+
109+
struct chksum_desc_ctx {
110+
u32 crc;
111+
};
112+
113+
static int chksum_init(struct shash_desc *desc)
114+
{
115+
struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
116+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
117+
118+
ctx->crc = mctx->key;
119+
120+
return 0;
121+
}
122+
123+
/*
124+
* Setting the seed allows arbitrary accumulators and flexible XOR policy
125+
* If your algorithm starts with ~0, then XOR with ~0 before you set the seed.
126+
*/
127+
static int chksum_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen)
128+
{
129+
struct chksum_ctx *mctx = crypto_shash_ctx(tfm);
130+
131+
if (keylen != sizeof(mctx->key))
132+
return -EINVAL;
133+
134+
mctx->key = get_unaligned_le32(key);
135+
136+
return 0;
137+
}
138+
139+
static int chksum_update(struct shash_desc *desc, const u8 *data, unsigned int length)
140+
{
141+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
142+
143+
ctx->crc = crc32_loongarch_hw(ctx->crc, data, length);
144+
return 0;
145+
}
146+
147+
static int chksumc_update(struct shash_desc *desc, const u8 *data, unsigned int length)
148+
{
149+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
150+
151+
ctx->crc = crc32c_loongarch_hw(ctx->crc, data, length);
152+
return 0;
153+
}
154+
155+
static int chksum_final(struct shash_desc *desc, u8 *out)
156+
{
157+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
158+
159+
put_unaligned_le32(ctx->crc, out);
160+
return 0;
161+
}
162+
163+
static int chksumc_final(struct shash_desc *desc, u8 *out)
164+
{
165+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
166+
167+
put_unaligned_le32(~ctx->crc, out);
168+
return 0;
169+
}
170+
171+
static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
172+
{
173+
put_unaligned_le32(crc32_loongarch_hw(crc, data, len), out);
174+
return 0;
175+
}
176+
177+
static int __chksumc_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
178+
{
179+
put_unaligned_le32(~crc32c_loongarch_hw(crc, data, len), out);
180+
return 0;
181+
}
182+
183+
static int chksum_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
184+
{
185+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
186+
187+
return __chksum_finup(ctx->crc, data, len, out);
188+
}
189+
190+
static int chksumc_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
191+
{
192+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
193+
194+
return __chksumc_finup(ctx->crc, data, len, out);
195+
}
196+
197+
static int chksum_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
198+
{
199+
struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
200+
201+
return __chksum_finup(mctx->key, data, length, out);
202+
}
203+
204+
static int chksumc_digest(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
205+
{
206+
struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm);
207+
208+
return __chksumc_finup(mctx->key, data, length, out);
209+
}
210+
211+
static int chksum_cra_init(struct crypto_tfm *tfm)
212+
{
213+
struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
214+
215+
mctx->key = 0;
216+
return 0;
217+
}
218+
219+
static int chksumc_cra_init(struct crypto_tfm *tfm)
220+
{
221+
struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
222+
223+
mctx->key = ~0;
224+
return 0;
225+
}
226+
227+
static struct shash_alg crc32_alg = {
228+
.digestsize = CHKSUM_DIGEST_SIZE,
229+
.setkey = chksum_setkey,
230+
.init = chksum_init,
231+
.update = chksum_update,
232+
.final = chksum_final,
233+
.finup = chksum_finup,
234+
.digest = chksum_digest,
235+
.descsize = sizeof(struct chksum_desc_ctx),
236+
.base = {
237+
.cra_name = "crc32",
238+
.cra_driver_name = "crc32-loongarch",
239+
.cra_priority = 300,
240+
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
241+
.cra_blocksize = CHKSUM_BLOCK_SIZE,
242+
.cra_alignmask = 0,
243+
.cra_ctxsize = sizeof(struct chksum_ctx),
244+
.cra_module = THIS_MODULE,
245+
.cra_init = chksum_cra_init,
246+
}
247+
};
248+
249+
static struct shash_alg crc32c_alg = {
250+
.digestsize = CHKSUM_DIGEST_SIZE,
251+
.setkey = chksum_setkey,
252+
.init = chksum_init,
253+
.update = chksumc_update,
254+
.final = chksumc_final,
255+
.finup = chksumc_finup,
256+
.digest = chksumc_digest,
257+
.descsize = sizeof(struct chksum_desc_ctx),
258+
.base = {
259+
.cra_name = "crc32c",
260+
.cra_driver_name = "crc32c-loongarch",
261+
.cra_priority = 300,
262+
.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
263+
.cra_blocksize = CHKSUM_BLOCK_SIZE,
264+
.cra_alignmask = 0,
265+
.cra_ctxsize = sizeof(struct chksum_ctx),
266+
.cra_module = THIS_MODULE,
267+
.cra_init = chksumc_cra_init,
268+
}
269+
};
270+
271+
static int __init crc32_mod_init(void)
272+
{
273+
int err;
274+
275+
if (!cpu_has(CPU_FEATURE_CRC32))
276+
return 0;
277+
278+
err = crypto_register_shash(&crc32_alg);
279+
if (err)
280+
return err;
281+
282+
err = crypto_register_shash(&crc32c_alg);
283+
if (err)
284+
return err;
285+
286+
return 0;
287+
}
288+
289+
static void __exit crc32_mod_exit(void)
290+
{
291+
if (!cpu_has(CPU_FEATURE_CRC32))
292+
return;
293+
294+
crypto_unregister_shash(&crc32_alg);
295+
crypto_unregister_shash(&crc32c_alg);
296+
}
297+
298+
module_init(crc32_mod_init);
299+
module_exit(crc32_mod_exit);
300+
301+
MODULE_AUTHOR("Min Zhou <zhoumin@loongson.cn>");
302+
MODULE_AUTHOR("Huacai Chen <chenhuacai@loongson.cn>");
303+
MODULE_DESCRIPTION("CRC32 and CRC32C using LoongArch crc* instructions");
304+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)