From: Catalin Marinas <catalin.marinas@arm.com>
To: Yaxiong Tian <13327272236@163.com>
Cc: will@kernel.org, keescook@chromium.org, tianyaxiong@kylinos.cn,
xiongxin@kylinos.cn, rppt@kernel.org, tony.luck@intel.com,
gpiccoli@igalia.com, songshuaishuai@tinylab.org,
wangkefeng.wang@huawei.com, akpm@linux-foundation.org,
ardb@kernel.org, david@redhat.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2] arm64: hibernate: Fix level3 translation fault in swsusp_save()
Date: Fri, 12 Apr 2024 18:30:27 +0100 [thread overview]
Message-ID: <Zhlvs2ol7Va1r1Mr@arm.com> (raw)
In-Reply-To: <20240301021924.33210-1-13327272236@163.com>
For some reason I missed the updated patch.
On Fri, Mar 01, 2024 at 10:19:24AM +0800, Yaxiong Tian wrote:
> From: Yaxiong Tian <tianyaxiong@kylinos.cn>
>
> On ARM64 machines using UEFI, if can_set_direct_map() return false by
> setting some CONFIGS in kernel build or grub,such as
> NO CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT、NO CONFIG_KFENCE
> NO CONFIG_RODATA_FULL_DEFAULT_ENABLED.Also with setting rodata=off、
> debug_pagealloc=off in grub and NO CONFIG_KFENCE.
> swsusp_save() will fail due to can't finding the map table under the
> nomap memory.such as:
[...]
> [ 48.532162] Call trace:
> [ 48.532162] swsusp_save+0x280/0x538
> [ 48.532162] swsusp_arch_suspend+0x148/0x190
> [ 48.532162] hibernation_snapshot+0x240/0x39c
> [ 48.532162] hibernate+0xc4/0x378
> [ 48.532162] state_store+0xf0/0x10c
> [ 48.532162] kobj_attr_store+0x14/0x24
>
> This issue can be reproduced in QEMU using UEFI when booting with
> rodata=off、debug_pagealloc=off in grub and NO CONFIG_KFENCE.
>
> This is because in swsusp_save()->copy_data_pages()->page_is_saveable(),
> kernel_page_present() presumes that a page is present when can_set_direct_map()
> returns false even for NOMAP ranges.So NOMAP pages will saved in after,and then
> cause level3 translation fault in this pages.
I can see how kernel_page_present() ended up returning true if
!can_set_direct_map(), though based on the function naming only, it
feels a bit unintuitive. Is arm64 the only architecture making use of
MEMBLOCK_NOMAP? Or is it the only one where kernel_page_present() also
returns true if !can_set_direct_map()?
> diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
> index 02870beb271e..d90005de1d26 100644
> --- a/arch/arm64/kernel/hibernate.c
> +++ b/arch/arm64/kernel/hibernate.c
> @@ -94,7 +94,7 @@ int pfn_is_nosave(unsigned long pfn)
> unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1);
>
> return ((pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn)) ||
> - crash_is_nosave(pfn);
> + crash_is_nosave(pfn) || !pfn_is_map_memory(pfn);
> }
This indeed fixes the problem but it looks like an arm64-specific
workaround. I can see at least arm, loongarch and riscv making use of
memblock_is_map_memory() (which is what pfn_is_map_memory() calls). Do
they not have the same problem? On riscv, for example,
kernel_page_present() does not depend on any ARCH_HAS_SET_DIRECT_MAP
related options/conditions (neither does x86 though not sure it cares
about MEMBLOCK_NOMAP). Should we do the same for arm64 and drop the
!can_set_direct_map() condition in kernel_page_present()?
--
Catalin
WARNING: multiple messages have this Message-ID (diff)
From: Catalin Marinas <catalin.marinas@arm.com>
To: Yaxiong Tian <13327272236@163.com>
Cc: will@kernel.org, keescook@chromium.org, tianyaxiong@kylinos.cn,
xiongxin@kylinos.cn, rppt@kernel.org, tony.luck@intel.com,
gpiccoli@igalia.com, songshuaishuai@tinylab.org,
wangkefeng.wang@huawei.com, akpm@linux-foundation.org,
ardb@kernel.org, david@redhat.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2] arm64: hibernate: Fix level3 translation fault in swsusp_save()
Date: Fri, 12 Apr 2024 18:30:27 +0100 [thread overview]
Message-ID: <Zhlvs2ol7Va1r1Mr@arm.com> (raw)
In-Reply-To: <20240301021924.33210-1-13327272236@163.com>
For some reason I missed the updated patch.
On Fri, Mar 01, 2024 at 10:19:24AM +0800, Yaxiong Tian wrote:
> From: Yaxiong Tian <tianyaxiong@kylinos.cn>
>
> On ARM64 machines using UEFI, if can_set_direct_map() return false by
> setting some CONFIGS in kernel build or grub,such as
> NO CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT、NO CONFIG_KFENCE
> NO CONFIG_RODATA_FULL_DEFAULT_ENABLED.Also with setting rodata=off、
> debug_pagealloc=off in grub and NO CONFIG_KFENCE.
> swsusp_save() will fail due to can't finding the map table under the
> nomap memory.such as:
[...]
> [ 48.532162] Call trace:
> [ 48.532162] swsusp_save+0x280/0x538
> [ 48.532162] swsusp_arch_suspend+0x148/0x190
> [ 48.532162] hibernation_snapshot+0x240/0x39c
> [ 48.532162] hibernate+0xc4/0x378
> [ 48.532162] state_store+0xf0/0x10c
> [ 48.532162] kobj_attr_store+0x14/0x24
>
> This issue can be reproduced in QEMU using UEFI when booting with
> rodata=off、debug_pagealloc=off in grub and NO CONFIG_KFENCE.
>
> This is because in swsusp_save()->copy_data_pages()->page_is_saveable(),
> kernel_page_present() presumes that a page is present when can_set_direct_map()
> returns false even for NOMAP ranges.So NOMAP pages will saved in after,and then
> cause level3 translation fault in this pages.
I can see how kernel_page_present() ended up returning true if
!can_set_direct_map(), though based on the function naming only, it
feels a bit unintuitive. Is arm64 the only architecture making use of
MEMBLOCK_NOMAP? Or is it the only one where kernel_page_present() also
returns true if !can_set_direct_map()?
> diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
> index 02870beb271e..d90005de1d26 100644
> --- a/arch/arm64/kernel/hibernate.c
> +++ b/arch/arm64/kernel/hibernate.c
> @@ -94,7 +94,7 @@ int pfn_is_nosave(unsigned long pfn)
> unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1);
>
> return ((pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn)) ||
> - crash_is_nosave(pfn);
> + crash_is_nosave(pfn) || !pfn_is_map_memory(pfn);
> }
This indeed fixes the problem but it looks like an arm64-specific
workaround. I can see at least arm, loongarch and riscv making use of
memblock_is_map_memory() (which is what pfn_is_map_memory() calls). Do
they not have the same problem? On riscv, for example,
kernel_page_present() does not depend on any ARCH_HAS_SET_DIRECT_MAP
related options/conditions (neither does x86 though not sure it cares
about MEMBLOCK_NOMAP). Should we do the same for arm64 and drop the
!can_set_direct_map() condition in kernel_page_present()?
--
Catalin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-04-12 17:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-26 3:42 [PATCH] PM: hibernate: Fix level3 translation fault in swsusp_save() Yaxiong Tian
2024-02-26 8:37 ` David Hildenbrand
2024-02-26 9:14 ` Mike Rapoport
2024-02-27 7:51 ` Yaxiong Tian
2024-02-29 9:42 ` Mike Rapoport
2024-03-01 2:19 ` [PATCH v2] arm64: " Yaxiong Tian
2024-03-01 2:19 ` Yaxiong Tian
2024-04-12 17:30 ` Catalin Marinas [this message]
2024-04-12 17:30 ` Catalin Marinas
2024-04-17 2:13 ` Yaxiong Tian
2024-04-17 2:13 ` Yaxiong Tian
2024-03-01 2:55 ` [PATCH] PM: " Yaxiong Tian
-- strict thread matches above, loose matches on Subject: below --
2024-02-27 7:54 [PATCH v2] arm64: " Yaxiong Tian
2024-02-27 7:54 ` Yaxiong Tian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Zhlvs2ol7Va1r1Mr@arm.com \
--to=catalin.marinas@arm.com \
--cc=13327272236@163.com \
--cc=akpm@linux-foundation.org \
--cc=ardb@kernel.org \
--cc=david@redhat.com \
--cc=gpiccoli@igalia.com \
--cc=keescook@chromium.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rppt@kernel.org \
--cc=songshuaishuai@tinylab.org \
--cc=tianyaxiong@kylinos.cn \
--cc=tony.luck@intel.com \
--cc=wangkefeng.wang@huawei.com \
--cc=will@kernel.org \
--cc=xiongxin@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.