Re: [PATCH v5 1/4] riscv: Move kernel mapping to vmalloc zone

2020-07-09 Thread Zong Li
On Thu, Jul 9, 2020 at 1:05 PM Palmer Dabbelt  wrote:
>
> On Sun, 07 Jun 2020 00:59:46 PDT (-0700), a...@ghiti.fr wrote:
> > This is a preparatory patch for relocatable kernel.
> >
> > The kernel used to be linked at PAGE_OFFSET address and used to be loaded
> > physically at the beginning of the main memory. Therefore, we could use
> > the linear mapping for the kernel mapping.
> >
> > But the relocated kernel base address will be different from PAGE_OFFSET
> > and since in the linear mapping, two different virtual addresses cannot
> > point to the same physical address, the kernel mapping needs to lie outside
> > the linear mapping.
>
> I know it's been a while, but I keep opening this up to review it and just
> can't get over how ugly it is to put the kernel's linear map in the vmalloc
> region.
>
> I guess I don't understand why this is necessary at all.  Specifically: why
> can't we just relocate the kernel within the linear map?  That would let the
> bootloader put the kernel wherever it wants, modulo the physical memory size 
> we
> support.  We'd need to handle the regions that are coupled to the kernel's
> execution address, but we could just put them in an explicit memory region
> which is what we should probably be doing anyway.

The original implementation of relocation doesn't move the kernel's linear map
to the vmalloc region, and I also give the KASLR RFC patch [1] based on that.
In original, we relocate the kernel in the linear map region, we would
calculate a
random value first as the offset, then we move the kernel image to the
new target
address which is obtained by adding this offset to it's VA and PA.
It's enough for
randomizing the kernel, but it seems to me if we want to decouple the kernel's
linear mapping, the physical mapping of RAM and virtual mapping of RAM,
it might be good to move the kernel's mapping out from the linear region.
Even so, it is still an intrusive change. As far as I know, only arm64
does something
like that.

[1]  https://patchwork.kernel.org/project/linux-riscv/list/?series=260615



>
> > In addition, because modules and BPF must be close to the kernel (inside
> > +-2GB window), the kernel is placed at the end of the vmalloc zone minus
> > 2GB, which leaves room for modules and BPF. The kernel could not be
> > placed at the beginning of the vmalloc zone since other vmalloc
> > allocations from the kernel could get all the +-2GB window around the
> > kernel which would prevent new modules and BPF programs to be loaded.
>
> Well, that's not enough to make sure this doesn't happen -- it's just enough 
> to
> make sure it doesn't happen very quickily.  That's the same boat we're already
> in, though, so it's not like it's worse.
>
> > Signed-off-by: Alexandre Ghiti 
> > Reviewed-by: Zong Li 
> > ---
> >  arch/riscv/boot/loader.lds.S |  3 +-
> >  arch/riscv/include/asm/page.h| 10 +-
> >  arch/riscv/include/asm/pgtable.h | 38 ++---
> >  arch/riscv/kernel/head.S |  3 +-
> >  arch/riscv/kernel/module.c   |  4 +--
> >  arch/riscv/kernel/vmlinux.lds.S  |  3 +-
> >  arch/riscv/mm/init.c | 58 +---
> >  arch/riscv/mm/physaddr.c |  2 +-
> >  8 files changed, 88 insertions(+), 33 deletions(-)
> >
> > diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
> > index 47a5003c2e28..62d94696a19c 100644
> > --- a/arch/riscv/boot/loader.lds.S
> > +++ b/arch/riscv/boot/loader.lds.S
> > @@ -1,13 +1,14 @@
> >  /* SPDX-License-Identifier: GPL-2.0 */
> >
> >  #include 
> > +#include 
> >
> >  OUTPUT_ARCH(riscv)
> >  ENTRY(_start)
> >
> >  SECTIONS
> >  {
> > - . = PAGE_OFFSET;
> > + . = KERNEL_LINK_ADDR;
> >
> >   .payload : {
> >   *(.payload)
> > diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> > index 2d50f76efe48..48bb09b6a9b7 100644
> > --- a/arch/riscv/include/asm/page.h
> > +++ b/arch/riscv/include/asm/page.h
> > @@ -90,18 +90,26 @@ typedef struct page *pgtable_t;
> >
> >  #ifdef CONFIG_MMU
> >  extern unsigned long va_pa_offset;
> > +extern unsigned long va_kernel_pa_offset;
> >  extern unsigned long pfn_base;
> >  #define ARCH_PFN_OFFSET  (pfn_base)
> >  #else
> >  #define va_pa_offset 0
> > +#define va_kernel_pa_offset  0
> >  #define ARCH_PFN_OFFSET  (PAGE_OFFSET >> PAGE_SHIFT)
> >  #endif /* CONFIG_MMU */
> >
> >  extern unsigned long max_low_pfn;
> >  extern unsigned long min_low_pfn;

Re: [PATCH v4 1/4] riscv: Move kernel mapping to vmalloc zone

2020-06-03 Thread Zong Li
 long)&_start & PAGE_MASK) + SZ_2G)
