diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index eadc37c30bb3bfeb7f3c3e5b072a2a58967ad689..9841df05b126f6ea014410da0a66bb347d8fa293 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -480,21 +481,19 @@ static void memory_failure_cb(struct callback_head *twork) unsigned long pfn = twcb->pfn; rc = memory_failure(pfn, twcb->flags); +#ifdef CONFIG_ARM64 + /* + * Remove a successfully recovered online page from the arm64 + * linear map to prevent speculative access to corrupted memory. + */ + if (!rc && pfn_to_online_page(pfn)) + set_memory_np((unsigned long)page_to_virt(pfn_to_page(pfn)), 1); +#endif kfree(twcb); if (!rc) return; - /* - * If the pfn reported by ghes can not be recovered, set - * the corresponding page table of linear mapping range - * to be non-present, which avoids the speculative - * access of corrupted memory. - */ -#ifdef CONFIG_ARM64 - set_memory_np((unsigned long)page_to_virt(pfn_to_page(pfn)), 1); -#endif - /* * -EHWPOISON from memory_failure() means that it already sent SIGBUS * to the current process with the proper error info, so no need to