* [PULL 01/25] tests/qemu-iotests: Mark 182 as Linux-only
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 02/25] tests/functional: Don't try to run functional tests on Windows Thomas Huth
` (24 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Daniel P. Berrangé
From: Thomas Huth <thuth@redhat.com>
Running test 182 on FreeBSD fails with this error message in the output:
+warning: File lock requested but OFD locking syscall is unavailable, falling back to POSIX file locks
+Due to the implementation, locks can be lost unexpectedly.
OFD locks seem to be only available on Linux, so let's mark this
test as Linux-only to silence the failure.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20260113141744.97469-1-thuth@redhat.com>
---
tests/qemu-iotests/182 | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
index bbd1132b052..af5eeb599c1 100755
--- a/tests/qemu-iotests/182
+++ b/tests/qemu-iotests/182
@@ -43,6 +43,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
+_supported_os Linux
size=32M
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 02/25] tests/functional: Don't try to run functional tests on Windows
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
2026-03-10 5:55 ` [PULL 01/25] tests/qemu-iotests: Mark 182 as Linux-only Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 03/25] tests/functional/ppc/test_40: Fix the URL of the NetBSD-7.1.2-prep.iso asset Thomas Huth
` (23 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
From: Thomas Huth <thuth@redhat.com>
They just don't work there yet, so don't try to run them there
(these need some development work from a Windows wizard first).
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20260216103924.39493-1-thuth@redhat.com>
---
tests/functional/meson.build | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index b979cff2b97..9bec5a07516 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -4,8 +4,9 @@
# (e.g. tests that fetch assets from the internet) should be put into
# the 'thorough' category instead.
-# Most tests run too slow with TCI enabled, so skip the functional tests there
-if get_option('tcg_interpreter')
+# Most tests run too slow with TCI enabled, and they haven't been adapted
+# to Windows yet, so skip the functional tests in these environments
+if get_option('tcg_interpreter') or host_os == 'windows'
subdir_done()
endif
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 03/25] tests/functional/ppc/test_40: Fix the URL of the NetBSD-7.1.2-prep.iso asset
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
2026-03-10 5:55 ` [PULL 01/25] tests/qemu-iotests: Mark 182 as Linux-only Thomas Huth
2026-03-10 5:55 ` [PULL 02/25] tests/functional: Don't try to run functional tests on Windows Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-19 17:41 ` Peter Maydell
2026-03-10 5:55 ` [PULL 04/25] tests/functional/x86_64: Disable memlock test for asan builds Thomas Huth
` (22 subsequent siblings)
25 siblings, 1 reply; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Reinoud Zandijk
From: Thomas Huth <thuth@redhat.com>
We now need a slightly different URL to be able to download this asset.
Suggested-by: Reinoud Zandijk <reinoud@NetBSD.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20260212143843.287090-1-thuth@redhat.com>
---
tests/functional/ppc/test_40p.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/functional/ppc/test_40p.py b/tests/functional/ppc/test_40p.py
index 614972a7eb3..ed272147f6e 100755
--- a/tests/functional/ppc/test_40p.py
+++ b/tests/functional/ppc/test_40p.py
@@ -27,7 +27,7 @@ class IbmPrep40pMachine(QemuSystemTest):
'f86236e9d01b3f0dd0f5d3b8d5bbd40c68e78b4db560a108358f5ad58e636619')
ASSET_NETBSD71 = Asset(
('https://archive.netbsd.org/pub/NetBSD-archive/'
- 'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso'),
+ 'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso?key=NetBSD'),
'cc7cb290b06aaa839362deb7bd9f417ac5015557db24088508330f76c3f825ec')
# 12H0455 PPS Firmware Licensed Materials
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PULL 03/25] tests/functional/ppc/test_40: Fix the URL of the NetBSD-7.1.2-prep.iso asset
2026-03-10 5:55 ` [PULL 03/25] tests/functional/ppc/test_40: Fix the URL of the NetBSD-7.1.2-prep.iso asset Thomas Huth
@ 2026-03-19 17:41 ` Peter Maydell
0 siblings, 0 replies; 28+ messages in thread
From: Peter Maydell @ 2026-03-19 17:41 UTC (permalink / raw)
To: Thomas Huth; +Cc: qemu-devel, Reinoud Zandijk
On Tue, 10 Mar 2026 at 05:55, Thomas Huth <thuth@redhat.com> wrote:
>
> From: Thomas Huth <thuth@redhat.com>
>
> We now need a slightly different URL to be able to download this asset.
>
> Suggested-by: Reinoud Zandijk <reinoud@NetBSD.org>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> Message-ID: <20260212143843.287090-1-thuth@redhat.com>
> ---
> tests/functional/ppc/test_40p.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/functional/ppc/test_40p.py b/tests/functional/ppc/test_40p.py
> index 614972a7eb3..ed272147f6e 100755
> --- a/tests/functional/ppc/test_40p.py
> +++ b/tests/functional/ppc/test_40p.py
> @@ -27,7 +27,7 @@ class IbmPrep40pMachine(QemuSystemTest):
> 'f86236e9d01b3f0dd0f5d3b8d5bbd40c68e78b4db560a108358f5ad58e636619')
> ASSET_NETBSD71 = Asset(
> ('https://archive.netbsd.org/pub/NetBSD-archive/'
> - 'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso'),
> + 'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso?key=NetBSD'),
> 'cc7cb290b06aaa839362deb7bd9f417ac5015557db24088508330f76c3f825ec')
My local machine has been sat downloading this file very very
slowly for the last half an hour. Is there somewhere that
we can get the asset from that manages faster downloads?
thanks
-- PMM
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PULL 04/25] tests/functional/x86_64: Disable memlock test for asan builds
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (2 preceding siblings ...)
2026-03-10 5:55 ` [PULL 03/25] tests/functional/ppc/test_40: Fix the URL of the NetBSD-7.1.2-prep.iso asset Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 05/25] tests/functional/migration: Use socket_dir Thomas Huth
` (21 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Pierrick Bouvier
From: Peter Maydell <peter.maydell@linaro.org>
The address-sanitizer intercepts mlock() and makes it a no-op,
because it interacts badly with the sanitizer's own use of large
amounts of memory. This means that our 'memlock' test will always
fail, because it checks via /proc for whether the QEMU process really
locked some pages. Don't add the test when QEMU is built with asan.
Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Message-ID: <20260309104545.1550888-1-peter.maydell@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/functional/x86_64/meson.build | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
index 05e4914c772..1ed10ad6c29 100644
--- a/tests/functional/x86_64/meson.build
+++ b/tests/functional/x86_64/meson.build
@@ -14,13 +14,20 @@ tests_x86_64_system_quick = [
'cpu_model_versions',
'cpu_queries',
'mem_addr_space',
- 'memlock',
'migration',
'pc_cpu_hotplug_props',
'virtio_version',
'vmstate',
]
+# The address-sanitizer makes mlock() a no-op because it
+# interacts badly with the sanitizer; this means the memlock
+# test (which checks via /proc for whether pages were locked)
+# will always fail on a sanitizer build, so don't run it.
+if not get_option('asan')
+ tests_x86_64_system_quick += [ 'memlock' ]
+endif
+
tests_x86_64_system_thorough = [
'acpi_bits',
'hotplug_blk',
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 05/25] tests/functional/migration: Use socket_dir
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (3 preceding siblings ...)
2026-03-10 5:55 ` [PULL 04/25] tests/functional/x86_64: Disable memlock test for asan builds Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 06/25] tests/functional/migration: Add migrate_vms Thomas Huth
` (20 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Daniel P. Berrangé, Peter Xu, Fabiano Rosas
From: Fabiano Rosas <farosas@suse.de>
Use QemuBaseTest.socket_dir instead of calling tempfile directly so
all tests have consistent directory prefixes.
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Message-ID: <20260303173320.10942-2-farosas@suse.de>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/functional/migration.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tests/functional/migration.py b/tests/functional/migration.py
index 2bfb1f77901..0aa873edbaa 100644
--- a/tests/functional/migration.py
+++ b/tests/functional/migration.py
@@ -11,7 +11,6 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-import tempfile
import time
from qemu_test import QemuSystemTest, which
@@ -65,9 +64,8 @@ def migration_with_tcp_localhost(self):
self.do_migrate(dest_uri)
def migration_with_unix(self):
- with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
- dest_uri = 'unix:%s/qemu-test.sock' % socket_path
- self.do_migrate(dest_uri)
+ dest_uri = 'unix:%s/migration.sock' % self.socket_dir().name
+ self.do_migrate(dest_uri)
def migration_with_exec(self):
if not which('ncat'):
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 06/25] tests/functional/migration: Add migrate_vms
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (4 preceding siblings ...)
2026-03-10 5:55 ` [PULL 05/25] tests/functional/migration: Use socket_dir Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 07/25] tests/functional/migration: Use the migrate_vms helper Thomas Huth
` (19 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Peter Xu, Fabiano Rosas
From: Fabiano Rosas <farosas@suse.de>
Add a migration helper to MigrationTest that uses the migrate-incoming
QMP command and takes the already instantiated VMs. The -incoming
'defer' command line option is preferred way instead of the -incoming
URI syntax that's currently used.
Suggested-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Message-ID: <20260303173320.10942-3-farosas@suse.de>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/functional/migration.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/functional/migration.py b/tests/functional/migration.py
index 0aa873edbaa..3362e5c743e 100644
--- a/tests/functional/migration.py
+++ b/tests/functional/migration.py
@@ -40,6 +40,11 @@ def assert_migration(self, src_vm, dst_vm):
self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
+ def migrate_vms(self, dst_uri, src_uri, dst_vm, src_vm):
+ dst_vm.qmp('migrate-incoming', uri=dst_uri)
+ src_vm.qmp('migrate', uri=src_uri)
+ self.assert_migration(src_vm, dst_vm)
+
def do_migrate(self, dest_uri, src_uri=None):
dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu")
dest_vm.add_args('-nodefaults')
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 07/25] tests/functional/migration: Use the migrate_vms helper
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (5 preceding siblings ...)
2026-03-10 5:55 ` [PULL 06/25] tests/functional/migration: Add migrate_vms Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 08/25] tests/functional/ppc64/pseries: Remove custom migration routine Thomas Huth
` (18 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Peter Xu, Fabiano Rosas
From: Fabiano Rosas <farosas@suse.de>
Change do_migrate() to call the migrate_vms() helper and provide it
with the two VMs already created. Rename do_migrate -> migrate and
adjust the callers.
While here, standardize on the "src" and "dst" names.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Message-ID: <20260303173320.10942-4-farosas@suse.de>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/functional/migration.py | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/tests/functional/migration.py b/tests/functional/migration.py
index 3362e5c743e..49347a30bbf 100644
--- a/tests/functional/migration.py
+++ b/tests/functional/migration.py
@@ -45,17 +45,19 @@ def migrate_vms(self, dst_uri, src_uri, dst_vm, src_vm):
src_vm.qmp('migrate', uri=src_uri)
self.assert_migration(src_vm, dst_vm)
- def do_migrate(self, dest_uri, src_uri=None):
- dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu")
- dest_vm.add_args('-nodefaults')
- dest_vm.launch()
+ def migrate(self, dst_uri, src_uri=None):
+ dst_vm = self.get_vm('-incoming', 'defer', name="dst-qemu")
+ dst_vm.add_args('-nodefaults')
+ dst_vm.launch()
+
+ src_vm = self.get_vm(name="src-qemu")
+ src_vm.add_args('-nodefaults')
+ src_vm.launch()
+
if src_uri is None:
- src_uri = dest_uri
- source_vm = self.get_vm(name="source-qemu")
- source_vm.add_args('-nodefaults')
- source_vm.launch()
- source_vm.qmp('migrate', uri=src_uri)
- self.assert_migration(source_vm, dest_vm)
+ src_uri = dst_uri
+
+ self.migrate_vms(dst_uri, src_uri, dst_vm, src_vm)
def _get_free_port(self, ports):
port = ports.find_free_port()
@@ -65,18 +67,18 @@ def _get_free_port(self, ports):
def migration_with_tcp_localhost(self):
with Ports() as ports:
- dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
- self.do_migrate(dest_uri)
+ dst_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
+ self.migrate(dst_uri)
def migration_with_unix(self):
- dest_uri = 'unix:%s/migration.sock' % self.socket_dir().name
- self.do_migrate(dest_uri)
+ dst_uri = 'unix:%s/migration.sock' % self.socket_dir().name
+ self.migrate(dst_uri)
def migration_with_exec(self):
if not which('ncat'):
self.skipTest('ncat is not available')
with Ports() as ports:
free_port = self._get_free_port(ports)
- dest_uri = 'exec:ncat -l localhost %u' % free_port
+ dst_uri = 'exec:ncat -l localhost %u' % free_port
src_uri = 'exec:ncat localhost %u' % free_port
- self.do_migrate(dest_uri, src_uri)
+ self.migrate(dst_uri, src_uri)
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 08/25] tests/functional/ppc64/pseries: Remove custom migration routine
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (6 preceding siblings ...)
2026-03-10 5:55 ` [PULL 07/25] tests/functional/migration: Use the migrate_vms helper Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 09/25] pc-bios/s390-ccw: Fix misattributed function prototypes Thomas Huth
` (17 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Aditya Gupta, Fabiano Rosas, Peter Xu
From: Fabiano Rosas <farosas@suse.de>
Don't implement a custom migration routine at PpcMigrationTest and
instead reuse the generic one from MigrationTest.
This removes the dependency of PpcMigrationTest from
PseriesMachine. Having one test import another causes unittest code to
instantiate the imported test, resulting in the setup and teardown
methods being invoked for the imported test class, even if no test
from that class will be executed.
If run in parallel, the extra setup/teardown methods that result from
importing can race with the ones from the actual test being executed
and cause the following error:
File "<SRC_DIR>/tests/functional/qemu_test/testcase.py", line 238, in tearDown
shutil.rmtree(self.workdir)
...
FileNotFoundError: [Errno 2] No such file or directory:
'<SRC_DIR>/build/tests/functional/ppc64/.../test_migration_with_exec/scratch'
The PseriesMachine class is changed to inherit from MigrationTest so
both the migration routines and the class attributes of PseriesMachine
can be accessed without the need to instantiate another object.
Fixes: f4e34d0fd5 ("tests/functional: Add a OS level migration test for pseries")
Reported-by: Aditya Gupta <adityag@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Peter Xu <peterx@redhat.com>
Tested-by: Aditya Gupta <adityag@linux.ibm.com>
Message-ID: <20260303173320.10942-5-farosas@suse.de>
[thuth: Remove superfluous ";" as suggested by Aditya]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/functional/migration.py | 5 +++++
tests/functional/ppc64/test_migration.py | 11 -----------
tests/functional/ppc64/test_pseries.py | 10 +++++-----
3 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/tests/functional/migration.py b/tests/functional/migration.py
index 49347a30bbf..e995328e833 100644
--- a/tests/functional/migration.py
+++ b/tests/functional/migration.py
@@ -65,6 +65,11 @@ def _get_free_port(self, ports):
self.skipTest('Failed to find a free port')
return port
+ def migration_with_tcp_localhost_vms(self, dst_vm, src_vm):
+ with Ports() as ports:
+ uri = 'tcp:localhost:%u' % self._get_free_port(ports)
+ self.migrate_vms(uri, uri, dst_vm, src_vm)
+
def migration_with_tcp_localhost(self):
with Ports() as ports:
dst_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
diff --git a/tests/functional/ppc64/test_migration.py b/tests/functional/ppc64/test_migration.py
index a3b819680bc..7d49ee175bb 100755
--- a/tests/functional/ppc64/test_migration.py
+++ b/tests/functional/ppc64/test_migration.py
@@ -22,17 +22,6 @@ def test_migration_with_exec(self):
self.set_machine('mac99')
self.migration_with_exec()
- def do_migrate_ppc64_linux(self, source_vm, dest_vm):
- with Ports() as ports:
- port = ports.find_free_port()
- if port is None:
- self.skipTest('Failed to find a free port')
- uri = 'tcp:localhost:%u' % port
-
- dest_vm.qmp('migrate-incoming', uri=uri)
- source_vm.qmp('migrate', uri=uri)
- self.assert_migration(source_vm, dest_vm)
-
if __name__ == '__main__':
MigrationTest.main()
diff --git a/tests/functional/ppc64/test_pseries.py b/tests/functional/ppc64/test_pseries.py
index b45763c3050..cb6d25dc816 100755
--- a/tests/functional/ppc64/test_pseries.py
+++ b/tests/functional/ppc64/test_pseries.py
@@ -7,11 +7,11 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-from qemu_test import QemuSystemTest, Asset
+from qemu_test import Asset
from qemu_test import wait_for_console_pattern
-from test_migration import PpcMigrationTest
+from migration import MigrationTest
-class PseriesMachine(QemuSystemTest):
+class PseriesMachine(MigrationTest):
timeout = 90
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 console=hvc0 '
@@ -116,11 +116,11 @@ def test_ppc64_linux_migration(self):
wait_for_console_pattern(self, console_pattern, self.panic_message,
vm=source_vm)
- PpcMigrationTest().do_migrate_ppc64_linux(source_vm, dest_vm);
+ self.migration_with_tcp_localhost_vms(dest_vm, source_vm)
# ensure the boot proceeds after migration
wait_for_console_pattern(self, self.good_message, self.panic_message,
vm=dest_vm)
if __name__ == '__main__':
- QemuSystemTest.main()
+ MigrationTest.main()
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 09/25] pc-bios/s390-ccw: Fix misattributed function prototypes
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (7 preceding siblings ...)
2026-03-10 5:55 ` [PULL 08/25] tests/functional/ppc64/pseries: Remove custom migration routine Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 10/25] pc-bios/s390-ccw: Remove redundant vring schid attribute Thomas Huth
` (16 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Farhan Ali, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
The virtio-blkdev functions are incorrectly listed in s390-ccw.h as belonging to
virtio.c. Additionally, virtio_load_direct() has an unused subchan_id argument.
Remove the unused argument and move the prototypes to virtio.h so that they are
independent from the CCW bus.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-2-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/s390-ccw.h | 4 ----
pc-bios/s390-ccw/virtio.h | 7 +++++++
pc-bios/s390-ccw/bootmap.c | 2 +-
pc-bios/s390-ccw/virtio-blkdev.c | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index b1dc35cdedf..47ea66bd4d1 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -67,11 +67,7 @@ void sclp_get_loadparm_ascii(char *loadparm);
int sclp_read(char *str, size_t count);
/* virtio.c */
-unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
- unsigned long subchan_id, void *load_addr);
bool virtio_is_supported(SubChannelId schid);
-int virtio_blk_setup_device(SubChannelId schid);
-int virtio_read(unsigned long sector, void *load_addr);
/* bootmap.c */
void zipl_load(void);
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 5c5e808a500..597bd423586 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -277,7 +277,14 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
int virtio_reset(VDev *vdev);
int virtio_setup_ccw(VDev *vdev);
+/* virtio-net.c */
int virtio_net_init(void *mac_addr);
void virtio_net_deinit(void);
+/* virtio-blkdev.c */
+int virtio_blk_setup_device(SubChannelId schid);
+int virtio_read(unsigned long sector, void *load_addr);
+unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
+ void *load_addr);
+
#endif /* VIRTIO_H */
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 0f8baa01985..420ee32eff8 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -662,7 +662,7 @@ static int zipl_load_segment(ComponentEntry *entry)
*/
break;
}
- address = virtio_load_direct(cur_desc[0], cur_desc[1], 0,
+ address = virtio_load_direct(cur_desc[0], cur_desc[1],
(void *)address);
if (!address) {
puts("zIPL load segment failed");
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 7b2d1e20f4d..4b819dd80fb 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -64,7 +64,7 @@ int virtio_read_many(unsigned long sector, void *load_addr, int sec_num)
}
unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
- unsigned long subchan_id, void *load_addr)
+ void *load_addr)
{
u8 status;
int sec = rec_list1;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 10/25] pc-bios/s390-ccw: Remove redundant vring schid attribute
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (8 preceding siblings ...)
2026-03-10 5:55 ` [PULL 09/25] pc-bios/s390-ccw: Fix misattributed function prototypes Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 11/25] pc-bios/s390-ccw: Always reset virtio device on failed boot attempt Thomas Huth
` (15 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Farhan Ali, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
The schid is already stored as an attribute of the VDev itself and any other
instances are copies of this same value. To avoid CCW specific attributes in
the VRing let's just access the existing VDev schid attribute as needed.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-3-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/virtio.h | 3 +--
pc-bios/s390-ccw/virtio-blkdev.c | 2 +-
pc-bios/s390-ccw/virtio-net.c | 2 +-
pc-bios/s390-ccw/virtio.c | 9 ++++-----
4 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 597bd423586..06ba4e45aca 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -103,7 +103,6 @@ struct VRing {
VRingDesc *desc;
VRingAvail *avail;
VRingUsed *used;
- SubChannelId schid;
long cookie;
int id;
};
@@ -269,7 +268,7 @@ struct VirtioCmd {
typedef struct VirtioCmd VirtioCmd;
bool vring_notify(VRing *vr);
-int drain_irqs(SubChannelId schid);
+int drain_irqs(void);
void vring_send_buf(VRing *vr, void *p, int len, int flags);
int vr_poll(VRing *vr);
int vring_wait_reply(void);
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 4b819dd80fb..019c2718b18 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -42,7 +42,7 @@ static int virtio_blk_read_many(VDev *vdev, unsigned long sector, void *load_add
/* Now we can tell the host to read */
vring_wait_reply();
- if (drain_irqs(vr->schid)) {
+ if (drain_irqs()) {
/* Well, whatever status is supposed to contain... */
status = 1;
}
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
index 301445bf978..7eb08500695 100644
--- a/pc-bios/s390-ccw/virtio-net.c
+++ b/pc-bios/s390-ccw/virtio-net.c
@@ -88,7 +88,7 @@ int send(int fd, const void *buf, int len, int flags)
while (!vr_poll(txvq)) {
yield();
}
- if (drain_irqs(txvq->schid)) {
+ if (drain_irqs()) {
puts("send: drain irqs failed");
return -1;
}
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index cd6c99c7e32..f384a990dcc 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -72,14 +72,14 @@ static long virtio_notify(SubChannelId schid, int vq_idx, long cookie)
* Virtio functions *
***********************************************/
-int drain_irqs(SubChannelId schid)
+int drain_irqs(void)
{
Irb irb = {};
int r = 0;
while (1) {
/* FIXME: make use of TPI, for that enable subchannel and isc */
- if (tsch(schid, &irb)) {
+ if (tsch(vdev.schid, &irb)) {
/* Might want to differentiate error codes later on. */
if (irb.scsw.cstat) {
r = -EIO;
@@ -134,7 +134,7 @@ static void vring_init(VRing *vr, VqInfo *info)
bool vring_notify(VRing *vr)
{
- vr->cookie = virtio_notify(vr->schid, vr->id, vr->cookie);
+ vr->cookie = virtio_notify(vdev.schid, vr->id, vr->cookie);
return vr->cookie >= 0;
}
@@ -211,7 +211,7 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd)
} while (cmd[i++].flags & VRING_DESC_F_NEXT);
vring_wait_reply();
- if (drain_irqs(vr->schid)) {
+ if (drain_irqs()) {
return -1;
}
return 0;
@@ -316,7 +316,6 @@ int virtio_setup_ccw(VDev *vdev)
}
info.num = config.num;
vring_init(&vdev->vrings[i], &info);
- vdev->vrings[i].schid = vdev->schid;
if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) {
puts("Cannot set VQ info");
return -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 11/25] pc-bios/s390-ccw: Always reset virtio device on failed boot attempt
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (9 preceding siblings ...)
2026-03-10 5:55 ` [PULL 10/25] pc-bios/s390-ccw: Remove redundant vring schid attribute Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 12/25] s390x: Remove duplicate definitions of IPL types Thomas Huth
` (14 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
The virtio spec necessitates that live virtqueues must not be altered. Reset
the failed device so that the queues are not live before we attempt to boot any
fallback devices.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-4-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 76bf743900c..8e2c99bee13 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -277,7 +277,8 @@ static void ipl_boot_device(void)
break;
case CU_TYPE_VIRTIO:
if (virtio_setup() == 0) {
- zipl_load();
+ zipl_load(); /* only return on error */
+ virtio_reset(virtio_get_device());
}
break;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 12/25] s390x: Remove duplicate definitions of IPL types
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (10 preceding siblings ...)
2026-03-10 5:55 ` [PULL 11/25] pc-bios/s390-ccw: Always reset virtio device on failed boot attempt Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 13/25] pc-bios/s390-ccw: Store device type independent of sense data Thomas Huth
` (13 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Remove the duplicate definitions from hw/s390x/ipl.h and pc-bios/s390-ccw/iplb.h
and add a shared definition. The new definition is an enum to enforce default
handling in switches.
Because the IPL type is determined by the IPLB, and because an IPLB is not
strictly necessary, the IPL type is set to a default value if not otherwise
specified. A default IPL type is required so future functionality may add
IPL new bus and/or device types that dictate specific behavior during IPL.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-5-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/ipl.h | 5 -----
include/hw/s390x/ipl/qipl.h | 10 ++++++++++
pc-bios/s390-ccw/iplb.h | 4 ----
pc-bios/s390-ccw/virtio.h | 1 +
pc-bios/s390-ccw/main.c | 14 ++++++++++----
5 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 086e57681c2..c542d30ce2d 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -103,11 +103,6 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define DIAG308_PV_STORE 9
#define DIAG308_PV_START 10
-#define S390_IPL_TYPE_FCP 0x00
-#define S390_IPL_TYPE_CCW 0x02
-#define S390_IPL_TYPE_PV 0x05
-#define S390_IPL_TYPE_QEMU_SCSI 0xff
-
#define S390_IPLB_HEADER_LEN 8
#define S390_IPLB_MIN_PV_LEN 148
#define S390_IPLB_MIN_CCW_LEN 200
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index 6824391111c..6dc12dd859f 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -20,6 +20,16 @@
#define LOADPARM_LEN 8
#define NO_LOADPARM "\0\0\0\0\0\0\0\0"
+enum S390IplType {
+ S390_IPL_TYPE_FCP = 0x00,
+ S390_IPL_TYPE_CCW = 0x02,
+ S390_IPL_TYPE_PV = 0x05,
+ S390_IPL_TYPE_QEMU_SCSI = 0xff
+};
+typedef enum S390IplType S390IplType;
+
+#define QEMU_DEFAULT_IPL S390_IPL_TYPE_CCW
+
/*
* The QEMU IPL Parameters will be stored at absolute address
* 204 (0xcc) which means it is 32-bit word aligned but not
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 08f259ff319..926e8eed5d4 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -23,10 +23,6 @@ extern QemuIplParameters qipl;
extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
extern bool have_iplb;
-#define S390_IPL_TYPE_FCP 0x00
-#define S390_IPL_TYPE_CCW 0x02
-#define S390_IPL_TYPE_QEMU_SCSI 0xff
-
static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
{
register unsigned long addr asm("0") = (unsigned long) iplb;
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 06ba4e45aca..391d6ff2f7f 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -238,6 +238,7 @@ struct VDev {
VirtioGDN guessed_disk_nature;
SubChannelId schid;
SenseId senseid;
+ S390IplType ipl_type;
union {
VirtioBlkConfig blk;
VirtioScsiConfig scsi;
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 8e2c99bee13..2e9261904fa 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -149,7 +149,7 @@ static bool find_subch(int dev_no)
return false;
}
-static void menu_setup(void)
+static void menu_setup(VDev *vdev)
{
if (memcmp(loadparm_str, LOADPARM_PROMPT, LOADPARM_LEN) == 0) {
menu_set_parms(QIPL_FLAG_BM_OPTS_CMD, 0);
@@ -162,11 +162,13 @@ static void menu_setup(void)
return;
}
- switch (iplb.pbt) {
+ switch (vdev->ipl_type) {
case S390_IPL_TYPE_CCW:
case S390_IPL_TYPE_QEMU_SCSI:
menu_set_parms(qipl.qipl_flags & BOOT_MENU_FLAG_MASK,
qipl.boot_menu_timeout);
+ /* fall through */
+ default:
return;
}
}
@@ -190,6 +192,7 @@ static void css_setup(void)
static void boot_setup(void)
{
char lpmsg[] = "LOADPARM=[________]\n";
+ VDev *vdev = virtio_get_device();
if (have_iplb && memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) {
ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN);
@@ -198,7 +201,10 @@ static void boot_setup(void)
}
if (have_iplb) {
- menu_setup();
+ vdev->ipl_type = iplb.pbt;
+ menu_setup(vdev);
+ } else {
+ vdev->ipl_type = QEMU_DEFAULT_IPL;
}
memcpy(lpmsg + 10, loadparm_str, 8);
@@ -216,7 +222,7 @@ static bool find_boot_device(void)
VDev *vdev = virtio_get_device();
bool found = false;
- switch (iplb.pbt) {
+ switch (vdev->ipl_type) {
case S390_IPL_TYPE_CCW:
vdev->scsi_device_selected = false;
debug_print_int("device no. ", iplb.ccw.devno);
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 13/25] pc-bios/s390-ccw: Store device type independent of sense data
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (11 preceding siblings ...)
2026-03-10 5:55 ` [PULL 12/25] s390x: Remove duplicate definitions of IPL types Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 14/25] pc-bios/s390-ccw: Split virtio-ccw and generic virtio Thomas Huth
` (12 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Farhan Ali, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Store the device type (e.g. block) directly as an attribute of the VDev rather
than assume all devices can be identified by accessing CCW specific sense data.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-6-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/virtio.h | 1 +
pc-bios/s390-ccw/main.c | 2 +-
pc-bios/s390-ccw/virtio-blkdev.c | 39 +++++++++++++++++++-------------
pc-bios/s390-ccw/virtio.c | 11 ++++++---
4 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 391d6ff2f7f..39b507b2219 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -239,6 +239,7 @@ struct VDev {
SubChannelId schid;
SenseId senseid;
S390IplType ipl_type;
+ VirtioDevType dev_type;
union {
VirtioBlkConfig blk;
VirtioScsiConfig scsi;
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 2e9261904fa..64bde497103 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -251,7 +251,7 @@ static int virtio_setup(void)
vdev->is_cdrom = false;
int ret;
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_NET:
puts("Network boot device detected");
return 0;
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 019c2718b18..9cc40e9108d 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -53,14 +53,14 @@ int virtio_read_many(unsigned long sector, void *load_addr, int sec_num)
{
VDev *vdev = virtio_get_device();
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
return virtio_blk_read_many(vdev, sector, load_addr, sec_num);
case VIRTIO_ID_SCSI:
return virtio_scsi_read_many(vdev, sector, load_addr, sec_num);
+ default:
+ return -1;
}
-
- return -1;
}
unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
@@ -119,7 +119,7 @@ void virtio_assume_iso9660(void)
{
VDev *vdev = virtio_get_device();
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
vdev->guessed_disk_nature = VIRTIO_GDN_SCSI;
vdev->config.blk.blk_size = VIRTIO_ISO_BLOCK_SIZE;
@@ -129,6 +129,8 @@ void virtio_assume_iso9660(void)
case VIRTIO_ID_SCSI:
vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE;
break;
+ default:
+ return;
}
}
@@ -139,13 +141,15 @@ void virtio_assume_eckd(void)
vdev->guessed_disk_nature = VIRTIO_GDN_DASD;
vdev->blk_factor = 1;
vdev->config.blk.physical_block_exp = 0;
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
vdev->config.blk.blk_size = VIRTIO_DASD_DEFAULT_BLOCK_SIZE;
break;
case VIRTIO_ID_SCSI:
vdev->config.blk.blk_size = vdev->scsi_block_size;
break;
+ default:
+ break;
}
vdev->config.blk.geometry.heads = 15;
vdev->config.blk.geometry.sectors =
@@ -162,50 +166,52 @@ bool virtio_ipl_disk_is_valid(void)
return true;
}
- return (vdev->senseid.cu_model == VIRTIO_ID_BLOCK ||
- vdev->senseid.cu_model == VIRTIO_ID_SCSI) &&
- blksize >= 512 && blksize <= 4096;
+ return (vdev->dev_type == VIRTIO_ID_BLOCK || vdev->dev_type == VIRTIO_ID_SCSI)
+ && blksize >= 512 && blksize <= 4096;
}
int virtio_get_block_size(void)
{
VDev *vdev = virtio_get_device();
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
return vdev->config.blk.blk_size;
case VIRTIO_ID_SCSI:
return vdev->scsi_block_size;
+ default:
+ return 0;
}
- return 0;
}
uint8_t virtio_get_heads(void)
{
VDev *vdev = virtio_get_device();
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
return vdev->config.blk.geometry.heads;
case VIRTIO_ID_SCSI:
return vdev->guessed_disk_nature == VIRTIO_GDN_DASD
? vdev->config.blk.geometry.heads : 255;
+ default:
+ return 0;
}
- return 0;
}
uint8_t virtio_get_sectors(void)
{
VDev *vdev = virtio_get_device();
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
return vdev->config.blk.geometry.sectors;
case VIRTIO_ID_SCSI:
return vdev->guessed_disk_nature == VIRTIO_GDN_DASD
? vdev->config.blk.geometry.sectors : 63;
+ default:
+ return 0;
}
- return 0;
}
uint64_t virtio_get_blocks(void)
@@ -213,13 +219,14 @@ uint64_t virtio_get_blocks(void)
VDev *vdev = virtio_get_device();
const uint64_t factor = virtio_get_block_size() / VIRTIO_SECTOR_SIZE;
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_BLOCK:
return vdev->config.blk.capacity / factor;
case VIRTIO_ID_SCSI:
return vdev->scsi_last_block / factor;
+ default:
+ return 0;
}
- return 0;
}
int virtio_blk_setup_device(SubChannelId schid)
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index f384a990dcc..5dd407d5c9b 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -41,7 +41,7 @@ VDev *virtio_get_device(void)
VirtioDevType virtio_get_device_type(void)
{
- return vdev.senseid.cu_model;
+ return vdev.dev_type;
}
/* virtio spec v1.0 para 4.3.3.2 */
@@ -248,7 +248,7 @@ int virtio_setup_ccw(VDev *vdev)
return -EIO;
}
- switch (vdev->senseid.cu_model) {
+ switch (vdev->dev_type) {
case VIRTIO_ID_NET:
vdev->nr_vqs = 2;
vdev->cmd_vr_idx = 0;
@@ -346,12 +346,17 @@ bool virtio_is_supported(SubChannelId schid)
true)) {
return false;
}
+
+ vdev.dev_type = vdev.senseid.cu_model;
+
if (vdev.senseid.cu_type == 0x3832) {
- switch (vdev.senseid.cu_model) {
+ switch (vdev.dev_type) {
case VIRTIO_ID_BLOCK:
case VIRTIO_ID_SCSI:
case VIRTIO_ID_NET:
return true;
+ default:
+ return false;
}
}
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 14/25] pc-bios/s390-ccw: Split virtio-ccw and generic virtio
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (12 preceding siblings ...)
2026-03-10 5:55 ` [PULL 13/25] pc-bios/s390-ccw: Store device type independent of sense data Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 15/25] include/hw/s390x: Move CLP definitions for easier BIOS access Thomas Huth
` (11 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Separate the CCW specific virtio routines and create generic wrappers for easier
reuse of existing virtio functions with non-CCW devices.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-7-jrossi@linux.ibm.com>
[thuth: Use SPDX license identifier in virtio-ccw.c]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/s390-ccw.h | 3 -
pc-bios/s390-ccw/virtio-ccw.h | 24 ++++
pc-bios/s390-ccw/virtio-scsi.h | 2 +-
pc-bios/s390-ccw/virtio.h | 5 +-
pc-bios/s390-ccw/main.c | 8 +-
pc-bios/s390-ccw/netmain.c | 2 +-
pc-bios/s390-ccw/virtio-blkdev.c | 15 +-
pc-bios/s390-ccw/virtio-ccw.c | 239 +++++++++++++++++++++++++++++++
pc-bios/s390-ccw/virtio-net.c | 3 +-
pc-bios/s390-ccw/virtio-scsi.c | 8 +-
pc-bios/s390-ccw/virtio.c | 239 ++++++-------------------------
pc-bios/s390-ccw/Makefile | 3 +-
12 files changed, 330 insertions(+), 221 deletions(-)
create mode 100644 pc-bios/s390-ccw/virtio-ccw.h
create mode 100644 pc-bios/s390-ccw/virtio-ccw.c
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 47ea66bd4d1..ccd68ff0a4b 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -66,9 +66,6 @@ void sclp_setup(void);
void sclp_get_loadparm_ascii(char *loadparm);
int sclp_read(char *str, size_t count);
-/* virtio.c */
-bool virtio_is_supported(SubChannelId schid);
-
/* bootmap.c */
void zipl_load(void);
diff --git a/pc-bios/s390-ccw/virtio-ccw.h b/pc-bios/s390-ccw/virtio-ccw.h
new file mode 100644
index 00000000000..a506767eaa8
--- /dev/null
+++ b/pc-bios/s390-ccw/virtio-ccw.h
@@ -0,0 +1,24 @@
+/*
+ * Virtio definitions for CCW devices
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef VIRTIO_CCW_H
+#define VIRTIO_CCW_H
+
+/* main.c */
+extern SubChannelId blk_schid;
+
+/* virtio-ccw.c */
+int drain_irqs_ccw(SubChannelId schid);
+bool virtio_ccw_is_supported(VDev *vdev);
+int virtio_ccw_run(VDev *vdev, int vqid, VirtioCmd *cmd);
+long virtio_ccw_notify(SubChannelId schid, int vq_idx, long cookie);
+int virtio_ccw_setup(VDev *vdev);
+int virtio_ccw_reset(VDev *vdev);
+
+#endif
diff --git a/pc-bios/s390-ccw/virtio-scsi.h b/pc-bios/s390-ccw/virtio-scsi.h
index c5612e16a26..070f24b7e5a 100644
--- a/pc-bios/s390-ccw/virtio-scsi.h
+++ b/pc-bios/s390-ccw/virtio-scsi.h
@@ -69,6 +69,6 @@ static inline bool virtio_scsi_response_ok(const VirtioScsiCmdResp *r)
int virtio_scsi_read_many(VDev *vdev,
unsigned long sector, void *load_addr, int sec_num);
-int virtio_scsi_setup_device(SubChannelId schid);
+int virtio_scsi_setup_device(VDev *vdev);
#endif /* VIRTIO_SCSI_H */
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 39b507b2219..c3cb5a6ee3b 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -108,6 +108,7 @@ struct VRing {
};
typedef struct VRing VRing;
+char *virtio_get_ring_area(int ring_num);
/***********************************************
* Virtio block *
@@ -269,6 +270,8 @@ struct VirtioCmd {
};
typedef struct VirtioCmd VirtioCmd;
+void vring_init(VRing *vr, VqInfo *info);
+bool virtio_is_supported(VDev *vdev);
bool vring_notify(VRing *vr);
int drain_irqs(void);
void vring_send_buf(VRing *vr, void *p, int len, int flags);
@@ -283,7 +286,7 @@ int virtio_net_init(void *mac_addr);
void virtio_net_deinit(void);
/* virtio-blkdev.c */
-int virtio_blk_setup_device(SubChannelId schid);
+int virtio_blk_setup_device(VDev *vdev);
int virtio_read(unsigned long sector, void *load_addr);
unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list2,
void *load_addr);
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 64bde497103..32154c5db8d 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -71,6 +71,7 @@ static int is_dev_possibly_bootable(int dev_no, int sch_no)
bool is_virtio;
Schib schib;
int r;
+ VDev *vdev = virtio_get_device();
blk_schid.sch_no = sch_no;
r = stsch_err(blk_schid, &schib);
@@ -91,7 +92,8 @@ static int is_dev_possibly_bootable(int dev_no, int sch_no)
* Note: we always have to run virtio_is_supported() here to make
* sure that the vdev.senseid data gets pre-initialized correctly
*/
- is_virtio = virtio_is_supported(blk_schid);
+ vdev->schid = blk_schid;
+ is_virtio = virtio_is_supported(vdev);
/* No specific devno given, just return whether the device is possibly bootable */
if (dev_no < 0) {
@@ -256,10 +258,10 @@ static int virtio_setup(void)
puts("Network boot device detected");
return 0;
case VIRTIO_ID_BLOCK:
- ret = virtio_blk_setup_device(blk_schid);
+ ret = virtio_blk_setup_device(vdev);
break;
case VIRTIO_ID_SCSI:
- ret = virtio_scsi_setup_device(blk_schid);
+ ret = virtio_scsi_setup_device(vdev);
break;
default:
puts("\n! No IPL device available !\n");
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index a9521dff416..651cedf6efa 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -500,7 +500,7 @@ static bool find_net_dev(Schib *schib, int dev_no)
continue;
}
enable_subchannel(net_schid);
- if (!virtio_is_supported(net_schid)) {
+ if (!virtio_is_supported(virtio_get_device())) {
continue;
}
if (virtio_get_device_type() != VIRTIO_ID_NET) {
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 9cc40e9108d..9722b6970f1 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -12,6 +12,7 @@
#include "s390-ccw.h"
#include "virtio.h"
#include "virtio-scsi.h"
+#include "virtio-ccw.h"
#define VIRTIO_BLK_F_GEOMETRY (1 << 4)
#define VIRTIO_BLK_F_BLK_SIZE (1 << 6)
@@ -229,15 +230,17 @@ uint64_t virtio_get_blocks(void)
}
}
-int virtio_blk_setup_device(SubChannelId schid)
+int virtio_blk_setup_device(VDev *vdev)
{
- VDev *vdev = virtio_get_device();
-
vdev->guest_features[0] = VIRTIO_BLK_F_GEOMETRY | VIRTIO_BLK_F_BLK_SIZE;
- vdev->schid = schid;
- virtio_setup_ccw(vdev);
puts("Using virtio-blk.");
- return 0;
+ switch (vdev->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return virtio_ccw_setup(vdev);
+ default:
+ return 1;
+ }
}
diff --git a/pc-bios/s390-ccw/virtio-ccw.c b/pc-bios/s390-ccw/virtio-ccw.c
new file mode 100644
index 00000000000..5cb2158ed20
--- /dev/null
+++ b/pc-bios/s390-ccw/virtio-ccw.c
@@ -0,0 +1,239 @@
+/*
+ * Virtio functionality for CCW devices
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
+ * Copyright 2025 IBM Corp.
+ *
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ */
+
+#include <string.h>
+#include "s390-ccw.h"
+#include "cio.h"
+#include "virtio.h"
+#include "virtio-ccw.h"
+#include "virtio-scsi.h"
+#include "bswap.h"
+#include "helper.h"
+#include "s390-time.h"
+
+/* virtio spec v1.0 para 4.3.3.2 */
+static long kvm_hypercall(unsigned long nr, unsigned long param1,
+ unsigned long param2, unsigned long param3)
+{
+ register unsigned long r_nr asm("1") = nr;
+ register unsigned long r_param1 asm("2") = param1;
+ register unsigned long r_param2 asm("3") = param2;
+ register unsigned long r_param3 asm("4") = param3;
+ register long retval asm("2");
+
+ asm volatile ("diag %%r2,%%r4,0x500"
+ : "=d" (retval)
+ : "d" (r_nr), "0" (r_param1), "r"(r_param2), "d"(r_param3)
+ : "memory", "cc");
+
+ return retval;
+}
+
+static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
+{
+ Ccw1 ccw = {};
+
+ ccw.cmd_code = cmd;
+ ccw.cda = (long)ptr;
+ ccw.count = len;
+
+ if (sli) {
+ ccw.flags |= CCW_FLAG_SLI;
+ }
+
+ return do_cio(vdev->schid, vdev->senseid.cu_type, ptr2u32(&ccw), CCW_FMT1);
+}
+
+bool virtio_ccw_is_supported(VDev *vdev)
+{
+ memset(&vdev->senseid, 0, sizeof(vdev->senseid));
+
+ /*
+ * Run sense id command.
+ * The size of the senseid data differs between devices (notably,
+ * between virtio devices and dasds), so specify the largest possible
+ * size and suppress the incorrect length indication for smaller sizes.
+ */
+ if (run_ccw(vdev, CCW_CMD_SENSE_ID, &vdev->senseid, sizeof(vdev->senseid),
+ true)) {
+ return false;
+ }
+
+ vdev->dev_type = vdev->senseid.cu_model;
+
+ if (vdev->senseid.cu_type == 0x3832) {
+ switch (vdev->dev_type) {
+ case VIRTIO_ID_BLOCK:
+ case VIRTIO_ID_SCSI:
+ case VIRTIO_ID_NET:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+int drain_irqs_ccw(SubChannelId schid)
+{
+ Irb irb = {};
+ int r = 0;
+
+ while (1) {
+ /* FIXME: make use of TPI, for that enable subchannel and isc */
+ if (tsch(schid, &irb)) {
+ /* Might want to differentiate error codes later on. */
+ if (irb.scsw.cstat) {
+ r = -EIO;
+ } else if (irb.scsw.dstat != 0xc) {
+ r = -EIO;
+ }
+ return r;
+ }
+ }
+}
+
+long virtio_ccw_notify(SubChannelId schid, int vq_idx, long cookie)
+{
+ return kvm_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY, *(u32 *)&schid,
+ vq_idx, cookie);
+}
+
+int virtio_ccw_run(VDev *vdev, int vqid, VirtioCmd *cmd)
+{
+ VRing *vr = &vdev->vrings[vqid];
+ int i = 0;
+
+ do {
+ vring_send_buf(vr, cmd[i].data, cmd[i].size,
+ cmd[i].flags | (i ? VRING_HIDDEN_IS_CHAIN : 0));
+ } while (cmd[i++].flags & VRING_DESC_F_NEXT);
+
+ vring_wait_reply();
+ if (drain_irqs()) {
+ return -1;
+ }
+ return 0;
+}
+
+int virtio_ccw_reset(VDev *vdev)
+{
+ return run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false);
+}
+
+int virtio_ccw_setup(VDev *vdev)
+{
+ int i, cfg_size = 0;
+ uint8_t status;
+ struct VirtioFeatureDesc {
+ uint32_t features;
+ uint8_t index;
+ } __attribute__((packed)) feats;
+
+ if (!virtio_ccw_is_supported(vdev)) {
+ puts("Virtio unsupported for this device ID");
+ return -ENODEV;
+ }
+ /* device ID has been established now */
+
+ vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */
+ vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
+
+ virtio_reset(vdev);
+
+ status = VIRTIO_CONFIG_S_ACKNOWLEDGE;
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write ACKNOWLEDGE status to host");
+ return -EIO;
+ }
+
+ switch (vdev->dev_type) {
+ case VIRTIO_ID_NET:
+ vdev->nr_vqs = 2;
+ vdev->cmd_vr_idx = 0;
+ cfg_size = sizeof(vdev->config.net);
+ break;
+ case VIRTIO_ID_BLOCK:
+ vdev->nr_vqs = 1;
+ vdev->cmd_vr_idx = 0;
+ cfg_size = sizeof(vdev->config.blk);
+ break;
+ case VIRTIO_ID_SCSI:
+ vdev->nr_vqs = 3;
+ vdev->cmd_vr_idx = VR_REQUEST;
+ cfg_size = sizeof(vdev->config.scsi);
+ break;
+ default:
+ puts("Unsupported virtio device");
+ return -ENODEV;
+ }
+
+ status |= VIRTIO_CONFIG_S_DRIVER;
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write DRIVER status to host");
+ return -EIO;
+ }
+
+ /* Feature negotiation */
+ for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
+ feats.features = 0;
+ feats.index = i;
+ if (run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false)) {
+ puts("Could not get features bits");
+ return -EIO;
+ }
+
+ vdev->guest_features[i] &= bswap32(feats.features);
+ feats.features = bswap32(vdev->guest_features[i]);
+ if (run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false)) {
+ puts("Could not set features bits");
+ return -EIO;
+ }
+ }
+
+ if (run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false)) {
+ puts("Could not get virtio device configuration");
+ return -EIO;
+ }
+
+ for (i = 0; i < vdev->nr_vqs; i++) {
+ VqInfo info = {
+ .queue = (unsigned long long) virtio_get_ring_area(i),
+ .align = KVM_S390_VIRTIO_RING_ALIGN,
+ .index = i,
+ .num = 0,
+ };
+ VqConfig config = {
+ .index = i,
+ .num = 0,
+ };
+
+ if (run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config),
+ false)) {
+ puts("Could not get virtio device VQ config");
+ return -EIO;
+ }
+ info.num = config.num;
+ vring_init(&vdev->vrings[i], &info);
+ if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) {
+ puts("Cannot set VQ info");
+ return -EIO;
+ }
+ }
+
+ status |= VIRTIO_CONFIG_S_DRIVER_OK;
+ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
+ puts("Could not write DRIVER_OK status to host");
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c
index 7eb08500695..f58f7ffc55b 100644
--- a/pc-bios/s390-ccw/virtio-net.c
+++ b/pc-bios/s390-ccw/virtio-net.c
@@ -19,6 +19,7 @@
#include <ethernet.h>
#include "s390-ccw.h"
#include "virtio.h"
+#include "virtio-ccw.h"
#include "s390-time.h"
#include "helper.h"
@@ -54,7 +55,7 @@ int virtio_net_init(void *mac_addr)
rx_last_idx = 0;
vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT;
- virtio_setup_ccw(vdev);
+ virtio_ccw_setup(vdev);
if (!(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT)) {
puts("virtio-net device does not support the MAC address feature");
diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c
index 71db75ce7b4..9ea00c6fe67 100644
--- a/pc-bios/s390-ccw/virtio-scsi.c
+++ b/pc-bios/s390-ccw/virtio-scsi.c
@@ -15,6 +15,7 @@
#include "virtio.h"
#include "scsi.h"
#include "virtio-scsi.h"
+#include "virtio-ccw.h"
#include "s390-time.h"
#include "helper.h"
@@ -476,12 +477,9 @@ static int virtio_scsi_setup(VDev *vdev)
return 0;
}
-int virtio_scsi_setup_device(SubChannelId schid)
+int virtio_scsi_setup_device(VDev *vdev)
{
- VDev *vdev = virtio_get_device();
-
- vdev->schid = schid;
- virtio_setup_ccw(vdev);
+ virtio_ccw_setup(vdev);
if (vdev->config.scsi.sense_size != VIRTIO_SCSI_SENSE_SIZE) {
puts("Config: sense size mismatch");
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 5dd407d5c9b..956b34ff33a 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -2,6 +2,9 @@
* Virtio driver bits
*
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
+ * Copyright 2025 IBM Corp.
+ *
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
@@ -13,6 +16,7 @@
#include "cio.h"
#include "virtio.h"
#include "virtio-scsi.h"
+#include "virtio-ccw.h"
#include "bswap.h"
#include "helper.h"
#include "s390-time.h"
@@ -44,28 +48,9 @@ VirtioDevType virtio_get_device_type(void)
return vdev.dev_type;
}
-/* virtio spec v1.0 para 4.3.3.2 */
-static long kvm_hypercall(unsigned long nr, unsigned long param1,
- unsigned long param2, unsigned long param3)
+char *virtio_get_ring_area(int ring_num)
{
- register unsigned long r_nr asm("1") = nr;
- register unsigned long r_param1 asm("2") = param1;
- register unsigned long r_param2 asm("3") = param2;
- register unsigned long r_param3 asm("4") = param3;
- register long retval asm("2");
-
- asm volatile ("diag %%r2,%%r4,0x500"
- : "=d" (retval)
- : "d" (r_nr), "0" (r_param1), "r"(r_param2), "d"(r_param3)
- : "memory", "cc");
-
- return retval;
-}
-
-static long virtio_notify(SubChannelId schid, int vq_idx, long cookie)
-{
- return kvm_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY, *(u32 *)&schid,
- vq_idx, cookie);
+ return ring_area + ring_num * VIRTIO_RING_SIZE;
}
/***********************************************
@@ -74,39 +59,27 @@ static long virtio_notify(SubChannelId schid, int vq_idx, long cookie)
int drain_irqs(void)
{
- Irb irb = {};
- int r = 0;
-
- while (1) {
- /* FIXME: make use of TPI, for that enable subchannel and isc */
- if (tsch(vdev.schid, &irb)) {
- /* Might want to differentiate error codes later on. */
- if (irb.scsw.cstat) {
- r = -EIO;
- } else if (irb.scsw.dstat != 0xc) {
- r = -EIO;
- }
- return r;
- }
+ switch (vdev.ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return drain_irqs_ccw(vdev.schid);
+ default:
+ return 0;
}
}
-static int run_ccw(VDev *vdev, int cmd, void *ptr, int len, bool sli)
+int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd)
{
- Ccw1 ccw = {};
-
- ccw.cmd_code = cmd;
- ccw.cda = (long)ptr;
- ccw.count = len;
-
- if (sli) {
- ccw.flags |= CCW_FLAG_SLI;
+ switch (vdev->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return virtio_ccw_run(vdev, vqid, cmd);
+ default:
+ return -1;
}
-
- return do_cio(vdev->schid, vdev->senseid.cu_type, ptr2u32(&ccw), CCW_FMT1);
}
-static void vring_init(VRing *vr, VqInfo *info)
+void vring_init(VRing *vr, VqInfo *info)
{
void *p = (void *) info->queue;
@@ -134,7 +107,15 @@ static void vring_init(VRing *vr, VqInfo *info)
bool vring_notify(VRing *vr)
{
- vr->cookie = virtio_notify(vdev.schid, vr->id, vr->cookie);
+ switch (vdev.ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ vr->cookie = virtio_ccw_notify(vdev.schid, vr->id, vr->cookie);
+ break;
+ default:
+ return 1;
+ }
+
return vr->cookie >= 0;
}
@@ -200,164 +181,24 @@ int vring_wait_reply(void)
return 1;
}
-int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd)
-{
- VRing *vr = &vdev->vrings[vqid];
- int i = 0;
-
- do {
- vring_send_buf(vr, cmd[i].data, cmd[i].size,
- cmd[i].flags | (i ? VRING_HIDDEN_IS_CHAIN : 0));
- } while (cmd[i++].flags & VRING_DESC_F_NEXT);
-
- vring_wait_reply();
- if (drain_irqs()) {
- return -1;
- }
- return 0;
-}
-
int virtio_reset(VDev *vdev)
{
- return run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false);
-}
-
-int virtio_setup_ccw(VDev *vdev)
-{
- int i, cfg_size = 0;
- uint8_t status;
- struct VirtioFeatureDesc {
- uint32_t features;
- uint8_t index;
- } __attribute__((packed)) feats;
-
- if (!virtio_is_supported(vdev->schid)) {
- puts("Virtio unsupported for this device ID");
- return -ENODEV;
- }
- /* device ID has been established now */
-
- vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */
- vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
-
- virtio_reset(vdev);
-
- status = VIRTIO_CONFIG_S_ACKNOWLEDGE;
- if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
- puts("Could not write ACKNOWLEDGE status to host");
- return -EIO;
- }
-
- switch (vdev->dev_type) {
- case VIRTIO_ID_NET:
- vdev->nr_vqs = 2;
- vdev->cmd_vr_idx = 0;
- cfg_size = sizeof(vdev->config.net);
- break;
- case VIRTIO_ID_BLOCK:
- vdev->nr_vqs = 1;
- vdev->cmd_vr_idx = 0;
- cfg_size = sizeof(vdev->config.blk);
- break;
- case VIRTIO_ID_SCSI:
- vdev->nr_vqs = 3;
- vdev->cmd_vr_idx = VR_REQUEST;
- cfg_size = sizeof(vdev->config.scsi);
- break;
+ switch (vdev->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return virtio_ccw_reset(vdev);
default:
- puts("Unsupported virtio device");
- return -ENODEV;
- }
-
- status |= VIRTIO_CONFIG_S_DRIVER;
- if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
- puts("Could not write DRIVER status to host");
- return -EIO;
- }
-
- /* Feature negotiation */
- for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
- feats.features = 0;
- feats.index = i;
- if (run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false)) {
- puts("Could not get features bits");
- return -EIO;
- }
-
- vdev->guest_features[i] &= bswap32(feats.features);
- feats.features = bswap32(vdev->guest_features[i]);
- if (run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false)) {
- puts("Could not set features bits");
- return -EIO;
- }
- }
-
- if (run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false)) {
- puts("Could not get virtio device configuration");
- return -EIO;
- }
-
- for (i = 0; i < vdev->nr_vqs; i++) {
- VqInfo info = {
- .queue = (unsigned long long) ring_area + (i * VIRTIO_RING_SIZE),
- .align = KVM_S390_VIRTIO_RING_ALIGN,
- .index = i,
- .num = 0,
- };
- VqConfig config = {
- .index = i,
- .num = 0,
- };
-
- if (run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config),
- false)) {
- puts("Could not get virtio device VQ config");
- return -EIO;
- }
- info.num = config.num;
- vring_init(&vdev->vrings[i], &info);
- if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) {
- puts("Cannot set VQ info");
- return -EIO;
- }
- }
-
- status |= VIRTIO_CONFIG_S_DRIVER_OK;
- if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) {
- puts("Could not write DRIVER_OK status to host");
- return -EIO;
+ return -1;
}
-
- return 0;
}
-bool virtio_is_supported(SubChannelId schid)
+bool virtio_is_supported(VDev *vdev)
{
- vdev.schid = schid;
- memset(&vdev.senseid, 0, sizeof(vdev.senseid));
-
- /*
- * Run sense id command.
- * The size of the senseid data differs between devices (notably,
- * between virtio devices and dasds), so specify the largest possible
- * size and suppress the incorrect length indication for smaller sizes.
- */
- if (run_ccw(&vdev, CCW_CMD_SENSE_ID, &vdev.senseid, sizeof(vdev.senseid),
- true)) {
+ switch (vdev->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return virtio_ccw_is_supported(vdev);
+ default:
return false;
}
-
- vdev.dev_type = vdev.senseid.cu_model;
-
- if (vdev.senseid.cu_type == 0x3832) {
- switch (vdev.dev_type) {
- case VIRTIO_ID_BLOCK:
- case VIRTIO_ID_SCSI:
- case VIRTIO_ID_NET:
- return true;
- default:
- return false;
- }
- }
- return false;
}
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index a0f24c94a87..259cff09db6 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -34,7 +34,8 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
.PHONY : all clean build-all distclean
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
- virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o
+ virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
+ virtio-ccw.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 15/25] include/hw/s390x: Move CLP definitions for easier BIOS access
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (13 preceding siblings ...)
2026-03-10 5:55 ` [PULL 14/25] pc-bios/s390-ccw: Split virtio-ccw and generic virtio Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 16/25] pc-bios/s390-ccw: Introduce CLP Architecture Thomas Huth
` (10 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Matthew Rosato, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Move the s390-pci-clp definitions into the "ipl" sub-directory, which is visible
to the s390-bios. This allows the bios to reuse the architected definitions and
prevents code duplication.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-8-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
MAINTAINERS | 1 +
include/hw/s390x/{ => ipl}/s390-pci-clp.h | 0
include/hw/s390x/s390-pci-bus.h | 2 +-
hw/s390x/s390-pci-vfio.c | 2 +-
4 files changed, 3 insertions(+), 2 deletions(-)
rename include/hw/s390x/{ => ipl}/s390-pci-clp.h (100%)
diff --git a/MAINTAINERS b/MAINTAINERS
index f6d43a41431..9d1614fd7e9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1882,6 +1882,7 @@ R: Eric Farman <farman@linux.ibm.com>
S: Supported
F: hw/s390x/s390-pci*
F: include/hw/s390x/s390-pci*
+F: include/hw/s390x/ipl/s390-pci*
F: util/s390x_pci_mmio.c
L: qemu-s390x@nongnu.org
diff --git a/include/hw/s390x/s390-pci-clp.h b/include/hw/s390x/ipl/s390-pci-clp.h
similarity index 100%
rename from include/hw/s390x/s390-pci-clp.h
rename to include/hw/s390x/ipl/s390-pci-clp.h
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
index 04944d4fed7..f643e130579 100644
--- a/include/hw/s390x/s390-pci-bus.h
+++ b/include/hw/s390x/s390-pci-bus.h
@@ -19,7 +19,7 @@
#include "hw/s390x/sclp.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/css.h"
-#include "hw/s390x/s390-pci-clp.h"
+#include "hw/s390x/ipl/s390-pci-clp.h"
#include "qom/object.h"
#define TYPE_S390_PCI_HOST_BRIDGE "s390-pcihost"
diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c
index 9e31029d7ac..8ce44dbecce 100644
--- a/hw/s390x/s390-pci-vfio.c
+++ b/hw/s390x/s390-pci-vfio.c
@@ -17,7 +17,7 @@
#include "trace.h"
#include "hw/s390x/s390-pci-bus.h"
-#include "hw/s390x/s390-pci-clp.h"
+#include "hw/s390x/ipl/s390-pci-clp.h"
#include "hw/s390x/s390-pci-vfio.h"
#include "hw/vfio/pci.h"
#include "hw/vfio/vfio-container-legacy.h"
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 16/25] pc-bios/s390-ccw: Introduce CLP Architecture
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (14 preceding siblings ...)
2026-03-10 5:55 ` [PULL 15/25] include/hw/s390x: Move CLP definitions for easier BIOS access Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 17/25] s390x: Add definitions for PCI IPL type Thomas Huth
` (9 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Eric Farman, Jared Rossi, Matthew Rosato, Farhan Ali
From: Jared Rossi <jrossi@linux.ibm.com>
Call Logical Processor (CLP) Architecture is used for managing PCI functions on
s390x. Define and include the structures and routines needed to interact with
PCI devices during IPL.
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Message-ID: <20260309003601.242634-9-jrossi@linux.ibm.com>
[thuth: fix a typo in one of the comments]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/clp.h | 24 ++++++++++
pc-bios/s390-ccw/clp.c | 99 +++++++++++++++++++++++++++++++++++++++
pc-bios/s390-ccw/Makefile | 2 +-
3 files changed, 124 insertions(+), 1 deletion(-)
create mode 100644 pc-bios/s390-ccw/clp.h
create mode 100644 pc-bios/s390-ccw/clp.c
diff --git a/pc-bios/s390-ccw/clp.h b/pc-bios/s390-ccw/clp.h
new file mode 100644
index 00000000000..1ac2f8c177f
--- /dev/null
+++ b/pc-bios/s390-ccw/clp.h
@@ -0,0 +1,24 @@
+/*
+ * Call Logical Processor (CLP) architecture definitions
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef CLP_H
+#define CLP_H
+
+#ifndef QEMU_PACKED
+#define QEMU_PACKED __attribute__((packed))
+#endif
+
+#include <stdint.h>
+#include <s390-pci-clp.h>
+
+int clp_pci(void *data);
+int find_pci_function(uint32_t fid, ClpFhListEntry *entry);
+int enable_pci_function(uint32_t *fhandle);
+
+#endif
diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
new file mode 100644
index 00000000000..ca9565d8ded
--- /dev/null
+++ b/pc-bios/s390-ccw/clp.c
@@ -0,0 +1,99 @@
+/*
+ * Call Logical Processor (CLP) architecture
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "clp.h"
+#include <stdio.h>
+#include <string.h>
+
+int clp_pci(void *data)
+{
+ struct { uint8_t _[CLP_BLK_SIZE]; } *req = data;
+ int cc = 3;
+
+ asm volatile (
+ " .insn rrf,0xb9a00000,0,%[req],0,2\n"
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "+d" (cc), "+m" (*req)
+ : [req] "a" (req)
+ : "cc");
+ if (cc) {
+ printf("CLP returned with non-zero condition code %d\n", cc);
+ }
+ return cc;
+}
+
+/*
+ * Get the PCI function entry for a given function ID
+ * Return 0 on success, 1 if the FID is not found, or a negative RC on error
+ */
+int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
+{
+ int count = 0;
+ int limit = PCI_MAX_FUNCTIONS;
+ ClpReqRspListPci rrb;
+
+ rrb.request.hdr.len = sizeof(ClpReqListPci);
+ rrb.request.hdr.cmd = 0x02;
+ rrb.request.resume_token = 0;
+ rrb.response.hdr.len = sizeof(ClpRspListPci);
+
+ do {
+ if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
+ puts("Failed to list PCI functions");
+ return -1;
+ }
+
+ /* Resume token set when max entries are returned */
+ if (rrb.response.resume_token) {
+ count = CLP_FH_LIST_NR_ENTRIES;
+ rrb.request.resume_token = rrb.response.resume_token;
+ } else {
+ count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
+ }
+
+ limit -= count;
+
+ for (int i = 0; i < count; i++) {
+ if (rrb.response.fh_list[i].fid == fid) {
+ memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
+ return 0;
+ }
+ }
+
+ } while (rrb.request.resume_token && limit > 0);
+
+ puts("No function entry found for FID!");
+
+ return 1;
+}
+
+/*
+ * Enable the PCI function associated with a given handle
+ * Return 0 on success or a negative RC on error
+ */
+int enable_pci_function(uint32_t *fhandle)
+{
+ ClpReqRspSetPci rrb;
+
+ rrb.request.hdr.len = sizeof(ClpReqSetPci);
+ rrb.request.hdr.cmd = 0x05;
+ rrb.request.fh = *fhandle;
+ rrb.request.oc = 0;
+ rrb.request.ndas = 1;
+ rrb.response.hdr.len = sizeof(ClpRspSetPci);
+
+ if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
+ puts("Failed to enable PCI function");
+ return -1;
+ }
+
+ *fhandle = rrb.response.fh;
+ return 0;
+}
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 259cff09db6..9c29548f849 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
- virtio-ccw.o
+ virtio-ccw.o clp.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 17/25] s390x: Add definitions for PCI IPL type
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (15 preceding siblings ...)
2026-03-10 5:55 ` [PULL 16/25] pc-bios/s390-ccw: Introduce CLP Architecture Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 18/25] pc-bios/s390-ccw: Introduce PCI device Thomas Huth
` (8 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Define a new PBT code and IPLB layout in preparation for supporting PCI device
IPL on s390x.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-10-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
include/hw/s390x/ipl/qipl.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index 6dc12dd859f..8d3c83a80bd 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -23,6 +23,7 @@
enum S390IplType {
S390_IPL_TYPE_FCP = 0x00,
S390_IPL_TYPE_CCW = 0x02,
+ S390_IPL_TYPE_PCI = 0x04,
S390_IPL_TYPE_PV = 0x05,
S390_IPL_TYPE_QEMU_SCSI = 0xff
};
@@ -108,6 +109,14 @@ struct IplBlockQemuScsi {
} QEMU_PACKED;
typedef struct IplBlockQemuScsi IplBlockQemuScsi;
+struct IplBlockPci {
+ uint32_t reserved0[76];
+ uint8_t opt;
+ uint8_t reserved1[3];
+ uint32_t fid;
+} QEMU_PACKED;
+typedef struct IplBlockPci IplBlockPci;
+
union IplParameterBlock {
struct {
uint32_t len;
@@ -123,6 +132,7 @@ union IplParameterBlock {
IplBlockFcp fcp;
IPLBlockPV pv;
IplBlockQemuScsi scsi;
+ IplBlockPci pci;
};
} QEMU_PACKED;
struct {
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 18/25] pc-bios/s390-ccw: Introduce PCI device
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (16 preceding siblings ...)
2026-03-10 5:55 ` [PULL 17/25] s390x: Add definitions for PCI IPL type Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 19/25] pc-bios/s390-ccw: Introduce virtio-pci functions Thomas Huth
` (7 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Jared Rossi, Matthew Rosato, Farhan Ali
From: Jared Rossi <jrossi@linux.ibm.com>
Define selected s390x PCI instructions.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20260309003601.242634-11-jrossi@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
[thuth: Remove unused defines as suggested by Farhan]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/pci.h | 36 ++++++++++++
pc-bios/s390-ccw/pci.c | 118 ++++++++++++++++++++++++++++++++++++++
pc-bios/s390-ccw/Makefile | 2 +-
3 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 pc-bios/s390-ccw/pci.h
create mode 100644 pc-bios/s390-ccw/pci.c
diff --git a/pc-bios/s390-ccw/pci.h b/pc-bios/s390-ccw/pci.h
new file mode 100644
index 00000000000..968635eff11
--- /dev/null
+++ b/pc-bios/s390-ccw/pci.h
@@ -0,0 +1,36 @@
+/*
+ * s390x PCI definitions
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef PCI_H
+#define PCI_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "clp.h"
+
+#define ZPCI_CREATE_REQ(handle, space, len) \
+ ((uint64_t) handle << 32 | space << 16 | len)
+
+union register_pair {
+ unsigned __int128 pair;
+ struct {
+ unsigned long even;
+ unsigned long odd;
+ };
+};
+
+#define PCI_CFGBAR 0xF /* Base Address Register for config space */
+#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
+
+int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
+ uint8_t len);
+int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
+ uint8_t len);
+
+#endif
diff --git a/pc-bios/s390-ccw/pci.c b/pc-bios/s390-ccw/pci.c
new file mode 100644
index 00000000000..247070e5f07
--- /dev/null
+++ b/pc-bios/s390-ccw/pci.c
@@ -0,0 +1,118 @@
+/*
+ * s390x PCI functionality
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "clp.h"
+#include "pci.h"
+#include "bswap.h"
+#include <stdio.h>
+#include <stdbool.h>
+
+/* PCI load */
+static inline int pcilg(uint64_t *data, uint64_t req, uint64_t offset,
+ uint8_t *status)
+{
+ union register_pair req_off = {.even = req, .odd = offset};
+ int cc = -1;
+ uint64_t __data;
+
+ asm volatile (
+ " .insn rre,0xb9d20000,%[data],%[req_off]\n"
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "+d" (cc), [data] "=d" (__data),
+ [req_off] "+d" (req_off.pair) :: "cc");
+ *status = req_off.even >> 24 & 0xff;
+ *data = __data;
+ return cc;
+}
+
+/* PCI store */
+static inline int pcistg(uint64_t data, uint64_t req, uint64_t offset,
+ uint8_t *status)
+{
+ union register_pair req_off = {.even = req, .odd = offset};
+ int cc = -1;
+
+ asm volatile (
+ " .insn rre,0xb9d00000,%[data],%[req_off]\n"
+ " ipm %[cc]\n"
+ " srl %[cc],28\n"
+ : [cc] "+d" (cc), [req_off] "+d" (req_off.pair)
+ : [data] "d" (data)
+ : "cc");
+ *status = req_off.even >> 24 & 0xff;
+ return cc;
+}
+
+int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
+ uint8_t len)
+{
+
+ uint64_t req = ZPCI_CREATE_REQ(fhandle, pcias, len);
+ uint8_t status;
+ int rc;
+
+ /* len must be non-zero power of 2 with a maximum of 8 bytes per write */
+ switch (len) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ rc = pcistg(data, req, offset, &status);
+ break;
+ default:
+ return -1;
+ }
+
+ /* Error condition detected */
+ if (rc != 0) {
+ printf("PCI store failed with status condition %d, return code %d\n",
+ status, rc);
+ return -1;
+ }
+
+ return 0;
+}
+
+int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
+ uint8_t len)
+{
+ uint64_t req, data;
+ uint8_t status;
+ int rc;
+
+ req = ZPCI_CREATE_REQ(fhandle, pcias, len);
+ rc = pcilg(&data, req, offset, &status);
+
+ /* Error condition detected */
+ if (rc != 0) {
+ printf("PCI load failed with status condition %d, return code %d\n",
+ status, rc);
+ return -1;
+ }
+
+ switch (len) {
+ case 1:
+ *(uint8_t *)buf = data;
+ break;
+ case 2:
+ *(uint16_t *)buf = data;
+ break;
+ case 4:
+ *(uint32_t *)buf = data;
+ break;
+ case 8:
+ *(uint64_t *)buf = data;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 9c29548f849..a62fc9d7660 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
- virtio-ccw.o clp.o
+ virtio-ccw.o clp.o pci.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 19/25] pc-bios/s390-ccw: Introduce virtio-pci functions
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (17 preceding siblings ...)
2026-03-10 5:55 ` [PULL 18/25] pc-bios/s390-ccw: Introduce PCI device Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 20/25] pc-bios/s390-ccw: Add support for virtio-blk-pci IPL Thomas Huth
` (6 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Jared Rossi, Matthew Rosato, Eric Farman
From: Jared Rossi <jrossi@linux.ibm.com>
Define common functionality for interacting with virtio-pci devices.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Acked-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-ID: <20260309003601.242634-12-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/virtio-pci.h | 80 ++++++++++++++++
pc-bios/s390-ccw/virtio.h | 3 +
pc-bios/s390-ccw/virtio-pci.c | 167 ++++++++++++++++++++++++++++++++++
pc-bios/s390-ccw/Makefile | 2 +-
4 files changed, 251 insertions(+), 1 deletion(-)
create mode 100644 pc-bios/s390-ccw/virtio-pci.h
create mode 100644 pc-bios/s390-ccw/virtio-pci.c
diff --git a/pc-bios/s390-ccw/virtio-pci.h b/pc-bios/s390-ccw/virtio-pci.h
new file mode 100644
index 00000000000..54c524f6986
--- /dev/null
+++ b/pc-bios/s390-ccw/virtio-pci.h
@@ -0,0 +1,80 @@
+/*
+ * Definitions for virtio-pci
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef VIRTIO_PCI_H
+#define VIRTIO_PCI_H
+
+/* Common configuration */
+#define VPCI_CAP_COMMON_CFG 1
+/* Notifications */
+#define VPCI_CAP_NOTIFY_CFG 2
+/* ISR access */
+#define VPCI_CAP_ISR_CFG 3
+/* Device specific configuration */
+#define VPCI_CAP_DEVICE_CFG 4
+/* PCI configuration access */
+#define VPCI_CAP_PCI_CFG 5
+/* Additional shared memory capability */
+#define VPCI_CAP_SHARED_MEMORY_CFG 8
+/* PCI vendor data configuration */
+#define VPCI_CAP_VENDOR_CFG 9
+
+/* Offsets within capability header */
+#define VPCI_CAP_VNDR 0
+#define VPCI_CAP_NEXT 1
+#define VPCI_CAP_LEN 2
+#define VPCI_CAP_CFG_TYPE 3
+#define VPCI_CAP_BAR 4
+#define VPCI_CAP_OFFSET 8
+#define VPCI_CAP_LENGTH 12
+
+#define VPCI_N_CAP_MULT 16 /* Notify multiplier, VPCI_CAP_NOTIFY_CFG only */
+
+/* Common Area Offsets for virtio-pci queue */
+#define VPCI_C_OFFSET_DFSELECT 0
+#define VPCI_C_OFFSET_DF 4
+#define VPCI_C_OFFSET_GFSELECT 8
+#define VPCI_C_OFFSET_GF 12
+#define VPCI_C_COMMON_NUMQ 18
+#define VPCI_C_OFFSET_STATUS 20
+#define VPCI_C_OFFSET_Q_SELECT 22
+#define VPCI_C_OFFSET_Q_SIZE 24
+#define VPCI_C_OFFSET_Q_ENABLE 28
+#define VPCI_C_OFFSET_Q_NOFF 30
+#define VPCI_C_OFFSET_Q_DESCLO 32
+#define VPCI_C_OFFSET_Q_DESCHI 36
+#define VPCI_C_OFFSET_Q_AVAILLO 40
+#define VPCI_C_OFFSET_Q_AVAILHI 44
+#define VPCI_C_OFFSET_Q_USEDLO 48
+#define VPCI_C_OFFSET_Q_USEDHI 52
+
+#define VIRTIO_F_VERSION_1 1 /* Feature bit 32 */
+
+struct VirtioPciCap {
+ uint8_t bar; /* Which PCIAS it's in */
+ uint32_t off; /* Offset within bar */
+};
+typedef struct VirtioPciCap VirtioPciCap;
+
+void virtio_pci_id2type(VDev *vdev, uint16_t device_id);
+int virtio_pci_reset(VDev *vdev);
+long virtio_pci_notify(int vq_id);
+
+int vpci_read_flex(uint64_t offset, uint8_t pcias, void *buf, int len);
+int vpci_read_bswap64(uint64_t offset, uint8_t pcias, uint64_t *buf);
+int vpci_read_bswap32(uint64_t offset, uint8_t pcias, uint32_t *buf);
+int vpci_read_bswap16(uint64_t offset, uint8_t pcias, uint16_t *buf);
+int vpci_read_byte(uint64_t offset, uint8_t pcias, uint8_t *buf);
+
+int vpci_bswap64_write(uint64_t offset, uint8_t pcias, uint64_t data);
+int vpci_bswap32_write(uint64_t offset, uint8_t pcias, uint32_t data);
+int vpci_bswap16_write(uint64_t offset, uint8_t pcias, uint16_t data);
+int vpci_write_byte(uint64_t offset, uint8_t pcias, uint8_t data);
+
+#endif
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index c3cb5a6ee3b..1ef64675f4a 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -18,6 +18,8 @@
#define VIRTIO_CONFIG_S_DRIVER 2
/* Driver has used its parts of the config, and is happy */
#define VIRTIO_CONFIG_S_DRIVER_OK 4
+/* Feature negotiation complete */
+#define VIRTIO_CONFIG_S_FEATURES_OK 8
/* We've given up on this device. */
#define VIRTIO_CONFIG_S_FAILED 0x80
@@ -255,6 +257,7 @@ struct VDev {
uint8_t scsi_dev_heads;
bool scsi_device_selected;
ScsiDevice selected_scsi_device;
+ uint32_t pci_fh;
uint32_t max_transfer;
uint32_t guest_features[2];
};
diff --git a/pc-bios/s390-ccw/virtio-pci.c b/pc-bios/s390-ccw/virtio-pci.c
new file mode 100644
index 00000000000..f6ce7ec7661
--- /dev/null
+++ b/pc-bios/s390-ccw/virtio-pci.c
@@ -0,0 +1,167 @@
+/*
+ * Functionality for virtio-pci
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "clp.h"
+#include "pci.h"
+#include "helper.h"
+#include "virtio.h"
+#include "bswap.h"
+#include "virtio-pci.h"
+#include "s390-time.h"
+#include <stdio.h>
+
+/* Variable offsets used for reads/writes to modern memory regions */
+VirtioPciCap c_cap; /* Common capabilities */
+VirtioPciCap d_cap; /* Device capabilities */
+VirtioPciCap n_cap; /* Notify capabilities */
+uint32_t notify_mult;
+uint16_t q_notify_offset;
+
+static int virtio_pci_set_status(uint8_t status)
+{
+ int rc = vpci_write_byte(c_cap.off + VPCI_C_OFFSET_STATUS, c_cap.bar, status);
+ if (rc) {
+ puts("Failed to write virtio-pci status");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int virtio_pci_get_status(uint8_t *status)
+{
+ int rc = vpci_read_byte(c_cap.off + VPCI_C_OFFSET_STATUS, c_cap.bar, status);
+ if (rc) {
+ puts("Failed to read virtio-pci status");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/* virtio spec v1.3 section 4.1.2.1 */
+void virtio_pci_id2type(VDev *vdev, uint16_t device_id)
+{
+ switch (device_id) {
+ case 0x1042:
+ case 0x1001:
+ vdev->dev_type = VIRTIO_ID_BLOCK;
+ break;
+ default:
+ vdev->dev_type = 0;
+ }
+}
+
+int virtio_pci_reset(VDev *vdev)
+{
+ int rc;
+ uint8_t status = 0;
+
+ rc = virtio_pci_set_status(status);
+ rc |= virtio_pci_get_status(&status);
+
+ if (rc || status) {
+ puts("Failed to reset virtio-pci device");
+ return 1;
+ }
+
+ return 0;
+}
+
+long virtio_pci_notify(int vq_id)
+{
+ uint32_t offset = n_cap.off + notify_mult * q_notify_offset;
+ return vpci_bswap16_write(offset, n_cap.bar, (uint16_t) vq_id);
+}
+
+/*
+ * Wrappers to byte swap common data sizes then write
+ */
+int vpci_write_byte(uint64_t offset, uint8_t pcias, uint8_t data)
+{
+ return pci_write(virtio_get_device()->pci_fh, offset, pcias, (uint64_t) data, 1);
+}
+
+int vpci_bswap16_write(uint64_t offset, uint8_t pcias, uint16_t data)
+{
+ uint64_t le_data = bswap16(data);
+ return pci_write(virtio_get_device()->pci_fh, offset, pcias, le_data, 2);
+}
+
+int vpci_bswap32_write(uint64_t offset, uint8_t pcias, uint32_t data)
+{
+ uint64_t le_data = bswap32(data);
+ return pci_write(virtio_get_device()->pci_fh, offset, pcias, le_data, 4);
+}
+
+int vpci_bswap64_write(uint64_t offset, uint8_t pcias, uint64_t data)
+{
+ uint64_t le_data = bswap64(data);
+ return pci_write(virtio_get_device()->pci_fh, offset, pcias, le_data, 8);
+}
+
+/*
+ * Wrappers to read common data sizes then byte swap
+ */
+int vpci_read_byte(uint64_t offset, uint8_t pcias, uint8_t *buf)
+{
+ return pci_read(virtio_get_device()->pci_fh, offset, pcias, buf, 1);
+}
+
+int vpci_read_bswap16(uint64_t offset, uint8_t pcias, uint16_t *buf)
+{
+ int rc = pci_read(virtio_get_device()->pci_fh, offset, pcias, buf, 2);
+ *buf = bswap16(*buf);
+ return rc;
+}
+
+int vpci_read_bswap32(uint64_t offset, uint8_t pcias, uint32_t *buf)
+{
+ int rc = pci_read(virtio_get_device()->pci_fh, offset, pcias, buf, 4);
+ *buf = bswap32(*buf);
+ return rc;
+}
+
+int vpci_read_bswap64(uint64_t offset, uint8_t pcias, uint64_t *buf)
+{
+ int rc = pci_read(virtio_get_device()->pci_fh, offset, pcias, buf, 8);
+ *buf = bswap64(*buf);
+ return rc;
+}
+
+/*
+ * Read to an arbitrary length buffer without byte swapping
+ */
+int vpci_read_flex(uint64_t offset, uint8_t pcias, void *buf, int len)
+{
+ uint8_t readlen;
+ int rc;
+ int remaining = len;
+
+ /* Read bytes in powers of 2, up to a maximum of 8 bytes per read */
+ while (remaining) {
+ for (int i = 3; i >= 0; i--) {
+ readlen = 1 << i;
+ if (remaining >= readlen) {
+ break;
+ }
+ }
+
+ rc = pci_read(virtio_get_device()->pci_fh, offset, pcias, buf, readlen);
+ if (rc) {
+ return -1;
+ }
+
+ remaining -= readlen;
+ buf += readlen;
+ offset += readlen;
+ }
+
+ return 0;
+}
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index a62fc9d7660..3e5dfb64d5d 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
- virtio-ccw.o clp.o pci.o
+ virtio-ccw.o clp.o pci.o virtio-pci.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 20/25] pc-bios/s390-ccw: Add support for virtio-blk-pci IPL
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (18 preceding siblings ...)
2026-03-10 5:55 ` [PULL 19/25] pc-bios/s390-ccw: Introduce virtio-pci functions Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 21/25] s390x: Build IPLB for virtio-pci devices Thomas Huth
` (5 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Add little-endian virt-queue configuration and support for virtio-blk-pci IPL
devices.
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-13-jrossi@linux.ibm.com>
[thuth: Fix coding style error & spelling warning reported by checkpatch.pl]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/pci.h | 3 +
pc-bios/s390-ccw/virtio-pci.h | 2 +
pc-bios/s390-ccw/virtio.h | 1 +
pc-bios/s390-ccw/main.c | 61 ++++++-
pc-bios/s390-ccw/virtio-blkdev.c | 18 +++
pc-bios/s390-ccw/virtio-pci.c | 266 +++++++++++++++++++++++++++++++
pc-bios/s390-ccw/virtio.c | 54 ++++++-
7 files changed, 400 insertions(+), 5 deletions(-)
diff --git a/pc-bios/s390-ccw/pci.h b/pc-bios/s390-ccw/pci.h
index 968635eff11..b9eb86b2e67 100644
--- a/pc-bios/s390-ccw/pci.h
+++ b/pc-bios/s390-ccw/pci.h
@@ -26,8 +26,11 @@ union register_pair {
};
#define PCI_CFGBAR 0xF /* Base Address Register for config space */
+#define PCI_CMD_REG 0x4 /* Offset of command register */
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
+#define PCI_BUS_MASTER_MASK 0x0020 /* LE bit 3 of 16 bit register */
+
int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
uint8_t len);
int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
diff --git a/pc-bios/s390-ccw/virtio-pci.h b/pc-bios/s390-ccw/virtio-pci.h
index 54c524f6986..90d07cb9a76 100644
--- a/pc-bios/s390-ccw/virtio-pci.h
+++ b/pc-bios/s390-ccw/virtio-pci.h
@@ -65,6 +65,8 @@ typedef struct VirtioPciCap VirtioPciCap;
void virtio_pci_id2type(VDev *vdev, uint16_t device_id);
int virtio_pci_reset(VDev *vdev);
long virtio_pci_notify(int vq_id);
+int virtio_pci_setup(VDev *vdev);
+int virtio_pci_setup_device(void);
int vpci_read_flex(uint64_t offset, uint8_t pcias, void *buf, int len);
int vpci_read_bswap64(uint64_t offset, uint8_t pcias, uint64_t *buf);
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index 1ef64675f4a..d32a4830cad 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -273,6 +273,7 @@ struct VirtioCmd {
};
typedef struct VirtioCmd VirtioCmd;
+bool be_ipl(void);
void vring_init(VRing *vr, VqInfo *info);
bool virtio_is_supported(VDev *vdev);
bool vring_notify(VRing *vr);
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 32154c5db8d..26287cfd811 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -18,6 +18,8 @@
#include "virtio.h"
#include "virtio-scsi.h"
#include "dasd-ipl.h"
+#include "clp.h"
+#include "virtio-pci.h"
static SubChannelId blk_schid = { .one = 1 };
static char loadparm_str[LOADPARM_LEN + 1];
@@ -151,6 +153,21 @@ static bool find_subch(int dev_no)
return false;
}
+static bool find_fid(uint32_t fid)
+{
+ ClpFhListEntry entry;
+ VDev *vdev = virtio_get_device();
+
+ if (find_pci_function(fid, &entry)) {
+ return false;
+ }
+
+ vdev->pci_fh = entry.fh;
+ virtio_pci_id2type(vdev, entry.device_id);
+
+ return vdev->dev_type != 0;
+}
+
static void menu_setup(VDev *vdev)
{
if (memcmp(loadparm_str, LOADPARM_PROMPT, LOADPARM_LEN) == 0) {
@@ -240,6 +257,9 @@ static bool find_boot_device(void)
blk_schid.ssid = iplb.scsi.ssid & 0x3;
found = find_subch(iplb.scsi.devno);
break;
+ case S390_IPL_TYPE_PCI:
+ found = find_fid(iplb.pci.fid);
+ break;
default:
puts("Unsupported IPLB");
}
@@ -276,7 +296,7 @@ static int virtio_setup(void)
return ret;
}
-static void ipl_boot_device(void)
+static void ipl_ccw_device(void)
{
switch (cutype) {
case CU_TYPE_DASD_3990:
@@ -290,7 +310,44 @@ static void ipl_boot_device(void)
}
break;
default:
- printf("Attempting to boot from unexpected device type 0x%X\n", cutype);
+ printf("Cannot boot CCW device with cu type 0x%X\n", cutype);
+ }
+}
+
+static void ipl_pci_device(void)
+{
+ VDev *vdev = virtio_get_device();
+ vdev->is_cdrom = false;
+ vdev->scsi_device_selected = false;
+
+ if (virtio_pci_setup_device()) {
+ return;
+ }
+
+ switch (vdev->dev_type) {
+ case VIRTIO_ID_BLOCK:
+ if (virtio_setup() == 0) {
+ zipl_load(); /* only return on error */
+ virtio_reset(virtio_get_device());
+ }
+ break;
+ default:
+ printf("Cannot boot PCI device type 0x%X\n", vdev->dev_type);
+ }
+}
+
+static void ipl_boot_device(void)
+{
+ switch (virtio_get_device()->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ ipl_ccw_device();
+ break;
+ case S390_IPL_TYPE_PCI:
+ ipl_pci_device();
+ break;
+ default:
+ puts("Unrecognized IPL type!");
}
}
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 9722b6970f1..98b6cec3a09 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -13,10 +13,22 @@
#include "virtio.h"
#include "virtio-scsi.h"
#include "virtio-ccw.h"
+#include "virtio-pci.h"
+#include "bswap.h"
#define VIRTIO_BLK_F_GEOMETRY (1 << 4)
#define VIRTIO_BLK_F_BLK_SIZE (1 << 6)
+/*
+ * Format header for little endian IPL
+ */
+static void fmt_blk_hdr_le(VirtioBlkOuthdr *hdr)
+{
+ hdr->type = bswap32(hdr->type);
+ hdr->ioprio = bswap32(hdr->ioprio);
+ hdr->sector = bswap64(hdr->sector);
+}
+
static int virtio_blk_read_many(VDev *vdev, unsigned long sector, void *load_addr,
int sec_num)
{
@@ -29,6 +41,10 @@ static int virtio_blk_read_many(VDev *vdev, unsigned long sector, void *load_add
out_hdr.ioprio = 99;
out_hdr.sector = virtio_sector_adjust(sector);
+ if (!be_ipl()) {
+ fmt_blk_hdr_le(&out_hdr);
+ }
+
vring_send_buf(vr, &out_hdr, sizeof(out_hdr), VRING_DESC_F_NEXT);
/* This is where we want to receive data */
@@ -240,6 +256,8 @@ int virtio_blk_setup_device(VDev *vdev)
case S390_IPL_TYPE_QEMU_SCSI:
case S390_IPL_TYPE_CCW:
return virtio_ccw_setup(vdev);
+ case S390_IPL_TYPE_PCI:
+ return virtio_pci_setup(vdev);
default:
return 1;
}
diff --git a/pc-bios/s390-ccw/virtio-pci.c b/pc-bios/s390-ccw/virtio-pci.c
index f6ce7ec7661..53bdb52e76a 100644
--- a/pc-bios/s390-ccw/virtio-pci.c
+++ b/pc-bios/s390-ccw/virtio-pci.c
@@ -165,3 +165,269 @@ int vpci_read_flex(uint64_t offset, uint8_t pcias, void *buf, int len)
return 0;
}
+
+static int vpci_set_selected_vq(uint16_t queue_num)
+{
+ return vpci_bswap16_write(c_cap.off + VPCI_C_OFFSET_Q_SELECT, c_cap.bar, queue_num);
+}
+
+static int vpci_set_queue_enable(uint16_t enabled)
+{
+ return vpci_bswap16_write(c_cap.off + VPCI_C_OFFSET_Q_ENABLE, c_cap.bar, enabled);
+}
+
+static int set_pci_vq_addr(uint64_t config_off, void *addr)
+{
+ return vpci_bswap64_write(c_cap.off + config_off, c_cap.bar, (uint64_t) addr);
+}
+
+static int virtio_pci_get_blk_config(void)
+{
+ VirtioBlkConfig *cfg = &virtio_get_device()->config.blk;
+ int rc = vpci_read_flex(d_cap.off, d_cap.bar, cfg, sizeof(VirtioBlkConfig));
+
+ /* single byte fields are not touched */
+ cfg->capacity = bswap64(cfg->capacity);
+ cfg->size_max = bswap32(cfg->size_max);
+ cfg->seg_max = bswap32(cfg->seg_max);
+
+ cfg->geometry.cylinders = bswap16(cfg->geometry.cylinders);
+
+ cfg->blk_size = bswap32(cfg->blk_size);
+ cfg->min_io_size = bswap16(cfg->min_io_size);
+ cfg->opt_io_size = bswap32(cfg->opt_io_size);
+
+ return rc;
+}
+
+static int virtio_pci_negotiate(void)
+{
+ int i, rc;
+ VDev *vdev = virtio_get_device();
+ struct VirtioFeatureDesc {
+ uint32_t features;
+ uint8_t index;
+ } __attribute__((packed)) feats;
+
+ for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) {
+ feats.features = 0;
+ feats.index = i;
+
+ rc = vpci_bswap32_write(c_cap.off + VPCI_C_OFFSET_DFSELECT, c_cap.bar,
+ feats.index);
+ rc |= vpci_read_flex(c_cap.off + VPCI_C_OFFSET_DF, c_cap.bar, &feats, 4);
+
+ vdev->guest_features[i] &= bswap32(feats.features);
+ feats.features = vdev->guest_features[i];
+
+
+ rc |= vpci_bswap32_write(c_cap.off + VPCI_C_OFFSET_GFSELECT, c_cap.bar,
+ feats.index);
+ rc |= vpci_bswap32_write(c_cap.off + VPCI_C_OFFSET_GF, c_cap.bar,
+ feats.features);
+ }
+
+ return rc;
+}
+
+/*
+ * Find the position of the capability config within PCI configuration
+ * space for a given cfg type. Return the position if found, otherwise 0.
+ */
+static uint8_t virtio_pci_find_cap_pos(uint8_t cfg_type)
+{
+ uint8_t next, cfg;
+ int rc;
+
+ rc = vpci_read_byte(PCI_CAPABILITY_LIST, PCI_CFGBAR, &next);
+ rc |= vpci_read_byte(next + 3, PCI_CFGBAR, &cfg);
+
+ while (!rc && (cfg != cfg_type) && next) {
+ rc = vpci_read_byte(next + 1, PCI_CFGBAR, &next);
+ rc |= vpci_read_byte(next + 3, PCI_CFGBAR, &cfg);
+ }
+
+ return rc ? 0 : next;
+}
+
+/*
+ * Read PCI configuration space to find the offset of the Common, Device, and
+ * Notification memory regions within the modern memory space.
+ * Returns 0 if success, 1 if a capability could not be located, or a
+ * negative RC if the configuration read failed.
+ */
+static int virtio_pci_read_pci_cap_config(void)
+{
+ uint8_t pos;
+ int rc;
+
+ /* Common capabilities */
+ pos = virtio_pci_find_cap_pos(VPCI_CAP_COMMON_CFG);
+ if (!pos) {
+ puts("Failed to locate PCI common configuration");
+ return 1;
+ }
+
+ rc = vpci_read_byte(pos + VPCI_CAP_BAR, PCI_CFGBAR, &c_cap.bar);
+ if (rc || vpci_read_bswap32(pos + VPCI_CAP_OFFSET, PCI_CFGBAR, &c_cap.off)) {
+ puts("Failed to read PCI common configuration");
+ return -EIO;
+ }
+
+ /* Device capabilities */
+ pos = virtio_pci_find_cap_pos(VPCI_CAP_DEVICE_CFG);
+ if (!pos) {
+ puts("Failed to locate PCI device configuration");
+ return 1;
+ }
+
+ rc = vpci_read_byte(pos + VPCI_CAP_BAR, PCI_CFGBAR, &d_cap.bar);
+ if (rc || vpci_read_bswap32(pos + VPCI_CAP_OFFSET, PCI_CFGBAR, &d_cap.off)) {
+ puts("Failed to read PCI device configuration");
+ return -EIO;
+ }
+
+ /* Notification capabilities */
+ pos = virtio_pci_find_cap_pos(VPCI_CAP_NOTIFY_CFG);
+ if (!pos) {
+ puts("Failed to locate PCI notification configuration");
+ return 1;
+ }
+
+ rc = vpci_read_byte(pos + VPCI_CAP_BAR, PCI_CFGBAR, &n_cap.bar);
+ if (rc || vpci_read_bswap32(pos + VPCI_CAP_OFFSET, PCI_CFGBAR, &n_cap.off)) {
+ puts("Failed to read PCI notification configuration");
+ return -EIO;
+ }
+
+ rc = vpci_read_bswap32(pos + VPCI_N_CAP_MULT, PCI_CFGBAR, ¬ify_mult);
+ if (rc || vpci_read_bswap16(c_cap.off + VPCI_C_OFFSET_Q_NOFF, c_cap.bar,
+ &q_notify_offset)) {
+ puts("Failed to read notification queue configuration");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int enable_pci_bus_master(void)
+{
+ uint16_t cmd_reg;
+
+ if (vpci_read_bswap16(PCI_CMD_REG, PCI_CFGBAR, &cmd_reg)) {
+ puts("Failed to read PCI command register");
+ return -EIO;
+ }
+
+ if (vpci_bswap16_write(PCI_CMD_REG, PCI_CFGBAR, cmd_reg | PCI_BUS_MASTER_MASK)) {
+ puts("Failed to enable PCI bus mastering");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int virtio_pci_setup(VDev *vdev)
+{
+ VRing *vr;
+ int rc;
+ uint8_t status;
+ uint16_t vq_size;
+ int i = 0;
+
+ vdev->guessed_disk_nature = VIRTIO_GDN_NONE;
+ vdev->cmd_vr_idx = 0;
+
+ if (virtio_pci_read_pci_cap_config()) {
+ puts("Invalid virtio PCI capabilities");
+ return -EIO;
+ }
+
+ if (enable_pci_bus_master()) {
+ return -EIO;
+ }
+
+ if (virtio_reset(vdev)) {
+ return -EIO;
+ }
+
+ status = VIRTIO_CONFIG_S_ACKNOWLEDGE;
+ if (virtio_pci_set_status(status)) {
+ puts("Virtio-pci device Failed to ACKNOWLEDGE");
+ return -EIO;
+ }
+
+ vdev->guest_features[1] = VIRTIO_F_VERSION_1;
+ if (virtio_pci_negotiate()) {
+ panic("Virtio feature negotiation failed!");
+ }
+
+ switch (vdev->dev_type) {
+ case VIRTIO_ID_BLOCK:
+ vdev->nr_vqs = 1;
+ vdev->cmd_vr_idx = 0;
+ virtio_pci_get_blk_config();
+ break;
+ default:
+ puts("Unsupported virtio device");
+ return -ENODEV;
+ }
+
+ status |= VIRTIO_CONFIG_S_DRIVER;
+ rc = virtio_pci_set_status(status);
+ if (rc) {
+ puts("Set status failed");
+ return -EIO;
+ }
+
+ if (vpci_read_bswap16(VPCI_C_OFFSET_Q_SIZE, c_cap.bar, &vq_size)) {
+ puts("Failed to read virt-queue configuration");
+ return -EIO;
+ }
+
+ /* Configure virt-queues for pci */
+ for (i = 0; i < vdev->nr_vqs; i++) {
+ VqInfo info = {
+ .queue = (unsigned long long) virtio_get_ring_area(i),
+ .align = KVM_S390_VIRTIO_RING_ALIGN,
+ .index = i,
+ .num = vq_size,
+ };
+
+ vr = &vdev->vrings[i];
+ vring_init(vr, &info);
+
+ if (vpci_set_selected_vq(vr->id)) {
+ puts("Failed to set selected virt-queue");
+ return -EIO;
+ }
+
+ rc = set_pci_vq_addr(VPCI_C_OFFSET_Q_DESCLO, vr->desc);
+ rc |= set_pci_vq_addr(VPCI_C_OFFSET_Q_AVAILLO, vr->avail);
+ rc |= set_pci_vq_addr(VPCI_C_OFFSET_Q_USEDLO, vr->used);
+ if (rc) {
+ puts("Failed to configure virt-queue address");
+ return -EIO;
+ }
+
+ if (vpci_set_queue_enable(true)) {
+ puts("Failed to set virt-queue enabled");
+ return -EIO;
+ }
+ }
+
+ status |= VIRTIO_CONFIG_S_FEATURES_OK | VIRTIO_CONFIG_S_DRIVER_OK;
+ return virtio_pci_set_status(status);
+}
+
+int virtio_pci_setup_device(void)
+{
+ VDev *vdev = virtio_get_device();
+
+ if (enable_pci_function(&vdev->pci_fh)) {
+ puts("Failed to enable PCI function");
+ return -ENODEV;
+ }
+
+ return 0;
+}
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index 956b34ff33a..390b55c7b92 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -17,6 +17,7 @@
#include "virtio.h"
#include "virtio-scsi.h"
#include "virtio-ccw.h"
+#include "virtio-pci.h"
#include "bswap.h"
#include "helper.h"
#include "s390-time.h"
@@ -96,7 +97,7 @@ void vring_init(VRing *vr, VqInfo *info)
vr->avail->idx = 0;
/* We're running with interrupts off anyways, so don't bother */
- vr->used->flags = VRING_USED_F_NO_NOTIFY;
+ vr->used->flags = be_ipl() ? VRING_USED_F_NO_NOTIFY : bswap16(VRING_USED_F_NO_NOTIFY);
vr->used->idx = 0;
vr->used_idx = 0;
vr->next_idx = 0;
@@ -112,6 +113,8 @@ bool vring_notify(VRing *vr)
case S390_IPL_TYPE_CCW:
vr->cookie = virtio_ccw_notify(vdev.schid, vr->id, vr->cookie);
break;
+ case S390_IPL_TYPE_PCI:
+ vr->cookie = virtio_pci_notify(vr->id);
default:
return 1;
}
@@ -119,11 +122,45 @@ bool vring_notify(VRing *vr)
return vr->cookie >= 0;
}
+/*
+ * Get endienness of the IPL type
+ * Return true for s390x native big-endian
+ */
+bool be_ipl(void)
+{
+ switch (virtio_get_device()->ipl_type) {
+ case S390_IPL_TYPE_QEMU_SCSI:
+ case S390_IPL_TYPE_CCW:
+ return true;
+ case S390_IPL_TYPE_PCI:
+ return false;
+ default:
+ return true;
+ }
+}
+
+/*
+ * Format the virtio ring descriptor endianness
+ * Return the available index increment in the appropriate endianness
+ */
+static void vr_bswap_descriptor(VRingDesc *desc)
+{
+ desc->addr = bswap64(desc->addr);
+ desc->len = bswap32(desc->len);
+ desc->flags = bswap16(desc->flags);
+ desc->next = bswap16(desc->next);
+}
+
void vring_send_buf(VRing *vr, void *p, int len, int flags)
{
+ if (!be_ipl()) {
+ vr->avail->idx = bswap16(vr->avail->idx);
+ }
+
/* For follow-up chains we need to keep the first entry point */
if (!(flags & VRING_HIDDEN_IS_CHAIN)) {
- vr->avail->ring[vr->avail->idx % vr->num] = vr->next_idx;
+ vr->avail->ring[vr->avail->idx % vr->num] = be_ipl() ? vr->next_idx :
+ bswap16(vr->next_idx);
}
vr->desc[vr->next_idx].addr = (unsigned long)p;
@@ -131,12 +168,21 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags)
vr->desc[vr->next_idx].flags = flags & ~VRING_HIDDEN_IS_CHAIN;
vr->desc[vr->next_idx].next = vr->next_idx;
vr->desc[vr->next_idx].next++;
+
+ if (!be_ipl()) {
+ vr_bswap_descriptor(&vr->desc[vr->next_idx]);
+ }
+
vr->next_idx++;
/* Chains only have a single ID */
if (!(flags & VRING_DESC_F_NEXT)) {
vr->avail->idx++;
}
+
+ if (!be_ipl()) {
+ vr->avail->idx = bswap16(vr->avail->idx);
+ }
}
int vr_poll(VRing *vr)
@@ -147,7 +193,7 @@ int vr_poll(VRing *vr)
return 0;
}
- vr->used_idx = vr->used->idx;
+ vr->used_idx = vr->used->idx; /* Endianness is preserved */
vr->next_idx = 0;
vr->desc[0].len = 0;
vr->desc[0].flags = 0;
@@ -187,6 +233,8 @@ int virtio_reset(VDev *vdev)
case S390_IPL_TYPE_QEMU_SCSI:
case S390_IPL_TYPE_CCW:
return virtio_ccw_reset(vdev);
+ case S390_IPL_TYPE_PCI:
+ return virtio_pci_reset(vdev);
default:
return -1;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 21/25] s390x: Build IPLB for virtio-pci devices
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (19 preceding siblings ...)
2026-03-10 5:55 ` [PULL 20/25] pc-bios/s390-ccw: Add support for virtio-blk-pci IPL Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 22/25] hw: Add "loadparm" property to virtio block PCI devices booting on s390x Thomas Huth
` (4 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Eric Farman, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Search for a corresponding S390PCIBusDevice and build an IPLB if a device has
been indexed for boot but does not identify as a CCW device,
PCI devices are not yet included in boot probing (they must have a boot index).
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-14-jrossi@linux.ibm.com>
[thuth: Fix endianness issue when running on a little endian host]
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/ipl.h | 3 ++
include/hw/s390x/s390-pci-bus.h | 2 ++
hw/s390x/ipl.c | 56 ++++++++++++++++++++++++++++++---
hw/s390x/s390-pci-bus.c | 3 +-
4 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index c542d30ce2d..403cd08450d 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -107,6 +107,7 @@ QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define S390_IPLB_MIN_PV_LEN 148
#define S390_IPLB_MIN_CCW_LEN 200
#define S390_IPLB_MIN_FCP_LEN 384
+#define S390_IPLB_MIN_PCI_LEN 376
#define S390_IPLB_MIN_QEMU_SCSI_LEN 200
static inline bool iplb_valid_len(IplParameterBlock *iplb)
@@ -179,6 +180,8 @@ static inline bool iplb_valid(IplParameterBlock *iplb)
return len >= S390_IPLB_MIN_FCP_LEN;
case S390_IPL_TYPE_CCW:
return len >= S390_IPLB_MIN_CCW_LEN;
+ case S390_IPL_TYPE_PCI:
+ return len >= S390_IPLB_MIN_PCI_LEN;
case S390_IPL_TYPE_QEMU_SCSI:
default:
return false;
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
index f643e130579..9228523ce8e 100644
--- a/include/hw/s390x/s390-pci-bus.h
+++ b/include/hw/s390x/s390-pci-bus.h
@@ -402,6 +402,8 @@ S390PCIBusDevice *s390_pci_find_dev_by_fh(S390pciState *s, uint32_t fh);
S390PCIBusDevice *s390_pci_find_dev_by_fid(S390pciState *s, uint32_t fid);
S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s,
const char *target);
+S390PCIBusDevice *s390_pci_find_dev_by_pci(S390pciState *s,
+ PCIDevice *pci_dev);
S390PCIBusDevice *s390_pci_find_next_avail_dev(S390pciState *s,
S390PCIBusDevice *pbdev);
void s390_pci_ism_reset(void);
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index d34adb55220..7e09a8cf80d 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -28,6 +28,8 @@
#include "hw/s390x/ebcdic.h"
#include "hw/scsi/scsi.h"
#include "hw/virtio/virtio-net.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/s390x/s390-pci-bus.h"
#include "exec/cpu-common.h"
#include "ipl.h"
#include "qemu/error-report.h"
@@ -340,7 +342,8 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time);
}
-#define CCW_DEVTYPE_NONE 0x00
+#define S390_DEVTYPE_NONE 0x00
+
#define CCW_DEVTYPE_VIRTIO 0x01
#define CCW_DEVTYPE_VIRTIO_NET 0x02
#define CCW_DEVTYPE_SCSI 0x03
@@ -349,7 +352,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
{
CcwDevice *ccw_dev = NULL;
- int tmp_dt = CCW_DEVTYPE_NONE;
+ int tmp_dt = S390_DEVTYPE_NONE;
if (dev_st) {
VirtIONet *virtio_net_dev = (VirtIONet *)
@@ -396,6 +399,31 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
return ccw_dev;
}
+#define PCI_DEVTYPE_VIRTIO 0x05
+
+static S390PCIBusDevice *s390_get_pci_device(DeviceState *dev_st, int *devtype)
+{
+ S390PCIBusDevice *pbdev = NULL;
+ int tmp_dt = S390_DEVTYPE_NONE;
+
+ if (dev_st) {
+ PCIDevice *pci_dev = (PCIDevice *)
+ object_dynamic_cast(OBJECT(qdev_get_parent_bus(dev_st)->parent),
+ TYPE_VIRTIO_PCI);
+ if (pci_dev) {
+ pbdev = s390_pci_find_dev_by_pci(s390_get_phb(), pci_dev);
+ if (pbdev) {
+ tmp_dt = PCI_DEVTYPE_VIRTIO;
+ }
+ }
+ }
+ if (devtype) {
+ *devtype = tmp_dt;
+ }
+
+ return pbdev;
+}
+
static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain)
{
S390IPLState *ipl = get_ipl_device();
@@ -428,14 +456,12 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
{
CcwDevice *ccw_dev = NULL;
+ S390PCIBusDevice *pbdev = NULL;
SCSIDevice *sd;
int devtype;
uint8_t *lp;
g_autofree void *scsi_lp = NULL;
- /*
- * Currently allow IPL only from CCW devices.
- */
ccw_dev = s390_get_ccw_device(dev_st, &devtype);
if (ccw_dev) {
lp = ccw_dev->loadparm;
@@ -485,6 +511,26 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
return true;
}
+ pbdev = s390_get_pci_device(dev_st, &devtype);
+ if (pbdev) {
+ switch (devtype) {
+ case PCI_DEVTYPE_VIRTIO:
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_PCI_LEN);
+ iplb->pbt = S390_IPL_TYPE_PCI;
+ iplb->pci.fid = cpu_to_be32(pbdev->fid);
+ break;
+ default:
+ return false;
+ }
+
+ /* Per-device loadparm not yet supported for non-ccw IPL */
+ lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
+ s390_ipl_convert_loadparm((char *)lp, iplb->loadparm);
+ iplb->flags |= DIAG308_FLAGS_LP_VALID;
+
+ return true;
+ }
+
return false;
}
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 3166b91c461..4de7b587e8a 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -250,8 +250,7 @@ S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s,
return NULL;
}
-static S390PCIBusDevice *s390_pci_find_dev_by_pci(S390pciState *s,
- PCIDevice *pci_dev)
+S390PCIBusDevice *s390_pci_find_dev_by_pci(S390pciState *s, PCIDevice *pci_dev)
{
S390PCIBusDevice *pbdev;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 22/25] hw: Add "loadparm" property to virtio block PCI devices booting on s390x
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (20 preceding siblings ...)
2026-03-10 5:55 ` [PULL 21/25] s390x: Build IPLB for virtio-pci devices Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 23/25] tests/qtest: Add s390x PCI boot test to cdrom-test.c Thomas Huth
` (3 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
The loadparm is required on s390x to pass the information to the boot loader
such as which kernel should be started or whether the boot menu should be shown.
Because PCI devices do not naturally allocate space for this, the property is
added on an architecture specific basis for supported device types.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-15-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
include/hw/pci/pci.h | 1 +
include/hw/pci/pci_device.h | 3 +++
hw/pci/pci.c | 38 +++++++++++++++++++++++++++++++++++++
hw/s390x/ipl.c | 11 +++++++++--
hw/virtio/virtio-blk-pci.c | 1 +
5 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 64141e92fec..5b179091dee 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -380,6 +380,7 @@ const char *pci_root_bus_path(PCIDevice *dev);
bool pci_bus_bypass_iommu(PCIBus *bus);
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
int pci_qdev_find_device(const char *id, PCIDevice **pdev);
+void pci_qdev_property_add_specifics(DeviceClass *dc);
void pci_bus_get_w64_range(PCIBus *bus, Range *range);
void pci_device_deassert_intx(PCIDevice *dev);
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index 88ccea50113..5cac6e16886 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -62,6 +62,9 @@ struct PCIDevice {
bool partially_hotplugged;
bool enabled;
+ /* only for s390x */
+ char *loadparm;
+
/* PCI config space */
uint8_t *config;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 6399ebd41cb..2c3657d00de 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -36,6 +36,7 @@
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"
#include "net/net.h"
+#include "system/arch_init.h"
#include "system/numa.h"
#include "system/runstate.h"
#include "system/system.h"
@@ -2843,6 +2844,43 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
return rc;
}
+static char *pci_qdev_property_get_loadparm(Object *obj, Error **errp)
+{
+ return g_strdup(PCI_DEVICE(obj)->loadparm);
+}
+
+static void pci_qdev_property_set_loadparm(Object *obj, const char *value,
+ Error **errp)
+{
+ void *lp_str;
+
+ if (object_property_get_int(obj, "bootindex", NULL) < 0) {
+ error_setg(errp, "'loadparm' is only valid for boot devices");
+ return;
+ }
+
+ lp_str = g_malloc0(strlen(value) + 1);
+ if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) {
+ g_free(lp_str);
+ return;
+ }
+ PCI_DEVICE(obj)->loadparm = lp_str;
+}
+
+void pci_qdev_property_add_specifics(DeviceClass *dc)
+{
+ ObjectClass *oc = OBJECT_CLASS(dc);
+
+ /* The loadparm property is only supported on s390x */
+ if (target_s390x()) {
+ object_class_property_add_str(oc, "loadparm",
+ pci_qdev_property_get_loadparm,
+ pci_qdev_property_set_loadparm);
+ object_class_property_set_description(oc, "loadparm",
+ "load parameter (s390x only)");
+ }
+}
+
MemoryRegion *pci_address_space(PCIDevice *dev)
{
return pci_get_bus(dev)->address_space_mem;
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 7e09a8cf80d..1babcd2b7dd 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -461,6 +461,7 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
int devtype;
uint8_t *lp;
g_autofree void *scsi_lp = NULL;
+ g_autofree void *pci_lp = NULL;
ccw_dev = s390_get_ccw_device(dev_st, &devtype);
if (ccw_dev) {
@@ -513,6 +514,14 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
pbdev = s390_get_pci_device(dev_st, &devtype);
if (pbdev) {
+ pci_lp = object_property_get_str(OBJECT(pbdev->pdev), "loadparm", NULL);
+ if (pci_lp && strlen(pci_lp) > 0) {
+ lp = pci_lp;
+ } else {
+ /* Use machine loadparm as a place holder if PCI LP is unset */
+ lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
+ }
+
switch (devtype) {
case PCI_DEVTYPE_VIRTIO:
iplb->len = cpu_to_be32(S390_IPLB_MIN_PCI_LEN);
@@ -523,8 +532,6 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
return false;
}
- /* Per-device loadparm not yet supported for non-ccw IPL */
- lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
s390_ipl_convert_loadparm((char *)lp, iplb->loadparm);
iplb->flags |= DIAG308_FLAGS_LP_VALID;
diff --git a/hw/virtio/virtio-blk-pci.c b/hw/virtio/virtio-blk-pci.c
index 64a434c81b5..3eecc23a657 100644
--- a/hw/virtio/virtio-blk-pci.c
+++ b/hw/virtio/virtio-blk-pci.c
@@ -71,6 +71,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, const void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
device_class_set_props(dc, virtio_blk_pci_properties);
+ pci_qdev_property_add_specifics(dc);
k->realize = virtio_blk_pci_realize;
pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 23/25] tests/qtest: Add s390x PCI boot test to cdrom-test.c
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (21 preceding siblings ...)
2026-03-10 5:55 ` [PULL 22/25] hw: Add "loadparm" property to virtio block PCI devices booting on s390x Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 24/25] pc-bios/s390-ccw: Fix compiler warning when compiling with DEBUG enabled Thomas Huth
` (2 subsequent siblings)
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Jared Rossi
From: Jared Rossi <jrossi@linux.ibm.com>
Add a rudimentary test for s390x IPL to verify that a guest may boot using
virtio-blk-pci device.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20260309003601.242634-16-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
tests/qtest/cdrom-test.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
index 56e2d283a9d..a65854d2bc5 100644
--- a/tests/qtest/cdrom-test.c
+++ b/tests/qtest/cdrom-test.c
@@ -246,6 +246,13 @@ static void add_s390x_tests(void)
"-drive if=none,id=d2,media=cdrom,file=",
test_cdboot);
}
+ if (qtest_has_device("virtio-blk-pci")) {
+ qtest_add_data_func("cdrom/boot/pci-bus-with-bootindex",
+ "-device virtio-scsi -device virtio-serial "
+ "-device virtio-blk-pci,drive=d1,bootindex=1 "
+ "-drive if=none,id=d1,media=cdrom,file=",
+ test_cdboot);
+ }
}
int main(int argc, char **argv)
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 24/25] pc-bios/s390-ccw: Fix compiler warning when compiling with DEBUG enabled
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (22 preceding siblings ...)
2026-03-10 5:55 ` [PULL 23/25] tests/qtest: Add s390x PCI boot test to cdrom-test.c Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 5:55 ` [PULL 25/25] pc-bios/s390-ccw.img: Update the s390 bios blog with the latest changes Thomas Huth
2026-03-10 13:31 ` [PULL 00/25] s390x & functional tests pull request for the softfreeze Peter Maydell
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Farhan Ali
From: Thomas Huth <thuth@redhat.com>
When compiling with DEBUG=1, there is currently a compiler warning:
pc-bios/s390-ccw: Compiling main.o
In file included from /home/thuth/devel/qemu/pc-bios/s390-ccw/main.c:14:
In file included from /home/thuth/devel/qemu/pc-bios/s390-ccw/helper.h:16:
/home/thuth/devel/qemu/pc-bios/s390-ccw/s390-ccw.h:122:31: warning: format specifies type
'unsigned int' but the argument has type 'u64' (aka 'unsigned long long') [-Wformat]
122 | printf("%s 0x%X\n", desc, addr);
| ~~ ^~~~
| %llX
1 warning generated.
Fix it by using the right format string here.
Message-ID: <20260306203645.28232-1-thuth@redhat.com>
Reviewed-by: Farhan Ali<alifm@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw/s390-ccw.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index ccd68ff0a4b..1e1f71775ec 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -112,7 +112,7 @@ static inline void fill_hex_val(char *out, void *ptr, unsigned size)
static inline void debug_print_int(const char *desc, u64 addr)
{
#ifdef DEBUG
- printf("%s 0x%X\n", desc, addr);
+ printf("%s 0x%llx\n", desc, addr);
#endif
}
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PULL 25/25] pc-bios/s390-ccw.img: Update the s390 bios blog with the latest changes
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (23 preceding siblings ...)
2026-03-10 5:55 ` [PULL 24/25] pc-bios/s390-ccw: Fix compiler warning when compiling with DEBUG enabled Thomas Huth
@ 2026-03-10 5:55 ` Thomas Huth
2026-03-10 13:31 ` [PULL 00/25] s390x & functional tests pull request for the softfreeze Peter Maydell
25 siblings, 0 replies; 28+ messages in thread
From: Thomas Huth @ 2026-03-10 5:55 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
From: Thomas Huth <thuth@redhat.com>
- Make sure the reset virtio devices on failed boot attempts
- Add support for booting via virtio-blk-pci
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
pc-bios/s390-ccw.img | Bin 87824 -> 95992 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index ff60978d28c59a3d9ee706e48ff268aad6476ddc..48ac78c894592b655062fcf9513acc39d917f176 100644
GIT binary patch
literal 95992
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
P{y^P4+6Ge6_2K^mU6)D|
literal 87824
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
--
2.53.0
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PULL 00/25] s390x & functional tests pull request for the softfreeze
2026-03-10 5:55 [PULL 00/25] s390x & functional tests pull request for the softfreeze Thomas Huth
` (24 preceding siblings ...)
2026-03-10 5:55 ` [PULL 25/25] pc-bios/s390-ccw.img: Update the s390 bios blog with the latest changes Thomas Huth
@ 2026-03-10 13:31 ` Peter Maydell
25 siblings, 0 replies; 28+ messages in thread
From: Peter Maydell @ 2026-03-10 13:31 UTC (permalink / raw)
To: Thomas Huth; +Cc: qemu-devel
On Tue, 10 Mar 2026 at 05:55, Thomas Huth <thuth@redhat.com> wrote:
>
> The following changes since commit de61484ec39f418e5c0d4603017695f9ffb8fe24:
>
> Merge tag 'linux-user-for-v11-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2026-03-09 14:53:42 +0000)
>
> are available in the Git repository at:
>
> https://gitlab.com/thuth/qemu.git tags/pull-request-2026-03-10
>
> for you to fetch changes up to f2bd9693f22b105182b0bacdba390a0e41b2cf82:
>
> pc-bios/s390-ccw.img: Update the s390 bios blog with the latest changes (2026-03-10 06:46:45 +0100)
>
> ----------------------------------------------------------------
> - Improve the s390-ccw bios to be able to boot from virtio-blk-pci devices
> - Rework migration functional test to avoid a problem in the ppc64 test
> - Disable functional memlock test for asan builds
> - Some other minor tests improvements
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 28+ messages in thread