From 57ff1319018f45069477b5d10f1e553bcc63e289 Mon Sep 17 00:00:00 2001 From: Vaibhav Agrawal Date: Mon, 12 Oct 2020 20:05:00 +0530 Subject: [PATCH] Add support for EMMC storage type Add support for parsing EMMC specific address for hwkm slave in cqhci crypto driver. Add similar support in ufs crypto driver as well to get UFS specific address. Remove support for parsing the hwkm slave address from dtsi node from hwkm driver as it will be received as part of hwkm_init(). Enable/disable cqhci crypto from cqhci_enable and cqhci_disable instead of __cqhci_enable and __cqhci_disable. Test: 1. Device booted upto UI with File Based Encryption enabled. 2. Key insertion using fscryptctl tool. 3. Created new files under /data and checked retention across multiple re-boots. 4. vts_kernel_encryption_test tests. 5. check_encryption test for verifying metadata encryption. 6. Bootup wth qgki compiled build. 7. Bootup on holi and shima UFS device. 8. Setting encryption policy and read/write of data over multiple reboots, using fscryptctl tool. Change-Id: I1f437ebf8a3f4cd008027d708ccacc02dfb14d07 Signed-off-by: Vaibhav Agrawal --- drivers/mmc/host/Kconfig | 4 ++-- drivers/mmc/host/cqhci-crypto-qti.c | 25 +++++++++++++++++++++++-- drivers/mmc/host/cqhci-crypto.h | 3 ++- drivers/mmc/host/cqhci.c | 13 +++++++------ drivers/scsi/ufs/ufshcd-crypto-qti.c | 24 ++++++++++++++++++++++-- drivers/soc/qcom/crypto-qti-common.c | 3 ++- drivers/soc/qcom/crypto-qti-hwkm.c | 4 ++-- drivers/soc/qcom/hwkm.c | 16 ++++++++++------ include/linux/crypto-qti-common.h | 4 +++- include/linux/hwkm.h | 5 +++-- 10 files changed, 76 insertions(+), 25 deletions(-) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 8f696b2bcba7..e6eb14b9795c 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -1043,7 +1043,7 @@ config SDC_QTI MMC upstream driver. config MMC_CQHCI_CRYPTO - bool "CQHCI Crypto Engine Support" + tristate "CQHCI Crypto Engine Support" depends on MMC_CQHCI && BLK_INLINE_ENCRYPTION help Enable Crypto Engine Support in CQHCI. @@ -1052,7 +1052,7 @@ config MMC_CQHCI_CRYPTO operations on data being transferred to/from the device. config MMC_CQHCI_CRYPTO_QTI - bool "Vendor specific CQHCI Crypto Engine Support" + tristate "Vendor specific CQHCI Crypto Engine Support" depends on MMC_CQHCI_CRYPTO help Enable Vendor Crypto Engine Support in CQHCI diff --git a/drivers/mmc/host/cqhci-crypto-qti.c b/drivers/mmc/host/cqhci-crypto-qti.c index 4f1f3c08c7f3..c4f95ca67f05 100644 --- a/drivers/mmc/host/cqhci-crypto-qti.c +++ b/drivers/mmc/host/cqhci-crypto-qti.c @@ -243,6 +243,8 @@ int cqhci_crypto_qti_init_crypto(struct cqhci_host *host, { int err = 0; struct resource *cqhci_ice_memres = NULL; + struct resource *hwkm_ice_memres = NULL; + void __iomem *hwkm_ice_mmio = NULL; cqhci_ice_memres = platform_get_resource_byname(host->pdev, IORESOURCE_MEM, @@ -261,6 +263,24 @@ int cqhci_crypto_qti_init_crypto(struct cqhci_host *host, return PTR_ERR(host->icemmio); } + hwkm_ice_memres = platform_get_resource_byname(host->pdev, + IORESOURCE_MEM, + "cqhci_ice_hwkm"); + + if (!hwkm_ice_memres) { + pr_err("%s: Either no entry in dtsi or no memory available for IORESOURCE\n", + __func__); + } else { + hwkm_ice_mmio = devm_ioremap_resource(&host->pdev->dev, + hwkm_ice_memres); + if (IS_ERR(hwkm_ice_mmio)) { + err = PTR_ERR(hwkm_ice_mmio); + pr_err("%s: Error = %d mapping HWKM memory\n", + __func__, err); + return err; + } + } + err = cqhci_host_init_crypto_qti_spec(host, &cqhci_crypto_qti_ksm_ops); if (err) { pr_err("%s: Error initiating crypto capabilities, err %d\n", @@ -268,8 +288,9 @@ int cqhci_crypto_qti_init_crypto(struct cqhci_host *host, return err; } - err = crypto_qti_init_crypto(&host->pdev->dev, - host->icemmio, (void **)&host->crypto_vops->priv); + err = crypto_qti_init_crypto(&host->pdev->dev, host->icemmio, + hwkm_ice_mmio, + (void **)&host->crypto_vops->priv); if (err) { pr_err("%s: Error initiating crypto, err %d\n", __func__, err); diff --git a/drivers/mmc/host/cqhci-crypto.h b/drivers/mmc/host/cqhci-crypto.h index fefad902ddea..2553393fe997 100644 --- a/drivers/mmc/host/cqhci-crypto.h +++ b/drivers/mmc/host/cqhci-crypto.h @@ -9,10 +9,11 @@ #ifndef _CQHCI_CRYPTO_H #define _CQHCI_CRYPTO_H -#ifdef CONFIG_MMC_CQHCI_CRYPTO #include #include "cqhci.h" +#ifdef CONFIG_MMC_CQHCI_CRYPTO + static inline int cqhci_num_keyslots(struct cqhci_host *host) { return host->crypto_capabilities.config_count + 1; diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index 8507fb417557..70aaf65ed951 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c @@ -276,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 (cqhci_host_is_crypto_supported(cq_host)) { - cqhci_crypto_enable(cq_host); + if (cqhci_host_is_crypto_supported(cq_host)) cqcfg |= CQHCI_ICE_ENABLE; - } cqhci_writel(cq_host, cqcfg, CQHCI_CFG); @@ -314,9 +312,6 @@ static void __cqhci_disable(struct cqhci_host *cq_host) { u32 cqcfg; - if (cqhci_host_is_crypto_supported(cq_host)) - cqhci_crypto_disable(cq_host); - cqcfg = cqhci_readl(cq_host, CQHCI_CFG); cqcfg &= ~CQHCI_ENABLE; cqhci_writel(cq_host, cqcfg, CQHCI_CFG); @@ -367,6 +362,9 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) return err; } + if (cqhci_host_is_crypto_supported(cq_host)) + cqhci_crypto_enable(cq_host); + __cqhci_enable(cq_host); cq_host->enabled = true; @@ -418,6 +416,9 @@ static void cqhci_disable(struct mmc_host *mmc) cqhci_off(mmc); + if (cqhci_host_is_crypto_supported(cq_host)) + cqhci_crypto_disable(cq_host); + __cqhci_disable(cq_host); dmam_free_coherent(mmc_dev(mmc), cq_host->data_size, diff --git a/drivers/scsi/ufs/ufshcd-crypto-qti.c b/drivers/scsi/ufs/ufshcd-crypto-qti.c index a7f629d7c943..fcaa01b612c9 100644 --- a/drivers/scsi/ufs/ufshcd-crypto-qti.c +++ b/drivers/scsi/ufs/ufshcd-crypto-qti.c @@ -267,6 +267,8 @@ int ufshcd_crypto_qti_init_crypto(struct ufs_hba *hba, struct platform_device *pdev = to_platform_device(hba->dev); void __iomem *mmio_base; struct resource *mem_res; + void __iomem *hwkm_ice_mmio = NULL; + struct resource *hwkm_ice_memres = NULL; mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ufs_ice"); @@ -276,6 +278,24 @@ int ufshcd_crypto_qti_init_crypto(struct ufs_hba *hba, return PTR_ERR(mmio_base); } + hwkm_ice_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ufs_ice_hwkm"); + + if (!hwkm_ice_memres) { + pr_err("%s: Either no entry in dtsi or no memory available for IORESOURCE\n", + __func__); + } else { + hwkm_ice_mmio = devm_ioremap_resource(hba->dev, + hwkm_ice_memres); + + if (IS_ERR(hwkm_ice_mmio)) { + err = PTR_ERR(hwkm_ice_mmio); + pr_err("%s: Error = %d mapping HWKM memory\n", + __func__, err); + return err; + } + } + err = ufshcd_hba_init_crypto_qti_spec(hba, &ufshcd_crypto_qti_ksm_ops); if (err) { pr_err("%s: Error initiating crypto capabilities, err %d\n", @@ -283,8 +303,8 @@ int ufshcd_crypto_qti_init_crypto(struct ufs_hba *hba, return err; } - err = crypto_qti_init_crypto(hba->dev, - mmio_base, (void **)&hba->crypto_vops->priv); + err = crypto_qti_init_crypto(hba->dev, mmio_base, hwkm_ice_mmio, + (void **)&hba->crypto_vops->priv); if (err) { pr_err("%s: Error initiating crypto, err %d\n", __func__, err); diff --git a/drivers/soc/qcom/crypto-qti-common.c b/drivers/soc/qcom/crypto-qti-common.c index ee4cb2dda82a..b958c9be8f7e 100644 --- a/drivers/soc/qcom/crypto-qti-common.c +++ b/drivers/soc/qcom/crypto-qti-common.c @@ -58,7 +58,7 @@ static int ice_check_version(struct crypto_vops_qti_entry *ice_entry) } int crypto_qti_init_crypto(struct device *dev, void __iomem *mmio_base, - void **priv_data) + void __iomem *hwkm_slave_mmio_base, void **priv_data) { int err = 0; struct crypto_vops_qti_entry *ice_entry; @@ -70,6 +70,7 @@ int crypto_qti_init_crypto(struct device *dev, void __iomem *mmio_base, return -ENOMEM; ice_entry->icemmio_base = mmio_base; + ice_entry->hwkm_slave_mmio_base = hwkm_slave_mmio_base; ice_entry->flags = 0; err = ice_check_version(ice_entry); diff --git a/drivers/soc/qcom/crypto-qti-hwkm.c b/drivers/soc/qcom/crypto-qti-hwkm.c index 92e33ee31c2f..143e203d1585 100644 --- a/drivers/soc/qcom/crypto-qti-hwkm.c +++ b/drivers/soc/qcom/crypto-qti-hwkm.c @@ -90,7 +90,7 @@ int crypto_qti_program_key(struct crypto_vops_qti_entry *ice_entry, } if ((ice_entry->flags & QTI_HWKM_INIT_DONE) != QTI_HWKM_INIT_DONE) { - err_program = qti_hwkm_init(); + err_program = qti_hwkm_init(ice_entry->hwkm_slave_mmio_base); if (err_program) { pr_err("%s: Error with HWKM init %d\n", __func__, err_program); @@ -267,7 +267,7 @@ int crypto_qti_derive_raw_secret_platform( } if ((ice_entry->flags & QTI_HWKM_INIT_DONE) != QTI_HWKM_INIT_DONE) { - err_program = qti_hwkm_init(); + err_program = qti_hwkm_init(ice_entry->hwkm_slave_mmio_base); if (err_program) { pr_err("%s: Error with HWKM init %d\n", __func__, err_program); diff --git a/drivers/soc/qcom/hwkm.c b/drivers/soc/qcom/hwkm.c index d763292fbd6b..0e001523dbd1 100644 --- a/drivers/soc/qcom/hwkm.c +++ b/drivers/soc/qcom/hwkm.c @@ -1021,17 +1021,15 @@ static int qti_hwkm_get_device_tree_data(struct platform_device *pdev, hwkm_dev->km_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "km_master"); - hwkm_dev->ice_res = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "ice_slave"); - if (!hwkm_dev->km_res || !hwkm_dev->ice_res) { + + if (!hwkm_dev->km_res) { pr_err("%s: No memory available for IORESOURCE\n", __func__); return -ENOMEM; } hwkm_dev->km_base = devm_ioremap_resource(dev, hwkm_dev->km_res); - hwkm_dev->ice_base = devm_ioremap_resource(dev, hwkm_dev->ice_res); - if (IS_ERR(hwkm_dev->km_base) || IS_ERR(hwkm_dev->ice_base)) { + if (IS_ERR(hwkm_dev->km_base)) { ret = PTR_ERR(hwkm_dev->km_base); pr_err("%s: Error = %d mapping HWKM memory\n", __func__, ret); goto out; @@ -1213,10 +1211,16 @@ static int qti_hwkm_set_tpkey(void) return 0; } -int qti_hwkm_init(void) +int qti_hwkm_init(void __iomem *hwkm_slave_mmio_base) { int ret = 0; + if (!hwkm_slave_mmio_base) { + pr_err("%s: HWKM ICE slave mmio invalid\n", __func__); + return -EINVAL; + } + km_device->ice_base = hwkm_slave_mmio_base; + ret = qti_hwkm_ice_init_sequence(km_device); if (ret) { pr_err("%s: Error in ICE init sequence %d\n", __func__, ret); diff --git a/include/linux/crypto-qti-common.h b/include/linux/crypto-qti-common.h index 56ea368a50fa..62cc3b196083 100644 --- a/include/linux/crypto-qti-common.h +++ b/include/linux/crypto-qti-common.h @@ -18,6 +18,7 @@ struct crypto_vops_qti_entry { void __iomem *icemmio_base; + void __iomem *hwkm_slave_mmio_base; uint32_t ice_hw_version; uint8_t ice_dev_type[QTI_ICE_TYPE_NAME_LEN]; uint32_t flags; @@ -25,7 +26,7 @@ struct crypto_vops_qti_entry { #if IS_ENABLED(CONFIG_QTI_CRYPTO_COMMON) int crypto_qti_init_crypto(struct device *dev, void __iomem *mmio_base, - void **priv_data); + void __iomem *hwkm_slave_mmio_base, void **priv_data); int crypto_qti_enable(void *priv_data); void crypto_qti_disable(void *priv_data); int crypto_qti_resume(void *priv_data); @@ -43,6 +44,7 @@ int crypto_qti_derive_raw_secret(void *priv_data, #else static inline int crypto_qti_init_crypto(struct device *dev, void __iomem *mmio_base, + void __iomem *hwkm_slave_mmio_base, void **priv_data) { return -EOPNOTSUPP; diff --git a/include/linux/hwkm.h b/include/linux/hwkm.h index 3b2ee303eefc..7a956c5e24b5 100644 --- a/include/linux/hwkm.h +++ b/include/linux/hwkm.h @@ -288,7 +288,8 @@ enum hwkm_master_key_slots { #if IS_ENABLED(CONFIG_QTI_HW_KEY_MANAGER) int qti_hwkm_handle_cmd(struct hwkm_cmd *cmd, struct hwkm_rsp *rsp); int qti_hwkm_clocks(bool on); -int qti_hwkm_init(void); +int qti_hwkm_init(void __iomem *hwkm_slave_mmio_base); + #else static inline int qti_hwkm_add_req(struct hwkm_cmd *cmd, struct hwkm_rsp *rsp) @@ -299,7 +300,7 @@ static inline int qti_hwkm_clocks(bool on) { return -EOPNOTSUPP; } -static inline int qti_hwkm_init(void) +static inline int qti_hwkm_init(void __iomem *hwkm_slave_mmio_base) { return -EOPNOTSUPP; }