[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250926054402.1571-1-wangchuanguo@inspur.com>
Date: Fri, 26 Sep 2025 13:44:02 +0800
From: wangchuanguo <wangchuanguo@...pur.com>
To: <tony.luck@...el.com>, <bp@...en8.de>
CC: <tglx@...utronix.de>, <mingo@...hat.com>, <dave.hansen@...ux.intel.com>,
<x86@...nel.org>, <hpa@...or.com>, <linux-edac@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, wangchuanguo <wangchuanguo@...pur.com>
Subject: [PATCH] x86/mce: deal with UCE when copy clean pagecache to user space
Based on copy_from_user, extending the goal to unmap,discard,
and remap when errors occur in clean pagecache.
Signed-off-by: wangchuanguo <wangchuanguo@...pur.com>
---
arch/x86/kernel/cpu/mce/severity.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/severity.c b/arch/x86/kernel/cpu/mce/severity.c
index 2235a7477436..d1fc9568fa71 100644
--- a/arch/x86/kernel/cpu/mce/severity.c
+++ b/arch/x86/kernel/cpu/mce/severity.c
@@ -231,8 +231,22 @@ static struct severity {
#define mc_recoverable(mcg) (((mcg) & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) == \
(MCG_STATUS_RIPV|MCG_STATUS_EIPV))
-
-static bool is_copy_from_user(struct pt_regs *regs)
+static bool is_clean_pagecache(unsigned long addr)
+{
+ if (virt_addr_valid(addr)) {
+ struct page *page;
+
+ page = virt_to_page(addr);
+ if (page) {
+ if (!PageSlab(page) && !PageAnon(page)) {
+ if (!PageDirty(page))
+ return true;
+ }
+ }
+ }
+ return false;
+}
+static bool is_copy_user(struct pt_regs *regs)
{
u8 insn_buf[MAX_INSN_SIZE];
unsigned long addr;
@@ -264,8 +278,14 @@ static bool is_copy_from_user(struct pt_regs *regs)
return false;
}
- if (fault_in_kernel_space(addr))
- return false;
+ if (fault_in_kernel_space(addr)) {
+ if (is_clean_pagecache(addr) && !fault_in_kernel_space(regs->di)) {
+ //is copying clean pagecache to user space
+ addr = regs->di;
+ } else {
+ return false;
+ }
+ }
current->mce_vaddr = (void __user *)addr;
@@ -297,7 +317,7 @@ static noinstr int error_context(struct mce *m, struct pt_regs *regs)
/* Allow instrumentation around external facilities usage. */
instrumentation_begin();
fixup_type = ex_get_fixup_type(m->ip);
- copy_user = is_copy_from_user(regs);
+ copy_user = is_copy_user(regs);
instrumentation_end();
if (copy_user) {
--
2.39.3
Powered by blists - more mailing lists