From fae7a427c787359fc4a3bc244541c5bd9e8e14bc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2024 10:27:21 +0200 Subject: meson: move shared_module() calls where modules are already walked Signed-off-by: Paolo Bonzini --- meson.build | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/meson.build b/meson.build index 54e6b09f4f..8909f8c87d 100644 --- a/meson.build +++ b/meson.build @@ -3602,6 +3602,7 @@ modinfo_files = [] block_mods = [] system_mods = [] +emulator_modules = [] foreach d, list : modules if not (d == 'block' ? have_block : have_system) continue @@ -3609,14 +3610,20 @@ foreach d, list : modules foreach m, module_ss : list if enable_modules + module_ss.add(modulecommon) module_ss = module_ss.apply(config_all_devices, strict: false) sl = static_library(d + '-' + m, [genh, module_ss.sources()], - dependencies: [modulecommon, module_ss.dependencies()], pic: true) + dependencies: module_ss.dependencies(), pic: true) if d == 'block' block_mods += sl else system_mods += sl endif + emulator_modules += shared_module(sl.name(), + name_prefix: '', + link_whole: sl, + install: true, + install_dir: qemu_moddir) if module_ss.sources() != [] # FIXME: Should use sl.extract_all_objects(recursive: true) as # input. Sources can be used multiple times but objects are @@ -3642,6 +3649,7 @@ endforeach foreach d, list : target_modules foreach m, module_ss : list if enable_modules + module_ss.add(modulecommon) foreach target : target_dirs if target.endswith('-softmmu') config_target = config_target_mak[target] @@ -3654,11 +3662,16 @@ foreach d, list : target_modules module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] sl = static_library(module_name, [genh, target_module_ss.sources()], - dependencies: [modulecommon, target_module_ss.dependencies()], + dependencies: target_module_ss.dependencies(), include_directories: target_inc, c_args: c_args, pic: true) system_mods += sl + emulator_modules += shared_module(sl.name(), + name_prefix: '', + link_whole: sl, + install: true, + install_dir: qemu_moddir) # FIXME: Should use sl.extract_all_objects(recursive: true) too. modinfo_files += custom_target(module_name + '.modinfo', output: module_name + '.modinfo', @@ -3692,6 +3705,10 @@ if enable_modules hw_arch[arch].add(modinfo_dep) endif endforeach + + if emulator_modules.length() > 0 + alias_target('modules', emulator_modules) + endif endif nm = find_program('nm') @@ -3785,19 +3802,6 @@ common_ss.add(hwcore) # Targets # ########### -emulator_modules = [] -foreach m : block_mods + system_mods - emulator_modules += shared_module(m.name(), - build_by_default: true, - name_prefix: '', - link_whole: m, - install: true, - install_dir: qemu_moddir) -endforeach -if emulator_modules.length() > 0 - alias_target('modules', emulator_modules) -endif - system_ss.add(authz, blockdev, chardev, crypto, io, qmp) common_ss.add(qom, qemuutil) -- cgit v1.2.3 From e8f62689acd5930a712655d0c6838ec5eccc6b1c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2024 13:17:08 +0200 Subject: meson: move block.syms dependency out of libblock In order to define libqemuutil symbols that are requested by block modules, QEMU currently uses a combination of the "link_depends" argument of libraries (which is propagated into dependencies, but not available in dependencies) and the "link_args" argument of declare_dependency() (which _is_ available in static_library, but probably not used for historical reasons only). Unfortunately the link_depends will not be propagated into the "block" dependency if it is defined using declare_dependency(objects: ...); and it is not possible to add it directly to the dependency because the keyword argument simply is not available. The only solution, in order to switch to defining the dependency without using "link_whole" (which has problems of its own, see https://github.com/mesonbuild/meson/pull/8151#issuecomment-754796420), is unfortunately to add the link_args and link_depends to the executables directly; fortunately there is just four of them. It is possible (and I will look into it) to add "link_depends" to declare_dependency(), but it probably will be a while before QEMU can use it. Signed-off-by: Paolo Bonzini --- meson.build | 5 +++-- storage-daemon/meson.build | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 8909f8c87d..df9a64302f 100644 --- a/meson.build +++ b/meson.build @@ -3759,12 +3759,10 @@ system_ss.add(migration) block_ss = block_ss.apply({}) libblock = static_library('block', block_ss.sources() + genh, dependencies: block_ss.dependencies(), - link_depends: block_syms, name_suffix: 'fa', build_by_default: false) block = declare_dependency(link_whole: [libblock], - link_args: '@block.syms', dependencies: [crypto, io]) blockdev_ss = blockdev_ss.apply({}) @@ -4033,10 +4031,13 @@ endif if have_tools qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], + link_args: '@block.syms', link_depends: block_syms, dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) qemu_io = executable('qemu-io', files('qemu-io.c'), + link_args: '@block.syms', link_depends: block_syms, dependencies: [block, qemuutil], install: true) qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), + link_args: '@block.syms', link_depends: block_syms, dependencies: [blockdev, qemuutil, gnutls, selinux], install: true) diff --git a/storage-daemon/meson.build b/storage-daemon/meson.build index 46267b63e7..fd5e32f4b2 100644 --- a/storage-daemon/meson.build +++ b/storage-daemon/meson.build @@ -8,6 +8,7 @@ if have_tools qsd_ss = qsd_ss.apply({}) qsd = executable('qemu-storage-daemon', qsd_ss.sources(), + link_args: '@block.syms', link_depends: block_syms, dependencies: qsd_ss.dependencies(), install: true) endif -- cgit v1.2.3 From 0082475e26430297ef65e598db5b67c8ac182620 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 6 Jun 2024 15:07:23 +0200 Subject: meson: merge plugin_ldflags into emulator_link_args These serve the same purpose, except plugin_ldflags ends up in the linker command line in a more roundabout way (through specific_ss). Simplify. Signed-off-by: Paolo Bonzini --- plugins/meson.build | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/meson.build b/plugins/meson.build index 51b4350c2a..18a0303bff 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -1,4 +1,3 @@ -plugin_ldflags = [] # Modules need more symbols than just those in plugins/qemu-plugins.symbols if not enable_modules if host_os == 'darwin' @@ -7,9 +6,9 @@ if not enable_modules output: 'qemu-plugins-ld64.symbols', capture: true, command: ['sed', '-ne', 's/^[[:space:]]*\\(qemu_.*\\);/_\\1/p', '@INPUT@']) - plugin_ldflags = ['-Wl,-exported_symbols_list,plugins/qemu-plugins-ld64.symbols'] + emulator_link_args += ['-Wl,-exported_symbols_list,plugins/qemu-plugins-ld64.symbols'] else - plugin_ldflags = ['-Xlinker', '--dynamic-list=' + (meson.project_source_root() / 'plugins/qemu-plugins.symbols')] + emulator_link_args += ['-Xlinker', '--dynamic-list=' + (meson.project_source_root() / 'plugins/qemu-plugins.symbols')] endif endif @@ -37,5 +36,5 @@ if get_option('plugins') 'loader.c', 'core.c', 'api.c', - ), declare_dependency(link_args: plugin_ldflags)) + )) endif -- cgit v1.2.3 From 414b180d42315dc77c02170f1eee8db58c9fe052 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Fri, 24 May 2024 17:00:22 +0900 Subject: meson: Pass objects and dependencies to declare_dependency() We used to request declare_dependency() to link_whole static libraries. If a static library is a thin archive, GNU ld keeps all object files referenced by the archive open, and sometimes exceeds the open file limit. Another problem with link_whole is that suboptimal handling of nested dependencies. link_whole by itself does not propagate dependencies. In particular, gnutls, a dependency of crypto, is not propagated to its users, and we currently workaround the issue by declaring gnutls as a dependency for each crypto user. On the other hand, if you write something like libfoo = static_library('foo', 'foo.c', dependencies: gnutls) foo = declare_dependency(link_whole: libfoo) libbar = static_library('bar', 'bar.c', dependencies: foo) bar = declare_dependency(link_whole: libbar, dependencies: foo) executable('prog', sources: files('prog.c'), dependencies: [foo, bar]) hoping to propagate the gnutls dependency into bar.c, you'll see a linking failure for "prog", because the foo.c.o object file is included in libbar.a and therefore it is linked twice into "prog": once from libfoo.a and once from libbar.a. Here Meson does not see the duplication, it just asks the linker to link all of libfoo.a and libbar.a into "prog". Instead of using link_whole, extract objects included in static libraries and pass them to declare_dependency(); and then the dependencies can be added as well so that they are propagated, because object files on the linker command line are always deduplicated. This requires Meson 1.1.0 or later. Signed-off-by: Akihiko Odaki Message-ID: <20240524-objects-v1-1-07cbbe96166b@daynix.com> Signed-off-by: Paolo Bonzini --- docs/devel/build-system.rst | 3 ++- gdbstub/meson.build | 4 ++-- meson.build | 44 ++++++++++++++++++++++++------------------ pythondeps.toml | 2 +- tcg/meson.build | 6 ++++-- tests/qtest/libqos/meson.build | 2 +- 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst index f4fd76117d..39a1934c63 100644 --- a/docs/devel/build-system.rst +++ b/docs/devel/build-system.rst @@ -238,7 +238,8 @@ Subsystem sourcesets: name_suffix: 'fa', build_by_default: false) - chardev = declare_dependency(link_whole: libchardev) + chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), + dependencies: chardev_ss.dependencies()) As of Meson 0.55.1, the special ``.fa`` suffix should be used for everything that is used with ``link_whole``, to ensure that the link flags are placed diff --git a/gdbstub/meson.build b/gdbstub/meson.build index da5721d845..c56b54eae7 100644 --- a/gdbstub/meson.build +++ b/gdbstub/meson.build @@ -28,9 +28,9 @@ libgdb_system = static_library('gdb_system', name_suffix: 'fa', build_by_default: false) -gdb_user = declare_dependency(link_whole: libgdb_user) +gdb_user = declare_dependency(objects: libgdb_user.extract_all_objects(recursive: false)) user_ss.add(gdb_user) -gdb_system = declare_dependency(link_whole: libgdb_system) +gdb_system = declare_dependency(objects: libgdb_system.extract_all_objects(recursive: false)) system_ss.add(gdb_system) common_ss.add(files('syscalls.c')) diff --git a/meson.build b/meson.build index df9a64302f..0c314ae570 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('qemu', ['c'], meson_version: '>=0.63.0', +project('qemu', ['c'], meson_version: '>=1.1.0', default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto', 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'], version: files('VERSION')) @@ -3461,7 +3461,7 @@ endif if enable_modules libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') - modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') + modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') endif qom_ss = qom_ss.apply({}) @@ -3469,14 +3469,15 @@ libqom = static_library('qom', qom_ss.sources() + genh, dependencies: [qom_ss.dependencies()], name_suffix: 'fa', build_by_default: false) -qom = declare_dependency(link_whole: libqom) +qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), + dependencies: qom_ss.dependencies()) event_loop_base = files('event-loop-base.c') event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh, name_suffix: 'fa', build_by_default: false) -event_loop_base = declare_dependency(link_whole: event_loop_base, +event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), dependencies: [qom]) stub_ss = stub_ss.apply({}) @@ -3621,7 +3622,8 @@ foreach d, list : modules endif emulator_modules += shared_module(sl.name(), name_prefix: '', - link_whole: sl, + objects: sl.extract_all_objects(recursive: false), + dependencies: module_ss.dependencies(), install: true, install_dir: qemu_moddir) if module_ss.sources() != [] @@ -3669,7 +3671,8 @@ foreach d, list : target_modules system_mods += sl emulator_modules += shared_module(sl.name(), name_prefix: '', - link_whole: sl, + objects: sl.extract_all_objects(recursive: false), + dependencies: target_module_ss.dependencies(), install: true, install_dir: qemu_moddir) # FIXME: Should use sl.extract_all_objects(recursive: true) too. @@ -3728,8 +3731,8 @@ libauthz = static_library('authz', authz_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -authz = declare_dependency(link_whole: libauthz, - dependencies: qom) +authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), + dependencies: [authz_ss.dependencies(), qom]) crypto_ss = crypto_ss.apply({}) libcrypto = static_library('crypto', crypto_ss.sources() + genh, @@ -3737,8 +3740,8 @@ libcrypto = static_library('crypto', crypto_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -crypto = declare_dependency(link_whole: libcrypto, - dependencies: [authz, qom]) +crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), + dependencies: [crypto_ss.dependencies(), authz, qom]) io_ss = io_ss.apply({}) libio = static_library('io', io_ss.sources() + genh, @@ -3747,12 +3750,13 @@ libio = static_library('io', io_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) +io = declare_dependency(objects: libio.extract_all_objects(recursive: false), + dependencies: [io_ss.dependencies(), crypto, qom]) libmigration = static_library('migration', sources: migration_files + genh, name_suffix: 'fa', build_by_default: false) -migration = declare_dependency(link_with: libmigration, +migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), dependencies: [qom, io]) system_ss.add(migration) @@ -3762,8 +3766,8 @@ libblock = static_library('block', block_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -block = declare_dependency(link_whole: [libblock], - dependencies: [crypto, io]) +block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), + dependencies: [block_ss.dependencies(), crypto, io]) blockdev_ss = blockdev_ss.apply({}) libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, @@ -3771,8 +3775,8 @@ libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -blockdev = declare_dependency(link_whole: [libblockdev], - dependencies: [block, event_loop_base]) +blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), + dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) qmp_ss = qmp_ss.apply({}) libqmp = static_library('qmp', qmp_ss.sources() + genh, @@ -3780,20 +3784,22 @@ libqmp = static_library('qmp', qmp_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -qmp = declare_dependency(link_whole: [libqmp]) +qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), + dependencies: qmp_ss.dependencies()) libchardev = static_library('chardev', chardev_ss.sources() + genh, name_suffix: 'fa', dependencies: chardev_ss.dependencies(), build_by_default: false) -chardev = declare_dependency(link_whole: libchardev) +chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), + dependencies: chardev_ss.dependencies()) hwcore_ss = hwcore_ss.apply({}) libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, name_suffix: 'fa', build_by_default: false) -hwcore = declare_dependency(link_whole: libhwcore) +hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) common_ss.add(hwcore) ########### diff --git a/pythondeps.toml b/pythondeps.toml index 9c16602d30..6aba0c9daa 100644 --- a/pythondeps.toml +++ b/pythondeps.toml @@ -19,7 +19,7 @@ [meson] # The install key should match the version in python/wheels/ -meson = { accepted = ">=0.63.0", installed = "1.2.3", canary = "meson" } +meson = { accepted = ">=1.1.0", installed = "1.2.3", canary = "meson" } [docs] # Please keep the installed versions in sync with docs/requirements.txt diff --git a/tcg/meson.build b/tcg/meson.build index ffbe754d8b..165e773abb 100644 --- a/tcg/meson.build +++ b/tcg/meson.build @@ -36,7 +36,8 @@ libtcg_user = static_library('tcg_user', c_args: '-DCONFIG_USER_ONLY', build_by_default: false) -tcg_user = declare_dependency(link_with: libtcg_user) +tcg_user = declare_dependency(objects: libtcg_user.extract_all_objects(recursive: false), + dependencies: tcg_ss.dependencies()) user_ss.add(tcg_user) libtcg_system = static_library('tcg_system', @@ -46,5 +47,6 @@ libtcg_system = static_library('tcg_system', c_args: '-DCONFIG_SOFTMMU', build_by_default: false) -tcg_system = declare_dependency(link_with: libtcg_system) +tcg_system = declare_dependency(objects: libtcg_system.extract_all_objects(recursive: false), + dependencies: tcg_ss.dependencies()) system_ss.add(tcg_system) diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 558eb4c24b..05fe57a4b9 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -72,4 +72,4 @@ libqos = static_library('qos', libqos_srcs + genh, name_suffix: 'fa', build_by_default: false) -qos = declare_dependency(link_whole: libqos) +qos = declare_dependency(objects: libqos.extract_all_objects(recursive: false)) -- cgit v1.2.3 From 7b1070a7e17cc65c3134350728c85e1d218c3578 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Fri, 24 May 2024 17:00:23 +0900 Subject: Revert "meson: Propagate gnutls dependency" This reverts commit 3eacf70bb5a83e4775ad8003cbca63a40f70c8c2. It was only needed because of duplicate objects caused by declare_dependency(link_whole: ...), and can be dropped now that meson.build specifies objects and dependencies separately for the internal dependencies. Signed-off-by: Akihiko Odaki Message-ID: <20240524-objects-v1-2-07cbbe96166b@daynix.com> Signed-off-by: Paolo Bonzini --- block/meson.build | 2 +- io/meson.build | 2 +- meson.build | 4 ++-- storage-daemon/meson.build | 2 +- ui/meson.build | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/block/meson.build b/block/meson.build index 158dc3b89d..f1262ec2ba 100644 --- a/block/meson.build +++ b/block/meson.build @@ -39,7 +39,7 @@ block_ss.add(files( 'throttle.c', 'throttle-groups.c', 'write-threshold.c', -), zstd, zlib, gnutls) +), zstd, zlib) system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c')) system_ss.add(files('block-ram-registrar.c')) diff --git a/io/meson.build b/io/meson.build index 283b9b2bdb..1164812f91 100644 --- a/io/meson.build +++ b/io/meson.build @@ -13,4 +13,4 @@ io_ss.add(files( 'dns-resolver.c', 'net-listener.c', 'task.c', -), gnutls) +)) diff --git a/meson.build b/meson.build index 0c314ae570..429899d860 100644 --- a/meson.build +++ b/meson.build @@ -3526,7 +3526,7 @@ if have_block 'blockdev-nbd.c', 'iothread.c', 'job-qmp.c', - ), gnutls) + )) # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, # os-win32.c does not @@ -4044,7 +4044,7 @@ if have_tools dependencies: [block, qemuutil], install: true) qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), link_args: '@block.syms', link_depends: block_syms, - dependencies: [blockdev, qemuutil, gnutls, selinux], + dependencies: [blockdev, qemuutil, selinux], install: true) subdir('storage-daemon') diff --git a/storage-daemon/meson.build b/storage-daemon/meson.build index fd5e32f4b2..5e61a9d1bd 100644 --- a/storage-daemon/meson.build +++ b/storage-daemon/meson.build @@ -1,6 +1,6 @@ qsd_ss = ss.source_set() qsd_ss.add(files('qemu-storage-daemon.c')) -qsd_ss.add(blockdev, chardev, qmp, qom, qemuutil, gnutls) +qsd_ss.add(blockdev, chardev, qmp, qom, qemuutil) subdir('qapi') diff --git a/ui/meson.build b/ui/meson.build index cfbf29428d..28c7381dd1 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -44,7 +44,7 @@ vnc_ss.add(files( 'vnc-jobs.c', 'vnc-clipboard.c', )) -vnc_ss.add(zlib, jpeg, gnutls) +vnc_ss.add(zlib, jpeg) vnc_ss.add(when: sasl, if_true: files('vnc-auth-sasl.c')) system_ss.add_all(when: [vnc, pixman], if_true: vnc_ss) system_ss.add(when: vnc, if_false: files('vnc-stubs.c')) -- cgit v1.2.3 From 4408155ac593644f04e22db0656d79a0e198be63 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2024 10:56:55 +0200 Subject: meson: Drop the .fa library suffix The non-standard .fa library suffix breaks the link source de-duplication done by Meson so drop it. The lack of link source de-duplication causes AddressSanitizer to complain ODR violations, and makes GNU ld abort when combined with clang's LTO. Fortunately, the non-standard suffix is not necessary anymore for two reasons. First, the non-standard suffix was necessary for fork-fuzzing. Meson wraps all standard-suffixed libraries with --start-group and --end-group. This made a fork-fuzz.ld linker script wrapped as well and broke builds. Commit d2e6f9272d33 ("fuzz: remove fork-fuzzing scaffolding") dropped fork-fuzzing so we can now restore the standard suffix. Second, the libraries are not even built anymore, because it is possible to just use the object files directly via extract_all_objects(). The occurences of the suffix were detected and removed by performing a tree-wide search with 'fa' and .fa (note the quotes and dot). Signed-off-by: Akihiko Odaki Message-ID: <20240524-xkb-v4-4-2de564e5c859@daynix.com> Signed-off-by: Paolo Bonzini --- .gitlab-ci.d/buildtest-template.yml | 2 -- .gitlab-ci.d/buildtest.yml | 2 -- docs/devel/build-system.rst | 5 ----- gdbstub/meson.build | 2 -- meson.build | 17 ++--------------- stubs/blk-exp-close-all.c | 2 +- tcg/meson.build | 2 -- tests/Makefile.include | 2 +- tests/qtest/libqos/meson.build | 1 - 9 files changed, 4 insertions(+), 31 deletions(-) diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml index 278a5ea966..8f7ebfaed8 100644 --- a/.gitlab-ci.d/buildtest-template.yml +++ b/.gitlab-ci.d/buildtest-template.yml @@ -45,10 +45,8 @@ exclude: - build/**/*.p - build/**/*.a.p - - build/**/*.fa.p - build/**/*.c.o - build/**/*.c.o.d - - build/**/*.fa .common_test_job_template: extends: .base_job_template diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index 0eec570310..425fc6479b 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -178,10 +178,8 @@ build-previous-qemu: exclude: - build-previous/**/*.p - build-previous/**/*.a.p - - build-previous/**/*.fa.p - build-previous/**/*.c.o - build-previous/**/*.c.o.d - - build-previous/**/*.fa needs: job: amd64-opensuse-leap-container variables: diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst index 39a1934c63..79eceb179d 100644 --- a/docs/devel/build-system.rst +++ b/docs/devel/build-system.rst @@ -235,16 +235,11 @@ Subsystem sourcesets: are then turned into static libraries as follows:: libchardev = static_library('chardev', chardev_ss.sources(), - name_suffix: 'fa', build_by_default: false) chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), dependencies: chardev_ss.dependencies()) - As of Meson 0.55.1, the special ``.fa`` suffix should be used for everything - that is used with ``link_whole``, to ensure that the link flags are placed - correctly in the command line. - Target-independent emulator sourcesets: Various general purpose helper code is compiled only once and the .o files are linked into all output binaries that need it. diff --git a/gdbstub/meson.build b/gdbstub/meson.build index c56b54eae7..dff741ddd4 100644 --- a/gdbstub/meson.build +++ b/gdbstub/meson.build @@ -19,13 +19,11 @@ gdb_system_ss = gdb_system_ss.apply({}) libgdb_user = static_library('gdb_user', gdb_user_ss.sources() + genh, - name_suffix: 'fa', c_args: '-DCONFIG_USER_ONLY', build_by_default: false) libgdb_system = static_library('gdb_system', gdb_system_ss.sources() + genh, - name_suffix: 'fa', build_by_default: false) gdb_user = declare_dependency(objects: libgdb_user.extract_all_objects(recursive: false)) diff --git a/meson.build b/meson.build index 429899d860..3a1ad4ddeb 100644 --- a/meson.build +++ b/meson.build @@ -3467,7 +3467,6 @@ endif qom_ss = qom_ss.apply({}) libqom = static_library('qom', qom_ss.sources() + genh, dependencies: [qom_ss.dependencies()], - name_suffix: 'fa', build_by_default: false) qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), dependencies: qom_ss.dependencies()) @@ -3475,7 +3474,6 @@ qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), event_loop_base = files('event-loop-base.c') event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh, - name_suffix: 'fa', build_by_default: false) event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), dependencies: [qom]) @@ -3728,7 +3726,6 @@ qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', authz_ss = authz_ss.apply({}) libauthz = static_library('authz', authz_ss.sources() + genh, dependencies: [authz_ss.dependencies()], - name_suffix: 'fa', build_by_default: false) authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), @@ -3737,7 +3734,6 @@ authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: fals crypto_ss = crypto_ss.apply({}) libcrypto = static_library('crypto', crypto_ss.sources() + genh, dependencies: [crypto_ss.dependencies()], - name_suffix: 'fa', build_by_default: false) crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), @@ -3747,14 +3743,12 @@ io_ss = io_ss.apply({}) libio = static_library('io', io_ss.sources() + genh, dependencies: [io_ss.dependencies()], link_with: libqemuutil, - name_suffix: 'fa', build_by_default: false) io = declare_dependency(objects: libio.extract_all_objects(recursive: false), dependencies: [io_ss.dependencies(), crypto, qom]) libmigration = static_library('migration', sources: migration_files + genh, - name_suffix: 'fa', build_by_default: false) migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), dependencies: [qom, io]) @@ -3763,7 +3757,6 @@ system_ss.add(migration) block_ss = block_ss.apply({}) libblock = static_library('block', block_ss.sources() + genh, dependencies: block_ss.dependencies(), - name_suffix: 'fa', build_by_default: false) block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), @@ -3772,7 +3765,6 @@ block = declare_dependency(objects: libblock.extract_all_objects(recursive: fals blockdev_ss = blockdev_ss.apply({}) libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, dependencies: blockdev_ss.dependencies(), - name_suffix: 'fa', build_by_default: false) blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), @@ -3781,14 +3773,12 @@ blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive qmp_ss = qmp_ss.apply({}) libqmp = static_library('qmp', qmp_ss.sources() + genh, dependencies: qmp_ss.dependencies(), - name_suffix: 'fa', build_by_default: false) qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), dependencies: qmp_ss.dependencies()) libchardev = static_library('chardev', chardev_ss.sources() + genh, - name_suffix: 'fa', dependencies: chardev_ss.dependencies(), build_by_default: false) @@ -3797,7 +3787,6 @@ chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: hwcore_ss = hwcore_ss.apply({}) libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, - name_suffix: 'fa', build_by_default: false) hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) common_ss.add(hwcore) @@ -3820,8 +3809,7 @@ common_all = static_library('common', sources: common_ss.all_sources() + genh, include_directories: common_user_inc, implicit_include_directories: false, - dependencies: common_ss.all_dependencies(), - name_suffix: 'fa') + dependencies: common_ss.all_dependencies()) feature_to_c = find_program('scripts/feature_to_c.py') @@ -3930,8 +3918,7 @@ foreach target : target_dirs objects: objects, include_directories: target_inc, c_args: c_args, - build_by_default: false, - name_suffix: 'fa') + build_by_default: false) if target.endswith('-softmmu') execs = [{ diff --git a/stubs/blk-exp-close-all.c b/stubs/blk-exp-close-all.c index 1c71316763..2f68e06d7d 100644 --- a/stubs/blk-exp-close-all.c +++ b/stubs/blk-exp-close-all.c @@ -1,7 +1,7 @@ #include "qemu/osdep.h" #include "block/export.h" -/* Only used in programs that support block exports (libblockdev.fa) */ +/* Only used in programs that support block exports (libblockdev.a) */ void blk_exp_close_all(void) { } diff --git a/tcg/meson.build b/tcg/meson.build index 165e773abb..69ebb4908a 100644 --- a/tcg/meson.build +++ b/tcg/meson.build @@ -31,7 +31,6 @@ tcg_ss = tcg_ss.apply({}) libtcg_user = static_library('tcg_user', tcg_ss.sources() + genh, - name_suffix: 'fa', dependencies: tcg_ss.dependencies(), c_args: '-DCONFIG_USER_ONLY', build_by_default: false) @@ -42,7 +41,6 @@ user_ss.add(tcg_user) libtcg_system = static_library('tcg_system', tcg_ss.sources() + genh, - name_suffix: 'fa', dependencies: tcg_ss.dependencies(), c_args: '-DCONFIG_SOFTMMU', build_by_default: false) diff --git a/tests/Makefile.include b/tests/Makefile.include index c9d1674bd0..d39d5dd6a4 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -87,7 +87,7 @@ distclean-tcg: $(DISTCLEAN_TCG_TARGET_RULES) .PHONY: check-venv check-avocado check-acceptance check-acceptance-deprecated-warning # Build up our target list from the filtered list of ninja targets -TARGETS=$(patsubst libqemu-%.fa, %, $(filter libqemu-%.fa, $(ninja-targets))) +TARGETS=$(patsubst libqemu-%.a, %, $(filter libqemu-%.a, $(ninja-targets))) TESTS_VENV_TOKEN=$(BUILD_DIR)/pyvenv/tests.group TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 05fe57a4b9..1b2b2dbb22 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -69,7 +69,6 @@ if have_virtfs endif libqos = static_library('qos', libqos_srcs + genh, - name_suffix: 'fa', build_by_default: false) qos = declare_dependency(objects: libqos.extract_all_objects(recursive: false)) -- cgit v1.2.3 From 8dee38483274bd0fcf3f74dea024d719b958200d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 Jun 2024 01:12:42 +0200 Subject: target/i386: pass X86CPU to x86_cpu_get_supported_feature_word This allows modifying the bits in "-cpu max"/"-cpu host" depending on the guest CPU vendor (which, at least by default, is the host vendor in the case of KVM). For example, machine check architecture differs between Intel and AMD, and bits from AMD should be dropped when configuring the guest for an Intel model. Cc: Xiaoyao Li Cc: John Allen Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 11 +++++------ target/i386/cpu.h | 3 +-- target/i386/kvm/kvm-cpu.c | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 4c2e6f3a71..4364cb0f8e 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6035,8 +6035,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) #endif /* !CONFIG_USER_ONLY */ -uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - bool migratable_only) +uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w) { FeatureWordInfo *wi = &feature_word_info[w]; uint64_t r = 0; @@ -6078,7 +6077,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, r &= ~unavail; } #endif - if (migratable_only) { + if (cpu && cpu->migratable) { r &= x86_cpu_get_migratable_flags(w); } return r; @@ -7371,7 +7370,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) * by the user. */ env->features[w] |= - x86_cpu_get_supported_feature_word(w, cpu->migratable) & + x86_cpu_get_supported_feature_word(cpu, w) & ~env->user_features[w] & ~feature_word_info[w].no_autoenable_flags; } @@ -7497,7 +7496,7 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) for (w = 0; w < FEATURE_WORDS; w++) { uint64_t host_feat = - x86_cpu_get_supported_feature_word(w, false); + x86_cpu_get_supported_feature_word(NULL, w); uint64_t requested_features = env->features[w]; uint64_t unavailable_features = requested_features & ~host_feat; mark_unavailable_features(cpu, w, unavailable_features, prefix); @@ -7617,7 +7616,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) env->features[FEAT_PERF_CAPABILITIES] & PERF_CAP_LBR_FMT; if (requested_lbr_fmt && kvm_enabled()) { uint64_t host_perf_cap = - x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES, false); + x86_cpu_get_supported_feature_word(NULL, FEAT_PERF_CAPABILITIES); unsigned host_lbr_fmt = host_perf_cap & PERF_CAP_LBR_FMT; if (!cpu->enable_pmu) { diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 29daf37048..9bea7142bf 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -666,8 +666,7 @@ typedef enum FeatureWord { } FeatureWord; typedef uint64_t FeatureWordArray[FEATURE_WORDS]; -uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - bool migratable_only); +uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); /* cpuid_features bits */ #define CPUID_FP87 (1U << 0) diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index d57a68a301..6bf8dcfc60 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -143,7 +143,7 @@ static void kvm_cpu_xsave_init(void) if (!esa->size) { continue; } - if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits) + if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits) != esa->bits) { continue; } -- cgit v1.2.3 From 0b2757412cb1d1947d7e2c1fe14985f1e72bba32 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 Jun 2024 01:13:08 +0200 Subject: target/i386: drop AMD machine check bits from Intel CPUID The recent addition of the SUCCOR bit to kvm_arch_get_supported_cpuid() causes the bit to be visible when "-cpu host" VMs are started on Intel processors. While this should in principle be harmless, it's not tidy and we don't even know for sure that it doesn't cause any guest OS to take unexpected paths. Since x86_cpu_get_supported_feature_word() can return different different values depending on the guest, adjust it to hide the SUCCOR bit if the guest has non-AMD vendor. Suggested-by: Xiaoyao Li Cc: John Allen Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 4364cb0f8e..5e5bf71702 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6039,6 +6039,7 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w) { FeatureWordInfo *wi = &feature_word_info[w]; uint64_t r = 0; + uint32_t unavail = 0; if (kvm_enabled()) { switch (wi->type) { @@ -6064,19 +6065,33 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w) } else { return ~0; } + + switch (w) { #ifndef TARGET_X86_64 - if (w == FEAT_8000_0001_EDX) { + case FEAT_8000_0001_EDX: /* * 32-bit TCG can emulate 64-bit compatibility mode. If there is no * way for userspace to get out of its 32-bit jail, we can leave * the LM bit set. */ - uint32_t unavail = tcg_enabled() + unavail = tcg_enabled() ? CPUID_EXT2_LM & ~CPUID_EXT2_KERNEL_FEATURES : CPUID_EXT2_LM; - r &= ~unavail; - } + break; #endif + + case FEAT_8000_0007_EBX: + if (cpu && !IS_AMD_CPU(&cpu->env)) { + /* Disable AMD machine check architecture for Intel CPU. */ + unavail = ~0; + } + break; + + default: + break; + } + + r &= ~unavail; if (cpu && cpu->migratable) { r &= x86_cpu_get_migratable_flags(w); } -- cgit v1.2.3 From 9b40d376f66640eb7b6080ca000c866dfe630dc7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Jul 2024 10:37:23 +0200 Subject: target/i386: SEV: fix formatting of CPUID mismatch message Fixes: 70943ad8e4d ("i386/sev: Add support for SNP CPUID validation", 2024-06-05) Signed-off-by: Paolo Bonzini --- target/i386/sev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/i386/sev.c b/target/i386/sev.c index 3ab8b3c28b..2a0f94d390 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -841,7 +841,7 @@ sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old, size_t i; if (old->count != new->count) { - error_report("SEV-SNP: CPUID validation failed due to count mismatch," + error_report("SEV-SNP: CPUID validation failed due to count mismatch, " "provided: %d, expected: %d", old->count, new->count); return; } @@ -853,8 +853,8 @@ sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old, new_func = &new->entries[i]; if (memcmp(old_func, new_func, sizeof(SnpCpuidFunc))) { - error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x" - "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x" + error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x, " + "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x, " "expected: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x", old_func->eax_in, old_func->ecx_in, old_func->eax, old_func->ebx, old_func->ecx, old_func->edx, -- cgit v1.2.3 From 29a51b2bb55c6b2e0224d82c154d82498ccece35 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Jul 2024 11:29:17 +0200 Subject: target/i386: do not include undefined bits in the AMD topoext leaf Commit d7c72735f61 ("target/i386: Add new EPYC CPU versions with updated cache_info", 2023-05-08) ensured that AMD-defined CPU models did not have the 'complex_indexing' bit set, but left it set in "-cpu host" which uses the default ("legacy") cache information. Reimplement that commit using a CPU feature, so that it can be applied to all guests using a new machine type, independent of the CPU model. Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 1 + target/i386/cpu.c | 4 ++++ target/i386/cpu.h | 3 +++ 3 files changed, 8 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 77415064c6..5dff91422f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -80,6 +80,7 @@ { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, }, GlobalProperty pc_compat_9_0[] = { + { TYPE_X86_CPU, "x-amd-topoext-features-only", "false" }, { TYPE_X86_CPU, "x-l1-cache-per-thread", "false" }, { TYPE_X86_CPU, "guest-phys-bits", "0" }, { "sev-guest", "legacy-vm-type", "true" }, diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 5e5bf71702..c40551d9bf 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6982,6 +6982,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax = *ebx = *ecx = *edx = 0; break; } + if (cpu->amd_topoext_features_only) { + *edx &= CACHE_NO_INVD_SHARING | CACHE_INCLUSIVE; + } break; case 0x8000001E: if (cpu->core_id <= 255) { @@ -8293,6 +8296,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor), DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true), DEFINE_PROP_BOOL("x-vendor-cpuid-only", X86CPU, vendor_cpuid_only, true), + DEFINE_PROP_BOOL("x-amd-topoext-features-only", X86CPU, amd_topoext_features_only, true), DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false), DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true), DEFINE_PROP_BOOL("kvm-pv-enforce-cpuid", X86CPU, kvm_pv_enforce_cpuid, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 9bea7142bf..0d5624355e 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2104,6 +2104,9 @@ struct ArchCPU { /* Only advertise CPUID leaves defined by the vendor */ bool vendor_cpuid_only; + /* Only advertise TOPOEXT features that AMD defines */ + bool amd_topoext_features_only; + /* Enable auto level-increase for Intel Processor Trace leave */ bool intel_pt_auto_level; -- cgit v1.2.3 From ab5f4edf721fc0403d40a4db7e96808175157def Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 24 Jun 2024 10:52:48 +0200 Subject: i386/sev: Fix error message in sev_get_capabilities() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a custom path is provided to sev-guest object and opening the path fails an error message is reported. But the error message still mentions DEFAULT_SEV_DEVICE ("/dev/sev") instead of the custom path. Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0 Signed-off-by: Michal Privoznik Reviewed-by: Philippe Mathieu-Daudé Link: https://lore.kernel.org/r/b4648905d399780063dc70851d3d6a3cd28719a5.1719218926.git.mprivozn@redhat.com Signed-off-by: Paolo Bonzini --- target/i386/sev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/sev.c b/target/i386/sev.c index 2a0f94d390..054366878a 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -597,7 +597,7 @@ static SevCapability *sev_get_capabilities(Error **errp) fd = open(sev_device, O_RDWR); if (fd < 0) { error_setg_errno(errp, errno, "SEV: Failed to open %s", - DEFAULT_SEV_DEVICE); + sev_device); g_free(sev_device); return NULL; } -- cgit v1.2.3 From f4e5f302b3361f13349b2a44378e7cf578a8e012 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 24 Jun 2024 10:52:49 +0200 Subject: i386/sev: Fallback to the default SEV device if none provided in sev_get_capabilities() When management tools (e.g. libvirt) query QEMU capabilities, they start QEMU with a minimalistic configuration and issue various commands on monitor. One of the command issued is/might be "query-sev-capabilities" to learn values like cbitpos or reduced-phys-bits. But as of v9.0.0-1145-g16dcf200dc the monitor command returns an error instead. This creates a chicken-egg problem because in order to query those aforementioned values QEMU needs to be started with a 'sev-guest' object. But to start QEMU with the values must be known. I think it's safe to assume that the default path ("/dev/sev") provides the same data as user provided one. So fall back to it. Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0 Signed-off-by: Michal Privoznik Link: https://lore.kernel.org/r/157f93712c23818be193ce785f648f0060b33dee.1719218926.git.mprivozn@redhat.com Signed-off-by: Paolo Bonzini --- target/i386/sev.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target/i386/sev.c b/target/i386/sev.c index 054366878a..2f3dbe289f 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -587,13 +587,13 @@ static SevCapability *sev_get_capabilities(Error **errp) } sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - if (!sev_common) { - error_setg(errp, "SEV is not configured"); - return NULL; + if (sev_common) { + sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", + &error_abort); + } else { + sev_device = g_strdup(DEFAULT_SEV_DEVICE); } - sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", - &error_abort); fd = open(sev_device, O_RDWR); if (fd < 0) { error_setg_errno(errp, errno, "SEV: Failed to open %s", -- cgit v1.2.3 From 138c3377a9b27accec516b2c0da90dedef98a780 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Jul 2024 13:42:49 +0200 Subject: target/i386: add avx-vnni-int16 feature AVX-VNNI-INT16 (CPUID[EAX=7,ECX=1).EDX[10]) is supported by Clearwater Forest processor, add it to QEMU as it does not need any specific enablement. Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index c40551d9bf..c05765eeaf 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1131,7 +1131,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .feat_names = { NULL, NULL, NULL, NULL, "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - "amx-complex", NULL, NULL, NULL, + "amx-complex", NULL, "avx-vnni-int16", NULL, NULL, NULL, "prefetchiti", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -- cgit v1.2.3 From a0124e333e2176640f233e5ea57a2f413985d9b5 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Wed, 3 Jul 2024 22:08:12 +0300 Subject: char-stdio: Restore blocking mode of stdout on exit qemu_chr_open_fd() sets stdout into non-blocking mode. Restore the old fd flags on exit to avoid breaking unsuspecting applications that run on the same terminal after qemu and don't expect to get EAGAIN. While at at, also ensure term_exit is called once (at the moment it's called both from char_stdio_finalize() and as the atexit() hook. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2423 Signed-off-by: Maxim Mikityanskiy Link: https://lore.kernel.org/r/20240703190812.3459514-1-maxtram95@gmail.com Signed-off-by: Paolo Bonzini --- chardev/char-stdio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c index 3c648678ab..b960ddd4e4 100644 --- a/chardev/char-stdio.c +++ b/chardev/char-stdio.c @@ -41,6 +41,7 @@ /* init terminal so that we can grab keys */ static struct termios oldtty; static int old_fd0_flags; +static int old_fd1_flags; static bool stdio_in_use; static bool stdio_allow_signal; static bool stdio_echo_state; @@ -50,6 +51,8 @@ static void term_exit(void) if (stdio_in_use) { tcsetattr(0, TCSANOW, &oldtty); fcntl(0, F_SETFL, old_fd0_flags); + fcntl(1, F_SETFL, old_fd1_flags); + stdio_in_use = false; } } @@ -102,6 +105,7 @@ static void qemu_chr_open_stdio(Chardev *chr, stdio_in_use = true; old_fd0_flags = fcntl(0, F_GETFL); + old_fd1_flags = fcntl(1, F_GETFL); tcgetattr(0, &oldtty); if (!g_unix_set_fd_nonblocking(0, true, NULL)) { error_setg_errno(errp, errno, "Failed to set FD nonblocking"); -- cgit v1.2.3 From c28d8b097f6da0389d0e915e26ab210aaac38ba0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Jul 2024 11:12:06 +0200 Subject: target/i386: add support for masking CPUID features in confidential guests Some CPUID features may be provided by KVM for some guests, independent of processor support, for example TSC deadline or TSC adjust. If these are not supported by the confidential computing firmware, however, the guest will fail to start. Add support for removing unsupported features from "-cpu host". Signed-off-by: Paolo Bonzini --- target/i386/confidential-guest.h | 24 ++++++++++++++++++++++++ target/i386/kvm/kvm.c | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h index 532e172a60..7342d2843a 100644 --- a/target/i386/confidential-guest.h +++ b/target/i386/confidential-guest.h @@ -39,6 +39,8 @@ struct X86ConfidentialGuestClass { /* */ int (*kvm_type)(X86ConfidentialGuest *cg); + uint32_t (*mask_cpuid_features)(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, + int reg, uint32_t value); }; /** @@ -56,4 +58,26 @@ static inline int x86_confidential_guest_kvm_type(X86ConfidentialGuest *cg) return 0; } } + +/** + * x86_confidential_guest_mask_cpuid_features: + * + * Removes unsupported features from a confidential guest's CPUID values, returns + * the value with the bits removed. The bits removed should be those that KVM + * provides independent of host-supported CPUID features, but are not supported by + * the confidential computing firmware. + */ +static inline int x86_confidential_guest_mask_cpuid_features(X86ConfidentialGuest *cg, + uint32_t feature, uint32_t index, + int reg, uint32_t value) +{ + X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg); + + if (klass->mask_cpuid_features) { + return klass->mask_cpuid_features(cg, feature, index, reg, value); + } else { + return value; + } +} + #endif diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index dd8b0f3313..056d117cd1 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -548,6 +548,11 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, ret |= 1U << KVM_HINTS_REALTIME; } + if (current_machine->cgs) { + ret = x86_confidential_guest_mask_cpuid_features( + X86_CONFIDENTIAL_GUEST(current_machine->cgs), + function, index, reg, ret); + } return ret; } -- cgit v1.2.3 From 188569c10d5dc6996bde90ce25645083e9661ecb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Jul 2024 11:16:56 +0200 Subject: target/i386/SEV: implement mask_cpuid_features Drop features that are listed as "BitMask" in the PPR and currently not supported by AMD processors. The only ones that may become useful in the future are TSC deadline timer and x2APIC, everything else is not needed for SEV-SNP guests (e.g. VIRT_SSBD) or would require processor support (e.g. TSC_ADJUST). This allows running SEV-SNP guests with "-cpu host". Signed-off-by: Paolo Bonzini --- target/i386/cpu.h | 4 ++++ target/i386/sev.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 0d5624355e..c43ac01c79 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -812,6 +812,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */ #define CPUID_7_0_EBX_FSGSBASE (1U << 0) +/* Support TSC adjust MSR */ +#define CPUID_7_0_EBX_TSC_ADJUST (1U << 1) /* Support SGX */ #define CPUID_7_0_EBX_SGX (1U << 2) /* 1st Group of Advanced Bit Manipulation Extensions */ @@ -1002,6 +1004,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); #define CPUID_8000_0008_EBX_STIBP_ALWAYS_ON (1U << 17) /* Speculative Store Bypass Disable */ #define CPUID_8000_0008_EBX_AMD_SSBD (1U << 24) +/* Paravirtualized Speculative Store Bypass Disable MSR */ +#define CPUID_8000_0008_EBX_VIRT_SSBD (1U << 25) /* Predictive Store Forwarding Disable */ #define CPUID_8000_0008_EBX_AMD_PSFD (1U << 28) diff --git a/target/i386/sev.c b/target/i386/sev.c index 2f3dbe289f..2ba5f51722 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -945,6 +945,38 @@ out: return ret; } +static uint32_t +sev_snp_mask_cpuid_features(X86ConfidentialGuest *cg, uint32_t feature, uint32_t index, + int reg, uint32_t value) +{ + switch (feature) { + case 1: + if (reg == R_ECX) { + return value & ~CPUID_EXT_TSC_DEADLINE_TIMER; + } + break; + case 7: + if (index == 0 && reg == R_EBX) { + return value & ~CPUID_7_0_EBX_TSC_ADJUST; + } + if (index == 0 && reg == R_EDX) { + return value & ~(CPUID_7_0_EDX_SPEC_CTRL | + CPUID_7_0_EDX_STIBP | + CPUID_7_0_EDX_FLUSH_L1D | + CPUID_7_0_EDX_ARCH_CAPABILITIES | + CPUID_7_0_EDX_CORE_CAPABILITY | + CPUID_7_0_EDX_SPEC_CTRL_SSBD); + } + break; + case 0x80000008: + if (reg == R_EBX) { + return value & ~CPUID_8000_0008_EBX_VIRT_SSBD; + } + break; + } + return value; +} + static int sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, uint8_t *addr, size_t len) @@ -2315,6 +2347,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) klass->launch_finish = sev_snp_launch_finish; klass->launch_update_data = sev_snp_launch_update_data; klass->kvm_init = sev_snp_kvm_init; + x86_klass->mask_cpuid_features = sev_snp_mask_cpuid_features; x86_klass->kvm_type = sev_snp_kvm_type; object_class_property_add(oc, "policy", "uint64", -- cgit v1.2.3