1 Star 0 Fork 22

OpenCloudOS-fork/qemu

forked from OpenCloudOS Stream/qemu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0028-target-i386-csv-add-support-to-encrypt-the-outgoing-.patch 7.07 KB
一键复制 编辑 原始数据 按行查看 历史
From 34e24d428e60ac780386ffe581f604b3d624dd4e Mon Sep 17 00:00:00 2001
From: fangbaoshun <[email protected]>
Date: Mon, 2 Aug 2021 11:41:58 +0800
Subject: [PATCH 20/28] target/i386: csv: add support to encrypt the outgoing
pages in the list queued before.
The csv_save_queued_outgoing_pages() provide the implementation to encrypt
the guest private pages during transmission. The routines uses SEND_START
command to create the outgoing encryption context on the first call then
uses COMMAND_BATCH command to send the SEND_UPDATE_DATA commands queued
in the list to encrypt the data before writing it to the socket. While
encrypting the data SEND_UPDATE_DATA produces some metadata (e.g MAC, IV).
The metadata is also sent to the target machine. After migration is completed,
we issue the SEND_FINISH command to transition the SEV guest state from sending
to unrunnable state.
Signed-off-by: hanliyang <[email protected]>
---
include/exec/confidential-guest-support.h | 4 ++
linux-headers/linux/kvm.h | 8 +++
target/i386/csv.h | 1 +
target/i386/sev.c | 88 +++++++++++++++++++++++
target/i386/sev.h | 3 +
5 files changed, 104 insertions(+)
diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h
index 8949568ac..c84f8c1ef 100644
--- a/include/exec/confidential-guest-support.h
+++ b/include/exec/confidential-guest-support.h
@@ -80,6 +80,10 @@ struct ConfidentialGuestMemoryEncryptionOps {
/* Queue the encrypted page and metadata associated with it into a list */
int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr);
+
+ /* Write the list queued with encrypted pages and metadata associated
+ * with them */
+ int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent);
};
typedef struct ConfidentialGuestSupportClass {
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 3b94ba3c4..bd23b2cc0 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1917,6 +1917,9 @@ enum sev_cmd_id {
/* Guest Migration Extension */
KVM_SEV_SEND_CANCEL,
+ /* Hygon CSV batch command */
+ KVM_CSV_COMMAND_BATCH = 0x18,
+
KVM_SEV_NR_MAX,
};
@@ -2019,6 +2022,11 @@ struct kvm_csv_batch_list_node {
__u64 next_cmd_addr;
};
+struct kvm_csv_command_batch {
+ __u32 command_id;
+ __u64 csv_batch_list_uaddr;
+};
+
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
diff --git a/target/i386/csv.h b/target/i386/csv.h
index 4c1ef2002..2a3a3119d 100644
--- a/target/i386/csv.h
+++ b/target/i386/csv.h
@@ -54,5 +54,6 @@ struct CsvBatchCmdList {
};
int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr);
+int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent);
#endif
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 027249e44..cfbc9fb59 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -191,6 +191,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = {
.save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list,
.load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list,
.queue_outgoing_page = csv_queue_outgoing_page,
+ .save_queued_outgoing_pages = csv_save_queued_outgoing_pages,
};
static int
@@ -2011,6 +2012,69 @@ err:
return ret;
}
+static int
+csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err)
+{
+ int ret;
+ struct kvm_csv_command_batch command_batch = { };
+
+ command_batch.command_id = cmd_id;
+ command_batch.csv_batch_list_uaddr = head_uaddr;
+
+ ret = sev_ioctl(sev_guest->sev_fd, KVM_CSV_COMMAND_BATCH,
+ &command_batch, fw_err);
+ if (ret) {
+ error_report("%s: COMMAND_BATCH ret=%d fw_err=%d '%s'",
+ __func__, ret, *fw_err, fw_error_to_str(*fw_err));
+ }
+
+ return ret;
+}
+
+static int
+csv_send_update_data_batch(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent)
+{
+ int ret, fw_error = 0;
+ struct kvm_sev_send_update_data *update;
+ struct kvm_csv_batch_list_node *node;
+
+ ret = csv_command_batch(KVM_SEV_SEND_UPDATE_DATA,
+ (uint64_t)s->csv_batch_cmd_list->head, &fw_error);
+ if (ret) {
+ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'",
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
+ goto err;
+ }
+
+ for (node = s->csv_batch_cmd_list->head;
+ node != NULL;
+ node = (struct kvm_csv_batch_list_node *)node->next_cmd_addr) {
+ if (node != s->csv_batch_cmd_list->head) {
+ /* head's page header is saved before send_update_data */
+ qemu_put_be64(f, node->addr);
+ *bytes_sent += 8;
+ if (node->next_cmd_addr != 0)
+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH);
+ else
+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END);
+ *bytes_sent += 4;
+ }
+ update = (struct kvm_sev_send_update_data *)node->cmd_data_addr;
+ qemu_put_be32(f, update->hdr_len);
+ qemu_put_buffer(f, (uint8_t *)update->hdr_uaddr, update->hdr_len);
+ *bytes_sent += (4 + update->hdr_len);
+
+ qemu_put_be32(f, update->trans_len);
+ qemu_put_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len);
+ *bytes_sent += (4 + update->trans_len);
+ }
+
+err:
+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list);
+ s->csv_batch_cmd_list = NULL;
+ return ret;
+}
+
int
csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr)
{
@@ -2025,6 +2089,30 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr)
return csv_send_queue_data(s, ptr, sz, addr);
}
+int
+csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent)
+{
+ SevGuestState *s = sev_guest;
+
+ /* Only support for HYGON CSV */
+ if (!is_hygon_cpu()) {
+ error_report("Only support transfer queued pages for HYGON CSV");
+ return -EINVAL;
+ }
+
+ /*
+ * If this is a first buffer then create outgoing encryption context
+ * and write our PDH, policy and session data.
+ */
+ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) &&
+ sev_send_start(s, f, bytes_sent)) {
+ error_report("Failed to create outgoing context");
+ return 1;
+ }
+
+ return csv_send_update_data_batch(s, f, bytes_sent);
+}
+
static const QemuUUID sev_hash_table_header_guid = {
.data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
0xd4, 0x11, 0xfd, 0x21)
diff --git a/target/i386/sev.h b/target/i386/sev.h
index 84e3bdf2d..f7886116e 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -41,6 +41,9 @@ typedef struct SevKernelLoaderContext {
#define RAM_SAVE_ENCRYPTED_PAGE 0x1
#define RAM_SAVE_SHARED_REGIONS_LIST 0x2
+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4
+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5
+
#ifdef CONFIG_SEV
bool sev_enabled(void);
bool sev_es_enabled(void);
--
2.41.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/OpenCloudOS-fork/qemu.git
[email protected]:OpenCloudOS-fork/qemu.git
OpenCloudOS-fork
qemu
qemu
master

搜索帮助