This cast is invalid, arg being an unsigned long in this case. I'm surprised the compiler doesn't warn about this. For both functions, I'd suggest using something like: void __user *uarg = compat_ptr(arg); in the prologue. This avoids the need for a cast when calling the actual handler with uarg (void * is implicitly convertible to any pointer type), which is not just shorter but also avoids this strange cast to a pointer to a native struct, despite the pointer being actually to a compat struct in this case.
I thought there was something fishy here! Do you know why the compiler would ignore this, could it have anything to do with how I've got the build configured (specifically the #ifdef CONFIG_COMPAT)?
Many thanks for the feedback as always,
Akram