diff --git a/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch b/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0071b50932b38fd7736dad548a083f356980f7f --- /dev/null +++ b/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch @@ -0,0 +1,27 @@ +From 9e2158495059b485f2c28bb649c8b4a87fb3105c Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 11:24:32 +0800 +Subject: [PATCH 12/15] Currently, while kvm and qemu can not handle some kvm + exit, qemu will do vm_stop, which will make vm in pause state. This action + make vm unrecoverable, so send guest panic to libvirt instead. + +--- + accel/kvm/kvm-all.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index eecd8031cf..b128d311c2 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2970,7 +2970,7 @@ int kvm_cpu_exec(CPUState *cpu) + + if (ret < 0) { + cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); +- vm_stop(RUN_STATE_INTERNAL_ERROR); ++ qemu_system_guest_panicked(cpu_get_crash_info(cpu)); + } + + qatomic_set(&cpu->exit_request, 0); +-- +2.27.0 + diff --git a/block-Add-sanity-check-when-setting-retry-parameters.patch b/block-Add-sanity-check-when-setting-retry-parameters.patch new file mode 100644 index 0000000000000000000000000000000000000000..d48fa5d654a4d5eb2e50b2336715bbeff40242a5 --- /dev/null +++ b/block-Add-sanity-check-when-setting-retry-parameters.patch @@ -0,0 +1,156 @@ +From f329ec9bd971ba7776cadb57e7311bfb6da41060 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 18 Mar 2021 19:45:11 +0800 +Subject: [PATCH 9/9] block: Add sanity check when setting retry parameters + +Add sanity check when setting retry parameters to avoid invalid retry +configuration. + +Signed-off-by: Jiahui Cen +Signed-off-by: Alex Chen +--- + hw/core/qdev-prop-internal.h | 2 ++ + hw/core/qdev-properties-system.c | 45 +++++++++++++++++++++++++++++ + hw/core/qdev-properties.c | 4 +-- + include/hw/block/block.h | 7 +++-- + include/hw/qdev-properties-system.h | 8 +++++ + 5 files changed, 61 insertions(+), 5 deletions(-) + +diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h +index d7b77844fe..68b1b9d10c 100644 +--- a/hw/core/qdev-prop-internal.h ++++ b/hw/core/qdev-prop-internal.h +@@ -22,6 +22,8 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op, + + void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp); ++void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp); + void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp); + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index 6a6ff03be7..b93ed9b4dd 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -612,6 +612,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = { + .set_default_value = qdev_propinfo_set_default_value_enum, + }; + ++static void set_retry_time(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ DeviceState *dev = DEVICE(obj); ++ Property *prop = opaque; ++ int64_t value, *ptr = object_field_prop_ptr(obj, prop); ++ Error *local_err = NULL; ++ ++ if (dev->realized) { ++ qdev_prop_set_after_realize(dev, name, errp); ++ return; ++ } ++ ++ visit_type_int64(v, name, &value, &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ /* value should not be negative */ ++ if (value < 0) { ++ error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, ++ dev->id ? : "", name, (int64_t)value, 0L, LONG_MAX); ++ return; ++ } ++ ++ *ptr = value; ++} ++ ++const PropertyInfo qdev_prop_blockdev_retry_interval = { ++ .name = "BlockdevRetryInterval", ++ .description = "Interval for retry error handling policy", ++ .get = qdev_propinfo_get_int64, ++ .set = set_retry_time, ++ .set_default_value = qdev_propinfo_set_default_value_int, ++}; ++ ++const PropertyInfo qdev_prop_blockdev_retry_timeout = { ++ .name = "BlockdevRetryTimeout", ++ .description = "Timeout for retry error handling policy", ++ .get = qdev_propinfo_get_int64, ++ .set = set_retry_time, ++ .set_default_value = qdev_propinfo_set_default_value_int, ++}; ++ + /* --- BIOS CHS translation */ + + QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); +diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c +index c34aac6ebc..2d5f662663 100644 +--- a/hw/core/qdev-properties.c ++++ b/hw/core/qdev-properties.c +@@ -396,7 +396,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name, + visit_type_uint64(v, name, ptr, errp); + } + +-static void get_int64(Object *obj, Visitor *v, const char *name, ++void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) + { + Property *prop = opaque; +@@ -423,7 +423,7 @@ const PropertyInfo qdev_prop_uint64 = { + + const PropertyInfo qdev_prop_int64 = { + .name = "int64", +- .get = get_int64, ++ .get = qdev_propinfo_get_int64, + .set = set_int64, + .set_default_value = qdev_propinfo_set_default_value_int, + }; +diff --git a/include/hw/block/block.h b/include/hw/block/block.h +index 24fb7d77af..282929e8f0 100644 +--- a/include/hw/block/block.h ++++ b/include/hw/block/block.h +@@ -82,9 +82,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) + BLOCKDEV_ON_ERROR_AUTO), \ + DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ + BLOCKDEV_ON_ERROR_AUTO), \ +- DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ +- -1), \ +- DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) ++ DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL("retry_interval", _state, \ ++ _conf.retry_interval, 1000), \ ++ DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT("retry_timeout", _state, \ ++ _conf.retry_timeout, 0) + + /* Backend access helpers */ + +diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h +index 0ac327ae60..906a027676 100644 +--- a/include/hw/qdev-properties-system.h ++++ b/include/hw/qdev-properties-system.h +@@ -9,6 +9,8 @@ extern const PropertyInfo qdev_prop_reserved_region; + extern const PropertyInfo qdev_prop_multifd_compression; + extern const PropertyInfo qdev_prop_losttickpolicy; + extern const PropertyInfo qdev_prop_blockdev_on_error; ++extern const PropertyInfo qdev_prop_blockdev_retry_interval; ++extern const PropertyInfo qdev_prop_blockdev_retry_timeout; + extern const PropertyInfo qdev_prop_bios_chs_trans; + extern const PropertyInfo qdev_prop_fdc_drive_type; + extern const PropertyInfo qdev_prop_drive; +@@ -47,6 +49,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width; + #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ + BlockdevOnError) ++#define DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_interval, \ ++ int64_t) ++#define DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT(_n, _s, _f, _d) \ ++ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_timeout, \ ++ int64_t) + #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) + #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \ +-- +2.27.0 + diff --git a/block-backend-Stop-retrying-when-draining.patch b/block-backend-Stop-retrying-when-draining.patch new file mode 100644 index 0000000000000000000000000000000000000000..baf5c6c35333786da98e82334cf8b84eb59eaa38 --- /dev/null +++ b/block-backend-Stop-retrying-when-draining.patch @@ -0,0 +1,38 @@ +From 06db37983cfd20d7e92001ac3cb06867a281f1c9 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 25 Feb 2021 18:03:57 +0800 +Subject: [PATCH 8/9] block-backend: Stop retrying when draining + +Retrying failed requests when draining would make the draining hung. So it +is better not to trigger the retry timer when draining. And after the +virtual devices go back to work, they would retry those queued requests. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + block/block-backend.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index d3d90a95a5..49d236b2a4 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1874,9 +1874,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, + send_qmp_error_event(blk, action, is_read, error); + qemu_system_vmstop_request(RUN_STATE_IO_ERROR); + } else if (action == BLOCK_ERROR_ACTION_RETRY) { +- timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + +- blk->retry_interval); +- send_qmp_error_event(blk, action, is_read, error); ++ if (!blk->quiesce_counter) { ++ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ++ blk->retry_interval); ++ send_qmp_error_event(blk, action, is_read, error); ++ } + } else { + send_qmp_error_event(blk, action, is_read, error); + } +-- +2.27.0 + diff --git a/cpu-features-fix-bug-for-memory-leakage.patch b/cpu-features-fix-bug-for-memory-leakage.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb7010440d9d395acd9bb0bc9792de279a4d4088 --- /dev/null +++ b/cpu-features-fix-bug-for-memory-leakage.patch @@ -0,0 +1,25 @@ +From 12706113392018fd7aa6471a3cbada62f0180539 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 12:51:19 +0800 +Subject: [PATCH 13/15] cpu/features: fix bug for memory leakage + +strList hash not free after used, Fix it. +--- + target/i386/cpu.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index aa9e636800..b9690e3250 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -4752,6 +4752,7 @@ static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v, + + x86_cpu_list_feature_names(xc->filtered_features, &result); + visit_type_strList(v, "unavailable-features", &result, errp); ++ qapi_free_strList(result); + } + + /* Check for missing features that may prevent the CPU class from +-- +2.27.0 + diff --git a/hugepages-hugepages-files-maybe-leftover.patch b/hugepages-hugepages-files-maybe-leftover.patch new file mode 100644 index 0000000000000000000000000000000000000000..611f1eace32aebf33917851b1a3833984efab124 --- /dev/null +++ b/hugepages-hugepages-files-maybe-leftover.patch @@ -0,0 +1,99 @@ +From 3cb1b0ce091998532a30793e3272925da4e6f3aa Mon Sep 17 00:00:00 2001 +From: Jiajie Li +Date: Mon, 7 Feb 2022 14:31:34 +0800 +Subject: [PATCH 1/2] hugepages: hugepages files maybe leftover + +Before qemu uses the hugepage memory directory /dev/hugepages/libvirt/qemu/xxx, +The directory may be deleted because of the destroy virtual machine. +Cause qemu to create files directly under /dev/hugepages/libvirt/qemu/. +After the file is created, the file is not cleaned up by unlink, +and when the virtual machine is destroyed, libvirt will only clean up +/dev/hugepages/libvirt/qemu/xxx directory. After creating the hugepage file, +execute unlink to clean up the file to fix the problem. + +Signed-off-by: Jinhua Cao +Signed-off-by: Jiajie Li +--- + include/qemu/mmap-alloc.h | 3 +++ + softmmu/physmem.c | 10 +++++++++- + util/mmap-alloc.c | 22 ++++++++++++++++++++++ + 3 files changed, 34 insertions(+), 1 deletion(-) + +diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h +index 90d0eee705..707202e5be 100644 +--- a/include/qemu/mmap-alloc.h ++++ b/include/qemu/mmap-alloc.h +@@ -1,6 +1,9 @@ + #ifndef QEMU_MMAP_ALLOC_H + #define QEMU_MMAP_ALLOC_H + ++#define HUGETLBFS_MAGIC 0x958458f6 ++ ++size_t qemu_fd_getfiletype(int fd); + + size_t qemu_fd_getpagesize(int fd); + +diff --git a/softmmu/physmem.c b/softmmu/physmem.c +index 3524c04c2a..3b9a61448c 100644 +--- a/softmmu/physmem.c ++++ b/softmmu/physmem.c +@@ -1496,7 +1496,14 @@ static int file_ram_open(const char *path, + /* @path names a file that doesn't exist, create it */ + fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644); + if (fd >= 0) { +- *created = true; ++ info_report("open %s success \n", path); ++ /* if fd file type is HUGETLBFS_MAGIC, unlink it, */ ++ /* in case to prevent residue after qemu killed */ ++ if (qemu_fd_getfiletype(fd) == HUGETLBFS_MAGIC) { ++ unlink(path); ++ } else { ++ *created = true; ++ } + break; + } + } else if (errno == EISDIR) { +@@ -1515,6 +1522,7 @@ static int file_ram_open(const char *path, + + fd = mkstemp(filename); + if (fd >= 0) { ++ info_report("mkstemp %s success \n", filename); + unlink(filename); + g_free(filename); + break; +diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c +index 893d864354..4993dd5bfa 100644 +--- a/util/mmap-alloc.c ++++ b/util/mmap-alloc.c +@@ -29,6 +29,28 @@ + #include + #endif + ++size_t qemu_fd_getfiletype(int fd) ++{ ++ struct statfs fs; ++ int ret; ++ ++ if (fd != -1) { ++ do { ++ ret = fstatfs(fd, &fs); ++ } while (ret != 0 && errno == EINTR); ++ ++ if (ret != 0) { ++ fprintf(stderr, "Couldn't fstatfs() fd: %s\n", ++ strerror(errno)); ++ return -1; ++ } ++ return fs.f_type; ++ } else { ++ fprintf(stderr, "fd is invalid \n"); ++ return -1; ++ } ++} ++ + size_t qemu_fd_getpagesize(int fd) + { + #ifdef CONFIG_LINUX +-- +2.27.0 + diff --git a/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch b/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch new file mode 100644 index 0000000000000000000000000000000000000000..d7f90b3e2cf859fecaf55cffaa886a08297ff5d4 --- /dev/null +++ b/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch @@ -0,0 +1,47 @@ +From d9fef6139e17976db194d73848baff543c4a2590 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 08:49:41 +0800 +Subject: [PATCH 10/15] migration: skip cache_drop for bios bootloader and + nvram template + +Qemu enabled page cache dropping for raw device on the destionation host +during shared storage migration. +However, fsync may take 300ms to multiple seconds to return in multiple-migration +scene, because all domains in a host share bios bootloader file, skip cache_drop +for bios bootloader and nvram template to avoid downtime increase. +--- + block.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/block.c b/block.c +index 0ac5b163d2..91f123a354 100644 +--- a/block.c ++++ b/block.c +@@ -67,6 +67,9 @@ + + #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ + ++#define DEFAULT_BIOS_BOOT_LOADER_DIR "/usr/share/edk2" ++#define DEFAULT_NVRAM_TEMPLATE_DIR "/var/lib/libvirt/qemu/nvram" ++ + static QTAILQ_HEAD(, BlockDriverState) graph_bdrv_states = + QTAILQ_HEAD_INITIALIZER(graph_bdrv_states); + +@@ -6432,7 +6435,13 @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp) + return ret; + } + +- if (bs->drv->bdrv_co_invalidate_cache) { ++ /* ++ * It's not necessary for bios bootloader and nvram template to drop cache ++ * when migration, skip this step for them to avoid dowtime increase. ++ */ ++ if (bs->drv->bdrv_co_invalidate_cache && ++ !strstr(bs->filename, DEFAULT_BIOS_BOOT_LOADER_DIR) && ++ !strstr(bs->filename, DEFAULT_NVRAM_TEMPLATE_DIR)) { + bs->drv->bdrv_co_invalidate_cache(bs, &local_err); + if (local_err) { + bs->open_flags |= BDRV_O_INACTIVE; +-- +2.27.0 + diff --git a/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch b/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch new file mode 100644 index 0000000000000000000000000000000000000000..d45cb3189c161de501ac329027b502ec60858546 --- /dev/null +++ b/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch @@ -0,0 +1,111 @@ +From 7eb28408efe75192a0f976a197f8f1906d9073e8 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 14:13:05 +0800 +Subject: [PATCH 14/15] monitor/qmp: drop inflight rsp if qmp client broken + +If libvirt restart while qemu is handle qmp message, libvirt will +reconnect qemu monitor socket, and query status of qemu by qmp. +But qemu may return last qmp respond to new connect socket, and libvirt +recv unexpected respond, So libvirt think qemu is abnormal, and will +kill qemu. + +This patch add qmp connect id, while reconnect id will change. While +respond to libvirt, judge if id is same, if not, drop this respond. +--- + monitor/monitor-internal.h | 1 + + monitor/qmp.c | 19 +++++++++++-------- + 2 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h +index 3da3f86c6a..5435864add 100644 +--- a/monitor/monitor-internal.h ++++ b/monitor/monitor-internal.h +@@ -144,6 +144,7 @@ typedef struct { + const QmpCommandList *commands; + bool capab_offered[QMP_CAPABILITY__MAX]; /* capabilities offered */ + bool capab[QMP_CAPABILITY__MAX]; /* offered and accepted */ ++ uint64_t qmp_client_id; /*qmp client id, update if peer disconnect */ + /* + * Protects qmp request/response queue. + * Take monitor_lock first when you need both. +diff --git a/monitor/qmp.c b/monitor/qmp.c +index 092c527b6f..4d1ac66785 100644 +--- a/monitor/qmp.c ++++ b/monitor/qmp.c +@@ -125,18 +125,19 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rsp) + * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP. + * Nothing is emitted then. + */ +-static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) ++static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp, uint64_t req_client_id) + { +- if (rsp) { +- qmp_send_response(mon, rsp); ++ if (!rsp || (mon->qmp_client_id != req_client_id)) { ++ return; + } ++ qmp_send_response(mon, rsp); + } + + /* + * Runs outside of coroutine context for OOB commands, but in + * coroutine context for everything else. + */ +-static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) ++static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req, uint64_t req_client_id) + { + QDict *rsp; + QDict *error; +@@ -156,7 +157,7 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) + } + } + +- monitor_qmp_respond(mon, rsp); ++ monitor_qmp_respond(mon, rsp, req_client_id); + qobject_unref(rsp); + } + +@@ -315,13 +316,13 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data) + trace_monitor_qmp_cmd_in_band(id_json->str); + g_string_free(id_json, true); + } +- monitor_qmp_dispatch(mon, req_obj->req); ++ monitor_qmp_dispatch(mon, req_obj->req, mon->qmp_client_id); + } else { + assert(req_obj->err); + trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err)); + rsp = qmp_error_response(req_obj->err); + req_obj->err = NULL; +- monitor_qmp_respond(mon, rsp); ++ monitor_qmp_respond(mon, rsp, mon->qmp_client_id); + qobject_unref(rsp); + } + +@@ -366,7 +367,7 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) + trace_monitor_qmp_cmd_out_of_band(id_json->str); + g_string_free(id_json, true); + } +- monitor_qmp_dispatch(mon, req); ++ monitor_qmp_dispatch(mon, req, mon->qmp_client_id); + qobject_unref(req); + return; + } +@@ -452,6 +453,7 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event) + mon_refcount++; + break; + case CHR_EVENT_CLOSED: ++ mon->qmp_client_id++; + /* + * Note: this is only useful when the output of the chardev + * backend is still open. For example, when the backend is +@@ -505,6 +507,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) + } + qemu_chr_fe_set_echo(&mon->common.chr, true); + ++ mon->qmp_client_id = 1; + /* Note: we run QMP monitor in I/O thread when @chr supports that */ + monitor_data_init(&mon->common, true, false, + qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT)); +-- +2.27.0 + diff --git a/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch b/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e87543dfe4485d6799039e6783c165d87452a39 --- /dev/null +++ b/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch @@ -0,0 +1,56 @@ +From e5fc3a755c9ba9f18bc0416c60f745912cb5b104 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 14:21:39 +0800 +Subject: [PATCH 15/15] oslib-posix: optimise vm startup time for 1G hugepage + +It takes quit a long time to clear 1G-hugepage, which makes glibc +pthread_create quit slow. +Create touch_pages threads in advance, and then handle the touch_pages +callback. Only read lock is held here. +--- + util/oslib-posix.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/util/oslib-posix.c b/util/oslib-posix.c +index e8bdb02e1d..18a38b9464 100644 +--- a/util/oslib-posix.c ++++ b/util/oslib-posix.c +@@ -84,6 +84,7 @@ typedef struct MemsetThread MemsetThread; + + static MemsetThread *memset_thread; + static int memset_num_threads; ++static int started_num_threads; + static bool memset_thread_failed; + + static QemuMutex page_mutex; +@@ -464,6 +465,10 @@ static void *do_touch_pages(void *arg) + } + qemu_mutex_unlock(&page_mutex); + ++ while (started_num_threads != memset_num_threads) { ++ smp_mb(); ++ } ++ + /* unblock SIGBUS */ + sigemptyset(&set); + sigaddset(&set, SIGBUS); +@@ -529,7 +534,7 @@ static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, + memset_thread = g_new0(MemsetThread, memset_num_threads); + numpages_per_thread = numpages / memset_num_threads; + leftover = numpages % memset_num_threads; +- for (i = 0; i < memset_num_threads; i++) { ++ for (i = 0, started_num_threads = 0; i < memset_num_threads; i++) { + memset_thread[i].addr = addr; + memset_thread[i].numpages = numpages_per_thread + (i < leftover); + memset_thread[i].hpagesize = hpagesize; +@@ -537,6 +542,7 @@ static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, + do_touch_pages, &memset_thread[i], + QEMU_THREAD_JOINABLE); + addr += memset_thread[i].numpages * hpagesize; ++ started_num_threads++; + } + + qemu_mutex_lock(&page_mutex); +-- +2.27.0 + diff --git a/ps2-fix-oob-in-ps2-kbd.patch b/ps2-fix-oob-in-ps2-kbd.patch new file mode 100644 index 0000000000000000000000000000000000000000..a385968fd30566264e234cc57ef60a7ad03097a3 --- /dev/null +++ b/ps2-fix-oob-in-ps2-kbd.patch @@ -0,0 +1,35 @@ +From 19523565181bb6efb1b9f819d45a7ca8ea6eca19 Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Wed, 9 Feb 2022 11:21:28 +0800 +Subject: [PATCH 11/15] ps2: fix oob in ps2 kbd + +fix oob in ps2 kbd +--- + hw/input/ps2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/input/ps2.c b/hw/input/ps2.c +index 9376a8f4ce..5d82ee3cdf 100644 +--- a/hw/input/ps2.c ++++ b/hw/input/ps2.c +@@ -205,7 +205,7 @@ void ps2_queue_noirq(PS2State *s, int b) + } + + q->data[q->wptr] = b; +- if (++q->wptr == PS2_BUFFER_SIZE) { ++ if (++q->wptr >= PS2_BUFFER_SIZE) { + q->wptr = 0; + } + q->count++; +@@ -578,7 +578,7 @@ uint32_t ps2_read_data(PS2State *s) + val = q->data[index]; + } else { + val = q->data[q->rptr]; +- if (++q->rptr == PS2_BUFFER_SIZE) { ++ if (++q->rptr >= PS2_BUFFER_SIZE) { + q->rptr = 0; + } + q->count--; +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index b1dcce7c6909da47d4d957952967dcc43ee00392..70eac667888cc877c0421785dad8d22e25aa68ee 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 7 +Release: 8 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -32,6 +32,21 @@ Patch0019: doc-Update-multi-thread-compression-doc.patch Patch0020: Revert-cpu-parse-feature-to-avoid-failure.patch Patch0021: Revert-cpu-add-Cortex-A72-processor-kvm-target-suppo.patch Patch0022: 0003-cpu-add-Cortex-A72-processor-kvm-target-support.patch +Patch0023: hugepages-hugepages-files-maybe-leftover.patch +Patch0024: target-i386-Modify-the-VM-s-physical-bits-value-set-.patch +Patch0025: vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch +Patch0026: vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch +Patch0027: vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch +Patch0028: scsi-bus-Refactor-the-code-that-retries-requests.patch +Patch0029: scsi-disk-Add-support-for-retry-on-errors.patch +Patch0030: block-backend-Stop-retrying-when-draining.patch +Patch0031: block-Add-sanity-check-when-setting-retry-parameters.patch +Patch0032: migration-skip-cache_drop-for-bios-bootloader-and-nv.patch +Patch0033: ps2-fix-oob-in-ps2-kbd.patch +Patch0034: Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch +Patch0035: cpu-features-fix-bug-for-memory-leakage.patch +Patch0036: monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch +Patch0037: oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch BuildRequires: flex BuildRequires: gcc @@ -476,6 +491,29 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Feb 11 2022 imxcc +- migration: skip cache_drop for bios bootloader and +- ps2: fix oob in ps2 kbd +- Currently, while kvm and qemu can not handle some kvm +- cpu/features: fix bug for memory leakage +- monitor/qmp: drop inflight rsp if qmp client broken +- oslib-posix: optimise vm startup time for 1G hugepage + +* Fri Feb 11 2022 imxcc +- scsi-bus: Refactor the code that retries requests +- scsi-disk: Add support for retry on errors +- block-backend: Stop retrying when draining +- block: Add sanity check when setting retry parameters + +* Fri Feb 11 2022 imxcc +- vfio/pci: Ascend310 need 4Bytes quirk in bar4 +- vfio/pci: Ascend710 need 4Bytes quirk in bar0 +- vfio/pci: Ascend910 need 4Bytes quirk in bar0 + +* Fri Feb 11 2022 imxcc +- hugepages: hugepages files maybe leftover +- Patch0024: target-i386: Modify the VM's physical bits value set + * Fri Feb 11 2022 Yan Wang - log: disable qemu_log function for "make check V=1" diff --git a/scsi-bus-Refactor-the-code-that-retries-requests.patch b/scsi-bus-Refactor-the-code-that-retries-requests.patch new file mode 100644 index 0000000000000000000000000000000000000000..84802c483fb08d03c8e101106f33bdc0ce31461c --- /dev/null +++ b/scsi-bus-Refactor-the-code-that-retries-requests.patch @@ -0,0 +1,69 @@ +From 391dd8f1458c8db0b848450718af5c69285e5705 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:54 +0800 +Subject: [PATCH 6/9] scsi-bus: Refactor the code that retries requests + +Move the code that retries requests from scsi_dma_restart_bh() to its own, +non-static, function. This will allow us to call it from the +retry_request_cb() of scsi-disk in a future patch. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/scsi/scsi-bus.c | 16 +++++++++++----- + include/hw/scsi/scsi.h | 1 + + 2 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index 77325d8cc7..5e6f891b9d 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -143,14 +143,10 @@ void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host, + qbus_set_bus_hotplug_handler(BUS(bus)); + } + +-static void scsi_dma_restart_bh(void *opaque) ++void scsi_retry_requests(SCSIDevice *s) + { +- SCSIDevice *s = opaque; + SCSIRequest *req, *next; + +- qemu_bh_delete(s->bh); +- s->bh = NULL; +- + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { + scsi_req_ref(req); +@@ -174,6 +170,16 @@ static void scsi_dma_restart_bh(void *opaque) + object_unref(OBJECT(s)); + } + ++static void scsi_dma_restart_bh(void *opaque) ++{ ++ SCSIDevice *s = opaque; ++ ++ qemu_bh_delete(s->bh); ++ s->bh = NULL; ++ ++ scsi_retry_requests(s); ++} ++ + void scsi_req_retry(SCSIRequest *req) + { + /* No need to save a reference, because scsi_dma_restart_bh just +diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h +index a567a5ed86..e5d90cd9dc 100644 +--- a/include/hw/scsi/scsi.h ++++ b/include/hw/scsi/scsi.h +@@ -212,6 +212,7 @@ void scsi_req_cancel_complete(SCSIRequest *req); + void scsi_req_cancel(SCSIRequest *req); + void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier); + void scsi_req_retry(SCSIRequest *req); ++void scsi_retry_requests(SCSIDevice *s); + void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); + void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense); + void scsi_device_report_change(SCSIDevice *dev, SCSISense sense); +-- +2.27.0 + diff --git a/scsi-disk-Add-support-for-retry-on-errors.patch b/scsi-disk-Add-support-for-retry-on-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..69f76143bc27c0ea1f121d7419b88ae2764e07dc --- /dev/null +++ b/scsi-disk-Add-support-for-retry-on-errors.patch @@ -0,0 +1,77 @@ +From 52115ca0ad925b1d719eb46e22c455aa5839534a Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 21 Jan 2021 15:46:55 +0800 +Subject: [PATCH 7/9] scsi-disk: Add support for retry on errors + +Mark failed requests as to be retried and implement retry_request_cb to +handle these requests. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +Signed-off-by: Alex Chen +--- + hw/scsi/scsi-disk.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index d4914178ea..d278efc701 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -246,6 +246,10 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) + scsi_req_retry(&r->req); + return true; + ++ case BLOCK_ERROR_ACTION_RETRY: ++ scsi_req_retry(&r->req); ++ return true; ++ + default: + g_assert_not_reached(); + } +@@ -253,6 +257,8 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) + + static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) + { ++ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); ++ + if (r->req.io_canceled) { + scsi_req_cancel_complete(&r->req); + return true; +@@ -262,6 +268,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) + return scsi_handle_rw_error(r, ret, acct_failed); + } + ++ blk_error_retry_reset_timeout(s->qdev.conf.blk); + return false; + } + +@@ -2278,6 +2285,13 @@ static void scsi_disk_resize_cb(void *opaque) + } + } + ++static void scsi_disk_retry_request(void *opaque) ++{ ++ SCSIDiskState *s = opaque; ++ ++ scsi_retry_requests(&s->qdev); ++} ++ + static void scsi_cd_change_media_cb(void *opaque, bool load, Error **errp) + { + SCSIDiskState *s = opaque; +@@ -2326,10 +2340,12 @@ static const BlockDevOps scsi_disk_removable_block_ops = { + .is_medium_locked = scsi_cd_is_medium_locked, + + .resize_cb = scsi_disk_resize_cb, ++ .retry_request_cb = scsi_disk_retry_request, + }; + + static const BlockDevOps scsi_disk_block_ops = { + .resize_cb = scsi_disk_resize_cb, ++ .retry_request_cb = scsi_disk_retry_request, + }; + + static void scsi_disk_unit_attention_reported(SCSIDevice *dev) +-- +2.27.0 + diff --git a/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch b/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a490b614796ce0d33f645039c057ca8950187be --- /dev/null +++ b/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch @@ -0,0 +1,116 @@ +From a09c3928b33b0c53831bd9eeb56f8171c26057bc Mon Sep 17 00:00:00 2001 +From: Jiajie Li +Date: Tue, 8 Feb 2022 09:46:53 +0800 +Subject: [PATCH 2/2] target-i386: Modify the VM's physical bits value set + policy. + +To resolve the problem that a VM with large memory capacity fails +to be live migrated, determine whether the VM is a large memory +capacity based on the memory size (4 TB). If yes, set the bus width +of the VM address to 46 bits. If no, set the bus width to 42 bits. + +Signed-off-by: Jinhua Cao +Signed-off-by: Jiajie Li +--- + target/i386/cpu.c | 19 ++++++++++++++++++- + target/i386/cpu.h | 6 ++++++ + target/i386/host-cpu.c | 13 +++++++------ + 3 files changed, 31 insertions(+), 7 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index aa9e636800..868cf3e7e8 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -6678,6 +6678,23 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value) + cpu->env.eip = value; + } + ++/* At present, we check the vm is *LARGE* or not, i.e. whether ++ * the memory size is more than 4T or not. ++ */ ++const uint64_t large_vm_mem_size = 0x40000000000UL; ++void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu) ++{ ++ /* If there is not a large vm, we set the phys_bits to 42 bits, ++ * otherwise, we increase the phys_bits to 46 bits. ++ */ ++ if (ram_size < large_vm_mem_size) { ++ cpu->phys_bits = DEFAULT_VM_CPU_PHYS_BITS; ++ } else { ++ cpu->phys_bits = LARGE_VM_CPU_PHYS_BITS; ++ cpu->fill_mtrr_mask = true; ++ } ++} ++ + int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request) + { + X86CPU *cpu = X86_CPU(cs); +@@ -6862,7 +6879,7 @@ static Property x86_cpu_properties[] = { + DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), + DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false), + DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0), +- DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true), ++ DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, false), + DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7, + UINT32_MAX), + DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX), +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 04f2b790c9..6f777fd6ca 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -24,6 +24,7 @@ + #include "cpu-qom.h" + #include "kvm/hyperv-proto.h" + #include "exec/cpu-defs.h" ++#include "exec/cpu-common.h" + #include "qapi/qapi-types-common.h" + + /* The x86 has a strong memory model with some store-after-load re-ordering */ +@@ -1841,6 +1842,11 @@ struct X86CPU { + extern const VMStateDescription vmstate_x86_cpu; + #endif + ++#define DEFAULT_VM_CPU_PHYS_BITS 42 ++#define LARGE_VM_CPU_PHYS_BITS 46 ++ ++void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu); ++ + int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request); + + int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, +diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c +index 10f8aba86e..5a1bbefa36 100644 +--- a/target/i386/host-cpu.c ++++ b/target/i386/host-cpu.c +@@ -12,6 +12,7 @@ + #include "host-cpu.h" + #include "qapi/error.h" + #include "sysemu/sysemu.h" ++#include "hw/boards.h" + + /* Note: Only safe for use on x86(-64) hosts */ + static uint32_t host_cpu_phys_bits(void) +@@ -56,14 +57,14 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu) + uint32_t phys_bits = cpu->phys_bits; + static bool warned; + +- /* +- * Print a warning if the user set it to a value that's not the +- * host value. +- */ +- if (phys_bits != host_phys_bits && phys_bits != 0 && ++ /* adjust x86 cpu phys_bits according to ram_size. */ ++ x86_cpu_adjuest_by_ram_size(current_machine->ram_size, cpu); ++ ++ /* Print a warning if the host value less than the user set. */ ++ if (phys_bits > host_phys_bits && phys_bits != 0 && + !warned) { + warn_report("Host physical bits (%u)" +- " does not match phys-bits property (%u)", ++ " less than phys-bits property (%u)", + host_phys_bits, phys_bits); + warned = true; + } +-- +2.27.0 + diff --git a/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch b/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3ea4c233b747fac21f166edb4b65717b1998cb1 --- /dev/null +++ b/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch @@ -0,0 +1,105 @@ +From eee7ff398496524881225d503309a9853972c5df Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 17:00:39 +0800 +Subject: [PATCH 3/5] vfio/pci: Ascend310 need 4Bytes quirk in bar4 + +--- + hw/vfio/pci-quirks.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index 0cf69a8c6d..d86bcaf309 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1209,6 +1209,80 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + return 0; + } + ++#define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND310_XLOADER_SIZE 4 ++#define ASCEND310_XLOADER_OFFSET 0x400 ++ ++typedef struct VFIOAscendBarQuirk { ++ struct VFIOPCIDevice *vdev; ++ pcibus_t offset; ++ uint8_t bar; ++ MemoryRegion *mem; ++} VFIOAscendBarQuirk; ++ ++static uint64_t vfio_ascend_quirk_read(void *opaque, ++ hwaddr addr, unsigned size) ++{ ++ VFIOAscendBarQuirk *quirk = opaque; ++ VFIOPCIDevice *vdev = quirk->vdev; ++ ++ qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", ++ addr + quirk->offset, size); ++ ++ return vfio_region_read(&vdev->bars[quirk->bar].region, ++ addr + quirk->offset, size); ++} ++ ++static void vfio_ascend_quirk_write(void *opaque, hwaddr addr, ++ uint64_t data, unsigned size) ++{ ++ VFIOAscendBarQuirk *quirk = opaque; ++ ++ qemu_log("modifying RO region is not allowed! addr=0x%" ++ HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", ++ addr + quirk->offset, data, size); ++} ++ ++static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { ++ .read = vfio_ascend_quirk_read, ++ .write = vfio_ascend_quirk_write, ++ .endianness = DEVICE_LITTLE_ENDIAN, ++}; ++ ++static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar4_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND310) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar4_quirk = quirk->data = g_new0(typeof(*bar4_quirk), quirk->nr_mem); ++ bar4_quirk[0].vdev = vdev; ++ bar4_quirk[0].offset = ASCEND310_XLOADER_OFFSET; ++ bar4_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar4_quirk[0], ++ "vfio-ascend310-bar4-intercept-regs-quirk", ++ ASCEND310_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar4_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + /* + * Common quirk probe entry points. + */ +@@ -1261,6 +1335,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend310_bar4_quirk(vdev, nr); + } + + void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr) +-- +2.27.0 + diff --git a/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch new file mode 100644 index 0000000000000000000000000000000000000000..93d7b2584b41a640d2b3615f7495d4734a47ac72 --- /dev/null +++ b/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch @@ -0,0 +1,75 @@ +From bcc63ff3975cca783308fac7517a7911c29bd7c1 Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 17:16:04 +0800 +Subject: [PATCH 4/5] vfio/pci: Ascend710 need 4Bytes quirk in bar0 + +--- + hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index d86bcaf309..6a9fc0afc5 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1210,7 +1210,10 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + } + + #define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND710 0xd500 + #define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND710_XLOADER_SIZE 4 ++#define ASCEND710_XLOADER_OFFSET 0x20430 + #define ASCEND310_XLOADER_SIZE 4 + #define ASCEND310_XLOADER_OFFSET 0x400 + +@@ -1250,6 +1253,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { + .endianness = DEVICE_LITTLE_ENDIAN, + }; + ++static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar0_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND710) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); ++ bar0_quirk[0].vdev = vdev; ++ bar0_quirk[0].offset = ASCEND710_XLOADER_OFFSET; ++ bar0_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar0_quirk[0], ++ "vfio-ascend710-bar0-intercept-regs-quirk", ++ ASCEND710_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar0_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) + { + VFIOQuirk *quirk; +@@ -1335,6 +1371,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend710_bar0_quirk(vdev, nr); + vfio_probe_ascend310_bar4_quirk(vdev, nr); + } + +-- +2.27.0 + diff --git a/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch new file mode 100644 index 0000000000000000000000000000000000000000..34b835d9b297aa8f532ff8498374dd8341d6861f --- /dev/null +++ b/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch @@ -0,0 +1,76 @@ +From 4cf7d00e43c4e90327e13afa3cbc9c7ca3657c9f Mon Sep 17 00:00:00 2001 +From: Binfeng Wu +Date: Tue, 8 Feb 2022 19:20:36 +0800 +Subject: [PATCH 5/5] vfio/pci: Ascend910 need 4Bytes quirk in bar0 + +--- + hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c +index 6a9fc0afc5..2457a61196 100644 +--- a/hw/vfio/pci-quirks.c ++++ b/hw/vfio/pci-quirks.c +@@ -1210,8 +1210,11 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, + } + + #define PCI_VENDOR_ID_HUAWEI 0x19e5 ++#define PCI_DEVICE_ID_ASCEND910 0xd801 + #define PCI_DEVICE_ID_ASCEND710 0xd500 + #define PCI_DEVICE_ID_ASCEND310 0xd100 ++#define ASCEND910_XLOADER_SIZE 4 ++#define ASCEND910_XLOADER_OFFSET 0x80400 + #define ASCEND710_XLOADER_SIZE 4 + #define ASCEND710_XLOADER_OFFSET 0x20430 + #define ASCEND310_XLOADER_SIZE 4 +@@ -1253,6 +1256,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { + .endianness = DEVICE_LITTLE_ENDIAN, + }; + ++static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) ++{ ++ VFIOQuirk *quirk; ++ VFIOAscendBarQuirk *bar0_quirk; ++ ++ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || ++ vdev->device_id != PCI_DEVICE_ID_ASCEND910) { ++ return; ++ } ++ ++ quirk = g_malloc0(sizeof(*quirk)); ++ quirk->nr_mem = 1; ++ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); ++ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); ++ bar0_quirk[0].vdev = vdev; ++ bar0_quirk[0].offset = ASCEND910_XLOADER_OFFSET; ++ bar0_quirk[0].bar = nr; ++ ++ /* ++ * intercept w/r to the xloader-updating register, ++ * so the vm can't enable xloader-updating ++ */ ++ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), ++ &vfio_ascend_intercept_regs_quirk, ++ &bar0_quirk[0], ++ "vfio-ascend910-bar0-intercept-regs-quirk", ++ ASCEND910_XLOADER_SIZE); ++ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, ++ bar0_quirk[0].offset, ++ &quirk->mem[0], 1); ++ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); ++} ++ + static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) + { + VFIOQuirk *quirk; +@@ -1371,6 +1407,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) + #ifdef CONFIG_VFIO_IGD + vfio_probe_igd_bar4_quirk(vdev, nr); + #endif ++ vfio_probe_ascend910_bar0_quirk(vdev, nr); + vfio_probe_ascend710_bar0_quirk(vdev, nr); + vfio_probe_ascend310_bar4_quirk(vdev, nr); + } +-- +2.27.0 +