* [PATCH v3 0/4] arm64: Add support for handling memory corruption
@ 2017-06-08 17:25 Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 1/4] arm64: hugetlb: Fix huge_pte_offset to return poisoned page table entries Punit Agrawal
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Punit Agrawal @ 2017-06-08 17:25 UTC (permalink / raw)
To: catalin.marinas, will.deacon
Cc: Punit Agrawal, tbaicar, steve.capper, linux-arm-kernel,
linux-kernel, manoj.iyer
Hi,
This series enables memory failure handling for arm64. Previous
posting can be found at [0] and [1].
Changelog
v2 -> v3:
* Added a new patch to update the perf accounting for fault handling
(patch 3)
* Added test and review tags
v1 -> v2:
* Reworked Patch 1 based on Catalin's feedbak to symmetrically deal
with PUD and PMD hugepages in huge_pte_offset()
* Added Steve's acks
With support for contiguous hugepages being turned off[2], some of the
problems arising from swap entries go away[3]. This simplifies the
changes needed to enable memory corruption handling for arm64 (done in
this seris).
In this series, we updates huge_pte_offset() to correctly deal with
swap entries (Patch 1). This function will need to be updated when
contiguous hugepages are re-enabled.
Patch 2 adds support to send SIGBUS to processes that have their
memory corrupted.
Patch 3 updates the perf accounting for memory faults to exclude
hwpoison faults.
With the prerequisites in place, enable memory corruption handling for
arm64 (patch 4).
Thanks,
Punit
[0] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1376052.html
[1] https://www.spinics.net/lists/arm-kernel/msg581657.html
[1] https://lkml.org/lkml/2017/4/7/486
[2] https://lkml.org/lkml/2017/4/5/402
Jonathan (Zhixiong) Zhang (2):
arm64: hwpoison: add VM_FAULT_HWPOISON[_LARGE] handling
arm64: kconfig: allow support for memory failure handling
Punit Agrawal (2):
arm64: hugetlb: Fix huge_pte_offset to return poisoned page table
entries
arm64: mm: Update perf accounting to handle poison faults
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/mm/fault.c | 90 ++++++++++++++++++++++++----------------
arch/arm64/mm/hugetlbpage.c | 29 +++++--------
4 files changed, 67 insertions(+), 55 deletions(-)
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/4] arm64: hugetlb: Fix huge_pte_offset to return poisoned page table entries
2017-06-08 17:25 [PATCH v3 0/4] arm64: Add support for handling memory corruption Punit Agrawal
@ 2017-06-08 17:25 ` Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 2/4] arm64: hwpoison: add VM_FAULT_HWPOISON[_LARGE] handling Punit Agrawal
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Punit Agrawal @ 2017-06-08 17:25 UTC (permalink / raw)
To: catalin.marinas, will.deacon
Cc: Punit Agrawal, tbaicar, steve.capper, linux-arm-kernel,
linux-kernel, manoj.iyer, David Woods
When memory failure is enabled, a poisoned hugepage pte is marked as a
swap entry. huge_pte_offset() does not return the poisoned page table
entries when it encounters PUD/PMD hugepages.
This behaviour of huge_pte_offset() leads to error such as below when
munmap is called on poisoned hugepages.
[ 344.165544] mm/pgtable-generic.c:33: bad pmd 000000083af00074.
Fix huge_pte_offset() to return the poisoned pte which is then
appropriately handled by the generic layer code.
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Steve Capper <steve.capper@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Woods <dwoods@mellanox.com>
Tested-by: Manoj Iyer <manoj.iyer@canonical.com>
---
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/mm/hugetlbpage.c | 29 ++++++++++-------------------
2 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c213fdbd056c..6eae342ced6b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -441,7 +441,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
#define pud_none(pud) (!pud_val(pud))
#define pud_bad(pud) (!(pud_val(pud) & PUD_TABLE_BIT))
-#define pud_present(pud) (pud_val(pud))
+#define pud_present(pud) pte_present(pud_pte(pud))
static inline void set_pud(pud_t *pudp, pud_t pud)
{
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 7514a000e361..69b8200b1cfd 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -136,36 +136,27 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
- pmd_t *pmd = NULL;
- pte_t *pte = NULL;
+ pmd_t *pmd;
pgd = pgd_offset(mm, addr);
pr_debug("%s: addr:0x%lx pgd:%p\n", __func__, addr, pgd);
if (!pgd_present(*pgd))
return NULL;
+
pud = pud_offset(pgd, addr);
- if (!pud_present(*pud))
+ if (pud_none(*pud))
return NULL;
-
- if (pud_huge(*pud))
+ /* swap or huge page */
+ if (!pud_present(*pud) || pud_huge(*pud))
return (pte_t *)pud;
+ /* table; check the next level */
+
pmd = pmd_offset(pud, addr);
- if (!pmd_present(*pmd))
+ if (pmd_none(*pmd))
return NULL;
-
- if (pte_cont(pmd_pte(*pmd))) {
- pmd = pmd_offset(
- pud, (addr & CONT_PMD_MASK));
- return (pte_t *)pmd;
- }
- if (pmd_huge(*pmd))
+ if (!pmd_present(*pmd) || pmd_huge(*pmd))
return (pte_t *)pmd;
- pte = pte_offset_kernel(pmd, addr);
- if (pte_present(*pte) && pte_cont(*pte)) {
- pte = pte_offset_kernel(
- pmd, (addr & CONT_PTE_MASK));
- return pte;
- }
+
return NULL;
}
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/4] arm64: hwpoison: add VM_FAULT_HWPOISON[_LARGE] handling
2017-06-08 17:25 [PATCH v3 0/4] arm64: Add support for handling memory corruption Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 1/4] arm64: hugetlb: Fix huge_pte_offset to return poisoned page table entries Punit Agrawal
@ 2017-06-08 17:25 ` Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 3/4] arm64: mm: Update perf accounting to handle poison faults Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 4/4] arm64: kconfig: allow support for memory failure handling Punit Agrawal
3 siblings, 0 replies; 5+ messages in thread
From: Punit Agrawal @ 2017-06-08 17:25 UTC (permalink / raw)
To: catalin.marinas, will.deacon
Cc: Jonathan (Zhixiong) Zhang, tbaicar, steve.capper,
linux-arm-kernel, linux-kernel, manoj.iyer, Punit Agrawal
From: "Jonathan (Zhixiong) Zhang" <zjzhang@codeaurora.org>
Add VM_FAULT_HWPOISON[_LARGE] handling to the arm64 page fault
handler. Handling of VM_FAULT_HWPOISON[_LARGE] is very similar
to VM_FAULT_OOM, the only difference is that a different si_code
(BUS_MCEERR_AR) is passed to user space and si_addr_lsb field is
initialized.
Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
(fix new __do_user_fault call-site)
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Steve Capper <steve.capper@arm.com>
Tested-by: Manoj Iyer <manoj.iyer@canonical.com>
---
arch/arm64/mm/fault.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 37b95dff0b07..a85b44343ac6 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -31,6 +31,7 @@
#include <linux/highmem.h>
#include <linux/perf_event.h>
#include <linux/preempt.h>
+#include <linux/hugetlb.h>
#include <asm/bug.h>
#include <asm/cpufeature.h>
@@ -239,10 +240,11 @@ static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
*/
static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
unsigned int esr, unsigned int sig, int code,
- struct pt_regs *regs)
+ struct pt_regs *regs, int fault)
{
struct siginfo si;
const struct fault_info *inf;
+ unsigned int lsb = 0;
if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) {
inf = esr_to_fault_info(esr);
@@ -259,6 +261,17 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
si.si_errno = 0;
si.si_code = code;
si.si_addr = (void __user *)addr;
+ /*
+ * Either small page or large page may be poisoned.
+ * In other words, VM_FAULT_HWPOISON_LARGE and
+ * VM_FAULT_HWPOISON are mutually exclusive.
+ */
+ if (fault & VM_FAULT_HWPOISON_LARGE)
+ lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
+ else if (fault & VM_FAULT_HWPOISON)
+ lsb = PAGE_SHIFT;
+ si.si_addr_lsb = lsb;
+
force_sig_info(sig, &si, tsk);
}
@@ -274,7 +287,7 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
*/
if (user_mode(regs)) {
inf = esr_to_fault_info(esr);
- __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs);
+ __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs, 0);
} else
__do_kernel_fault(mm, addr, esr, regs);
}
@@ -461,6 +474,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
*/
sig = SIGBUS;
code = BUS_ADRERR;
+ } else if (fault & (VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) {
+ sig = SIGBUS;
+ code = BUS_MCEERR_AR;
} else {
/*
* Something tried to access memory that isn't in our memory
@@ -471,7 +487,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
SEGV_ACCERR : SEGV_MAPERR;
}
- __do_user_fault(tsk, addr, esr, sig, code, regs);
+ __do_user_fault(tsk, addr, esr, sig, code, regs, fault);
return 0;
no_context:
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 3/4] arm64: mm: Update perf accounting to handle poison faults
2017-06-08 17:25 [PATCH v3 0/4] arm64: Add support for handling memory corruption Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 1/4] arm64: hugetlb: Fix huge_pte_offset to return poisoned page table entries Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 2/4] arm64: hwpoison: add VM_FAULT_HWPOISON[_LARGE] handling Punit Agrawal
@ 2017-06-08 17:25 ` Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 4/4] arm64: kconfig: allow support for memory failure handling Punit Agrawal
3 siblings, 0 replies; 5+ messages in thread
From: Punit Agrawal @ 2017-06-08 17:25 UTC (permalink / raw)
To: catalin.marinas, will.deacon
Cc: Punit Agrawal, tbaicar, steve.capper, linux-arm-kernel,
linux-kernel, manoj.iyer
Re-organise the perf accounting for fault handling in preparation for
enabling handling of hardware poison faults in subsequent commits. The
change updates perf accounting to be inline with the behaviour on
x86.
With this update, the perf fault accounting -
* Always report PERF_COUNT_SW_PAGE_FAULTS
* Doesn't report anything else for VM_FAULT_ERROR (which includes
hwpoison faults)
* Reports PERF_COUNT_SW_PAGE_FAULTS_MAJ if it's a major
fault (indicated by VM_FAULT_MAJOR)
* Otherwise, reports PERF_COUNT_SW_PAGE_FAULTS_MIN
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
---
arch/arm64/mm/fault.c | 68 +++++++++++++++++++++++++++------------------------
1 file changed, 36 insertions(+), 32 deletions(-)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index a85b44343ac6..7e501e7faec1 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -342,7 +342,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
{
struct task_struct *tsk;
struct mm_struct *mm;
- int fault, sig, code;
+ int fault, sig, code, major = 0;
unsigned long vm_flags = VM_READ | VM_WRITE;
unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
@@ -381,6 +381,8 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
die("Accessing user space memory outside uaccess.h routines", regs, esr);
}
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+
/*
* As per x86, we may deadlock here. However, since the kernel only
* validly references user space from well defined areas of the code,
@@ -404,24 +406,42 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
}
fault = __do_page_fault(mm, addr, mm_flags, vm_flags, tsk);
+ major |= fault & VM_FAULT_MAJOR;
- /*
- * If we need to retry but a fatal signal is pending, handle the
- * signal first. We do not need to release the mmap_sem because it
- * would already be released in __lock_page_or_retry in mm/filemap.c.
- */
- if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
- return 0;
+ if (fault & VM_FAULT_RETRY) {
+ /*
+ * If we need to retry but a fatal signal is pending,
+ * handle the signal first. We do not need to release
+ * the mmap_sem because it would already be released
+ * in __lock_page_or_retry in mm/filemap.c.
+ */
+ if (fatal_signal_pending(current))
+ return 0;
+
+ /*
+ * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of
+ * starvation.
+ */
+ if (mm_flags & FAULT_FLAG_ALLOW_RETRY) {
+ mm_flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ mm_flags |= FAULT_FLAG_TRIED;
+ goto retry;
+ }
+ }
+ up_read(&mm->mmap_sem);
/*
- * Major/minor page fault accounting is only done on the initial
- * attempt. If we go through a retry, it is extremely likely that the
- * page will be found in page cache at that point.
+ * Handle the "normal" (no error) case first.
*/
-
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
- if (mm_flags & FAULT_FLAG_ALLOW_RETRY) {
- if (fault & VM_FAULT_MAJOR) {
+ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
+ VM_FAULT_BADACCESS)))) {
+ /*
+ * Major/minor page fault accounting is only done
+ * once. If we go through a retry, it is extremely
+ * likely that the page will be found in page cache at
+ * that point.
+ */
+ if (major) {
tsk->maj_flt++;
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs,
addr);
@@ -430,25 +450,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs,
addr);
}
- if (fault & VM_FAULT_RETRY) {
- /*
- * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of
- * starvation.
- */
- mm_flags &= ~FAULT_FLAG_ALLOW_RETRY;
- mm_flags |= FAULT_FLAG_TRIED;
- goto retry;
- }
- }
-
- up_read(&mm->mmap_sem);
- /*
- * Handle the "normal" case first - VM_FAULT_MAJOR
- */
- if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP |
- VM_FAULT_BADACCESS))))
return 0;
+ }
/*
* If we are in kernel mode at this point, we have no context to
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 4/4] arm64: kconfig: allow support for memory failure handling
2017-06-08 17:25 [PATCH v3 0/4] arm64: Add support for handling memory corruption Punit Agrawal
` (2 preceding siblings ...)
2017-06-08 17:25 ` [PATCH v3 3/4] arm64: mm: Update perf accounting to handle poison faults Punit Agrawal
@ 2017-06-08 17:25 ` Punit Agrawal
3 siblings, 0 replies; 5+ messages in thread
From: Punit Agrawal @ 2017-06-08 17:25 UTC (permalink / raw)
To: catalin.marinas, will.deacon
Cc: Jonathan (Zhixiong) Zhang, tbaicar, steve.capper,
linux-arm-kernel, linux-kernel, manoj.iyer, Punit Agrawal
From: "Jonathan (Zhixiong) Zhang" <zjzhang@codeaurora.org>
Declare ARCH_SUPPORTS_MEMORY_FAILURE, as arm64 does support
memory failure recovery attempt.
Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
(Dropped changes to ACPI APEI Kconfig and updated commit log)
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Steve Capper <steve.capper@arm.com>
Tested-by: Manoj Iyer <manoj.iyer@canonical.com>
---
arch/arm64/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3dcd7ec69bca..39986b63383e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -20,6 +20,7 @@ config ARM64
select ARCH_HAS_STRICT_MODULE_RWX
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_NUMA_BALANCING
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
--
2.11.0
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-06-08 17:26 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-08 17:25 [PATCH v3 0/4] arm64: Add support for handling memory corruption Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 1/4] arm64: hugetlb: Fix huge_pte_offset to return poisoned page table entries Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 2/4] arm64: hwpoison: add VM_FAULT_HWPOISON[_LARGE] handling Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 3/4] arm64: mm: Update perf accounting to handle poison faults Punit Agrawal
2017-06-08 17:25 ` [PATCH v3 4/4] arm64: kconfig: allow support for memory failure handling Punit Agrawal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®