Skip to content

Commit 1f0f29c

Browse files
authored
Merge pull request #10590 from douzzer/20260603-linuxkm-fixes
20260603-linuxkm-fixes
2 parents 3bf1ae3 + 396e83a commit 1f0f29c

3 files changed

Lines changed: 66 additions & 21 deletions

File tree

linuxkm/linuxkm_wc_port.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,14 @@
167167
#ifndef WC_LINUXKM_INTR_SIGNALS
168168
#define WC_LINUXKM_INTR_SIGNALS { SIGKILL, SIGABRT, SIGHUP, SIGINT }
169169
#endif
170-
extern int wc_linuxkm_sig_ignore_begin(void);
171-
extern int wc_linuxkm_sig_ignore_end(void);
172-
extern int wc_linuxkm_check_for_intr_signals(void);
170+
WOLFSSL_API int wc_linuxkm_can_block(void);
171+
WOLFSSL_API int wc_linuxkm_sig_ignore_begin(void);
172+
WOLFSSL_API int wc_linuxkm_sig_ignore_end(void);
173+
WOLFSSL_API int wc_linuxkm_check_for_intr_signals(void);
173174
#ifndef WC_LINUXKM_MAX_NS_WITHOUT_YIELD
174175
#define WC_LINUXKM_MAX_NS_WITHOUT_YIELD 1000000000
175176
#endif
176-
extern void wc_linuxkm_relax_long_loop(void);
177+
WOLFSSL_API void wc_linuxkm_relax_long_loop(void);
177178

178179
#ifndef WC_SIG_IGNORE_BEGIN
179180
#define WC_SIG_IGNORE_BEGIN() wc_linuxkm_sig_ignore_begin()
@@ -1221,6 +1222,7 @@
12211222
typeof(wc_lkm_LockMutex) *wc_lkm_LockMutex;
12221223
#endif
12231224

1225+
typeof(wc_linuxkm_can_block) *wc_linuxkm_can_block;
12241226
typeof(wc_linuxkm_sig_ignore_begin) *wc_linuxkm_sig_ignore_begin;
12251227
typeof(wc_linuxkm_sig_ignore_end) *wc_linuxkm_sig_ignore_end;
12261228
typeof(wc_linuxkm_check_for_intr_signals) *wc_linuxkm_check_for_intr_signals;
@@ -1521,8 +1523,9 @@
15211523
wolfssl_spin_unlock_irqrestore_rt((lock), (flags))
15221524
#endif
15231525

1524-
#define wc_linuxkm_sig_ignore_begin WC_PIE_INDIRECT_SYM(wc_linuxkm_sig_ignore_begin);
1525-
#define wc_linuxkm_sig_ignore_end WC_PIE_INDIRECT_SYM(wc_linuxkm_sig_ignore_end);
1526+
#define wc_linuxkm_can_block WC_PIE_INDIRECT_SYM(wc_linuxkm_can_block)
1527+
#define wc_linuxkm_sig_ignore_begin WC_PIE_INDIRECT_SYM(wc_linuxkm_sig_ignore_begin)
1528+
#define wc_linuxkm_sig_ignore_end WC_PIE_INDIRECT_SYM(wc_linuxkm_sig_ignore_end)
15261529
#define wc_linuxkm_check_for_intr_signals WC_PIE_INDIRECT_SYM(wc_linuxkm_check_for_intr_signals)
15271530
#define wc_linuxkm_relax_long_loop WC_PIE_INDIRECT_SYM(wc_linuxkm_relax_long_loop)
15281531

