* Mon Jul 24 2023 Miroslav Rezanina <mrezanin@redhat.com> - 8.0.0-9

- kvm-scsi-fetch-unit-attention-when-creating-the-request.patch [bz#2176702]
- kvm-scsi-cleanup-scsi_clear_unit_attention.patch [bz#2176702]
- kvm-scsi-clear-unit-attention-only-for-REPORT-LUNS-comma.patch [bz#2176702]
- kvm-s390x-ap-Wire-up-the-device-request-notifier-interfa.patch [RHEL-794]
- kvm-multifd-Create-property-multifd-flush-after-each-sec.patch [bz#2196295]
- kvm-multifd-Protect-multifd_send_sync_main-calls.patch [bz#2196295]
- kvm-multifd-Only-flush-once-each-full-round-of-memory.patch [bz#2196295]
- kvm-net-socket-prepare-to-cleanup-net_init_socket.patch [RHEL-582]
- kvm-net-socket-move-fd-type-checking-to-its-own-function.patch [RHEL-582]
- kvm-net-socket-remove-net_init_socket.patch [RHEL-582]
- kvm-pcie-Add-hotplug-detect-state-register-to-cmask.patch [bz#2215819]
- kvm-spec-Build-DBUS-display.patch [bz#2207940]
- Resolves: bz#2176702
  ([RHEL9][virtio-scsi] scsi-hd cannot hot-plug successfully after hot-plug it repeatly)
- Resolves: RHEL-794
  (Backport s390x fixes from QEMU 8.1)
- Resolves: bz#2196295
  (Multifd flushes its channels 10 times per second)
- Resolves: RHEL-582
  ([passt][rhel 9.3] qemu core dump occurs when guest is shutdown after hotunplug/hotplug a passt interface)
- Resolves: bz#2215819
  (Migration test failed while guest with PCIe devices)
- Resolves: bz#2207940
  ([RFE] Enable qemu-ui-dbus subpackage)
This commit is contained in:
Miroslav Rezanina 2023-07-24 02:34:43 -04:00
parent 42a945317b
commit 5e258fbe95
12 changed files with 1311 additions and 1 deletions

View File

@ -0,0 +1,127 @@
From 2a5ea92ca0a5dffad54e4d06a683f683996cea9a Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 21 Jun 2022 12:13:14 +0200
Subject: [PATCH 05/12] multifd: Create property
multifd-flush-after-each-section
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: quintela1 <quintela@redhat.com>
RH-MergeRequest: 186: Multifd flushes its channels 10 times per second
RH-Bugzilla: 2196295
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Leonardo Brás <leobras@redhat.com>
RH-Commit: [1/3] 5bf5348e8be5b1d1629b859ce1ddb7aa0d72c0d6 (juan.quintela/c9s-qemu-kvm)
We used to flush all channels at the end of each RAM section
sent. That is not needed, so preparing to only flush after a full
iteration through all the RAM.
Default value of the property is false. But we return "true" in
migrate_multifd_flush_after_each_section() until we implement the code
in following patches.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
---
Rename each-iteration to after-each-section
Rename multifd-sync-after-each-section to
multifd-flush-after-each-section
Move to machine-8.0 (peter)
conflit hw_compat_8_0 and hw_compat_rhel_9_2
(cherry picked from commit 77c259a4cb1c9799754b48f570301ebf1de5ded8)
---
hw/core/machine.c | 2 ++
migration/migration.h | 12 ++++++++++++
migration/options.c | 13 +++++++++++++
migration/options.h | 1 +
4 files changed, 28 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 5abdc8c39b..5ea52317b9 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -54,6 +54,8 @@ const char *rhel_old_machine_deprecation =
"machine types for previous major releases are deprecated";
GlobalProperty hw_compat_rhel_9_2[] = {
+ /* hw_compat_rhel_9_2 from hw_compat_8_0 */
+ { "migration", "multifd-flush-after-each-section", "on"},
/* hw_compat_rhel_9_2 from hw_compat_7_2 */
{ "e1000e", "migrate-timadj", "off" },
/* hw_compat_rhel_9_2 from hw_compat_7_2 */
diff --git a/migration/migration.h b/migration/migration.h
index 7ccf460aa2..04c78c1fd6 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -411,6 +411,18 @@ struct MigrationState {
*/
bool preempt_pre_7_2;
+ /*
+ * flush every channel after each section sent.
+ *
+ * This assures that we can't mix pages from one iteration through
+ * ram pages with pages for the following iteration. We really
+ * only need to do this flush after we have go through all the
+ * dirty pages. For historical reasons, we do that after each
+ * section. This is suboptimal (we flush too many times).
+ * Default value is false. Setting this property has no effect
+ * until the patch that removes this comment. (since 8.1)
+ */
+ bool multifd_flush_after_each_section;
/*
* This decides the size of guest memory chunk that will be used
* to track dirty bitmap clearing. The size of memory chunk will
diff --git a/migration/options.c b/migration/options.c
index ccd7ef3907..5b0d080ecb 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -88,6 +88,8 @@ Property migration_properties[] = {
send_section_footer, true),
DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
decompress_error_check, true),
+ DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
+ multifd_flush_after_each_section, true),
DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
@@ -344,6 +346,17 @@ bool migrate_zero_copy_send(void)
/* pseudo capabilities */
+bool migrate_multifd_flush_after_each_section(void)
+{
+ MigrationState *s = migrate_get_current();
+
+ /*
+ * Until the patch that remove this comment, we always return that
+ * the property is enabled.
+ */
+ return true || s->multifd_flush_after_each_section;
+}
+
bool migrate_postcopy(void)
{
return migrate_postcopy_ram() || migrate_dirty_bitmaps();
diff --git a/migration/options.h b/migration/options.h
index 0fc7be6869..271f49ae5f 100644
--- a/migration/options.h
+++ b/migration/options.h
@@ -60,6 +60,7 @@ bool migrate_zero_copy_send(void);
* check, but they are not a capability.
*/
+bool migrate_multifd_flush_after_each_section(void);
bool migrate_postcopy(void);
bool migrate_tls(void);
--
2.39.3

View File

@ -0,0 +1,166 @@
From e6f770506091eada46c63ac1c8b934b508e3807f Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 21 Jun 2022 13:36:11 +0200
Subject: [PATCH 07/12] multifd: Only flush once each full round of memory
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: quintela1 <quintela@redhat.com>
RH-MergeRequest: 186: Multifd flushes its channels 10 times per second
RH-Bugzilla: 2196295
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Leonardo Brás <leobras@redhat.com>
RH-Commit: [3/3] 33f76dfc72a2552a42dc7f0fe3923564185a7bf7 (juan.quintela/c9s-qemu-kvm)
We need to add a new flag to mean to flush at that point.
Notice that we still flush at the end of setup and at the end of
complete stages.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
---
Add missing qemu_fflush(), now it passes all tests always.
In the previous version, the check that changes the default value to
false got lost in some rebase. Get it back.
(cherry picked from commit 294e5a4034e81b3d8db03b4e0f691386f20d6ed3)
---
migration/migration.h | 3 +--
migration/options.c | 8 ++------
migration/ram.c | 28 +++++++++++++++++++++++++++-
3 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/migration/migration.h b/migration/migration.h
index 04c78c1fd6..dfec649af8 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -419,8 +419,7 @@ struct MigrationState {
* only need to do this flush after we have go through all the
* dirty pages. For historical reasons, we do that after each
* section. This is suboptimal (we flush too many times).
- * Default value is false. Setting this property has no effect
- * until the patch that removes this comment. (since 8.1)
+ * Default value is false. (since 8.1)
*/
bool multifd_flush_after_each_section;
/*
diff --git a/migration/options.c b/migration/options.c
index 5b0d080ecb..e13c7cb8e5 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -89,7 +89,7 @@ Property migration_properties[] = {
DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
decompress_error_check, true),
DEFINE_PROP_BOOL("multifd-flush-after-each-section", MigrationState,
- multifd_flush_after_each_section, true),
+ multifd_flush_after_each_section, false),
DEFINE_PROP_UINT8("x-clear-bitmap-shift", MigrationState,
clear_bitmap_shift, CLEAR_BITMAP_SHIFT_DEFAULT),
DEFINE_PROP_BOOL("x-preempt-pre-7-2", MigrationState,
@@ -350,11 +350,7 @@ bool migrate_multifd_flush_after_each_section(void)
{
MigrationState *s = migrate_get_current();
- /*
- * Until the patch that remove this comment, we always return that
- * the property is enabled.
- */
- return true || s->multifd_flush_after_each_section;
+ return s->multifd_flush_after_each_section;
}
bool migrate_postcopy(void)
diff --git a/migration/ram.c b/migration/ram.c
index 1e2414d681..e9dcda8b9d 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -86,6 +86,7 @@
#define RAM_SAVE_FLAG_XBZRLE 0x40
/* 0x80 is reserved in qemu-file.h for RAM_SAVE_FLAG_HOOK */
#define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100
+#define RAM_SAVE_FLAG_MULTIFD_FLUSH 0x200
/* We can't use any flag that is bigger than 0x200 */
int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int,
@@ -1581,6 +1582,7 @@ retry:
* associated with the search process.
*
* Returns:
+ * <0: An error happened
* PAGE_ALL_CLEAN: no dirty page found, give up
* PAGE_TRY_AGAIN: no dirty page found, retry for next block
* PAGE_DIRTY_FOUND: dirty page found
@@ -1608,6 +1610,15 @@ static int find_dirty_block(RAMState *rs, PageSearchStatus *pss)
pss->page = 0;
pss->block = QLIST_NEXT_RCU(pss->block, next);
if (!pss->block) {
+ if (!migrate_multifd_flush_after_each_section()) {
+ QEMUFile *f = rs->pss[RAM_CHANNEL_PRECOPY].pss_channel;
+ int ret = multifd_send_sync_main(f);
+ if (ret < 0) {
+ return ret;
+ }
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ qemu_fflush(f);
+ }
/*
* If memory migration starts over, we will meet a dirtied page
* which may still exists in compression threads's ring, so we
@@ -2600,6 +2611,9 @@ static int ram_find_and_save_block(RAMState *rs)
break;
} else if (res == PAGE_TRY_AGAIN) {
continue;
+ } else if (res < 0) {
+ pages = res;
+ break;
}
}
}
@@ -3286,6 +3300,10 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
return ret;
}
+ if (!migrate_multifd_flush_after_each_section()) {
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ }
+
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
qemu_fflush(f);
@@ -3471,6 +3489,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
return ret;
}
+ if (!migrate_multifd_flush_after_each_section()) {
+ qemu_put_be64(f, RAM_SAVE_FLAG_MULTIFD_FLUSH);
+ }
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
qemu_fflush(f);
@@ -4152,7 +4173,9 @@ int ram_load_postcopy(QEMUFile *f, int channel)
}
decompress_data_with_multi_threads(f, page_buffer, len);
break;
-
+ case RAM_SAVE_FLAG_MULTIFD_FLUSH:
+ multifd_recv_sync_main();
+ break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
if (migrate_multifd_flush_after_each_section()) {
@@ -4426,6 +4449,9 @@ static int ram_load_precopy(QEMUFile *f)
break;
}
break;
+ case RAM_SAVE_FLAG_MULTIFD_FLUSH:
+ multifd_recv_sync_main();
+ break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
if (migrate_multifd_flush_after_each_section()) {
--
2.39.3

View File

@ -0,0 +1,78 @@
From c4bfb4900b95e13bef2d86b83c33786c7c4f6289 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Tue, 21 Jun 2022 12:21:32 +0200
Subject: [PATCH 06/12] multifd: Protect multifd_send_sync_main() calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: quintela1 <quintela@redhat.com>
RH-MergeRequest: 186: Multifd flushes its channels 10 times per second
RH-Bugzilla: 2196295
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: Leonardo Brás <leobras@redhat.com>
RH-Commit: [2/3] a91adf59c6b2f39bf4a308f566b00e39cae6e0ae (juan.quintela/c9s-qemu-kvm)
We only need to do that on the ram_save_iterate() call on sending and
on destination when we get a RAM_SAVE_FLAG_EOS.
In setup() and complete() we need to synch in both new and old cases,
so don't add a check there.
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
---
Remove the wrappers that we take out on patch 5.
(cherry picked from commit b05292c237030343516d073b1a1e5f49ffc017a8)
---
migration/ram.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index 01356f60a4..1e2414d681 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3394,9 +3394,11 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
out:
if (ret >= 0
&& migration_is_setup_or_active(migrate_get_current()->state)) {
- ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
- if (ret < 0) {
- return ret;
+ if (migrate_multifd_flush_after_each_section()) {
+ ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel);
+ if (ret < 0) {
+ return ret;
+ }
}
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
@@ -4153,7 +4155,9 @@ int ram_load_postcopy(QEMUFile *f, int channel)
case RAM_SAVE_FLAG_EOS:
/* normal exit */
- multifd_recv_sync_main();
+ if (migrate_multifd_flush_after_each_section()) {
+ multifd_recv_sync_main();
+ }
break;
default:
error_report("Unknown combination of migration flags: 0x%x"
@@ -4424,7 +4428,9 @@ static int ram_load_precopy(QEMUFile *f)
break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
- multifd_recv_sync_main();
+ if (migrate_multifd_flush_after_each_section()) {
+ multifd_recv_sync_main();
+ }
break;
default:
if (flags & RAM_SAVE_FLAG_HOOK) {
--
2.39.3

View File

@ -0,0 +1,78 @@
From d6b3f9e4b388b8d621761104ddf075d6087f6d6c Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
Date: Fri, 9 Jun 2023 09:27:47 +0200
Subject: [PATCH 09/12] net: socket: move fd type checking to its own function
RH-Author: Laurent Vivier <lvivier@redhat.com>
RH-MergeRequest: 187: net: socket: do not close file descriptor if it's not a socket
RH-Jira: RHEL-582
RH-Acked-by: Stefano Brivio <None>
RH-Acked-by: Jason Wang <jasowang@redhat.com>
RH-Acked-by: David Gibson (Red Hat) <dgibson@redhat.com>
RH-Commit: [2/3] 9726f0ae81ac209b5db33dc7767f652867d8ca0a (lvivier/qemu-kvm-centos)
JIRA: https://issues.redhat.com/browse/RHEL-582
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 23455ae341656ca867ee4a171826b9d280d6acb5)
---
net/socket.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index 24dcaa55bc..6b1f0fec3a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -446,16 +446,32 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
return s;
}
+static int net_socket_fd_check(int fd, Error **errp)
+{
+ int so_type, optlen = sizeof(so_type);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
+ (socklen_t *)&optlen) < 0) {
+ error_setg(errp, "can't get socket option SO_TYPE");
+ return -1;
+ }
+ if (so_type != SOCK_DGRAM && so_type != SOCK_STREAM) {
+ error_setg(errp, "socket type=%d for fd=%d must be either"
+ " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
+ return -1;
+ }
+ return so_type;
+}
+
static NetSocketState *net_socket_fd_init(NetClientState *peer,
const char *model, const char *name,
int fd, int is_connected,
const char *mc, Error **errp)
{
- int so_type = -1, optlen=sizeof(so_type);
+ int so_type;
- if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
- (socklen_t *)&optlen)< 0) {
- error_setg(errp, "can't get socket option SO_TYPE");
+ so_type = net_socket_fd_check(fd, errp);
+ if (so_type < 0) {
close(fd);
return NULL;
}
@@ -465,10 +481,6 @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
mc, errp);
case SOCK_STREAM:
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
- default:
- error_setg(errp, "socket type=%d for fd=%d must be either"
- " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
- close(fd);
}
return NULL;
}
--
2.39.3

View File

@ -0,0 +1,60 @@
From a467540e49e76c5961d86e3f47d3f8fcad8cef09 Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
Date: Fri, 9 Jun 2023 09:27:46 +0200
Subject: [PATCH 08/12] net: socket: prepare to cleanup net_init_socket()
RH-Author: Laurent Vivier <lvivier@redhat.com>
RH-MergeRequest: 187: net: socket: do not close file descriptor if it's not a socket
RH-Jira: RHEL-582
RH-Acked-by: Stefano Brivio <None>
RH-Acked-by: Jason Wang <jasowang@redhat.com>
RH-Acked-by: David Gibson (Red Hat) <dgibson@redhat.com>
RH-Commit: [1/3] 3e4f8370586ae1ac2474fef971a239edb31eeb67 (lvivier/qemu-kvm-centos)
JIRA: https://issues.redhat.com/browse/RHEL-582
Use directly net_socket_fd_init_stream() and net_socket_fd_init_dgram()
when the socket type is already known.
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 006c3fa74c3edb978ff46d2851699e9a95609da5)
---
net/socket.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index ba6e5b0b00..24dcaa55bc 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -587,7 +587,7 @@ static int net_socket_connect_init(NetClientState *peer,
break;
}
}
- s = net_socket_fd_init(peer, model, name, fd, connected, NULL, errp);
+ s = net_socket_fd_init_stream(peer, model, name, fd, connected);
if (!s) {
return -1;
}
@@ -629,7 +629,7 @@ static int net_socket_mcast_init(NetClientState *peer,
return -1;
}
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
+ s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp);
if (!s) {
return -1;
}
@@ -683,7 +683,7 @@ static int net_socket_udp_init(NetClientState *peer,
}
qemu_socket_set_nonblock(fd);
- s = net_socket_fd_init(peer, model, name, fd, 0, NULL, errp);
+ s = net_socket_fd_init_dgram(peer, model, name, fd, 0, NULL, errp);
if (!s) {
return -1;
}
--
2.39.3

View File

@ -0,0 +1,102 @@
From ecb4f97895849c562112b76a30ddc2037e8df79e Mon Sep 17 00:00:00 2001
From: Laurent Vivier <lvivier@redhat.com>
Date: Fri, 9 Jun 2023 09:27:48 +0200
Subject: [PATCH 10/12] net: socket: remove net_init_socket()
RH-Author: Laurent Vivier <lvivier@redhat.com>
RH-MergeRequest: 187: net: socket: do not close file descriptor if it's not a socket
RH-Jira: RHEL-582
RH-Acked-by: Stefano Brivio <None>
RH-Acked-by: Jason Wang <jasowang@redhat.com>
RH-Acked-by: David Gibson (Red Hat) <dgibson@redhat.com>
RH-Commit: [3/3] e1d7939f5df4a77c2fff62d1ae4899a7a3615ad9 (lvivier/qemu-kvm-centos)
JIRA: https://issues.redhat.com/browse/RHEL-582
Move the file descriptor type checking before doing anything with it.
If it's not usable, don't close it as it could be in use by another
part of QEMU, only fail and report an error.
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit b6aeee02980e193f744f74c48fd900940feb2799)
---
net/socket.c | 43 +++++++++++++++++--------------------------
1 file changed, 17 insertions(+), 26 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index 6b1f0fec3a..8e3702e1f3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -463,28 +463,6 @@ static int net_socket_fd_check(int fd, Error **errp)
return so_type;
}
-static NetSocketState *net_socket_fd_init(NetClientState *peer,
- const char *model, const char *name,
- int fd, int is_connected,
- const char *mc, Error **errp)
-{
- int so_type;
-
- so_type = net_socket_fd_check(fd, errp);
- if (so_type < 0) {
- close(fd);
- return NULL;
- }
- switch(so_type) {
- case SOCK_DGRAM:
- return net_socket_fd_init_dgram(peer, model, name, fd, is_connected,
- mc, errp);
- case SOCK_STREAM:
- return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
- }
- return NULL;
-}
-
static void net_socket_accept(void *opaque)
{
NetSocketState *s = opaque;
@@ -728,21 +706,34 @@ int net_init_socket(const Netdev *netdev, const char *name,
}
if (sock->fd) {
- int fd, ret;
+ int fd, ret, so_type;
fd = monitor_fd_param(monitor_cur(), sock->fd, errp);
if (fd == -1) {
return -1;
}
+ so_type = net_socket_fd_check(fd, errp);
+ if (so_type < 0) {
+ return -1;
+ }
ret = qemu_socket_try_set_nonblock(fd);
if (ret < 0) {
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
name, fd);
return -1;
}
- if (!net_socket_fd_init(peer, "socket", name, fd, 1, sock->mcast,
- errp)) {
- return -1;
+ switch (so_type) {
+ case SOCK_DGRAM:
+ if (!net_socket_fd_init_dgram(peer, "socket", name, fd, 1,
+ sock->mcast, errp)) {
+ return -1;
+ }
+ break;
+ case SOCK_STREAM:
+ if (!net_socket_fd_init_stream(peer, "socket", name, fd, 1)) {
+ return -1;
+ }
+ break;
}
return 0;
}
--
2.39.3

View File

@ -0,0 +1,87 @@
From 2732b6c5ef249d3ec9affca66768cc2fc476ff7c Mon Sep 17 00:00:00 2001
From: Leonardo Bras <leobras@redhat.com>
Date: Thu, 6 Jul 2023 01:55:47 -0300
Subject: [PATCH 11/12] pcie: Add hotplug detect state register to cmask
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Leonardo Brás <leobras@redhat.com>
RH-MergeRequest: 188: pcie: Add hotplug detect state register to cmask
RH-Bugzilla: 2215819
RH-Acked-by: Peter Xu <peterx@redhat.com>
RH-Acked-by: quintela1 <quintela@redhat.com>
RH-Commit: [1/1] a125fa337711bddbc957c399044393e82272b143 (LeoBras/centos-qemu-kvm)
When trying to migrate a machine type pc-q35-6.0 or lower, with this
cmdline options,
-device driver=pcie-root-port,port=18,chassis=19,id=pcie-root-port18,bus=pcie.0,addr=0x12 \
-device driver=nec-usb-xhci,p2=4,p3=4,id=nex-usb-xhci0,bus=pcie-root-port18,addr=0x12.0x1
the following bug happens after all ram pages were sent:
qemu-kvm: get_pci_config_device: Bad config data: i=0x6e read: 0 device: 40 cmask: ff wmask: 0 w1cmask:19
qemu-kvm: Failed to load PCIDevice:config
qemu-kvm: Failed to load pcie-root-port:parent_obj.parent_obj.parent_obj
qemu-kvm: error while loading state for instance 0x0 of device '0000:00:12.0/pcie-root-port'
qemu-kvm: load of migration failed: Invalid argument
This happens on pc-q35-6.0 or lower because of:
{ "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" }
In this scenario, hotplug_handler_plug() calls pcie_cap_slot_plug_cb(),
which sets dev->config byte 0x6e with bit PCI_EXP_SLTSTA_PDS to signal PCI
hotplug for the guest. After a while the guest will deal with this hotplug
and qemu will clear the above bit.
Then, during migration, get_pci_config_device() will compare the
configs of both the freshly created device and the one that is being
received via migration, which will differ due to the PCI_EXP_SLTSTA_PDS bit
and cause the bug to reproduce.
To avoid this fake incompatibility, there are tree fields in PCIDevice that
can help:
- wmask: Used to implement R/W bytes, and
- w1cmask: Used to implement RW1C(Write 1 to Clear) bytes
- cmask: Used to enable config checks on load.
According to PCI Express® Base Specification Revision 5.0 Version 1.0,
table 7-27 (Slot Status Register) bit 6, the "Presence Detect State" is
listed as RO (read-only), so it only makes sense to make use of the cmask
field.
So, clear PCI_EXP_SLTSTA_PDS bit on cmask, so the fake incompatibility on
get_pci_config_device() does not abort the migration.
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2215819
Signed-off-by: Leonardo Bras <leobras@redhat.com>
Message-Id: <20230706045546.593605-3-leobras@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 625b370c45f4acd155ee625d61c0057d770a5b5e)
Signed-off-by: Leonardo Bras <leobras@redhat.com>
---
hw/pci/pcie.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index b8c24cf45f..8bc4a4ee57 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -659,6 +659,10 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
pci_word_test_and_set_mask(dev->w1cmask + pos + PCI_EXP_SLTSTA,
PCI_EXP_HP_EV_SUPPORTED);
+ /* Avoid migration abortion when this device hot-removed by guest */
+ pci_word_test_and_clear_mask(dev->cmask + pos + PCI_EXP_SLTSTA,
+ PCI_EXP_SLTSTA_PDS);
+
dev->exp.hpev_notified = false;
qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))),
--
2.39.3

View File

@ -0,0 +1,220 @@
From 41987ce0dd79d8734088002cbd34f20704dd017a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
Date: Mon, 17 Jul 2023 17:36:07 +0200
Subject: [PATCH 04/12] s390x/ap: Wire up the device request notifier interface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Cédric Le Goater <clg@redhat.com>
RH-MergeRequest: 185: Backport s390x fixes from QEMU 8.1
RH-Jira: RHEL-794
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Commit: [1/1] ab6c912a1b8cdb584adacac16af79352fdfe7355 (clegoate/qemu-kvm-c9s)
Jira: https://issues.redhat.com/browse/RHEL-794
commit 1360b2ad1f673d32a09de5826cd71ecd0510164a
Author: Tony Krowiak <akrowiak@linux.ibm.com>
Date: Fri Jun 2 10:11:25 2023 -0400
s390x/ap: Wire up the device request notifier interface
Let's wire up the device request notifier interface to handle device unplug
requests for AP.
Signed-off-by: Tony Krowiak <akrowiak@linux.ibm.com>
Link: https://lore.kernel.org/qemu-devel/20230530225544.280031-1-akrowiak@linux.ibm.com/
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Backport note:
- linux-headers/linux/vfio.h
updated to v6.5-rc1 level for VFIO_AP_REQ_IRQ_INDEX definition
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
hw/vfio/ap.c | 113 +++++++++++++++++++++++++++++++++++++
linux-headers/linux/vfio.h | 9 +++
2 files changed, 122 insertions(+)
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index e0dd561e85..6e21d1da5a 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -18,6 +18,8 @@
#include "hw/vfio/vfio-common.h"
#include "hw/s390x/ap-device.h"
#include "qemu/error-report.h"
+#include "qemu/event_notifier.h"
+#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -33,6 +35,7 @@
struct VFIOAPDevice {
APDevice apdev;
VFIODevice vdev;
+ EventNotifier req_notifier;
};
OBJECT_DECLARE_SIMPLE_TYPE(VFIOAPDevice, VFIO_AP_DEVICE)
@@ -84,10 +87,110 @@ static VFIOGroup *vfio_ap_get_group(VFIOAPDevice *vapdev, Error **errp)
return vfio_get_group(groupid, &address_space_memory, errp);
}
+static void vfio_ap_req_notifier_handler(void *opaque)
+{
+ VFIOAPDevice *vapdev = opaque;
+ Error *err = NULL;
+
+ if (!event_notifier_test_and_clear(&vapdev->req_notifier)) {
+ return;
+ }
+
+ qdev_unplug(DEVICE(vapdev), &err);
+
+ if (err) {
+ warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name);
+ }
+}
+
+static void vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev,
+ unsigned int irq, Error **errp)
+{
+ int fd;
+ size_t argsz;
+ IOHandler *fd_read;
+ EventNotifier *notifier;
+ struct vfio_irq_info *irq_info;
+ VFIODevice *vdev = &vapdev->vdev;
+
+ switch (irq) {
+ case VFIO_AP_REQ_IRQ_INDEX:
+ notifier = &vapdev->req_notifier;
+ fd_read = vfio_ap_req_notifier_handler;
+ break;
+ default:
+ error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
+ return;
+ }
+
+ if (vdev->num_irqs < irq + 1) {
+ error_setg(errp, "vfio: IRQ %u not available (number of irqs %u)",
+ irq, vdev->num_irqs);
+ return;
+ }
+
+ argsz = sizeof(*irq_info);
+ irq_info = g_malloc0(argsz);
+ irq_info->index = irq;
+ irq_info->argsz = argsz;
+
+ if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO,
+ irq_info) < 0 || irq_info->count < 1) {
+ error_setg_errno(errp, errno, "vfio: Error getting irq info");
+ goto out_free_info;
+ }
+
+ if (event_notifier_init(notifier, 0)) {
+ error_setg_errno(errp, errno,
+ "vfio: Unable to init event notifier for irq (%d)",
+ irq);
+ goto out_free_info;
+ }
+
+ fd = event_notifier_get_fd(notifier);
+ qemu_set_fd_handler(fd, fd_read, NULL, vapdev);
+
+ if (vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd,
+ errp)) {
+ qemu_set_fd_handler(fd, NULL, NULL, vapdev);
+ event_notifier_cleanup(notifier);
+ }
+
+out_free_info:
+ g_free(irq_info);
+
+}
+
+static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev,
+ unsigned int irq)
+{
+ Error *err = NULL;
+ EventNotifier *notifier;
+
+ switch (irq) {
+ case VFIO_AP_REQ_IRQ_INDEX:
+ notifier = &vapdev->req_notifier;
+ break;
+ default:
+ error_report("vfio: Unsupported device irq(%d)", irq);
+ return;
+ }
+
+ if (vfio_set_irq_signaling(&vapdev->vdev, irq, 0,
+ VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) {
+ warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name);
+ }
+
+ qemu_set_fd_handler(event_notifier_get_fd(notifier),
+ NULL, NULL, vapdev);
+ event_notifier_cleanup(notifier);
+}
+
static void vfio_ap_realize(DeviceState *dev, Error **errp)
{
int ret;
char *mdevid;
+ Error *err = NULL;
VFIOGroup *vfio_group;
APDevice *apdev = AP_DEVICE(dev);
VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
@@ -116,6 +219,15 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
goto out_get_dev_err;
}
+ vfio_ap_register_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX, &err);
+ if (err) {
+ /*
+ * Report this error, but do not make it a failing condition.
+ * Lack of this IRQ in the host does not prevent normal operation.
+ */
+ error_report_err(err);
+ }
+
return;
out_get_dev_err:
@@ -129,6 +241,7 @@ static void vfio_ap_unrealize(DeviceState *dev)
VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
VFIOGroup *group = vapdev->vdev.group;
+ vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX);
vfio_ap_put_device(vapdev);
vfio_put_group(group);
}
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index c59692ce0b..ce464957c8 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -642,6 +642,15 @@ enum {
VFIO_CCW_NUM_IRQS
};
+/*
+ * The vfio-ap bus driver makes use of the following IRQ index mapping.
+ * Unimplemented IRQ types return a count of zero.
+ */
+enum {
+ VFIO_AP_REQ_IRQ_INDEX,
+ VFIO_AP_NUM_IRQS
+};
+
/**
* VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 12,
* struct vfio_pci_hot_reset_info)
--
2.39.3

View File

@ -0,0 +1,81 @@
From 5dd7d26c034c26b2d4d9b91b8d1a7b605e19730f Mon Sep 17 00:00:00 2001
From: Stefano Garzarella <sgarzare@redhat.com>
Date: Wed, 12 Jul 2023 15:43:51 +0200
Subject: [PATCH 02/12] scsi: cleanup scsi_clear_unit_attention()
RH-Author: Stefano Garzarella <sgarzare@redhat.com>
RH-MergeRequest: 184: scsi: fix issue with Linux guest and unit attention
RH-Bugzilla: 2176702
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [2/3] b3a06a91644e44fae3d76d0fbe72448652db517a (sgarzarella/qemu-kvm-c-9-s)
The previous commit moved the unit attention clearing when we create
the request. So now we can clean scsi_clear_unit_attention() to handle
only the case of the REPORT LUNS command: this is the only case in
which a UNIT ATTENTION is cleared without having been reported.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-ID: <20230712134352.118655-3-sgarzare@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ba947dab98e7cd4337c70975bd255701a2a6aad8)
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
hw/scsi/scsi-bus.c | 28 ++++++----------------------
1 file changed, 6 insertions(+), 22 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 5d22313b9d..cecd26479e 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -828,26 +828,12 @@ static void scsi_clear_unit_attention(SCSIRequest *req)
return;
}
- if (req->dev->unit_attention.key != UNIT_ATTENTION &&
- req->bus->unit_attention.key != UNIT_ATTENTION) {
- return;
- }
-
- /*
- * If an INQUIRY command enters the enabled command state,
- * the device server shall [not] clear any unit attention condition;
- * See also MMC-6, paragraphs 6.5 and 6.6.2.
- */
- if (req->cmd.buf[0] == INQUIRY ||
- req->cmd.buf[0] == GET_CONFIGURATION ||
- req->cmd.buf[0] == GET_EVENT_STATUS_NOTIFICATION) {
- return;
- }
-
if (req->dev->unit_attention.key == UNIT_ATTENTION) {
ua = &req->dev->unit_attention;
- } else {
+ } else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
ua = &req->bus->unit_attention;
+ } else {
+ return;
}
/*
@@ -856,12 +842,10 @@ static void scsi_clear_unit_attention(SCSIRequest *req)
* with an additional sense code of REPORTED LUNS DATA HAS CHANGED.
*/
if (req->cmd.buf[0] == REPORT_LUNS &&
- !(ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
- ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) {
- return;
+ ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
+ ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq) {
+ *ua = SENSE_CODE(NO_SENSE);
}
-
- *ua = SENSE_CODE(NO_SENSE);
}
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
--
2.39.3

