Takashi Iwai 750d5f
From e74ef2194b41ba5e511fab29fe5ff00e72d2f42a Mon Sep 17 00:00:00 2001
Takashi Iwai 750d5f
From: Bastian Stender <bst@pengutronix.de>
Takashi Iwai 750d5f
Date: Thu, 8 Mar 2018 15:08:11 +0100
Takashi Iwai 750d5f
Subject: [PATCH] mmc: block: fix updating ext_csd caches on ioctl call
Takashi Iwai 750d5f
Git-commit: e74ef2194b41ba5e511fab29fe5ff00e72d2f42a
Takashi Iwai 750d5f
Patch-mainline: v4.16-rc7
Takashi Iwai 750d5f
References: bsc#1051510
Takashi Iwai 750d5f
Takashi Iwai 750d5f
PARTITION_CONFIG is cached in mmc_card->ext_csd.part_config and the
Takashi Iwai 750d5f
currently active partition in mmc_blk_data->part_curr. These caches do
Takashi Iwai 750d5f
not always reflect changes if the ioctl call modifies the
Takashi Iwai 750d5f
PARTITION_CONFIG registers, e.g. by changing BOOT_PARTITION_ENABLE.
Takashi Iwai 750d5f
Takashi Iwai 750d5f
Write the PARTITION_CONFIG value extracted from the ioctl call to the
Takashi Iwai 750d5f
cache and update the currently active partition accordingly. This
Takashi Iwai 750d5f
ensures that the user space cannot change the values behind the
Takashi Iwai 750d5f
kernel's back. The next call to mmc_blk_part_switch() will operate on
Takashi Iwai 750d5f
the data set by the ioctl and reflect the changes appropriately.
Takashi Iwai 750d5f
Takashi Iwai 750d5f
Signed-off-by: Bastian Stender <bst@pengutronix.de>
Takashi Iwai 750d5f
Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
Takashi Iwai 750d5f
Cc: stable@vger.kernel.org
Takashi Iwai 750d5f
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Takashi Iwai 750d5f
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 750d5f
Takashi Iwai 750d5f
---
Takashi Iwai 750d5f
 drivers/mmc/core/block.c |   19 +++++++++++++++++++
Takashi Iwai 750d5f
 1 file changed, 19 insertions(+)
Takashi Iwai 750d5f
Takashi Iwai 750d5f
--- a/drivers/mmc/core/block.c
Takashi Iwai 750d5f
+++ b/drivers/mmc/core/block.c
Takashi Iwai 750d5f
@@ -64,6 +64,7 @@ MODULE_ALIAS("mmc:block");
Takashi Iwai 750d5f
 #define MMC_BLK_TIMEOUT_MS  (10 * 60 * 1000)        /* 10 minute timeout */
Takashi Iwai 750d5f
 #define MMC_SANITIZE_REQ_TIMEOUT 240000
Takashi Iwai 750d5f
 #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
Takashi Iwai 750d5f
+#define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8)
Takashi Iwai 750d5f
 
Takashi Iwai 750d5f
 #define mmc_req_rel_wr(req)	((req->cmd_flags & REQ_FUA) && \
Takashi Iwai 750d5f
 				  (rq_data_dir(req) == WRITE))
Takashi Iwai 750d5f
@@ -543,6 +544,24 @@ static int __mmc_blk_ioctl_cmd(struct mm
Takashi Iwai 750d5f
 	}
Takashi Iwai 750d5f
 
Takashi Iwai 750d5f
 	/*
Takashi Iwai 750d5f
+	 * Make sure the cache of the PARTITION_CONFIG register and
Takashi Iwai 750d5f
+	 * PARTITION_ACCESS bits is updated in case the ioctl ext_csd write
Takashi Iwai 750d5f
+	 * changed it successfully.
Takashi Iwai 750d5f
+	 */
Takashi Iwai 750d5f
+	if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_PART_CONFIG) &&
Takashi Iwai 750d5f
+	    (cmd.opcode == MMC_SWITCH)) {
Takashi Iwai 750d5f
+		struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev);
Takashi Iwai 750d5f
+		u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg);
Takashi Iwai 750d5f
+
Takashi Iwai 750d5f
+		/*
Takashi Iwai 750d5f
+		 * Update cache so the next mmc_blk_part_switch call operates
Takashi Iwai 750d5f
+		 * on up-to-date data.
Takashi Iwai 750d5f
+		 */
Takashi Iwai 750d5f
+		card->ext_csd.part_config = value;
Takashi Iwai 750d5f
+		main_md->part_curr = value & EXT_CSD_PART_CONFIG_ACC_MASK;
Takashi Iwai 750d5f
+	}
Takashi Iwai 750d5f
+
Takashi Iwai 750d5f
+	/*
Takashi Iwai 750d5f
 	 * According to the SD specs, some commands require a delay after
Takashi Iwai 750d5f
 	 * issuing the command.
Takashi Iwai 750d5f
 	 */