From 46ff83258c97c6fcfd224bb438f524d12e744b4e Mon Sep 17 00:00:00 2001 From: liupingwei Date: Tue, 5 Nov 2024 16:15:53 +0800 Subject: [PATCH] virtcca feature : SM Cryptographic Aacceleration. virtcca inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAZTU5 -------------------------------- VirtCCA Feature: support SM Cryptographic Aacceleration in cvm. Signed-off-by: liupingwei --- --- arch/arm64/include/asm/kvm_tmi.h | 16 ++++++++++++++ arch/arm64/include/asm/kvm_tmm.h | 5 +++++ arch/arm64/kvm/tmi.c | 15 +++++++++++++ arch/arm64/kvm/virtcca_cvm.c | 36 ++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/arch/arm64/include/asm/kvm_tmi.h b/arch/arm64/include/asm/kvm_tmi.h index cab2b4cdd0f2..8ea849e0779d 100644 --- a/arch/arm64/include/asm/kvm_tmi.h +++ b/arch/arm64/include/asm/kvm_tmi.h @@ -231,6 +231,8 @@ struct tmi_tec_run { #define TMI_FNUM_TTT_MAP_RANGE U(0x26D) #define TMI_FNUM_TTT_UNMAP_RANGE U(0x26E) #define TMI_FNUM_INF_TEST U(0x270) +#define TMI_FNUM_KAE_INIT U(0x273) +#define TMI_FNUM_KAE_ENABLE U(0x274) #define TMI_FNUM_SMMU_QUEUE_CREATE U(0x277) #define TMI_FNUM_SMMU_QUEUE_WRITE U(0x278) @@ -265,6 +267,8 @@ struct tmi_tec_run { #define TMI_TMM_TTT_MAP_RANGE TMI_FID(SMC_64, TMI_FNUM_TTT_MAP_RANGE) #define TMI_TMM_TTT_UNMAP_RANGE TMI_FID(SMC_64, TMI_FNUM_TTT_UNMAP_RANGE) #define TMI_TMM_INF_TEST TMI_FID(SMC_64, TMI_FNUM_INF_TEST) +#define TMI_TMM_KAE_INIT TMI_FID(SMC_64, TMI_FNUM_KAE_INIT) +#define TMI_TMM_KAE_ENABLE TMI_FID(SMC_64, TMI_FNUM_KAE_ENABLE) #define TMI_TMM_SMMU_QUEUE_CREATE TMI_FID(SMC_64, TMI_FNUM_SMMU_QUEUE_CREATE) #define TMI_TMM_SMMU_QUEUE_WRITE TMI_FID(SMC_64, TMI_FNUM_SMMU_QUEUE_WRITE) @@ -304,6 +308,9 @@ struct tmi_tec_run { #define KVM_CAP_ARM_TMM_CFG_SVE 2 #define KVM_CAP_ARM_TMM_CFG_DBG 3 #define KVM_CAP_ARM_TMM_CFG_PMU 4 +#define KVM_CAP_ARM_TMM_CFG_KAE 5 + +#define KVM_CAP_ARM_TMM_MAX_KAE_VF_NUM 11 DECLARE_STATIC_KEY_FALSE(virtcca_cvm_is_available); @@ -335,6 +342,13 @@ struct kvm_cap_arm_tmm_config_item { struct { __u32 num_pmu_cntrs; }; + + /* cfg == KVM_CAP_ARM_TMM_CFG_KAE */ + struct { + __u32 kae_vf_num; + __u64 sec_addr[KVM_CAP_ARM_TMM_MAX_KAE_VF_NUM]; + __u64 hpre_addr[KVM_CAP_ARM_TMM_MAX_KAE_VF_NUM]; + }; /* Fix the size of the union */ __u8 reserved[256]; }; @@ -397,6 +411,8 @@ u64 tmi_smmu_device_reset(u64 params); u64 tmi_smmu_pcie_core_check(u64 smmu_base); u64 tmi_smmu_write(u64 smmu_base, u64 reg_offset, u64 val, u64 bits); u64 tmi_smmu_read(u64 smmu_base, u64 reg_offset, u64 bits); +u64 tmi_kae_init(void); +u64 tmi_kae_enable(u64 rd, u64 numa_set, u64 is_enable); u64 mmio_va_to_pa(void *addr); void kvm_cvm_vcpu_put(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/asm/kvm_tmm.h b/arch/arm64/include/asm/kvm_tmm.h index 7f865789415b..5dab4b141d2e 100644 --- a/arch/arm64/include/asm/kvm_tmm.h +++ b/arch/arm64/include/asm/kvm_tmm.h @@ -31,6 +31,8 @@ enum virtcca_cvm_state { CVM_STATE_DYING }; +#define MAX_KAE_VF_NUM 11 + /* * Many of these fields are smaller than u64 but all fields have u64 * alignment, so use u64 to ensure correct alignment. @@ -50,6 +52,9 @@ struct tmi_cvm_params { s64 ttt_level_start; u64 ttt_num_start; u8 rpv[64]; /* Bits 512 */ + u64 kae_vf_num; + u64 sec_addr[MAX_KAE_VF_NUM]; + u64 hpre_addr[MAX_KAE_VF_NUM]; }; struct cvm { diff --git a/arch/arm64/kvm/tmi.c b/arch/arm64/kvm/tmi.c index cd38be6f2fba..d06890d4f500 100644 --- a/arch/arm64/kvm/tmi.c +++ b/arch/arm64/kvm/tmi.c @@ -349,3 +349,18 @@ u64 tmi_dev_ttt_create(u64 numa_set, u64 rd, u64 map_addr, u64 level) return res.a1; } +u64 tmi_kae_init(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(TMI_TMM_KAE_INIT, &res); + return res.a1; +} + +u64 tmi_kae_enable(u64 rd, u64 numa_set, u64 is_enable) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(TMI_TMM_KAE_ENABLE, rd, numa_set, is_enable, &res); + return res.a1; +} diff --git a/arch/arm64/kvm/virtcca_cvm.c b/arch/arm64/kvm/virtcca_cvm.c index 85943f6f5161..f2a5611d34c9 100644 --- a/arch/arm64/kvm/virtcca_cvm.c +++ b/arch/arm64/kvm/virtcca_cvm.c @@ -208,6 +208,11 @@ void kvm_destroy_cvm(struct kvm *kvm) WRITE_ONCE(cvm->state, CVM_STATE_DYING); + u64 numa_set = kvm_get_first_binded_numa_set(kvm); + + if (tmi_kae_enable(cvm->rd, numa_set, 0)) + kvm_err("vf destroy failed!\n"); + if (!tmi_cvm_destroy(cvm->rd)) kvm_info("KVM has destroyed cVM: %d\n", cvm->cvm_vmid); @@ -476,6 +481,23 @@ static int config_cvm_pmu(struct kvm *kvm, struct kvm_cap_arm_tmm_config_item *c return 0; } +static int config_cvm_kae(struct kvm *kvm, struct kvm_cap_arm_tmm_config_item *cfg) +{ + struct virtcca_cvm *cvm = kvm->arch.virtcca_cvm; + struct tmi_cvm_params *params; + + params = cvm->params; + + if (cfg->kae_vf_num > KVM_CAP_ARM_TMM_MAX_KAE_VF_NUM) + return -EINVAL; + + params->kae_vf_num = cfg->kae_vf_num; + memcpy(params->sec_addr, cfg->sec_addr, cfg->kae_vf_num * sizeof(u64)); + memcpy(params->hpre_addr, cfg->sec_addr, cfg->kae_vf_num * sizeof(u64)); + + return 0; +} + static int kvm_tmm_config_cvm(struct kvm *kvm, struct kvm_enable_cap *cap) { struct virtcca_cvm *cvm = kvm->arch.virtcca_cvm; @@ -498,6 +520,10 @@ static int kvm_tmm_config_cvm(struct kvm *kvm, struct kvm_enable_cap *cap) case KVM_CAP_ARM_TMM_CFG_HASH_ALGO: r = config_cvm_hash_algo(cvm->params, &cfg); break; + case KVM_CAP_ARM_TMM_CFG_KAE: + r = config_cvm_kae(kvm, &cfg); + break; + default: r = -EINVAL; } @@ -567,6 +593,13 @@ static int kvm_activate_cvm(struct kvm *kvm) } #endif + u64 numa_set = kvm_get_first_binded_numa_set(kvm); + + if (tmi_kae_enable(cvm->rd, numa_set, 1)) { + kvm_err("tmi_kae_enable failed!\n"); + return -ENXIO; + } + if (tmi_cvm_activate(cvm->rd)) { kvm_err("tmi_cvm_activate failed!\n"); return -ENXIO; @@ -739,6 +772,9 @@ int kvm_init_tmm(void) if (tmi_check_version()) return 0; + if (tmi_kae_init()) + pr_warn("kvm [%i]: Warning: kae init failed!\n", task_pid_nr(current)); + ret = cvm_vmid_init(); if (ret) return ret; -- Gitee