View File

@ -0,0 +1,110 @@
From 0a784c45a7b7ee32c36bf86eebb24c8431a89f49 Mon Sep 17 00:00:00 2001
From: Stefano Garzarella <sgarzare@redhat.com>
Date: Wed, 12 Jul 2023 15:43:52 +0200
Subject: [PATCH 03/12] scsi: clear unit attention only for REPORT LUNS
commands
RH-Author: Stefano Garzarella <sgarzare@redhat.com>
RH-MergeRequest: 184: scsi: fix issue with Linux guest and unit attention
RH-Bugzilla: 2176702
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [3/3] 01d5e112ef9ae204d96ceb01b4a453fdb4e8b669 (sgarzarella/qemu-kvm-c-9-s)
scsi_clear_unit_attention() now only handles REPORTED LUNS DATA HAS
CHANGED.
This only happens when we handle REPORT LUNS commands, so let's rename
the function in scsi_clear_reported_luns_changed() and call it only in
scsi_target_emulate_report_luns().
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-ID: <20230712134352.118655-4-sgarzare@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2eb5599e8a73e70a9e86a97120818ff95a43a23a)
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
hw/scsi/scsi-bus.c | 34 +++++++++++-----------------------
1 file changed, 11 insertions(+), 23 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index cecd26479e..9542410800 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -22,6 +22,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev);
static void scsi_req_dequeue(SCSIRequest *req);
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
static void scsi_target_free_buf(SCSIRequest *req);
+static void scsi_clear_reported_luns_changed(SCSIRequest *req);
static int next_scsi_bus;
@@ -518,6 +519,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
/* store the LUN list length */
stl_be_p(&r->buf[0], len - 8);
+
+ /*
+ * If a REPORT LUNS command enters the enabled command state, [...]
+ * the device server shall clear any pending unit attention condition
+ * with an additional sense code of REPORTED LUNS DATA HAS CHANGED.
+ */
+ scsi_clear_reported_luns_changed(&r->req);
+
return true;
}
@@ -816,18 +825,10 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
return req->ops->get_buf(req);
}
-static void scsi_clear_unit_attention(SCSIRequest *req)
+static void scsi_clear_reported_luns_changed(SCSIRequest *req)
{
SCSISense *ua;
- /*
- * scsi_fetch_unit_attention_sense() already cleaned the unit attention
- * in this case.
- */
- if (req->ops == &reqops_unit_attention) {
- return;
- }
-
if (req->dev->unit_attention.key == UNIT_ATTENTION) {
ua = &req->dev->unit_attention;
} else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
@@ -836,13 +837,7 @@ static void scsi_clear_unit_attention(SCSIRequest *req)
return;
}
- /*
- * If a REPORT LUNS command enters the enabled command state, [...]
- * the device server shall clear any pending unit attention condition
- * with an additional sense code of REPORTED LUNS DATA HAS CHANGED.
- */
- if (req->cmd.buf[0] == REPORT_LUNS &&
- ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
+ if (ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq) {
*ua = SENSE_CODE(NO_SENSE);
}
@@ -1528,13 +1523,6 @@ void scsi_req_complete(SCSIRequest *req, int status)
req->dev->sense_is_ua = false;
}
- /*
- * Unit attention state is now stored in the device's sense buffer
- * if the HBA didn't do autosense. Clear the pending unit attention
- * flags.
- */
- scsi_clear_unit_attention(req);
-
scsi_req_ref(req);
scsi_req_dequeue(req);
req->bus->info->complete(req, req->residual);
--
2.39.3

