Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-22 Thread Atish Patra
On Thu, Oct 22, 2020 at 12:22 AM Anup Patel  wrote:
>
> On Thu, Oct 22, 2020 at 10:33 AM Anup Patel  wrote:
> >
> > On Thu, Oct 22, 2020 at 7:01 AM Atish Patra  wrote:
> > >
> > > On Fri, Oct 16, 2020 at 11:24 AM Atish Patra  
> > > wrote:
> > > >
> > > > On Tue, Oct 13, 2020 at 10:24 PM Atish Patra  
> > > > wrote:
> > > > >
> > > > > On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
> > > > > >
> > > > > > On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  
> > > > > > wrote:
> > > > > > > This happens only when copy_from_user is called from function 
> > > > > > > that is
> > > > > > > annotated with __init.
> > > > > > > Adding Kito & Jim for their input
> > > > > > >
> > > > > > > @kito, @Jim: Please let me know if I should create a issue in
> > > > > > > riscv-gnu-toolchain repo or somewhere else.
> > > > > >
> > > > > > I can't do anything useful without a testcase that I can use to
> > > > > > reproduce the problem.  The interactions here are complex, so 
> > > > > > pointing
> > > > > > at lines of code or kernel config options doesn't give me any useful
> > > > > > info.
> > > > > >
> > > > > > Relaxation can convert calls to a jal.  I don't know of any open 
> > > > > > bugs
> > > > > > in this area that can generate relocation errors.  if it is a
> > > > > > relaxation error then turning off relaxation should work around the
> > > > > > problem as you suggested.
> > > > > >
> > > > > > A kernel build problem is serious.  I think this is worth a bug
> > > > > > report.  FSF binutils or riscv-gnu-toolchain is fine.
> > > > > >
> > > > >
> > > > > I have created an issue with detailed descriptions and reproduction 
> > > > > steps.
> > > > > Please let me know if you need anything else.
> > > > >
> > > >
> > > > It may be a toolchain issue. Here is the ongoing discussion in case
> > > > anybody else is interested.
> > > >
> > > > https://github.com/riscv/riscv-gnu-toolchain/issues/738
> > > >
> > > > > > Jim
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Regards,
> > > > > Atish
> > > >
> > > >
> > > >
> > > > --
> > > > Regards,
> > > > Atish
> > >
> > > Thanks to Jim, we know the cause now. Jim has provided an excellent
> > > analysis of the issue in the github issue report.
> > > https://github.com/riscv/riscv-gnu-toolchain/issues/738
> > >
> > > To summarize, the linker relaxation code is not aware of the
> > > alignments between sections.
> > > That's why it relaxes the calls from .text to .init.text and  converts
> > > a auipc+jalr pair to jal even if the address can't be fit +/- 1MB.
> > >
> > > There are few ways we can solve this problem.
> > >
> > > 1. As per Jim's suggestion, linker relaxation code is aware of the
> > > section alignments. We can mark .init.text as a 2MB aligned section.
> > >For calls within a section, section's alignment will be used in the
> > > calculation. For calls across sections, e.g. from .init.text to .text,
> > > the maximum
> > >section alignment of every section will be used. Thus, all
> > > relaxation within .init.text and between any sections will be
> > > impacted.
> > >Thus, it avoids the error but results in the following increase in
> > > size of various sections.
> > >  section   change in size (in bytes)
> > >  .head.text  +4
> > >  .text   +40
> > >  .init.text.+6530
> > >  .exit.text+84
> > >
> > > The only significant increase is .init.text but it is freed after
> > > boot. Thus, I don't see any significant performance degradation due to
> > > that.
> > >
> > > Here is the diff
> > > --- a/arch/riscv/kernel/vmlinux.lds.S
> > > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > > @@ -51,7 +51,13 @@ SECTIONS
> > > . = ALIGN(SECTION_ALIGN);
> > > __init_begin = .;
> > > __init_text_begin = .;
> > > -   INIT_TEXT_SECTION(PAGE_SIZE)
> > > +   . = ALIGN(PAGE_SIZE);   \
> > > +   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
> > > ALIGN(SECTION_ALIGN) {  \
> > > +   _sinittext = .; \
> > > +   INIT_TEXT   \
> > > +   _einittext = .; \
> > > +   }
> > > +
> > > . = ALIGN(8);
> > > __soc_early_init_table : {
> > > __soc_early_init_table_start = .;
> > >
> > > 2. We will continue to keep head.txt & .init.text together before
> > > .text. However, we will map the pages that contain head & init.text at
> > > page
> > > granularity so that .head.text and init.text can have different
> > > permissions. I have not measured the performance impact of this but it
> > > won't
> > > too bad given that the combined size of sections .head.txt &
> > > .init.text is 200K. So we are talking about page level permission only
> > > for
> > > ~50 pages during boot.
> > >
> > > 3. Keep head.text in a separate 2MB aligned section. 

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-22 Thread Anup Patel
On Thu, Oct 22, 2020 at 10:33 AM Anup Patel  wrote:
>
> On Thu, Oct 22, 2020 at 7:01 AM Atish Patra  wrote:
> >
> > On Fri, Oct 16, 2020 at 11:24 AM Atish Patra  wrote:
> > >
> > > On Tue, Oct 13, 2020 at 10:24 PM Atish Patra  
> > > wrote:
> > > >
> > > > On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
> > > > >
> > > > > On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  
> > > > > wrote:
> > > > > > This happens only when copy_from_user is called from function that 
> > > > > > is
> > > > > > annotated with __init.
> > > > > > Adding Kito & Jim for their input
> > > > > >
> > > > > > @kito, @Jim: Please let me know if I should create a issue in
> > > > > > riscv-gnu-toolchain repo or somewhere else.
> > > > >
> > > > > I can't do anything useful without a testcase that I can use to
> > > > > reproduce the problem.  The interactions here are complex, so pointing
> > > > > at lines of code or kernel config options doesn't give me any useful
> > > > > info.
> > > > >
> > > > > Relaxation can convert calls to a jal.  I don't know of any open bugs
> > > > > in this area that can generate relocation errors.  if it is a
> > > > > relaxation error then turning off relaxation should work around the
> > > > > problem as you suggested.
> > > > >
> > > > > A kernel build problem is serious.  I think this is worth a bug
> > > > > report.  FSF binutils or riscv-gnu-toolchain is fine.
> > > > >
> > > >
> > > > I have created an issue with detailed descriptions and reproduction 
> > > > steps.
> > > > Please let me know if you need anything else.
> > > >
> > >
> > > It may be a toolchain issue. Here is the ongoing discussion in case
> > > anybody else is interested.
> > >
> > > https://github.com/riscv/riscv-gnu-toolchain/issues/738
> > >
> > > > > Jim
> > > >
> > > >
> > > >
> > > > --
> > > > Regards,
> > > > Atish
> > >
> > >
> > >
> > > --
> > > Regards,
> > > Atish
> >
> > Thanks to Jim, we know the cause now. Jim has provided an excellent
> > analysis of the issue in the github issue report.
> > https://github.com/riscv/riscv-gnu-toolchain/issues/738
> >
> > To summarize, the linker relaxation code is not aware of the
> > alignments between sections.
> > That's why it relaxes the calls from .text to .init.text and  converts
> > a auipc+jalr pair to jal even if the address can't be fit +/- 1MB.
> >
> > There are few ways we can solve this problem.
> >
> > 1. As per Jim's suggestion, linker relaxation code is aware of the
> > section alignments. We can mark .init.text as a 2MB aligned section.
> >For calls within a section, section's alignment will be used in the
> > calculation. For calls across sections, e.g. from .init.text to .text,
> > the maximum
> >section alignment of every section will be used. Thus, all
> > relaxation within .init.text and between any sections will be
> > impacted.
> >Thus, it avoids the error but results in the following increase in
> > size of various sections.
> >  section   change in size (in bytes)
> >  .head.text  +4
> >  .text   +40
> >  .init.text.+6530
> >  .exit.text+84
> >
> > The only significant increase is .init.text but it is freed after
> > boot. Thus, I don't see any significant performance degradation due to
> > that.
> >
> > Here is the diff
> > --- a/arch/riscv/kernel/vmlinux.lds.S
> > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > @@ -51,7 +51,13 @@ SECTIONS
> > . = ALIGN(SECTION_ALIGN);
> > __init_begin = .;
> > __init_text_begin = .;
> > -   INIT_TEXT_SECTION(PAGE_SIZE)
> > +   . = ALIGN(PAGE_SIZE);   \
> > +   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
> > ALIGN(SECTION_ALIGN) {  \
> > +   _sinittext = .; \
> > +   INIT_TEXT   \
> > +   _einittext = .; \
> > +   }
> > +
> > . = ALIGN(8);
> > __soc_early_init_table : {
> > __soc_early_init_table_start = .;
> >
> > 2. We will continue to keep head.txt & .init.text together before
> > .text. However, we will map the pages that contain head & init.text at
> > page
> > granularity so that .head.text and init.text can have different
> > permissions. I have not measured the performance impact of this but it
> > won't
> > too bad given that the combined size of sections .head.txt &
> > .init.text is 200K. So we are talking about page level permission only
> > for
> > ~50 pages during boot.
> >
> > 3. Keep head.text in a separate 2MB aligned section. .init.text will
> > follow .head.text in its own section as well. This increases the
> > kernel
> > size by 2MB for MMU kernels. For nommu case, it will only increase
> > by 64 bytes due to smaller section alignment for nommu kernels.
> >
> > Both solutions 1 & 2 come at minimal performance on boot time while
> > solution 3 comes at 

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-21 Thread Anup Patel
On Thu, Oct 22, 2020 at 7:01 AM Atish Patra  wrote:
>
> On Fri, Oct 16, 2020 at 11:24 AM Atish Patra  wrote:
> >
> > On Tue, Oct 13, 2020 at 10:24 PM Atish Patra  wrote:
> > >
> > > On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
> > > >
> > > > On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  
> > > > wrote:
> > > > > This happens only when copy_from_user is called from function that is
> > > > > annotated with __init.
> > > > > Adding Kito & Jim for their input
> > > > >
> > > > > @kito, @Jim: Please let me know if I should create a issue in
> > > > > riscv-gnu-toolchain repo or somewhere else.
> > > >
> > > > I can't do anything useful without a testcase that I can use to
> > > > reproduce the problem.  The interactions here are complex, so pointing
> > > > at lines of code or kernel config options doesn't give me any useful
> > > > info.
> > > >
> > > > Relaxation can convert calls to a jal.  I don't know of any open bugs
> > > > in this area that can generate relocation errors.  if it is a
> > > > relaxation error then turning off relaxation should work around the
> > > > problem as you suggested.
> > > >
> > > > A kernel build problem is serious.  I think this is worth a bug
> > > > report.  FSF binutils or riscv-gnu-toolchain is fine.
> > > >
> > >
> > > I have created an issue with detailed descriptions and reproduction steps.
> > > Please let me know if you need anything else.
> > >
> >
> > It may be a toolchain issue. Here is the ongoing discussion in case
> > anybody else is interested.
> >
> > https://github.com/riscv/riscv-gnu-toolchain/issues/738
> >
> > > > Jim
> > >
> > >
> > >
> > > --
> > > Regards,
> > > Atish
> >
> >
> >
> > --
> > Regards,
> > Atish
>
> Thanks to Jim, we know the cause now. Jim has provided an excellent
> analysis of the issue in the github issue report.
> https://github.com/riscv/riscv-gnu-toolchain/issues/738
>
> To summarize, the linker relaxation code is not aware of the
> alignments between sections.
> That's why it relaxes the calls from .text to .init.text and  converts
> a auipc+jalr pair to jal even if the address can't be fit +/- 1MB.
>
> There are few ways we can solve this problem.
>
> 1. As per Jim's suggestion, linker relaxation code is aware of the
> section alignments. We can mark .init.text as a 2MB aligned section.
>For calls within a section, section's alignment will be used in the
> calculation. For calls across sections, e.g. from .init.text to .text,
> the maximum
>section alignment of every section will be used. Thus, all
> relaxation within .init.text and between any sections will be
> impacted.
>Thus, it avoids the error but results in the following increase in
> size of various sections.
>  section   change in size (in bytes)
>  .head.text  +4
>  .text   +40
>  .init.text.+6530
>  .exit.text+84
>
> The only significant increase is .init.text but it is freed after
> boot. Thus, I don't see any significant performance degradation due to
> that.
>
> Here is the diff
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -51,7 +51,13 @@ SECTIONS
> . = ALIGN(SECTION_ALIGN);
> __init_begin = .;
> __init_text_begin = .;
> -   INIT_TEXT_SECTION(PAGE_SIZE)
> +   . = ALIGN(PAGE_SIZE);   \
> +   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
> ALIGN(SECTION_ALIGN) {  \
> +   _sinittext = .; \
> +   INIT_TEXT   \
> +   _einittext = .; \
> +   }
> +
> . = ALIGN(8);
> __soc_early_init_table : {
> __soc_early_init_table_start = .;
>
> 2. We will continue to keep head.txt & .init.text together before
> .text. However, we will map the pages that contain head & init.text at
> page
> granularity so that .head.text and init.text can have different
> permissions. I have not measured the performance impact of this but it
> won't
> too bad given that the combined size of sections .head.txt &
> .init.text is 200K. So we are talking about page level permission only
> for
> ~50 pages during boot.
>
> 3. Keep head.text in a separate 2MB aligned section. .init.text will
> follow .head.text in its own section as well. This increases the
> kernel
> size by 2MB for MMU kernels. For nommu case, it will only increase
> by 64 bytes due to smaller section alignment for nommu kernels.
>
> Both solutions 1 & 2 come at minimal performance on boot time while
> solution 3 comes at increased kernel size.
>
> Any preference ?

I prefer solution#3 because:
1. This will help us avoid special handling of static objects
2.  This will make RISC-V linker script more aligned with other
 major architectures

I don't think solution#3 will increase the size of the kernel by 2MB. We
can make head.text part of text 

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-21 Thread Atish Patra
On Fri, Oct 16, 2020 at 11:24 AM Atish Patra  wrote:
>
> On Tue, Oct 13, 2020 at 10:24 PM Atish Patra  wrote:
> >
> > On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
> > >
> > > On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  wrote:
> > > > This happens only when copy_from_user is called from function that is
> > > > annotated with __init.
> > > > Adding Kito & Jim for their input
> > > >
> > > > @kito, @Jim: Please let me know if I should create a issue in
> > > > riscv-gnu-toolchain repo or somewhere else.
> > >
> > > I can't do anything useful without a testcase that I can use to
> > > reproduce the problem.  The interactions here are complex, so pointing
> > > at lines of code or kernel config options doesn't give me any useful
> > > info.
> > >
> > > Relaxation can convert calls to a jal.  I don't know of any open bugs
> > > in this area that can generate relocation errors.  if it is a
> > > relaxation error then turning off relaxation should work around the
> > > problem as you suggested.
> > >
> > > A kernel build problem is serious.  I think this is worth a bug
> > > report.  FSF binutils or riscv-gnu-toolchain is fine.
> > >
> >
> > I have created an issue with detailed descriptions and reproduction steps.
> > Please let me know if you need anything else.
> >
>
> It may be a toolchain issue. Here is the ongoing discussion in case
> anybody else is interested.
>
> https://github.com/riscv/riscv-gnu-toolchain/issues/738
>
> > > Jim
> >
> >
> >
> > --
> > Regards,
> > Atish
>
>
>
> --
> Regards,
> Atish

Thanks to Jim, we know the cause now. Jim has provided an excellent
analysis of the issue in the github issue report.
https://github.com/riscv/riscv-gnu-toolchain/issues/738

To summarize, the linker relaxation code is not aware of the
alignments between sections.
That's why it relaxes the calls from .text to .init.text and  converts
a auipc+jalr pair to jal even if the address can't be fit +/- 1MB.

There are few ways we can solve this problem.

1. As per Jim's suggestion, linker relaxation code is aware of the
section alignments. We can mark .init.text as a 2MB aligned section.
   For calls within a section, section's alignment will be used in the
calculation. For calls across sections, e.g. from .init.text to .text,
the maximum
   section alignment of every section will be used. Thus, all
relaxation within .init.text and between any sections will be
impacted.
   Thus, it avoids the error but results in the following increase in
size of various sections.
 section   change in size (in bytes)
 .head.text  +4
 .text   +40
 .init.text.+6530
 .exit.text+84

The only significant increase is .init.text but it is freed after
boot. Thus, I don't see any significant performance degradation due to
that.

Here is the diff
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -51,7 +51,13 @@ SECTIONS
. = ALIGN(SECTION_ALIGN);
__init_begin = .;
__init_text_begin = .;
-   INIT_TEXT_SECTION(PAGE_SIZE)
+   . = ALIGN(PAGE_SIZE);   \
+   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
ALIGN(SECTION_ALIGN) {  \
+   _sinittext = .; \
+   INIT_TEXT   \
+   _einittext = .; \
+   }
+
. = ALIGN(8);
__soc_early_init_table : {
__soc_early_init_table_start = .;

2. We will continue to keep head.txt & .init.text together before
.text. However, we will map the pages that contain head & init.text at
page
granularity so that .head.text and init.text can have different
permissions. I have not measured the performance impact of this but it
won't
too bad given that the combined size of sections .head.txt &
.init.text is 200K. So we are talking about page level permission only
for
~50 pages during boot.

3. Keep head.text in a separate 2MB aligned section. .init.text will
follow .head.text in its own section as well. This increases the
kernel
size by 2MB for MMU kernels. For nommu case, it will only increase
by 64 bytes due to smaller section alignment for nommu kernels.

Both solutions 1 & 2 come at minimal performance on boot time while
solution 3 comes at increased kernel size.

Any preference ?

-- 
Regards,
Atish


Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-16 Thread Atish Patra
On Tue, Oct 13, 2020 at 10:24 PM Atish Patra  wrote:
>
> On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
> >
> > On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  wrote:
> > > This happens only when copy_from_user is called from function that is
> > > annotated with __init.
> > > Adding Kito & Jim for their input
> > >
> > > @kito, @Jim: Please let me know if I should create a issue in
> > > riscv-gnu-toolchain repo or somewhere else.
> >
> > I can't do anything useful without a testcase that I can use to
> > reproduce the problem.  The interactions here are complex, so pointing
> > at lines of code or kernel config options doesn't give me any useful
> > info.
> >
> > Relaxation can convert calls to a jal.  I don't know of any open bugs
> > in this area that can generate relocation errors.  if it is a
> > relaxation error then turning off relaxation should work around the
> > problem as you suggested.
> >
> > A kernel build problem is serious.  I think this is worth a bug
> > report.  FSF binutils or riscv-gnu-toolchain is fine.
> >
>
> I have created an issue with detailed descriptions and reproduction steps.
> Please let me know if you need anything else.
>

It may be a toolchain issue. Here is the ongoing discussion in case
anybody else is interested.

https://github.com/riscv/riscv-gnu-toolchain/issues/738

> > Jim
>
>
>
> --
> Regards,
> Atish



-- 
Regards,
Atish


Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-14 Thread Atish Patra
On Mon, Oct 12, 2020 at 8:08 PM Greentime Hu  wrote:
>
> Atish Patra  於 2020年10月13日 週二 上午9:28寫道:
> >
> > On Mon, Oct 12, 2020 at 4:26 PM Atish Patra  wrote:
> > >
> > > On Mon, Oct 12, 2020 at 6:15 AM Greentime Hu  
> > > wrote:
> > > >
> > > > Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
> > > > >
> > > > > Currently, .init.text & .init.data are intermixed which makes it 
> > > > > impossible
> > > > > apply different permissions to them. .init.data shouldn't need exec
> > > > > permissions while .init.text shouldn't have write permission.
> > > > >
> > > > > Keep them in separate sections so that different permissions are 
> > > > > applied to
> > > > > each section. This improves the kernel protection under
> > > > > CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for 
> > > > > the
> > > > > entire _init section after it is freed so that those pages can be 
> > > > > used for
> > > > > other purpose.
> > > > >
> > > > > Signed-off-by: Atish Patra 
> > > > > ---
> > > > >  arch/riscv/include/asm/sections.h   |  2 ++
> > > > >  arch/riscv/include/asm/set_memory.h |  2 ++
> > > > >  arch/riscv/kernel/setup.c   |  4 
> > > > >  arch/riscv/kernel/vmlinux.lds.S | 10 +-
> > > > >  arch/riscv/mm/init.c|  6 ++
> > > > >  arch/riscv/mm/pageattr.c|  6 ++
> > > > >  6 files changed, 29 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/arch/riscv/include/asm/sections.h 
> > > > > b/arch/riscv/include/asm/sections.h
> > > > > index d60802bfafbc..730d2c4a844d 100644
> > > > > --- a/arch/riscv/include/asm/sections.h
> > > > > +++ b/arch/riscv/include/asm/sections.h
> > > > > @@ -10,6 +10,8 @@
> > > > >  #include 
> > > > >  extern char _start[];
> > > > >  extern char _start_kernel[];
> > > > > +extern char __init_data_begin[], __init_data_end[];
> > > > > +extern char __init_text_begin[], __init_text_end[];
> > > > >
> > > > >  extern bool init_mem_is_free;
> > > > >
> > > > > diff --git a/arch/riscv/include/asm/set_memory.h 
> > > > > b/arch/riscv/include/asm/set_memory.h
> > > > > index 4cc3a4e2afd3..913429c9c1ae 100644
> > > > > --- a/arch/riscv/include/asm/set_memory.h
> > > > > +++ b/arch/riscv/include/asm/set_memory.h
> > > > > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
> > > > >  int set_memory_rw(unsigned long addr, int numpages);
> > > > >  int set_memory_x(unsigned long addr, int numpages);
> > > > >  int set_memory_nx(unsigned long addr, int numpages);
> > > > > +int set_memory_default(unsigned long addr, int numpages);
> > > > >  void protect_kernel_text_data(void);
> > > > >  #else
> > > > >  static inline int set_memory_ro(unsigned long addr, int numpages) { 
> > > > > return 0; }
> > > > > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, 
> > > > > int numpages) { return 0; }
> > > > >  static inline int set_memory_x(unsigned long addr, int numpages) { 
> > > > > return 0; }
> > > > >  static inline int set_memory_nx(unsigned long addr, int numpages) { 
> > > > > return 0; }
> > > > >  static inline void protect_kernel_text_data(void) {};
> > > > > +static inline int set_memory_default(unsigned long addr, int 
> > > > > numpages) { return 0; }
> > > > >  #endif
> > > > >
> > > > >  int set_direct_map_invalid_noflush(struct page *page);
> > > > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > > > index 4176a2affd1d..b8a35ef0eab0 100644
> > > > > --- a/arch/riscv/kernel/setup.c
> > > > > +++ b/arch/riscv/kernel/setup.c
> > > > > @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
> > > > >
> > > > >  void free_initmem(void)
> > > > >  {
> > > > > +   unsigned long init_begin = (unsigned long)__init_begin;
> > > > > +   unsigned long init_end = (unsigned long)__init_end;
> > > > > +
> > > > > +   set_memory_default(init_begin, (init_end - init_begin) >> 
> > > > > PAGE_SHIFT);
> > > > > free_initmem_default(POISON_FREE_INITMEM);
> > > > > init_mem_is_free = true;
> > > > >  }
> > > > > diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> > > > > b/arch/riscv/kernel/vmlinux.lds.S
> > > > > index 0807633f0dc8..15b9882588ae 100644
> > > > > --- a/arch/riscv/kernel/vmlinux.lds.S
> > > > > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > > > > @@ -30,8 +30,8 @@ SECTIONS
> > > > > . = ALIGN(PAGE_SIZE);
> > > > >
> > > > > __init_begin = .;
> > > > > +   __init_text_begin = .;
> > > > > INIT_TEXT_SECTION(PAGE_SIZE)
> > > > > -   INIT_DATA_SECTION(16)
> > > > > . = ALIGN(8);
> > > > > __soc_early_init_table : {
> > > > > __soc_early_init_table_start = .;
> > > > > @@ -48,11 +48,19 @@ SECTIONS
> > > > > {
> > > > > EXIT_TEXT
> > > > > }
> > > > > +
> > > > > +   __init_text_end = .;
> > > > > +   . = ALIGN(SECTION_ALIGN);
> > > > > +   /* Start of init data section */
> > > > > +   __init_data_begin = .;
> > > > > +   

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-14 Thread Jim Wilson
On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  wrote:
> This happens only when copy_from_user is called from function that is
> annotated with __init.
> Adding Kito & Jim for their input
>
> @kito, @Jim: Please let me know if I should create a issue in
> riscv-gnu-toolchain repo or somewhere else.

I can't do anything useful without a testcase that I can use to
reproduce the problem.  The interactions here are complex, so pointing
at lines of code or kernel config options doesn't give me any useful
info.

Relaxation can convert calls to a jal.  I don't know of any open bugs
in this area that can generate relocation errors.  if it is a
relaxation error then turning off relaxation should work around the
problem as you suggested.

A kernel build problem is serious.  I think this is worth a bug
report.  FSF binutils or riscv-gnu-toolchain is fine.

Jim


Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-14 Thread Atish Patra
On Tue, Oct 13, 2020 at 6:21 PM Jim Wilson  wrote:
>
> On Tue, Oct 13, 2020 at 3:25 PM Atish Patra  wrote:
> > This happens only when copy_from_user is called from function that is
> > annotated with __init.
> > Adding Kito & Jim for their input
> >
> > @kito, @Jim: Please let me know if I should create a issue in
> > riscv-gnu-toolchain repo or somewhere else.
>
> I can't do anything useful without a testcase that I can use to
> reproduce the problem.  The interactions here are complex, so pointing
> at lines of code or kernel config options doesn't give me any useful
> info.
>
> Relaxation can convert calls to a jal.  I don't know of any open bugs
> in this area that can generate relocation errors.  if it is a
> relaxation error then turning off relaxation should work around the
> problem as you suggested.
>
> A kernel build problem is serious.  I think this is worth a bug
> report.  FSF binutils or riscv-gnu-toolchain is fine.
>

I have created an issue with detailed descriptions and reproduction steps.
Please let me know if you need anything else.

> Jim



-- 
Regards,
Atish


Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Greentime Hu
Atish Patra  於 2020年10月13日 週二 上午9:28寫道:
>
> On Mon, Oct 12, 2020 at 4:26 PM Atish Patra  wrote:
> >
> > On Mon, Oct 12, 2020 at 6:15 AM Greentime Hu  
> > wrote:
> > >
> > > Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
> > > >
> > > > Currently, .init.text & .init.data are intermixed which makes it 
> > > > impossible
> > > > apply different permissions to them. .init.data shouldn't need exec
> > > > permissions while .init.text shouldn't have write permission.
> > > >
> > > > Keep them in separate sections so that different permissions are 
> > > > applied to
> > > > each section. This improves the kernel protection under
> > > > CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for 
> > > > the
> > > > entire _init section after it is freed so that those pages can be used 
> > > > for
> > > > other purpose.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  arch/riscv/include/asm/sections.h   |  2 ++
> > > >  arch/riscv/include/asm/set_memory.h |  2 ++
> > > >  arch/riscv/kernel/setup.c   |  4 
> > > >  arch/riscv/kernel/vmlinux.lds.S | 10 +-
> > > >  arch/riscv/mm/init.c|  6 ++
> > > >  arch/riscv/mm/pageattr.c|  6 ++
> > > >  6 files changed, 29 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/riscv/include/asm/sections.h 
> > > > b/arch/riscv/include/asm/sections.h
> > > > index d60802bfafbc..730d2c4a844d 100644
> > > > --- a/arch/riscv/include/asm/sections.h
> > > > +++ b/arch/riscv/include/asm/sections.h
> > > > @@ -10,6 +10,8 @@
> > > >  #include 
> > > >  extern char _start[];
> > > >  extern char _start_kernel[];
> > > > +extern char __init_data_begin[], __init_data_end[];
> > > > +extern char __init_text_begin[], __init_text_end[];
> > > >
> > > >  extern bool init_mem_is_free;
> > > >
> > > > diff --git a/arch/riscv/include/asm/set_memory.h 
> > > > b/arch/riscv/include/asm/set_memory.h
> > > > index 4cc3a4e2afd3..913429c9c1ae 100644
> > > > --- a/arch/riscv/include/asm/set_memory.h
> > > > +++ b/arch/riscv/include/asm/set_memory.h
> > > > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
> > > >  int set_memory_rw(unsigned long addr, int numpages);
> > > >  int set_memory_x(unsigned long addr, int numpages);
> > > >  int set_memory_nx(unsigned long addr, int numpages);
> > > > +int set_memory_default(unsigned long addr, int numpages);
> > > >  void protect_kernel_text_data(void);
> > > >  #else
> > > >  static inline int set_memory_ro(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, 
> > > > int numpages) { return 0; }
> > > >  static inline int set_memory_x(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > >  static inline int set_memory_nx(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > >  static inline void protect_kernel_text_data(void) {};
> > > > +static inline int set_memory_default(unsigned long addr, int numpages) 
> > > > { return 0; }
> > > >  #endif
> > > >
> > > >  int set_direct_map_invalid_noflush(struct page *page);
> > > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > > index 4176a2affd1d..b8a35ef0eab0 100644
> > > > --- a/arch/riscv/kernel/setup.c
> > > > +++ b/arch/riscv/kernel/setup.c
> > > > @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
> > > >
> > > >  void free_initmem(void)
> > > >  {
> > > > +   unsigned long init_begin = (unsigned long)__init_begin;
> > > > +   unsigned long init_end = (unsigned long)__init_end;
> > > > +
> > > > +   set_memory_default(init_begin, (init_end - init_begin) >> 
> > > > PAGE_SHIFT);
> > > > free_initmem_default(POISON_FREE_INITMEM);
> > > > init_mem_is_free = true;
> > > >  }
> > > > diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> > > > b/arch/riscv/kernel/vmlinux.lds.S
> > > > index 0807633f0dc8..15b9882588ae 100644
> > > > --- a/arch/riscv/kernel/vmlinux.lds.S
> > > > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > > > @@ -30,8 +30,8 @@ SECTIONS
> > > > . = ALIGN(PAGE_SIZE);
> > > >
> > > > __init_begin = .;
> > > > +   __init_text_begin = .;
> > > > INIT_TEXT_SECTION(PAGE_SIZE)
> > > > -   INIT_DATA_SECTION(16)
> > > > . = ALIGN(8);
> > > > __soc_early_init_table : {
> > > > __soc_early_init_table_start = .;
> > > > @@ -48,11 +48,19 @@ SECTIONS
> > > > {
> > > > EXIT_TEXT
> > > > }
> > > > +
> > > > +   __init_text_end = .;
> > > > +   . = ALIGN(SECTION_ALIGN);
> > > > +   /* Start of init data section */
> > > > +   __init_data_begin = .;
> > > > +   INIT_DATA_SECTION(16)
> > > > .exit.data :
> > > > {
> > > > EXIT_DATA
> > > > }
> > > > PERCPU_SECTION(L1_CACHE_BYTES)
> > > > +
> > > > +   __init_data_end = .;
> > > > __init_end = .;
> > > >
> > > > . = 

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Atish Patra
On Mon, Oct 12, 2020 at 4:26 PM Atish Patra  wrote:
>
> On Mon, Oct 12, 2020 at 6:15 AM Greentime Hu  wrote:
> >
> > Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
> > >
> > > Currently, .init.text & .init.data are intermixed which makes it 
> > > impossible
> > > apply different permissions to them. .init.data shouldn't need exec
> > > permissions while .init.text shouldn't have write permission.
> > >
> > > Keep them in separate sections so that different permissions are applied 
> > > to
> > > each section. This improves the kernel protection under
> > > CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
> > > entire _init section after it is freed so that those pages can be used for
> > > other purpose.
> > >
> > > Signed-off-by: Atish Patra 
> > > ---
> > >  arch/riscv/include/asm/sections.h   |  2 ++
> > >  arch/riscv/include/asm/set_memory.h |  2 ++
> > >  arch/riscv/kernel/setup.c   |  4 
> > >  arch/riscv/kernel/vmlinux.lds.S | 10 +-
> > >  arch/riscv/mm/init.c|  6 ++
> > >  arch/riscv/mm/pageattr.c|  6 ++
> > >  6 files changed, 29 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/riscv/include/asm/sections.h 
> > > b/arch/riscv/include/asm/sections.h
> > > index d60802bfafbc..730d2c4a844d 100644
> > > --- a/arch/riscv/include/asm/sections.h
> > > +++ b/arch/riscv/include/asm/sections.h
> > > @@ -10,6 +10,8 @@
> > >  #include 
> > >  extern char _start[];
> > >  extern char _start_kernel[];
> > > +extern char __init_data_begin[], __init_data_end[];
> > > +extern char __init_text_begin[], __init_text_end[];
> > >
> > >  extern bool init_mem_is_free;
> > >
> > > diff --git a/arch/riscv/include/asm/set_memory.h 
> > > b/arch/riscv/include/asm/set_memory.h
> > > index 4cc3a4e2afd3..913429c9c1ae 100644
> > > --- a/arch/riscv/include/asm/set_memory.h
> > > +++ b/arch/riscv/include/asm/set_memory.h
> > > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
> > >  int set_memory_rw(unsigned long addr, int numpages);
> > >  int set_memory_x(unsigned long addr, int numpages);
> > >  int set_memory_nx(unsigned long addr, int numpages);
> > > +int set_memory_default(unsigned long addr, int numpages);
> > >  void protect_kernel_text_data(void);
> > >  #else
> > >  static inline int set_memory_ro(unsigned long addr, int numpages) { 
> > > return 0; }
> > > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int 
> > > numpages) { return 0; }
> > >  static inline int set_memory_x(unsigned long addr, int numpages) { 
> > > return 0; }
> > >  static inline int set_memory_nx(unsigned long addr, int numpages) { 
> > > return 0; }
> > >  static inline void protect_kernel_text_data(void) {};
> > > +static inline int set_memory_default(unsigned long addr, int numpages) { 
> > > return 0; }
> > >  #endif
> > >
> > >  int set_direct_map_invalid_noflush(struct page *page);
> > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > index 4176a2affd1d..b8a35ef0eab0 100644
> > > --- a/arch/riscv/kernel/setup.c
> > > +++ b/arch/riscv/kernel/setup.c
> > > @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
> > >
> > >  void free_initmem(void)
> > >  {
> > > +   unsigned long init_begin = (unsigned long)__init_begin;
> > > +   unsigned long init_end = (unsigned long)__init_end;
> > > +
> > > +   set_memory_default(init_begin, (init_end - init_begin) >> 
> > > PAGE_SHIFT);
> > > free_initmem_default(POISON_FREE_INITMEM);
> > > init_mem_is_free = true;
> > >  }
> > > diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> > > b/arch/riscv/kernel/vmlinux.lds.S
> > > index 0807633f0dc8..15b9882588ae 100644
> > > --- a/arch/riscv/kernel/vmlinux.lds.S
> > > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > > @@ -30,8 +30,8 @@ SECTIONS
> > > . = ALIGN(PAGE_SIZE);
> > >
> > > __init_begin = .;
> > > +   __init_text_begin = .;
> > > INIT_TEXT_SECTION(PAGE_SIZE)
> > > -   INIT_DATA_SECTION(16)
> > > . = ALIGN(8);
> > > __soc_early_init_table : {
> > > __soc_early_init_table_start = .;
> > > @@ -48,11 +48,19 @@ SECTIONS
> > > {
> > > EXIT_TEXT
> > > }
> > > +
> > > +   __init_text_end = .;
> > > +   . = ALIGN(SECTION_ALIGN);
> > > +   /* Start of init data section */
> > > +   __init_data_begin = .;
> > > +   INIT_DATA_SECTION(16)
> > > .exit.data :
> > > {
> > > EXIT_DATA
> > > }
> > > PERCPU_SECTION(L1_CACHE_BYTES)
> > > +
> > > +   __init_data_end = .;
> > > __init_end = .;
> > >
> > > . = ALIGN(SECTION_ALIGN);
> > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> > > index 7859a1d1b34d..3ef0eafcc7c7 100644
> > > --- a/arch/riscv/mm/init.c
> > > +++ b/arch/riscv/mm/init.c
> > > @@ -627,11 +627,17 @@ void protect_kernel_text_data(void)
> > >  {
> > > unsigned long text_start = 

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Atish Patra
On Mon, Oct 12, 2020 at 6:15 AM Greentime Hu  wrote:
>
> Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
> >
> > Currently, .init.text & .init.data are intermixed which makes it impossible
> > apply different permissions to them. .init.data shouldn't need exec
> > permissions while .init.text shouldn't have write permission.
> >
> > Keep them in separate sections so that different permissions are applied to
> > each section. This improves the kernel protection under
> > CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
> > entire _init section after it is freed so that those pages can be used for
> > other purpose.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  arch/riscv/include/asm/sections.h   |  2 ++
> >  arch/riscv/include/asm/set_memory.h |  2 ++
> >  arch/riscv/kernel/setup.c   |  4 
> >  arch/riscv/kernel/vmlinux.lds.S | 10 +-
> >  arch/riscv/mm/init.c|  6 ++
> >  arch/riscv/mm/pageattr.c|  6 ++
> >  6 files changed, 29 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/riscv/include/asm/sections.h 
> > b/arch/riscv/include/asm/sections.h
> > index d60802bfafbc..730d2c4a844d 100644
> > --- a/arch/riscv/include/asm/sections.h
> > +++ b/arch/riscv/include/asm/sections.h
> > @@ -10,6 +10,8 @@
> >  #include 
> >  extern char _start[];
> >  extern char _start_kernel[];
> > +extern char __init_data_begin[], __init_data_end[];
> > +extern char __init_text_begin[], __init_text_end[];
> >
> >  extern bool init_mem_is_free;
> >
> > diff --git a/arch/riscv/include/asm/set_memory.h 
> > b/arch/riscv/include/asm/set_memory.h
> > index 4cc3a4e2afd3..913429c9c1ae 100644
> > --- a/arch/riscv/include/asm/set_memory.h
> > +++ b/arch/riscv/include/asm/set_memory.h
> > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
> >  int set_memory_rw(unsigned long addr, int numpages);
> >  int set_memory_x(unsigned long addr, int numpages);
> >  int set_memory_nx(unsigned long addr, int numpages);
> > +int set_memory_default(unsigned long addr, int numpages);
> >  void protect_kernel_text_data(void);
> >  #else
> >  static inline int set_memory_ro(unsigned long addr, int numpages) { return 
> > 0; }
> > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int 
> > numpages) { return 0; }
> >  static inline int set_memory_x(unsigned long addr, int numpages) { return 
> > 0; }
> >  static inline int set_memory_nx(unsigned long addr, int numpages) { return 
> > 0; }
> >  static inline void protect_kernel_text_data(void) {};
> > +static inline int set_memory_default(unsigned long addr, int numpages) { 
> > return 0; }
> >  #endif
> >
> >  int set_direct_map_invalid_noflush(struct page *page);
> > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > index 4176a2affd1d..b8a35ef0eab0 100644
> > --- a/arch/riscv/kernel/setup.c
> > +++ b/arch/riscv/kernel/setup.c
> > @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
> >
> >  void free_initmem(void)
> >  {
> > +   unsigned long init_begin = (unsigned long)__init_begin;
> > +   unsigned long init_end = (unsigned long)__init_end;
> > +
> > +   set_memory_default(init_begin, (init_end - init_begin) >> 
> > PAGE_SHIFT);
> > free_initmem_default(POISON_FREE_INITMEM);
> > init_mem_is_free = true;
> >  }
> > diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> > b/arch/riscv/kernel/vmlinux.lds.S
> > index 0807633f0dc8..15b9882588ae 100644
> > --- a/arch/riscv/kernel/vmlinux.lds.S
> > +++ b/arch/riscv/kernel/vmlinux.lds.S
> > @@ -30,8 +30,8 @@ SECTIONS
> > . = ALIGN(PAGE_SIZE);
> >
> > __init_begin = .;
> > +   __init_text_begin = .;
> > INIT_TEXT_SECTION(PAGE_SIZE)
> > -   INIT_DATA_SECTION(16)
> > . = ALIGN(8);
> > __soc_early_init_table : {
> > __soc_early_init_table_start = .;
> > @@ -48,11 +48,19 @@ SECTIONS
> > {
> > EXIT_TEXT
> > }
> > +
> > +   __init_text_end = .;
> > +   . = ALIGN(SECTION_ALIGN);
> > +   /* Start of init data section */
> > +   __init_data_begin = .;
> > +   INIT_DATA_SECTION(16)
> > .exit.data :
> > {
> > EXIT_DATA
> > }
> > PERCPU_SECTION(L1_CACHE_BYTES)
> > +
> > +   __init_data_end = .;
> > __init_end = .;
> >
> > . = ALIGN(SECTION_ALIGN);
> > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> > index 7859a1d1b34d..3ef0eafcc7c7 100644
> > --- a/arch/riscv/mm/init.c
> > +++ b/arch/riscv/mm/init.c
> > @@ -627,11 +627,17 @@ void protect_kernel_text_data(void)
> >  {
> > unsigned long text_start = (unsigned long)_text;
> > unsigned long text_end = (unsigned long)_etext;
> > +   unsigned long init_text_start = (unsigned long)__init_text_begin;
> > +   unsigned long init_text_end = (unsigned long)__init_text_end;
> > +   unsigned long init_data_start = (unsigned long)__init_data_begin;
> > +

Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Greentime Hu
Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
>
> Currently, .init.text & .init.data are intermixed which makes it impossible
> apply different permissions to them. .init.data shouldn't need exec
> permissions while .init.text shouldn't have write permission.
>
> Keep them in separate sections so that different permissions are applied to
> each section. This improves the kernel protection under
> CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
> entire _init section after it is freed so that those pages can be used for
> other purpose.
>
> Signed-off-by: Atish Patra 
> ---
>  arch/riscv/include/asm/sections.h   |  2 ++
>  arch/riscv/include/asm/set_memory.h |  2 ++
>  arch/riscv/kernel/setup.c   |  4 
>  arch/riscv/kernel/vmlinux.lds.S | 10 +-
>  arch/riscv/mm/init.c|  6 ++
>  arch/riscv/mm/pageattr.c|  6 ++
>  6 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/sections.h 
> b/arch/riscv/include/asm/sections.h
> index d60802bfafbc..730d2c4a844d 100644
> --- a/arch/riscv/include/asm/sections.h
> +++ b/arch/riscv/include/asm/sections.h
> @@ -10,6 +10,8 @@
>  #include 
>  extern char _start[];
>  extern char _start_kernel[];
> +extern char __init_data_begin[], __init_data_end[];
> +extern char __init_text_begin[], __init_text_end[];
>
>  extern bool init_mem_is_free;
>
> diff --git a/arch/riscv/include/asm/set_memory.h 
> b/arch/riscv/include/asm/set_memory.h
> index 4cc3a4e2afd3..913429c9c1ae 100644
> --- a/arch/riscv/include/asm/set_memory.h
> +++ b/arch/riscv/include/asm/set_memory.h
> @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
>  int set_memory_rw(unsigned long addr, int numpages);
>  int set_memory_x(unsigned long addr, int numpages);
>  int set_memory_nx(unsigned long addr, int numpages);
> +int set_memory_default(unsigned long addr, int numpages);
>  void protect_kernel_text_data(void);
>  #else
>  static inline int set_memory_ro(unsigned long addr, int numpages) { return 
> 0; }
> @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int 
> numpages) { return 0; }
>  static inline int set_memory_x(unsigned long addr, int numpages) { return 0; 
> }
>  static inline int set_memory_nx(unsigned long addr, int numpages) { return 
> 0; }
>  static inline void protect_kernel_text_data(void) {};
> +static inline int set_memory_default(unsigned long addr, int numpages) { 
> return 0; }
>  #endif
>
>  int set_direct_map_invalid_noflush(struct page *page);
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 4176a2affd1d..b8a35ef0eab0 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
>
>  void free_initmem(void)
>  {
> +   unsigned long init_begin = (unsigned long)__init_begin;
> +   unsigned long init_end = (unsigned long)__init_end;
> +
> +   set_memory_default(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
> free_initmem_default(POISON_FREE_INITMEM);
> init_mem_is_free = true;
>  }
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 0807633f0dc8..15b9882588ae 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -30,8 +30,8 @@ SECTIONS
> . = ALIGN(PAGE_SIZE);
>
> __init_begin = .;
> +   __init_text_begin = .;
> INIT_TEXT_SECTION(PAGE_SIZE)
> -   INIT_DATA_SECTION(16)
> . = ALIGN(8);
> __soc_early_init_table : {
> __soc_early_init_table_start = .;
> @@ -48,11 +48,19 @@ SECTIONS
> {
> EXIT_TEXT
> }
> +
> +   __init_text_end = .;
> +   . = ALIGN(SECTION_ALIGN);
> +   /* Start of init data section */
> +   __init_data_begin = .;
> +   INIT_DATA_SECTION(16)
> .exit.data :
> {
> EXIT_DATA
> }
> PERCPU_SECTION(L1_CACHE_BYTES)
> +
> +   __init_data_end = .;
> __init_end = .;
>
> . = ALIGN(SECTION_ALIGN);
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 7859a1d1b34d..3ef0eafcc7c7 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -627,11 +627,17 @@ void protect_kernel_text_data(void)
>  {
> unsigned long text_start = (unsigned long)_text;
> unsigned long text_end = (unsigned long)_etext;
> +   unsigned long init_text_start = (unsigned long)__init_text_begin;
> +   unsigned long init_text_end = (unsigned long)__init_text_end;
> +   unsigned long init_data_start = (unsigned long)__init_data_begin;
> +   unsigned long init_data_end = (unsigned long)__init_data_end;
> unsigned long rodata_start = (unsigned long)__start_rodata;
> unsigned long data_start = (unsigned long)_data;
> unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));
>
> +