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

!11783 mm: hwpoison: two more poison recovery

Merge Pull Request from: @ci-robot 
 
PR sync from: Tong Tiangen <tongtiangen@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/RDENVCUUSPOH5EES5HWF5FC623GF4ZLA/ 
One more CoW path to support poison recorvery in do_cow_fault(), and
the last copy_user_highpage() user is replaced to copy_mc_user_highpage()
from copy_present_page() during fork to support poison recorvery too.

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


-- 
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/IATH6V 
 
Link:https://gitee.com/openeuler/kernel/pulls/11783

 

Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 18f2b5db f034a32a
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -920,8 +920,11 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
	 * We have a prealloc page, all good!  Take it
	 * over and copy the page & arm it.
	 */

	if (copy_mc_user_highpage(&new_folio->page, page, addr, src_vma))
		return -EHWPOISON;

	*prealloc = NULL;
	copy_user_highpage(&new_folio->page, page, addr, src_vma);
	__folio_mark_uptodate(new_folio);
	folio_add_new_anon_rmap(new_folio, dst_vma, addr, RMAP_EXCLUSIVE);
	folio_add_lru_vma(new_folio, dst_vma);
@@ -1161,8 +1164,9 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
		/*
		 * If we need a pre-allocated page for this pte, drop the
		 * locks, allocate, and try again.
		 * If copy failed due to hwpoison in source page, break out.
		 */
		if (unlikely(ret == -EAGAIN))
		if (unlikely(ret == -EAGAIN || ret == -EHWPOISON))
			break;
		if (unlikely(prealloc)) {
			/*
@@ -1192,7 +1196,7 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
			goto out;
		}
		entry.val = 0;
	} else if (ret == -EBUSY) {
	} else if (ret == -EBUSY || unlikely(ret == -EHWPOISON)) {
		goto out;
	} else if (ret ==  -EAGAIN) {
		prealloc = folio_prealloc(src_mm, src_vma, addr, false);
@@ -5054,10 +5058,14 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
	if (ret & VM_FAULT_DONE_COW)
		return ret;

	copy_user_highpage(vmf->cow_page, vmf->page, vmf->address, vma);
	if (copy_mc_user_highpage(vmf->cow_page, vmf->page, vmf->address, vma)) {
		ret = VM_FAULT_HWPOISON;
		goto unlock;
	}
	__folio_mark_uptodate(folio);

	ret |= finish_fault(vmf);
unlock:
	unlock_page(vmf->page);
	put_page(vmf->page);
	if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))