On 27/08/2026 18:07, Linlin Zhang wrote: > From: linlzhan <[email protected]> > > In a Qualcomm GVM environment the ICE hardware is controlled by the
What is GVM? > host, GVM has no direct access to it. So, key operation in GVM is > done through SCM calls rather than direct register access. In this > way the access to ICE registers are offloaded to Trust Zone. > > Add QCOM_CRYPTO_VIRT, which implements struct virtblk_crypto_variant_ops > for the virtio_blk_crypto_ext dispatch layer. It maps keyslot > program/evict to qcom_scm_ice_set_key() and > qcom_scm_ice_invalidate_key(), and software-secret derivation to > qcom_scm_derive_sw_secret(). > > Signed-off-by: linlzhan <[email protected]> > --- > drivers/soc/qcom/Kconfig | 12 +++++ > drivers/soc/qcom/Makefile | 1 + > drivers/soc/qcom/crypto_virt.c | 89 ++++++++++++++++++++++++++++++++++ > 3 files changed, 102 insertions(+) > create mode 100644 drivers/soc/qcom/crypto_virt.c > > diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig > index 2b524154d9fb..6c632d114d45 100644 > --- a/drivers/soc/qcom/Kconfig > +++ b/drivers/soc/qcom/Kconfig > @@ -298,6 +298,18 @@ config QCOM_INLINE_CRYPTO_ENGINE > tristate > select QCOM_SCM > > +config QCOM_CRYPTO_VIRT > + tristate "Qualcomm Technologies, Inc. Crypto Virt driver" > + depends on VIRTBLK_CRYPTO_VIRTUALIZATION > + depends on QCOM_SCM > + default VIRTBLK_CRYPTO_VIRTUALIZATION if ARCH_QCOM > + help > + GVM-side hardware-wrapped-key SCM operations exposed to > + virtio_blk's inline crypto layer: per-slot key programming and > + eviction, and key derive/generate/prepare/import. > + Say Y here to compile the driver as a part of kernel or M to compile > + as a module. > + > config QCOM_KRYO_L2_ACCESSORS > bool > depends on ARM64 > diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile > index 798643be3590..6d4b7546d1fb 100644 > --- a/drivers/soc/qcom/Makefile > +++ b/drivers/soc/qcom/Makefile > @@ -39,5 +39,6 @@ obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) += > kryo-l2-accessors.o > obj-$(CONFIG_QCOM_ICC_BWMON) += icc-bwmon.o > qcom_ice-objs += ice.o > obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE) += qcom_ice.o > +obj-$(CONFIG_QCOM_CRYPTO_VIRT) += crypto_virt.o > obj-$(CONFIG_QCOM_PBS) += qcom-pbs.o > obj-$(CONFIG_QCOM_UBWC_CONFIG) += ubwc_config.o > diff --git a/drivers/soc/qcom/crypto_virt.c b/drivers/soc/qcom/crypto_virt.c > new file mode 100644 > index 000000000000..4ee2a36af6c1 > --- /dev/null > +++ b/drivers/soc/qcom/crypto_virt.c > @@ -0,0 +1,89 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + > +#include <linux/module.h> > +#include <linux/types.h> > +#include <linux/blk-crypto.h> > +#include <linux/virtio_blk_crypto_ext.h> > +#include <linux/firmware/qcom/qcom_scm.h> > + > +static int crypto_virt_program_key(const struct blk_crypto_key *key, > + unsigned int slot) > +{ > + u32 dus_512_units; > + int ret; > + > + if (!key || !key->size) { > + pr_err("%s: invalid key\n", __func__); > + return -EINVAL; > + } > + > + /* Only AES-256-XTS has been tested so far. */ > + if (key->crypto_cfg.crypto_mode != > + BLK_ENCRYPTION_MODE_AES_256_XTS) { > + pr_err_ratelimited("Unsupported crypto mode: %d\n", > + key->crypto_cfg.crypto_mode); > + return -EINVAL; > + } > + > + /* qcom_scm_ice_set_key()'s data_unit_size is expressed in 512-byte > units */ > + dus_512_units = key->crypto_cfg.data_unit_size / 512; > + > + ret = qcom_scm_ice_set_key(slot, key->bytes, key->size, > + QCOM_SCM_ICE_CIPHER_AES_256_XTS, dus_512_units); > + if (ret) > + pr_err("%s: slot=%u ret=%d\n", __func__, slot, ret); > + > + return ret; > +} > + > +static int crypto_virt_invalidate_key(unsigned int slot) > +{ > + int ret; > + > + ret = qcom_scm_ice_invalidate_key(slot); > + if (ret) > + pr_err("%s: slot=%u ret=%d\n", __func__, slot, ret); > + > + return ret; > +} > + > +static int crypto_virt_derive_sw_secret_key(const u8 *eph_key, size_t > eph_key_size, > + u8 > sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) > +{ > + int ret; > + > + ret = qcom_scm_derive_sw_secret(eph_key, eph_key_size, > + sw_secret, BLK_CRYPTO_SW_SECRET_SIZE); > + if (ret == -EIO || ret == -EINVAL) > + ret = -EBADMSG; /* probably invalid key */ > + > + if (ret) > + pr_err("%s: ret=%d\n", __func__, ret); > + > + return ret; > +} > + > +static struct virtblk_crypto_variant_ops virtblk_crypto_qcom_vops = { Why is a crypto-handling code in drivers/soc/? > + .owner = THIS_MODULE, > + .program_key = crypto_virt_program_key, > + .evict_key = crypto_virt_invalidate_key, > + .derive_sw_secret_key = crypto_virt_derive_sw_secret_key, > +}; > + > +static int __init crypto_virt_init(void) > +{ > + virtblk_set_crypto_ops(&virtblk_crypto_qcom_vops); > + return 0; > +} > +module_init(crypto_virt_init); > + > +#if IS_MODULE(CONFIG_QCOM_CRYPTO_VIRT) > +static void __exit crypto_virt_exit(void) > +{ > + virtblk_set_crypto_ops(NULL); > +} > +module_exit(crypto_virt_exit); > +#endif How do you instantiate this driver exactly? Best regards, Krzysztof

