If I understand the question correctly, the simplest way is to use a spin-lock:
#include <linux/spinlock.h>
static DEFINE_SPINLOCK(foo_lock);
int my_system_call(...)
{
...
/* critical section starts */
spin_lock(&foo_lock);
/* critical section goes here */
...
/* critical section ends */
spin_unlock(&foo_lock);
...
}
Such critical section will be non-preemptable and concurrent executions of critical section won't overlap.