All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <ajones@ventanamicro.com>
To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
Cc: "paul.walmsley@sifive.com" <paul.walmsley@sifive.com>,
	"palmer@dabbelt.com" <palmer@dabbelt.com>,
	"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Leyfoon Tan <leyfoon.tan@starfivetech.com>,
	Mason Huo <mason.huo@starfivetech.com>
Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
Date: Fri, 24 Feb 2023 10:55:26 +0100	[thread overview]
Message-ID: <20230224095526.ctctpzw3p3csf6qj@orel> (raw)
In-Reply-To: <9cfd485d1e0d46cdb1323bb6ea330f6e@EXMBX066.cuchost.com>

On Fri, Feb 24, 2023 at 09:33:31AM +0000, JeeHeng Sia wrote:
> 
> 
> > -----Original Message-----
> > From: Andrew Jones <ajones@ventanamicro.com>
> > Sent: Friday, 24 February, 2023 5:00 PM
> > To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
> > Cc: paul.walmsley@sifive.com; palmer@dabbelt.com; aou@eecs.berkeley.edu; linux-riscv@lists.infradead.org; linux-
> > kernel@vger.kernel.org; Leyfoon Tan <leyfoon.tan@starfivetech.com>; Mason Huo <mason.huo@starfivetech.com>
> > Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
> > 
> > On Fri, Feb 24, 2023 at 02:05:43AM +0000, JeeHeng Sia wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Andrew Jones <ajones@ventanamicro.com>
> > > > Sent: Friday, 24 February, 2023 2:07 AM
> > > > To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
> > > > Cc: paul.walmsley@sifive.com; palmer@dabbelt.com; aou@eecs.berkeley.edu; linux-riscv@lists.infradead.org; linux-
> > > > kernel@vger.kernel.org; Leyfoon Tan <leyfoon.tan@starfivetech.com>; Mason Huo <mason.huo@starfivetech.com>
> > > > Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
> > > >
> > > > On Tue, Feb 21, 2023 at 10:35:23AM +0800, Sia Jee Heng wrote:
> > > > > Low level Arch functions were created to support hibernation.
> > > > > swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write
> > > > > cpu state onto the stack, then calling swsusp_save() to save the memory
> > > > > image.
> > > > >
> > > > > Arch specific hibernation header is implemented and is utilized by the
> > > > > arch_hibernation_header_restore() and arch_hibernation_header_save()
> > > > > functions. The arch specific hibernation header consists of satp, hartid,
> > > > > and the cpu_resume address. The kernel built version is also need to be
> > > > > saved into the hibernation image header to making sure only the same
> > > > > kernel is restore when resume.
> > > > >
> > > > > swsusp_arch_resume() creates a temporary page table that covering only
> > > > > the linear map. It copies the restore code to a 'safe' page, then start
> > > > > to restore the memory image. Once completed, it restores the original
> > > > > kernel's page table. It then calls into __hibernate_cpu_resume()
> > > > > to restore the CPU context. Finally, it follows the normal hibernation
> > > > > path back to the hibernation core.
> > > > >
> > > > > To enable hibernation/suspend to disk into RISCV, the below config
> > > > > need to be enabled:
> > > > > - CONFIG_ARCH_HIBERNATION_HEADER
> > > > > - CONFIG_ARCH_HIBERNATION_POSSIBLE
> > > > >
> > > > > Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
> > > > > Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
> > > > > Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
> > > > > ---
> > > > >  arch/riscv/Kconfig                 |   7 +
> > > > >  arch/riscv/include/asm/assembler.h |  20 ++
> > > > >  arch/riscv/include/asm/suspend.h   |  19 ++
> > > > >  arch/riscv/kernel/Makefile         |   1 +
> > > > >  arch/riscv/kernel/asm-offsets.c    |   5 +
> > > > >  arch/riscv/kernel/hibernate-asm.S  |  77 +++++
> > > > >  arch/riscv/kernel/hibernate.c      | 447 +++++++++++++++++++++++++++++
> > > > >  7 files changed, 576 insertions(+)
> > > > >  create mode 100644 arch/riscv/kernel/hibernate-asm.S
> > > > >  create mode 100644 arch/riscv/kernel/hibernate.c
> > > > >
> > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > > > > index e2b656043abf..4555848a817f 100644
> > > > > --- a/arch/riscv/Kconfig
> > > > > +++ b/arch/riscv/Kconfig
> > > > > @@ -690,6 +690,13 @@ menu "Power management options"
> > > > >
> > > > >  source "kernel/power/Kconfig"
> > > > >
> > > > > +config ARCH_HIBERNATION_POSSIBLE
> > > > > +	def_bool y
> > > > > +
> > > > > +config ARCH_HIBERNATION_HEADER
> > > > > +	def_bool y
> > > > > +	depends on HIBERNATION
> > > >
> > > > nit: I think this can be simplified as def_bool HIBERNATION
> > > good suggestion. will change it.
> > > >
> > > > > +
> > > > >  endmenu # "Power management options"
> > > > >
> > > > >  menu "CPU Power Management"
> > > > > diff --git a/arch/riscv/include/asm/assembler.h b/arch/riscv/include/asm/assembler.h
> > > > > index 727a97735493..68c46c0e0ea8 100644
> > > > > --- a/arch/riscv/include/asm/assembler.h
> > > > > +++ b/arch/riscv/include/asm/assembler.h
> > > > > @@ -59,4 +59,24 @@
> > > > >  		REG_L	s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
> > > > >  	.endm
> > > > >
> > > > > +/*
> > > > > + * copy_page - copy 1 page (4KB) of data from source to destination
> > > > > + * @a0 - destination
> > > > > + * @a1 - source
> > > > > + */
> > > > > +	.macro	copy_page a0, a1
> > > > > +		lui	a2, 0x1
> > > > > +		add	a2, a2, a0
> > > > > +1 :
> > > >     ^ please remove this space
> > > can't remove it otherwise checkpatch will throws ERROR: spaces required around that ':'
> > 
> > Oh, right, labels in macros have this requirement.
> > 
> > > >
> > > > > +		REG_L	t0, 0(a1)
> > > > > +		REG_L	t1, SZREG(a1)
> > > > > +
> > > > > +		REG_S	t0, 0(a0)
> > > > > +		REG_S	t1, SZREG(a0)
> > > > > +
> > > > > +		addi	a0, a0, 2 * SZREG
> > > > > +		addi	a1, a1, 2 * SZREG
> > > > > +		bne	a2, a0, 1b
> > > > > +	.endm
> > > > > +
> > > > >  #endif	/* __ASM_ASSEMBLER_H */
> > > > > diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h
> > > > > index 75419c5ca272..3362da56a9d8 100644
> > > > > --- a/arch/riscv/include/asm/suspend.h
> > > > > +++ b/arch/riscv/include/asm/suspend.h
> > > > > @@ -21,6 +21,11 @@ struct suspend_context {
> > > > >  #endif
> > > > >  };
> > > > >
> > > > > +/*
> > > > > + * Used by hibernation core and cleared during resume sequence
> > > > > + */
> > > > > +extern int in_suspend;
> > > > > +
> > > > >  /* Low-level CPU suspend entry function */
> > > > >  int __cpu_suspend_enter(struct suspend_context *context);
> > > > >
> > > > > @@ -36,4 +41,18 @@ int __cpu_resume_enter(unsigned long hartid, unsigned long context);
> > > > >  /* Used to save and restore the csr */
> > > > >  void suspend_save_csrs(struct suspend_context *context);
> > > > >  void suspend_restore_csrs(struct suspend_context *context);
> > > > > +
> > > > > +/* Low-level API to support hibernation */
> > > > > +int swsusp_arch_suspend(void);
> > > > > +int swsusp_arch_resume(void);
> > > > > +int arch_hibernation_header_save(void *addr, unsigned int max_size);
> > > > > +int arch_hibernation_header_restore(void *addr);
> > > > > +int __hibernate_cpu_resume(void);
> > > > > +
> > > > > +/* Used to resume on the CPU we hibernated on */
> > > > > +int hibernate_resume_nonboot_cpu_disable(void);
> > > > > +
> > > > > +asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp,
> > > > > +					unsigned long cpu_resume);
> > > > > +asmlinkage int hibernate_core_restore_code(void);
> > > > >  #endif
> > > > > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > > > > index 4cf303a779ab..daab341d55e4 100644
> > > > > --- a/arch/riscv/kernel/Makefile
> > > > > +++ b/arch/riscv/kernel/Makefile
> > > > > @@ -64,6 +64,7 @@ obj-$(CONFIG_MODULES)		+= module.o
> > > > >  obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
> > > > >
> > > > >  obj-$(CONFIG_CPU_PM)		+= suspend_entry.o suspend.o
> > > > > +obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate-asm.o
> > > > >
> > > > >  obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
> > > > >  obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
> > > > > diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> > > > > index df9444397908..d6a75aac1d27 100644
> > > > > --- a/arch/riscv/kernel/asm-offsets.c
> > > > > +++ b/arch/riscv/kernel/asm-offsets.c
> > > > > @@ -9,6 +9,7 @@
> > > > >  #include <linux/kbuild.h>
> > > > >  #include <linux/mm.h>
> > > > >  #include <linux/sched.h>
> > > > > +#include <linux/suspend.h>
> > > > >  #include <asm/kvm_host.h>
> > > > >  #include <asm/thread_info.h>
> > > > >  #include <asm/ptrace.h>
> > > > > @@ -116,6 +117,10 @@ void asm_offsets(void)
> > > > >
> > > > >  	OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
> > > > >
> > > > > +	OFFSET(HIBERN_PBE_ADDR, pbe, address);
> > > > > +	OFFSET(HIBERN_PBE_ORIG, pbe, orig_address);
> > > > > +	OFFSET(HIBERN_PBE_NEXT, pbe, next);
> > > > > +
> > > > >  	OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
> > > > >  	OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
> > > > >  	OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
> > > > > diff --git a/arch/riscv/kernel/hibernate-asm.S b/arch/riscv/kernel/hibernate-asm.S
> > > > > new file mode 100644
> > > > > index 000000000000..846affe4dced
> > > > > --- /dev/null
> > > > > +++ b/arch/riscv/kernel/hibernate-asm.S
> > > > > @@ -0,0 +1,77 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > > +/*
> > > > > + * Hibernation low level support for RISCV.
> > > > > + *
> > > > > + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> > > > > + *
> > > > > + * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
> > > > > + */
> > > > > +
> > > > > +#include <asm/asm.h>
> > > > > +#include <asm/asm-offsets.h>
> > > > > +#include <asm/assembler.h>
> > > > > +#include <asm/csr.h>
> > > > > +
> > > > > +#include <linux/linkage.h>
> > > > > +
> > > > > +/*
> > > > > + * int __hibernate_cpu_resume(void)
> > > > > + * Switch back to the hibernated image's page table prior to restoring the CPU
> > > > > + * context.
> > > > > + *
> > > > > + * Always returns 0
> > > > > + */
> > > > > +ENTRY(__hibernate_cpu_resume)
> > > > > +	/* switch to hibernated image's page table. */
> > > > > +	csrw CSR_SATP, s0
> > > > > +	sfence.vma
> > > > > +
> > > > > +	REG_L	a0, hibernate_cpu_context
> > > > > +
> > > > > +	restore_csr
> > > > > +	restore_reg
> > > > > +
> > > > > +	/* Return zero value. */
> > > > > +	add	a0, zero, zero
> > > >
> > > > nit: mv a0, zero
> > > sure
> > > >
> > > > > +
> > > > > +	ret
> > > > > +END(__hibernate_cpu_resume)
> > > > > +
> > > > > +/*
> > > > > + * Prepare to restore the image.
> > > > > + * a0: satp of saved page tables.
> > > > > + * a1: satp of temporary page tables.
> > > > > + * a2: cpu_resume.
> > > > > + */
> > > > > +ENTRY(hibernate_restore_image)
> > > > > +	mv	s0, a0
> > > > > +	mv	s1, a1
> > > > > +	mv	s2, a2
> > > > > +	REG_L	s4, restore_pblist
> > > > > +	REG_L	a1, relocated_restore_code
> > > > > +
> > > > > +	jalr	a1
> > > > > +END(hibernate_restore_image)
> > > > > +
> > > > > +/*
> > > > > + * The below code will be executed from a 'safe' page.
> > > > > + * It first switches to the temporary page table, then starts to copy the pages
> > > > > + * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume()
> > > > > + * to restore the CPU context.
> > > > > + */
> > > > > +ENTRY(hibernate_core_restore_code)
> > > > > +	/* switch to temp page table. */
> > > > > +	csrw satp, s1
> > > > > +	sfence.vma
> > > > > +.Lcopy:
> > > > > +	/* The below code will restore the hibernated image. */
> > > > > +	REG_L	a1, HIBERN_PBE_ADDR(s4)
> > > > > +	REG_L	a0, HIBERN_PBE_ORIG(s4)
> > > >
> > > > Are we sure restore_pblist will never be NULL?
> > > restore_pblist is a link-list, it will be null during initialization or during page clean up by hibernation core. During the initial resume
> > process, the hibernation core will check the header and load the pages. If everything works correctly, the page will be linked to the
> > restore_pblist and then invoke swsusp_arch_resume() else hibernation core will throws error and failed to resume from the
> > hibernated image.
> > 
> > I know restore_pblist is a linked-list and this doesn't answer the
> > question. The comment above restore_pblist says
> > 
> > /*
> >  * List of PBEs needed for restoring the pages that were allocated before
> >  * the suspend and included in the suspend image, but have also been
> >  * allocated by the "resume" kernel, so their contents cannot be written
> >  * directly to their "original" page frames.
> >  */
> > 
> > which implies the pages that end up on this list are "special". My
> > question is whether or not we're guaranteed to have at least one
> > of these special pages. If not, we shouldn't assume s4 is non-null.
> > If so, then a comment stating why that's guaranteed would be nice.
> The restore_pblist will not be null otherwise swsusp_arch_resume wouldn't get invoked. you can find how the link-list are link and how it checks against validity at https://elixir.bootlin.com/linux/v6.2-rc8/source/kernel/power/snapshot.c . " A comment stating why that's guaranteed would be nice" ? Hmm, perhaps this is out of my scope but I do believe in the page validity checking in the link I shared.