@@ -1905,21 +1908,21 @@
19051908
#endif
19061909
#else /* !WC_LINUXKM_USE_HEAP_WRAPPERS */
19071910
#ifdef USE_KVMALLOC
1908-
#define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC), NUMA_NO_NODE)
1911+
#define malloc(size) kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC), NUMA_NO_NODE)
19091912
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
1910-
#define free(ptr) (preempt_count() == 0 ? kvfree(ptr) : kvfree_atomic(ptr))
1913+
#define free(ptr) (wc_linuxkm_can_block() ? kvfree(ptr) : kvfree_atomic(ptr))
19111914
#else
19121915
#define free(ptr) kvfree(ptr)
19131916
#endif
19141917
#ifdef USE_KVREALLOC
1915-
#define realloc(ptr, newsize) kvrealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC))
1918+
#define realloc(ptr, newsize) kvrealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC))
19161919
#else
19171920
#define realloc(ptr, newsize) ((void)(ptr), (void)(newsize), NULL)
19181921
#endif
19191922
#else
1920-
#define malloc(size) kmalloc(WC_LINUXKM_ROUND_UP_P_OF_2(size), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC))
1923+
#define malloc(size) kmalloc(WC_LINUXKM_ROUND_UP_P_OF_2(size), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC))
19211924
#define free(ptr) kfree(ptr)
1922-
#define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC))
1925+
#define realloc(ptr, newsize) krealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC))
19231926
#endif
19241927
#endif /* !WC_LINUXKM_USE_HEAP_WRAPPERS */
19251928

linuxkm/lkcapi_sha_glue.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ static volatile int wc_linuxkm_rng_initing_default_bank_flag = 0;
10091009

10101010
static int linuxkm_affinity_lock(void *arg) {
10111011
(void)arg;
1012-
if (preempt_count() != 0)
1012+
if (! wc_linuxkm_can_block())
10131013
return ALREADY_E;
10141014
#if defined(CONFIG_SMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
10151015
migrate_disable(); /* this actually makes irq_count() nonzero, so that
@@ -1118,7 +1118,7 @@ static struct wc_rng_bank_inst *linuxkm_get_drbg(struct wc_rng_bank *ctx) {
11181118
WC_RNG_BANK_FLAG_CAN_WAIT |
11191119
WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST;
11201120

1121-
if (preempt_count() == 0)
1121+
if (wc_linuxkm_can_block())
11221122
flags |= WC_RNG_BANK_FLAG_AFFINITY_LOCK;
11231123
else
11241124
flags |= WC_RNG_BANK_FLAG_NO_VECTOR_OPS;
@@ -1487,7 +1487,7 @@ static int wc_mix_pool_bytes(const void *buf, size_t len) {
14871487
struct wc_rng_bank *ctx;
14881488
size_t i;
14891489
int n;
1490-
int can_sleep = (preempt_count() == 0);
1490+
int can_sleep = wc_linuxkm_can_block();
14911491

14921492
if (len == 0)
14931493
return 0;
@@ -1545,7 +1545,7 @@ static int wc_mix_pool_bytes(const void *buf, size_t len) {
15451545

15461546
static int wc_crng_reseed(void) {
15471547
struct wc_rng_bank *ctx;
1548-
int can_sleep = (preempt_count() == 0);
1548+
int can_sleep = wc_linuxkm_can_block();
15491549
int ret = wc_rng_bank_default_checkout(&ctx);
15501550

15511551
if (ret) {

linuxkm/module_hooks.c

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,13 @@ MODULE_PARM_DESC(rodata_dump_path,
316316
#include "linuxkm/lkcapi_glue.c"
317317
#endif
318318

319+
int wc_linuxkm_can_block(void) {
320+
/* We can't use preemptible() for this, because we need an accurate test
321+
* even in !CONFIG_PREEMPT_COUNT configs where preemptible() is always 0.
322+
*/
323+
return (preempt_count() == 0) && (! irqs_disabled());
324+
}
325+
319326
/* for simplicity, we use a global count to suspend signal processing while any
320327
* thread is running fipsEntry(), wolfCrypt_IntegrityTest_fips(),
321328
* linuxkm_lkcapi_register(), or linuxkm_lkcapi_unregister(). This only affects
@@ -336,7 +343,7 @@ int wc_linuxkm_sig_ignore_end(void) {
336343

337344
int wc_linuxkm_check_for_intr_signals(void) {
338345
static const int intr_signals[] = WC_LINUXKM_INTR_SIGNALS;
339-
if (preempt_count() != 0)
346+
if (! wc_linuxkm_can_block())
340347
return 0;
341348
if (signal_pending(current)) {
342349
int i;
@@ -365,7 +372,7 @@ int wc_linuxkm_check_for_intr_signals(void) {
365372

366373
void wc_linuxkm_relax_long_loop(void) {
367374
#if WC_LINUXKM_MAX_NS_WITHOUT_YIELD >= 0
368-
if (preempt_count() == 0) {
375+
if (wc_linuxkm_can_block()) {
369376
#if (WC_LINUXKM_MAX_NS_WITHOUT_YIELD == 0) || !defined(CONFIG_SCHED_INFO)
370377
cond_resched();
371378
#else
@@ -662,6 +669,11 @@ static int wolfssl_init(void)
662669
}
663670
#endif
664671

672+
#if defined(WC_LINUXKM_USE_HEAP_WRAPPERS) && defined(CONFIG_HAVE_KPROBES)
673+
/* cache the function pointer to find_vm_area(). */
674+
(void)wc_linuxkm_malloc_usable_size(NULL);
675+
#endif
676+
665677
#ifdef WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE
666678
#ifdef CONFIG_MODULE_SIG
667679
if (THIS_MODULE->sig_ok == false) {
@@ -1283,13 +1295,13 @@ static const struct wc_reloc_table_segments seg_map = {
12831295

12841296
void *wc_linuxkm_malloc(size_t size)
12851297
{
1286-
return kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC), NUMA_NO_NODE);
1298+
return kvmalloc_node(WC_LINUXKM_ROUND_UP_P_OF_2(size), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC), NUMA_NO_NODE);
12871299
}
12881300

