mm/hwpoison: introduce copy_mc_highpage
Similar to how copy_mc_user_highpage is implemented for copy_user_highpage on #MC supported architecture, introduce the #MC handled version of copy_highpage. This helper has immediate usage when khugepaged wants to copy file-backed memory pages and tolerate #MC. Link: https://lkml.kernel.org/r/20230329151121.949896-3-jiaqiyan@google.com Signed-off-by: Jiaqi Yan <jiaqiyan@google.com> Reviewed-by: Yang Shi <shy828301@gmail.com> Cc: David Stevens <stevensd@chromium.org> Cc: Hugh Dickins <hughd@google.com> Cc: Kefeng Wang <wangkefeng.wang@huawei.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Cc: Miaohe Lin <linmiaohe@huawei.com> Cc: Naoya Horiguchi <naoya.horiguchi@nec.com> Cc: Oscar Salvador <osalvador@suse.de> Cc: Tong Tiangen <tongtiangen@huawei.com> Cc: Tony Luck <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
98c76c9f1e
commit
6efc7afb5c
@ -315,7 +315,29 @@ static inline void copy_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_COPY_HIGHPAGE
|
||||
|
||||
static inline void copy_highpage(struct page *to, struct page *from)
|
||||
{
|
||||
char *vfrom, *vto;
|
||||
|
||||
vfrom = kmap_local_page(from);
|
||||
vto = kmap_local_page(to);
|
||||
copy_page(vto, vfrom);
|
||||
kmsan_copy_page_meta(to, from);
|
||||
kunmap_local(vto);
|
||||
kunmap_local(vfrom);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef copy_mc_to_kernel
|
||||
/*
|
||||
* If architecture supports machine check exception handling, define the
|
||||
* #MC versions of copy_user_highpage and copy_highpage. They copy a memory
|
||||
* page with #MC in source page (@from) handled, and return the number
|
||||
* of bytes not copied if there was a #MC, otherwise 0 for success.
|
||||
*/
|
||||
static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
@ -332,6 +354,22 @@ static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int copy_mc_highpage(struct page *to, struct page *from)
|
||||
{
|
||||
unsigned long ret;
|
||||
char *vfrom, *vto;
|
||||
|
||||
vfrom = kmap_local_page(from);
|
||||
vto = kmap_local_page(to);
|
||||
ret = copy_mc_to_kernel(vto, vfrom, PAGE_SIZE);
|
||||
if (!ret)
|
||||
kmsan_copy_page_meta(to, from);
|
||||
kunmap_local(vto);
|
||||
kunmap_local(vfrom);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long vaddr, struct vm_area_struct *vma)
|
||||
@ -339,22 +377,12 @@ static inline int copy_mc_user_highpage(struct page *to, struct page *from,
|
||||
copy_user_highpage(to, from, vaddr, vma);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_COPY_HIGHPAGE
|
||||
|
||||
static inline void copy_highpage(struct page *to, struct page *from)
|
||||
static inline int copy_mc_highpage(struct page *to, struct page *from)
|
||||
{
|
||||
char *vfrom, *vto;
|
||||
|
||||
vfrom = kmap_local_page(from);
|
||||
vto = kmap_local_page(to);
|
||||
copy_page(vto, vfrom);
|
||||
kmsan_copy_page_meta(to, from);
|
||||
kunmap_local(vto);
|
||||
kunmap_local(vfrom);
|
||||
copy_highpage(to, from);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void memcpy_page(struct page *dst_page, size_t dst_off,
|
||||
|
Loading…
x
Reference in New Issue
Block a user