- hw/arm/virt:Keep Guest L1 cache type consistent with KVM - cvm : Add support for TEE-based national encryption acceleration. - Add virtCCA Coda annotation Adjust the position of the security device - target/i386: sev: Add support for reuse ASID for different CSV guests - target/i386: sev: Fix incompatibility between SEV and CSV on the GET_ID API - hw/cxl: Ensure there is enough data for the header in cmd_ccls_set_lsa() - hw/pci: Add parenthesis to PCI_BUILD_BDF macro - hw/audio/hda: free timer on exit - meson.build: Remove ncurses workaround for OpenBSD - ui/console-vc: Silence warning about sprintf() on OpenBSD - ui: remove break after g_assert_not_reached() - s390x/sclp: Simplify get_sclp_device() - hw/vfio/hct: qemu startup terminate once error happened in hct - hw/vfio/hct: fix ccp_index error caused by uninitialized buf - hw/vfio/hct: update support ccp count to 48. - hw/vfio: add device hct based on vfio. Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit 702a9cc4e262a50f7aa6f7c9549fbc13d4cd0770)
295 lines
9.4 KiB
Diff
295 lines
9.4 KiB
Diff
From dffc0f55d93ececee55a8548d7dab227ee76b234 Mon Sep 17 00:00:00 2001
|
|
From: liupingwei <liupingwei0317@outlook.com>
|
|
Date: Thu, 24 Oct 2024 19:05:58 +0800
|
|
Subject: [PATCH] cvm : Add support for TEE-based national encryption
|
|
acceleration.
|
|
|
|
This commit enables the use of TEE for national encryption acceleration
|
|
in cvm and speeds up OpenSSL encrption /decryption operations.
|
|
|
|
Signed-off-by: liupingwei <liupingwei0317@outlook.com>
|
|
---
|
|
hw/arm/virt.c | 61 ++++++++++++++++++++++++++++++-
|
|
include/hw/arm/virt.h | 1 +
|
|
linux-headers/asm-arm64/kvm.h | 10 ++++++
|
|
qapi/qom.json | 1 +
|
|
target/arm/kvm-tmm.c | 68 +++++++++++++++++++++++++++++++++--
|
|
target/arm/kvm_arm.h | 4 +++
|
|
6 files changed, 142 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
|
index e73a795d3d..248788db03 100644
|
|
--- a/hw/arm/virt.c
|
|
+++ b/hw/arm/virt.c
|
|
@@ -1967,6 +1967,10 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
|
|
"kvm-type", &error_abort);
|
|
|
|
if (!strcmp(kvm_type, "cvm")) {
|
|
+ /* support kae vf device tree nodes */
|
|
+ vms->memmap[VIRT_PCIE_MMIO] = (MemMapEntry) { 0x10000000, 0x2edf0000 };
|
|
+ vms->memmap[VIRT_KAE_DEVICE] = (MemMapEntry) { 0x3edf0000, 0x00200000 };
|
|
+
|
|
vms->memmap[VIRT_MEM].base = 3 * GiB;
|
|
vms->memmap[VIRT_MEM].size = ms->ram_size;
|
|
info_report("[qemu] fix VIRT_MEM range 0x%llx - 0x%llx\n", (unsigned long long)(vms->memmap[VIRT_MEM].base),
|
|
@@ -2380,6 +2384,56 @@ out:
|
|
return;
|
|
}
|
|
|
|
+static void fdt_add_hisi_sec_nodes(const VirtMachineState *vms, int dev_id)
|
|
+{
|
|
+ const MachineState *ms = MACHINE(vms);
|
|
+ hwaddr size = 0x10000;
|
|
+
|
|
+ /*
|
|
+ * Calculate the base address for the sec device node.
|
|
+ * Each device group contains one sec device and one hpre device,spaced by 2 * size.
|
|
+ */
|
|
+ hwaddr base = vms->memmap[VIRT_KAE_DEVICE].base + dev_id * 2 * size;
|
|
+ char *nodename;
|
|
+
|
|
+ tmm_set_sec_addr(base, dev_id);
|
|
+
|
|
+ nodename = g_strdup_printf("/hisi-sec@%" PRIx64, base);
|
|
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
|
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "hisilicon,hip07-sec-vf");
|
|
+ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
|
|
+ g_free(nodename);
|
|
+}
|
|
+
|
|
+static void fdt_add_hisi_hpre_nodes(const VirtMachineState *vms, int dev_id)
|
|
+{
|
|
+ const MachineState *ms = MACHINE(vms);
|
|
+ hwaddr size = 0x10000;
|
|
+
|
|
+ /*
|
|
+ * Calculate the base address for the hpre device node.
|
|
+ * Each hpre device follows the corresponding sec device by an additional offset of size.
|
|
+ */
|
|
+ hwaddr base = vms->memmap[VIRT_KAE_DEVICE].base + dev_id * 2 * size + size;
|
|
+ char *nodename;
|
|
+
|
|
+ tmm_set_hpre_addr(base, dev_id);
|
|
+
|
|
+ nodename = g_strdup_printf("/hisi-hpre@%" PRIx64, base);
|
|
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
|
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "hisilicon,hip07-hpre-vf");
|
|
+ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
|
|
+ g_free(nodename);
|
|
+}
|
|
+
|
|
+static void fdt_add_all_hisi_nodes(const VirtMachineState *vms, int dev_id)
|
|
+{
|
|
+ for (int i = 0; i < dev_id; i++) {
|
|
+ fdt_add_hisi_sec_nodes(vms, i);
|
|
+ fdt_add_hisi_hpre_nodes(vms, i);
|
|
+ }
|
|
+}
|
|
+
|
|
static void machvirt_init(MachineState *machine)
|
|
{
|
|
VirtMachineState *vms = VIRT_MACHINE(machine);
|
|
@@ -2530,14 +2584,19 @@ static void machvirt_init(MachineState *machine)
|
|
}
|
|
}
|
|
|
|
+ create_fdt(vms);
|
|
+
|
|
if (virtcca_cvm_enabled()) {
|
|
+ int kae_num = tmm_get_kae_num();
|
|
+ fdt_add_all_hisi_nodes(vms, kae_num);
|
|
+
|
|
int ret = kvm_arm_tmm_init(machine->cgs, &error_fatal);
|
|
if (ret != 0) {
|
|
error_report("fail to initialize TMM");
|
|
exit(1);
|
|
}
|
|
}
|
|
- create_fdt(vms);
|
|
+
|
|
qemu_log("cpu init start\n");
|
|
|
|
cpu_class = object_class_by_name(machine->cpu_type);
|
|
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
|
index 27f5333772..76a0d3fa5b 100644
|
|
--- a/include/hw/arm/virt.h
|
|
+++ b/include/hw/arm/virt.h
|
|
@@ -66,6 +66,7 @@ enum {
|
|
VIRT_FW_CFG,
|
|
VIRT_PCIE,
|
|
VIRT_PCIE_MMIO,
|
|
+ VIRT_KAE_DEVICE,
|
|
VIRT_PCIE_PIO,
|
|
VIRT_PCIE_ECAM,
|
|
VIRT_PLATFORM_BUS,
|
|
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
|
|
index 2b040b5d60..552fdcb18f 100644
|
|
--- a/linux-headers/asm-arm64/kvm.h
|
|
+++ b/linux-headers/asm-arm64/kvm.h
|
|
@@ -541,6 +541,9 @@ struct reg_mask_range {
|
|
#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_ARM_TMM_MAX_KAE_VF_NUM 11
|
|
|
|
struct kvm_cap_arm_tmm_config_item {
|
|
__u32 cfg;
|
|
@@ -570,6 +573,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_ARM_TMM_MAX_KAE_VF_NUM];
|
|
+ __u64 hpre_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM];
|
|
+ };
|
|
/* Fix the size of the union */
|
|
__u8 reserved[256];
|
|
};
|
|
diff --git a/qapi/qom.json b/qapi/qom.json
|
|
index 213edd8db2..293d727a04 100644
|
|
--- a/qapi/qom.json
|
|
+++ b/qapi/qom.json
|
|
@@ -921,6 +921,7 @@
|
|
{ 'struct': 'TmmGuestProperties',
|
|
'data': { '*sve-vector-length': 'uint32',
|
|
'*num-pmu-counters': 'uint32',
|
|
+ '*kae': 'uint32',
|
|
'*measurement-algo': 'TmmGuestMeasurementAlgo' } }
|
|
|
|
##
|
|
diff --git a/target/arm/kvm-tmm.c b/target/arm/kvm-tmm.c
|
|
index efe2ca0006..ea6bcc0f40 100644
|
|
--- a/target/arm/kvm-tmm.c
|
|
+++ b/target/arm/kvm-tmm.c
|
|
@@ -19,13 +19,20 @@
|
|
#include "sysemu/kvm.h"
|
|
#include "sysemu/runstate.h"
|
|
#include "hw/loader.h"
|
|
+#include "linux-headers/asm-arm64/kvm.h"
|
|
|
|
#define TYPE_TMM_GUEST "tmm-guest"
|
|
OBJECT_DECLARE_SIMPLE_TYPE(TmmGuest, TMM_GUEST)
|
|
|
|
#define TMM_PAGE_SIZE qemu_real_host_page_size()
|
|
-#define TMM_MAX_PMU_CTRS 0x20
|
|
-#define TMM_MAX_CFG 5
|
|
+#define TMM_MAX_PMU_CTRS 0x20
|
|
+#define TMM_MAX_CFG 6
|
|
+
|
|
+typedef struct {
|
|
+ uint32_t kae_vf_num;
|
|
+ hwaddr sec_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM];
|
|
+ hwaddr hpre_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM];
|
|
+} KaeDeviceInfo;
|
|
|
|
struct TmmGuest {
|
|
ConfidentialGuestSupport parent_obj;
|
|
@@ -33,6 +40,7 @@ struct TmmGuest {
|
|
TmmGuestMeasurementAlgo measurement_algo;
|
|
uint32_t sve_vl;
|
|
uint32_t num_pmu_cntrs;
|
|
+ KaeDeviceInfo kae_device_info;
|
|
};
|
|
|
|
typedef struct {
|
|
@@ -92,6 +100,17 @@ static int tmm_configure_one(TmmGuest *guest, uint32_t cfg, Error **errp)
|
|
args.num_pmu_cntrs = guest->num_pmu_cntrs;
|
|
cfg_str = "PMU";
|
|
break;
|
|
+ case KVM_CAP_ARM_TMM_CFG_KAE:
|
|
+ if (!guest->kae_device_info.kae_vf_num) {
|
|
+ return 0;
|
|
+ }
|
|
+ args.kae_vf_num= guest->kae_device_info.kae_vf_num;
|
|
+ for (int i = 0; i < guest->kae_device_info.kae_vf_num; i++) {
|
|
+ args.sec_addr[i] = guest->kae_device_info.sec_addr[i];
|
|
+ args.hpre_addr[i] = guest->kae_device_info.hpre_addr[i];
|
|
+ }
|
|
+ cfg_str = "KAE";
|
|
+ break;
|
|
default:
|
|
g_assert_not_reached();
|
|
}
|
|
@@ -289,6 +308,47 @@ static void tmm_set_measurement_algo(Object *obj, int algo, Error **errp G_GNUC_
|
|
guest->measurement_algo = algo;
|
|
}
|
|
|
|
+static void tmm_get_kae_vf_num(Object *obj, Visitor *v, const char *name,
|
|
+ void *opaque, Error **errp)
|
|
+{
|
|
+ TmmGuest *guest = TMM_GUEST(obj);
|
|
+
|
|
+ visit_type_uint32(v, name, &guest->kae_device_info.kae_vf_num, errp);
|
|
+}
|
|
+
|
|
+static void tmm_set_kae_vf_num(Object *obj, Visitor *v, const char *name,
|
|
+ void *opaque, Error **errp)
|
|
+{
|
|
+ TmmGuest *guest = TMM_GUEST(obj);
|
|
+ uint32_t value;
|
|
+
|
|
+ if (!visit_type_uint32(v, name, &value, errp)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (value > KVM_ARM_TMM_MAX_KAE_VF_NUM) {
|
|
+ error_setg(errp, "invalid number of kae vfs");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ guest->kae_device_info.kae_vf_num = value;
|
|
+}
|
|
+
|
|
+int tmm_get_kae_num(void)
|
|
+{
|
|
+ return tmm_guest->kae_device_info.kae_vf_num;
|
|
+}
|
|
+
|
|
+void tmm_set_sec_addr(hwaddr base, int num)
|
|
+{
|
|
+ tmm_guest->kae_device_info.sec_addr[num] = base;
|
|
+}
|
|
+
|
|
+void tmm_set_hpre_addr(hwaddr base, int num)
|
|
+{
|
|
+ tmm_guest->kae_device_info.hpre_addr[num] = base;
|
|
+}
|
|
+
|
|
static void tmm_guest_class_init(ObjectClass *oc, void *data)
|
|
{
|
|
object_class_property_add_enum(oc, "measurement-algo",
|
|
@@ -314,6 +374,10 @@ static void tmm_guest_class_init(ObjectClass *oc, void *data)
|
|
NULL, NULL);
|
|
object_class_property_set_description(oc, "num-pmu-counters",
|
|
"Number of PMU counters");
|
|
+ object_class_property_add(oc, "kae", "uint32", tmm_get_kae_vf_num,
|
|
+ tmm_set_kae_vf_num, NULL, NULL);
|
|
+ object_class_property_set_description(oc, "kae",
|
|
+ "Number of KAE virtual functions. 0 disables KAE (the default)");
|
|
}
|
|
|
|
static void tmm_guest_instance_init(Object *obj)
|
|
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
|
|
index d6c7139f4a..31457a57f7 100644
|
|
--- a/target/arm/kvm_arm.h
|
|
+++ b/target/arm/kvm_arm.h
|
|
@@ -390,6 +390,10 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
|
|
|
|
void tmm_add_ram_region(hwaddr base1, hwaddr len1, hwaddr base2, hwaddr len2, bool populate);
|
|
|
|
+int tmm_get_kae_num(void);
|
|
+void tmm_set_sec_addr(hwaddr base, int num);
|
|
+void tmm_set_hpre_addr(hwaddr base, int num);
|
|
+
|
|
int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp);
|
|
bool kvm_arm_tmm_enabled(void);
|
|
|
|
--
|
|
2.41.0.windows.1
|
|
|