Unverified Commit a2a2cb65 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13125 v7 mm: support poison recover for more

Merge Pull Request from: @ci-robot 
 
PR sync from: Wupeng Ma <mawupeng1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/5TXDE65HGQWLNHIZTUCQ65YNICS7EUA4/ 
From: Ma Wupeng <mawupeng1@huawei.com>

Add machine check safe support for cow & migrate_pages.
Avoid kernel panic during arm64_do_kernel_sea if no valid info is
reported.

Changelog since v5:
- cleanup in patch #6

Changelog since v3:
- backport bugfix commit 88e4f525002b ("mm/hugetlb: add missing VM_FAULT_SET_HINDEX in hugetlb_wp")

Changelog since v1:
- fix incorrect patch format

Kefeng Wang (2):
  mm: support poison recovery from copy_present_page()
  mm: support poison recovery from do_cow_fault()

Liu Shixin (1):
  mm: hwpoison: support recovery from HugePage copy-on-write faults

Ma Wupeng (2):
  arm64: mm: Add copy mc support for all migrate_page
  arm64: send sig fault for user task when apei_claim_sea fails

Oscar Salvador (1):
  mm/hugetlb: add missing VM_FAULT_SET_HINDEX in hugetlb_wp

Tong Tiangen (1):
  make copy_[user]_highpage_mc have return value


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/IB0OV7 
 
Link:https://gitee.com/openeuler/kernel/pulls/13125

 

Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents d14b2a1c 5d57512c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -29,12 +29,12 @@ void copy_highpage(struct page *to, struct page *from);
#define __HAVE_ARCH_COPY_HIGHPAGE

#ifdef CONFIG_ARCH_HAS_COPY_MC
extern void copy_page_mc(void *to, const void *from);
void copy_highpage_mc(struct page *to, struct page *from);
extern int copy_page_mc(void *to, const void *from);
int copy_highpage_mc(struct page *to, struct page *from);
int copy_mc_highpage(struct page *to, struct page *from);
#define __HAVE_ARCH_COPY_HIGHPAGE_MC

void copy_user_highpage_mc(struct page *to, struct page *from,
int copy_user_highpage_mc(struct page *to, struct page *from,
		unsigned long vaddr, struct vm_area_struct *vma);
#define __HAVE_ARCH_COPY_USER_HIGHPAGE_MC
#endif
+5 −1
Original line number Diff line number Diff line
@@ -74,7 +74,11 @@ CPY_MC(9998f, stnp x12, x13, [x0, #80 - 256])
CPY_MC(9998f, stnp	x14, x15, [x0, #96 - 256])
CPY_MC(9998f, stnp	x16, x17, [x0, #112 - 256])

9998:	ret
	mov x0, #0
	ret

9998:	mov x0, #-EFAULT
	ret

SYM_FUNC_END(copy_page_mc)
EXPORT_SYMBOL(copy_page_mc)
+15 −6
Original line number Diff line number Diff line
@@ -44,21 +44,30 @@ void copy_user_highpage(struct page *to, struct page *from,
EXPORT_SYMBOL_GPL(copy_user_highpage);

#ifdef CONFIG_ARCH_HAS_COPY_MC
void copy_highpage_mc(struct page *to, struct page *from)
int copy_highpage_mc(struct page *to, struct page *from)
{
	void *kto = page_address(to);
	void *kfrom = page_address(from);
	int ret;

	copy_page_mc(kto, kfrom);
	ret = copy_page_mc(kto, kfrom);
	if (!ret)
		do_mte(to, from, kto, kfrom, true);

	return ret;
}
EXPORT_SYMBOL(copy_highpage_mc);

void copy_user_highpage_mc(struct page *to, struct page *from,
int copy_user_highpage_mc(struct page *to, struct page *from,
			unsigned long vaddr, struct vm_area_struct *vma)
{
	copy_highpage_mc(to, from);
	int ret;

	ret = copy_highpage_mc(to, from);
	if (!ret)
		flush_dcache_page(to);

	return ret;
}
EXPORT_SYMBOL_GPL(copy_user_highpage_mc);

+12 −5
Original line number Diff line number Diff line
@@ -729,6 +729,9 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
static bool arm64_do_kernel_sea(void __user *addr, unsigned int esr,
				struct pt_regs *regs, int sig, int code)
{
	u64 orig_pc = regs->pc;
	int err;

	if (!IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC))
		return false;

@@ -738,14 +741,18 @@ static bool arm64_do_kernel_sea(void __user *addr, unsigned int esr,
	if (user_mode(regs))
		return false;

	if (apei_claim_sea(regs) < 0)
		return false;

	if (!fixup_exception_mc(regs))
		return false;

	if (current->flags & PF_KTHREAD)
		return true;
	err = apei_claim_sea(regs);
	if (err) {
		regs->pc = orig_pc;
		pr_emerg("apei claim sea failed. addr: %#lx, esr: %#x\n",
			 (unsigned long)addr, esr);
	}

	if (!current->mm)
		return err ? false : true;

	set_thread_esr(0, esr);
	arm64_force_sig_fault(sig, code, addr,
+11 −2
Original line number Diff line number Diff line
@@ -342,7 +342,12 @@ static inline void copy_user_highpage(struct page *to, struct page *from,
#endif

#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE_MC
#define copy_user_highpage_mc copy_user_highpage
static inline int copy_user_highpage_mc(struct page *to, struct page *from,
	unsigned long vaddr, struct vm_area_struct *vma)
{
	copy_user_highpage(to, from, vaddr, vma);
	return 0;
}
#endif

#ifndef __HAVE_ARCH_COPY_HIGHPAGE
@@ -361,7 +366,11 @@ static inline void copy_highpage(struct page *to, struct page *from)
#endif

#ifndef __HAVE_ARCH_COPY_HIGHPAGE_MC
#define copy_highpage_mc copy_highpage
static inline int copy_highpage_mc(struct page *to, struct page *from)
{
	copy_highpage(to, from);
	return 0;
}
#endif

#ifndef __HAVE_ARCH_COPY_HUGEPAGES
Loading