> +#endif
>
>  /*
>   * Roughly size the vmemmap space to be large enough to fit enough
> @@ -57,9 +63,16 @@
>  #define FIXADDR_SIZE PGDIR_SIZE
>  #endif
>  #define FIXADDR_START(FIXADDR_TOP - FIXADDR_SIZE)
> -
>  #endif
>
> +#ifndef __ASSEMBLY__
> +
> +/* Page Upper Directory not used in RISC-V */
> +#include 
> +#include 
> +#include 
> +#include 
> +
>  #ifdef CONFIG_64BIT
>  #include 
>  #else
> @@ -483,6 +496,7 @@ static inline void __kernel_map_pages(struct page *page, 
> int numpages, int enabl
>
>  #define kern_addr_valid(addr)   (1) /* FIXME */
>
> +extern char _start[];
>  extern void *dtb_early_va;
>  void setup_bootmem(void);
>  void paging_init(void);
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 98a406474e7d..8f5bb7731327 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -49,7 +49,8 @@ ENTRY(_start)
>  #ifdef CONFIG_MMU
>  relocate:
> /* Relocate return address */
> -   li a1, PAGE_OFFSET
> +   la a1, kernel_virt_addr
> +   REG_L a1, 0(a1)
> la a2, _start
> sub a1, a1, a2
> add ra, ra, a1
> diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
> index 8bbe5dbe1341..1a8fbe05accf 100644
> --- a/arch/riscv/kernel/module.c
> +++ b/arch/riscv/kernel/module.c
> @@ -392,12 +392,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char 
> *strtab,
>  }
>
>  #if defined(CONFIG_MMU) && defined(CONFIG_64BIT)
> -#define VMALLOC_MODULE_START \
> -max(PFN_ALIGN((unsigned long)&_end - SZ_2G), VMALLOC_START)
>  void *module_alloc(unsigned long size)
>  {
> return __vmalloc_node_range(size, 1, VMALLOC_MODULE_START,
> -   VMALLOC_END, GFP_KERNEL,
> +   VMALLOC_MODULE_END, GFP_KERNEL,
> PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
> __builtin_return_address(0));
>  }
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 0339b6bbe11a..a9abde62909f 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -4,7 +4,8 @@
>   * Copyright (C) 2017 SiFive
>   */
>
> -#define LOAD_OFFSET PAGE_OFFSET
> +#include 
> +#define LOAD_OFFSET KERNEL_LINK_ADDR
>  #include 
>  #include 
>  #include 
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 736de6c8739f..37be2eb45e58 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -22,6 +22,9 @@
>
>  #include "../kernel/head.h"
>
> +unsigned long kernel_virt_addr = KERNEL_VIRT_ADDR;
> +EXPORT_SYMBOL(kernel_virt_addr);
> +
>  unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
> __page_aligned_bss;
>  EXPORT_SYMBOL(empty_zero_page);
> @@ -178,8 +181,12 @@ void __init setup_bootmem(void)
>  }
>
>  #ifdef CONFIG_MMU
> +/* Offset between linear mapping virtual address and kernel load address */
>  unsigned long va_pa_offset;
>  EXPORT_SYMBOL(va_pa_offset);
> +/* Offset between kernel mapping virtual address and kernel load address */
> +unsigned long va_kernel_pa_offset;
> +EXPORT_SYMBOL(va_kernel_pa_offset);
>  unsigned long pfn_base;
>  EXPORT_SYMBOL(pfn_base);
>
> @@ -271,7 +278,7 @@ static phys_addr_t __init alloc_pmd(uintptr_t va)
> if (mmu_enabled)
> return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
>
> -   pmd_num = (va - PAGE_OFFSET) >> PGDIR_SHIFT;
> +   pmd_num = (va - kernel_virt_addr) >> PGDIR_SHIFT;
> BUG_ON(pmd_num >= NUM_EARLY_PMDS);
> return (uintptr_t)_pmd[pmd_num * PTRS_PER_PMD];
>  }
> @@ -372,14 +379,30 @@ static uintptr_t __init best_map_size(phys_addr_t base, 
> phys_addr_t size)
>  #error "setup_vm() is called from head.S before relocate so it should not 
> use absolute addressing."
>  #endif
>
> +static uintptr_t load_pa, load_sz;
> +
> +void create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size)