Sorry, but pointing to an entire source file (one that I've obviously
already looked at, since I quoted a comment from it...) is not helpful.
I don't see where restore_pblist is being checked before
swsusp_arch_resume() is issued (from its callsite in hibernate.c).

Thanks,
drew

WARNING: multiple messages have this Message-ID (diff)
From: Andrew Jones <ajones@ventanamicro.com>
To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
Cc: "paul.walmsley@sifive.com" <paul.walmsley@sifive.com>,
	"palmer@dabbelt.com" <palmer@dabbelt.com>,
	"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Leyfoon Tan <leyfoon.tan@starfivetech.com>,
	Mason Huo <mason.huo@starfivetech.com>
Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
Date: Fri, 24 Feb 2023 10:55:26 +0100	[thread overview]
Message-ID: <20230224095526.ctctpzw3p3csf6qj@orel> (raw)
In-Reply-To: <9cfd485d1e0d46cdb1323bb6ea330f6e@EXMBX066.cuchost.com>

On Fri, Feb 24, 2023 at 09:33:31AM +0000, JeeHeng Sia wrote:
> 
> 
> > -----Original Message-----
> > From: Andrew Jones <ajones@ventanamicro.com>
> > Sent: Friday, 24 February, 2023 5:00 PM
> > To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
> > Cc: paul.walmsley@sifive.com; palmer@dabbelt.com; aou@eecs.berkeley.edu; linux-riscv@lists.infradead.org; linux-
> > kernel@vger.kernel.org; Leyfoon Tan <leyfoon.tan@starfivetech.com>; Mason Huo <mason.huo@starfivetech.com>
> > Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
> > 
> > On Fri, Feb 24, 2023 at 02:05:43AM +0000, JeeHeng Sia wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Andrew Jones <ajones@ventanamicro.com>
> > > > Sent: Friday, 24 February, 2023 2:07 AM
> > > > To: JeeHeng Sia <jeeheng.sia@starfivetech.com>
> > > > Cc: paul.walmsley@sifive.com; palmer@dabbelt.com; aou@eecs.berkeley.edu; linux-riscv@lists.infradead.org; linux-
> > > > kernel@vger.kernel.org; Leyfoon Tan <leyfoon.tan@starfivetech.com>; Mason Huo <mason.huo@starfivetech.com>
> > > > Subject: Re: [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk
> > > >
> > > > On Tue, Feb 21, 2023 at 10:35:23AM +0800, Sia Jee Heng wrote:
> > > > > Low level Arch functions were created to support hibernation.
> > > > > swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write
> > > > > cpu state onto the stack, then calling swsusp_save() to save the memory
> > > > > image.
> > > > >
> > > > > Arch specific hibernation header is implemented and is utilized by the
> > > > > arch_hibernation_header_restore() and arch_hibernation_header_save()
> > > > > functions. The arch specific hibernation header consists of satp, hartid,
> > > > > and the cpu_resume address. The kernel built version is also need to be
> > > > > saved into the hibernation image header to making sure only the same
> > > > > kernel is restore when resume.
> > > > >
> > > > > swsusp_arch_resume() creates a temporary page table that covering only
> > > > > the linear map. It copies the restore code to a 'safe' page, then start
> > > > > to restore the memory image. Once completed, it restores the original
> > > > > kernel's page table. It then calls into __hibernate_cpu_resume()
> > > > > to restore the CPU context. Finally, it follows the normal hibernation
> > > > > path back to the hibernation core.
> > > > >
> > > > > To enable hibernation/suspend to disk into RISCV, the below config
> > > > > need to be enabled:
> > > > > - CONFIG_ARCH_HIBERNATION_HEADER
> > > > > - CONFIG_ARCH_HIBERNATION_POSSIBLE
> > > > >
> > > > > Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
> > > > > Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
> > > > > Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
> > > > > ---
> > > > >  arch/riscv/Kconfig                 |   7 +
> > > > >  arch/riscv/include/asm/assembler.h |  20 ++
> > > > >  arch/riscv/include/asm/suspend.h   |  19 ++
> > > > >  arch/riscv/kernel/Makefile         |   1 +
> > > > >  arch/riscv/kernel/asm-offsets.c    |   5 +
> > > > >  arch/riscv/kernel/hibernate-asm.S  |  77 +++++
> > > > >  arch/riscv/kernel/hibernate.c      | 447 +++++++++++++++++++++++++++++
> > > > >  7 files changed, 576 insertions(+)
> > > > >  create mode 100644 arch/riscv/kernel/hibernate-asm.S
> > > > >  create mode 100644 arch/riscv/kernel/hibernate.c
> > > > >
> > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > > > > index e2b656043abf..4555848a817f 100644
> > > > > --- a/arch/riscv/Kconfig
> > > > > +++ b/arch/riscv/Kconfig
> > > > > @@ -690,6 +690,13 @@ menu "Power management options"
> > > > >
> > > > >  source "kernel/power/Kconfig"
> > > > >
> > > > > +config ARCH_HIBERNATION_POSSIBLE
> > > > > +	def_bool y
> > > > > +
> > > > > +config ARCH_HIBERNATION_HEADER
> > > > > +	def_bool y
> > > > > +	depends on HIBERNATION
> > > >
> > > > nit: I think this can be simplified as def_bool HIBERNATION
> > > good suggestion. will change it.
> > > >
> > > > > +
> > > > >  endmenu # "Power management options"
> > > > >
> > > > >  menu "CPU Power Management"
> > > > > diff --git a/arch/riscv/include/asm/assembler.h b/arch/riscv/include/asm/assembler.h
> > > > > index 727a97735493..68c46c0e0ea8 100644
> > > > > --- a/arch/riscv/include/asm/assembler.h
> > > > > +++ b/arch/riscv/include/asm/assembler.h
> > > > > @@ -59,4 +59,24 @@
> > > > >  		REG_L	s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
> > > > >  	.endm
> > > > >
> > > > > +/*
> > > > > + * copy_page - copy 1 page (4KB) of data from source to destination
> > > > > + * @a0 - destination
> > > > > + * @a1 - source
> > > > > + */
> > > > > +	.macro	copy_page a0, a1
> > > > > +		lui	a2, 0x1
> > > > > +		add	a2, a2, a0
> > > > > +1 :
> > > >     ^ please remove this space
> > > can't remove it otherwise checkpatch will throws ERROR: spaces required around that ':'
> > 
> > Oh, right, labels in macros have this requirement.
> > 
> > > >
> > > > > +		REG_L	t0, 0(a1)
> > > > > +		REG_L	t1, SZREG(a1)
> > > > > +
> > > > > +		REG_S	t0, 0(a0)
> > > > > +		REG_S	t1, SZREG(a0)
> > > > > +
> > > > > +		addi	a0, a0, 2 * SZREG
> > > > > +		addi	a1, a1, 2 * SZREG
> > > > > +		bne	a2, a0, 1b
> > > > > +	.endm
> > > > > +
> > > > >  #endif	/* __ASM_ASSEMBLER_H */
> > > > > diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h
> > > > > index 75419c5ca272..3362da56a9d8 100644
> > > > > --- a/arch/riscv/include/asm/suspend.h
> > > > > +++ b/arch/riscv/include/asm/suspend.h
> > > > > @@ -21,6 +21,11 @@ struct suspend_context {
> > > > >  #endif
> > > > >  };
> > > > >
> > > > > +/*
> > > > > + * Used by hibernation core and cleared during resume sequence
> > > > > + */
> > > > > +extern int in_suspend;
> > > > > +
> > > > >  /* Low-level CPU suspend entry function */
> > > > >  int __cpu_suspend_enter(struct suspend_context *context);
> > > > >
> > > > > @@ -36,4 +41,18 @@ int __cpu_resume_enter(unsigned long hartid, unsigned long context);
> > > > >  /* Used to save and restore the csr */
> > > > >  void suspend_save_csrs(struct suspend_context *context);
> > > > >  void suspend_restore_csrs(struct suspend_context *context);
> > > > > +
> > > > > +/* Low-level API to support hibernation */
> > > > > +int swsusp_arch_suspend(void);
> > > > > +int swsusp_arch_resume(void);
> > > > > +int arch_hibernation_header_save(void *addr, unsigned int max_size);
> > > > > +int arch_hibernation_header_restore(void *addr);
> > > > > +int __hibernate_cpu_resume(void);
> > > > > +
> > > > > +/* Used to resume on the CPU we hibernated on */
> > > > > +int hibernate_resume_nonboot_cpu_disable(void);
> > > > > +
> > > > > +asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp,
> > > > > +					unsigned long cpu_resume);
> > > > > +asmlinkage int hibernate_core_restore_code(void);
> > > > >  #endif
> > > > > diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> > > > > index 4cf303a779ab..daab341d55e4 100644
> > > > > --- a/arch/riscv/kernel/Makefile
> > > > > +++ b/arch/riscv/kernel/Makefile
> > > > > @@ -64,6 +64,7 @@ obj-$(CONFIG_MODULES)		+= module.o
> > > > >  obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
> > > > >
> > > > >  obj-$(CONFIG_CPU_PM)		+= suspend_entry.o suspend.o
> > > > > +obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate-asm.o
> > > > >
> > > > >  obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
> > > > >  obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
> > > > > diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> > > > > index df9444397908..d6a75aac1d27 100644
> > > > > --- a/arch/riscv/kernel/asm-offsets.c
> > > > > +++ b/arch/riscv/kernel/asm-offsets.c
> > > > > @@ -9,6 +9,7 @@
> > > > >  #include <linux/kbuild.h>
> > > > >  #include <linux/mm.h>
> > > > >  #include <linux/sched.h>
> > > > > +#include <linux/suspend.h>
> > > > >  #include <asm/kvm_host.h>
> > > > >  #include <asm/thread_info.h>
> > > > >  #include <asm/ptrace.h>
> > > > > @@ -116,6 +117,10 @@ void asm_offsets(void)
> > > > >
> > > > >  	OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
> > > > >
> > > > > +	OFFSET(HIBERN_PBE_ADDR, pbe, address);
> > > > > +	OFFSET(HIBERN_PBE_ORIG, pbe, orig_address);
> > > > > +	OFFSET(HIBERN_PBE_NEXT, pbe, next);
> > > > > +
> > > > >  	OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
> > > > >  	OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
> > > > >  	OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
> > > > > diff --git a/arch/riscv/kernel/hibernate-asm.S b/arch/riscv/kernel/hibernate-asm.S
> > > > > new file mode 100644
> > > > > index 000000000000..846affe4dced
> > > > > --- /dev/null
> > > > > +++ b/arch/riscv/kernel/hibernate-asm.S
> > > > > @@ -0,0 +1,77 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > > +/*
> > > > > + * Hibernation low level support for RISCV.
> > > > > + *
> > > > > + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> > > > > + *
> > > > > + * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
> > > > > + */
> > > > > +
> > > > > +#include <asm/asm.h>
> > > > > +#include <asm/asm-offsets.h>
> > > > > +#include <asm/assembler.h>
> > > > > +#include <asm/csr.h>
> > > > > +
> > > > > +#include <linux/linkage.h>
> > > > > +
> > > > > +/*
> > > > > + * int __hibernate_cpu_resume(void)
> > > > > + * Switch back to the hibernated image's page table prior to restoring the CPU
> > > > > + * context.
> > > > > + *
> > > > > + * Always returns 0
> > > > > + */
> > > > > +ENTRY(__hibernate_cpu_resume)
> > > > > +	/* switch to hibernated image's page table. */
> > > > > +	csrw CSR_SATP, s0
> > > > > +	sfence.vma
> > > > > +
> > > > > +	REG_L	a0, hibernate_cpu_context
> > > > > +
> > > > > +	restore_csr
> > > > > +	restore_reg
> > > > > +
> > > > > +	/* Return zero value. */
> > > > > +	add	a0, zero, zero
> > > >
> > > > nit: mv a0, zero
> > > sure
> > > >
> > > > > +
> > > > > +	ret
> > > > > +END(__hibernate_cpu_resume)
> > > > > +
> > > > > +/*
> > > > > + * Prepare to restore the image.
> > > > > + * a0: satp of saved page tables.
> > > > > + * a1: satp of temporary page tables.
> > > > > + * a2: cpu_resume.
> > > > > + */
> > > > > +ENTRY(hibernate_restore_image)
> > > > > +	mv	s0, a0
> > > > > +	mv	s1, a1
> > > > > +	mv	s2, a2
> > > > > +	REG_L	s4, restore_pblist
> > > > > +	REG_L	a1, relocated_restore_code
> > > > > +
> > > > > +	jalr	a1
> > > > > +END(hibernate_restore_image)
> > > > > +
> > > > > +/*
> > > > > + * The below code will be executed from a 'safe' page.
> > > > > + * It first switches to the temporary page table, then starts to copy the pages
> > > > > + * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume()
> > > > > + * to restore the CPU context.
> > > > > + */
> > > > > +ENTRY(hibernate_core_restore_code)
> > > > > +	/* switch to temp page table. */
> > > > > +	csrw satp, s1
> > > > > +	sfence.vma
> > > > > +.Lcopy:
> > > > > +	/* The below code will restore the hibernated image. */
> > > > > +	REG_L	a1, HIBERN_PBE_ADDR(s4)
> > > > > +	REG_L	a0, HIBERN_PBE_ORIG(s4)
> > > >
> > > > Are we sure restore_pblist will never be NULL?
> > > restore_pblist is a link-list, it will be null during initialization or during page clean up by hibernation core. During the initial resume
> > process, the hibernation core will check the header and load the pages. If everything works correctly, the page will be linked to the
> > restore_pblist and then invoke swsusp_arch_resume() else hibernation core will throws error and failed to resume from the
> > hibernated image.
> > 
> > I know restore_pblist is a linked-list and this doesn't answer the
> > question. The comment above restore_pblist says
> > 
> > /*
> >  * List of PBEs needed for restoring the pages that were allocated before
> >  * the suspend and included in the suspend image, but have also been
> >  * allocated by the "resume" kernel, so their contents cannot be written
> >  * directly to their "original" page frames.
> >  */
> > 
> > which implies the pages that end up on this list are "special". My
> > question is whether or not we're guaranteed to have at least one
> > of these special pages. If not, we shouldn't assume s4 is non-null.
> > If so, then a comment stating why that's guaranteed would be nice.
> The restore_pblist will not be null otherwise swsusp_arch_resume wouldn't get invoked. you can find how the link-list are link and how it checks against validity at https://elixir.bootlin.com/linux/v6.2-rc8/source/kernel/power/snapshot.c . " A comment stating why that's guaranteed would be nice" ? Hmm, perhaps this is out of my scope but I do believe in the page validity checking in the link I shared.

