Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 312403
b: refs/heads/master
c: 70fb74a
h: refs/heads/master
i:
  312401: 801ab68
  312399: 754be7f
v: v3
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Jun 8, 2012
1 parent 0cfb757 commit f9bc7fd
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c7d65a78fc18ed70353baeb7497ec71a7c775ac5
refs/heads/master: 70fb74a5420f9caa3e001d65004e4b669124283e
12 changes: 12 additions & 0 deletions trunk/arch/x86/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,22 @@ static __kprobes void default_do_nmi(struct pt_regs *regs)
* thus there is no race between the first check of state for NOT_RUNNING
* and setting it to NMI_EXECUTING. The HW will prevent nested NMIs
* at this point.
*
* In case the NMI takes a page fault, we need to save off the CR2
* because the NMI could have preempted another page fault and corrupt
* the CR2 that is about to be read. As nested NMIs must be restarted
* and they can not take breakpoints or page faults, the update of the
* CR2 must be done before converting the nmi state back to NOT_RUNNING.
* Otherwise, there would be a race of another nested NMI coming in
* after setting state to NOT_RUNNING but before updating the nmi_cr2.
*/
enum nmi_states {
NMI_NOT_RUNNING = 0,
NMI_EXECUTING,
NMI_LATCHED,
};
static DEFINE_PER_CPU(enum nmi_states, nmi_state);
static DEFINE_PER_CPU(unsigned long, nmi_cr2);

#define nmi_nesting_preprocess(regs) \
do { \
Expand All @@ -410,11 +419,14 @@ static DEFINE_PER_CPU(enum nmi_states, nmi_state);
return; \
} \
this_cpu_write(nmi_state, NMI_EXECUTING); \
this_cpu_write(nmi_cr2, read_cr2()); \
} while (0); \
nmi_restart:

#define nmi_nesting_postprocess() \
do { \
if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) \
write_cr2(this_cpu_read(nmi_cr2)); \
if (this_cpu_dec_return(nmi_state)) \
goto nmi_restart; \
} while (0)
Expand Down

0 comments on commit f9bc7fd

Please sign in to comment.