It could be static if this function is only used in this file, as
kbuild test reported.
Apart from this, it looks good to me.
Reviewed-by: Zong Li 

> +{
> +   uintptr_t va, end_va;
> +
> +   end_va = kernel_virt_addr + load_sz;
> +   for (va = kernel_virt_addr; va < end_va; va += map_size)
> +   create_pgd_mapping(pgdir, va,
> +  load_pa + (va - kernel_virt_addr),
> +  map_size, PAGE_KERNEL_EXEC);
> +}
> +
>

Re: [PATCH v3 1/3] riscv: Move kernel mapping to vmalloc zone

2020-05-27 Thread Zong Li
On Wed, May 27, 2020 at 1:06 AM Alex Ghiti  wrote:
>
> Hi Zong,
>
> Le 5/26/20 à 5:43 AM, Zong Li a écrit :
> > On Sun, May 24, 2020 at 4:54 PM Alexandre Ghiti  wrote:
> >> This is a preparatory patch for relocatable kernel.
> >>
> >> The kernel used to be linked at PAGE_OFFSET address and used to be loaded
> >> physically at the beginning of the main memory. Therefore, we could use
> >> the linear mapping for the kernel mapping.
> >>
> >> But the relocated kernel base address will be different from PAGE_OFFSET
> >> and since in the linear mapping, two different virtual addresses cannot
> >> point to the same physical address, the kernel mapping needs to lie outside
> >> the linear mapping.
> >>
> >> In addition, because modules and BPF must be close to the kernel (inside
> >> +-2GB window), the kernel is placed at the end of the vmalloc zone minus
> >> 2GB, which leaves room for modules and BPF. The kernel could not be
> >> placed at the beginning of the vmalloc zone since other vmalloc
> >> allocations from the kernel could get all the +-2GB window around the
> >> kernel which would prevent new modules and BPF programs to be loaded.
> >>
> >> Signed-off-by: Alexandre Ghiti 
> >> ---
> >>   arch/riscv/boot/loader.lds.S |  3 +-
> >>   arch/riscv/include/asm/page.h| 10 +-
> >>   arch/riscv/include/asm/pgtable.h | 37 +---
> >>   arch/riscv/kernel/head.S |  3 +-
> >>   arch/riscv/kernel/module.c   |  4 +--
> >>   arch/riscv/kernel/vmlinux.lds.S  |  3 +-
> >>   arch/riscv/mm/init.c | 58 +---
> >>   arch/riscv/mm/physaddr.c |  2 +-
> >>   8 files changed, 87 insertions(+), 33 deletions(-)
> >>
> >> diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
> >> index 47a5003c2e28..62d94696a19c 100644
> >> --- a/arch/riscv/boot/loader.lds.S
> >> +++ b/arch/riscv/boot/loader.lds.S
> >> @@ -1,13 +1,14 @@
> >>   /* SPDX-License-Identifier: GPL-2.0 */
> >>
> >>   #include 
> >> +#include 
> >>
> >>   OUTPUT_ARCH(riscv)
> >>   ENTRY(_start)
> >>
> >>   SECTIONS
> >>   {
> >> -   . = PAGE_OFFSET;
> >> +   . = KERNEL_LINK_ADDR;
> >>
> >>  .payload : {
> >>  *(.payload)
> >> diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> >> index 2d50f76efe48..48bb09b6a9b7 100644
> >> --- a/arch/riscv/include/asm/page.h
> >> +++ b/arch/riscv/include/asm/page.h
> >> @@ -90,18 +90,26 @@ typedef struct page *pgtable_t;
> >>
> >>   #ifdef CONFIG_MMU
> >>   extern unsigned long va_pa_offset;
> >> +extern unsigned long va_kernel_pa_offset;
> >>   extern unsigned long pfn_base;
> >>   #define ARCH_PFN_OFFSET(pfn_base)
> >>   #else
> >>   #define va_pa_offset   0
> >> +#define va_kernel_pa_offset0
> >>   #define ARCH_PFN_OFFSET(PAGE_OFFSET >> PAGE_SHIFT)
> >>   #endif /* CONFIG_MMU */
> >>
> >>   extern unsigned long max_low_pfn;
> >>   extern unsigned long min_low_pfn;
> >> +extern unsigned long kernel_virt_addr;
> >>
> >>   #define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + 
> >> va_pa_offset))
> >> -#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - va_pa_offset)
> >> +#define linear_mapping_va_to_pa(x) ((unsigned long)(x) - va_pa_offset)
> >> +#define kernel_mapping_va_to_pa(x) \
> >> +   ((unsigned long)(x) - va_kernel_pa_offset)
> >> +#define __va_to_pa_nodebug(x)  \
> >> +   (((x) >= PAGE_OFFSET) ? \
> >> +   linear_mapping_va_to_pa(x) : kernel_mapping_va_to_pa(x))
> >>
> >>   #ifdef CONFIG_DEBUG_VIRTUAL
> >>   extern phys_addr_t __virt_to_phys(unsigned long x);
> >> diff --git a/arch/riscv/include/asm/pgtable.h 
> >> b/arch/riscv/include/asm/pgtable.h
> >> index 35b60035b6b0..25213cfaf680 100644
> >> --- a/arch/riscv/include/asm/pgtable.h
> >> +++ b/arch/riscv/include/asm/pgtable.h
> >> @@ -11,23 +11,29 @@
> >>
> >>   #include 
> >>
> >> -#ifndef __ASSEMBLY__
> >> -
> >> -/* Page Upper Directory not used in RISC-V */
> >> -#include 
> >> -#include 
> >> -#include 
> >&

