duptext: export fault data structure, add mmu notifier when memory unmap and add an offset to heap segment

Signed-off-by: wangzhimin1179@phytium.com.cn
This commit is contained in:
wangzhimin 2024-09-10 16:17:04 +08:00
parent 23fc10f227
commit e007f5685f
6 changed files with 35 additions and 5 deletions

View File

@ -48,7 +48,8 @@ struct fault_info {
const char *name;
};
static const struct fault_info fault_info[];
struct fault_info fault_info[];
EXPORT_SYMBOL(fault_info);
static struct fault_info debug_fault_info[];
static inline const struct fault_info *esr_to_fault_info(unsigned int esr)
@ -387,7 +388,7 @@ static void set_thread_esr(unsigned long address, unsigned int esr)
current->thread.fault_code = esr;
}
static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
{
/*
* If we are in kernel mode at this point, we have no context to
@ -403,6 +404,7 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
__do_kernel_fault(addr, esr, regs);
}
}
EXPORT_SYMBOL(do_bad_area);
#define VM_FAULT_BADMAP 0x010000
#define VM_FAULT_BADACCESS 0x020000
@ -1593,7 +1595,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
return 0;
}
static const struct fault_info fault_info[] = {
struct fault_info fault_info[] = {
{ do_bad, SIGKILL, SI_KERNEL, "ttbr address size fault" },
{ do_bad, SIGKILL, SI_KERNEL, "level 1 address size fault" },
{ do_bad, SIGKILL, SI_KERNEL, "level 2 address size fault" },

View File

@ -75,6 +75,7 @@ void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
pgd_clear_fixmap();
spin_unlock(&swapper_pgdir_lock);
}
EXPORT_SYMBOL(set_swapper_pgd);
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
@ -694,6 +695,7 @@ void __init paging_init(void)
memblock_allow_resize();
}
EXPORT_SYMBOL(swapper_pg_dir);
/*
* Check whether a kernel address is valid (derived from arch/x86/).

View File

@ -57,6 +57,13 @@
#define elf_check_fdpic(ex) false
#endif
#ifndef CONFIG_COMPAT_BINFMT_ELF
unsigned long brk_offset = PMD_SIZE;
EXPORT_SYMBOL(brk_offset);
#endif
extern struct static_key_false phytium_duptext_static_key;
static int load_elf_binary(struct linux_binprm *bprm);
#ifdef CONFIG_USELIB
@ -1118,9 +1125,12 @@ out_free_interp:
loc->elf_ex.e_type == ET_DYN && !interpreter)
current->mm->brk = current->mm->start_brk =
ELF_ET_DYN_BASE;
if (static_branch_unlikely(&phytium_duptext_static_key)) {
current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm) + brk_offset;
} else {
current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm);
}
current->mm->brk = current->mm->start_brk =
arch_randomize_brk(current->mm);
#ifdef compat_brk_randomized
current->brk_randomized = 1;
#endif

View File

@ -130,4 +130,9 @@
/*
* We share all the actual code with the native (64-bit) version.
*/
#ifdef CONFIG_COMPAT_BINFMT_ELF
unsigned long brk_offset = PMD_SIZE;
EXPORT_SYMBOL(brk_offset);
#endif
#include "binfmt_elf.c"

View File

@ -85,6 +85,7 @@ extern int sysctl_protected_hardlinks;
extern int sysctl_protected_fifos;
extern int sysctl_protected_regular;
extern unsigned int sysctl_nvidia_smi_trap;
extern unsigned long brk_offset;
typedef __kernel_rwf_t rwf_t;

View File

@ -2640,6 +2640,9 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
validate_mm(mm);
}
DEFINE_STATIC_KEY_FALSE(phytium_duptext_static_key);
EXPORT_SYMBOL(phytium_duptext_static_key);
/*
* Get rid of page table information in the indicated region.
*
@ -2649,6 +2652,7 @@ static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
unsigned long start, unsigned long end)
{
struct mmu_notifier_range range;
struct vm_area_struct *next = prev ? prev->vm_next : mm->mmap;
struct mmu_gather tlb;
struct vm_area_struct *cur_vma;
@ -2675,6 +2679,12 @@ static void unmap_region(struct mm_struct *mm,
free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
next ? next->vm_start : USER_PGTABLES_CEILING);
if (static_branch_unlikely(&phytium_duptext_static_key)) {
mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma, vma->vm_mm,
start, end);
mmu_notifier_invalidate_range_start(&range);
mmu_notifier_invalidate_range_end(&range);
}
tlb_finish_mmu(&tlb, start, end);
}