diff --git a/src/binfmt_rto/binfmt_rto.c b/src/binfmt_rto/binfmt_rto.c index e91c0c5ef5b9b51ae09369ac6d50a531195fa8f2..ff3826181874bd95f3216ff2569b71988b5bdd84 100644 --- a/src/binfmt_rto/binfmt_rto.c +++ b/src/binfmt_rto/binfmt_rto.c @@ -68,6 +68,11 @@ #define MM_SAVED_AUXV(mm) mm->saved_auxv #endif +/* x86, 22.03 LTS map_vdso is undefine */ +#ifndef map_vdso +extern int map_vdso(const struct vdso_image *image, unsigned long addr); +#endif + #define proc_symbol(SYM) typeof(SYM) *(SYM) static struct global_symbols { #ifdef CONFIG_ARM64 @@ -1389,7 +1394,7 @@ out_free_interp: for(i = 0, elf_ppnt = elf_phdata; i < elf_ex->e_phnum; i++, elf_ppnt++) { int elf_prot, elf_flags; - unsigned long k, vaddr, size, off; + unsigned long k, vaddr; unsigned long total_size = 0; unsigned long alignment; diff --git a/src/binfmt_rto/rto_populate.c b/src/binfmt_rto/rto_populate.c index 19f45b4aa208e092afd38961130bb5b284d51032..45ac1391ea992036189ebbf8703417dede261198 100644 --- a/src/binfmt_rto/rto_populate.c +++ b/src/binfmt_rto/rto_populate.c @@ -33,7 +33,9 @@ #include #include +#ifdef CONFIG_ARM64 #include +#endif #include #include "main.h" @@ -56,7 +58,10 @@ static struct global_symbols { proc_symbol(__pud_alloc); proc_symbol(__anon_vma_prepare); proc_symbol(__pmd_alloc); - +#ifdef CONFIG_X86 + proc_symbol(__p4d_alloc); + proc_symbol(pud_clear_bad); +#endif } ppl_sym; #define proc_symbol_char(x) #x @@ -66,8 +71,47 @@ static char *global_symbol_names[] = { proc_symbol_char(__pud_alloc), proc_symbol_char(__anon_vma_prepare), proc_symbol_char(__pmd_alloc), +#ifdef CONFIG_X86 + proc_symbol_char(__p4d_alloc), + proc_symbol_char(pud_clear_bad), +#endif }; +#ifdef CONFIG_X86 +// p4d_alloc -> __p4d_alloc +#define p4d_alloc rto_p4d_alloc +static inline p4d_t *rto_p4d_alloc(struct mm_struct *mm, pgd_t *pgd, + unsigned long address) +{ + return (unlikely(pgd_none(*pgd)) && ppl_sym.__p4d_alloc(mm, pgd, address)) ? + NULL : p4d_offset(pgd, address); +} + +// pud_trans_unstable() +// pud_none_or_trans_huge_or_dev_or_clear_bad() +// pud_clear_bad() +#define pud_trans_unstable rto_pud_trans_unstable + +static inline int rto_pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) +{ + pud_t pudval = READ_ONCE(*pud); + + if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval)) + return 1; + if (unlikely(pud_bad(pudval))) { + ppl_sym.pud_clear_bad(pud); + return 1; + } + return 0; +} + +static inline int rto_pud_trans_unstable(pud_t *pud) +{ + return rto_pud_none_or_trans_huge_or_dev_or_clear_bad(pud); +} + +#endif + static int init_symbols(void) { int ret;