function rcu_dereference:long (protected_pointer:long) %{ /* pure */
void *protected_pointer = (void *)(long)STAP_ARG_protected_pointer;
long fetched_value;
-
#ifndef STAP_ALWAYS_ACQUIRE_RCU_LOCK
int lock_acquired = 0;
+#endif
+ /* We call kderef() here to ensure the memory is valid to read.
+ * Note the result is thrown away, then we use the "real"
+ * rcu_dereference function now that we know the address is
+ * safe. */
+ (void)kderef(sizeof(*protected_pointer), protected_pointer);
+
+#ifndef STAP_ALWAYS_ACQUIRE_RCU_LOCK
if (! rcu_read_lock_held()) {
rcu_read_lock();
lock_acquired = 1;
rcu_read_unlock();
#endif
STAP_RETVALUE = fetched_value;
+ CATCH_DEREF_FAULT();
%}