From 65ec3786aa1bfba5ca2e259fc78b0ef9d7924c9f Mon Sep 17 00:00:00 2001 From: Phanindra Babu Pabba Date: Tue, 1 Dec 2020 22:21:22 +0530 Subject: [PATCH] mmc: host: Fix bootup issue with file encryption with GKI Export and call crypto APIs from command queue driver to service file encryption request and program inline crypto engine to encrypt/decrypt the data. Change-Id: I8c9c8413e59454605c711a6a5c14308122a751e2 Signed-off-by: Phanindra Babu Pabba --- drivers/mmc/host/Kconfig | 2 +- drivers/mmc/host/cqhci-crypto-qti.c | 13 ++-- drivers/mmc/host/cqhci-crypto-qti.h | 5 ++ drivers/mmc/host/cqhci-crypto.c | 10 ++++ drivers/mmc/host/cqhci-crypto.h | 92 +++++++++++++++++++++++------ drivers/mmc/host/cqhci.c | 26 +------- drivers/mmc/host/sdhci-msm.c | 2 - 7 files changed, 99 insertions(+), 51 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index e6eb14b9795c..a95781d7a4fd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -1044,7 +1044,7 @@ config SDC_QTI config MMC_CQHCI_CRYPTO tristate "CQHCI Crypto Engine Support" - depends on MMC_CQHCI && BLK_INLINE_ENCRYPTION + depends on BLK_INLINE_ENCRYPTION help Enable Crypto Engine Support in CQHCI. Enabling this makes it possible for the kernel to use the crypto diff --git a/drivers/mmc/host/cqhci-crypto-qti.c b/drivers/mmc/host/cqhci-crypto-qti.c index de7fc5c5c63b..27dcebe1e1b4 100644 --- a/drivers/mmc/host/cqhci-crypto-qti.c +++ b/drivers/mmc/host/cqhci-crypto-qti.c @@ -210,19 +210,21 @@ int cqhci_host_init_crypto_qti_spec(struct cqhci_host *host, host->crypto_cap_array[cap_idx].sdus_mask * 512; } - host->ksm = keyslot_manager_create(host->mmc->parent, + host->mmc->ksm = keyslot_manager_create(host->mmc->parent, cqhci_num_keyslots(host), ksm_ops, BLK_CRYPTO_FEATURE_STANDARD_KEYS | BLK_CRYPTO_FEATURE_WRAPPED_KEYS, crypto_modes_supported, host); - keyslot_manager_set_max_dun_bytes(host->ksm, sizeof(u32)); - - if (!host->ksm) { + if (!host->mmc->ksm) { err = -ENOMEM; goto out; } + + host->mmc->caps2 |= MMC_CAP2_CRYPTO; + keyslot_manager_set_max_dun_bytes(host->mmc->ksm, sizeof(u32)); + /* * In case host controller supports cryptographic operations * then, it uses 128bit task descriptor. Upper 64 bits of task @@ -305,10 +307,9 @@ int cqhci_crypto_qti_debug(struct cqhci_host *host) void cqhci_crypto_qti_set_vops(struct cqhci_host *host) { -#if defined(CONFIG_MMC_CQHCI_CRYPTO) return cqhci_crypto_set_vops(host, &cqhci_crypto_qti_variant_ops); -#endif } +EXPORT_SYMBOL(cqhci_crypto_qti_set_vops); int cqhci_crypto_qti_resume(struct cqhci_host *host) { diff --git a/drivers/mmc/host/cqhci-crypto-qti.h b/drivers/mmc/host/cqhci-crypto-qti.h index 2788e96b8c16..07300624b6a1 100644 --- a/drivers/mmc/host/cqhci-crypto-qti.h +++ b/drivers/mmc/host/cqhci-crypto-qti.h @@ -19,7 +19,12 @@ int cqhci_crypto_qti_init_crypto(struct cqhci_host *host, int cqhci_crypto_qti_debug(struct cqhci_host *host); +#if IS_ENABLED(CONFIG_MMC_CQHCI_CRYPTO_QTI) void cqhci_crypto_qti_set_vops(struct cqhci_host *host); +#else +void cqhci_crypto_qti_set_vops(struct cqhci_host *host) +{} +#endif /* CONFIG_MMC_CQHCI_CRYPTO_QTI) */ int cqhci_crypto_qti_resume(struct cqhci_host *host); diff --git a/drivers/mmc/host/cqhci-crypto.c b/drivers/mmc/host/cqhci-crypto.c index 2241ba7f7e92..adb61f6c48a7 100644 --- a/drivers/mmc/host/cqhci-crypto.c +++ b/drivers/mmc/host/cqhci-crypto.c @@ -426,6 +426,7 @@ void cqhci_crypto_enable(struct cqhci_host *host) return cqhci_crypto_enable_spec(host); } +EXPORT_SYMBOL(cqhci_crypto_enable); void cqhci_crypto_disable(struct cqhci_host *host) { @@ -434,6 +435,7 @@ void cqhci_crypto_disable(struct cqhci_host *host) return cqhci_crypto_disable_spec(host); } +EXPORT_SYMBOL(cqhci_crypto_disable); int cqhci_host_init_crypto(struct cqhci_host *host) { @@ -443,6 +445,7 @@ int cqhci_host_init_crypto(struct cqhci_host *host) return cqhci_host_init_crypto_spec(host, &cqhci_ksm_ops); } +EXPORT_SYMBOL(cqhci_host_init_crypto); void cqhci_crypto_setup_rq_keyslot_manager(struct cqhci_host *host, struct request_queue *q) @@ -472,6 +475,7 @@ int cqhci_crypto_get_ctx(struct cqhci_host *host, return cqhci_prepare_crypto_desc_spec(host, mrq, ice_ctx); } +EXPORT_SYMBOL(cqhci_crypto_get_ctx); int cqhci_complete_crypto_desc(struct cqhci_host *host, struct mmc_request *mrq, @@ -483,18 +487,21 @@ int cqhci_complete_crypto_desc(struct cqhci_host *host, return 0; } +EXPORT_SYMBOL(cqhci_complete_crypto_desc); void cqhci_crypto_debug(struct cqhci_host *host) { if (host->crypto_vops && host->crypto_vops->debug) host->crypto_vops->debug(host); } +EXPORT_SYMBOL(cqhci_crypto_debug); void cqhci_crypto_set_vops(struct cqhci_host *host, struct cqhci_host_crypto_variant_ops *crypto_vops) { host->crypto_vops = crypto_vops; } +EXPORT_SYMBOL(cqhci_crypto_set_vops); int cqhci_crypto_suspend(struct cqhci_host *host) { @@ -503,6 +510,7 @@ int cqhci_crypto_suspend(struct cqhci_host *host) return 0; } +EXPORT_SYMBOL(cqhci_crypto_suspend); int cqhci_crypto_resume(struct cqhci_host *host) { @@ -519,6 +527,7 @@ int cqhci_crypto_reset(struct cqhci_host *host) return 0; } +EXPORT_SYMBOL(cqhci_crypto_reset); int cqhci_crypto_recovery_finish(struct cqhci_host *host) { @@ -530,6 +539,7 @@ int cqhci_crypto_recovery_finish(struct cqhci_host *host) return 0; } +EXPORT_SYMBOL(cqhci_crypto_recovery_finish); MODULE_DESCRIPTION("CQHCI Crypto Engine Support"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/host/cqhci-crypto.h b/drivers/mmc/host/cqhci-crypto.h index a6dbeb25f198..94f6cc174ebf 100644 --- a/drivers/mmc/host/cqhci-crypto.h +++ b/drivers/mmc/host/cqhci-crypto.h @@ -40,8 +40,8 @@ static inline bool cqhci_is_crypto_enabled(struct cqhci_host *host) /* Functions implementing eMMC v5.2 specification behaviour */ int cqhci_prepare_crypto_desc_spec(struct cqhci_host *host, - struct mmc_request *mrq, - u64 *ice_ctx); + struct mmc_request *mrq, + u64 *ice_ctx); void cqhci_crypto_enable_spec(struct cqhci_host *host); @@ -51,46 +51,102 @@ int cqhci_host_init_crypto_spec(struct cqhci_host *host, const struct keyslot_mgmt_ll_ops *ksm_ops); void cqhci_crypto_setup_rq_keyslot_manager_spec(struct cqhci_host *host, - struct request_queue *q); + struct request_queue *q); void cqhci_crypto_destroy_rq_keyslot_manager_spec(struct cqhci_host *host, - struct request_queue *q); + struct request_queue *q); +#if IS_ENABLED(CONFIG_MMC_CQHCI_CRYPTO) void cqhci_crypto_set_vops(struct cqhci_host *host, - struct cqhci_host_crypto_variant_ops *crypto_vops); + struct cqhci_host_crypto_variant_ops *crypto_vops); +#else +void cqhci_crypto_set_vops(struct cqhci_host *host, + struct cqhci_host_crypto_variant_ops *crypto_vops) +{} +#endif /* CONFIG_MMC_CQHCI_CRYPTO */ /* Crypto Variant Ops Support */ - +#if IS_ENABLED(CONFIG_MMC_CQHCI_CRYPTO) void cqhci_crypto_enable(struct cqhci_host *host); void cqhci_crypto_disable(struct cqhci_host *host); int cqhci_host_init_crypto(struct cqhci_host *host); -void cqhci_crypto_setup_rq_keyslot_manager(struct cqhci_host *host, - struct request_queue *q); - -void cqhci_crypto_destroy_rq_keyslot_manager(struct cqhci_host *host, - struct request_queue *q); - int cqhci_crypto_get_ctx(struct cqhci_host *host, - struct mmc_request *mrq, - u64 *ice_ctx); + struct mmc_request *mrq, + u64 *ice_ctx); int cqhci_complete_crypto_desc(struct cqhci_host *host, - struct mmc_request *mrq, - u64 *ice_ctx); + struct mmc_request *mrq, + u64 *ice_ctx); void cqhci_crypto_debug(struct cqhci_host *host); int cqhci_crypto_suspend(struct cqhci_host *host); -int cqhci_crypto_resume(struct cqhci_host *host); - int cqhci_crypto_reset(struct cqhci_host *host); int cqhci_crypto_recovery_finish(struct cqhci_host *host); + +void cqhci_crypto_setup_rq_keyslot_manager(struct cqhci_host *host, + struct request_queue *q); +#else +void cqhci_crypto_enable(struct cqhci_host *host) +{} + +void cqhci_crypto_disable(struct cqhci_host *host) +{} + +int cqhci_host_init_crypto(struct cqhci_host *host) +{ + return 0; +} + +int cqhci_crypto_get_ctx(struct cqhci_host *host, + struct mmc_request *mrq, + u64 *ice_ctx) +{ + return 0; +} + +int cqhci_complete_crypto_desc(struct cqhci_host *host, + struct mmc_request *mrq, + u64 *ice_ctx) +{ + return 0; +} + +void cqhci_crypto_debug(struct cqhci_host *host) +{} + +int cqhci_crypto_suspend(struct cqhci_host *host) +{ + return 0; +} + +int cqhci_crypto_reset(struct cqhci_host *host) +{ + return 0; +} + +int cqhci_crypto_recovery_finish(struct cqhci_host *host) +{ + return 0; +} + +void cqhci_crypto_setup_rq_keyslot_manager(struct cqhci_host *host, + struct request_queue *q) +{} +#endif /* CONFIG_MMC_CQHCI_CRYPTO */ + +void cqhci_crypto_destroy_rq_keyslot_manager(struct cqhci_host *host, + struct request_queue *q); + + +int cqhci_crypto_resume(struct cqhci_host *host); + int cqhci_crypto_cap_find(void *host_p, enum blk_crypto_mode_num crypto_mode, unsigned int data_unit_size); diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index 8c41477bcb88..c239ffa7629d 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c @@ -154,9 +154,7 @@ static void cqhci_dumpregs(struct cqhci_host *cq_host) CQHCI_DUMP("Vendor cfg 0x%08x\n", cqhci_readl(cq_host, CQHCI_VENDOR_CFG + offset)); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) cqhci_crypto_debug(cq_host); -#endif if (cq_host->ops->dumpregs) cq_host->ops->dumpregs(mmc); @@ -278,10 +276,8 @@ static void __cqhci_enable(struct cqhci_host *cq_host) if (cq_host->caps & CQHCI_TASK_DESC_SZ_128) cqcfg |= CQHCI_TASK_DESC_SZ; -#if defined(CONFIG_MMC_CQHCI_CRYPTO) if (cqhci_host_is_crypto_supported(cq_host)) cqcfg |= CQHCI_ICE_ENABLE; -#endif cqhci_writel(cq_host, cqcfg, CQHCI_CFG); @@ -330,9 +326,7 @@ int cqhci_deactivate(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; -#if defined(CONFIG_MMC_CQHCI_CRYPTO) cqhci_crypto_suspend(cq_host); -#endif if (cq_host->enabled && cq_host->activated) __cqhci_disable(cq_host); @@ -367,10 +361,8 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) return err; } -#if defined(CONFIG_MMC_CQHCI_CRYPTO) if (cqhci_host_is_crypto_supported(cq_host)) cqhci_crypto_enable(cq_host); -#endif __cqhci_enable(cq_host); @@ -425,10 +417,8 @@ static void cqhci_disable(struct mmc_host *mmc) cqhci_off(mmc); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) if (cqhci_host_is_crypto_supported(cq_host)) cqhci_crypto_disable(cq_host); -#endif __cqhci_disable(cq_host); @@ -660,14 +650,12 @@ static int cqhci_request(struct mmc_host *mmc, struct mmc_request *mrq) } if (mrq->data) { -#if defined(CONFIG_MMC_CQHCI_CRYPTO) err = cqhci_crypto_get_ctx(cq_host, mrq, &ice_ctx); if (err) { pr_err("%s: failed to retrieve crypto ctx for tag %d\n", mmc_hostname(mmc), tag); return err; } -#endif task_desc = (__le64 __force *)get_desc(cq_host, tag); cqhci_prep_task_desc(mrq, &data, 1); *task_desc = cpu_to_le64(data); @@ -707,14 +695,12 @@ out_unlock: if (err) cqhci_post_req(mmc, mrq); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) if (mrq->data) cqhci_complete_crypto_desc(cq_host, mrq, NULL); -#endif return err; } -#if defined(CONFIG_SDC_QTI) && defined(CONFIG_MMC_CQHCI_CRYPTO) +#if defined(CONFIG_SDC_QTI) static void cqhci_crypto_update_queue(struct mmc_host *mmc, struct request_queue *queue) { @@ -852,9 +838,7 @@ static void cqhci_finish_mrq(struct mmc_host *mmc, unsigned int tag) data = mrq->data; if (data) { -#if defined(CONFIG_MMC_CQHCI_CRYPTO) cqhci_complete_crypto_desc(cq_host, mrq, NULL); -#endif if (data->error) data->bytes_xfered = 0; else @@ -1062,9 +1046,7 @@ static void cqhci_recovery_start(struct mmc_host *mmc) pr_debug("%s: cqhci: %s\n", mmc_hostname(mmc), __func__); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) cqhci_crypto_reset(cq_host); -#endif WARN_ON(!cq_host->recovery_halt); @@ -1186,9 +1168,7 @@ static void cqhci_recovery_finish(struct mmc_host *mmc) cqhci_set_irqs(cq_host, CQHCI_IS_MASK); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) cqhci_crypto_recovery_finish(cq_host); -#endif pr_debug("%s: cqhci: recovery done\n", mmc_hostname(mmc)); mmc_log_string(mmc, "recovery done\n"); } @@ -1203,7 +1183,7 @@ static const struct mmc_cqe_ops cqhci_cqe_ops = { .cqe_timeout = cqhci_timeout, .cqe_recovery_start = cqhci_recovery_start, .cqe_recovery_finish = cqhci_recovery_finish, -#if defined(CONFIG_SDC_QTI) && defined(CONFIG_MMC_CQHCI_CRYPTO) +#if defined(CONFIG_SDC_QTI) .cqe_crypto_update_queue = cqhci_crypto_update_queue, #endif }; @@ -1279,14 +1259,12 @@ int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, spin_lock_init(&cq_host->lock); -#if defined(CONFIG_MMC_CQHCI_CRYPTO) err = cqhci_host_init_crypto(cq_host); if (err) { pr_err("%s: CQHCI version %u.%02u Crypto init failed err %d\n", mmc_hostname(mmc), cqhci_ver_major(cq_host), cqhci_ver_minor(cq_host), err); } -#endif init_completion(&cq_host->halt_comp); init_waitqueue_head(&cq_host->wait_queue); diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 3659601a46d3..d4352faa295c 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -3161,9 +3161,7 @@ static int sdhci_msm_cqe_add_host(struct sdhci_host *host, * Set the vendor specific ops needed for ICE. * Default implementation if the ops are not set. */ -#ifdef CONFIG_MMC_CQHCI_CRYPTO_QTI cqhci_crypto_qti_set_vops(cq_host); -#endif ret = cqhci_init(cq_host, host->mmc, dma64); if (ret) {