@@ -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
337344int 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
366373void 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
12841296void * 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
12891301void 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
13011313void * 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+
13061322size_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