register panic notifier callback for saveing regs, add a module param regfs_panic to enable the show reg info when panic. Signed-off-by: Zou Cao <zoucao@xxxxxxxxxxxxxxxxx> --- fs/regfs/inode.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/fs/regfs/inode.c b/fs/regfs/inode.c index 1643fcd..6c79f73 100644 --- a/fs/regfs/inode.c +++ b/fs/regfs/inode.c @@ -46,10 +46,41 @@ static LIST_HEAD(regfs_head); static const struct inode_operations regfs_dir_inode_operations; -int regfs_debug; +int regfs_debug = 1; module_param(regfs_debug, int, S_IRUGO); MODULE_PARM_DESC(regfs_debug, "enable regfs debug mode"); +static int regfs_panic = 1; +module_param(regfs_panic, int, S_IRUGO); +MODULE_PARM_DESC(regfs_debug, "printk the register when panic"); + +//save all register val when panic +static int regfs_panic_event(struct notifier_block *self, + unsigned long val, void *data) +{ + struct regfs_fs_info *fsi; + struct inode *inode, *next; + + + list_for_each_entry(fsi, ®fs_head, regfs_head) { + list_for_each_entry_safe(inode, next, &fsi->sb->s_inodes, i_sb_list) { + struct regfs_inode_info *info = REGFS_I(inode);; + //save the regs val + if (info->type == RES_TYPE_ITEM) { + info->val = readl_relaxed(info->base + info->offset); + if (regfs_panic) + printk("%llx:%llx\n", (u64)(info->base + info->offset), info->val); + } + } + } + + return NOTIFY_DONE; +} + +static struct notifier_block regfs_panic_event_nb = { + .notifier_call = regfs_panic_event, +}; + struct inode *regfs_get_inode(struct super_block *sb, const struct inode *dir, umode_t mode, dev_t dev) { struct inode *inode = new_inode(sb); @@ -328,6 +359,7 @@ static void init_once(void *foo) static int __init init_regfs_fs(void) { + int ret; regfs_inode_cachep = kmem_cache_create_usercopy("regfs_inode_cache", sizeof(struct regfs_inode_info), 0, @@ -337,11 +369,16 @@ static int __init init_regfs_fs(void) if (!regfs_inode_cachep) return -ENOMEM; + ret = atomic_notifier_chain_register(&panic_notifier_list, ®fs_panic_event_nb); + if (ret) + pr_warn("regfs regiter panic notifier failed\n"); + return register_filesystem(®fs_fs_type); } static void __exit exit_regfs_fs(void) { + atomic_notifier_chain_unregister(&panic_notifier_list, ®fs_panic_event_nb); unregister_filesystem(®fs_fs_type); rcu_barrier(); kmem_cache_destroy(regfs_inode_cachep); -- 1.8.3.1