mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
x86 mmiotrace: fix race with release_kmmio_fault_page()
There was a theoretical possibility to a race between arming a page in
post_kmmio_handler() and disarming the page in
release_kmmio_fault_page():
cpu0 cpu1
------------------------------------------------------------------
mmiotrace shutdown
enter release_kmmio_fault_page
fault on the page
disarm the page
disarm the page
handle the MMIO access
re-arm the page
put the page on release list
remove_kmmio_fault_pages()
fault on the page
page not known to mmiotrace
fall back to do_page_fault()
*KABOOM*
(This scenario also shows the double disarm case which is allowed.)
Fixed by acquiring kmmio_lock in post_kmmio_handler() and checking
if the page is being released from mmiotrace.
Signed-off-by: Pekka Paalanen <pq@iki.fi>
Cc: Stuart Bennett <stuart@freedesktop.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
3e39aa156a
commit
340430c572
|
|
@ -38,7 +38,8 @@ struct kmmio_fault_page {
|
|||
/*
|
||||
* Number of times this page has been registered as a part
|
||||
* of a probe. If zero, page is disarmed and this may be freed.
|
||||
* Used only by writers (RCU).
|
||||
* Used only by writers (RCU) and post_kmmio_handler().
|
||||
* Protected by kmmio_lock, when linked into kmmio_page_table.
|
||||
*/
|
||||
int count;
|
||||
};
|
||||
|
|
@ -317,7 +318,11 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
|
|||
if (ctx->probe && ctx->probe->post_handler)
|
||||
ctx->probe->post_handler(ctx->probe, condition, regs);
|
||||
|
||||
arm_kmmio_fault_page(ctx->fpage);
|
||||
/* Prevent racing against release_kmmio_fault_page(). */
|
||||
spin_lock(&kmmio_lock);
|
||||
if (ctx->fpage->count)
|
||||
arm_kmmio_fault_page(ctx->fpage);
|
||||
spin_unlock(&kmmio_lock);
|
||||
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
regs->flags |= ctx->saved_flags;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user