mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-11 20:26:46 +07:00
arm64: mm: print out correct page table entries
When we take a fault that can't be handled, we print out the page table entries associated with the faulting address. In some cases we currently print out the wrong entries. For a faulting TTBR1 address, we sometimes print out TTBR0 table entries instead, and for a faulting TTBR0 address we sometimes print out TTBR1 table entries. Fix this by choosing the tables based on the faulting address. Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com> [will: zero-extend addrs to 64-bit, don't walk swapper w/ TTBR0 addr] Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
e71a4e1beb
commit
67ce16ec15
@ -40,7 +40,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
|
||||
int sig, int code, const char *name);
|
||||
|
||||
struct mm_struct;
|
||||
extern void show_pte(struct mm_struct *mm, unsigned long addr);
|
||||
extern void show_pte(unsigned long addr);
|
||||
extern void __show_regs(struct pt_regs *);
|
||||
|
||||
extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
|
||||
|
@ -80,18 +80,33 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dump out the page tables associated with 'addr' in mm 'mm'.
|
||||
* Dump out the page tables associated with 'addr' in the currently active mm.
|
||||
*/
|
||||
void show_pte(struct mm_struct *mm, unsigned long addr)
|
||||
void show_pte(unsigned long addr)
|
||||
{
|
||||
struct mm_struct *mm;
|
||||
pgd_t *pgd;
|
||||
|
||||
if (!mm)
|
||||
if (addr < TASK_SIZE) {
|
||||
/* TTBR0 */
|
||||
mm = current->active_mm;
|
||||
if (mm == &init_mm) {
|
||||
pr_alert("[%016lx] user address but active_mm is swapper\n",
|
||||
addr);
|
||||
return;
|
||||
}
|
||||
} else if (addr >= VA_START) {
|
||||
/* TTBR1 */
|
||||
mm = &init_mm;
|
||||
} else {
|
||||
pr_alert("[%016lx] address between user and kernel address ranges\n",
|
||||
addr);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_alert("pgd = %p\n", mm->pgd);
|
||||
pgd = pgd_offset(mm, addr);
|
||||
pr_alert("[%08lx] *pgd=%016llx", addr, pgd_val(*pgd));
|
||||
pr_alert("[%016lx] *pgd=%016llx", addr, pgd_val(*pgd));
|
||||
|
||||
do {
|
||||
pud_t *pud;
|
||||
@ -196,8 +211,8 @@ static inline bool is_permission_fault(unsigned int esr, struct pt_regs *regs,
|
||||
/*
|
||||
* The kernel tried to access some page that wasn't present.
|
||||
*/
|
||||
static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
|
||||
unsigned int esr, struct pt_regs *regs)
|
||||
static void __do_kernel_fault(unsigned long addr, unsigned int esr,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
const char *msg;
|
||||
|
||||
@ -227,7 +242,7 @@ static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
|
||||
pr_alert("Unable to handle kernel %s at virtual address %08lx\n", msg,
|
||||
addr);
|
||||
|
||||
show_pte(mm, addr);
|
||||
show_pte(addr);
|
||||
die("Oops", regs, esr);
|
||||
bust_spinlocks(0);
|
||||
do_exit(SIGKILL);
|
||||
@ -249,7 +264,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
|
||||
pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n",
|
||||
tsk->comm, task_pid_nr(tsk), inf->name, sig,
|
||||
addr, esr);
|
||||
show_pte(tsk->mm, addr);
|
||||
show_pte(addr);
|
||||
__show_regs(regs);
|
||||
}
|
||||
|
||||
@ -265,7 +280,6 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
|
||||
static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
struct mm_struct *mm = tsk->active_mm;
|
||||
const struct fault_info *inf;
|
||||
|
||||
/*
|
||||
@ -276,7 +290,7 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
|
||||
inf = esr_to_fault_info(esr);
|
||||
__do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs);
|
||||
} else
|
||||
__do_kernel_fault(mm, addr, esr, regs);
|
||||
__do_kernel_fault(addr, esr, regs);
|
||||
}
|
||||
|
||||
#define VM_FAULT_BADMAP 0x010000
|
||||
@ -475,7 +489,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
|
||||
return 0;
|
||||
|
||||
no_context:
|
||||
__do_kernel_fault(mm, addr, esr, regs);
|
||||
__do_kernel_fault(addr, esr, regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user