162306a36Sopenharmony_ci#include <asm/interrupt.h>
262306a36Sopenharmony_ci#include <asm/kprobes.h>
362306a36Sopenharmony_ci
462306a36Sopenharmony_cistruct soft_mask_table_entry {
562306a36Sopenharmony_ci	unsigned long start;
662306a36Sopenharmony_ci	unsigned long end;
762306a36Sopenharmony_ci};
862306a36Sopenharmony_ci
962306a36Sopenharmony_cistruct restart_table_entry {
1062306a36Sopenharmony_ci	unsigned long start;
1162306a36Sopenharmony_ci	unsigned long end;
1262306a36Sopenharmony_ci	unsigned long fixup;
1362306a36Sopenharmony_ci};
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciextern struct soft_mask_table_entry __start___soft_mask_table[];
1662306a36Sopenharmony_ciextern struct soft_mask_table_entry __stop___soft_mask_table[];
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciextern struct restart_table_entry __start___restart_table[];
1962306a36Sopenharmony_ciextern struct restart_table_entry __stop___restart_table[];
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* Given an address, look for it in the soft mask table */
2262306a36Sopenharmony_cibool search_kernel_soft_mask_table(unsigned long addr)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	struct soft_mask_table_entry *smte = __start___soft_mask_table;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	while (smte < __stop___soft_mask_table) {
2762306a36Sopenharmony_ci		unsigned long start = smte->start;
2862306a36Sopenharmony_ci		unsigned long end = smte->end;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci		if (addr >= start && addr < end)
3162306a36Sopenharmony_ci			return true;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci		smte++;
3462306a36Sopenharmony_ci	}
3562306a36Sopenharmony_ci	return false;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ciNOKPROBE_SYMBOL(search_kernel_soft_mask_table);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* Given an address, look for it in the kernel exception table */
4062306a36Sopenharmony_ciunsigned long search_kernel_restart_table(unsigned long addr)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	struct restart_table_entry *rte = __start___restart_table;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	while (rte < __stop___restart_table) {
4562306a36Sopenharmony_ci		unsigned long start = rte->start;
4662306a36Sopenharmony_ci		unsigned long end = rte->end;
4762306a36Sopenharmony_ci		unsigned long fixup = rte->fixup;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci		if (addr >= start && addr < end)
5062306a36Sopenharmony_ci			return fixup;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci		rte++;
5362306a36Sopenharmony_ci	}
5462306a36Sopenharmony_ci	return 0;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ciNOKPROBE_SYMBOL(search_kernel_restart_table);
57