Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 718c0ddd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull RCU updates from Ingo Molnar:
 "The main RCU changes in this development cycle were:

   - Miscellaneous fixes, including a change to call_rcu()'s rcu_head
     alignment check.

   - Security-motivated list consistency checks, which are disabled by
     default behind DEBUG_LIST.

   - Torture-test updates.

   - Documentation updates, yet again just simple changes"

* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  torture: Prevent jitter from delaying build-only runs
  torture: Remove obsolete files from rcutorture .gitignore
  rcu: Don't kick unless grace period or request
  rcu: Make expedited grace periods recheck dyntick idle state
  torture: Trace long read-side delays
  rcu: RCU_TRACE enables event tracing as well as debugfs
  rcu: Remove obsolete comment from __call_rcu()
  rcu: Remove obsolete rcu_check_callbacks() header comment
  rcu: Tighten up __call_rcu() rcu_head alignment check
  Documentation/RCU: Fix minor typo
  documentation: Present updated RCU guarantee
  bug: Avoid Kconfig warning for BUG_ON_DATA_CORRUPTION
  lib/Kconfig.debug: Fix typo in select statement
  lkdtm: Add tests for struct list corruption
  bug: Provide toggle for BUG on data corruption
  list: Split list_del() debug checking into separate function
  rculist: Consolidate DEBUG_LIST for list_add_rcu()
  list: Split list_add() debug checking into separate function
parents 8fa3b6f9 af91a811
Loading
Loading
Loading
Loading
+24 −1
Original line number Original line Diff line number Diff line
@@ -547,7 +547,7 @@ The <tt>rcu_access_pointer()</tt> on line&nbsp;6 is similar to
	It could reuse a value formerly fetched from this same pointer.
	It could reuse a value formerly fetched from this same pointer.
	It could also fetch the pointer from <tt>gp</tt> in a byte-at-a-time
	It could also fetch the pointer from <tt>gp</tt> in a byte-at-a-time
	manner, resulting in <i>load tearing</i>, in turn resulting a bytewise
	manner, resulting in <i>load tearing</i>, in turn resulting a bytewise
	mash-up of two distince pointer values.
	mash-up of two distinct pointer values.
	It might even use value-speculation optimizations, where it makes
	It might even use value-speculation optimizations, where it makes
	a wrong guess, but by the time it gets around to checking the
	a wrong guess, but by the time it gets around to checking the
	value, an update has changed the pointer to match the wrong guess.
	value, an update has changed the pointer to match the wrong guess.
@@ -659,6 +659,29 @@ systems with more than one CPU:
	In other words, a given instance of <tt>synchronize_rcu()</tt>
	In other words, a given instance of <tt>synchronize_rcu()</tt>
	can avoid waiting on a given RCU read-side critical section only
	can avoid waiting on a given RCU read-side critical section only
	if it can prove that <tt>synchronize_rcu()</tt> started first.
	if it can prove that <tt>synchronize_rcu()</tt> started first.

	<p>
	A related question is &ldquo;When <tt>rcu_read_lock()</tt>
	doesn't generate any code, why does it matter how it relates
	to a grace period?&rdquo;
	The answer is that it is not the relationship of
	<tt>rcu_read_lock()</tt> itself that is important, but rather
	the relationship of the code within the enclosed RCU read-side
	critical section to the code preceding and following the
	grace period.
	If we take this viewpoint, then a given RCU read-side critical
	section begins before a given grace period when some access
	preceding the grace period observes the effect of some access
	within the critical section, in which case none of the accesses
	within the critical section may observe the effects of any
	access following the grace period.

	<p>
	As of late 2016, mathematical models of RCU take this
	viewpoint, for example, see slides&nbsp;62 and&nbsp;63
	of the
	<a href="http://www2.rdrop.com/users/paulmck/scalability/paper/LinuxMM.2016.10.04c.LCE.pdf">2016 LinuxCon EU</a>
	presentation.
</font></td></tr>
</font></td></tr>
<tr><td>&nbsp;</td></tr>
<tr><td>&nbsp;</td></tr>
</table>
</table>
+1 −1
Original line number Original line Diff line number Diff line
@@ -237,7 +237,7 @@ rcu_dereference()


	The reader uses rcu_dereference() to fetch an RCU-protected
	The reader uses rcu_dereference() to fetch an RCU-protected
	pointer, which returns a value that may then be safely
	pointer, which returns a value that may then be safely
	dereferenced.  Note that rcu_deference() does not actually
	dereferenced.  Note that rcu_dereference() does not actually
	dereference the pointer, instead, it protects the pointer for
	dereference the pointer, instead, it protects the pointer for
	later dereferencing.  It also executes any needed memory-barrier
	later dereferencing.  It also executes any needed memory-barrier
	instructions for a given CPU architecture.  Currently, only Alpha
	instructions for a given CPU architecture.  Currently, only Alpha