View File

@ -0,0 +1,132 @@
From 562ea3a2d602cf41c548f3ddf52c43c04fded347 Mon Sep 17 00:00:00 2001
From: Stefano Garzarella <sgarzare@redhat.com>
Date: Wed, 12 Jul 2023 15:43:50 +0200
Subject: [PATCH 01/12] scsi: fetch unit attention when creating the request
RH-Author: Stefano Garzarella <sgarzare@redhat.com>
RH-MergeRequest: 184: scsi: fix issue with Linux guest and unit attention
RH-Bugzilla: 2176702
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Commit: [1/3] 04563caac45d0110ea65eda8e55472556cd317c0 (sgarzarella/qemu-kvm-c-9-s)
Commit 1880ad4f4e ("virtio-scsi: Batched prepare for cmd reqs") split
calls to scsi_req_new() and scsi_req_enqueue() in the virtio-scsi device.
No ill effects were observed until commit 8cc5583abe ("virtio-scsi: Send
"REPORTED LUNS CHANGED" sense data upon disk hotplug events") added a
unit attention that was easy to trigger with device hotplug and
hot-unplug.
Because the two calls were separated, all requests in the batch were
prepared calling scsi_req_new() to report a sense. The first one
submitted would report the right sense and reset it to NO_SENSE, while
the others reported CHECK_CONDITION with no sense data. This caused
SCSI errors in Linux.
To solve this issue, let's fetch the unit attention as early as possible
when we prepare the request, so that only the first request in the batch
will use the unit attention SCSIReqOps and the others will not report
CHECK CONDITION.
Fixes: 1880ad4f4e ("virtio-scsi: Batched prepare for cmd reqs")
Fixes: 8cc5583abe ("virtio-scsi: Send "REPORTED LUNS CHANGED" sense data upon disk hotplug events")
Reported-by: Thomas Huth <thuth@redhat.com>
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2176702
Co-developed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-ID: <20230712134352.118655-2-sgarzare@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9472083e642bfb9bc836b38662baddd9bc964ebc)
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
hw/scsi/scsi-bus.c | 36 +++++++++++++++++++++++++++++++++---
include/hw/scsi/scsi.h | 1 +
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 3c20b47ad0..5d22313b9d 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -413,19 +413,35 @@ static const struct SCSIReqOps reqops_invalid_opcode = {
/* SCSIReqOps implementation for unit attention conditions. */
-static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+static void scsi_fetch_unit_attention_sense(SCSIRequest *req)
{
+ SCSISense *ua = NULL;
+
if (req->dev->unit_attention.key == UNIT_ATTENTION) {
- scsi_req_build_sense(req, req->dev->unit_attention);
+ ua = &req->dev->unit_attention;
} else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
- scsi_req_build_sense(req, req->bus->unit_attention);
+ ua = &req->bus->unit_attention;
}
+
+ /*
+ * Fetch the unit attention sense immediately so that another
+ * scsi_req_new does not use reqops_unit_attention.
+ */
+ if (ua) {
+ scsi_req_build_sense(req, *ua);
+ *ua = SENSE_CODE(NO_SENSE);
+ }
+}
+
+static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+{
scsi_req_complete(req, CHECK_CONDITION);
return 0;
}
static const struct SCSIReqOps reqops_unit_attention = {
.size = sizeof(SCSIRequest),
+ .init_req = scsi_fetch_unit_attention_sense,
.send_command = scsi_unit_attention
};
@@ -699,6 +715,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
object_ref(OBJECT(d));
object_ref(OBJECT(qbus->parent));
notifier_list_init(&req->cancel_notifiers);
+
+ if (reqops->init_req) {
+ reqops->init_req(req);
+ }
+
trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
return req;
}
@@ -798,6 +819,15 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
static void scsi_clear_unit_attention(SCSIRequest *req)
{
SCSISense *ua;
+
+ /*
+ * scsi_fetch_unit_attention_sense() already cleaned the unit attention
+ * in this case.
+ */
+ if (req->ops == &reqops_unit_attention) {
+ return;
+ }
+
if (req->dev->unit_attention.key != UNIT_ATTENTION &&
req->bus->unit_attention.key != UNIT_ATTENTION) {
return;
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 6f23a7a73e..1787ddd01e 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -108,6 +108,7 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
/* scsi-bus.c */
struct SCSIReqOps {
size_t size;
+ void (*init_req)(SCSIRequest *req);
void (*free_req)(SCSIRequest *req);
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
--
2.39.3

View File

@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
Summary: QEMU is a machine emulator and virtualizer
Name: qemu-kvm
Version: 8.0.0
Release: 8%{?rcrel}%{?dist}%{?cc_suffix}
Release: 9%{?rcrel}%{?dist}%{?cc_suffix}
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
# Epoch 15 used for RHEL 8
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
@ -446,6 +446,28 @@ Patch144: kvm-pc-bios-s390-ccw-Don-t-use-__bss_start-with-the-larl.patch
Patch145: kvm-ui-Fix-pixel-colour-channel-order-for-PNG-screenshot.patch
# For bz#2213317 - Enable libblkio-based block drivers in QEMU
Patch146: kvm-block-blkio-fix-module_block.py-parsing.patch
# For bz#2176702 - [RHEL9][virtio-scsi] scsi-hd cannot hot-plug successfully after hot-plug it repeatly
Patch147: kvm-scsi-fetch-unit-attention-when-creating-the-request.patch
# For bz#2176702 - [RHEL9][virtio-scsi] scsi-hd cannot hot-plug successfully after hot-plug it repeatly
Patch148: kvm-scsi-cleanup-scsi_clear_unit_attention.patch
# For bz#2176702 - [RHEL9][virtio-scsi] scsi-hd cannot hot-plug successfully after hot-plug it repeatly
Patch149: kvm-scsi-clear-unit-attention-only-for-REPORT-LUNS-comma.patch
# For RHEL-794 - Backport s390x fixes from QEMU 8.1
Patch150: kvm-s390x-ap-Wire-up-the-device-request-notifier-interfa.patch
# For bz#2196295 - Multifd flushes its channels 10 times per second
Patch151: kvm-multifd-Create-property-multifd-flush-after-each-sec.patch
# For bz#2196295 - Multifd flushes its channels 10 times per second
Patch152: kvm-multifd-Protect-multifd_send_sync_main-calls.patch
# For bz#2196295 - Multifd flushes its channels 10 times per second
Patch153: kvm-multifd-Only-flush-once-each-full-round-of-memory.patch
# For RHEL-582 - [passt][rhel 9.3] qemu core dump occurs when guest is shutdown after hotunplug/hotplug a passt interface
Patch154: kvm-net-socket-prepare-to-cleanup-net_init_socket.patch
# For RHEL-582 - [passt][rhel 9.3] qemu core dump occurs when guest is shutdown after hotunplug/hotplug a passt interface
Patch155: kvm-net-socket-move-fd-type-checking-to-its-own-function.patch
# For RHEL-582 - [passt][rhel 9.3] qemu core dump occurs when guest is shutdown after hotunplug/hotplug a passt interface
Patch156: kvm-net-socket-remove-net_init_socket.patch
# For bz#2215819 - Migration test failed while guest with PCIe devices
Patch157: kvm-pcie-Add-hotplug-detect-state-register-to-cmask.patch
%if %{have_clang}
BuildRequires: clang
@ -757,6 +779,19 @@ Obsoletes: %{name}-hw-usbredir <= %{epoch}:%{version}
This package provides usbredir support.
%endif
%package ui-dbus
Summary: QEMU D-Bus UI driver
Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release}
%description ui-dbus
This package provides the additional D-Bus UI for QEMU.
%package audio-dbus
Summary: QEMU D-Bus audio driver
Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release}
Requires: %{name}-ui-dbus = %{epoch}:%{version}-%{release}
%description audio-dbus
This package provides the additional D-Bus audio driver for QEMU.
%prep
%setup -q -n qemu-%{version}%{?rcstr}
%autopatch -p1
@ -959,11 +994,13 @@ run_configure \
--enable-capstone \
--enable-coroutine-pool \
--enable-curl \
--enable-dbus-display \
--enable-debug-info \
--enable-docs \
%if %{have_fdt}
--enable-fdt=system \
%endif
--enable-gio \
--enable-gnutls \
--enable-guest-agent \
--enable-iconv \
@ -1482,10 +1519,42 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
%{_libdir}/%{name}/hw-usb-redirect.so
%endif
%files audio-dbus
%{_libdir}/%{name}/audio-dbus.so
%files ui-dbus
%{_libdir}/%{name}/ui-dbus.so
# endif !tools_only
%endif
%changelog
* Mon Jul 24 2023 Miroslav Rezanina <mrezanin@redhat.com> - 8.0.0-9
- kvm-scsi-fetch-unit-attention-when-creating-the-request.patch [bz#2176702]
- kvm-scsi-cleanup-scsi_clear_unit_attention.patch [bz#2176702]
- kvm-scsi-clear-unit-attention-only-for-REPORT-LUNS-comma.patch [bz#2176702]
- kvm-s390x-ap-Wire-up-the-device-request-notifier-interfa.patch [RHEL-794]
- kvm-multifd-Create-property-multifd-flush-after-each-sec.patch [bz#2196295]
- kvm-multifd-Protect-multifd_send_sync_main-calls.patch [bz#2196295]
- kvm-multifd-Only-flush-once-each-full-round-of-memory.patch [bz#2196295]
- kvm-net-socket-prepare-to-cleanup-net_init_socket.patch [RHEL-582]
- kvm-net-socket-move-fd-type-checking-to-its-own-function.patch [RHEL-582]
- kvm-net-socket-remove-net_init_socket.patch [RHEL-582]
- kvm-pcie-Add-hotplug-detect-state-register-to-cmask.patch [bz#2215819]
- kvm-spec-Build-DBUS-display.patch [bz#2207940]
- Resolves: bz#2176702
([RHEL9][virtio-scsi] scsi-hd cannot hot-plug successfully after hot-plug it repeatly)
- Resolves: RHEL-794
(Backport s390x fixes from QEMU 8.1)
- Resolves: bz#2196295
(Multifd flushes its channels 10 times per second)
- Resolves: RHEL-582
([passt][rhel 9.3] qemu core dump occurs when guest is shutdown after hotunplug/hotplug a passt interface)
- Resolves: bz#2215819
(Migration test failed while guest with PCIe devices)
- Resolves: bz#2207940
([RFE] Enable qemu-ui-dbus subpackage)
* Mon Jul 17 2023 Miroslav Rezanina <mrezanin@redhat.com> - 8.0.0-8
- kvm-virtio-iommu-Fix-64kB-host-page-size-VFIO-device-ass.patch [bz#2211609 bz#2211634]
- kvm-virtio-iommu-Rework-the-traces-in-virtio_iommu_set_p.patch [bz#2211609 bz#2211634]