aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2017-11-21 08:42:30 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2017-11-23 08:39:13 -0500
commitf9f0da98819503b06b35e61869d18cf3a8cd3323 (patch)
tree3958ac5701d4c83a9b79f27bbdb40df395aaa7db
parentebe7dd45cf49e3b49cacbaace17f9f878f21fbea (diff)
mmc: block: Ensure that debugfs files are removed
The card is not necessarily being removed, but the debugfs files must be removed when the driver is removed, otherwise they will continue to exist after unbinding the card from the driver. e.g. # echo "mmc1:0001" > /sys/bus/mmc/drivers/mmcblk/unbind # cat /sys/kernel/debug/mmc1/mmc1\:0001/ext_csd [ 173.634584] BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 [ 173.643356] IP: mmc_ext_csd_open+0x5e/0x170 A complication is that the debugfs_root may have already been removed, so check for that too. Fixes: 627c3ccfb46a ("mmc: debugfs: Move block debugfs into block module") Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Cc: stable@vger.kernel.org # 4.14+ Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/mmc/core/block.c44
-rw-r--r--drivers/mmc/core/debugfs.c1
2 files changed, 38 insertions, 7 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 4a319ddbd956..ccfa98af1dd3 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -122,6 +122,10 @@ struct mmc_blk_data {
122 struct device_attribute force_ro; 122 struct device_attribute force_ro;
123 struct device_attribute power_ro_lock; 123 struct device_attribute power_ro_lock;
124 int area_type; 124 int area_type;
125
126 /* debugfs files (only in main mmc_blk_data) */
127 struct dentry *status_dentry;
128 struct dentry *ext_csd_dentry;
125}; 129};
126 130
127/* Device type for RPMB character devices */ 131/* Device type for RPMB character devices */
@@ -2653,7 +2657,7 @@ static const struct file_operations mmc_dbg_ext_csd_fops = {
2653 .llseek = default_llseek, 2657 .llseek = default_llseek,
2654}; 2658};
2655 2659
2656static int mmc_blk_add_debugfs(struct mmc_card *card) 2660static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)
2657{ 2661{
2658 struct dentry *root; 2662 struct dentry *root;
2659 2663
@@ -2663,28 +2667,53 @@ static int mmc_blk_add_debugfs(struct mmc_card *card)
2663 root = card->debugfs_root; 2667 root = card->debugfs_root;
2664 2668
2665 if (mmc_card_mmc(card) || mmc_card_sd(card)) { 2669 if (mmc_card_mmc(card) || mmc_card_sd(card)) {
2666 if (!debugfs_create_file("status", S_IRUSR, root, card, 2670 md->status_dentry =
2667 &mmc_dbg_card_status_fops)) 2671 debugfs_create_file("status", S_IRUSR, root, card,
2672 &mmc_dbg_card_status_fops);
2673 if (!md->status_dentry)
2668 return -EIO; 2674 return -EIO;
2669 } 2675 }
2670 2676
2671 if (mmc_card_mmc(card)) { 2677 if (mmc_card_mmc(card)) {
2672 if (!debugfs_create_file("ext_csd", S_IRUSR, root, card, 2678 md->ext_csd_dentry =
2673 &mmc_dbg_ext_csd_fops)) 2679 debugfs_create_file("ext_csd", S_IRUSR, root, card,
2680 &mmc_dbg_ext_csd_fops);
2681 if (!md->ext_csd_dentry)
2674 return -EIO; 2682 return -EIO;
2675 } 2683 }
2676 2684
2677 return 0; 2685 return 0;
2678} 2686}
2679 2687
2688static void mmc_blk_remove_debugfs(struct mmc_card *card,
2689 struct mmc_blk_data *md)
2690{
2691 if (!card->debugfs_root)
2692 return;
2693
2694 if (!IS_ERR_OR_NULL(md->status_dentry)) {
2695 debugfs_remove(md->status_dentry);
2696 md->status_dentry = NULL;
2697 }
2698
2699 if (!IS_ERR_OR_NULL(md->ext_csd_dentry)) {
2700 debugfs_remove(md->ext_csd_dentry);
2701 md->ext_csd_dentry = NULL;
2702 }
2703}
2680 2704
2681#else 2705#else
2682 2706
2683static int mmc_blk_add_debugfs(struct mmc_card *card) 2707static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)
2684{ 2708{
2685 return 0; 2709 return 0;
2686} 2710}
2687 2711
2712static void mmc_blk_remove_debugfs(struct mmc_card *card,
2713 struct mmc_blk_data *md)
2714{
2715}
2716
2688#endif /* CONFIG_DEBUG_FS */ 2717#endif /* CONFIG_DEBUG_FS */
2689 2718
2690static int mmc_blk_probe(struct mmc_card *card) 2719static int mmc_blk_probe(struct mmc_card *card)
@@ -2724,7 +2753,7 @@ static int mmc_blk_probe(struct mmc_card *card)
2724 } 2753 }
2725 2754
2726 /* Add two debugfs entries */ 2755 /* Add two debugfs entries */
2727 mmc_blk_add_debugfs(card); 2756 mmc_blk_add_debugfs(card, md);
2728 2757
2729 pm_runtime_set_autosuspend_delay(&card->dev, 3000); 2758 pm_runtime_set_autosuspend_delay(&card->dev, 3000);
2730 pm_runtime_use_autosuspend(&card->dev); 2759 pm_runtime_use_autosuspend(&card->dev);
@@ -2750,6 +2779,7 @@ static void mmc_blk_remove(struct mmc_card *card)
2750{ 2779{
2751 struct mmc_blk_data *md = dev_get_drvdata(&card->dev); 2780 struct mmc_blk_data *md = dev_get_drvdata(&card->dev);
2752 2781
2782 mmc_blk_remove_debugfs(card, md);
2753 mmc_blk_remove_parts(card, md); 2783 mmc_blk_remove_parts(card, md);
2754 pm_runtime_get_sync(&card->dev); 2784 pm_runtime_get_sync(&card->dev);
2755 mmc_claim_host(card->host); 2785 mmc_claim_host(card->host);
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 01e459a34f33..0f4a7d7b2626 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -314,4 +314,5 @@ err:
314void mmc_remove_card_debugfs(struct mmc_card *card) 314void mmc_remove_card_debugfs(struct mmc_card *card)
315{ 315{
316 debugfs_remove_recursive(card->debugfs_root); 316 debugfs_remove_recursive(card->debugfs_root);
317 card->debugfs_root = NULL;
317} 318}