Sorry, but pointing to an entire source file (one that I've obviously
already looked at, since I quoted a comment from it...) is not helpful.
I don't see where restore_pblist is being checked before
swsusp_arch_resume() is issued (from its callsite in hibernate.c).

Thanks,
drew

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2023-02-24  9:55 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-21  2:35 [PATCH v4 0/4] RISC-V Hibernation Support Sia Jee Heng
2023-02-21  2:35 ` Sia Jee Heng
2023-02-21  2:35 ` [PATCH v4 1/4] RISC-V: Change suspend_save_csrs and suspend_restore_csrs to public function Sia Jee Heng
2023-02-21  2:35   ` Sia Jee Heng
2023-02-23  6:39   ` Andrew Jones
2023-02-23  6:39     ` Andrew Jones
2023-02-24  1:33     ` JeeHeng Sia
2023-02-24  1:33       ` JeeHeng Sia
2023-02-21  2:35 ` [PATCH v4 2/4] RISC-V: Factor out common code of __cpu_resume_enter() Sia Jee Heng
2023-02-21  2:35   ` Sia Jee Heng
2023-02-23  6:51   ` Andrew Jones
2023-02-23  6:51     ` Andrew Jones
2023-02-24  1:33     ` JeeHeng Sia
2023-02-24  1:33       ` JeeHeng Sia
2023-02-24 10:19   ` Alexandre Ghiti
2023-02-24 10:19     ` Alexandre Ghiti
2023-02-27  2:21     ` JeeHeng Sia
2023-02-27  2:21       ` JeeHeng Sia
2023-02-21  2:35 ` [PATCH v4 3/4] RISC-V: mm: Enable huge page support to kernel_page_present() function Sia Jee Heng
2023-02-21  2:35   ` Sia Jee Heng
2023-02-23  6:57   ` Andrew Jones
2023-02-23  6:57     ` Andrew Jones
2023-02-24  1:33     ` JeeHeng Sia
2023-02-24  1:33       ` JeeHeng Sia
2023-02-24 10:21   ` Alexandre Ghiti
2023-02-24 10:21     ` Alexandre Ghiti
2023-02-21  2:35 ` [PATCH v4 4/4] RISC-V: Add arch functions to support hibernation/suspend-to-disk Sia Jee Heng
2023-02-21  2:35   ` Sia Jee Heng
2023-02-23 18:07   ` Andrew Jones
2023-02-23 18:07     ` Andrew Jones
2023-02-24  2:05     ` JeeHeng Sia
2023-02-24  2:05       ` JeeHeng Sia
2023-02-24  9:00       ` Andrew Jones
2023-02-24  9:00         ` Andrew Jones
2023-02-24  9:33         ` JeeHeng Sia
2023-02-24  9:33           ` JeeHeng Sia
2023-02-24  9:55           ` Andrew Jones [this message]
2023-02-24  9:55             ` Andrew Jones
2023-02-24 10:30             ` JeeHeng Sia
2023-02-24 10:30               ` JeeHeng Sia
2023-02-24 12:07               ` Andrew Jones
2023-02-24 12:07                 ` Andrew Jones
2023-02-27  2:14                 ` JeeHeng Sia
2023-02-27  2:14                   ` JeeHeng Sia
2023-02-27  7:59                   ` Andrew Jones
2023-02-27  7:59                     ` Andrew Jones
2023-02-27 10:52                     ` JeeHeng Sia
2023-02-27 10:52                       ` JeeHeng Sia
2023-02-27 11:44                       ` Andrew Jones
2023-02-27 11:44                         ` Andrew Jones
2023-02-28  1:32                         ` JeeHeng Sia
2023-02-28  1:32                           ` JeeHeng Sia
2023-02-28  5:04                           ` Andrew Jones
2023-02-28  5:04                             ` Andrew Jones
2023-02-28  5:33                             ` JeeHeng Sia
2023-02-28  5:33                               ` JeeHeng Sia
2023-02-28  7:18                               ` Andrew Jones
2023-02-28  7:18                                 ` Andrew Jones
2023-02-28  7:29                                 ` JeeHeng Sia
2023-02-28  7:29                                   ` JeeHeng Sia
2023-02-28  7:37                                   ` Andrew Jones
2023-02-28  7:37                                     ` Andrew Jones
2023-03-03  1:53                                     ` JeeHeng Sia
2023-03-03  1:53                                       ` JeeHeng Sia
2023-03-03  8:09                                       ` Andrew Jones
2023-03-03  8:09                                         ` Andrew Jones
2023-02-28  6:33                             ` JeeHeng Sia
2023-02-28  6:33                               ` JeeHeng Sia
2023-02-28  7:29                               ` Andrew Jones
2023-02-28  7:29                                 ` Andrew Jones
2023-02-28  7:34                                 ` JeeHeng Sia
2023-02-28  7:34                                   ` JeeHeng Sia
2023-02-24  2:12   ` JeeHeng Sia
2023-02-24  2:12     ` JeeHeng Sia
2023-02-24 12:29   ` Alexandre Ghiti
2023-02-24 12:29     ` Alexandre Ghiti
2023-02-27  3:11     ` JeeHeng Sia
2023-02-27  3:11       ` JeeHeng Sia
2023-02-27 20:31       ` Alexandre Ghiti
2023-02-27 20:31         ` Alexandre Ghiti
2023-02-28  1:20         ` JeeHeng Sia
2023-02-28  1:20           ` JeeHeng Sia

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=20230224095526.ctctpzw3p3csf6qj@orel \
    --to=ajones@ventanamicro.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=jeeheng.sia@starfivetech.com \
    --cc=leyfoon.tan@starfivetech.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=mason.huo@starfivetech.com \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    /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.