Re: [PATCH v3 1/3] riscv: Move kernel mapping to vmalloc zone

2020-05-26 Thread Zong Li
On Sun, May 24, 2020 at 4:54 PM Alexandre Ghiti  wrote:
>
> This is a preparatory patch for relocatable kernel.
>
> The kernel used to be linked at PAGE_OFFSET address and used to be loaded
> physically at the beginning of the main memory. Therefore, we could use
> the linear mapping for the kernel mapping.
>
> But the relocated kernel base address will be different from PAGE_OFFSET
> and since in the linear mapping, two different virtual addresses cannot
> point to the same physical address, the kernel mapping needs to lie outside
> the linear mapping.
>
> In addition, because modules and BPF must be close to the kernel (inside
> +-2GB window), the kernel is placed at the end of the vmalloc zone minus
> 2GB, which leaves room for modules and BPF. The kernel could not be
> placed at the beginning of the vmalloc zone since other vmalloc
> allocations from the kernel could get all the +-2GB window around the
> kernel which would prevent new modules and BPF programs to be loaded.
>
> Signed-off-by: Alexandre Ghiti 
> ---
>  arch/riscv/boot/loader.lds.S |  3 +-
>  arch/riscv/include/asm/page.h| 10 +-
>  arch/riscv/include/asm/pgtable.h | 37 +---
>  arch/riscv/kernel/head.S |  3 +-
>  arch/riscv/kernel/module.c   |  4 +--
>  arch/riscv/kernel/vmlinux.lds.S  |  3 +-
>  arch/riscv/mm/init.c | 58 +---
>  arch/riscv/mm/physaddr.c |  2 +-
>  8 files changed, 87 insertions(+), 33 deletions(-)
>
> diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
> index 47a5003c2e28..62d94696a19c 100644
> --- a/arch/riscv/boot/loader.lds.S
> +++ b/arch/riscv/boot/loader.lds.S
> @@ -1,13 +1,14 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>
>  #include 
> +#include 
>
>  OUTPUT_ARCH(riscv)
>  ENTRY(_start)
>
>  SECTIONS
>  {
> -   . = PAGE_OFFSET;
> +   . = KERNEL_LINK_ADDR;
>
> .payload : {
> *(.payload)
> diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> index 2d50f76efe48..48bb09b6a9b7 100644
> --- a/arch/riscv/include/asm/page.h
> +++ b/arch/riscv/include/asm/page.h
> @@ -90,18 +90,26 @@ typedef struct page *pgtable_t;
>
>  #ifdef CONFIG_MMU
>  extern unsigned long va_pa_offset;
> +extern unsigned long va_kernel_pa_offset;
>  extern unsigned long pfn_base;
>  #define ARCH_PFN_OFFSET(pfn_base)
>  #else
>  #define va_pa_offset   0
> +#define va_kernel_pa_offset0
>  #define ARCH_PFN_OFFSET(PAGE_OFFSET >> PAGE_SHIFT)
>  #endif /* CONFIG_MMU */
>
>  extern unsigned long max_low_pfn;
>  extern unsigned long min_low_pfn;
> +extern unsigned long kernel_virt_addr;
>
>  #define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + va_pa_offset))
> -#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - va_pa_offset)
> +#define linear_mapping_va_to_pa(x) ((unsigned long)(x) - va_pa_offset)
> +#define kernel_mapping_va_to_pa(x) \
> +   ((unsigned long)(x) - va_kernel_pa_offset)
> +#define __va_to_pa_nodebug(x)  \
> +   (((x) >= PAGE_OFFSET) ? \
> +   linear_mapping_va_to_pa(x) : kernel_mapping_va_to_pa(x))
>
>  #ifdef CONFIG_DEBUG_VIRTUAL
>  extern phys_addr_t __virt_to_phys(unsigned long x);
> diff --git a/arch/riscv/include/asm/pgtable.h 
> b/arch/riscv/include/asm/pgtable.h
> index 35b60035b6b0..25213cfaf680 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -11,23 +11,29 @@
>
>  #include 
>
> -#ifndef __ASSEMBLY__
> -
> -/* Page Upper Directory not used in RISC-V */
> -#include 
> -#include 
> -#include 
> -#include 
> -
> -#ifdef CONFIG_MMU
> +#ifndef CONFIG_MMU
> +#define KERNEL_VIRT_ADDR   PAGE_OFFSET
> +#define KERNEL_LINK_ADDR   PAGE_OFFSET
> +#else
> +/*
> + * Leave 2GB for modules and BPF that must lie within a 2GB range around
> + * the kernel.
> + */
> +#define KERNEL_VIRT_ADDR   (VMALLOC_END - SZ_2G + 1)
> +#define KERNEL_LINK_ADDR   KERNEL_VIRT_ADDR
>
>  #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
>  #define VMALLOC_END  (PAGE_OFFSET - 1)
>  #define VMALLOC_START(PAGE_OFFSET - VMALLOC_SIZE)
>
>  #define BPF_JIT_REGION_SIZE(SZ_128M)
> -#define BPF_JIT_REGION_START   (PAGE_OFFSET - BPF_JIT_REGION_SIZE)
> -#define BPF_JIT_REGION_END (VMALLOC_END)
> +#define BPF_JIT_REGION_START   (kernel_virt_addr)
> +#define BPF_JIT_REGION_END (kernel_virt_addr + BPF_JIT_REGION_SIZE)

It seems to have a potential risk here, the region of bpf is
overlapping with kernel mapping, so if kernel size is bigger than
128MB, bpf region would be occupied and run out by kernel mapping.

> +
> +#ifdef CONFIG_64BIT
> +#define VMALLOC_MODULE_START   BPF_JIT_REGION_END
> +#define VMALLOC_MODULE_END VMALLOC_END
> +#endif
>

Although kernel_virt_addr is a fixed address now, I think it could be
changed for the purpose of relocatable or KASLR, so if
kernel_virt_addr is moved to far from VMALLOC_END than 2G, the region
of module 

Re: [PATCH v3 2/3] riscv: Introduce CONFIG_RELOCATABLE

2020-05-26 Thread Zong Li
 Elf_Addr addr = (rela->r_offset - va_kernel_link_pa_offset);
> +   Elf_Addr relocated_addr = rela->r_addend;
> +
> +   if (rela->r_info != R_RISCV_RELATIVE)
> +   continue;
> +
> +   /*
> +* Make sure to not relocate vdso symbols like rt_sigreturn
> +* which are linked from the address 0 in vmlinux since
> +* vdso symbol addresses are actually used as an offset from
> +* mm->context.vdso in VDSO_OFFSET macro.
> +*/
> +   if (relocated_addr >= KERNEL_LINK_ADDR)
> +   relocated_addr += reloc_offset;
> +
> +   *(Elf_Addr *)addr = relocated_addr;
> +   }
> +}
> +
> +#endif
> +
>  static uintptr_t load_pa, load_sz;
>
>  void create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size)
> @@ -405,6 +455,19 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
>
> pfn_base = PFN_DOWN(load_pa);
>
> +#ifdef CONFIG_RELOCATABLE
> +#ifdef CONFIG_64BIT
> +   /*
> +* Early page table uses only one PGDIR, which makes it possible
> +* to map PGDIR_SIZE aligned on PGDIR_SIZE: if the relocation offset
> +* makes the kernel cross over a PGDIR_SIZE boundary, raise a bug
> +* since a part of the kernel would not get mapped.
> +* This cannot happen on rv32 as we use the entire page directory 
> level.
> +*/
> +   BUG_ON(PGDIR_SIZE - (kernel_virt_addr & (PGDIR_SIZE - 1)) < load_sz);
> +#endif
> +   relocate_kernel(load_pa);
> +#endif
> /*
>  * Enforce boot alignment requirements of RV32 and
>  * RV64 by only allowing PMD or PGD mappings.
> --
> 2.20.1
>

Looks good to me.

Reviewed-by: Zong Li 


Re: linux-next: build warning after merge of the bpf-next tree

2020-01-12 Thread Zong Li
On Sat, Jan 11, 2020 at 10:31 PM Alexandre Ghiti  wrote:
>
>
> On 1/10/20 7:20 PM, Palmer Dabbelt wrote:
> > On Fri, 10 Jan 2020 14:28:17 PST (-0800), alexan...@ghiti.fr wrote:
> >> Hi guys,
> >>
> >> On 10/27/19 8:02 PM, Stephen Rothwell wrote:
> >>> Hi all,
> >>>
> >>> On Fri, 18 Oct 2019 10:56:57 +1100 Stephen Rothwell
> >>>  wrote:
>  Hi all,
> 
>  After merging the bpf-next tree, today's linux-next build (powerpc
>  ppc64_defconfig) produced this warning:
> 
>  WARNING: 2 bad relocations
>  c1998a48 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_start
>  c1998a50 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_end
> 
>  Introduced by commit
> 
> 8580ac9404f6 ("bpf: Process in-kernel BTF")
> >>> This warning now appears in the net-next tree build.
> >>>
> >>>
> >> I bump that thread up because Zong also noticed that 2 new
> >> relocations for
> >> those symbols appeared in my riscv relocatable kernel branch following
> >> that commit.
> >>
> >> I also noticed 2 new relocations R_AARCH64_ABS64 appearing in arm64
> >> kernel.
> >>
> >> Those 2 weak undefined symbols have existed since commit
> >> 341dfcf8d78e ("btf: expose BTF info through sysfs") but this is the fact
> >> to declare those symbols into btf.c that produced those relocations.
> >>
> >> I'm not sure what this all means, but this is not something I expected
> >> for riscv for
> >> a kernel linked with -shared/-fpie. Maybe should we just leave them to
> >> zero ?
> >>
> >> I think that deserves a deeper look if someone understands all this
> >> better than I do.
> >
> > Can you give me a pointer to your tree and how to build a relocatable
> > kernel?
> > Weak undefined symbols have the absolute value 0,
>
>
> So according to you the 2 new relocations R_RISCV_64 are normal and
> should not
> be modified at runtime right ?
>
>
> > but the kernel is linked at
> > an address such that 0 can't be reached by normal means.  When I added
> > support
> > to binutils for this I did it in a way that required almost no code --
> > essetially I just stopped dissallowing x0 as a possible base register
> > for PCREL
> > relocations, which results in 0 always being accessible.  I just
> > wanted to get
> > the kernel to build again, so I didn't worry about chasing around all the
> > addressing modes.  The PIC/PIE support generates different relocations
> > and I
> > wouldn't be surprised if I just missed one (or more likely all) of them.
> >
> > It's probably a simple fix, though I feel like every time I say that
> > about the
> > linker I end up spending a month in there...
>
> You can find it here:
>
> https://github.com/AlexGhiti/riscv-linux/tree/int/alex/riscv_relocatable_v1
>
> Zong fixed the bug introduced by those 2 new relocations and everything
> works
> like a charm, so I'm not sure you have to dig in the linker :)
>

I'm not quite familiar with btf, so I have no idea why there are two
weak symbols be added in 8580ac9404f6 ("bpf: Process in-kernel BTF")
as well, According on relocation mechanism, maybe it is unnecessary to
handle weak undefined symbol at this time, because there is no
substantive help to relocate the absolute value 0. I just simply
ignore the non-relative relocation types to make processing can go
forward, and it works for me based on v5.5-rc5.

> Alex
>