12891301
void wc_linuxkm_free(void *ptr)
12901302
{
12911303
#if LINUX_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
1292-
if (preempt_count() == 0)
1304+
if (wc_linuxkm_can_block())
12931305
kvfree(ptr);
12941306
else
12951307
kvfree_atomic(ptr);
@@ -1300,12 +1312,41 @@ void wc_linuxkm_free(void *ptr)
13001312

13011313
void *wc_linuxkm_realloc(void *ptr, size_t newsize)
13021314
{
1303-
return kvrealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (preempt_count() == 0 ? GFP_KERNEL : GFP_ATOMIC));
1315+
return kvrealloc(ptr, WC_LINUXKM_ROUND_UP_P_OF_2(newsize), (wc_linuxkm_can_block() ? GFP_KERNEL : GFP_ATOMIC));
13041316
}
13051317

1318+
#ifdef CONFIG_HAVE_KPROBES
1319+
#include <linux/vmalloc.h>
1320+
#endif
1321+
13061322
size_t wc_linuxkm_malloc_usable_size(void *ptr)
13071323
{
1308-
return ksize(ptr);
1324+
if ((ptr == NULL) || is_vmalloc_addr(ptr)) {
1325+
#ifdef CONFIG_HAVE_KPROBES
1326+
static typeof(find_vm_area) *find_vm_area_ptr = NULL;
1327+
if (find_vm_area_ptr == NULL) {
1328+
if (! wc_linuxkm_can_block())
1329+
return 0;
1330+
find_vm_area_ptr = my_kallsyms_lookup_name("find_vm_area");
1331+
}
1332+
if (find_vm_area_ptr == NULL)
1333+
return 0;
1334+
else if (ptr == NULL)
1335+
return 0;
1336+
else {
1337+
struct vm_struct *vm = find_vm_area_ptr(ptr);
1338+
if (vm)
1339+
return get_vm_area_size(vm);
1340+
else
1341+
return 0;
1342+
}
1343+
#else
1344+
return 0;
1345+
#endif
1346+
}
1347+
else {
1348+
return ksize(ptr);
1349+
}
13091350
}
13101351

13111352
#endif /* WC_LINUXKM_USE_HEAP_WRAPPERS */
@@ -1678,6 +1719,7 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
16781719
#endif
16791720
#endif
16801721

1722+
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_can_block = wc_linuxkm_can_block;
16811723
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_sig_ignore_begin = wc_linuxkm_sig_ignore_begin;
16821724
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_sig_ignore_end = wc_linuxkm_sig_ignore_end;
16831725
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_check_for_intr_signals = wc_linuxkm_check_for_intr_signals;

0 commit comments

Comments
 (0)