1 Star 0 Fork 38

xisme/qemu-kvm_src-anolis

forked from src-anolis-os/qemu-kvm 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
1067-anolis-vfio-only-map-shared-region-for-CSV-virtual-m.patch 11.32 KB
一键复制 编辑 原始数据 按行查看 历史
jiangxin00 提交于 2023-12-08 17:29 +08:00 . Support Hygon CSV3 live migration
From 3b532188e4eac7fd291cf66970126a18af024364 Mon Sep 17 00:00:00 2001
From: liuyafei <liuyafei@hygon.cn>
Date: Mon, 22 May 2023 20:37:40 +0800
Subject: [PATCH 1067/1072] anolis: vfio: only map shared region for CSV
virtual machine
qemu vfio listener map/unmap all of the virtual machine's memory.
It does not work for CSV virtual machine, as only shared memory
should be accessed by device.
Change-Id: I3f281c28166a36f2bed8ea193523715af9ff3271
---
hw/vfio/common.c | 40 +++++++++-
include/exec/memory.h | 11 +++
softmmu/memory.c | 18 +++++
target/i386/csv-sysemu-stub.c | 10 +++
target/i386/csv.c | 134 ++++++++++++++++++++++++++++++++++
target/i386/csv.h | 12 +++
target/i386/kvm/kvm.c | 2 +
7 files changed, 225 insertions(+), 2 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 080046e3f5..7cc03a7ef9 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -41,6 +41,9 @@
#include "qapi/error.h"
#include "migration/migration.h"
+#include "target/i386/sev.h"
+#include "target/i386/csv.h"
+
VFIOGroupList vfio_group_list =
QLIST_HEAD_INITIALIZER(vfio_group_list);
static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
@@ -1251,6 +1254,30 @@ static void vfio_listener_log_global_stop(MemoryListener *listener)
vfio_set_dirty_page_tracking(container, false);
}
+static SharedRegionListener *g_shl;
+static void shared_memory_listener_register(MemoryListener *listener, AddressSpace *as)
+{
+ SharedRegionListener *shl;
+
+ shl = g_new0(SharedRegionListener, 1);
+
+ shl->listener = listener;
+ shl->as = as;
+
+ shared_region_register_listener(shl);
+ g_shl = shl;
+}
+
+static void shared_memory_listener_unregister(void)
+{
+ SharedRegionListener *shl = g_shl;
+
+ shared_region_unregister_listener(shl);
+
+ g_free(shl);
+ g_shl = NULL;
+}
+
static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
uint64_t size, ram_addr_t ram_addr)
{
@@ -1453,7 +1480,12 @@ static const MemoryListener vfio_memory_listener = {
static void vfio_listener_release(VFIOContainer *container)
{
- memory_listener_unregister(&container->listener);
+ if (csv_enabled()) {
+ shared_memory_listener_unregister();
+ } else {
+ memory_listener_unregister(&container->listener);
+ }
+
if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {
memory_listener_unregister(&container->prereg_listener);
}
@@ -2183,7 +2215,11 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
container->listener = vfio_memory_listener;
- memory_listener_register(&container->listener, container->space->as);
+ if (csv_enabled()) {
+ shared_memory_listener_register(&container->listener, container->space->as);
+ } else {
+ memory_listener_register(&container->listener, container->space->as);
+ }
if (container->error) {
ret = -1;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 20f1b27377..d4bd90dfcc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -710,6 +710,17 @@ void ram_discard_manager_register_listener(RamDiscardManager *rdm,
void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
RamDiscardListener *rdl);
+typedef struct SharedRegionListener SharedRegionListener;
+struct SharedRegionListener {
+ MemoryListener *listener;
+ AddressSpace *as;
+ QTAILQ_ENTRY(SharedRegionListener) next;
+};
+
+void shared_region_register_listener(SharedRegionListener *shl);
+void shared_region_unregister_listener(SharedRegionListener *shl);
+void *shared_region_listeners_get(void);
+
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7340e19ff5..b435bb4aa3 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -47,6 +47,9 @@ static QTAILQ_HEAD(, MemoryListener) memory_listeners
static QTAILQ_HEAD(, AddressSpace) address_spaces
= QTAILQ_HEAD_INITIALIZER(address_spaces);
+static QTAILQ_HEAD(, SharedRegionListener) shared_region_listeners
+ = QTAILQ_HEAD_INITIALIZER(shared_region_listeners);
+
static GHashTable *flat_views;
typedef struct AddrRange AddrRange;
@@ -2111,6 +2114,21 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
rdmc->unregister_listener(rdm, rdl);
}
+void shared_region_register_listener(SharedRegionListener *shl)
+{
+ QTAILQ_INSERT_TAIL(&shared_region_listeners, shl, next);
+}
+
+void shared_region_unregister_listener(SharedRegionListener *shl)
+{
+ QTAILQ_REMOVE(&shared_region_listeners, shl, next);
+}
+
+void *shared_region_listeners_get(void)
+{
+ return &shared_region_listeners;
+}
+
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
{
uint8_t mask = 1 << client;
diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c
index a5ce986e3c..96ca055270 100644
--- a/target/i386/csv-sysemu-stub.c
+++ b/target/i386/csv-sysemu-stub.c
@@ -29,3 +29,13 @@ int csv_launch_encrypt_vmcb(void)
{
g_assert_not_reached();
}
+
+int csv_shared_region_dma_map(uint64_t start, uint64_t end)
+{
+ return 0;
+}
+
+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end)
+{
+
+}
diff --git a/target/i386/csv.c b/target/i386/csv.c
index 161cad39ae..6d05382fb2 100644
--- a/target/i386/csv.c
+++ b/target/i386/csv.c
@@ -24,6 +24,7 @@
#include "cpu.h"
#include "sev.h"
#include "csv.h"
+#include "exec/address-spaces.h"
CsvGuestState csv_guest = { 0 };
@@ -63,6 +64,8 @@ csv_init(uint32_t policy, int fd, void *state, struct sev_ops *ops)
csv_guest.state = state;
csv_guest.sev_ioctl = ops->sev_ioctl;
csv_guest.fw_error_to_str = ops->fw_error_to_str;
+ QTAILQ_INIT(&csv_guest.dma_map_regions_list);
+ qemu_mutex_init(&csv_guest.dma_map_regions_list_mutex);
}
return 0;
}
@@ -163,3 +166,134 @@ csv_launch_encrypt_vmcb(void)
err:
return ret;
}
+
+int csv_shared_region_dma_map(uint64_t start, uint64_t end)
+{
+ MemoryRegionSection section;
+ AddressSpace *as;
+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners;
+ SharedRegionListener *shl;
+ MemoryListener *listener;
+ uint64_t size;
+ CsvGuestState *s = &csv_guest;
+ struct dma_map_region *region, *pos;
+ int ret = 0;
+
+ if (!csv_enabled())
+ return 0;
+
+ if (end <= start)
+ return 0;
+
+ shared_region_listeners = shared_region_listeners_get();
+ if (QTAILQ_EMPTY(shared_region_listeners))
+ return 0;
+
+ size = end - start;
+
+ qemu_mutex_lock(&s->dma_map_regions_list_mutex);
+ QTAILQ_FOREACH(pos, &s->dma_map_regions_list, list) {
+ if (start >= (pos->start + pos->size)) {
+ continue;
+ } else if ((start + size) <= pos->start) {
+ break;
+ } else {
+ goto end;
+ }
+ }
+ QTAILQ_FOREACH(shl, shared_region_listeners, next) {
+ listener = shl->listener;
+ as = shl->as;
+ section = memory_region_find(as->root, start, size);
+ if (!section.mr) {
+ goto end;
+ }
+
+ if (!memory_region_is_ram(section.mr)) {
+ memory_region_unref(section.mr);
+ goto end;
+ }
+
+ if (listener->region_add) {
+ listener->region_add(listener, &section);
+ }
+ memory_region_unref(section.mr);
+ }
+
+ region = g_malloc0(sizeof(*region));
+ if (!region) {
+ ret = -1;
+ goto end;
+ }
+ region->start = start;
+ region->size = size;
+
+ if (pos) {
+ QTAILQ_INSERT_BEFORE(pos, region, list);
+ } else {
+ QTAILQ_INSERT_TAIL(&s->dma_map_regions_list, region, list);
+ }
+
+end:
+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex);
+ return ret;
+}
+
+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end)
+{
+ MemoryRegionSection section;
+ AddressSpace *as;
+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners;
+ SharedRegionListener *shl;
+ MemoryListener *listener;
+ uint64_t size;
+ CsvGuestState *s = &csv_guest;
+ struct dma_map_region *pos, *next_pos;
+
+ if (!csv_enabled())
+ return;
+
+ if (end <= start)
+ return;
+
+ shared_region_listeners = shared_region_listeners_get();
+ if (QTAILQ_EMPTY(shared_region_listeners))
+ return;
+
+ size = end - start;
+
+ qemu_mutex_lock(&s->dma_map_regions_list_mutex);
+ QTAILQ_FOREACH_SAFE(pos, &s->dma_map_regions_list, list, next_pos) {
+ uint64_t l, r;
+ uint64_t curr_end = pos->start + pos->size;
+
+ l = MAX(start, pos->start);
+ r = MIN(start + size, pos->start + pos->size);
+ if (l < r) {
+ if ((start <= pos->start) && (start + size >= pos->start + pos->size)) {
+ QTAILQ_FOREACH(shl, shared_region_listeners, next) {
+ listener = shl->listener;
+ as = shl->as;
+ section = memory_region_find(as->root, pos->start, pos->size);
+ if (!section.mr) {
+ goto end;
+ }
+ if (listener->region_del) {
+ listener->region_del(listener, &section);
+ }
+ memory_region_unref(section.mr);
+ }
+
+ QTAILQ_REMOVE(&s->dma_map_regions_list, pos, list);
+ g_free(pos);
+ }
+ break;
+ }
+ if ((start + size) <= curr_end) {
+ break;
+ }
+ }
+end:
+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex);
+ return;
+}
diff --git a/target/i386/csv.h b/target/i386/csv.h
index e51cc83022..6412c0c70b 100644
--- a/target/i386/csv.h
+++ b/target/i386/csv.h
@@ -15,6 +15,8 @@
#define QEMU_CSV_H
#include "qapi/qapi-commands-misc-target.h"
+#include "qemu/thread.h"
+#include "qemu/queue.h"
#ifdef CONFIG_SEV
@@ -55,12 +57,19 @@ bool csv_enabled(void);
#define csv_enabled() 0
#endif
+struct dma_map_region {
+ uint64_t start, size;
+ QTAILQ_ENTRY(dma_map_region) list;
+};
+
struct CsvGuestState {
uint32_t policy;
int sev_fd;
void *state;
int (*sev_ioctl)(int fd, int cmd, void *data, int *error);
const char *(*fw_error_to_str)(int code);
+ QTAILQ_HEAD(, dma_map_region) dma_map_regions_list;
+ QemuMutex dma_map_regions_list_mutex;
};
typedef struct CsvGuestState CsvGuestState;
@@ -71,4 +80,7 @@ extern int csv_launch_encrypt_vmcb(void);
int csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp);
+int csv_shared_region_dma_map(uint64_t start, uint64_t end);
+void csv_shared_region_dma_unmap(uint64_t start, uint64_t end);
+
#endif
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 6192bcd36e..090800257f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -4626,8 +4626,10 @@ static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run)
if (enc) {
sev_remove_shared_regions_list(gfn_start, gfn_end);
+ csv_shared_region_dma_unmap(gpa, gfn_end << TARGET_PAGE_BITS);
} else {
sev_add_shared_regions_list(gfn_start, gfn_end);
+ csv_shared_region_dma_map(gpa, gfn_end << TARGET_PAGE_BITS);
}
}
return 0;
--
2.17.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xisme/qemu-kvm_src-anolis.git
git@gitee.com:xisme/qemu-kvm_src-anolis.git
xisme
qemu-kvm_src-anolis
qemu-kvm_src-anolis
vtkm_support_csv

搜索帮助

371d5123 14472233 46e8bd33 14472233