From 14a5823fec5c7bf137e1920b1f645b6b2c910064 Mon Sep 17 00:00:00 2001 From: Benjamin Levy Date: Wed, 8 Oct 2025 11:53:23 -0400 Subject: [PATCH] syscalls_hc: use mutex instead of rcu --- src/hooks/syscalls_hc.c | 23 +++++++++++------------ src/hooks/syscalls_hc.h | 4 ++-- src/portal/portal_syscall.c | 8 ++++---- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/hooks/syscalls_hc.c b/src/hooks/syscalls_hc.c index 518a00c..c1130ac 100644 --- a/src/hooks/syscalls_hc.c +++ b/src/hooks/syscalls_hc.c @@ -24,7 +24,7 @@ struct hlist_head syscall_hook_table[1024]; /* Main table indexed by hook pointer */ struct hlist_head syscall_name_table[1024]; /* Table indexed by syscall name hash */ struct hlist_head syscall_all_hooks; /* Special list for "match all syscalls" hooks */ -DEFINE_SPINLOCK(syscall_hook_lock); +DEFINE_MUTEX(syscall_hook_lock); /* Export symbols for use by other modules */ EXPORT_SYMBOL(syscall_hook_table); @@ -298,11 +298,11 @@ static long process_syscall_hooks( long modified_ret = orig_ret; struct kernel_syscall_hook *hook; int i; - rcu_read_lock(); + mutex_lock(&syscall_hook_lock); fill_handler(&original_info, argc, args, syscall_name); // 1. Check the "match all syscalls" list first if (!hlist_empty(&syscall_all_hooks)) { - hlist_for_each_entry_rcu(hook, &syscall_all_hooks, name_hlist) { + hlist_for_each_entry(hook, &syscall_all_hooks, name_hlist) { bool matches = false; if (is_entry) { matches = hook->hook.on_enter && hook_matches_syscall(hook, syscall_name, argc, args); @@ -345,7 +345,7 @@ static long process_syscall_hooks( // 2. Check hooks specific to this syscall name if (syscall_name) { u32 name_hash = syscall_name_hash(syscall_name); - hash_for_each_possible_rcu(syscall_name_table, hook, name_hlist, name_hash) { + hash_for_each_possible(syscall_name_table, hook, name_hlist, name_hash) { bool matches = false; if (is_entry) { matches = hook->hook.on_enter && hook_matches_syscall(hook, syscall_name, argc, args); @@ -385,7 +385,7 @@ static long process_syscall_hooks( } } } - rcu_read_unlock(); + mutex_unlock(&syscall_hook_lock); if (is_entry) { if (skip_syscall) { *skip_ret_val = skip_ret_val_local; @@ -461,21 +461,20 @@ int unregister_syscall_hook(struct kernel_syscall_hook *hook_ptr) if (!hook_ptr) return -EINVAL; - spin_lock(&syscall_hook_lock); + mutex_lock(&syscall_hook_lock); // Remove from main hash table hash_del(&hook_ptr->hlist); // Remove from name-based hash table if it was added if (hook_ptr->hook.on_all) { - hlist_del_rcu(&hook_ptr->name_hlist); + hlist_del(&hook_ptr->name_hlist); } else if (hook_ptr->hook.name[0] != '\0') { - hlist_del_rcu(&hook_ptr->name_hlist); + hlist_del(&hook_ptr->name_hlist); } + kfree(hook_ptr); - spin_unlock(&syscall_hook_lock); + mutex_unlock(&syscall_hook_lock); - // Free the hook after RCU grace period - kfree_rcu(hook_ptr, rcu); return 0; -} \ No newline at end of file +} diff --git a/src/hooks/syscalls_hc.h b/src/hooks/syscalls_hc.h index 171cb48..16eb9b3 100644 --- a/src/hooks/syscalls_hc.h +++ b/src/hooks/syscalls_hc.h @@ -81,7 +81,7 @@ struct kernel_syscall_hook { /* Global variables - defined in syscalls_hc.c */ extern struct hlist_head syscall_hook_table[1024]; -extern spinlock_t syscall_hook_lock; +extern struct mutex syscall_hook_lock; /* Unregister a syscall hook using its pointer */ @@ -130,4 +130,4 @@ static inline u32 syscall_name_hash(const char *str) return full_name_hash(NULL, normalized, strlen(normalized)); } -#endif /* _SYSCALLS_HC_H */ \ No newline at end of file +#endif /* _SYSCALLS_HC_H */ diff --git a/src/portal/portal_syscall.c b/src/portal/portal_syscall.c index adc4fe6..842ac95 100644 --- a/src/portal/portal_syscall.c +++ b/src/portal/portal_syscall.c @@ -9,7 +9,7 @@ extern struct hlist_head syscall_hook_table[1024]; extern struct hlist_head syscall_name_table[1024]; extern struct hlist_head syscall_all_hooks; -extern spinlock_t syscall_hook_lock; +extern struct mutex syscall_hook_lock; // Using normalize_syscall_name and syscall_name_hash from syscalls_hc.h @@ -48,7 +48,7 @@ void handle_op_register_syscall_hook(portal_region *mem_region) } // Add to the main hook table indexed by pointer address - spin_lock(&syscall_hook_lock); + mutex_lock(&syscall_hook_lock); hash_add_rcu(syscall_hook_table, &kernel_hook->hlist, (unsigned long)kernel_hook); // Also add to name-based hash table for faster lookups @@ -61,9 +61,9 @@ void handle_op_register_syscall_hook(portal_region *mem_region) hash_add_rcu(syscall_name_table, &kernel_hook->name_hlist, name_hash); } - spin_unlock(&syscall_hook_lock); + mutex_unlock(&syscall_hook_lock); // Return the hook's memory address in the size field mem_region->header.size = (unsigned long)kernel_hook; mem_region->header.op = HYPER_RESP_READ_NUM; -} \ No newline at end of file +}