提交 93f1c150 编写于 作者: E Eric Biggers 提交者: Ulf Hansson

mmc: core: Add basic support for inline encryption

In preparation for adding CQHCI crypto engine (inline encryption)
support, add the code required to make mmc_core and mmc_block aware of
inline encryption.  Specifically:

- Add a capability flag MMC_CAP2_CRYPTO to struct mmc_host.  Drivers
  will set this if the host and driver support inline encryption.

- Embed a blk_keyslot_manager in struct mmc_host.  Drivers will
  initialize this (as a device-managed resource) if the host and driver
  support inline encryption.  mmc_block registers this keyslot manager
  with the request_queue of any MMC card attached to the host.

- Make mmc_block copy the crypto keyslot and crypto data unit number
  from struct request to struct mmc_request, so that drivers will have
  access to them.

- If the MMC host is reset, reprogram all the keyslots to ensure that
  the software state stays in sync with the hardware state.
Co-developed-by: NSatya Tangirala <satyat@google.com>
Signed-off-by: NSatya Tangirala <satyat@google.com>
Acked-by: NAdrian Hunter <adrian.hunter@intel.com>
Reviewed-by: NSatya Tangirala <satyat@google.com>
Reviewed-and-tested-by: NPeng Zhou <peng.zhou@mediatek.com>
Signed-off-by: NEric Biggers <ebiggers@google.com>
Link: https://lore.kernel.org/r/20210126001456.382989-2-ebiggers@kernel.orgSigned-off-by: NUlf Hansson <ulf.hansson@linaro.org>
上级 d76d9d7d
...@@ -81,3 +81,11 @@ config MMC_TEST ...@@ -81,3 +81,11 @@ config MMC_TEST
This driver is only of interest to those developing or This driver is only of interest to those developing or
testing a host driver. Most people should say N here. testing a host driver. Most people should say N here.
config MMC_CRYPTO
bool "MMC Crypto Engine Support"
depends on BLK_INLINE_ENCRYPTION
help
Enable Crypto Engine Support in MMC.
Enabling this makes it possible for the kernel to use the crypto
capabilities of the MMC device (if present) to perform crypto
operations on data being transferred to/from the device.
...@@ -18,3 +18,4 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o ...@@ -18,3 +18,4 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
mmc_block-objs := block.o queue.o mmc_block-objs := block.o queue.o
obj-$(CONFIG_MMC_TEST) += mmc_test.o obj-$(CONFIG_MMC_TEST) += mmc_test.o
obj-$(CONFIG_SDIO_UART) += sdio_uart.o obj-$(CONFIG_SDIO_UART) += sdio_uart.o
mmc_core-$(CONFIG_MMC_CRYPTO) += crypto.o
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "block.h" #include "block.h"
#include "core.h" #include "core.h"
#include "card.h" #include "card.h"
#include "crypto.h"
#include "host.h" #include "host.h"
#include "bus.h" #include "bus.h"
#include "mmc_ops.h" #include "mmc_ops.h"
...@@ -1247,6 +1248,8 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, ...@@ -1247,6 +1248,8 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
memset(brq, 0, sizeof(struct mmc_blk_request)); memset(brq, 0, sizeof(struct mmc_blk_request));
mmc_crypto_prepare_req(mqrq);
brq->mrq.data = &brq->data; brq->mrq.data = &brq->data;
brq->mrq.tag = req->tag; brq->mrq.tag = req->tag;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "core.h" #include "core.h"
#include "card.h" #include "card.h"
#include "crypto.h"
#include "bus.h" #include "bus.h"
#include "host.h" #include "host.h"
#include "sdio_bus.h" #include "sdio_bus.h"
...@@ -992,6 +993,8 @@ void mmc_set_initial_state(struct mmc_host *host) ...@@ -992,6 +993,8 @@ void mmc_set_initial_state(struct mmc_host *host)
host->ops->hs400_enhanced_strobe(host, &host->ios); host->ops->hs400_enhanced_strobe(host, &host->ios);
mmc_set_ios(host); mmc_set_ios(host);
mmc_crypto_set_initial_state(host);
} }
/** /**
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* MMC crypto engine (inline encryption) support
*
* Copyright 2020 Google LLC
*/
#include <linux/blk-crypto.h>
#include <linux/mmc/host.h>
#include "core.h"
#include "crypto.h"
#include "queue.h"
void mmc_crypto_set_initial_state(struct mmc_host *host)
{
/* Reset might clear all keys, so reprogram all the keys. */
if (host->caps2 & MMC_CAP2_CRYPTO)
blk_ksm_reprogram_all_keys(&host->ksm);
}
void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host)
{
if (host->caps2 & MMC_CAP2_CRYPTO)
blk_ksm_register(&host->ksm, q);
}
EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue);
void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq)
{
struct request *req = mmc_queue_req_to_req(mqrq);
struct mmc_request *mrq = &mqrq->brq.mrq;
if (!req->crypt_keyslot)
return;
mrq->crypto_enabled = true;
mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot);
/*
* For now we assume that all MMC drivers set max_dun_bytes_supported=4,
* which is the limit for CQHCI crypto. So all DUNs should be 32-bit.
*/
WARN_ON_ONCE(req->crypt_ctx->bc_dun[0] > U32_MAX);
mrq->data_unit_num = req->crypt_ctx->bc_dun[0];
}
EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req);
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* MMC crypto engine (inline encryption) support
*
* Copyright 2020 Google LLC
*/
#ifndef _MMC_CORE_CRYPTO_H
#define _MMC_CORE_CRYPTO_H
struct mmc_host;
struct mmc_queue_req;
struct request_queue;
#ifdef CONFIG_MMC_CRYPTO
void mmc_crypto_set_initial_state(struct mmc_host *host);
void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host);
void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq);
#else /* CONFIG_MMC_CRYPTO */
static inline void mmc_crypto_set_initial_state(struct mmc_host *host)
{
}
static inline void mmc_crypto_setup_queue(struct request_queue *q,
struct mmc_host *host)
{
}
static inline void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq)
{
}
#endif /* !CONFIG_MMC_CRYPTO */
#endif /* _MMC_CORE_CRYPTO_H */
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/mmc/slot-gpio.h> #include <linux/mmc/slot-gpio.h>
#include "core.h" #include "core.h"
#include "crypto.h"
#include "host.h" #include "host.h"
#include "slot-gpio.h" #include "slot-gpio.h"
#include "pwrseq.h" #include "pwrseq.h"
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "block.h" #include "block.h"
#include "core.h" #include "core.h"
#include "card.h" #include "card.h"
#include "crypto.h"
#include "host.h" #include "host.h"
#define MMC_DMA_MAP_MERGE_SEGMENTS 512 #define MMC_DMA_MAP_MERGE_SEGMENTS 512
...@@ -407,6 +408,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) ...@@ -407,6 +408,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
mutex_init(&mq->complete_lock); mutex_init(&mq->complete_lock);
init_waitqueue_head(&mq->wait); init_waitqueue_head(&mq->wait);
mmc_crypto_setup_queue(mq->queue, host);
} }
static inline bool mmc_merge_capable(struct mmc_host *host) static inline bool mmc_merge_capable(struct mmc_host *host)
......
...@@ -162,6 +162,12 @@ struct mmc_request { ...@@ -162,6 +162,12 @@ struct mmc_request {
bool cap_cmd_during_tfr; bool cap_cmd_during_tfr;
int tag; int tag;
#ifdef CONFIG_MMC_CRYPTO
bool crypto_enabled;
int crypto_key_slot;
u32 data_unit_num;
#endif
}; };
struct mmc_card; struct mmc_card;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/pm.h> #include <linux/mmc/pm.h>
#include <linux/dma-direction.h> #include <linux/dma-direction.h>
#include <linux/keyslot-manager.h>
struct mmc_ios { struct mmc_ios {
unsigned int clock; /* clock rate */ unsigned int clock; /* clock rate */
...@@ -395,6 +396,11 @@ struct mmc_host { ...@@ -395,6 +396,11 @@ struct mmc_host {
#define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */
#define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */ #define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */
#define MMC_CAP2_MERGE_CAPABLE (1 << 26) /* Host can merge a segment over the segment size */ #define MMC_CAP2_MERGE_CAPABLE (1 << 26) /* Host can merge a segment over the segment size */
#ifdef CONFIG_MMC_CRYPTO
#define MMC_CAP2_CRYPTO (1 << 27) /* Host supports inline encryption */
#else
#define MMC_CAP2_CRYPTO 0
#endif
int fixed_drv_type; /* fixed driver type for non-removable media */ int fixed_drv_type; /* fixed driver type for non-removable media */
...@@ -489,6 +495,11 @@ struct mmc_host { ...@@ -489,6 +495,11 @@ struct mmc_host {
bool cqe_enabled; bool cqe_enabled;
bool cqe_on; bool cqe_on;
/* Inline encryption support */
#ifdef CONFIG_MMC_CRYPTO
struct blk_keyslot_manager ksm;
#endif
/* Host Software Queue support */ /* Host Software Queue support */
bool hsq_enabled; bool hsq_enabled;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册