Merge "mmc: host: Fix bootup issue with file encryption with GKI"

This commit is contained in:
qctecmdr 2020-12-21 04:30:53 -08:00 • committed by Gerrit - the friendly Code Review server
commit eb6b695ebe
7 changed files with 99 additions and 51 deletions

View file

@ -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

View file

@ -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)
{

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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);

View file

@ -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) {