@@ -1691,6 +1691,7 @@ follows:
1691
1691
#. `Hotplug CPU `_
1692
1692
#. `Scheduler and RCU `_
1693
1693
#. `Tracing and RCU `_
1694
+ #. `Accesses to User Memory and RCU `_
1694
1695
#. `Energy Efficiency `_
1695
1696
#. `Scheduling-Clock Interrupts and RCU `_
1696
1697
#. `Memory Efficiency `_
@@ -2004,6 +2005,59 @@ where RCU readers execute in environments in which tracing cannot be
2004
2005
used. The tracing folks both located the requirement and provided the
2005
2006
needed fix, so this surprise requirement was relatively painless.
2006
2007
2008
+ Accesses to User Memory and RCU
2009
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2010
+
2011
+ The kernel needs to access user-space memory, for example, to access data
2012
+ referenced by system-call parameters. The ``get_user() `` macro does this job.
2013
+
2014
+ However, user-space memory might well be paged out, which means that
2015
+ ``get_user() `` might well page-fault and thus block while waiting for the
2016
+ resulting I/O to complete. It would be a very bad thing for the compiler to
2017
+ reorder a ``get_user() `` invocation into an RCU read-side critical section.
2018
+
2019
+ For example, suppose that the source code looked like this:
2020
+
2021
+ ::
2022
+
2023
+ 1 rcu_read_lock();
2024
+ 2 p = rcu_dereference(gp);
2025
+ 3 v = p->value;
2026
+ 4 rcu_read_unlock();
2027
+ 5 get_user(user_v, user_p);
2028
+ 6 do_something_with(v, user_v);
2029
+
2030
+ The compiler must not be permitted to transform this source code into
2031
+ the following:
2032
+
2033
+ ::
2034
+
2035
+ 1 rcu_read_lock();
2036
+ 2 p = rcu_dereference(gp);
2037
+ 3 get_user(user_v, user_p); // BUG: POSSIBLE PAGE FAULT!!!
2038
+ 4 v = p->value;
2039
+ 5 rcu_read_unlock();
2040
+ 6 do_something_with(v, user_v);
2041
+
2042
+ If the compiler did make this transformation in a ``CONFIG_PREEMPT=n `` kernel
2043
+ build, and if ``get_user() `` did page fault, the result would be a quiescent
2044
+ state in the middle of an RCU read-side critical section. This misplaced
2045
+ quiescent state could result in line 4 being a use-after-free access,
2046
+ which could be bad for your kernel's actuarial statistics. Similar examples
2047
+ can be constructed with the call to ``get_user() `` preceding the
2048
+ ``rcu_read_lock() ``.
2049
+
2050
+ Unfortunately, ``get_user() `` doesn't have any particular ordering properties,
2051
+ and in some architectures the underlying ``asm `` isn't even marked
2052
+ ``volatile ``. And even if it was marked ``volatile ``, the above access to
2053
+ ``p->value `` is not volatile, so the compiler would not have any reason to keep
2054
+ those two accesses in order.
2055
+
2056
+ Therefore, the Linux-kernel definitions of ``rcu_read_lock() `` and
2057
+ ``rcu_read_unlock() `` must act as compiler barriers, at least for outermost
2058
+ instances of ``rcu_read_lock() `` and ``rcu_read_unlock() `` within a nested set
2059
+ of RCU read-side critical sections.
2060
+
2007
2061
Energy Efficiency
2008
2062
~~~~~~~~~~~~~~~~~
2009
2063
0 commit comments