diff options
| author | Tony Luck <tony.luck@intel.com> | 2012-07-11 13:20:47 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2012-07-11 13:20:47 -0400 |
| commit | 6751ed65dc6642af64f7b8a440a75563c8aab7ae (patch) | |
| tree | 8736d4c2b3aa00c6a4f39d2e6cba4805720c2874 /mm | |
| parent | 6887a4131da3adaab011613776d865f4bcfb5678 (diff) | |
x86/mce: Fix siginfo_t->si_addr value for non-recoverable memory faults
In commit dad1743e5993f1 ("x86/mce: Only restart instruction after machine
check recovery if it is safe") we fixed mce_notify_process() to force a
signal to the current process if it was not restartable (RIPV bit not
set in MCG_STATUS). But doing it here means that the process doesn't
get told the virtual address of the fault via siginfo_t->si_addr. This
would prevent application level recovery from the fault.
Make a new MF_MUST_KILL flag bit for memory_failure() et al. to use so
that we will provide the right information with the signal.
Signed-off-by: Tony Luck <tony.luck@intel.com>
Acked-by: Borislav Petkov <borislav.petkov@amd.com>
Cc: stable@kernel.org # 3.4+
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/memory-failure.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index ab1e7145e290..de4ce7058450 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
| @@ -345,14 +345,14 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, | |||
| 345 | * Also when FAIL is set do a force kill because something went | 345 | * Also when FAIL is set do a force kill because something went |
| 346 | * wrong earlier. | 346 | * wrong earlier. |
| 347 | */ | 347 | */ |
| 348 | static void kill_procs(struct list_head *to_kill, int doit, int trapno, | 348 | static void kill_procs(struct list_head *to_kill, int forcekill, int trapno, |
| 349 | int fail, struct page *page, unsigned long pfn, | 349 | int fail, struct page *page, unsigned long pfn, |
| 350 | int flags) | 350 | int flags) |
| 351 | { | 351 | { |
| 352 | struct to_kill *tk, *next; | 352 | struct to_kill *tk, *next; |
| 353 | 353 | ||
| 354 | list_for_each_entry_safe (tk, next, to_kill, nd) { | 354 | list_for_each_entry_safe (tk, next, to_kill, nd) { |
| 355 | if (doit) { | 355 | if (forcekill) { |
| 356 | /* | 356 | /* |
| 357 | * In case something went wrong with munmapping | 357 | * In case something went wrong with munmapping |
| 358 | * make sure the process doesn't catch the | 358 | * make sure the process doesn't catch the |
| @@ -858,7 +858,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
| 858 | struct address_space *mapping; | 858 | struct address_space *mapping; |
| 859 | LIST_HEAD(tokill); | 859 | LIST_HEAD(tokill); |
| 860 | int ret; | 860 | int ret; |
| 861 | int kill = 1; | 861 | int kill = 1, forcekill; |
| 862 | struct page *hpage = compound_head(p); | 862 | struct page *hpage = compound_head(p); |
| 863 | struct page *ppage; | 863 | struct page *ppage; |
| 864 | 864 | ||
| @@ -888,7 +888,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
| 888 | * be called inside page lock (it's recommended but not enforced). | 888 | * be called inside page lock (it's recommended but not enforced). |
| 889 | */ | 889 | */ |
| 890 | mapping = page_mapping(hpage); | 890 | mapping = page_mapping(hpage); |
| 891 | if (!PageDirty(hpage) && mapping && | 891 | if (!(flags & MF_MUST_KILL) && !PageDirty(hpage) && mapping && |
| 892 | mapping_cap_writeback_dirty(mapping)) { | 892 | mapping_cap_writeback_dirty(mapping)) { |
| 893 | if (page_mkclean(hpage)) { | 893 | if (page_mkclean(hpage)) { |
| 894 | SetPageDirty(hpage); | 894 | SetPageDirty(hpage); |
| @@ -965,12 +965,14 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
| 965 | * Now that the dirty bit has been propagated to the | 965 | * Now that the dirty bit has been propagated to the |
| 966 | * struct page and all unmaps done we can decide if | 966 | * struct page and all unmaps done we can decide if |
| 967 | * killing is needed or not. Only kill when the page | 967 | * killing is needed or not. Only kill when the page |
| 968 | * was dirty, otherwise the tokill list is merely | 968 | * was dirty or the process is not restartable, |
| 969 | * otherwise the tokill list is merely | ||
| 969 | * freed. When there was a problem unmapping earlier | 970 | * freed. When there was a problem unmapping earlier |
| 970 | * use a more force-full uncatchable kill to prevent | 971 | * use a more force-full uncatchable kill to prevent |
| 971 | * any accesses to the poisoned memory. | 972 | * any accesses to the poisoned memory. |
| 972 | */ | 973 | */ |
| 973 | kill_procs(&tokill, !!PageDirty(ppage), trapno, | 974 | forcekill = PageDirty(ppage) || (flags & MF_MUST_KILL); |
| 975 | kill_procs(&tokill, forcekill, trapno, | ||
| 974 | ret != SWAP_SUCCESS, p, pfn, flags); | 976 | ret != SWAP_SUCCESS, p, pfn, flags); |
| 975 | 977 | ||
| 976 | return ret; | 978 | return ret; |