+2 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,8 @@ void lkdtm_SPINLOCKUP(void);
void lkdtm_HUNG_TASK(void);
void lkdtm_HUNG_TASK(void);
void lkdtm_ATOMIC_UNDERFLOW(void);
void lkdtm_ATOMIC_UNDERFLOW(void);
void lkdtm_ATOMIC_OVERFLOW(void);
void lkdtm_ATOMIC_OVERFLOW(void);
void lkdtm_CORRUPT_LIST_ADD(void);
void lkdtm_CORRUPT_LIST_DEL(void);


/* lkdtm_heap.c */
/* lkdtm_heap.c */
void lkdtm_OVERWRITE_ALLOCATION(void);
void lkdtm_OVERWRITE_ALLOCATION(void);
+68 −0
Original line number Original line Diff line number Diff line
@@ -5,8 +5,13 @@
 * test source files.
 * test source files.
 */
 */
#include "lkdtm.h"
#include "lkdtm.h"
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/sched.h>


struct lkdtm_list {
	struct list_head node;
};

/*
/*
 * Make sure our attempts to over run the kernel stack doesn't trigger
 * Make sure our attempts to over run the kernel stack doesn't trigger
 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
@@ -146,3 +151,66 @@ void lkdtm_ATOMIC_OVERFLOW(void)
	pr_info("attempting bad atomic overflow\n");
	pr_info("attempting bad atomic overflow\n");
	atomic_inc(&over);
	atomic_inc(&over);
}
}

void lkdtm_CORRUPT_LIST_ADD(void)
{
	/*
	 * Initially, an empty list via LIST_HEAD:
	 *	test_head.next = &test_head
	 *	test_head.prev = &test_head
	 */
	LIST_HEAD(test_head);
	struct lkdtm_list good, bad;
	void *target[2] = { };
	void *redirection = &target;

	pr_info("attempting good list addition\n");

	/*
	 * Adding to the list performs these actions:
	 *	test_head.next->prev = &good.node
	 *	good.node.next = test_head.next
	 *	good.node.prev = test_head
	 *	test_head.next = good.node
	 */
	list_add(&good.node, &test_head);

	pr_info("attempting corrupted list addition\n");
	/*
	 * In simulating this "write what where" primitive, the "what" is
	 * the address of &bad.node, and the "where" is the address held
	 * by "redirection".
	 */
	test_head.next = redirection;
	list_add(&bad.node, &test_head);

	if (target[0] == NULL && target[1] == NULL)
		pr_err("Overwrite did not happen, but no BUG?!\n");
	else
		pr_err("list_add() corruption not detected!\n");
}

void lkdtm_CORRUPT_LIST_DEL(void)
{
	LIST_HEAD(test_head);
	struct lkdtm_list item;
	void *target[2] = { };
	void *redirection = &target;

	list_add(&item.node, &test_head);

	pr_info("attempting good list removal\n");
	list_del(&item.node);

	pr_info("attempting corrupted list removal\n");
	list_add(&item.node, &test_head);

	/* As with the list_add() test above, this corrupts "next". */
	item.node.next = redirection;
	list_del(&item.node);

	if (target[0] == NULL && target[1] == NULL)
		pr_err("Overwrite did not happen, but no BUG?!\n");
	else
		pr_err("list_del() corruption not detected!\n");
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -197,6 +197,8 @@ struct crashtype crashtypes[] = {
	CRASHTYPE(EXCEPTION),
	CRASHTYPE(EXCEPTION),
	CRASHTYPE(LOOP),
	CRASHTYPE(LOOP),
	CRASHTYPE(OVERFLOW),
	CRASHTYPE(OVERFLOW),
	CRASHTYPE(CORRUPT_LIST_ADD),
	CRASHTYPE(CORRUPT_LIST_DEL),
	CRASHTYPE(CORRUPT_STACK),
	CRASHTYPE(CORRUPT_STACK),
	CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
	CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
	CRASHTYPE(OVERWRITE_ALLOCATION),
	CRASHTYPE(OVERWRITE_ALLOCATION),
Loading