Compare commits

...

No commits in common. 'c9' and 'i10cs' have entirely different histories.
c9 ... i10cs

2
.gitignore vendored

@ -1 +1 @@
SOURCES/qemu-9.0.0.tar.xz SOURCES/qemu-9.1.0.tar.xz

@ -1 +1 @@
6699bb03d6da21159b89668bca01c6c958b95d07 SOURCES/qemu-9.0.0.tar.xz d5bcdca53341c29470ef323191a3388fdb0571ed SOURCES/qemu-9.1.0.tar.xz

@ -1,4 +1,4 @@
From ea7dff3dbf979d7d8a85a16cf5187235143e1048 Mon Sep 17 00:00:00 2001 From 7e57931a524e1e805ba8d68e75828e98c591e975 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 26 May 2021 10:56:02 +0200 Date: Wed, 26 May 2021 10:56:02 +0200
Subject: Initial redhat build Subject: Initial redhat build
@ -13,214 +13,33 @@ several issues are fixed in QEMU tree:
We disable make check due to issues with some of the tests. We disable make check due to issues with some of the tests.
This rebase is based on qemu-kvm-8.2.0-11.el9 We are rebasing from qemu-kvm-9.0.0-8.el10.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase changes (6.1.0):
- Move build to .distro
- Move changes for support file to related commit
- Added dependency for python3-sphinx-rtd_theme
- Removed --disable-sheepdog configure option
- Added new hw-display modules
- SASL initialization moved to ui/vnc-auth-sasl.c
- Add accel-qtest-<arch> and accel-tcg-x86_64 libraries
- Added hw-usb-host module
- Disable new configure options (bpf, nvmm, slirp-smbd)
- Use -pie for ksmctl build (annocheck complain fix)
Rebase changes (6.2.0):
- removed --disable-jemalloc and --disable-tcmalloc configure options
- added audio-oss.so
- added fdt requirement for x86_64
- tests/acceptance renamed to tests/avocado
- added multiboot_dma.bin
- Add -Wno-string-plus-int to extra flags
- Updated configure options
Rebase changes (7.0.0):
- Do not use -mlittle CFLAG on ppc64le
- Used upstream handling issue with ui/clipboard.c
- Use -mlittle-endian on ppc64le instead of deleteing it in configure
- Drop --disable-libxml2 option for configure (upstream)
- Remove vof roms
- Disable AVX2 support
- Use internal meson
- Disable new configure options (dbus-display and qga-vss)
- Change permissions on installing tests/Makefile.include
- Remove ssh block driver
Rebase changes (7.1.0):
- --disable-vnc-png renamed to --disable-png (upstream)
- removed --disable-vhost-vsock and --disable-vhost-scsi
- capstone submodule removed
- Temporary include capstone build
Rebase changes (7.2.0):
- Switch --enable-slirp=system to --enable-slirp
- Added new configure options (blkio and sndio, both disabled)
Rebase changes (7.2.0):
- Fix SRPM name generation to work on Fedora 37
- Switch back to system meson
Rebase changes (8.0.0):
- use enable-dtrace-backands instead of enable-dtrace-backend
- Removed qemu virtiofsd bits
- test/check-block.sh removed (upstream)
- Add new --disable-* options for configure
Rebase changes (8.1.0):
- qmp-spec.txt installed by make
- Removed --meson configure option
- Add --disable-pypi
- Removed --with-git and -with-gitsubmodules
- Renamed --disable-pypi to --disable-downloads
- Minor updates in README.tests
Rebase changes (8.2.0):
- Removed --disable-hax (upstream)
- Added --disable-plugins configure option
- Fixing frh.py strings
Rebase notes (9.0.0):
- Fixed qemu-kvm binary location change
- Remove hppa-firmware64.img
- Package stp files for utilities
- Download subprojects on local build
Merged patches (6.0.0):
- 605758c902 Limit build on Power to qemu-img and qemu-ga only
Merged patches (6.1.0):
- f04f91751f Use cached tarballs
- 6581165c65 Remove message with running VM count
- 03c3cac9fc spec-file: build qemu-kvm without SPICE and QXL
- e0ae6c1f6c spec-file: Obsolete qemu-kvm-ui-spice
- 9d2e9f9ecf spec: Do not build qemu-kvm-block-gluster
- cf470b4234 spec: Do not link pcnet and ne2k_pci roms
- e981284a6b redhat: Install the s390-netboot.img that we've built
- 24ef557f33 spec: Remove usage of Group: tag
- c40d69b4f4 spec: Drop %defattr usage
- f8e98798ce spec: Clean up BuildRequires
- 47246b43ee spec: Remove iasl BuildRequires
- 170dc1cbe0 spec: Remove redundant 0 in conditionals
- 8718f6fa11 spec: Add more have_XXX conditionals
- a001269ce9 spec: Remove binutils versioned Requires
- 34545ee641 spec: Remove diffutils BuildRequires
- c2c82beac9 spec: Remove redundant Requires:
- 9314c231f4 spec: Add XXX_version macros
- c43db0bf0f spec: Add have_block_rbd
- 3ecb0c0319 qga: drop StandardError=syslog
- 018049dc80 Remove iscsi support
- a2edf18777 redhat: Replace the kvm-setup.service with a /etc/modules-load.d config file
- 387b5fbcfe redhat: Move qemu-kvm-docs dependency to qemu-kvm
- 4ead693178 redhat: introducting qemu-kvm-hw-usbredir
- 4dc6fc3035 redhat: use the standard vhost-user JSON path
- 84757178b4 Fix local build
- 8c394227dd spec: Restrict block drivers in tools
- b6aa7c1fae Move tools to separate package
- eafd82e509 Split qemu-pr-helper to separate package
- 2c0182e2aa spec: RPM_BUILD_ROOT -> %{buildroot}
- 91bd55ca13 spec: More use of %{name} instead of 'qemu-kvm'
- 50ba299c61 spec: Use qemu-pr-helper.service from qemu.git (partial)
- ee08d4e0a3 spec: Use %{_sourcedir} for referencing sources
- 039e7f7d02 spec: Add tools_only
- 884ba71617 spec: %build: Add run_configure helper
- 8ebd864d65 spec: %build: Disable more bits with %{disable_everything} (partial)
- f23fdb53f5 spec: %build: Add macros for some 'configure' parameters
- fe951a8bd8 spec: %files: Move qemu-guest-agent and qemu-img earlier
- 353b632e37 spec: %install: Remove redundant bits
- 9d2015b752 spec: %install: Add %{modprobe_kvm_conf} macro
- 6d05134e8c spec: %install: Remove qemu-guest-agent /etc/qemu-kvm usage
- 985b226467 spec: %install: clean up qemu-ga section
- dfaf9c600d spec: %install: Use a single %{tools_only} section
- f6978ddb46 spec: Make tools_only not cross spec sections
- 071c211098 spec: %install: Limit time spent in %{qemu_kvm_build}
- 1b65c674be spec: misc syntactic merges with Fedora
- 4da16294cf spec: Use Fedora's pattern for specifying rc version
- d7ee259a79 spec: %files: don't use fine grained -docs file list
- 64cad0c60f spec: %files: Add licenses to qemu-common too
- c3de4f080a spec: %install: Drop python3 shebang fixup
- 46fc216115 Update local build to work with spec file improvements
- bab9531548 spec: Remove buildldflags
- c8360ab6a9 spec: Use %make_build macro
- f6966c66e9 spec: Drop make install sharedir and datadir usage
- 86982421bc spec: use %make_install macro
- 191c405d22 spec: parallelize `make check`
- 251a1fb958 spec: Drop explicit --build-id
- 44c7dda6c3 spec: use %{build_ldflags}
- 0009a34354 Move virtiofsd to separate package
- 34d1b200b3 Utilize --firmware configure option
- 2800e1dd03 spec: Switch toolchain to Clang/LLVM (except process-patches.sh)
- e8a70f500f spec: Use safe-stack for x86_64
- e29445d50d spec: Reenable write support for VMDK etc. in tools
- a4fe2a3e16 redhat: Disable LTO on non-x86 architectures
Merged patches (6.2.0):
- 333452440b remove sgabios dependency
- 7d3633f184 enable pulseaudio
- bd898709b0 spec: disable use of gcrypt for crypto backends in favour of gnutls
- e4f0c6dee6 spec: Remove block-curl and block-ssh dependency
- 4dc13bfe63 spec: Build the VDI block driver
- d2f2ff3c74 spec: Explicitly include compress filter
- a7d047f9c2 Move ksmtuned files to separate package
Merged patches (7.0.0):
- 098d4d08d0 spec: Rename qemu-kvm-hw-usbredir to qemu-kvm-device-usb-redirect
- c2bd0d6834 spec: Split qemu-kvm-ui-opengl
- 2c9cda805d spec: Introduce packages for virtio-gpu-* modules (changed as rhel device tree not set)
- d0414a3e0b spec: Introduce device-display-virtio-vga* packages
- 3534ec46d4 spec: Move usb-host module to separate package
- ddc14d4737 spec: Move qtest accel module to tests package
- 6f2c4befa6 spec: Extend qemu-kvm-core description
- 6f11866e4e (rhel/rhel-9.0.0) Update to qemu-kvm-6.2.0-6.el9
- da0a28758f ui/clipboard: fix use-after-free regression
- 895d4d52eb spec: Remove qemu-virtiofsd
- c8c8c8bd84 spec: Fix obsolete for spice subpackages
- d46d2710b2 spec: Obsolete old usb redir subpackage
- 6f52a50b68 spec: Obsolete ssh driver
Merged patches (7.2.0):
- 8c6834feb6 Remove opengl display device subpackages (C9S MR 124)
- 0ecc97f29e spec: Add requires for packages with additional virtio-gpu variants (C9S MR 124)
Merged patches (8.0.0):
- 7754f6ba78 Minor packaging fixes
- 401af56187 spec: Disable VDUSE
Merged patches (8.1.0):
- 0c2306676f Enable Linux io_uring
- b7fa6426d5 Enable libblkio block drivers
- 19f6d7a6f4 Fix virtio-blk-vhost-vdpa typo in spec file
- f356cae88f spec: Build DBUS display
- 77b763efd5 Provide elf2dmp binary in qemu-tools
Merged patches (8.2.0):
- cd9efa221d Enable qemu-kvm-device-usb-redirec for aarch64
Merged patches (9.0.0 rc0):
- 25de053dbf spec: Enable zstd
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--- ---
.distro/Makefile | 101 + Rebase notes (9.1.0 rc0):
- Remove --disable-block-migration and --disable-pvrdma configure options (upstream)
- Removed --disable-avx512f configure option
- Removed qemu-vsmr-helper (changed upstream)
---
.distro/Makefile | 101 ++
.distro/Makefile.common | 42 + .distro/Makefile.common | 42 +
.distro/README.tests | 39 + .distro/README.tests | 39 +
.distro/modules-load.conf | 4 + .distro/modules-load.conf | 4 +
.distro/qemu-guest-agent.service | 1 - .distro/qemu-guest-agent.service | 1 -
.distro/qemu-kvm.spec.template | 5170 +++++++++++++++++++++++ .distro/qemu-kvm.spec.template | 1332 +++++++++++++++++++++++
.distro/rpminspect.yaml | 6 +- .distro/rpminspect.yaml | 6 +-
.distro/scripts/extract_build_cmd.py | 12 + .distro/scripts/extract_build_cmd.py | 12 +
.distro/scripts/frh.py | 4 +- .distro/scripts/frh.py | 4 +-
.distro/scripts/process-patches.sh | 4 + .distro/scripts/process-patches.sh | 6 +-
.gitignore | 1 + .gitignore | 1 +
README.systemtap | 43 + README.systemtap | 43 +
scripts/qemu-guest-agent/fsfreeze-hook | 2 +- scripts/qemu-guest-agent/fsfreeze-hook | 2 +-
scripts/systemtap/conf.d/qemu_kvm.conf | 4 + scripts/systemtap/conf.d/qemu_kvm.conf | 4 +
scripts/systemtap/script.d/qemu_kvm.stp | 1 + scripts/systemtap/script.d/qemu_kvm.stp | 1 +
ui/vnc-auth-sasl.c | 2 +- ui/vnc-auth-sasl.c | 2 +-
16 files changed, 5430 insertions(+), 6 deletions(-) 16 files changed, 1593 insertions(+), 7 deletions(-)
create mode 100644 .distro/Makefile create mode 100644 .distro/Makefile
create mode 100644 .distro/Makefile.common create mode 100644 .distro/Makefile.common
create mode 100644 .distro/README.tests create mode 100644 .distro/README.tests

@ -1,4 +1,4 @@
From 780c39975b059deaee106775b6e3a240155acea3 Mon Sep 17 00:00:00 2001 From 003f37e17fb03b8977effd968426a0aeb5855028 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 7 Dec 2022 03:05:48 -0500 Date: Wed, 7 Dec 2022 03:05:48 -0500
Subject: Enable/disable devices for RHEL Subject: Enable/disable devices for RHEL
@ -6,101 +6,48 @@ Subject: Enable/disable devices for RHEL
This commit adds all changes related to changes in supported devices. This commit adds all changes related to changes in supported devices.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase notes (6.1.0):
- Added CONFIG_TPM (except s390x)
- default-configs moved to configs
- Use --with-device-<ARCH> configure option to use rhel configs
Rebase notes (6.2.0): ---
- Add CONFIG_ISA_FDC Rebase notes (9.1.0 rc0):
- Do not remove -no-hpet documentation - Return value added for kvm_s390_apply_cpu_model
- Added new USB_HID and USB_HUB options
Rebase notes (7.0.0):
- Added CONFIG_ARM_GIC_TCG option for aarch64
- Fixes necessary for layout change fixes
- Renamed CONFIG_ARM_GIC_TCG to CONFIG_ARM_GICV3_TCG
- Removed upstream devices
Rebase notes (7.1.0):
- Added CONFIG_VHOST_VSOCK and CONFIG_VHOST_USER_VSOCK configs
- Added CONFIG_CXL and CONFIG_CXL_MEM_DEVICE for aarch64 and x86_64
- Added CONFIG_VHOST_USER_FS option (all archs)
Rebase notes (7.2.0):
- Removed disabling a15mpcore.c as no longer needed
Rebase notes (8.0.0):
- Rename CONFIG_ACPI_X86_ICH to CONFIG_ACPI_ICH9
- Inlude qemu/error-report.h in hw/display/cirrus_vga.c
- Change virtiofsd dependency version
Rebase notes (8.1.0):
- Added CONFIG_PCIE_PCI_BRIDGE for x86_64
- Disabling tcg cpus for aarch64
- Disable CONFIG_ARM_V7M and remove related hack
- Moved aarch64 tcg cpu disabling from arm machine type commit
Rebase notes (8.2.0):
- Disabled new a710 arm64 tcg cpu
- No longer needed hack for removal of i2c-echo
- Disable new neoverse-v2
- Removed CONFIG_OPENGL from x86_64 config file
Rebase notes (9.0.0 rc0):
- Split CONFIG_IDE_QDEV to CONFIG_IDE_DEV and CONFIG_IDE_BUS (upstream change)
Rebase notes (9.0.0 rc1):
- Do not compile armv7 cpu types
Merged patches (6.1.0):
- c51bf45304 Remove SPICE and QXL from x86_64-rh-devices.mak
- 02fc745601 aarch64-rh-devices: add CONFIG_PVPANIC_PCI
- f2fe835153 aarch64-rh-devices: add CONFIG_PXB
- b5431733ad disable CONFIG_USB_STORAGE_BOT
- 478ba0cdf6 Disable TPM passthrough
- 2504d68a7c aarch64: Add USB storage devices
- 51c2a3253c disable ac97 audio
Merged patches (6.2.0):
- 9f2f9fa2ba disable sga device
Merged patches (7.0.0): Rebase notes (9.1.0 rc1):
- fd7c45a5a8 redhat: Enable virtio-mem as tech-preview on x86-64 - Fixing valid_cpu_types preprocessing
- c9e68ea451 Enable SGX -- RH Only
Merged patches (7.1.0): Rebase notes (9.1.0 rc4):
- 38b89dc245 pc: Move s3/s4 suspend disabling to compat (only hw/acpi/ich9.c chunk) - Moved x86 cpu deprecation from x86 machine type patch
- 8f663466c6 configs/devices/aarch64-softmmu: Enable CONFIG_VIRTIO_MEM - Removed unnecessary chunk in cirrus_vga.c
- 1bf372717a Enable virtio-iommu-pci on aarch64 - Not needed hack removal of cpu-v7m.c from build
- ae3f269458 Enable virtio-iommu-pci on x86_64
Merged patches (8.1.0): Rebase notes (9.1.0):
- 8173d2eaba Disable unwanted new devices - Remove ppc64 device configuration
- Remove unnecessary chunks
- Removed CONFIG_VHOST_USER_SCMI and CONFIG_VHOST_USER_SND from some archs
Merged patches (8.2.0): Merged commits (9.1.0 rc0):
- b29f66431f Enable igb on x86_64 - f24c7a1fee Disable FDC devices
- fe8c6cb1ce Disable vga-cirrus device
- fccd117a12 Enable vhost-user-snd-pci device
- c0b40cc648 target/cpu-models/x86: Remove the existing deprecated CPU models on c10s
- ce42b3da0e x86/cpu: deprecate cpu models that do not support x86-64-v3
- 01ffa96c3b target/s390x/cpu_models: Disable everything up to the z12 CPU model
- cd57d17e3c target/s390x: Revert the old s390x CPU model disablement code
- 42af7b3ad5 Enable vhost-user-scmi devices
Merged patches (9.0.0 rc0): Merged commits (9.1.0 rc4):
- 3889ede5d9 Compile IOMMUFD on x86_64 - aa374ce5ea x86/cpu: update deprecation string to match lowest undeprecated model
- 0beb18451f Compile IOMMUFD on s390x
- 2b4b13f70d Compile IOMMUFD object on aarch64
--- ---
.distro/qemu-kvm.spec.template | 18 +-- .distro/qemu-kvm.spec.template | 20 +--
.../aarch64-softmmu/aarch64-rh-devices.mak | 42 +++++++ .../aarch64-softmmu/aarch64-rh-devices.mak | 46 +++++++
.../ppc64-softmmu/ppc64-rh-devices.mak | 37 ++++++
configs/devices/rh-virtio.mak | 10 ++ configs/devices/rh-virtio.mak | 10 ++
.../s390x-softmmu/s390x-rh-devices.mak | 19 +++ .../s390x-softmmu/s390x-rh-devices.mak | 19 +++
.../x86_64-softmmu/x86_64-rh-devices.mak | 112 ++++++++++++++++++ .../x86_64-softmmu/x86_64-rh-devices.mak | 114 ++++++++++++++++++
hw/arm/virt.c | 2 + hw/arm/virt.c | 4 +
hw/block/fdc.c | 10 ++
hw/cpu/meson.build | 3 +-
hw/cxl/meson.build | 3 +- hw/cxl/meson.build | 3 +-
hw/display/cirrus_vga.c | 4 +
hw/ide/piix.c | 5 +- hw/ide/piix.c | 5 +-
hw/input/pckbd.c | 2 + hw/input/pckbd.c | 2 +
hw/net/e1000.c | 2 + hw/net/e1000.c | 2 +
hw/ppc/spapr_cpu_core.c | 2 +
hw/usb/meson.build | 2 +- hw/usb/meson.build | 2 +-
hw/virtio/meson.build | 6 +- hw/virtio/meson.build | 6 +-
target/arm/arm-qmp-cmds.c | 2 + target/arm/arm-qmp-cmds.c | 2 +
@ -109,24 +56,22 @@ Merged patches (9.0.0 rc0):
target/arm/cpu64.c | 12 +- target/arm/cpu64.c | 12 +-
target/arm/tcg/cpu32.c | 2 + target/arm/tcg/cpu32.c | 2 +
target/arm/tcg/cpu64.c | 8 ++ target/arm/tcg/cpu64.c | 8 ++
target/arm/tcg/meson.build | 4 +- target/arm/tcg/meson.build | 2 +-
target/ppc/cpu-models.c | 9 ++ target/i386/cpu.c | 19 +++
target/s390x/cpu_models_sysemu.c | 3 + target/s390x/cpu_models.c | 2 +-
target/s390x/kvm/kvm.c | 8 ++
tests/qtest/arm-cpu-features.c | 4 + tests/qtest/arm-cpu-features.c | 4 +
28 files changed, 321 insertions(+), 17 deletions(-) 22 files changed, 275 insertions(+), 16 deletions(-)
create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
create mode 100644 configs/devices/rh-virtio.mak create mode 100644 configs/devices/rh-virtio.mak
create mode 100644 configs/devices/s390x-softmmu/s390x-rh-devices.mak create mode 100644 configs/devices/s390x-softmmu/s390x-rh-devices.mak
create mode 100644 configs/devices/x86_64-softmmu/x86_64-rh-devices.mak create mode 100644 configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
new file mode 100644 new file mode 100644
index 0000000000..b0191d3c69 index 0000000000..58075e2812
--- /dev/null --- /dev/null
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak +++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
@@ -0,0 +1,42 @@ @@ -0,0 +1,46 @@
+include ../rh-virtio.mak +include ../rh-virtio.mak
+ +
+CONFIG_ARM_GIC_KVM=y +CONFIG_ARM_GIC_KVM=y
@ -149,6 +94,8 @@ index 0000000000..b0191d3c69
+CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_STORAGE_CORE=y +CONFIG_USB_STORAGE_CORE=y
+CONFIG_USB_STORAGE_CLASSIC=y +CONFIG_USB_STORAGE_CLASSIC=y
+CONFIG_USB_HUB=y
+CONFIG_USB_HID=y
+CONFIG_VFIO=y +CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y +CONFIG_VFIO_PCI=y
+CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_MMIO=y
@ -169,49 +116,8 @@ index 0000000000..b0191d3c69
+CONFIG_VHOST_USER_VSOCK=y +CONFIG_VHOST_USER_VSOCK=y
+CONFIG_VHOST_USER_FS=y +CONFIG_VHOST_USER_FS=y
+CONFIG_IOMMUFD=y +CONFIG_IOMMUFD=y
diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak +CONFIG_VHOST_USER_SND=y
new file mode 100644 +CONFIG_VHOST_USER_SCMI=y
index 0000000000..dbb7d30829
--- /dev/null
+++ b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
@@ -0,0 +1,37 @@
+include ../rh-virtio.mak
+
+CONFIG_DIMM=y
+CONFIG_MEM_DEVICE=y
+CONFIG_NVDIMM=y
+CONFIG_PCI=y
+CONFIG_PCI_DEVICES=y
+CONFIG_PCI_TESTDEV=y
+CONFIG_PCI_EXPRESS=y
+CONFIG_PSERIES=y
+CONFIG_SCSI=y
+CONFIG_SPAPR_VSCSI=y
+CONFIG_TEST_DEVICES=y
+CONFIG_USB=y
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_PCI=y
+CONFIG_USB_SMARTCARD=y
+CONFIG_USB_STORAGE_CORE=y
+CONFIG_USB_STORAGE_CLASSIC=y
+CONFIG_USB_XHCI=y
+CONFIG_USB_XHCI_NEC=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
+CONFIG_VHOST_USER=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_VGA=y
+CONFIG_WDT_IB6300ESB=y
+CONFIG_XICS=y
+CONFIG_XIVE=y
+CONFIG_TPM=y
+CONFIG_TPM_SPAPR=y
+CONFIG_TPM_EMULATOR=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_VHOST_USER_VSOCK=y
diff --git a/configs/devices/rh-virtio.mak b/configs/devices/rh-virtio.mak diff --git a/configs/devices/rh-virtio.mak b/configs/devices/rh-virtio.mak
new file mode 100644 new file mode 100644
index 0000000000..94ede1b5f6 index 0000000000..94ede1b5f6
@ -255,10 +161,10 @@ index 0000000000..24cf6dbd03
+CONFIG_IOMMUFD=y +CONFIG_IOMMUFD=y
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
new file mode 100644 new file mode 100644
index 0000000000..d60ff1bcfc index 0000000000..45a8a15291
--- /dev/null --- /dev/null
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
@@ -0,0 +1,112 @@ @@ -0,0 +1,114 @@
+include ../rh-virtio.mak +include ../rh-virtio.mak
+ +
+CONFIG_ACPI=y +CONFIG_ACPI=y
@ -280,9 +186,9 @@ index 0000000000..d60ff1bcfc
+CONFIG_E1000E_PCI_EXPRESS=y +CONFIG_E1000E_PCI_EXPRESS=y
+CONFIG_E1000_PCI=y +CONFIG_E1000_PCI=y
+CONFIG_EDU=y +CONFIG_EDU=y
+CONFIG_FDC=y +#CONFIG_FDC=y
+CONFIG_FDC_SYSBUS=y +#CONFIG_FDC_SYSBUS=y
+CONFIG_FDC_ISA=y +#CONFIG_FDC_ISA=y
+CONFIG_FW_CFG_DMA=y +CONFIG_FW_CFG_DMA=y
+CONFIG_HDA=y +CONFIG_HDA=y
+CONFIG_HYPERV=y +CONFIG_HYPERV=y
@ -345,10 +251,11 @@ index 0000000000..d60ff1bcfc
+CONFIG_USB_XHCI=y +CONFIG_USB_XHCI=y
+CONFIG_USB_XHCI_NEC=y +CONFIG_USB_XHCI_NEC=y
+CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PCI=y
+CONFIG_USB_HUB=y
+CONFIG_USB_HID=y
+CONFIG_VFIO=y +CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y +CONFIG_VFIO_PCI=y
+CONFIG_VGA=y +CONFIG_VGA=y
+CONFIG_VGA_CIRRUS=y
+CONFIG_VGA_PCI=y +CONFIG_VGA_PCI=y
+CONFIG_VHOST_USER=y +CONFIG_VHOST_USER=y
+CONFIG_VHOST_USER_BLK=y +CONFIG_VHOST_USER_BLK=y
@ -371,11 +278,12 @@ index 0000000000..d60ff1bcfc
+CONFIG_VHOST_USER_VSOCK=y +CONFIG_VHOST_USER_VSOCK=y
+CONFIG_VHOST_USER_FS=y +CONFIG_VHOST_USER_FS=y
+CONFIG_IOMMUFD=y +CONFIG_IOMMUFD=y
+CONFIG_VHOST_USER_SND=y
diff --git a/hw/arm/virt.c b/hw/arm/virt.c diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a9a913aead..6c6d155002 100644 index 687fe0bb8b..eea7d2d038 100644
--- a/hw/arm/virt.c --- a/hw/arm/virt.c
+++ b/hw/arm/virt.c +++ b/hw/arm/virt.c
@@ -2954,6 +2954,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) @@ -3032,6 +3032,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
static const char * const valid_cpu_types[] = { static const char * const valid_cpu_types[] = {
@ -383,53 +291,18 @@ index a9a913aead..6c6d155002 100644
#ifdef CONFIG_TCG #ifdef CONFIG_TCG
ARM_CPU_TYPE_NAME("cortex-a7"), ARM_CPU_TYPE_NAME("cortex-a7"),
ARM_CPU_TYPE_NAME("cortex-a15"), ARM_CPU_TYPE_NAME("cortex-a15"),
@@ -2971,6 +2972,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) @@ -3047,8 +3048,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
ARM_CPU_TYPE_NAME("neoverse-n2"),
#endif /* TARGET_AARCH64 */
#endif /* CONFIG_TCG */ #endif /* CONFIG_TCG */
+#endif /* disabled for RHEL */
#ifdef TARGET_AARCH64 #ifdef TARGET_AARCH64
+#if 0 /* Disabled for Red Hat Enterprise Linux */
ARM_CPU_TYPE_NAME("cortex-a53"), ARM_CPU_TYPE_NAME("cortex-a53"),
+#endif /* disabled for RHEL */ +#endif /* disabled for RHEL */
ARM_CPU_TYPE_NAME("cortex-a57"), ARM_CPU_TYPE_NAME("cortex-a57"),
#if defined(CONFIG_KVM) || defined(CONFIG_HVF) #if defined(CONFIG_KVM) || defined(CONFIG_HVF)
ARM_CPU_TYPE_NAME("host"), ARM_CPU_TYPE_NAME("host"),
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6dd94e98bc..a05757fc9a 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -49,6 +49,8 @@
#include "qom/object.h"
#include "fdc-internal.h"
+#include "hw/boards.h"
+
/********************************************************/
/* debug Floppy devices */
@@ -2346,6 +2348,14 @@ void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp)
FDrive *drive;
static int command_tables_inited = 0;
+ /* Restricted for Red Hat Enterprise Linux: */
+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+ if (!strstr(mc->name, "-rhel7.")) {
+ error_setg(errp, "Device %s is not supported with machine type %s",
+ object_get_typename(OBJECT(dev)), mc->name);
+ return;
+ }
+
if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
return;
diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build
index 38cdcfbe57..e588ecfd42 100644
--- a/hw/cpu/meson.build
+++ b/hw/cpu/meson.build
@@ -1,4 +1,5 @@
-system_ss.add(files('core.c', 'cluster.c'))
+#system_ss.add(files('core.c', 'cluster.c'))
+system_ss.add(files('core.c'))
system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c'))
system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c'))
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
index 3e375f61a9..613adb3ebb 100644 index 3e375f61a9..613adb3ebb 100644
--- a/hw/cxl/meson.build --- a/hw/cxl/meson.build
@ -444,28 +317,6 @@ index 3e375f61a9..613adb3ebb 100644
), ),
if_false: files( if_false: files(
'cxl-host-stubs.c', 'cxl-host-stubs.c',
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index 150883a971..497365bd80 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -36,6 +36,7 @@
#include "qemu/module.h"
#include "qemu/units.h"
#include "qemu/log.h"
+#include "qemu/error-report.h"
#include "sysemu/reset.h"
#include "qapi/error.h"
#include "trace.h"
@@ -2946,6 +2947,9 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
int16_t device_id = pc->device_id;
+ warn_report("'cirrus-vga' is deprecated, "
+ "please use a different VGA card instead");
+
/*
* Follow real hardware, cirrus card emulated has 4 MB video memory.
* Also accept 8 MB/16 MB for backward compatibility.
diff --git a/hw/ide/piix.c b/hw/ide/piix.c diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 80efc633d3..9cb82b8eea 100644 index 80efc633d3..9cb82b8eea 100644
--- a/hw/ide/piix.c --- a/hw/ide/piix.c
@ -503,7 +354,7 @@ index 74f10b640f..2e85ecf476 100644
static const TypeInfo i8042_info = { static const TypeInfo i8042_info = {
diff --git a/hw/net/e1000.c b/hw/net/e1000.c diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 43f3a4a701..267f182883 100644 index 5012b96464..b435e54228 100644
--- a/hw/net/e1000.c --- a/hw/net/e1000.c
+++ b/hw/net/e1000.c +++ b/hw/net/e1000.c
@@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = { @@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = {
@ -522,25 +373,8 @@ index 43f3a4a701..267f182883 100644
}; };
static void e1000_register_types(void) static void e1000_register_types(void)
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index e7c9edd033..3b0a47a28c 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -389,10 +389,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
.instance_size = sizeof(SpaprCpuCore),
.class_size = sizeof(SpaprCpuCoreClass),
},
+#if 0 /* Disabled for Red Hat Enterprise Linux */
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power5p_v2.1"),
+#endif
DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"),
DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"),
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
diff --git a/hw/usb/meson.build b/hw/usb/meson.build diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index aac3bb35f2..5411ff35df 100644 index d7de1003e3..1cdc0a1ba0 100644
--- a/hw/usb/meson.build --- a/hw/usb/meson.build
+++ b/hw/usb/meson.build +++ b/hw/usb/meson.build
@@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader @@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
@ -553,7 +387,7 @@ index aac3bb35f2..5411ff35df 100644
endif endif
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index d7f18c96e6..aaabbb8b0b 100644 index 621fc65454..c38bdd6fa4 100644
--- a/hw/virtio/meson.build --- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build +++ b/hw/virtio/meson.build
@@ -20,7 +20,8 @@ if have_vhost @@ -20,7 +20,8 @@ if have_vhost
@ -597,10 +431,10 @@ index 3cc8cc738b..6f21fea1f5 100644
QAPI_LIST_PREPEND(*cpu_list, info); QAPI_LIST_PREPEND(*cpu_list, info);
} }
diff --git a/target/arm/cpu.c b/target/arm/cpu.c diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ab8d007a86..e5dce20f19 100644 index 19191c2391..465f423d25 100644
--- a/target/arm/cpu.c --- a/target/arm/cpu.c
+++ b/target/arm/cpu.c +++ b/target/arm/cpu.c
@@ -2546,6 +2546,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) @@ -2726,6 +2726,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
acc->info = data; acc->info = data;
cc->gdb_core_xml_file = "arm-core.xml"; cc->gdb_core_xml_file = "arm-core.xml";
@ -612,10 +446,10 @@ index ab8d007a86..e5dce20f19 100644
void arm_cpu_register(const ARMCPUInfo *info) void arm_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bc0c84873f..e9472c8bb8 100644 index 9a3fd59562..1261eae94d 100644
--- a/target/arm/cpu.h --- a/target/arm/cpu.h
+++ b/target/arm/cpu.h +++ b/target/arm/cpu.h
@@ -37,6 +37,8 @@ @@ -35,6 +35,8 @@
#define KVM_HAVE_MCE_INJECTION 1 #define KVM_HAVE_MCE_INJECTION 1
#endif #endif
@ -624,7 +458,7 @@ index bc0c84873f..e9472c8bb8 100644
#define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */ #define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3 #define EXCP_PREFETCH_ABORT 3
@@ -1092,6 +1094,7 @@ typedef struct ARMCPUInfo { @@ -1110,6 +1112,7 @@ typedef struct ARMCPUInfo {
const char *name; const char *name;
void (*initfn)(Object *obj); void (*initfn)(Object *obj);
void (*class_init)(ObjectClass *oc, void *data); void (*class_init)(ObjectClass *oc, void *data);
@ -633,10 +467,10 @@ index bc0c84873f..e9472c8bb8 100644
/** /**
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 985b1efe16..46a4e80171 100644 index 262a1d6c0b..800514d3fc 100644
--- a/target/arm/cpu64.c --- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c +++ b/target/arm/cpu64.c
@@ -648,6 +648,7 @@ static void aarch64_a57_initfn(Object *obj) @@ -653,6 +653,7 @@ static void aarch64_a57_initfn(Object *obj)
define_cortex_a72_a57_a53_cp_reginfo(cpu); define_cortex_a72_a57_a53_cp_reginfo(cpu);
} }
@ -644,7 +478,7 @@ index 985b1efe16..46a4e80171 100644
static void aarch64_a53_initfn(Object *obj) static void aarch64_a53_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
@@ -704,6 +705,7 @@ static void aarch64_a53_initfn(Object *obj) @@ -710,6 +711,7 @@ static void aarch64_a53_initfn(Object *obj)
cpu->gic_pribits = 5; cpu->gic_pribits = 5;
define_cortex_a72_a57_a53_cp_reginfo(cpu); define_cortex_a72_a57_a53_cp_reginfo(cpu);
} }
@ -652,7 +486,7 @@ index 985b1efe16..46a4e80171 100644
static void aarch64_host_initfn(Object *obj) static void aarch64_host_initfn(Object *obj)
{ {
@@ -742,8 +744,11 @@ static void aarch64_max_initfn(Object *obj) @@ -748,8 +750,11 @@ static void aarch64_max_initfn(Object *obj)
} }
static const ARMCPUInfo aarch64_cpus[] = { static const ARMCPUInfo aarch64_cpus[] = {
@ -665,7 +499,7 @@ index 985b1efe16..46a4e80171 100644
{ .name = "max", .initfn = aarch64_max_initfn }, { .name = "max", .initfn = aarch64_max_initfn },
#if defined(CONFIG_KVM) || defined(CONFIG_HVF) #if defined(CONFIG_KVM) || defined(CONFIG_HVF)
{ .name = "host", .initfn = aarch64_host_initfn }, { .name = "host", .initfn = aarch64_host_initfn },
@@ -814,8 +819,13 @@ static void aarch64_cpu_instance_init(Object *obj) @@ -820,8 +825,13 @@ static void aarch64_cpu_instance_init(Object *obj)
static void cpu_register_class_init(ObjectClass *oc, void *data) static void cpu_register_class_init(ObjectClass *oc, void *data)
{ {
ARMCPUClass *acc = ARM_CPU_CLASS(oc); ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@ -680,10 +514,10 @@ index 985b1efe16..46a4e80171 100644
void aarch64_cpu_register(const ARMCPUInfo *info) void aarch64_cpu_register(const ARMCPUInfo *info)
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index de8f2be941..8896295ae3 100644 index 20c2737f17..7e66fb6f14 100644
--- a/target/arm/tcg/cpu32.c --- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c
@@ -92,6 +92,7 @@ void aa32_max_features(ARMCPU *cpu) @@ -120,6 +120,7 @@ void aa32_max_features(ARMCPU *cpu)
cpu->isar.id_dfr1 = t; cpu->isar.id_dfr1 = t;
} }
@ -691,13 +525,13 @@ index de8f2be941..8896295ae3 100644
/* CPU models. These are not needed for the AArch64 linux-user build. */ /* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
@@ -1037,3 +1038,4 @@ static void arm_tcg_cpu_register_types(void) @@ -1066,3 +1067,4 @@ static void arm_tcg_cpu_register_types(void)
type_init(arm_tcg_cpu_register_types) type_init(arm_tcg_cpu_register_types)
#endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */ #endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */
+#endif /* disabled for RHEL */ +#endif /* disabled for RHEL */
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 9f7a9f3d2c..7ec6851c9c 100644 index fe232eb306..2678047488 100644
--- a/target/arm/tcg/cpu64.c --- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
@ -708,7 +542,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize, static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
unsigned cachesize) unsigned cachesize)
{ {
@@ -134,6 +135,7 @@ static void aarch64_a35_initfn(Object *obj) @@ -135,6 +136,7 @@ static void aarch64_a35_initfn(Object *obj)
/* These values are the same with A53/A57/A72. */ /* These values are the same with A53/A57/A72. */
define_cortex_a72_a57_a53_cp_reginfo(cpu); define_cortex_a72_a57_a53_cp_reginfo(cpu);
} }
@ -716,7 +550,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name, static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp) void *opaque, Error **errp)
@@ -223,6 +225,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name, @@ -224,6 +226,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
static Property arm_cpu_lpa2_property = static Property arm_cpu_lpa2_property =
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true); DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
@ -724,7 +558,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static void aarch64_a55_initfn(Object *obj) static void aarch64_a55_initfn(Object *obj)
{ {
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
@@ -1065,6 +1068,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) @@ -1074,6 +1077,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
aarch64_add_pauth_properties(obj); aarch64_add_pauth_properties(obj);
aarch64_add_sve_properties(obj); aarch64_add_sve_properties(obj);
} }
@ -732,7 +566,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
/* /*
* -cpu max: a CPU with as many features enabled as our emulation supports. * -cpu max: a CPU with as many features enabled as our emulation supports.
@@ -1271,6 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj) @@ -1295,6 +1299,7 @@ void aarch64_max_tcg_initfn(Object *obj)
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property); qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
} }
@ -740,7 +574,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644
static const ARMCPUInfo aarch64_cpus[] = { static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn }, { .name = "cortex-a35", .initfn = aarch64_a35_initfn },
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn }, { .name = "cortex-a55", .initfn = aarch64_a55_initfn },
@@ -1282,14 +1287,17 @@ static const ARMCPUInfo aarch64_cpus[] = { @@ -1306,14 +1311,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn }, { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
{ .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn }, { .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
}; };
@ -759,115 +593,161 @@ index 9f7a9f3d2c..7ec6851c9c 100644
type_init(aarch64_cpu_register_types) type_init(aarch64_cpu_register_types)
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
index 3b1a9f0fc5..6898b4de6f 100644 index 508932a249..1293647501 100644
--- a/target/arm/tcg/meson.build --- a/target/arm/tcg/meson.build
+++ b/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build
@@ -56,5 +56,5 @@ arm_system_ss.add(files( @@ -58,5 +58,5 @@ arm_system_ss.add(files(
'psci.c', 'psci.c',
)) ))
-arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c')) -arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
-arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
+#arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c')) +#arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
+#arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c')) arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f2301b43f7..f77ebfcc81 100644 index 85ef7452c0..34e0ce5e62 100644
--- a/target/ppc/cpu-models.c --- a/target/i386/cpu.c
+++ b/target/ppc/cpu-models.c +++ b/target/i386/cpu.c
@@ -66,6 +66,7 @@ @@ -2411,9 +2411,13 @@ static const CPUCaches epyc_genoa_cache_info = {
#define POWERPC_DEF(_name, _pvr, _type, _desc) \ * PT in VMX operation
POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type) */
+#if 0 /* Embedded and 32-bit CPUs disabled for Red Hat Enterprise Linux */ +#define RHEL_CPU_DEPRECATION \
/* Embedded PowerPC */ + "use at least 'Haswell' / 'EPYC', or 'host' / 'max'"
/* PowerPC 405 family */ +
/* PowerPC 405 cores */ static const X86CPUDefinition builtin_x86_defs[] = {
@@ -698,8 +699,10 @@ {
"PowerPC 7447A v1.2 (G4)") .name = "qemu64",
POWERPC_DEF("7457a_v1.2", CPU_POWERPC_74x7A_v12, 7455, + .deprecation_note = RHEL_CPU_DEPRECATION,
"PowerPC 7457A v1.2 (G4)") .level = 0xd,
+#endif .vendor = CPUID_VENDOR_AMD,
/* 64 bits PowerPC */ .family = 15,
#if defined(TARGET_PPC64) @@ -2432,6 +2436,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
+#if 0 /* Disabled for Red Hat Enterprise Linux */ .xlevel = 0x8000000A,
POWERPC_DEF("970_v2.2", CPU_POWERPC_970_v22, 970, .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
"PowerPC 970 v2.2") },
POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970, +#if 0 // Deprecated CPU models are removed in RHEL-10
@@ -718,6 +721,7 @@ {
"PowerPC 970MP v1.1") .name = "phenom",
POWERPC_DEF("power5p_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, .level = 5,
"POWER5+ v2.1") @@ -2796,8 +2801,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
+#endif .xlevel = 0x80000008,
POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
"POWER7 v2.3") },
POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, +#endif // Removal of deprecated CPU models in RHEL-10
@@ -894,13 +898,16 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { {
{ "7447a", "7447a_v1.2" }, .name = "Nehalem",
{ "7457a", "7457a_v1.2" }, + .deprecation_note = RHEL_CPU_DEPRECATION,
{ "apollo7pm", "7457a_v1.0" }, .level = 11,
+#endif .vendor = CPUID_VENDOR_INTEL,
#if defined(TARGET_PPC64) .family = 6,
+#if 0 /* Disabled for Red Hat Enterprise Linux */ @@ -2875,6 +2882,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
{ "970", "970_v2.2" }, },
{ "970fx", "970fx_v3.1" }, {
{ "970mp", "970mp_v1.1" }, .name = "Westmere",
{ "power5+", "power5p_v2.1" }, + .deprecation_note = RHEL_CPU_DEPRECATION,
{ "power5+_v2.1", "power5p_v2.1" }, .level = 11,
{ "power5gs", "power5+_v2.1" }, .vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2956,6 +2964,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "SandyBridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -3042,6 +3051,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "IvyBridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4469,6 +4479,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Denverton",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 21,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4579,6 +4590,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Snowridge",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 27,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4760,8 +4772,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "Intel Xeon Phi Processor (Knights Mill)",
},
+#if 0 // Deprecated CPU models are removed in RHEL-10
{
.name = "Opteron_G1",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4782,6 +4796,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4804,6 +4819,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
@@ -4827,8 +4843,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x80000008,
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
},
+#endif +#endif
{ "power7", "power7_v2.3" }, {
{ "power7+", "power7p_v2.1" }, .name = "Opteron_G4",
{ "power7+_v2.1", "power7p_v2.1" }, + .deprecation_note = RHEL_CPU_DEPRECATION,
@@ -911,12 +918,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { .level = 0xd,
{ "power10", "power10_v2.0" }, .vendor = CPUID_VENDOR_AMD,
#endif .family = 21,
@@ -4861,6 +4879,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
+#if 0 /* Disabled for Red Hat Enterprise Linux */ },
/* Generic PowerPCs */ {
#if defined(TARGET_PPC64) .name = "Opteron_G5",
{ "ppc64", "970fx_v3.1" }, + .deprecation_note = RHEL_CPU_DEPRECATION,
#endif .level = 0xd,
{ "ppc32", "604" }, .vendor = CPUID_VENDOR_AMD,
{ "ppc", "604" }, .family = 21,
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index a27f4b6f79..798c18f940 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -72,7 +72,6 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"),
CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"),
CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"),
-#endif
CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"),
CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"),
CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"),
@@ -81,6 +80,7 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"),
CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"),
CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"),
+#endif +#endif
CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"),
{ NULL, NULL } CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"),
}; CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"),
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 2d99218069..0728bfcc20 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -34,6 +34,9 @@ static void check_unavailable_features(const S390CPUModel *max_model,
(max_model->def->gen == model->def->gen &&
max_model->def->ec_ga < model->def->ec_ga)) {
list_add_feat("type", unavailable);
+ } else if (model->def->gen < 11 && kvm_enabled()) {
+ /* Older CPU models are not supported on Red Hat Enterprise Linux */
+ list_add_feat("type", unavailable);
}
/* detect missing features if any to properly report them */
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 4ce809c5d4..55fb4855b1 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -2565,6 +2565,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
error_setg(errp, "KVM doesn't support CPU models");
return;
}
+
+ /* Older CPU models are not supported on Red Hat Enterprise Linux */
+ if (model->def->gen < 11) {
+ error_setg(errp, "KVM: Unsupported CPU type specified: %s",
+ MACHINE(qdev_get_machine())->cpu_type);
+ return;
+ }
+
prop.cpuid = s390_cpuid_from_cpu_model(model);
prop.ibc = s390_ibc_from_cpu_model(model);
/* configure cpu features indicated via STFL(e) */
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index 9d6e6190d5..f822526acb 100644 index cfd6f77353..3016e6233c 100644
--- a/tests/qtest/arm-cpu-features.c --- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c
@@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data) @@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data)

@ -1,4 +1,4 @@
From 8e6a30073f9c1a5d6294b2d16556522453e227e7 Mon Sep 17 00:00:00 2001 From 18ae40658bedd6dceab0ffe0bce77ba48e6f0fae Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 11 Jan 2019 09:54:45 +0100 Date: Fri, 11 Jan 2019 09:54:45 +0100
Subject: Machine type related general changes Subject: Machine type related general changes
@ -8,72 +8,18 @@ split to allow easier review. It contains changes not related to any
architecture. architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase notes (6.2.0):
- Do not duplicate minimal_version_id for piix4_pm
- Remove empty line chunks in serial.c
- Remove migration.h include in serial.c
- Update hw_compat_rhel_8_5 (from MR 66)
Rebase notes (7.0.0): ---
- Remove downstream changes leftovers in hw/rtc/mc146818rtc.c Rebase notes (9.1.0 rc0):
- Remove unnecessary change in hw/usb/hcd-uhci.c - Upstream removed uuid_encoced argument on smbios_set_defaults
Rebase notes (7.1.0):
- Moved adding rhel_old_machine_deprecation variable from s390x to general machine types commit
- Moved adding hw_compat_rhel_8_6 struct from x86_64 to general machine types commit
Rebase notes (8.1.0):
- Do not modify unused vga-isa.c
Rebase notes (9.0.0 rc0):
- Updated smsbios handling
Rebase notes (9.0.0 rc4):
- Moving downstream compat changes
Merged patches (6.1.0):
- f2fb42a3c6 redhat: add missing entries in hw_compat_rhel_8_4
- 1949ec258e hw/arm/virt: Disable PL011 clock migration through hw_compat_rhel_8_3
- a3995e2eff Remove RHEL 7.0.0 machine type (only generic changes)
- ad3190a79b Remove RHEL 7.1.0 machine type (only generic changes)
- 84bbe15d4e Remove RHEL 7.2.0 machine type (only generic changes)
- 0215eb3356 Remove RHEL 7.3.0 machine types (only generic changes)
- af69d1ca6e Remove RHEL 7.4.0 machine types (only generic changes)
- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only generic changes)
Merged patches (6.2.0):
- d687ac13d2 redhat: Define hw_compat_rhel_8_5
Merged patches (7.0.0):
- ef5afcc86d Fix virtio-net-pci* "vectors" compat
- 168f0d56e3 compat: Update hw_compat_rhel_8_5 with 6.2.0 RC2 changes
Merged patches (7.1.0):
- 38b89dc245 pc: Move s3/s4 suspend disabling to compat (only hw/acpi/piix4.c chunk)
- 1d6439527a WRB: Introduce RHEL 9.0.0 hw compat structure (only hw/core/machine.c and include/hw/boards.h chunk)
Merged patches (7.2.0):
- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts)
Merged patches (8.0.0):
- 21ed34787b Addd 7.2 compat bits for RHEL 9.1 machine type
- e5c8d5d603 virtio-rng-pci: fix migration compat for vectors
- 5a5fa77059 virtio-rng-pci: fix transitional migration compat for vectors
Merged patches (8.1.0):
- bd5d81d286 Add RHEL 9.2.0 compat structure (general part)
- 1165e24c6b hw/pci: Disable PCI_ERR_UNCOR_MASK reg for machine type <= pc-q35-rhel9.2.0
Merged patches (8.2.0):
- 4ee284aca9 Add machine types compat bits. (partial)
Merged patches (9.0.0 rc0): Merged commits (9.1.0 rc0):
- 4b8fe42abc virtio-mem: default-enable "dynamic-memslots" - 043ad5ce97 Add upstream compatibility bits (partial)
- bfbdab5824 rhel 9.4.0 machine type compat for virtio-gpu migration
--- ---
hw/acpi/piix4.c | 2 +- hw/acpi/piix4.c | 2 +-
hw/arm/virt.c | 2 +- hw/arm/virt.c | 3 +-
hw/core/machine.c | 269 +++++++++++++++++++++++++++++++++++ hw/core/machine.c | 281 +++++++++++++++++++++++++++++++++++
hw/i386/fw_cfg.c | 3 +- hw/i386/fw_cfg.c | 3 +-
hw/net/rtl8139.c | 4 +- hw/net/rtl8139.c | 4 +-
hw/smbios/smbios.c | 46 +++++- hw/smbios/smbios.c | 46 +++++-
@ -81,10 +27,10 @@ Merged patches (9.0.0 rc0):
hw/usb/hcd-xhci-pci.c | 59 ++++++-- hw/usb/hcd-xhci-pci.c | 59 ++++++--
hw/usb/hcd-xhci-pci.h | 1 + hw/usb/hcd-xhci-pci.h | 1 +
hw/virtio/virtio-mem.c | 3 +- hw/virtio/virtio-mem.c | 3 +-
include/hw/boards.h | 40 ++++++ include/hw/boards.h | 43 ++++++
include/hw/firmware/smbios.h | 4 +- include/hw/firmware/smbios.h | 4 +-
include/hw/i386/pc.h | 3 + include/hw/i386/pc.h | 3 +
13 files changed, 414 insertions(+), 24 deletions(-) 13 files changed, 430 insertions(+), 24 deletions(-)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index debe1adb84..e8ddcd716e 100644 index debe1adb84..e8ddcd716e 100644
@ -100,23 +46,24 @@ index debe1adb84..e8ddcd716e 100644
.fields = (const VMStateField[]) { .fields = (const VMStateField[]) {
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
diff --git a/hw/arm/virt.c b/hw/arm/virt.c diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6c6d155002..36e9b4b4e9 100644 index eea7d2d038..b2aa3f1355 100644
--- a/hw/arm/virt.c --- a/hw/arm/virt.c
+++ b/hw/arm/virt.c +++ b/hw/arm/virt.c
@@ -1651,7 +1651,7 @@ static void virt_build_smbios(VirtMachineState *vms) @@ -1699,7 +1699,8 @@ static void virt_build_smbios(VirtMachineState *vms)
}
smbios_set_defaults("QEMU", product, smbios_set_defaults("QEMU", product,
vmc->smbios_old_sys_ver ? "1.0" : mc->name, - vmc->smbios_old_sys_ver ? "1.0" : mc->name);
- true); + vmc->smbios_old_sys_ver ? "1.0" : mc->name,
+ true, NULL, NULL); + NULL, NULL);
/* build the array of physical mem area from base_memmap */ /* build the array of physical mem area from base_memmap */
mem_array.address = vms->memmap[VIRT_MEM].base; mem_array.address = vms->memmap[VIRT_MEM].base;
diff --git a/hw/core/machine.c b/hw/core/machine.c diff --git a/hw/core/machine.c b/hw/core/machine.c
index 37ede0e7d4..695cb89a46 100644 index 27dcda0248..f7fed78e4b 100644
--- a/hw/core/machine.c --- a/hw/core/machine.c
+++ b/hw/core/machine.c +++ b/hw/core/machine.c
@@ -296,6 +296,275 @@ GlobalProperty hw_compat_2_1[] = { @@ -305,6 +305,287 @@ GlobalProperty hw_compat_2_1[] = {
}; };
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1); const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
@ -126,6 +73,18 @@ index 37ede0e7d4..695cb89a46 100644
+const char *rhel_old_machine_deprecation = +const char *rhel_old_machine_deprecation =
+ "machine types for previous major releases are deprecated"; + "machine types for previous major releases are deprecated";
+ +
+GlobalProperty hw_compat_rhel_9_5[] = {
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "migration", "zero-page-detection", "legacy"},
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" },
+};
+const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
+
+GlobalProperty hw_compat_rhel_9_4[] = { +GlobalProperty hw_compat_rhel_9_4[] = {
+ /* hw_compat_rhel_9_4 from hw_compat_8_0 */ + /* hw_compat_rhel_9_4 from hw_compat_8_0 */
+ { TYPE_VIRTIO_NET, "host_uso", "off"}, + { TYPE_VIRTIO_NET, "host_uso", "off"},
@ -393,24 +352,24 @@ index 37ede0e7d4..695cb89a46 100644
static char *machine_get_kernel(Object *obj, Error **errp) static char *machine_get_kernel(Object *obj, Error **errp)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index d802d2787f..c7aa39a13e 100644 index 0e4494627c..33ef280420 100644
--- a/hw/i386/fw_cfg.c --- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c
@@ -64,7 +64,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, @@ -73,7 +73,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) { if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */ /* These values are guest ABI, do not change */
smbios_set_defaults("QEMU", mc->desc, mc->name, - smbios_set_defaults("QEMU", mc->desc, mc->name);
- pcmc->smbios_uuid_encoded); + smbios_set_defaults("QEMU", mc->desc, mc->name,
+ pcmc->smbios_uuid_encoded,
+ pcmc->smbios_stream_product, pcmc->smbios_stream_version); + pcmc->smbios_stream_product, pcmc->smbios_stream_version);
} }
/* tell smbios about cpuid version and features */ /* tell smbios about cpuid version and features */
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 897c86ec41..2d0db43f49 100644 index 03a204ef8a..f2fe057535 100644
--- a/hw/net/rtl8139.c --- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c
@@ -3169,7 +3169,7 @@ static int rtl8139_pre_save(void *opaque) @@ -3173,7 +3173,7 @@ static int rtl8139_pre_save(void *opaque)
static const VMStateDescription vmstate_rtl8139 = { static const VMStateDescription vmstate_rtl8139 = {
.name = "rtl8139", .name = "rtl8139",
@ -419,7 +378,7 @@ index 897c86ec41..2d0db43f49 100644
.minimum_version_id = 3, .minimum_version_id = 3,
.post_load = rtl8139_post_load, .post_load = rtl8139_post_load,
.pre_save = rtl8139_pre_save, .pre_save = rtl8139_pre_save,
@@ -3250,7 +3250,9 @@ static const VMStateDescription vmstate_rtl8139 = { @@ -3254,7 +3254,9 @@ static const VMStateDescription vmstate_rtl8139 = {
VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State), VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State), VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State), VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
@ -430,10 +389,10 @@ index 897c86ec41..2d0db43f49 100644
VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index eed5787b15..68608a3403 100644 index a394514264..88642ccce0 100644
--- a/hw/smbios/smbios.c --- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c
@@ -39,6 +39,10 @@ size_t usr_blobs_len; @@ -38,6 +38,10 @@ size_t usr_blobs_len;
static unsigned usr_table_max; static unsigned usr_table_max;
static unsigned usr_table_cnt; static unsigned usr_table_cnt;
@ -444,7 +403,7 @@ index eed5787b15..68608a3403 100644
uint8_t *smbios_tables; uint8_t *smbios_tables;
size_t smbios_tables_len; size_t smbios_tables_len;
unsigned smbios_table_max; unsigned smbios_table_max;
@@ -629,7 +633,7 @@ static void smbios_build_type_1_table(void) @@ -626,7 +630,7 @@ static void smbios_build_type_1_table(void)
static void smbios_build_type_2_table(void) static void smbios_build_type_2_table(void)
{ {
@ -453,17 +412,16 @@ index eed5787b15..68608a3403 100644
SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer); SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
SMBIOS_TABLE_SET_STR(2, product_str, type2.product); SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
@@ -1018,16 +1022,52 @@ void smbios_set_default_processor_family(uint16_t processor_family) @@ -1014,15 +1018,51 @@ void smbios_set_default_processor_family(uint16_t processor_family)
}
void smbios_set_defaults(const char *manufacturer, const char *product, void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version, - const char *version)
- bool uuid_encoded) + const char *version,
+ bool uuid_encoded,
+ const char *stream_product, + const char *stream_product,
+ const char *stream_version) + const char *stream_version)
{ {
smbios_have_defaults = true; smbios_have_defaults = true;
smbios_uuid_encoded = uuid_encoded;
+ /* + /*
+ * If @stream_product & @stream_version are non-NULL, then + * If @stream_product & @stream_version are non-NULL, then
@ -522,7 +480,7 @@ index 28fdabc321..bad13ec224 100644
vmstate_pit_channel, PITChannelState), vmstate_pit_channel, PITChannelState),
VMSTATE_INT64(channels[0].next_transition_time, VMSTATE_INT64(channels[0].next_transition_time,
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index 4423983308..43b4b71fdf 100644 index 264d7ebb77..2b9a3e06d4 100644
--- a/hw/usb/hcd-xhci-pci.c --- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c
@@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id) @@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
@ -586,7 +544,7 @@ index 4423983308..43b4b71fdf 100644
} }
pci_register_bar(dev, 0, pci_register_bar(dev, 0,
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_SPACE_MEMORY |
@@ -154,6 +170,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) @@ -153,6 +169,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
assert(ret > 0); assert(ret > 0);
} }
@ -601,7 +559,7 @@ index 4423983308..43b4b71fdf 100644
if (s->msix != ON_OFF_AUTO_OFF) { if (s->msix != ON_OFF_AUTO_OFF) {
/* TODO check for errors, and should fail when msix=on */ /* TODO check for errors, and should fail when msix=on */
msix_init(dev, s->xhci.numintrs, msix_init(dev, s->xhci.numintrs,
@@ -198,11 +222,18 @@ static void xhci_instance_init(Object *obj) @@ -197,11 +221,18 @@ static void xhci_instance_init(Object *obj)
qdev_alias_all_properties(DEVICE(&s->xhci), obj); qdev_alias_all_properties(DEVICE(&s->xhci), obj);
} }
@ -633,7 +591,7 @@ index 08f70ce97c..1be7527c1b 100644
#endif #endif
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index ffd119ebac..0e2be2219c 100644 index ef64bf1b4a..ba11aa4646 100644
--- a/hw/virtio/virtio-mem.c --- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c
@@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = { @@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = {
@ -648,13 +606,16 @@ index ffd119ebac..0e2be2219c 100644
}; };
diff --git a/include/hw/boards.h b/include/hw/boards.h diff --git a/include/hw/boards.h b/include/hw/boards.h
index 8b8f6d5c00..0466f9d0f3 100644 index 48ff6d8b93..ccfc3e10eb 100644
--- a/include/hw/boards.h --- a/include/hw/boards.h
+++ b/include/hw/boards.h +++ b/include/hw/boards.h
@@ -512,4 +512,44 @@ extern const size_t hw_compat_2_2_len; @@ -822,4 +822,47 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[]; extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len; extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_9_5[];
+extern const size_t hw_compat_rhel_9_5_len;
+
+extern GlobalProperty hw_compat_rhel_9_4[]; +extern GlobalProperty hw_compat_rhel_9_4[];
+extern const size_t hw_compat_rhel_9_4_len; +extern const size_t hw_compat_rhel_9_4_len;
+ +
@ -697,27 +658,27 @@ index 8b8f6d5c00..0466f9d0f3 100644
+extern const char *rhel_old_machine_deprecation; +extern const char *rhel_old_machine_deprecation;
#endif #endif
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 8d3fb2fb3b..d9d6d7a169 100644 index f066ab7262..e805d25fbe 100644
--- a/include/hw/firmware/smbios.h --- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h +++ b/include/hw/firmware/smbios.h
@@ -332,7 +332,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp); @@ -331,7 +331,9 @@ void smbios_add_usr_blob_size(size_t size);
void smbios_entry_add(QemuOpts *opts, Error **errp);
void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_cpuid(uint32_t version, uint32_t features);
void smbios_set_defaults(const char *manufacturer, const char *product, void smbios_set_defaults(const char *manufacturer, const char *product,
const char *version, - const char *version);
- bool uuid_encoded); + const char *version,
+ bool uuid_encoded,
+ const char *stream_product, + const char *stream_product,
+ const char *stream_version); + const char *stream_version);
void smbios_set_default_processor_family(uint16_t processor_family); void smbios_set_default_processor_family(uint16_t processor_family);
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp); uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
void smbios_get_tables(MachineState *ms, void smbios_get_tables(MachineState *ms,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 27a68071d7..ebd8f973f2 100644 index 4e55d7ef6e..8776a3c937 100644
--- a/include/hw/i386/pc.h --- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h
@@ -112,6 +112,9 @@ struct PCMachineClass { @@ -103,6 +103,9 @@ struct PCMachineClass {
bool smbios_defaults;
bool smbios_legacy_mode; bool smbios_legacy_mode;
bool smbios_uuid_encoded;
SmbiosEntryPointType default_smbios_ep_type; SmbiosEntryPointType default_smbios_ep_type;
+ /* New fields needed for Windows HardwareID-6 matching */ + /* New fields needed for Windows HardwareID-6 matching */
+ const char *smbios_stream_product; + const char *smbios_stream_product;

@ -1,496 +0,0 @@
From cf398296f3fcee185a00f23de5deae57c97d648e Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 12:53:31 +0200
Subject: Add aarch64 machine types
Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (6.1.0):
- Use CONFIG_TPM check when using TPM structures
- Add support for default_bus_bypass_iommu
- ea4c0b32d9 arm/virt: Register highmem and gic-version as class properties
- 895e1fa86a hw/arm/virt: Add 8.5 and 9.0 machine types and remove older ones
Rebase notes (7.0.0):
- Added dtb-kaslr-seed option
- Set no_tcg_lpa2 to true
Rebase notes (7.1.0):
- replace dtb_kaslr_seed by dtb_randomness
- Updated dtb_randomness comment
Rebase notes (7.2.0):
- Disabled cortex-a35
Rebase notes (8.0.0):
- Moved changed code from target/arm/helper.c to target/arm/arm-qmp-cmds.c
Rebase notes (8.1.0):
- Added setting default_nic
Rebase notes (9.0.0 rc0):
- call arm_virt_compat_set on rhel type class_init
Merged patches (6.2.0):
- 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type
- f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type
Merged patches (7.0.0):
- 3b82be3dd3 redhat: virt-rhel8.5.0: Update machine type compatibility for QEMU 6.2.0 update
- c354a86c9b hw/arm/virt: Register "iommu" as a class property
- c1a2630dc9 hw/arm/virt: Register "its" as a class property
- 9d8c61dc93 hw/arm/virt: Rename default_bus_bypass_iommu
- a1d1b6eeb6 hw/arm/virt: Expose the 'RAS' option
- 47f8fe1b82 hw/arm/virt: Add 9.0 machine type and remove 8.5 one
- ed2346788f hw/arm/virt: Check no_tcg_its and minor style changes
Merged patches (7.0.0):
- f79b31bdef hw/arm/virt: Remove the dtb-kaslr-seed machine option
- b6fca85f4a hw/arm/virt: Fix missing initialization in instance/class_init()
Merged patches (7.1.0):
- ac97dd4f9f RHEL-only: AArch64: Drop unsupported CPU types
- e9c0a70664 target/arm: deprecate named CPU models
Merged patches (7.2.0):
- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts)
Merged patches (8.0.0):
- c1a21266d8 redhat: aarch64: add rhel9.2.0 virt machine type
- d97cd7c513 redhat: fix virt-rhel9.2.0 compat props
Merged patches (8.1.0):
- bd5d81d286 Add RHEL 9.2.0 compat structure (arm part)
- c07f666086 hw/arm/virt: Validate cluster and NUMA node boundary for RHEL machines
Merged patches (8.2.0):
- 4ee284aca9 Add machine types compat bits. (partial)
Merged patches (9.0.0 rc0):
- 117068376a hw/arm/virt: Fix compats
- 8bcccfabc4 hw/arm/virt: Add properties to disable high memory regions
- 0005a8b93a hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types
---
hw/arm/virt.c | 299 +++++++++++++++++++++++++++++++++++++++++-
include/hw/arm/virt.h | 8 ++
2 files changed, 306 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 36e9b4b4e9..22bc345137 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -101,6 +101,7 @@ static void arm_virt_compat_set(MachineClass *mc)
arm_virt_compat_len);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
void *data) \
@@ -128,7 +129,63 @@ static void arm_virt_compat_set(MachineClass *mc)
DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
#define DEFINE_VIRT_MACHINE(major, minor) \
DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
+#endif /* disabled for RHEL */
+
+/*
+ * This variable is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
+ * machine type. They may be overriden by older machine compats.
+ *
+ * virtio-net-pci variant romfiles are not needed because edk2 does
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
+ * on rhel/aarch64.
+ */
+GlobalProperty arm_rhel_compat[] = {
+ {"virtio-net-pci", "romfile", "" },
+ {"virtio-net-pci-transitional", "romfile", "" },
+ {"virtio-net-pci-non-transitional", "romfile", "" },
+};
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
+/*
+ * This cannot be called from the rhel_virt_class_init() because
+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new()
+ * only is called on virt-rhelm.n.s non abstract class init.
+ */
+static void arm_rhel_compat_set(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, arm_rhel_compat,
+ arm_rhel_compat_len);
+}
+
+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \
+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \
+ void *data) \
+ { \
+ MachineClass *mc = MACHINE_CLASS(oc); \
+ arm_rhel_compat_set(mc); \
+ rhel##m##n##s##_virt_options(mc); \
+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \
+ if (latest) { \
+ mc->alias = "virt"; \
+ mc->is_default = 1; \
+ } \
+ } \
+ static const TypeInfo rhel##m##n##s##_machvirt_info = { \
+ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \
+ .parent = TYPE_RHEL_MACHINE, \
+ .class_init = rhel##m##n##s##_virt_class_init, \
+ }; \
+ static void rhel##m##n##s##_machvirt_init(void) \
+ { \
+ type_register_static(&rhel##m##n##s##_machvirt_info); \
+ } \
+ type_init(rhel##m##n##s##_machvirt_init);
+
+#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true)
+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false)
/* Number of external interrupt lines to configure the GIC with */
#define NUM_IRQS 256
@@ -2355,6 +2412,7 @@ static void machvirt_init(MachineState *machine)
qemu_add_machine_init_done_notifier(&vms->machine_done);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_secure(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2382,6 +2440,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
vms->virt = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem(Object *obj, Error **errp)
{
@@ -2397,6 +2456,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
vms->highmem = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_compact_highmem(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2410,6 +2470,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
vms->highmem_compact = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem_redists(Object *obj, Error **errp)
{
@@ -2453,7 +2514,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp)
vms->highmem_mmio = value;
}
-
static bool virt_get_its(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2468,6 +2528,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
vms->its = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_dtb_randomness(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2481,6 +2542,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
vms->dtb_randomness = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_oem_id(Object *obj, Error **errp)
{
@@ -2564,6 +2626,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
vms->ras = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_mte(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2577,6 +2640,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_gic_version(Object *obj, Error **errp)
{
@@ -2949,6 +3013,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
return fixed_ipa ? 0 : requested_pa_size;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void virt_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -3463,3 +3528,235 @@ static void virt_machine_2_6_options(MachineClass *mc)
vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
+#endif /* disabled for RHEL */
+
+static void rhel_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ arm_virt_compat_set(mc);
+
+ mc->family = "virt-rhel-Z";
+ mc->init = machvirt_init;
+ /* Maximum supported VCPU count for all virt-rhel* machines */
+ mc->max_cpus = 384;
+#ifdef CONFIG_TPM
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
+#endif
+ mc->block_default_type = IF_VIRTIO;
+ mc->no_cdrom = 1;
+ mc->pci_allow_0_address = true;
+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */
+ mc->minimum_page_bits = 12;
+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
+ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
+ mc->kvm_type = virt_kvm_type;
+ assert(!mc->get_hotplug_handler);
+ mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+ hc->pre_plug = virt_machine_device_pre_plug_cb;
+ hc->plug = virt_machine_device_plug_cb;
+ hc->unplug_request = virt_machine_device_unplug_request_cb;
+ hc->unplug = virt_machine_device_unplug_cb;
+ mc->nvdimm_supported = true;
+ mc->smp_props.clusters_supported = true;
+ mc->auto_enable_numa_with_memhp = true;
+ mc->auto_enable_numa_with_memdev = true;
+ /* platform instead of architectural choice */
+ mc->cpu_cluster_has_numa_boundary = true;
+ mc->default_ram_id = "mach-virt.ram";
+ mc->default_nic = "virtio-net-pci";
+
+ object_class_property_add(oc, "acpi", "OnOffAuto",
+ virt_get_acpi, virt_set_acpi,
+ NULL, NULL);
+ object_class_property_set_description(oc, "acpi",
+ "Enable ACPI");
+
+ object_class_property_add_bool(oc, "highmem", virt_get_highmem,
+ virt_set_highmem);
+ object_class_property_set_description(oc, "highmem",
+ "Set on/off to enable/disable using "
+ "physical address space above 32 bits");
+
+ object_class_property_add_bool(oc, "highmem-redists",
+ virt_get_highmem_redists,
+ virt_set_highmem_redists);
+ object_class_property_set_description(oc, "highmem-redists",
+ "Set on/off to enable/disable high "
+ "memory region for GICv3 or GICv4 "
+ "redistributor");
+
+ object_class_property_add_bool(oc, "highmem-ecam",
+ virt_get_highmem_ecam,
+ virt_set_highmem_ecam);
+ object_class_property_set_description(oc, "highmem-ecam",
+ "Set on/off to enable/disable high "
+ "memory region for PCI ECAM");
+
+ object_class_property_add_bool(oc, "highmem-mmio",
+ virt_get_highmem_mmio,
+ virt_set_highmem_mmio);
+ object_class_property_set_description(oc, "highmem-mmio",
+ "Set on/off to enable/disable high "
+ "memory region for PCI MMIO");
+
+ object_class_property_add_str(oc, "gic-version", virt_get_gic_version,
+ virt_set_gic_version);
+ object_class_property_set_description(oc, "gic-version",
+ "Set GIC version. "
+ "Valid values are 2, 3, host and max");
+
+ object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu);
+ object_class_property_set_description(oc, "iommu",
+ "Set the IOMMU type. "
+ "Valid values are none and smmuv3");
+
+ object_class_property_add_bool(oc, "default-bus-bypass-iommu",
+ virt_get_default_bus_bypass_iommu,
+ virt_set_default_bus_bypass_iommu);
+ object_class_property_set_description(oc, "default-bus-bypass-iommu",
+ "Set on/off to enable/disable "
+ "bypass_iommu for default root bus");
+
+ object_class_property_add_bool(oc, "ras", virt_get_ras,
+ virt_set_ras);
+ object_class_property_set_description(oc, "ras",
+ "Set on/off to enable/disable reporting host memory errors "
+ "to a KVM guest using ACPI and guest external abort exceptions");
+
+ object_class_property_add_bool(oc, "its", virt_get_its,
+ virt_set_its);
+ object_class_property_set_description(oc, "its",
+ "Set on/off to enable/disable "
+ "ITS instantiation");
+
+ object_class_property_add_str(oc, "x-oem-id",
+ virt_get_oem_id,
+ virt_set_oem_id);
+ object_class_property_set_description(oc, "x-oem-id",
+ "Override the default value of field OEMID "
+ "in ACPI table header."
+ "The string may be up to 6 bytes in size");
+
+
+ object_class_property_add_str(oc, "x-oem-table-id",
+ virt_get_oem_table_id,
+ virt_set_oem_table_id);
+ object_class_property_set_description(oc, "x-oem-table-id",
+ "Override the default value of field OEM Table ID "
+ "in ACPI table header."
+ "The string may be up to 8 bytes in size");
+}
+
+static void rhel_virt_instance_init(Object *obj)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
+
+ /* EL3 is disabled by default and non-configurable for RHEL */
+ vms->secure = false;
+
+ /* EL2 is disabled by default and non-configurable for RHEL */
+ vms->virt = false;
+
+ /* High memory is enabled by default */
+ vms->highmem = true;
+ vms->highmem_compact = !vmc->no_highmem_compact;
+ vms->gic_version = VIRT_GIC_VERSION_NOSEL;
+
+ vms->highmem_ecam = !vmc->no_highmem_ecam;
+ vms->highmem_mmio = true;
+ vms->highmem_redists = true;
+
+ if (vmc->no_its) {
+ vms->its = false;
+ } else {
+ /* Default allows ITS instantiation */
+ vms->its = true;
+
+ if (vmc->no_tcg_its) {
+ vms->tcg_its = false;
+ } else {
+ vms->tcg_its = true;
+ }
+ }
+
+ /* Default disallows iommu instantiation */
+ vms->iommu = VIRT_IOMMU_NONE;
+
+ /* The default root bus is attached to iommu by default */
+ vms->default_bus_bypass_iommu = false;
+
+ /* Default disallows RAS instantiation and is non-configurable for RHEL */
+ vms->ras = false;
+
+ /* MTE is disabled by default and non-configurable for RHEL */
+ vms->mte = false;
+
+ /* Supply kaslr-seed and rng-seed by default, non-configurable for RHEL */
+ vms->dtb_randomness = true;
+
+ vms->irqmap = a15irqmap;
+
+ virt_flash_create(vms);
+
+ vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
+ vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
+}
+
+static const TypeInfo rhel_machine_info = {
+ .name = TYPE_RHEL_MACHINE,
+ .parent = TYPE_MACHINE,
+ .abstract = true,
+ .instance_size = sizeof(VirtMachineState),
+ .class_size = sizeof(VirtMachineClass),
+ .class_init = rhel_machine_class_init,
+ .instance_init = rhel_virt_instance_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ },
+};
+
+static void rhel_machine_init(void)
+{
+ type_register_static(&rhel_machine_info);
+}
+type_init(rhel_machine_init);
+
+static void rhel940_virt_options(MachineClass *mc)
+{
+}
+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
+
+static void rhel920_virt_options(MachineClass *mc)
+{
+ rhel940_virt_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+
+ /* RHEL 9.4 is the first supported release */
+ mc->deprecation_reason =
+ "machine types for versions prior to 9.4 are deprecated";
+}
+DEFINE_RHEL_MACHINE(9, 2, 0)
+
+static void rhel900_virt_options(MachineClass *mc)
+{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ rhel920_virt_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+
+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
+ vmc->no_tcg_lpa2 = true;
+ /* Compact layout for high memory regions was introduced with 9.2.0 */
+ vmc->no_highmem_compact = true;
+}
+DEFINE_RHEL_MACHINE(9, 0, 0)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index bb486d36b1..237fc77bda 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -179,9 +179,17 @@ struct VirtMachineState {
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
+#if 0 /* disabled for Red Hat Enterprise Linux */
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
+#else
+#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel")
+typedef struct VirtMachineClass VirtMachineClass;
+typedef struct VirtMachineState VirtMachineState;
+DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_RHEL_MACHINE)
+#endif
+
void virt_acpi_setup(VirtMachineState *vms);
bool virt_is_acpi_enabled(VirtMachineState *vms);
--
2.39.3

@ -0,0 +1,36 @@
From 16946c2c7be0ae23dc1f267323cfc7630a1c9e87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:32:32 +0100
Subject: meson: temporarily disable -Wunused-function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Deleting the upstream versioned machine types will leave some functions
unused until RHEL machine types are added once again. Temporarily
disable the -Wunused-function warning to preserve bisectability with
fine grained patch splits.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
- New patch
---
meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/meson.build b/meson.build
index fbda17c987..161d496d55 100644
--- a/meson.build
+++ b/meson.build
@@ -651,6 +651,7 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',
+ '-Wno-unused-function',
]
if host_os != 'darwin'
--
2.39.3

@ -1,544 +0,0 @@
From fb905dbe5b51ed899062ef99a2dd7f238d3e3384 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:27:13 +0200
Subject: Add ppc64 machine types
Adding changes to add RHEL machine types for ppc64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Rebase notes (6.2.0):
- Fixed rebase conflict relicts
- Update machine type compat for 6.2 (from MR 66)
Merged patches (6.1.0):
- c438c25ac3 redhat: Define pseries-rhel8.5.0 machine type
- a3995e2eff Remove RHEL 7.0.0 machine type (only ppc64 changes)
- ad3190a79b Remove RHEL 7.1.0 machine type (only ppc64 changes)
- 84bbe15d4e Remove RHEL 7.2.0 machine type (only ppc64 changes)
- 0215eb3356 Remove RHEL 7.3.0 machine types (only ppc64 changes)
- af69d1ca6e Remove RHEL 7.4.0 machine types (only ppc64 changes)
- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only ppc64 changes)
Merged patches (7.1.0):
- baa6790171 target/ppc/cpu-models: Fix ppc_cpu_aliases list for RHEL
---
hw/ppc/spapr.c | 243 ++++++++++++++++++++++++++++++++++++++++
hw/ppc/spapr_cpu_core.c | 13 +++
include/hw/ppc/spapr.h | 4 +
target/ppc/compat.c | 13 ++-
target/ppc/cpu-models.c | 1 +
target/ppc/cpu.h | 1 +
target/ppc/kvm.c | 27 +++++
target/ppc/kvm_ppc.h | 13 +++
8 files changed, 314 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e9bc97fee0..a258d81846 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1718,6 +1718,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
pef_kvm_reset(machine->cgs, &error_fatal);
spapr_caps_apply(spapr);
spapr_nested_reset(spapr);
+ if (spapr->svm_allowed) {
+ kvmppc_svm_allow(&error_fatal);
+ }
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
@@ -3421,6 +3424,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
spapr->host_serial = g_strdup(value);
}
+static bool spapr_get_svm_allowed(Object *obj, Error **errp)
+{
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+
+ return spapr->svm_allowed;
+}
+
+static void spapr_set_svm_allowed(Object *obj, bool value, Error **errp)
+{
+ SpaprMachineState *spapr = SPAPR_MACHINE(obj);
+
+ spapr->svm_allowed = value;
+}
+
static void spapr_instance_init(Object *obj)
{
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
@@ -3499,6 +3516,12 @@ static void spapr_instance_init(Object *obj)
spapr_get_host_serial, spapr_set_host_serial);
object_property_set_description(obj, "host-serial",
"Host serial number to advertise in guest device tree");
+ object_property_add_bool(obj, "x-svm-allowed",
+ spapr_get_svm_allowed,
+ spapr_set_svm_allowed);
+ object_property_set_description(obj, "x-svm-allowed",
+ "Allow the guest to become a Secure Guest"
+ " (experimental only)");
}
static void spapr_machine_finalizefn(Object *obj)
@@ -4754,6 +4777,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
vmc->client_architecture_support = spapr_vof_client_architecture_support;
vmc->quiesce = spapr_vof_quiesce;
vmc->setprop = spapr_vof_setprop;
+ smc->has_power9_support = true;
}
static const TypeInfo spapr_machine_info = {
@@ -4805,6 +4829,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
} \
type_init(spapr_machine_register_##suffix)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
/*
* pseries-9.0
*/
@@ -4998,6 +5023,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc)
}
DEFINE_SPAPR_MACHINE(4_1, "4.1", false);
+#endif
/*
* pseries-4.0
@@ -5013,6 +5039,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
}
return true;
}
+
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void spapr_machine_4_0_class_options(MachineClass *mc)
{
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
@@ -5338,6 +5366,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc)
compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len);
}
DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
+#endif
+
+static void spapr_machine_rhel_default_class_options(MachineClass *mc)
+{
+ /*
+ * Defaults for the latest behaviour inherited from the base class
+ * can be overriden here for all pseries-rhel* machines.
+ */
+
+ /* Maximum supported VCPU count */
+ mc->max_cpus = 384;
+}
+
+/*
+ * pseries-rhel8.5.0
+ * like pseries-6.0
+ */
+
+static void spapr_machine_rhel850_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ /* The default machine type must apply the RHEL specific defaults */
+ spapr_machine_rhel_default_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_5,
+ hw_compat_rhel_8_5_len);
+ smc->pre_6_2_numa_affinity = true;
+ mc->smp_props.prefer_sockets = true;
+}
+
+DEFINE_SPAPR_MACHINE(rhel850, "rhel8.5.0", true);
+
+/*
+ * pseries-rhel8.4.0
+ * like pseries-5.2
+ */
+
+static void spapr_machine_rhel840_class_options(MachineClass *mc)
+{
+ spapr_machine_rhel850_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_4,
+ hw_compat_rhel_8_4_len);
+}
+
+DEFINE_SPAPR_MACHINE(rhel840, "rhel8.4.0", false);
+
+/*
+ * pseries-rhel8.3.0
+ * like pseries-5.1
+ */
+
+static void spapr_machine_rhel830_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_rhel840_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_3,
+ hw_compat_rhel_8_3_len);
+
+ /* from pseries-5.1 */
+ smc->pre_5_2_numa_associativity = true;
+}
+
+DEFINE_SPAPR_MACHINE(rhel830, "rhel8.3.0", false);
+
+/*
+ * pseries-rhel8.2.0
+ * like pseries-4.2 + pseries-5.0
+ * except SPAPR_CAP_CCF_ASSIST that has been backported to pseries-rhel8.1.0
+ */
+
+static void spapr_machine_rhel820_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ /* from pseries-5.0 */
+ static GlobalProperty compat[] = {
+ { TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-5.1-associativity", "on" },
+ };
+
+ spapr_machine_rhel830_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_2,
+ hw_compat_rhel_8_2_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+
+ /* from pseries-4.2 */
+ smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_OFF;
+ smc->rma_limit = 16 * GiB;
+ mc->nvdimm_supported = false;
+
+ /* from pseries-5.0 */
+ mc->numa_mem_supported = true;
+ smc->pre_5_1_assoc_refpoints = true;
+}
+
+DEFINE_SPAPR_MACHINE(rhel820, "rhel8.2.0", false);
+
+/*
+ * pseries-rhel8.1.0
+ * like pseries-4.1
+ */
+
+static void spapr_machine_rhel810_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ /* Only allow 4kiB and 64kiB IOMMU pagesizes */
+ { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" },
+ };
+
+ spapr_machine_rhel820_class_options(mc);
+
+ /* from pseries-4.1 */
+ smc->linux_pci_probe = false;
+ smc->smp_threads_vsmt = false;
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_1,
+ hw_compat_rhel_8_1_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+
+ /* from pseries-4.2 */
+ smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF;
+}
+
+DEFINE_SPAPR_MACHINE(rhel810, "rhel8.1.0", false);
+
+/*
+ * pseries-rhel8.0.0
+ * like pseries-3.1 and pseries-4.0
+ * except SPAPR_CAP_CFPC, SPAPR_CAP_SBBC and SPAPR_CAP_IBS
+ * that have been backported to pseries-rhel8.0.0
+ */
+
+static void spapr_machine_rhel800_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_rhel810_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_0,
+ hw_compat_rhel_8_0_len);
+
+ /* pseries-4.0 */
+ smc->phb_placement = phb_placement_4_0;
+ smc->irq = &spapr_irq_xics;
+ smc->pre_4_1_migration = true;
+
+ /* pseries-3.1 */
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
+ smc->update_dt_enabled = false;
+ smc->dr_phb_enabled = false;
+ smc->broken_host_serial_model = true;
+ smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
+}
+
+DEFINE_SPAPR_MACHINE(rhel800, "rhel8.0.0", false);
+
+/*
+ * pseries-rhel7.6.0
+ * like spapr_compat_2_12 and spapr_compat_3_0
+ * spapr_compat_0 is empty
+ */
+GlobalProperty spapr_compat_rhel7_6[] = {
+ { TYPE_POWERPC_CPU, "pre-3.0-migration", "on" },
+ { TYPE_SPAPR_CPU_CORE, "pre-3.0-migration", "on" },
+};
+const size_t spapr_compat_rhel7_6_len = G_N_ELEMENTS(spapr_compat_rhel7_6);
+
+
+static void spapr_machine_rhel760_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_rhel800_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
+ compat_props_add(mc->compat_props, spapr_compat_rhel7_6, spapr_compat_rhel7_6_len);
+
+ /* from spapr_machine_3_0_class_options() */
+ smc->legacy_irq_allocation = true;
+ smc->nr_xirqs = 0x400;
+ smc->irq = &spapr_irq_xics_legacy;
+
+ /* from spapr_machine_2_12_class_options() */
+ /* We depend on kvm_enabled() to choose a default value for the
+ * hpt-max-page-size capability. Of course we can't do it here
+ * because this is too early and the HW accelerator isn't initialzed
+ * yet. Postpone this to machine init (see default_caps_with_cpu()).
+ */
+ smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 0;
+
+ /* SPAPR_CAP_WORKAROUND enabled in pseries-rhel800 by
+ * f21757edc554
+ * "Enable mitigations by default for pseries-4.0 machine type")
+ */
+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN;
+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN;
+}
+
+DEFINE_SPAPR_MACHINE(rhel760, "rhel7.6.0", false);
+
+/*
+ * pseries-rhel7.6.0-sxxm
+ *
+ * pseries-rhel7.6.0 with speculative execution exploit mitigations enabled by default
+ */
+
+static void spapr_machine_rhel760sxxm_class_options(MachineClass *mc)
+{
+ SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
+ spapr_machine_rhel760_class_options(mc);
+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND;
+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD;
+}
+
+DEFINE_SPAPR_MACHINE(rhel760sxxm, "rhel7.6.0-sxxm", false);
static void spapr_machine_register_types(void)
{
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 3b0a47a28c..375e0c8e45 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -25,6 +25,7 @@
#include "sysemu/reset.h"
#include "sysemu/hw_accel.h"
#include "qemu/error-report.h"
+#include "cpu-models.h"
static void spapr_reset_vcpu(PowerPCCPU *cpu)
{
@@ -264,6 +265,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
{
CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
+ SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
return false;
@@ -280,6 +282,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
/* Set time-base frequency to 512 MHz. vhyp must be set first. */
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
+ if (!smc->has_power9_support &&
+ (((spapr->max_compat_pvr &&
+ ppc_compat_cmp(spapr->max_compat_pvr,
+ CPU_POWERPC_LOGICAL_3_00) >= 0)) ||
+ (!spapr->max_compat_pvr &&
+ ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "POWER9 CPU is not supported by this machine class");
+ return false;
+ }
+
if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) {
qdev_unrealize(DEVICE(cpu));
return false;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 4aaf23d28f..3233c54d11 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -157,6 +157,7 @@ struct SpaprMachineClass {
bool pre_5_2_numa_associativity;
bool pre_6_2_numa_affinity;
+ bool has_power9_support;
bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
@@ -259,6 +260,9 @@ struct SpaprMachineState {
/* Set by -boot */
char *boot_device;
+ /* Secure Guest support via x-svm-allowed */
+ bool svm_allowed;
+
/*< public >*/
char *kvm_type;
char *host_model;
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index ebef2cccec..ff2c00c60e 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -114,8 +114,19 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr)
return NULL;
}
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2)
+{
+ const CompatInfo *compat1 = compat_by_pvr(pvr1);
+ const CompatInfo *compat2 = compat_by_pvr(pvr2);
+
+ g_assert(compat1);
+ g_assert(compat2);
+
+ return compat1 - compat2;
+}
+
static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr,
- uint32_t min_compat_pvr, uint32_t max_compat_pvr)
+ uint32_t min_compat_pvr, uint32_t max_compat_pvr)
{
const CompatInfo *compat = compat_by_pvr(compat_pvr);
const CompatInfo *min = compat_by_pvr(min_compat_pvr);
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index f77ebfcc81..18e9422006 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -744,6 +744,7 @@
/* PowerPC CPU aliases */
PowerPCCPUAlias ppc_cpu_aliases[] = {
+#if 0 /* Disabled for Red Hat Enterprise Linux */
{ "405", "405d4" },
{ "405cr", "405crc" },
{ "405gp", "405gpd" },
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 67e6b2effd..11187aeb93 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1655,6 +1655,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
/* Compatibility modes */
#if defined(TARGET_PPC64)
+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2);
bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr,
uint32_t min_compat_pvr, uint32_t max_compat_pvr);
bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr,
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8231feb2d4..59f640cf7b 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -89,6 +89,7 @@ static int cap_large_decr;
static int cap_fwnmi;
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
+static int cap_ppc_secure_guest;
static uint32_t debug_inst_opcode;
@@ -141,6 +142,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
kvmppc_get_cpu_characteristics(s);
cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
+ cap_ppc_secure_guest = kvm_vm_check_extension(s, KVM_CAP_PPC_SECURE_GUEST);
cap_large_decr = kvmppc_get_dec_bits();
cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI);
/*
@@ -2564,6 +2566,16 @@ bool kvmppc_supports_ail_3(void)
return cap_ail_mode_3;
}
+bool kvmppc_has_cap_secure_guest(void)
+{
+ return !!cap_ppc_secure_guest;
+}
+
+int kvmppc_enable_cap_secure_guest(void)
+{
+ return kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SECURE_GUEST, 0, 1);
+}
+
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
{
uint32_t host_pvr = mfpvr();
@@ -2964,3 +2976,18 @@ bool kvm_arch_cpu_check_are_resettable(void)
void kvm_arch_accel_class_init(ObjectClass *oc)
{
}
+
+void kvmppc_svm_allow(Error **errp)
+{
+ if (!kvm_enabled()) {
+ error_setg(errp, "No PEF support in tcg, try x-svm-allowed=off");
+ return;
+ }
+
+ if (!kvmppc_has_cap_secure_guest()) {
+ error_setg(errp, "KVM implementation does not support secure guests, "
+ "try x-svm-allowed=off");
+ } else if (kvmppc_enable_cap_secure_guest() < 0) {
+ error_setg(errp, "Error enabling x-svm-allowed, try x-svm-allowed=off");
+ }
+}
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 1975fb5ee6..d1017f98be 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -46,6 +46,7 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu,
bool radix, bool gtse,
uint64_t proc_tbl);
+void kvmppc_svm_allow(Error **errp);
bool kvmppc_spapr_use_multitce(void);
int kvmppc_spapr_enable_inkernel_multitce(void);
void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift,
@@ -79,6 +80,8 @@ int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable);
int kvmppc_has_cap_rpt_invalidate(void);
bool kvmppc_supports_ail_3(void);
int kvmppc_enable_hwrng(void);
+bool kvmppc_has_cap_secure_guest(void);
+int kvmppc_enable_cap_secure_guest(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
void kvmppc_check_papr_resize_hpt(Error **errp);
@@ -427,6 +430,16 @@ static inline bool kvmppc_supports_ail_3(void)
return false;
}
+static inline bool kvmppc_has_cap_secure_guest(void)
+{
+ return false;
+}
+
+static inline int kvmppc_enable_cap_secure_guest(void)
+{
+ return -1;
+}
+
static inline int kvmppc_enable_hwrng(void)
{
return -1;
--
2.39.3

@ -0,0 +1,101 @@
From 2f0ba1a1ed66a8ae32e7a92f3d3b744d8b59b879 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 10 Jul 2024 02:25:51 -0400
Subject: Remove upstream machine types for aarch64, s390x and x86_64
architectures
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We will replace upstream machine types on supported architectures with RHEL
machine types.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Rebase notes (9.1.0 rc0):
- Split off commits adding RHEL machine types
---
hw/arm/virt.c | 2 ++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/s390x/s390-virtio-ccw.c | 2 ++
4 files changed, 8 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b2aa3f1355..5396e7cb24 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3306,6 +3306,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void virt_machine_9_1_options(MachineClass *mc)
{
}
@@ -3552,3 +3553,4 @@ static void virt_machine_2_6_options(MachineClass *mc)
vmc->no_pmu = true;
}
DEFINE_VIRT_MACHINE(2, 6)
+#endif /* disabled for RHEL */
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 347afa4c37..67107b174a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -448,6 +448,7 @@ static void pc_i440fx_init(MachineState *machine)
#define DEFINE_I440FX_MACHINE(major, minor) \
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor);
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_i440fx_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
@@ -775,6 +776,7 @@ static void pc_i440fx_machine_2_4_options(MachineClass *m)
}
DEFINE_I440FX_MACHINE(2, 4);
+#endif /* Disabled for Red Hat Enterprise Linux */
#ifdef CONFIG_ISAPC
static void isapc_machine_options(MachineClass *m)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index f2d8edfa84..5fb283f2df 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -356,6 +356,7 @@ static void pc_q35_machine_options(MachineClass *m)
pc_q35_compat_defaults, pc_q35_compat_defaults_len);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_q35_machine_9_1_options(MachineClass *m)
{
pc_q35_machine_options(m);
@@ -668,3 +669,4 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
}
DEFINE_Q35_MACHINE(2, 4);
+#endif /* Disabled for Red Hat Enterprise Linux */
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index c483ff8064..86bfc9d2eb 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -871,6 +871,7 @@ static const TypeInfo ccw_machine_info = {
DEFINE_CCW_MACHINE_IMPL(false, major, minor)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void ccw_machine_9_1_instance_options(MachineState *machine)
{
}
@@ -1305,6 +1306,7 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
DEFINE_CCW_MACHINE(2, 4);
#endif
+#endif /* disabled for RHEL */
static void ccw_machine_register_types(void)
{
--
2.39.3

@ -0,0 +1,197 @@
From ccb1eaa95ce9c92a196fe034c033502f582a324b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 15:27:03 +0100
Subject: Adapt versioned machine type macros for RHEL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The versioned machine type macros are changed thus:
* All symbol names get 'rhel' inserted eg 'virt_rhel_macine_9_4_0_<blah>'
* All machine type names get 'rhel' inserted eg 'virt-rhel9.4.0-machine'
* Lifecycle is changed to deprecate after 1 major RHEL release,
force non-registration (effectively deletion) after 2 major releases
* Custom message to explain RHEL deprecation/deletion policy
* Remove upstream logic that temporarily disabled deletion since
the upstream constraints in this area don't apply to RHEL
* For automatic deprecation/deletion, RHEL_VERSION is defined
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
.distro/Makefile | 2 +-
.distro/Makefile.common | 1 +
.distro/qemu-kvm.spec.template | 1 +
.distro/scripts/process-patches.sh | 3 ++
include/hw/boards.h | 60 ++++++++++--------------------
meson.build | 1 +
meson_options.txt | 2 +
scripts/meson-buildoptions.sh | 2 +
8 files changed, 30 insertions(+), 42 deletions(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index ccfc3e10eb..7f7eb4ec40 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -548,16 +548,16 @@ struct MachineState {
* "{prefix}-{major}.{minor}.{micro}-{tag}"
*/
#define _MACHINE_VER_TYPE_NAME2(prefix, major, minor) \
- prefix "-" #major "." #minor TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME3(prefix, major, minor, micro) \
- prefix "-" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME4(prefix, major, minor, _unused_, tag) \
- prefix "-" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX
#define _MACHINE_VER_TYPE_NAME5(prefix, major, minor, micro, _unused_, tag) \
- prefix "-" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX
+ prefix "-rhel" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX
#define MACHINE_VER_TYPE_NAME(prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -585,16 +585,16 @@ struct MachineState {
* {prefix}_machine_{major}_{minor}_{micro}_{tag}_{sym}
*/
#define _MACHINE_VER_SYM2(sym, prefix, major, minor) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## sym
#define _MACHINE_VER_SYM3(sym, prefix, major, minor, micro) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym
#define _MACHINE_VER_SYM4(sym, prefix, major, minor, _unused_, tag) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym
#define _MACHINE_VER_SYM5(sym, prefix, major, minor, micro, _unused_, tag) \
- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym
+ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym
#define MACHINE_VER_SYM(sym, prefix, ...) \
_MACHINE_VER_PICK(__VA_ARGS__, \
@@ -605,26 +605,22 @@ struct MachineState {
/*
- * How many years/major releases for each phase
- * of the life cycle. Assumes use of versioning
- * scheme where major is bumped each year
+ * How many RHEL major releases for each phase
+ * of the life cycle.
*/
-#define MACHINE_VER_DELETION_MAJOR 6
-#define MACHINE_VER_DEPRECATION_MAJOR 3
+#define MACHINE_VER_DELETION_MAJOR 2
+#define MACHINE_VER_DEPRECATION_MAJOR 1
/*
* Expands to a static string containing a deprecation
* message for a versioned machine type
*/
#define MACHINE_VER_DEPRECATION_MSG \
- "machines more than " stringify(MACHINE_VER_DEPRECATION_MAJOR) \
- " years old are subject to deletion after " \
- stringify(MACHINE_VER_DELETION_MAJOR) " years"
+ "machines from the previous RHEL major release are " \
+ "subject to deletion in the next RHEL major release"
#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
- (((QEMU_VERSION_MAJOR - major) > cutoff) || \
- (((QEMU_VERSION_MAJOR - major) == cutoff) && \
- (QEMU_VERSION_MINOR - minor) >= 0))
+ ((RHEL_VERSION - major) >= cutoff)
#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
_MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
@@ -686,32 +682,14 @@ struct MachineState {
* This must be unconditionally used in the register
* method for all machine types which support versioning.
*
- * Inijtially it will effectively be a no-op, but after a
- * suitable period of time has passed, it will cause
- * execution of the method to return, avoiding registration
- * of the machine
- *
- * The new deprecation and deletion policy for versioned
- * machine types was introduced in QEMU 9.1.0.
- *
- * Under the new policy a number of old machine types (any
- * prior to 2.12) would be liable for immediate deletion
- * which would be a violation of our historical deprecation
- * and removal policy
- *
- * Thus deletions are temporarily gated on existance of
- * the env variable "QEMU_DELETE_MACHINES" / QEMU version
- * number >= 10.1.0. This gate can be deleted in the 10.1.0
- * dev cycle
+ * It will automatically avoid registration of machines
+ * that should have been deleted at the start of this
+ * RHEL release
*/
#define MACHINE_VER_DELETION(...) \
do { \
if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \
- if (getenv("QEMU_DELETE_MACHINES") || \
- QEMU_VERSION_MAJOR > 10 || (QEMU_VERSION_MAJOR == 10 && \
- QEMU_VERSION_MINOR >= 1)) { \
- return; \
- } \
+ return; \
} \
} while (0)
diff --git a/meson.build b/meson.build
index 161d496d55..2de5ab024f 100644
--- a/meson.build
+++ b/meson.build
@@ -2440,6 +2440,7 @@ config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
+config_host_data.set('RHEL_VERSION', get_option('rhel_version').split('.')[0])
config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
diff --git a/meson_options.txt b/meson_options.txt
index 0269fa0f16..aa2ba0baef 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,6 +2,8 @@
# on the configure script command line. If you add more, list them in
# scripts/meson-buildoptions.py's SKIP_OPTIONS constant too.
+option('rhel_version', type: 'string', value: '0.0',
+ description: 'RHEL major/minor version')
option('qemu_suffix', type : 'string', value: 'qemu',
description: 'Suffix for QEMU data/modules/config directories (can be empty)')
option('docdir', type : 'string', value : 'share/doc',
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c97079a38c..5f0cbfc725 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -71,6 +71,7 @@ meson_options_help() {
printf "%s\n" ' "manufacturer" name for qemu-ga registry entries'
printf "%s\n" ' [QEMU]'
printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer'
+ printf "%s\n" ' --rhel-version=VALUE RHEL major/minor version [0.0]'
printf "%s\n" ' --smbd=VALUE Path to smbd for slirp networking'
printf "%s\n" ' --sysconfdir=VALUE Sysconf data directory [etc]'
printf "%s\n" ' --tls-priority=VALUE Default TLS protocol/cipher priority string'
@@ -450,6 +451,7 @@ _meson_option_parse() {
--disable-relocatable) printf "%s" -Drelocatable=false ;;
--enable-replication) printf "%s" -Dreplication=enabled ;;
--disable-replication) printf "%s" -Dreplication=disabled ;;
+ --rhel-version=*) quote_sh "-Drhel_version=$2" ;;
--enable-rng-none) printf "%s" -Drng_none=true ;;
--disable-rng-none) printf "%s" -Drng_none=false ;;
--enable-rutabaga-gfx) printf "%s" -Drutabaga_gfx=enabled ;;
--
2.39.3

@ -1,308 +0,0 @@
From 04178c77cfe188b4eed9c08a0bf66842e61fe5dc Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:47:32 +0200
Subject: Add s390x machine types
Adding changes to add RHEL machine types for s390x architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase changes (7.1.0):
- Moved adding rhel_old_machine_deprecation variable to general machine types commit
Merged patches (6.1.0):
- 64a9a5c971 hw/s390x: Remove the RHEL7-only machine type
- 395516d62b redhat: s390x: add rhel-8.5.0 compat machine
Merged patches (6.2.0):
- 3bf66f4520 redhat: Add s390x machine type compatibility update for 6.1 rebase
Merged patches (7.0.0):
- e6ff4de4f7 redhat: Add s390x machine type compatibility handling for the rebase to v6.2
- 4b0efa7e21 redhat: Add rhel8.6.0 and rhel9.0.0 machine types for s390x
- dcc64971bf RHEL: mark old machine types as deprecated (partialy)
Merged patches (7.1.0):
- 1d6439527a WRB: Introduce RHEL 9.0.0 hw compat structure (only hw/s390x/s390-virtio-ccw.c chunk)
- c8ad21ca31 redhat: Update s390x machine type compatibility for rebase to QEMU 7.0.0
- 5bcf8d874c target/s390x: deprecate CPUs older than z14
Merged patches (7.2.0):
- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts)
Merged patches (8.0.0):
- 27c188c6a4 redhat: Update s390x machine type compatibility for QEMU 7.2.0 update
- a932b8d429 redhat: Add new rhel-9.2.0 s390x machine type
- ac88104bad s390x/s390-virtio-ccw: Activate zPCI features on s390-ccw-virtio-rhel8.6.0
Merged patches (8.1.0):
- bd5d81d286 Add RHEL 9.2.0 compat structure (s390x part)
Merged patches (8.2.0):
- 4ee284aca9 Add machine types compat bits. (partial)
---
hw/s390x/s390-virtio-ccw.c | 159 +++++++++++++++++++++++++++++++
target/s390x/cpu_models.c | 11 +++
target/s390x/cpu_models.h | 2 +
target/s390x/cpu_models_sysemu.c | 2 +
4 files changed, 174 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b1dcb3857f..ff753a29e0 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -859,6 +859,7 @@ bool css_migration_enabled(void)
} \
type_init(ccw_machine_register_##suffix)
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void ccw_machine_9_0_instance_options(MachineState *machine)
{
}
@@ -1272,6 +1273,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_4, "2.4", false);
+#endif
+
+
+static void ccw_machine_rhel940_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_machine_rhel940_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true);
+
+static void ccw_machine_rhel920_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel940_instance_options(machine);
+}
+
+static void ccw_machine_rhel920_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel940_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+ mc->smp_props.drawers_supported = false; /* from ccw_machine_8_1 */
+ mc->smp_props.books_supported = false; /* from ccw_machine_8_1 */
+}
+DEFINE_CCW_MACHINE(rhel920, "rhel9.2.0", false);
+
+static void ccw_machine_rhel900_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
+
+ ccw_machine_rhel920_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
+}
+
+static void ccw_machine_rhel900_class_options(MachineClass *mc)
+{
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_machine_rhel920_class_options(mc);
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+ s390mc->max_threads = S390_MAX_CPUS;
+}
+DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", false);
+
+static void ccw_machine_rhel860_instance_options(MachineState *machine)
+{
+ /* Note: The -rhel8.6.0 and -rhel9.0.0 machines are technically identical */
+ ccw_machine_rhel900_instance_options(machine);
+}
+
+static void ccw_machine_rhel860_class_options(MachineClass *mc)
+{
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "on", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "on", },
+ };
+
+ ccw_machine_rhel900_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_6, hw_compat_rhel_8_6_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+
+ /* All RHEL machines for prior major releases are deprecated */
+ mc->deprecation_reason = rhel_old_machine_deprecation;
+}
+DEFINE_CCW_MACHINE(rhel860, "rhel8.6.0", false);
+
+static void ccw_machine_rhel850_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
+
+ ccw_machine_rhel860_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
+
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_NNPA);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_BEAR_ENH);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_RDP);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI);
+}
+
+static void ccw_machine_rhel850_class_options(MachineClass *mc)
+{
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_machine_rhel860_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_5, hw_compat_rhel_8_5_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ mc->smp_props.prefer_sockets = true;
+}
+DEFINE_CCW_MACHINE(rhel850, "rhel8.5.0", false);
+
+static void ccw_machine_rhel840_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel850_instance_options(machine);
+}
+
+static void ccw_machine_rhel840_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel850_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_4, hw_compat_rhel_8_4_len);
+}
+DEFINE_CCW_MACHINE(rhel840, "rhel8.4.0", false);
+
+static void ccw_machine_rhel820_instance_options(MachineState *machine)
+{
+ ccw_machine_rhel840_instance_options(machine);
+}
+
+static void ccw_machine_rhel820_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel840_class_options(mc);
+ mc->fixup_ram_size = s390_fixup_ram_size;
+ /* we did not publish a rhel8.3.0 machine */
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_3, hw_compat_rhel_8_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_2, hw_compat_rhel_8_2_len);
+}
+DEFINE_CCW_MACHINE(rhel820, "rhel8.2.0", false);
+
+static void ccw_machine_rhel760_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 };
+
+ ccw_machine_rhel820_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat);
+
+ /* The multiple-epoch facility was not available with rhel7.6.0 on z14GA1 */
+ s390_cpudef_featoff(14, 1, S390_FEAT_MULTIPLE_EPOCH);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QSIE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_QTOUE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOE);
+ s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOUE);
+}
+
+static void ccw_machine_rhel760_class_options(MachineClass *mc)
+{
+ ccw_machine_rhel820_class_options(mc);
+ /* We never published the s390x version of RHEL-AV 8.0 and 8.1, so add this here */
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len);
+}
+DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", false);
static void ccw_machine_register_types(void)
{
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 8ed3bb6a27..370b3b3065 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -46,6 +46,9 @@
* of a following release have been a superset of the previous release. With
* generation 15 one base feature and one optional feature have been deprecated.
*/
+
+#define RHEL_CPU_DEPRECATION "use at least 'z14', or 'host' / 'qemu' / 'max'"
+
static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"),
CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"),
@@ -866,22 +869,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* all base models are migration safe */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->is_static = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* model that can change between QEMU versions */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index d7b8912989..1a806a97c4 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -38,6 +38,8 @@ typedef struct S390CPUDef {
S390FeatBitmap full_feat;
/* used to init full_feat from generated data */
S390FeatInit full_init;
+ /* if deprecated, provides a suggestion */
+ const char *deprecation_note;
} S390CPUDef;
/* CPU model based on a CPU definition */
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index 0728bfcc20..ca2e5d91e2 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -59,6 +59,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
S390CPUClass *scc = S390_CPU_CLASS(klass);
+ CPUClass *cc = CPU_CLASS(klass);
/* strip off the -s390x-cpu */
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
@@ -68,6 +69,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
info->migration_safe = scc->is_migration_safe;
info->q_static = scc->is_static;
info->q_typename = g_strdup(object_class_get_name(klass));
+ info->deprecated = !!cc->deprecation_note;
/* check for unavailable features */
if (cpu_list_data->model) {
Object *obj;
--
2.39.3

@ -0,0 +1,37 @@
From 551632921a8330cff09e7d92429aa45cf51c75e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 18:45:58 +0100
Subject: Increase deletion schedule to 4 releases
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Until RHEL 10 pc machine type is introduced, we have to keep
7.6.0 machine types as a special exception to our normal rule of
deleting machine types after 2 releases due to being a default
machine type.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Rebase notes (9.1.0 rc0)
- New patch
---
include/hw/boards.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 7f7eb4ec40..fd5a957cad 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -608,7 +608,7 @@ struct MachineState {
* How many RHEL major releases for each phase
* of the life cycle.
*/
-#define MACHINE_VER_DELETION_MAJOR 2
+#define MACHINE_VER_DELETION_MAJOR 4
#define MACHINE_VER_DEPRECATION_MAJOR 1
/*
--
2.39.3

@ -0,0 +1,301 @@
From 6cb1d3cf4ac08fe8c435e98500224a022d019e55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:25:47 +0100
Subject: Add downstream aarch64 versioned 'virt' machine types
Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Merge copy+pasted base machine definition back with upstream
base machine definition to reduce RHEL delta, as is done with
other targets
- Convert to new DEFINE_VIRT_MACHINE macros
Rebase notes (9.1.0 rc1):
- do not remove cpu validation (review comment)
Rebase notes (9.1.0 rc2):
- use ifdef instead of removal for disabling unwanted upstream code
Merged patches (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
---
hw/arm/virt.c | 101 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 81 insertions(+), 20 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 5396e7cb24..903c0f2e9f 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -90,6 +90,22 @@ static GlobalProperty arm_virt_compat[] = {
};
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
+/*
+ * This variable is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest
+ * machine type. They may be overriden by older machine compats.
+ *
+ * virtio-net-pci variant romfiles are not needed because edk2 does
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
+ * on rhel/aarch64.
+ */
+GlobalProperty arm_rhel_compat[] = {
+ {"virtio-net-pci", "romfile", "" },
+ {"virtio-net-pci-transitional", "romfile", "" },
+ {"virtio-net-pci-non-transitional", "romfile", "" },
+};
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
+
/*
* This cannot be called from the virt_machine_class_init() because
* TYPE_VIRT_MACHINE is abstract and mc->compat_props g_ptr_array_new()
@@ -99,6 +115,8 @@ static void arm_virt_compat_set(MachineClass *mc)
{
compat_props_add(mc->compat_props, arm_virt_compat,
arm_virt_compat_len);
+ compat_props_add(mc->compat_props, arm_rhel_compat,
+ arm_rhel_compat_len);
}
#define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
@@ -109,10 +127,11 @@ static void arm_virt_compat_set(MachineClass *mc)
MachineClass *mc = MACHINE_CLASS(oc); \
arm_virt_compat_set(mc); \
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
- mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
+ mc->desc = "RHEL " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
if (latest) { \
mc->alias = "virt"; \
+ mc->is_default = 1; \
} \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
@@ -128,10 +147,10 @@ static void arm_virt_compat_set(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
-#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
-#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_VIRT_MACHINE_IMPL(true, major, minor, micro)
+#define DEFINE_VIRT_MACHINE(major, minor, micro) \
+ DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro)
/* Number of external interrupt lines to configure the GIC with */
@@ -2434,6 +2453,7 @@ static void machvirt_init(MachineState *machine)
qemu_add_machine_init_done_notifier(&vms->machine_done);
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_secure(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2461,6 +2481,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
vms->virt = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem(Object *obj, Error **errp)
{
@@ -2476,6 +2497,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
vms->highmem = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_compact_highmem(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2489,6 +2511,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
vms->highmem_compact = value;
}
+#endif /* disabled for RHEL */
static bool virt_get_highmem_redists(Object *obj, Error **errp)
{
@@ -2547,6 +2570,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
vms->its = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_dtb_randomness(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2560,6 +2584,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
vms->dtb_randomness = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_oem_id(Object *obj, Error **errp)
{
@@ -2643,6 +2668,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
vms->ras = value;
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static bool virt_get_mte(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -2656,6 +2682,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
+#endif /* disabled for RHEL */
static char *virt_get_gic_version(Object *obj, Error **errp)
{
@@ -3063,16 +3090,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL
};
+ mc->family = "virt-rhel-Z";
mc->init = machvirt_init;
- /* Start with max_cpus set to 512, which is the maximum supported by KVM.
- * The value may be reduced later when we have more information about the
- * configuration of the particular instance.
- */
- mc->max_cpus = 512;
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM);
+ /* Maximum supported VCPU count for all virt-rhel* machines */
+ mc->max_cpus = 384;
#ifdef CONFIG_TPM
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
@@ -3083,11 +3104,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->minimum_page_bits = 12;
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
-#ifdef CONFIG_TCG
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
-#else
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
-#endif
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
mc->valid_cpu_types = valid_cpu_types;
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
mc->kvm_type = virt_kvm_type;
@@ -3111,6 +3128,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
NULL, NULL);
object_class_property_set_description(oc, "acpi",
"Enable ACPI");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "secure", virt_get_secure,
virt_set_secure);
object_class_property_set_description(oc, "secure",
@@ -3123,6 +3141,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
"Virtualization Extensions");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "highmem", virt_get_highmem,
virt_set_highmem);
@@ -3130,12 +3149,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable using "
"physical address space above 32 bits");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "compact-highmem",
virt_get_compact_highmem,
virt_set_compact_highmem);
object_class_property_set_description(oc, "compact-highmem",
"Set on/off to enable/disable compact "
"layout for high memory regions");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "highmem-redists",
virt_get_highmem_redists,
@@ -3163,7 +3184,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
virt_set_gic_version);
object_class_property_set_description(oc, "gic-version",
"Set GIC version. "
- "Valid values are 2, 3, 4, host and max");
+ "Valid values are 2, 3, host and max");
object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu);
object_class_property_set_description(oc, "iommu",
@@ -3183,11 +3204,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable reporting host memory errors "
"to a KVM guest using ACPI and guest external abort exceptions");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "mte", virt_get_mte, virt_set_mte);
object_class_property_set_description(oc, "mte",
"Set on/off to enable/disable emulating a "
"guest CPU which implements the ARM "
"Memory Tagging Extension");
+#endif /* disabled for RHEL */
object_class_property_add_bool(oc, "its", virt_get_its,
virt_set_its);
@@ -3195,6 +3218,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
"Set on/off to enable/disable "
"ITS instantiation");
+#if 0 /* disabled for RHEL */
object_class_property_add_bool(oc, "dtb-randomness",
virt_get_dtb_randomness,
virt_set_dtb_randomness);
@@ -3207,6 +3231,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
virt_set_dtb_randomness);
object_class_property_set_description(oc, "dtb-kaslr-seed",
"Deprecated synonym of dtb-randomness");
+#endif /* disabled for RHEL */
object_class_property_add_str(oc, "x-oem-id",
virt_get_oem_id,
@@ -3554,3 +3579,39 @@ static void virt_machine_2_6_options(MachineClass *mc)
}
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+
+static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
+
+static void virt_rhel_machine_9_2_0_options(MachineClass *mc)
+{
+ virt_rhel_machine_9_4_0_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+
+ /* RHEL 9.4 is the first supported release */
+ mc->deprecation_reason =
+ "machine types for versions prior to 9.4 are deprecated";
+}
+DEFINE_VIRT_MACHINE(9, 2, 0)
+
+static void virt_rhel_machine_9_0_0_options(MachineClass *mc)
+{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
+ virt_rhel_machine_9_2_0_options(mc);
+
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+
+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
+ vmc->no_tcg_lpa2 = true;
+ /* Compact layout for high memory regions was introduced with 9.2.0 */
+ vmc->no_highmem_compact = true;
+}
+DEFINE_VIRT_MACHINE(9, 0, 0)
--
2.39.3

@ -0,0 +1,208 @@
From 24d6b22e10c87e9a4bf4df834738f42caa1d5014 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44:36 +0100
Subject: Add downstream s390x versioned 's390-ccw-virtio' machine types
Adding changes to add RHEL machine types for s390x architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
Rebase notes(9.1.0 rc0):
- Convert to new DEFINE_CCW_MACHINE macros
Merged patches (9.1.0 rc0):
- 043ad5ce97 Add upstream compatibility bits (partial)
- 04596b496e s390x: remove deprecated rhel machine types
---
hw/s390x/s390-virtio-ccw.c | 65 +++++++++++++++++++++++++++++---
target/s390x/cpu_models.c | 11 ++++++
target/s390x/cpu_models.h | 2 +
target/s390x/cpu_models_sysemu.c | 2 +
4 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 86bfc9d2eb..451017c50e 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -617,6 +617,7 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
s390_cpu_restart(S390_CPU(cs));
}
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
{
/* same logic as in sclp.c */
@@ -636,6 +637,7 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz)
}
return newsz;
}
+#endif /* disabled for RHEL */
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
{
@@ -837,7 +839,7 @@ static const TypeInfo ccw_machine_info = {
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc); \
- mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \
+ mc->desc = "Virtual s390x machine (version rhel" MACHINE_VER_STR(__VA_ARGS__) ")"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
if (latest) { \
mc->alias = "s390-ccw-virtio"; \
@@ -864,11 +866,11 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
-#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(true, major, minor)
+#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor, micro) \
+ DEFINE_CCW_MACHINE_IMPL(true, major, minor, micro)
-#define DEFINE_CCW_MACHINE(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(false, major, minor)
+#define DEFINE_CCW_MACHINE(major, minor, micro) \
+ DEFINE_CCW_MACHINE_IMPL(false, major, minor, micro)
#if 0 /* Disabled for Red Hat Enterprise Linux */
@@ -1308,6 +1310,59 @@ DEFINE_CCW_MACHINE(2, 4);
#endif
#endif /* disabled for RHEL */
+static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
+{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+}
+DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
+
+static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine)
+{
+ ccw_rhel_machine_9_4_0_instance_options(machine);
+}
+
+static void ccw_rhel_machine_9_2_0_class_options(MachineClass *mc)
+{
+ ccw_rhel_machine_9_4_0_class_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
+ mc->smp_props.drawers_supported = false; /* from ccw_machine_8_1 */
+ mc->smp_props.books_supported = false; /* from ccw_machine_8_1 */
+}
+DEFINE_CCW_MACHINE(9, 2, 0);
+
+static void ccw_rhel_machine_9_0_0_instance_options(MachineState *machine)
+{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 };
+
+ ccw_rhel_machine_9_2_0_instance_options(machine);
+
+ s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat);
+ s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE);
+}
+
+static void ccw_rhel_machine_9_0_0_class_options(MachineClass *mc)
+{
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ { TYPE_S390_PCI_DEVICE, "interpret", "off", },
+ { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", },
+ };
+
+ ccw_rhel_machine_9_2_0_class_options(mc);
+
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
+ s390mc->max_threads = S390_MAX_CPUS;
+}
+DEFINE_CCW_MACHINE(9, 0, 0);
+
static void ccw_machine_register_types(void)
{
type_register_static(&ccw_machine_info);
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 798c18f940..8afa9af1a5 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -47,6 +47,9 @@
* of a following release have been a superset of the previous release. With
* generation 15 one base feature and one optional feature have been deprecated.
*/
+
+#define RHEL_CPU_DEPRECATION "use at least 'z14', or 'host' / 'qemu' / 'max'"
+
static S390CPUDef s390_cpu_defs[] = {
/*
* Linux requires at least z10 nowadays, and IBM only supports recent CPUs
@@ -871,22 +874,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* all base models are migration safe */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->is_static = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_cpu_model_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *xcc = S390_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
/* model that can change between QEMU versions */
xcc->cpu_def = (const S390CPUDef *) data;
xcc->is_migration_safe = true;
xcc->desc = xcc->cpu_def->desc;
+ if (xcc->cpu_def->gen < 14) {
+ cc->deprecation_note = RHEL_CPU_DEPRECATION;
+ }
}
static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data)
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index 71d4bc2dd4..d6c7c2cb50 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -38,6 +38,8 @@ typedef struct S390CPUDef {
S390FeatBitmap full_feat;
/* used to init full_feat from generated data */
S390FeatInit full_init;
+ /* if deprecated, provides a suggestion */
+ const char *deprecation_note;
} S390CPUDef;
/* CPU model based on a CPU definition */
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
index f6df691b66..b8de04de99 100644
--- a/target/s390x/cpu_models_sysemu.c
+++ b/target/s390x/cpu_models_sysemu.c
@@ -56,6 +56,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
CpuDefinitionInfo *info;
char *name = g_strdup(object_class_get_name(klass));
S390CPUClass *scc = S390_CPU_CLASS(klass);
+ CPUClass *cc = CPU_CLASS(klass);
/* strip off the -s390x-cpu */
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
@@ -65,6 +66,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
info->migration_safe = scc->is_migration_safe;
info->q_static = scc->is_static;
info->q_typename = g_strdup(object_class_get_name(klass));
+ info->deprecated = !!cc->deprecation_note;
/* check for unavailable features */
if (cpu_list_data->model) {
Object *obj;
--
2.39.3

@ -1,98 +1,54 @@
From 3c88acb005806ad2386ab6c94a8831151f624738 Mon Sep 17 00:00:00 2001 From c8510c21f0fde361d6cbce81bfb2f4acb6941b58 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Fri, 19 Oct 2018 13:10:31 +0200 Date: Wed, 3 Jul 2024 13:44:41 +0100
Subject: Add x86_64 machine types Subject: Add downstream x86_64 versioned 'pc' & 'q35' machine types
Adding changes to add RHEL machine types for x86_64 architecture. Adding changes to add RHEL machine types for x86_64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.1.0 rc0):
- Merged pc_q35_machine_rhel_options back into
pc_q35_machine_options to reduce delta to upstream
- Convert to new DEFINE_(I440FX|Q35)_MACHINE macros
Rebase notes (6.1.0): Rebase notes (9.1.0 rc4):
- Update qemu64 cpu spec - Moved x86 cpu deprecation note to device disable patch
Rebase notes (7.0.0):
- Reset alias for all machine-types except latest one
Rebase notes (8.0.0):
- remove legacy_no_rng_seed usage (removed upstream)
Rebase notes (8.1.0):
- default_nic_model to default_nic
Merged patches (6.1.0):
- 59c284ad3b x86: Add x86 rhel8.5 machine types
- a8868b42fe redhat: x86: Enable 'kvm-asyncpf-int' by default
- a3995e2eff Remove RHEL 7.0.0 machine type (only x86_64 changes)
- ad3190a79b Remove RHEL 7.1.0 machine type (only x86_64 changes)
- 84bbe15d4e Remove RHEL 7.2.0 machine type (only x86_64 changes)
- 0215eb3356 Remove RHEL 7.3.0 machine types (only x86_64 changes)
- af69d1ca6e Remove RHEL 7.4.0 machine types (only x86_64 changes)
- 8f7a74ab78 Remove RHEL 7.5.0 machine types (only x86_64 changes)
Merged patches (7.0.0):
- eae7d8dd3c x86/rhel machine types: Add pc_rhel_8_5_compat
- 6762f56469 x86/rhel machine types: Wire compat into q35 and i440fx
- 5762101438 rhel machine types/x86: set prefer_sockets
- 9ba9ddc632 x86: Add q35 RHEL 8.6.0 machine type
- 6110d865e5 x86: Add q35 RHEL 9.0.0 machine type
- dcc64971bf RHEL: mark old machine types as deprecated (partialy)
- 6b396f182b RHEL: disable "seqpacket" for "vhost-vsock-device" in rhel8.6.0
Merged patches (7.1.0):
- 38b89dc245 pc: Move s3/s4 suspend disabling to compat (only hw/i386/pc.c chunk)
- 1d6439527a WRB: Introduce RHEL 9.0.0 hw compat structure (x86_64 specific changes)
- 35b5c8554f target/i386: deprecate CPUs older than x86_64-v2 ABI
Merged patches (7.2.0):
- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts)
Merged patches (8.0.0):
- f33ca8aed4 x86: rhel 9.2.0 machine type
Merged patches (8.1.0):
- bd5d81d286 Add RHEL 9.2.0 compat structure (x86_64 part)
- c6eaf73add redhat: hw/i386/pc: Update x86 machine type compatibility for QEMU 8.0.0 update
- 6cbf496e5e hw/acpi: Mark acpi blobs as resizable on RHEL pc machines version 7.6 and above
Merged patches (8.2.0):
- 4ee284aca9 Add machine types compat bits. (partial)
- 719e2ac147 Fix x86 machine type compatibility for qemu-kvm 8.1.0
Merged patches (9.0.0 rc0): Merged patches (9.1.0 rc0):
- 9149e2bc8f x86: rhel 9.2.0 machine type compat fix - 043ad5ce97 Add upstream compatibility bits (partial)
--- ---
hw/i386/fw_cfg.c | 2 +- hw/i386/fw_cfg.c | 2 +-
hw/i386/pc.c | 159 ++++++++++++++++++++- hw/i386/pc.c | 159 ++++++++++++++++++++++++++++-
hw/i386/pc_piix.c | 109 ++++++++++++++ hw/i386/pc_piix.c | 102 ++++++++++++++++++-
hw/i386/pc_q35.c | 285 +++++++++++++++++++++++++++++++++++++ hw/i386/pc_q35.c | 204 +++++++++++++++++++++++++++++++++++--
include/hw/boards.h | 2 + include/hw/boards.h | 2 +
include/hw/i386/pc.h | 33 +++++ include/hw/i386/pc.h | 33 ++++++
target/i386/cpu.c | 21 +++
target/i386/kvm/kvm-cpu.c | 1 + target/i386/kvm/kvm-cpu.c | 1 +
target/i386/kvm/kvm.c | 4 + target/i386/kvm/kvm.c | 4 +
tests/qtest/pvpanic-test.c | 5 +- tests/qtest/pvpanic-test.c | 5 +-
10 files changed, 617 insertions(+), 4 deletions(-) 9 files changed, 499 insertions(+), 13 deletions(-)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index c7aa39a13e..283c3f4c16 100644 index 33ef280420..a322709ffa 100644
--- a/hw/i386/fw_cfg.c --- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c
@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, @@ -73,7 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
if (pcmc->smbios_defaults) { if (pcmc->smbios_defaults) {
/* These values are guest ABI, do not change */ /* These values are guest ABI, do not change */
- smbios_set_defaults("QEMU", mc->desc, mc->name, - smbios_set_defaults("QEMU", mc->desc, mc->name,
+ smbios_set_defaults("Red Hat", "KVM", mc->desc, + smbios_set_defaults("Red Hat", "KVM", mc->desc,
pcmc->smbios_uuid_encoded,
pcmc->smbios_stream_product, pcmc->smbios_stream_version); pcmc->smbios_stream_product, pcmc->smbios_stream_version);
} }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5c21b0c4db..4a154c1a9a 100644 index 7779c88a91..a49d346d2e 100644
--- a/hw/i386/pc.c --- a/hw/i386/pc.c
+++ b/hw/i386/pc.c +++ b/hw/i386/pc.c
@@ -326,6 +326,161 @@ GlobalProperty pc_compat_2_0[] = { @@ -276,6 +276,161 @@ const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4);
}; */
const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0); #define PC_FW_DATA (0x20000 + 0x8000)
+/* This macro is for changes to properties that are RHEL specific, +/* This macro is for changes to properties that are RHEL specific,
+ * different to the current upstream and to be applied to the latest + * different to the current upstream and to be applied to the latest
@ -252,15 +208,15 @@ index 5c21b0c4db..4a154c1a9a 100644
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
{ {
GSIState *s; GSIState *s;
@@ -1813,6 +1968,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) @@ -1767,6 +1922,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->resizable_acpi_blob = true; pcmc->kvmclock_create_always = true;
x86mc->apic_xrupt_override = true; x86mc->apic_xrupt_override = true;
assert(!mc->get_hotplug_handler); assert(!mc->get_hotplug_handler);
+ mc->async_pf_vmexit_disable = false; + mc->async_pf_vmexit_disable = false;
mc->get_hotplug_handler = pc_get_hotplug_handler; mc->get_hotplug_handler = pc_get_hotplug_handler;
mc->hotplug_allowed = pc_hotplug_allowed; mc->hotplug_allowed = pc_hotplug_allowed;
mc->cpu_index_to_instance_props = x86_cpu_index_to_props; mc->auto_enable_numa_with_memhp = true;
@@ -1823,7 +1979,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) @@ -1774,7 +1930,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->has_hotpluggable_cpus = true; mc->has_hotpluggable_cpus = true;
mc->default_boot_order = "cad"; mc->default_boot_order = "cad";
mc->block_default_type = IF_IDE; mc->block_default_type = IF_IDE;
@ -271,7 +227,7 @@ index 5c21b0c4db..4a154c1a9a 100644
mc->wakeup = pc_machine_wakeup; mc->wakeup = pc_machine_wakeup;
hc->pre_plug = pc_machine_device_pre_plug_cb; hc->pre_plug = pc_machine_device_pre_plug_cb;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 18ba076609..a647262d63 100644 index 67107b174a..5535e1ffbf 100644
--- a/hw/i386/pc_piix.c --- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c
@@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
@ -282,19 +238,21 @@ index 18ba076609..a647262d63 100644
#ifdef CONFIG_XEN #ifdef CONFIG_XEN
#include <xen/hvm/hvm_info_table.h> #include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h" #include "hw/xen/xen_pt.h"
@@ -422,6 +423,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp) @@ -445,8 +446,8 @@ static void pc_i440fx_init(MachineState *machine)
* hw_compat_*, pc_compat_*, or * pc_*_machine_options(). pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
*/ }
+#if 0 /* Disabled for Red Hat Enterprise Linux */ -#define DEFINE_I440FX_MACHINE(major, minor) \
static void pc_compat_2_3_fn(MachineState *machine) - DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor);
{ +#define DEFINE_I440FX_MACHINE(major, minor, micro) \
X86MachineState *x86ms = X86_MACHINE(machine); + DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor, micro);
@@ -951,3 +953,110 @@ static void xenfv_3_1_machine_options(MachineClass *m)
#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_i440fx_machine_options(MachineClass *m)
@@ -826,3 +827,100 @@ static void xenfv_machine_3_1_options(MachineClass *m)
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
xenfv_3_1_machine_options); xenfv_machine_3_1_options);
#endif #endif
+#endif /* Disabled for Red Hat Enterprise Linux */
+ +
+/* Red Hat Enterprise Linux machine types */ +/* Red Hat Enterprise Linux machine types */
+ +
@ -305,7 +263,6 @@ index 18ba076609..a647262d63 100644
+ m->family = "pc_piix_Y"; + m->family = "pc_piix_Y";
+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; + m->default_machine_opts = "firmware=bios-256k.bin,hpet=off";
+ pcmc->pci_root_uid = 0; + pcmc->pci_root_uid = 0;
+ pcmc->resizable_acpi_blob = true;
+ m->default_nic = "e1000"; + m->default_nic = "e1000";
+ m->default_display = "std"; + m->default_display = "std";
+ m->no_parallel = 1; + m->no_parallel = 1;
@ -318,12 +275,7 @@ index 18ba076609..a647262d63 100644
+ m->smp_props.prefer_sockets = true; + m->smp_props.prefer_sockets = true;
+} +}
+ +
+static void pc_init_rhel760(MachineState *machine) +static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m)
+{
+ pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
+}
+
+static void pc_machine_rhel760_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ ObjectClass *oc = OBJECT_CLASS(m); + ObjectClass *oc = OBJECT_CLASS(m);
@ -332,9 +284,6 @@ index 18ba076609..a647262d63 100644
+ m->async_pf_vmexit_disable = true; + m->async_pf_vmexit_disable = true;
+ m->smbus_no_migration_support = true; + m->smbus_no_migration_support = true;
+ +
+ /* All RHEL machines for prior major releases are deprecated */
+ m->deprecation_reason = rhel_old_machine_deprecation;
+
+ pcmc->pvh_enabled = false; + pcmc->pvh_enabled = false;
+ pcmc->default_cpu_version = CPU_VERSION_LEGACY; + pcmc->default_cpu_version = CPU_VERSION_LEGACY;
+ pcmc->kvmclock_create_always = false; + pcmc->kvmclock_create_always = false;
@ -356,7 +305,8 @@ index 18ba076609..a647262d63 100644
+ object_class_property_set_description(oc, "x-south-bridge", + object_class_property_set_description(oc, "x-south-bridge",
+ "Use a different south bridge than PIIX3"); + "Use a different south bridge than PIIX3");
+ +
+ + compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_4, + compat_props_add(m->compat_props, hw_compat_rhel_9_4,
+ hw_compat_rhel_9_4_len); + hw_compat_rhel_9_4_len);
+ compat_props_add(m->compat_props, hw_compat_rhel_9_3, + compat_props_add(m->compat_props, hw_compat_rhel_9_3,
@ -399,78 +349,63 @@ index 18ba076609..a647262d63 100644
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); + compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, +DEFINE_I440FX_MACHINE(7, 6, 0);
+ pc_machine_rhel760_options);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c7bc8a2041..e872dc7e46 100644 index 5fb283f2df..2ca9ff3747 100644
--- a/hw/i386/pc_q35.c --- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c
@@ -341,6 +341,7 @@ static void pc_q35_init(MachineState *machine) @@ -338,20 +338,19 @@ static void pc_q35_machine_options(MachineClass *m)
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) pcmc->pci_root_uid = 0;
pcmc->default_cpu_version = 1;
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static void pc_q35_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
@@ -693,3 +694,287 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, - m->family = "pc_q35";
pc_q35_2_4_machine_options); - m->desc = "Standard PC (Q35 + ICH9, 2009)";
+#endif /* Disabled for Red Hat Enterprise Linux */
+
+/* Red Hat Enterprise Linux machine types */
+
+/* Options for the latest rhel q35 machine type */
+static void pc_q35_machine_rhel_options(MachineClass *m)
+{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pcmc->pci_root_uid = 0;
+ m->default_nic = "e1000e";
+ m->family = "pc_q35_Z"; + m->family = "pc_q35_Z";
+ m->units_per_default_bus = 1; m->units_per_default_bus = 1;
- m->default_machine_opts = "firmware=bios-256k.bin";
+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; + m->default_machine_opts = "firmware=bios-256k.bin,hpet=off";
+ m->default_display = "std"; m->default_display = "std";
+ m->no_floppy = 1; m->default_nic = "e1000e";
- m->default_kernel_irqchip_split = false;
m->no_floppy = 1;
- m->max_cpus = 4096;
- m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
+ m->max_cpus = 710;
+ m->no_parallel = 1; + m->no_parallel = 1;
+ pcmc->default_cpu_version = 1; machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); - machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
+ m->alias = "q35"; + m->alias = "q35";
+ m->max_cpus = 710;
+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); + compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
+ compat_props_add(m->compat_props, compat_props_add(m->compat_props,
+ pc_q35_compat_defaults, pc_q35_compat_defaults_len); pc_q35_compat_defaults, pc_q35_compat_defaults_len);
+} }
@@ -670,3 +669,194 @@ static void pc_q35_machine_2_4_options(MachineClass *m)
DEFINE_Q35_MACHINE(2, 4);
#endif /* Disabled for Red Hat Enterprise Linux */
+ +
+static void pc_q35_init_rhel940(MachineState *machine) +/* Red Hat Enterprise Linux machine types */
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel940_options(MachineClass *m) +static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel_options(m); + pc_q35_machine_options(m);
+ m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
+ pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_product = "RHEL";
+ pcmc->smbios_stream_version = "9.4.0"; + pcmc->smbios_stream_version = "9.4.0";
+}
+
+DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940,
+ pc_q35_machine_rhel940_options);
+
+ +
+static void pc_q35_init_rhel920(MachineState *machine) + compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+{ + hw_compat_rhel_9_5_len);
+ pc_q35_init(machine);
+} +}
+ +
+static void pc_q35_machine_rhel920_options(MachineClass *m) +DEFINE_Q35_MACHINE_BUGFIX(9, 4, 0);
+
+static void pc_q35_rhel_machine_9_2_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel940_options(m); + pc_q35_rhel_machine_9_4_0_options(m);
+ m->desc = "RHEL-9.2.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-9.2.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_product = "RHEL";
@ -493,18 +428,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_9_2_compat_len); + pc_rhel_9_2_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel920, "pc-q35-rhel9.2.0", pc_q35_init_rhel920, +DEFINE_Q35_MACHINE_BUGFIX(9, 2, 0);
+ pc_q35_machine_rhel920_options);
+ +
+static void pc_q35_init_rhel900(MachineState *machine) +static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel900_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel920_options(m); + pc_q35_rhel_machine_9_2_0_options(m);
+ m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_product = "RHEL";
@ -518,43 +447,27 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_9_0_compat_len); + pc_rhel_9_0_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900, +DEFINE_Q35_MACHINE_BUGFIX(9, 0, 0);
+ pc_q35_machine_rhel900_options);
+
+static void pc_q35_init_rhel860(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel860_options(MachineClass *m) +static void pc_q35_rhel_machine_8_6_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel900_options(m); + pc_q35_rhel_machine_9_0_0_options(m);
+ m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ +
+ /* All RHEL machines for prior major releases are deprecated */
+ m->deprecation_reason = rhel_old_machine_deprecation;
+
+ pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_product = "RHEL-AV";
+ pcmc->smbios_stream_version = "8.6.0"; + pcmc->smbios_stream_version = "8.6.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_8_6, + compat_props_add(m->compat_props, hw_compat_rhel_8_6,
+ hw_compat_rhel_8_6_len); + hw_compat_rhel_8_6_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel860, "pc-q35-rhel8.6.0", pc_q35_init_rhel860, +DEFINE_Q35_MACHINE_BUGFIX(8, 6, 0);
+ pc_q35_machine_rhel860_options);
+
+
+static void pc_q35_init_rhel850(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel850_options(MachineClass *m) +static void pc_q35_rhel_machine_8_5_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel860_options(m); + pc_q35_rhel_machine_8_6_0_options(m);
+ m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_product = "RHEL-AV";
@ -566,19 +479,12 @@ index c7bc8a2041..e872dc7e46 100644
+ m->smp_props.prefer_sockets = true; + m->smp_props.prefer_sockets = true;
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel850, "pc-q35-rhel8.5.0", pc_q35_init_rhel850, +DEFINE_Q35_MACHINE_BUGFIX(8, 5, 0);
+ pc_q35_machine_rhel850_options);
+
+
+static void pc_q35_init_rhel840(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel840_options(MachineClass *m) +static void pc_q35_rhel_machine_8_4_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel850_options(m); + pc_q35_rhel_machine_8_5_0_options(m);
+ m->desc = "RHEL-8.4.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.4.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_product = "RHEL-AV";
@ -589,19 +495,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_8_4_compat_len); + pc_rhel_8_4_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel840, "pc-q35-rhel8.4.0", pc_q35_init_rhel840, +DEFINE_Q35_MACHINE_BUGFIX(8, 4, 0);
+ pc_q35_machine_rhel840_options);
+ +
+ +static void pc_q35_rhel_machine_8_3_0_options(MachineClass *m)
+static void pc_q35_init_rhel830(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel830_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel840_options(m); + pc_q35_rhel_machine_8_4_0_options(m);
+ m->desc = "RHEL-8.3.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.3.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_product = "RHEL-AV";
@ -616,18 +515,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pcmc->pci_root_uid = 1; + pcmc->pci_root_uid = 1;
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel830, "pc-q35-rhel8.3.0", pc_q35_init_rhel830, +DEFINE_Q35_MACHINE_BUGFIX(8, 3, 0);
+ pc_q35_machine_rhel830_options);
+
+static void pc_q35_init_rhel820(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel820_options(MachineClass *m) +static void pc_q35_rhel_machine_8_2_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel830_options(m); + pc_q35_rhel_machine_8_3_0_options(m);
+ m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ m->numa_mem_supported = true; + m->numa_mem_supported = true;
@ -640,18 +533,12 @@ index c7bc8a2041..e872dc7e46 100644
+ pc_rhel_8_2_compat_len); + pc_rhel_8_2_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel820, "pc-q35-rhel8.2.0", pc_q35_init_rhel820, +DEFINE_Q35_MACHINE_BUGFIX(8, 2, 0);
+ pc_q35_machine_rhel820_options);
+
+static void pc_q35_init_rhel810(MachineState *machine)
+{
+ pc_q35_init(machine);
+}
+ +
+static void pc_q35_machine_rhel810_options(MachineClass *m) +static void pc_q35_rhel_machine_8_1_0_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel820_options(m); + pc_q35_rhel_machine_8_2_0_options(m);
+ m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)";
+ m->alias = NULL; + m->alias = NULL;
+ pcmc->smbios_stream_product = NULL; + pcmc->smbios_stream_product = NULL;
@ -660,18 +547,12 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len); + compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel810, "pc-q35-rhel8.1.0", pc_q35_init_rhel810, +DEFINE_Q35_MACHINE_BUGFIX(8, 1, 0);
+ pc_q35_machine_rhel810_options);
+ +
+static void pc_q35_init_rhel800(MachineState *machine) +static void pc_q35_rhel_machine_8_0_0_options(MachineClass *m)
+{
+ pc_q35_init(machine);
+}
+
+static void pc_q35_machine_rhel800_options(MachineClass *m)
+{ +{
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ pc_q35_machine_rhel810_options(m); + pc_q35_rhel_machine_8_1_0_options(m);
+ m->desc = "RHEL-8.0.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-8.0.0 PC (Q35 + ICH9, 2009)";
+ m->smbus_no_migration_support = true; + m->smbus_no_migration_support = true;
+ m->alias = NULL; + m->alias = NULL;
@ -681,17 +562,11 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len); + compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel800, "pc-q35-rhel8.0.0", pc_q35_init_rhel800, +DEFINE_Q35_MACHINE_BUGFIX(8, 0, 0);
+ pc_q35_machine_rhel800_options);
+ +
+static void pc_q35_init_rhel760(MachineState *machine) +static void pc_q35_rhel_machine_7_6_0_options(MachineClass *m)
+{ +{
+ pc_q35_init(machine); + pc_q35_rhel_machine_8_0_0_options(m);
+}
+
+static void pc_q35_machine_rhel760_options(MachineClass *m)
+{
+ pc_q35_machine_rhel800_options(m);
+ m->alias = NULL; + m->alias = NULL;
+ m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)"; + m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)";
+ m->async_pf_vmexit_disable = true; + m->async_pf_vmexit_disable = true;
@ -699,13 +574,13 @@ index c7bc8a2041..e872dc7e46 100644
+ compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); + compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len);
+} +}
+ +
+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, +DEFINE_Q35_MACHINE_BUGFIX(7, 6, 0);
+ pc_q35_machine_rhel760_options); +
diff --git a/include/hw/boards.h b/include/hw/boards.h diff --git a/include/hw/boards.h b/include/hw/boards.h
index 0466f9d0f3..46b8725c41 100644 index fd5a957cad..3dea5cee73 100644
--- a/include/hw/boards.h --- a/include/hw/boards.h
+++ b/include/hw/boards.h +++ b/include/hw/boards.h
@@ -283,6 +283,8 @@ struct MachineClass { @@ -289,6 +289,8 @@ struct MachineClass {
strList *allowed_dynamic_sysbus_devices; strList *allowed_dynamic_sysbus_devices;
bool auto_enable_numa_with_memhp; bool auto_enable_numa_with_memhp;
bool auto_enable_numa_with_memdev; bool auto_enable_numa_with_memdev;
@ -715,12 +590,12 @@ index 0466f9d0f3..46b8725c41 100644
bool smbus_no_migration_support; bool smbus_no_migration_support;
bool nvdimm_supported; bool nvdimm_supported;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ebd8f973f2..a984c951ad 100644 index 8776a3c937..8e9597f40f 100644
--- a/include/hw/i386/pc.h --- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h
@@ -291,6 +291,39 @@ extern const size_t pc_compat_2_1_len; @@ -302,6 +302,39 @@ extern const size_t pc_compat_2_4_len;
extern GlobalProperty pc_compat_2_0[]; extern GlobalProperty pc_compat_2_3[];
extern const size_t pc_compat_2_0_len; extern const size_t pc_compat_2_3_len;
+extern GlobalProperty pc_rhel_compat[]; +extern GlobalProperty pc_rhel_compat[];
+extern const size_t pc_rhel_compat_len; +extern const size_t pc_rhel_compat_len;
@ -758,165 +633,11 @@ index ebd8f973f2..a984c951ad 100644
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
{ \ { \
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 33760a2ee1..be7b0663cd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2190,9 +2190,13 @@ static const CPUCaches epyc_genoa_cache_info = {
* PT in VMX operation
*/
+#define RHEL_CPU_DEPRECATION \
+ "use at least 'Nehalem' / 'Opteron_G4', or 'host' / 'max'"
+
static const X86CPUDefinition builtin_x86_defs[] = {
{
.name = "qemu64",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -2213,6 +2217,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "phenom",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
@@ -2245,6 +2250,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "core2duo",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2287,6 +2293,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "kvm64",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -2328,6 +2335,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "qemu32",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2342,6 +2350,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "kvm32",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -2372,6 +2381,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "coreduo",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2405,6 +2415,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "486",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 4,
@@ -2417,6 +2428,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 5,
@@ -2429,6 +2441,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2441,6 +2454,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "pentium3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 3,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2453,6 +2467,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "athlon",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 2,
.vendor = CPUID_VENDOR_AMD,
.family = 6,
@@ -2468,6 +2483,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "n270",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2493,6 +2509,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Conroe",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -2533,6 +2550,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Penryn",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -4394,6 +4412,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G1",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4414,6 +4433,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G2",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -4436,6 +4456,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
},
{
.name = "Opteron_G3",
+ .deprecation_note = RHEL_CPU_DEPRECATION,
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 9c791b7b05..b91af5051f 100644 index 6bf8dcfc60..684e731cbc 100644
--- a/target/i386/kvm/kvm-cpu.c --- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c
@@ -138,6 +138,7 @@ static PropValue kvm_default_props[] = { @@ -178,6 +178,7 @@ static PropValue kvm_default_props[] = {
{ "acpi", "off" }, { "acpi", "off" },
{ "monitor", "off" }, { "monitor", "off" },
{ "svm", "off" }, { "svm", "off" },
@ -925,10 +646,10 @@ index 9c791b7b05..b91af5051f 100644
}; };
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index e68cbe9293..739f33db47 100644 index 2fa88ef1e3..2b28c18693 100644
--- a/target/i386/kvm/kvm.c --- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c
@@ -3715,6 +3715,7 @@ static int kvm_get_msrs(X86CPU *cpu) @@ -4244,6 +4244,7 @@ static int kvm_get_msrs(X86CPU *cpu)
struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
int ret, i; int ret, i;
uint64_t mtrr_top_bits; uint64_t mtrr_top_bits;
@ -936,7 +657,7 @@ index e68cbe9293..739f33db47 100644
kvm_msr_buf_reset(cpu); kvm_msr_buf_reset(cpu);
@@ -4069,6 +4070,9 @@ static int kvm_get_msrs(X86CPU *cpu) @@ -4636,6 +4637,9 @@ static int kvm_get_msrs(X86CPU *cpu)
break; break;
case MSR_KVM_ASYNC_PF_EN: case MSR_KVM_ASYNC_PF_EN:
env->async_pf_en_msr = msrs[i].data; env->async_pf_en_msr = msrs[i].data;
@ -947,10 +668,10 @@ index e68cbe9293..739f33db47 100644
case MSR_KVM_ASYNC_PF_INT: case MSR_KVM_ASYNC_PF_INT:
env->async_pf_int_msr = msrs[i].data; env->async_pf_int_msr = msrs[i].data;
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index 78f1cf8186..ac954c9b06 100644 index d49d2ba931..c18f63e255 100644
--- a/tests/qtest/pvpanic-test.c --- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c +++ b/tests/qtest/pvpanic-test.c
@@ -17,7 +17,7 @@ static void test_panic_nopause(void) @@ -18,7 +18,7 @@ static void test_panic_nopause(void)
QDict *response, *data; QDict *response, *data;
QTestState *qts; QTestState *qts;
@ -958,8 +679,8 @@ index 78f1cf8186..ac954c9b06 100644
+ qts = qtest_init("-M q35 -device pvpanic -action panic=none"); + qts = qtest_init("-M q35 -device pvpanic -action panic=none");
val = qtest_inb(qts, 0x505); val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3); g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
@@ -40,7 +40,8 @@ static void test_panic(void) @@ -41,7 +41,8 @@ static void test_panic(void)
QDict *response, *data; QDict *response, *data;
QTestState *qts; QTestState *qts;
@ -968,7 +689,7 @@ index 78f1cf8186..ac954c9b06 100644
+ qts = qtest_init("-M q35 -device pvpanic -action panic=pause"); + qts = qtest_init("-M q35 -device pvpanic -action panic=pause");
val = qtest_inb(qts, 0x505); val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3); g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
-- --
2.39.3 2.39.3

@ -0,0 +1,32 @@
From bd6f1170d3a011c475ec4a8315512c7c190de3e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:47:04 +0100
Subject: Revert "meson: temporarily disable -Wunused-function"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit c682111eaa73d9b985187b8be330338f50b78a7a.
No longer needed after introduction of downstream machines.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 1 -
1 file changed, 1 deletion(-)
diff --git a/meson.build b/meson.build
index 2de5ab024f..b3529aa0e1 100644
--- a/meson.build
+++ b/meson.build
@@ -651,7 +651,6 @@ warn_flags = [
'-Wno-string-plus-int',
'-Wno-tautological-type-limit-compare',
'-Wno-typedef-redefinition',
- '-Wno-unused-function',
]
if host_os != 'darwin'
--
2.39.3

@ -1,4 +1,4 @@
From 5768cf6811842e5c59da3b752f60659a9d6b5ba1 Mon Sep 17 00:00:00 2001 From 3c4bab07566d32859e227ca1083b0dc64111e3f7 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 2 Sep 2020 09:39:41 +0200 Date: Wed, 2 Sep 2020 09:39:41 +0200
Subject: Enable make check Subject: Enable make check
@ -7,50 +7,18 @@ Fixing tests after device disabling and machine types changes and enabling
make check run during build. make check run during build.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase changes (6.1.0):
- removed unnecessary test changes
Rebase changes (6.2.0):
- new way of disabling bios-table-test
Rebase changes (7.0.0):
- Disable testing virtio-iommu-pci
- Rename default_bus_bypass_iommu property to default-bus-bypass-iommu
- Disable qtest-bios-table for aarch64
- Removed redhat chunks for boot-serial-test.c, cdrom-test.c and cpu-plug-test.c qtests
- Do not disable boot-order-test, prom-env-test and boot-serial-test qtests
- Use rhel machine type for new intel hda qtest
- Remove unnecessary changes in iotest 051
- Remove changes in bios-tables-test.c and prom-env-test.c qtests
Rebase changes (7.1.0):
- Disable bcm2835-dma-test (added upstream)
Rebase changes (8.0.0):
- Removed chunks for disabling bios-table-test (protected upstream)
- Disable new qemu-iotests execution
- Revert change in tco qtest (blocking test run)
Rebase changes (8.1.0): ---
- Do not disable device-plug-test for s390x Rebase notes (9.1.0 rc0):
- Disable fdc-testa
Rebase changes (8.2.0 rc1):
- Remove unneeded hack in qtest/usb-hcd-xhci-test.c
Merged patches (6.1.0):
- 2f129df7d3 redhat: Enable the 'test-block-iothread' test again
Merged patches (7.1.0):
- 64d736640e RHEL-only: tests/avocado: Switch aarch64 tests from a53 to a57
Merged patches (8.1.0): Rebase notes (9.1.0 rc0):
- f468163234 iotests: Use alternative CPU type that is not deprecated in RHEL - Use q35 machine type for new pvpanic test
--- ---
.distro/qemu-kvm.spec.template | 4 ++-- .distro/qemu-kvm.spec.template | 4 ++--
tests/avocado/replay_kernel.py | 2 +- tests/avocado/replay_kernel.py | 2 +-
tests/avocado/reverse_debugging.py | 2 +- tests/avocado/reverse_debugging.py | 2 +-
tests/avocado/tcg_plugins.py | 6 ++--- tests/avocado/tcg_plugins.py | 4 ++--
tests/qemu-iotests/meson.build | 34 ++++++++++++++--------------- tests/qemu-iotests/meson.build | 34 ++++++++++++++---------------
tests/qemu-iotests/testenv.py | 3 +++ tests/qemu-iotests/testenv.py | 3 +++
tests/qtest/fuzz-e1000e-test.c | 2 +- tests/qtest/fuzz-e1000e-test.c | 2 +-
@ -58,15 +26,16 @@ Merged patches (8.1.0):
tests/qtest/intel-hda-test.c | 2 +- tests/qtest/intel-hda-test.c | 2 +-
tests/qtest/libqos/meson.build | 2 +- tests/qtest/libqos/meson.build | 2 +-
tests/qtest/lpc-ich9-test.c | 2 +- tests/qtest/lpc-ich9-test.c | 2 +-
tests/qtest/meson.build | 1 - tests/qtest/meson.build | 3 +--
tests/qtest/pvpanic-test.c | 2 +-
tests/qtest/virtio-net-failover.c | 1 + tests/qtest/virtio-net-failover.c | 1 +
13 files changed, 33 insertions(+), 30 deletions(-) 14 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
index 10d99403a4..c3422ea1e4 100644 index e22c200a36..cb7ca19b1b 100644
--- a/tests/avocado/replay_kernel.py --- a/tests/avocado/replay_kernel.py
+++ b/tests/avocado/replay_kernel.py +++ b/tests/avocado/replay_kernel.py
@@ -166,7 +166,7 @@ def test_aarch64_virt(self): @@ -193,7 +193,7 @@ def test_aarch64_virt(self):
""" """
:avocado: tags=arch:aarch64 :avocado: tags=arch:aarch64
:avocado: tags=machine:virt :avocado: tags=machine:virt
@ -76,10 +45,10 @@ index 10d99403a4..c3422ea1e4 100644
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot' '/linux/releases/29/Everything/aarch64/os/images/pxeboot'
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
index 92855a02a5..87822074b6 100644 index f24287cd0a..3880b81df6 100644
--- a/tests/avocado/reverse_debugging.py --- a/tests/avocado/reverse_debugging.py
+++ b/tests/avocado/reverse_debugging.py +++ b/tests/avocado/reverse_debugging.py
@@ -230,7 +230,7 @@ def test_aarch64_virt(self): @@ -228,7 +228,7 @@ def test_aarch64_virt(self):
""" """
:avocado: tags=arch:aarch64 :avocado: tags=arch:aarch64
:avocado: tags=machine:virt :avocado: tags=machine:virt
@ -89,7 +58,7 @@ index 92855a02a5..87822074b6 100644
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
'/linux/releases/29/Everything/aarch64/os/images/pxeboot' '/linux/releases/29/Everything/aarch64/os/images/pxeboot'
diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py
index 15fd87b2c1..f0d9d89c93 100644 index a6ff457e27..5172ee9b9e 100644
--- a/tests/avocado/tcg_plugins.py --- a/tests/avocado/tcg_plugins.py
+++ b/tests/avocado/tcg_plugins.py +++ b/tests/avocado/tcg_plugins.py
@@ -66,7 +66,7 @@ def test_aarch64_virt_insn(self): @@ -66,7 +66,7 @@ def test_aarch64_virt_insn(self):
@ -106,15 +75,6 @@ index 15fd87b2c1..f0d9d89c93 100644
:avocado: tags=arch:aarch64 :avocado: tags=arch:aarch64
:avocado: tags=machine:virt :avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53 - :avocado: tags=cpu:cortex-a53
+ :avocado: tags=cpu:cortex-a57
"""
kernel_path = self._grab_aarch64_kernel()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@@ -126,7 +126,7 @@ def test_aarch64_virt_mem_icount(self):
:avocado: tags=accel:tcg
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
- :avocado: tags=cpu:cortex-a53
+ :avocado: tags=cpu:cortex-a57 + :avocado: tags=cpu:cortex-a57
""" """
kernel_path = self._grab_aarch64_kernel() kernel_path = self._grab_aarch64_kernel()
@ -163,10 +123,10 @@ index fad340ad59..3c0d5241f6 100644
+# endforeach +# endforeach
endforeach endforeach
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 588f30a4f1..3929a3634f 100644 index c8848f2ec2..d515e5b8b0 100644
--- a/tests/qemu-iotests/testenv.py --- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py +++ b/tests/qemu-iotests/testenv.py
@@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str, @@ -249,6 +249,9 @@ def __init__(self, source_dir: str, build_dir: str,
if self.qemu_prog.endswith(f'qemu-system-{suffix}'): if self.qemu_prog.endswith(f'qemu-system-{suffix}'):
self.qemu_options += f' -machine {machine}' self.qemu_options += f' -machine {machine}'
@ -177,7 +137,7 @@ index 588f30a4f1..3929a3634f 100644
self.qemu_default_machine = get_default_machine(self.qemu_prog) self.qemu_default_machine = get_default_machine(self.qemu_prog)
diff --git a/tests/qtest/fuzz-e1000e-test.c b/tests/qtest/fuzz-e1000e-test.c diff --git a/tests/qtest/fuzz-e1000e-test.c b/tests/qtest/fuzz-e1000e-test.c
index 5052883fb6..b5286f4b12 100644 index 5052883fb6..8242190170 100644
--- a/tests/qtest/fuzz-e1000e-test.c --- a/tests/qtest/fuzz-e1000e-test.c
+++ b/tests/qtest/fuzz-e1000e-test.c +++ b/tests/qtest/fuzz-e1000e-test.c
@@ -17,7 +17,7 @@ static void test_lp1879531_eth_get_rss_ex_dst_addr(void) @@ -17,7 +17,7 @@ static void test_lp1879531_eth_get_rss_ex_dst_addr(void)
@ -185,12 +145,12 @@ index 5052883fb6..b5286f4b12 100644
QTestState *s; QTestState *s;
- s = qtest_init("-nographic -monitor none -serial none -M pc-q35-5.0"); - s = qtest_init("-nographic -monitor none -serial none -M pc-q35-5.0");
+ s = qtest_init("-nographic -monitor none -serial none -M pc-q35-rhel8.4.0"); + s = qtest_init("-nographic -monitor none -serial none -M pc-q35-rhel9.4.0");
qtest_outl(s, 0xcf8, 0x80001010); qtest_outl(s, 0xcf8, 0x80001010);
qtest_outl(s, 0xcfc, 0xe1020000); qtest_outl(s, 0xcfc, 0xe1020000);
diff --git a/tests/qtest/fuzz-virtio-scsi-test.c b/tests/qtest/fuzz-virtio-scsi-test.c diff --git a/tests/qtest/fuzz-virtio-scsi-test.c b/tests/qtest/fuzz-virtio-scsi-test.c
index e37b48b2cc..88647da054 100644 index e37b48b2cc..9f1965b530 100644
--- a/tests/qtest/fuzz-virtio-scsi-test.c --- a/tests/qtest/fuzz-virtio-scsi-test.c
+++ b/tests/qtest/fuzz-virtio-scsi-test.c +++ b/tests/qtest/fuzz-virtio-scsi-test.c
@@ -19,7 +19,7 @@ static void test_mmio_oob_from_memory_region_cache(void) @@ -19,7 +19,7 @@ static void test_mmio_oob_from_memory_region_cache(void)
@ -198,7 +158,7 @@ index e37b48b2cc..88647da054 100644
QTestState *s; QTestState *s;
- s = qtest_init("-M pc-q35-5.2 -m 512M " - s = qtest_init("-M pc-q35-5.2 -m 512M "
+ s = qtest_init("-M pc-q35-rhel8.4.0 -m 512M " + s = qtest_init("-M pc-q35-rhel9.4.0 -m 512M "
"-device virtio-scsi,num_queues=8,addr=03.0 "); "-device virtio-scsi,num_queues=8,addr=03.0 ");
qtest_outl(s, 0xcf8, 0x80001811); qtest_outl(s, 0xcf8, 0x80001811);
@ -216,7 +176,7 @@ index 663bb6c485..2efc43e3f7 100644
"-device intel-hda,id=" HDA_ID CODEC_DEVICES); "-device intel-hda,id=" HDA_ID CODEC_DEVICES);
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 3aed6efcb8..119613237e 100644 index 1b2b2dbb22..86afbddb58 100644
--- a/tests/qtest/libqos/meson.build --- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build
@@ -44,7 +44,7 @@ libqos_srcs = files( @@ -44,7 +44,7 @@ libqos_srcs = files(
@ -229,7 +189,7 @@ index 3aed6efcb8..119613237e 100644
'virtio-scmi.c', 'virtio-scmi.c',
'generic-pcihost.c', 'generic-pcihost.c',
diff --git a/tests/qtest/lpc-ich9-test.c b/tests/qtest/lpc-ich9-test.c diff --git a/tests/qtest/lpc-ich9-test.c b/tests/qtest/lpc-ich9-test.c
index 8ac95b89f7..cd2102555c 100644 index 8ac95b89f7..0e118b76eb 100644
--- a/tests/qtest/lpc-ich9-test.c --- a/tests/qtest/lpc-ich9-test.c
+++ b/tests/qtest/lpc-ich9-test.c +++ b/tests/qtest/lpc-ich9-test.c
@@ -15,7 +15,7 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void) @@ -15,7 +15,7 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void)
@ -237,15 +197,24 @@ index 8ac95b89f7..cd2102555c 100644
QTestState *s; QTestState *s;
- s = qtest_init("-M pc-q35-5.0 " - s = qtest_init("-M pc-q35-5.0 "
+ s = qtest_init("-M pc-q35-rhel8.4.0 " + s = qtest_init("-M pc-q35-rhel9.4.0 "
"-nographic -monitor none -serial none"); "-nographic -monitor none -serial none");
qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */ qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 36c5c13a7b..a2887d6057 100644 index 2f0d3ef080..134c48c10e 100644
--- a/tests/qtest/meson.build --- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build +++ b/tests/qtest/meson.build
@@ -101,7 +101,6 @@ qtests_i386 = \ @@ -91,7 +91,7 @@ qtests_i386 = \
config_all_devices.has_key('CONFIG_PARALLEL') ? ['bios-tables-test'] : []) + \
qtests_pci + \
qtests_cxl + \
- ['fdc-test',
+ [
'ide-test',
'hd-geo-test',
'boot-order-test',
@@ -102,7 +102,6 @@ qtests_i386 = \
'drive_del-test', 'drive_del-test',
'tco-test', 'tco-test',
'cpu-plug-test', 'cpu-plug-test',
@ -253,6 +222,19 @@ index 36c5c13a7b..a2887d6057 100644
'vmgenid-test', 'vmgenid-test',
'migration-test', 'migration-test',
'test-x86-cpuid-compat', 'test-x86-cpuid-compat',
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
index c18f63e255..57fb129ae4 100644
--- a/tests/qtest/pvpanic-test.c
+++ b/tests/qtest/pvpanic-test.c
@@ -65,7 +65,7 @@ static void test_pvshutdown(void)
QDict *response, *data;
QTestState *qts;
- qts = qtest_init("-device pvpanic");
+ qts = qtest_init("-M q35 -device pvpanic");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c
index 73dfabc272..a9dd304781 100644 index 73dfabc272..a9dd304781 100644
--- a/tests/qtest/virtio-net-failover.c --- a/tests/qtest/virtio-net-failover.c

@ -1,121 +0,0 @@
From 59470e8ab849f22b407f55292e540e16a8cad01a Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 20 Mar 2024 05:34:32 -0400
Subject: Add upstream compatibility bits
Adding new compats structure for changes introduced during rebase to QEMU 9.0.0.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (9.0.0 rc2):
- Add aw-bits setting for aarch compat record (overwritten for 9.4 and older)
---
hw/arm/virt.c | 3 +++
hw/core/machine.c | 10 ++++++++++
hw/i386/pc_piix.c | 3 ++-
hw/i386/pc_q35.c | 3 +++
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/boards.h | 3 +++
6 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 22bc345137..f1af9495c6 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -144,6 +144,8 @@ GlobalProperty arm_rhel_compat[] = {
{"virtio-net-pci", "romfile", "" },
{"virtio-net-pci-transitional", "romfile", "" },
{"virtio-net-pci-non-transitional", "romfile", "" },
+ /* arm_rhel_compat from arm_virt_compat, added for 9.0.0 rebase */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
};
const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
@@ -3728,6 +3730,7 @@ type_init(rhel_machine_init);
static void rhel940_virt_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 695cb89a46..0f256d9633 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -302,6 +302,16 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
const char *rhel_old_machine_deprecation =
"machine types for previous major releases are deprecated";
+GlobalProperty hw_compat_rhel_9_5[] = {
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { "migration", "zero-page-detection", "legacy"},
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
+};
+const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
+
GlobalProperty hw_compat_rhel_9_4[] = {
/* hw_compat_rhel_9_4 from hw_compat_8_0 */
{ TYPE_VIRTIO_NET, "host_uso", "off"},
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a647262d63..6b260682eb 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -1015,7 +1015,8 @@ static void pc_machine_rhel760_options(MachineClass *m)
object_class_property_set_description(oc, "x-south-bridge",
"Use a different south bridge than PIIX3");
-
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_4,
hw_compat_rhel_9_4_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_3,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e872dc7e46..2b54944c0f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -733,6 +733,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
+ hw_compat_rhel_9_5_len);
}
DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940,
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index ff753a29e0..9ad54682c6 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1282,6 +1282,7 @@ static void ccw_machine_rhel940_instance_options(MachineState *machine)
static void ccw_machine_rhel940_class_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 46b8725c41..cca62f906b 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -514,6 +514,9 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_9_5[];
+extern const size_t hw_compat_rhel_9_5_len;
+
extern GlobalProperty hw_compat_rhel_9_4[];
extern const size_t hw_compat_rhel_9_4_len;
--
2.39.3

@ -1,17 +1,8 @@
From e06a905d726fc20ea6bd95dff1bd0ffe97ebb202 Mon Sep 17 00:00:00 2001 From 9813098fb73e899dd1d824f9c1e7e570a87b1771 Mon Sep 17 00:00:00 2001
From: Bandan Das <bsd@redhat.com> From: Bandan Das <bsd@redhat.com>
Date: Tue, 3 Dec 2013 20:05:13 +0100 Date: Tue, 3 Dec 2013 20:05:13 +0100
Subject: vfio: cap number of devices that can be assigned Subject: vfio: cap number of devices that can be assigned
RH-Author: Bandan Das <bsd@redhat.com>
Message-id: <1386101113-31560-3-git-send-email-bsd@redhat.com>
Patchwork-id: 55984
O-Subject: [PATCH RHEL7 qemu-kvm v2 2/2] vfio: cap number of devices that can be assigned
Bugzilla: 678368
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
Go through all groups to get count of total number of devices Go through all groups to get count of total number of devices
active to enforce limit active to enforce limit
@ -26,16 +17,13 @@ Count of slots increased to 509 later so we could increase limit
to 64 as some usecases require more than 32 devices. to 64 as some usecases require more than 32 devices.
Signed-off-by: Bandan Das <bsd@redhat.com> Signed-off-by: Bandan Das <bsd@redhat.com>
Rebase changes (8.2.0):
- Update to upstream changes
--- ---
hw/vfio/pci.c | 31 ++++++++++++++++++++++++++++++- hw/vfio/pci.c | 31 ++++++++++++++++++++++++++++++-
hw/vfio/pci.h | 1 + hw/vfio/pci.h | 1 +
2 files changed, 31 insertions(+), 1 deletion(-) 2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 64780d1b79..57ac63c10c 100644 index 2407720c35..82a47edc89 100644
--- a/hw/vfio/pci.c --- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c +++ b/hw/vfio/pci.c
@@ -50,6 +50,9 @@ @@ -50,6 +50,9 @@
@ -48,19 +36,16 @@ index 64780d1b79..57ac63c10c 100644
static void vfio_disable_interrupts(VFIOPCIDevice *vdev); static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
static void vfio_msi_disable_common(VFIOPCIDevice *vdev); static void vfio_msi_disable_common(VFIOPCIDevice *vdev);
@@ -2946,13 +2949,36 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) @@ -2963,10 +2966,33 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
ERRP_GUARD(); ERRP_GUARD();
VFIOPCIDevice *vdev = VFIO_PCI(pdev); VFIOPCIDevice *vdev = VFIO_PCI(pdev);
VFIODevice *vbasedev = &vdev->vbasedev; VFIODevice *vbasedev = &vdev->vbasedev;
+ VFIODevice *vbasedev_iter;
+ VFIOGroup *group;
char *tmp, *subsys;
Error *err = NULL;
- int i, ret; - int i, ret;
+ int ret, i = 0; + int ret, i = 0;
bool is_mdev; + VFIODevice *vbasedev_iter;
+ VFIOGroup *group;
char uuid[UUID_STR_LEN]; char uuid[UUID_STR_LEN];
char *name; g_autofree char *name = NULL;
+ if (device_limit && device_limit != vdev->assigned_device_limit) { + if (device_limit && device_limit != vdev->assigned_device_limit) {
+ error_setg(errp, "Assigned device limit has been redefined. " + error_setg(errp, "Assigned device limit has been redefined. "
@ -86,7 +71,7 @@ index 64780d1b79..57ac63c10c 100644
if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
if (!(~vdev->host.domain || ~vdev->host.bus || if (!(~vdev->host.domain || ~vdev->host.bus ||
~vdev->host.slot || ~vdev->host.function)) { ~vdev->host.slot || ~vdev->host.function)) {
@@ -3370,6 +3396,9 @@ static Property vfio_pci_dev_properties[] = { @@ -3388,6 +3414,9 @@ static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false), DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice, DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
no_geforce_quirks, false), no_geforce_quirks, false),
@ -97,7 +82,7 @@ index 64780d1b79..57ac63c10c 100644
false), false),
DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd, DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 6e64a2654e..b7de39c010 100644 index bf67df2fbc..0d3c93fb2e 100644
--- a/hw/vfio/pci.h --- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h +++ b/hw/vfio/pci.h
@@ -142,6 +142,7 @@ struct VFIOPCIDevice { @@ -142,6 +142,7 @@ struct VFIOPCIDevice {

@ -1,17 +1,8 @@
From b467dc6a24ef41fa574260429807711f6802a54d Mon Sep 17 00:00:00 2001 From e46f7b696ec32b18969c9cd7c1553d7d30e489b3 Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com> From: Eduardo Habkost <ehabkost@redhat.com>
Date: Wed, 4 Dec 2013 18:53:17 +0100 Date: Wed, 4 Dec 2013 18:53:17 +0100
Subject: Add support statement to -help output Subject: Add support statement to -help output
RH-Author: Eduardo Habkost <ehabkost@redhat.com>
Message-id: <1386183197-27761-1-git-send-email-ehabkost@redhat.com>
Patchwork-id: 55994
O-Subject: [qemu-kvm RHEL7 PATCH] Add support statement to -help output
Bugzilla: 972773
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: knoel@redhat.com
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Add support statement to -help output, reporting direct qemu-kvm usage Add support statement to -help output, reporting direct qemu-kvm usage
as unsupported by Red Hat, and advising users to use libvirt instead. as unsupported by Red Hat, and advising users to use libvirt instead.
@ -21,10 +12,10 @@ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1 file changed, 9 insertions(+) 1 file changed, 9 insertions(+)
diff --git a/system/vl.c b/system/vl.c diff --git a/system/vl.c b/system/vl.c
index c644222982..03c3b0aa94 100644 index 01b8b8e77a..5359231bf5 100644
--- a/system/vl.c --- a/system/vl.c
+++ b/system/vl.c +++ b/system/vl.c
@@ -869,9 +869,17 @@ static void version(void) @@ -877,9 +877,17 @@ static void version(void)
QEMU_COPYRIGHT "\n"); QEMU_COPYRIGHT "\n");
} }
@ -42,7 +33,7 @@ index c644222982..03c3b0aa94 100644
printf("usage: %s [options] [disk_image]\n\n" printf("usage: %s [options] [disk_image]\n\n"
"'disk_image' is a raw hard disk image for IDE hard disk 0\n\n", "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
g_get_prgname()); g_get_prgname());
@@ -897,6 +905,7 @@ static void help(int exitcode) @@ -905,6 +913,7 @@ static void help(int exitcode)
"\n" "\n"
QEMU_HELP_BOTTOM "\n"); QEMU_HELP_BOTTOM "\n");

@ -1,30 +0,0 @@
From ba574acacf679850e337ec2d5e7836b8277cf393 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 18 Apr 2024 15:04:28 +0200
Subject: x86: rhel 9.4.0 machine type compat fix
Fix up the compatibility for 9.4.0. Ensure that pc-q35-rhel9.4.0
still uses SMBIOS 3.X by default.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/i386/pc_q35.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2b54944c0f..2f11f9af7d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -734,6 +734,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ /* From pc_q35_8_2_machine_options() - use SMBIOS 3.X by default */
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
+
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
}
--
2.39.3

@ -1,17 +1,8 @@
From 20cc3a6d9bce3e40d165f865b5e398c300cae7bf Mon Sep 17 00:00:00 2001 From 40274d161d20719709d92356077175f93795ea1e Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com> From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 8 Jul 2020 08:35:50 +0200 Date: Wed, 8 Jul 2020 08:35:50 +0200
Subject: Use qemu-kvm in documentation instead of qemu-system-<arch> Subject: Use qemu-kvm in documentation instead of qemu-system-<arch>
Patchwork-id: 62380
O-Subject: [RHEV-7.1 qemu-kvm-rhev PATCHv4] Use qemu-kvm in documentation instead of qemu-system-i386
Bugzilla: 1140620
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
From: Miroslav Rezanina <mrezanin@redhat.com>
We change the name and location of qemu-kvm binaries. Update documentation We change the name and location of qemu-kvm binaries. Update documentation
to reflect this change. Only architectures available in RHEL are updated. to reflect this change. Only architectures available in RHEL are updated.
@ -36,10 +27,10 @@ index 52d6454b93..d74dbdeca9 100644
.. |I2C| replace:: I\ :sup:`2`\ C .. |I2C| replace:: I\ :sup:`2`\ C
.. |I2S| replace:: I\ :sup:`2`\ S .. |I2S| replace:: I\ :sup:`2`\ S
diff --git a/qemu-options.hx b/qemu-options.hx diff --git a/qemu-options.hx b/qemu-options.hx
index 8ce85d4559..4fc27ee2e2 100644 index d94e2cbbae..a7444abc7f 100644
--- a/qemu-options.hx --- a/qemu-options.hx
+++ b/qemu-options.hx +++ b/qemu-options.hx
@@ -3493,11 +3493,11 @@ SRST @@ -3688,11 +3688,11 @@ SRST
:: ::

@ -1,19 +1,7 @@
From 2f9fdd21ecf2810d0d83a8125ce0cc1e75dbb13a Mon Sep 17 00:00:00 2001 From 728e3d8a124f4ec51c005ad6867270f3e60df16c Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com> From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 20 Aug 2021 18:25:12 +0200 Date: Fri, 20 Aug 2021 18:25:12 +0200
Subject: qcow2: Deprecation warning when opening v2 images rw Subject: qcow2: Deprecation warning when opening v2 images rw
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 37: qcow2: Deprecation warning when opening v2 images rw
RH-Commit: [1/1] f450d0ae32d35063b28c72c4f2d2ebb9e6d8db3e (kmwolf/centos-qemu-kvm)
RH-Bugzilla: 1951814
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Hanna Reitz <hreitz@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
qcow2 v3 has been around for a long time (since QEMU 1.1/RHEL 7), so qcow2 v3 has been around for a long time (since QEMU 1.1/RHEL 7), so
there is no real reason any more to use it. People still using it might there is no real reason any more to use it. People still using it might
@ -31,20 +19,13 @@ but it's what is available and the same function qcow2_do_open() already
uses it this way for another warning. uses it this way for another warning.
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
patch_name: kvm-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch
present_in_specfile: true
location_in_specfile: 116
---
Rebase notes (6.1.0):
- Replace bs->read_only with bdrv_is_read_only
--- ---
block/qcow2.c | 6 ++++++ block/qcow2.c | 6 ++++++
tests/qemu-iotests/common.filter | 1 + tests/qemu-iotests/common.filter | 1 +
2 files changed, 7 insertions(+) 2 files changed, 7 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c diff --git a/block/qcow2.c b/block/qcow2.c
index 956128b409..0e8b2f7518 100644 index 70b19730a3..a4cffb628c 100644
--- a/block/qcow2.c --- a/block/qcow2.c
+++ b/block/qcow2.c +++ b/block/qcow2.c
@@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, @@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
@ -61,7 +42,7 @@ index 956128b409..0e8b2f7518 100644
s->qcow_version = header.version; s->qcow_version = header.version;
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 2846c83808..83472953a2 100644 index fc3c64bcb8..4b238954d5 100644
--- a/tests/qemu-iotests/common.filter --- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter
@@ -83,6 +83,7 @@ _filter_qemu() @@ -83,6 +83,7 @@ _filter_qemu()

@ -0,0 +1,109 @@
From 03502faf7012e20fb7c4f1efee7e429ad3727fd1 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 15 May 2024 01:41:13 -0400
Subject: Add upstream compatibility bits
---
hw/arm/virt.c | 1 +
hw/core/machine.c | 17 +++++++++++++++++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/boards.h | 3 +++
6 files changed, 26 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 903c0f2e9f..3374d3b0bc 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3582,6 +3582,7 @@ DEFINE_VIRT_MACHINE(2, 6)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index f7fed78e4b..9cf8242b32 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -311,6 +311,23 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
const char *rhel_old_machine_deprecation =
"machine types for previous major releases are deprecated";
+GlobalProperty hw_compat_rhel_10_0[] = {
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"arm-cpu", "backcompat-cntfrq", "true" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "scsi-hd", "migrate-emulated-scsi-request", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "scsi-cd", "migrate-emulated-scsi-request", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"vfio-pci", "skip-vsc-check", "false" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ { "virtio-pci", "x-pcie-pm-no-soft-reset", "off" },
+ /* hw_compat_rhel_10_0 from hw_compat_9_0 */
+ {"sd-card", "spec_version", "2" },
+};
+const size_t hw_compat_rhel_10_0_len = G_N_ELEMENTS(hw_compat_rhel_10_0);
+
+
GlobalProperty hw_compat_rhel_9_5[] = {
/* hw_compat_rhel_9_5 from hw_compat_8_2 */
{ "migration", "zero-page-detection", "legacy"},
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5535e1ffbf..447f98b438 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -879,6 +879,8 @@ static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m)
object_class_property_set_description(oc, "x-south-bridge",
"Use a different south bridge than PIIX3");
+ compat_props_add(m->compat_props, hw_compat_rhel_10_0,
+ hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_4,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2ca9ff3747..849b231a74 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -680,6 +680,8 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ compat_props_add(m->compat_props, hw_compat_rhel_10_0,
+ hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 451017c50e..5db5fed1bf 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1316,6 +1316,7 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3dea5cee73..6d98aaf4c7 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -802,6 +802,9 @@ extern const size_t hw_compat_2_2_len;
extern GlobalProperty hw_compat_2_1[];
extern const size_t hw_compat_2_1_len;
+extern GlobalProperty hw_compat_rhel_10_0[];
+extern const size_t hw_compat_rhel_10_0_len;
+
extern GlobalProperty hw_compat_rhel_9_5[];
extern const size_t hw_compat_rhel_9_5_len;
--
2.39.3

@ -0,0 +1,37 @@
From d27437e5baba347cb3392280399d402414dcb21c Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:27:49 +0200
Subject: redhat: Add QEMU 9.1 compat handling to the s390x machine types
JIRA: https://issues.redhat.com/browse/RHEL-52319
Upstream changed the amount of information that is migrated for
the S390 interrupt controller (FLIC), so we have to switch on
a compatibility property for older machine types.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 5db5fed1bf..feef81ed8b 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1316,8 +1316,13 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ { TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", },
+ };
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
--
2.39.3

@ -0,0 +1,66 @@
From 926a9d0ca2437b4c4270062f707ed24284ad469f Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:42:24 +0200
Subject: redhat: Add rhel9.6.0 and rhel10.0.0 machine types
JIRA: https://issues.redhat.com/browse/RHEL-52319
Add a new machine types to enable the latest features by default.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index feef81ed8b..b61392bac1 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -1310,8 +1310,29 @@ DEFINE_CCW_MACHINE(2, 4);
#endif
#endif /* disabled for RHEL */
+static void ccw_rhel_machine_10_0_0_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_rhel_machine_10_0_0_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE_AS_LATEST(10, 0, 0);
+
+static void ccw_rhel_machine_9_6_0_instance_options(MachineState *machine)
+{
+ ccw_rhel_machine_10_0_0_instance_options(machine);
+}
+
+static void ccw_rhel_machine_9_6_0_class_options(MachineClass *mc)
+{
+ ccw_rhel_machine_10_0_0_class_options(mc);
+}
+DEFINE_CCW_MACHINE(9, 6, 0);
+
static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine)
{
+ ccw_rhel_machine_9_6_0_instance_options(machine);
}
static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
@@ -1320,11 +1341,13 @@ static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc)
{ TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", },
};
+ ccw_rhel_machine_9_6_0_class_options(mc);
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
-DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0);
+DEFINE_CCW_MACHINE(9, 4, 0);
static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine)
{
--
2.39.3

@ -0,0 +1,28 @@
From 6be70c681bf7a1b9666ed5896b5be8be7df2bf50 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Wed, 4 Sep 2024 15:46:53 +0200
Subject: x86: ensure compatibility of pc-q35-rhel9*
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/i386/pc_q35.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 849b231a74..a05df61cfc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -680,6 +680,10 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ /* From pc_q35_machine_9_0_options() */
+ pcmc->isa_bios_alias = false;
+ m->smbios_memory_device_size = 16 * GiB;
+
compat_props_add(m->compat_props, hw_compat_rhel_10_0,
hw_compat_rhel_10_0_len);
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
--
2.39.3

@ -0,0 +1,27 @@
From 17c3bccf2f2804772ab60bf4f04d7437f13ed48a Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Wed, 4 Sep 2024 15:52:00 +0200
Subject: arm: ensure compatibility of virt-rhel9*
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3374d3b0bc..31a71a7f45 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3582,6 +3582,9 @@ DEFINE_VIRT_MACHINE(2, 6)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ /* From virt_machine_9_0_options() */
+ mc->smbios_memory_device_size = 16 * GiB;
+
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
--
2.39.3

@ -1,139 +0,0 @@
From 93ea86ac8849ad9ca365b1646313dde9a34ba59c Mon Sep 17 00:00:00 2001
From: Xiaoyao Li <xiaoyao.li@intel.com>
Date: Wed, 20 Mar 2024 03:39:03 -0500
Subject: [PATCH 031/100] HostMem: Add mechanism to opt in kvm guest memfd via
MachineState
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [31/91] 43ce32aef954479cdb736301d1adcb919602c321 (bonzini/rhel-qemu-kvm)
Add a new member "guest_memfd" to memory backends. When it's set
to true, it enables RAM_GUEST_MEMFD in ram_flags, thus private kvm
guest_memfd will be allocated during RAMBlock allocation.
Memory backend's @guest_memfd is wired with @require_guest_memfd
field of MachineState. It avoid looking up the machine in phymem.c.
MachineState::require_guest_memfd is supposed to be set by any VMs
that requires KVM guest memfd as private memory, e.g., TDX VM.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20240320083945.991426-8-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 37662d85b0b7dded0ebdf6747bef6c3bb7ed6a0c)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
backends/hostmem-file.c | 1 +
backends/hostmem-memfd.c | 1 +
backends/hostmem-ram.c | 1 +
backends/hostmem.c | 1 +
hw/core/machine.c | 5 +++++
include/hw/boards.h | 2 ++
include/sysemu/hostmem.h | 1 +
7 files changed, 12 insertions(+)
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index ac3e433cbd..3c69db7946 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -85,6 +85,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
ram_flags |= RAM_NAMED_FILE;
return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 3923ea9364..745ead0034 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -55,6 +55,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
name = host_memory_backend_get_name(backend);
ram_flags = backend->share ? RAM_SHARED : 0;
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
backend->size, ram_flags, fd, 0, errp);
}
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index d121249f0f..f7d81af783 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -30,6 +30,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
name = host_memory_backend_get_name(backend);
ram_flags = backend->share ? RAM_SHARED : 0;
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
name, backend->size,
ram_flags, errp);
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 81a72ce40b..eb9682b4a8 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -277,6 +277,7 @@ static void host_memory_backend_init(Object *obj)
/* TODO: convert access to globals to compat properties */
backend->merge = machine_mem_merge(machine);
backend->dump = machine_dump_guest_core(machine);
+ backend->guest_memfd = machine_require_guest_memfd(machine);
backend->reserve = true;
backend->prealloc_threads = machine->smp.cpus;
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 92609aae27..07b994e136 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1480,6 +1480,11 @@ bool machine_mem_merge(MachineState *machine)
return machine->mem_merge;
}
+bool machine_require_guest_memfd(MachineState *machine)
+{
+ return machine->require_guest_memfd;
+}
+
static char *cpu_slot_to_string(const CPUArchId *cpu)
{
GString *s = g_string_new(NULL);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index cca62f906b..815a1c4b26 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -36,6 +36,7 @@ bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
bool machine_mem_merge(MachineState *machine);
+bool machine_require_guest_memfd(MachineState *machine);
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
void machine_set_cpu_numa_node(MachineState *machine,
const CpuInstanceProperties *props,
@@ -372,6 +373,7 @@ struct MachineState {
char *dt_compatible;
bool dump_guest_core;
bool mem_merge;
+ bool require_guest_memfd;
bool usb;
bool usb_disabled;
char *firmware;
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 0e411aaa29..04b884bf42 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -74,6 +74,7 @@ struct HostMemoryBackend {
uint64_t size;
bool merge, dump, use_canonical_path;
bool prealloc, is_mapped, share, reserve;
+ bool guest_memfd;
uint32_t prealloc_threads;
ThreadContext *prealloc_context;
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
--
2.39.3

@ -0,0 +1,50 @@
From 111d70a5bdc3ee0dde0a6def9e0c75ed20b4f093 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:33 -0400
Subject: [PATCH 6/9] KVM: Define KVM_MEMSLOTS_NUM_MAX_DEFAULT
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/7] e4c2a2c2f3a809c8efb709521c7a94ba0627c69b (peterx/qemu-kvm)
Make the default max nr_slots a macro, it's only used when KVM reports
nothing.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-3-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b34a908c8f24eedb0a8e5ff486b059b58fd793f4)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 38393bc86b..87db0f9494 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -71,6 +71,8 @@
/* Default num of memslots to be allocated when VM starts */
#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
+/* Default max allowed memslots if kernel reported nothing */
+#define KVM_MEMSLOTS_NR_MAX_DEFAULT 32
struct KVMParkedVcpu {
unsigned long vcpu_id;
@@ -2617,7 +2619,7 @@ static int kvm_init(MachineState *ms)
/* If unspecified, use the default value */
if (!s->nr_slots) {
- s->nr_slots = 32;
+ s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
}
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
--
2.39.3

@ -0,0 +1,251 @@
From c77a30265b8d0db43174b040ea82103f8fdb9911 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:32 -0400
Subject: [PATCH 5/9] KVM: Dynamic sized kvm memslots array
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [4/7] 46d4abec352a92112e593ea61b7cbf5ce5f94cdc (peterx/qemu-kvm)
Zhiyi reported an infinite loop issue in VFIO use case. The cause of that
was a separate discussion, however during that I found a regression of
dirty sync slowness when profiling.
Each KVMMemoryListerner maintains an array of kvm memslots. Currently it's
statically allocated to be the max supported by the kernel. However after
Linux commit 4fc096a99e ("KVM: Raise the maximum number of user memslots"),
the max supported memslots reported now grows to some number large enough
so that it may not be wise to always statically allocate with the max
reported.
What's worse, QEMU kvm code still walks all the allocated memslots entries
to do any form of lookups. It can drastically slow down all memslot
operations because each of such loop can run over 32K times on the new
kernels.
Fix this issue by making the memslots to be allocated dynamically.
Here the initial size was set to 16 because it should cover the basic VM
usages, so that the hope is the majority VM use case may not even need to
grow at all (e.g. if one starts a VM with ./qemu-system-x86_64 by default
it'll consume 9 memslots), however not too large to waste memory.
There can also be even better way to address this, but so far this is the
simplest and should be already better even than before we grow the max
supported memslots. For example, in the case of above issue when VFIO was
attached on a 32GB system, there are only ~10 memslots used. So it could
be good enough as of now.
In the above VFIO context, measurement shows that the precopy dirty sync
shrinked from ~86ms to ~3ms after this patch applied. It should also apply
to any KVM enabled VM even without VFIO.
NOTE: we don't have a FIXES tag for this patch because there's no real
commit that regressed this in QEMU. Such behavior existed for a long time,
but only start to be a problem when the kernel reports very large
nr_slots_max value. However that's pretty common now (the kernel change
was merged in 2021) so we attached cc:stable because we'll want this change
to be backported to stable branches.
Cc: qemu-stable <qemu-stable@nongnu.org>
Reported-by: Zhiyi Guo <zhguo@redhat.com>
Tested-by: Zhiyi Guo <zhguo@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20240917163835.194664-2-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5504a8126115d173687b37e657312a8ffe29fc0c)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 87 +++++++++++++++++++++++++++++++++-------
accel/kvm/trace-events | 1 +
include/sysemu/kvm_int.h | 1 +
3 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 8187ad3964..38393bc86b 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -69,6 +69,9 @@
#define KVM_GUESTDBG_BLOCKIRQ 0
#endif
+/* Default num of memslots to be allocated when VM starts */
+#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
+
struct KVMParkedVcpu {
unsigned long vcpu_id;
int kvm_fd;
@@ -165,6 +168,57 @@ void kvm_resample_fd_notify(int gsi)
}
}
+/**
+ * kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener
+ *
+ * @kml: The KVMMemoryListener* to grow the slots[] array
+ * @nr_slots_new: The new size of slots[] array
+ *
+ * Returns: True if the array grows larger, false otherwise.
+ */
+static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
+{
+ unsigned int i, cur = kml->nr_slots_allocated;
+ KVMSlot *slots;
+
+ if (nr_slots_new > kvm_state->nr_slots) {
+ nr_slots_new = kvm_state->nr_slots;
+ }
+
+ if (cur >= nr_slots_new) {
+ /* Big enough, no need to grow, or we reached max */
+ return false;
+ }
+
+ if (cur == 0) {
+ slots = g_new0(KVMSlot, nr_slots_new);
+ } else {
+ assert(kml->slots);
+ slots = g_renew(KVMSlot, kml->slots, nr_slots_new);
+ /*
+ * g_renew() doesn't initialize extended buffers, however kvm
+ * memslots require fields to be zero-initialized. E.g. pointers,
+ * memory_size field, etc.
+ */
+ memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur));
+ }
+
+ for (i = cur; i < nr_slots_new; i++) {
+ slots[i].slot = i;
+ }
+
+ kml->slots = slots;
+ kml->nr_slots_allocated = nr_slots_new;
+ trace_kvm_slots_grow(cur, nr_slots_new);
+
+ return true;
+}
+
+static bool kvm_slots_double(KVMMemoryListener *kml)
+{
+ return kvm_slots_grow(kml, kml->nr_slots_allocated * 2);
+}
+
unsigned int kvm_get_max_memslots(void)
{
KVMState *s = KVM_STATE(current_accel());
@@ -193,15 +247,26 @@ unsigned int kvm_get_free_memslots(void)
/* Called with KVMMemoryListener.slots_lock held */
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
{
- KVMState *s = kvm_state;
+ unsigned int n;
int i;
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
if (kml->slots[i].memory_size == 0) {
return &kml->slots[i];
}
}
+ /*
+ * If no free slots, try to grow first by doubling. Cache the old size
+ * here to avoid another round of search: if the grow succeeded, it
+ * means slots[] now must have the existing "n" slots occupied,
+ * followed by one or more free slots starting from slots[n].
+ */
+ n = kml->nr_slots_allocated;
+ if (kvm_slots_double(kml)) {
+ return &kml->slots[n];
+ }
+
return NULL;
}
@@ -222,10 +287,9 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml,
hwaddr start_addr,
hwaddr size)
{
- KVMState *s = kvm_state;
int i;
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
KVMSlot *mem = &kml->slots[i];
if (start_addr == mem->start_addr && size == mem->memory_size) {
@@ -267,7 +331,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
int i, ret = 0;
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
KVMSlot *mem = &kml->slots[i];
if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
@@ -1071,7 +1135,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
mem = &kml->slots[i];
/* Discard slots that are empty or do not overlap the section */
if (!mem->memory_size ||
@@ -1719,12 +1783,8 @@ static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
/* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
kvm_dirty_ring_flush();
- /*
- * TODO: make this faster when nr_slots is big while there are
- * only a few used slots (small VMs).
- */
kvm_slots_lock();
- for (i = 0; i < s->nr_slots; i++) {
+ for (i = 0; i < kml->nr_slots_allocated; i++) {
mem = &kml->slots[i];
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
kvm_slot_sync_dirty_pages(mem);
@@ -1839,12 +1899,9 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
{
int i;
- kml->slots = g_new0(KVMSlot, s->nr_slots);
kml->as_id = as_id;
- for (i = 0; i < s->nr_slots; i++) {
- kml->slots[i].slot = i;
- }
+ kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT);
QSIMPLEQ_INIT(&kml->transaction_add);
QSIMPLEQ_INIT(&kml->transaction_del);
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
index 37626c1ac5..ad2ae6fca5 100644
--- a/accel/kvm/trace-events
+++ b/accel/kvm/trace-events
@@ -36,3 +36,4 @@ kvm_io_window_exit(void) ""
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
+kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u"
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 1d8fb1473b..48e496b3d4 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -46,6 +46,7 @@ typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
unsigned int nr_used_slots;
+ unsigned int nr_slots_allocated;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
--
2.39.3

@ -0,0 +1,73 @@
From b1d082cfad79245ac0ffed45f723092388d1cf45 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:34 -0400
Subject: [PATCH 7/9] KVM: Rename KVMMemoryListener.nr_used_slots to
nr_slots_used
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [6/7] ed173123ee23edcf62a6c1940ca74cdfd6b545e9 (peterx/qemu-kvm)
This will make all nr_slots counters to be named in the same manner.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-4-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit dbdc00ba5b136bba80d850f61cc79a9cafaae1cd)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 6 +++---
include/sysemu/kvm_int.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 87db0f9494..e99aaba486 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -239,7 +239,7 @@ unsigned int kvm_get_free_memslots(void)
if (!s->as[i].ml) {
continue;
}
- used_slots = MAX(used_slots, s->as[i].ml->nr_used_slots);
+ used_slots = MAX(used_slots, s->as[i].ml->nr_slots_used);
}
kvm_slots_unlock();
@@ -1516,7 +1516,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
}
start_addr += slot_size;
size -= slot_size;
- kml->nr_used_slots--;
+ kml->nr_slots_used--;
} while (size);
return;
}
@@ -1555,7 +1555,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
ram_start_offset += slot_size;
ram += slot_size;
size -= slot_size;
- kml->nr_used_slots++;
+ kml->nr_slots_used++;
} while (size);
}
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 48e496b3d4..b705dfc9b4 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -45,7 +45,7 @@ typedef struct KVMMemoryUpdate {
typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
- unsigned int nr_used_slots;
+ unsigned int nr_slots_used;
unsigned int nr_slots_allocated;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
--
2.39.3

@ -0,0 +1,90 @@
From 891fb13363d168760cd21d0c57368e1a413cad27 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Tue, 17 Sep 2024 12:38:35 -0400
Subject: [PATCH 8/9] KVM: Rename KVMState->nr_slots to nr_slots_max
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/7] 7a1b28f04ee6a2c80b07db241fc88cb40f54e376 (peterx/qemu-kvm)
This value used to reflect the maximum supported memslots from KVM kernel.
Rename it to be clearer.
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/20240917163835.194664-5-peterx@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 943c742868c739c0b14fd996bad3adf744156fec)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 12 ++++++------
include/sysemu/kvm_int.h | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index e99aaba486..dc6253895d 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -183,8 +183,8 @@ static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
unsigned int i, cur = kml->nr_slots_allocated;
KVMSlot *slots;
- if (nr_slots_new > kvm_state->nr_slots) {
- nr_slots_new = kvm_state->nr_slots;
+ if (nr_slots_new > kvm_state->nr_slots_max) {
+ nr_slots_new = kvm_state->nr_slots_max;
}
if (cur >= nr_slots_new) {
@@ -225,7 +225,7 @@ unsigned int kvm_get_max_memslots(void)
{
KVMState *s = KVM_STATE(current_accel());
- return s->nr_slots;
+ return s->nr_slots_max;
}
unsigned int kvm_get_free_memslots(void)
@@ -243,7 +243,7 @@ unsigned int kvm_get_free_memslots(void)
}
kvm_slots_unlock();
- return s->nr_slots - used_slots;
+ return s->nr_slots_max - used_slots;
}
/* Called with KVMMemoryListener.slots_lock held */
@@ -2615,10 +2615,10 @@ static int kvm_init(MachineState *ms)
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
- s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
+ s->nr_slots_max = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
/* If unspecified, use the default value */
- if (!s->nr_slots) {
+ if (!s->nr_slots_max) {
s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
}
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index b705dfc9b4..2c57194b6b 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -103,8 +103,8 @@ struct KVMDirtyRingReaper {
struct KVMState
{
AccelState parent_obj;
-
- int nr_slots;
+ /* Max number of KVM slots supported */
+ int nr_slots_max;
int fd;
int vmfd;
int coalesced_mmio;
--
2.39.3

@ -1,203 +0,0 @@
From c46ac3db0a4db60e667edeabc9ed451c6e8e0ccf Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Mon, 18 Mar 2024 14:41:33 -0400
Subject: [PATCH 020/100] KVM: remove kvm_arch_cpu_check_are_resettable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [20/91] d7745bd1a0ed1b215847f150f4a1bb2e912beabc (bonzini/rhel-qemu-kvm)
Board reset requires writing a fresh CPU state. As far as KVM is
concerned, the only thing that blocks reset is that CPU state is
encrypted; therefore, kvm_cpus_are_resettable() can simply check
if that is the case.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a99c0c66ebe7d8db3af6f16689ade9375247e43e)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
accel/kvm/kvm-accel-ops.c | 2 +-
accel/kvm/kvm-all.c | 5 -----
include/sysemu/kvm.h | 10 ----------
target/arm/kvm.c | 5 -----
target/i386/kvm/kvm.c | 5 -----
target/loongarch/kvm/kvm.c | 5 -----
target/mips/kvm.c | 5 -----
target/ppc/kvm.c | 5 -----
target/riscv/kvm/kvm-cpu.c | 5 -----
target/s390x/kvm/kvm.c | 5 -----
10 files changed, 1 insertion(+), 51 deletions(-)
diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
index b3c946dc4b..74e3c5785b 100644
--- a/accel/kvm/kvm-accel-ops.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -82,7 +82,7 @@ static bool kvm_vcpu_thread_is_idle(CPUState *cpu)
static bool kvm_cpus_are_resettable(void)
{
- return !kvm_enabled() || kvm_cpu_check_are_resettable();
+ return !kvm_enabled() || !kvm_state->guest_state_protected;
}
#ifdef KVM_CAP_SET_GUEST_DEBUG
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ec0f6df7c5..b51e09a583 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2696,11 +2696,6 @@ void kvm_flush_coalesced_mmio_buffer(void)
s->coalesced_flush_in_progress = false;
}
-bool kvm_cpu_check_are_resettable(void)
-{
- return kvm_arch_cpu_check_are_resettable();
-}
-
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 302e8f6f1e..54f4d83a37 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -525,16 +525,6 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
/* Notify resamplefd for EOI of specific interrupts. */
void kvm_resample_fd_notify(int gsi);
-/**
- * kvm_cpu_check_are_resettable - return whether CPUs can be reset
- *
- * Returns: true: CPUs are resettable
- * false: CPUs are not resettable
- */
-bool kvm_cpu_check_are_resettable(void);
-
-bool kvm_arch_cpu_check_are_resettable(void);
-
bool kvm_dirty_ring_enabled(void);
uint32_t kvm_dirty_ring_size(void);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ab85d628a8..21ebbf3b8f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1598,11 +1598,6 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
return (data - 32) & 0xffff;
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
static void kvm_arch_get_eager_split_size(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index e271652620..a12207a8ee 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -5623,11 +5623,6 @@ bool kvm_has_waitpkg(void)
return has_msr_umwait;
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return !sev_es_enabled();
-}
-
#define ARCH_REQ_XCOMP_GUEST_PERM 0x1025
void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask)
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index d630cc39cb..8224d94333 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -733,11 +733,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
return true;
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
int ret = 0;
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index 6c52e59f55..a631ab544f 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -1273,11 +1273,6 @@ int kvm_arch_get_default_type(MachineState *machine)
return -1;
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
void kvm_arch_accel_class_init(ObjectClass *oc)
{
}
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 59f640cf7b..9d9d9f0d79 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2968,11 +2968,6 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset)
}
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
void kvm_arch_accel_class_init(ObjectClass *oc)
{
}
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 6a6c6cae80..49d2f3ad58 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1475,11 +1475,6 @@ void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
}
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
static int aia_mode;
static const char *kvm_aia_mode_str(uint64_t mode)
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 55fb4855b1..4db59658e1 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -2630,11 +2630,6 @@ void kvm_s390_stop_interrupt(S390CPU *cpu)
kvm_s390_vcpu_interrupt(cpu, &irq);
}
-bool kvm_arch_cpu_check_are_resettable(void)
-{
- return true;
-}
-
int kvm_s390_get_zpci_op(void)
{
return cap_zpci_op;
--
2.39.3

@ -1,127 +0,0 @@
From 50399796da938c4ea7c69058fde84695bce9d794 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Mon, 18 Mar 2024 14:41:10 -0400
Subject: [PATCH 019/100] KVM: track whether guest state is encrypted
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [19/91] 685b9c54d43d0043d15c33d13afc3a420cbe139b (bonzini/rhel-qemu-kvm)
So far, KVM has allowed KVM_GET/SET_* ioctls to execute even if the
guest state is encrypted, in which case they do nothing. For the new
API using VM types, instead, the ioctls will fail which is a safer and
more robust approach.
The new API will be the only one available for SEV-SNP and TDX, but it
is also usable for SEV and SEV-ES. In preparation for that, require
architecture-specific KVM code to communicate the point at which guest
state is protected (which must be after kvm_cpu_synchronize_post_init(),
though that might change in the future in order to suppor migration).
From that point, skip reading registers so that cpu->vcpu_dirty is
never true: if it ever becomes true, kvm_arch_put_registers() will
fail miserably.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5c3131c392f84c660033d511ec39872d8beb4b1e)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
accel/kvm/kvm-all.c | 17 ++++++++++++++---
include/sysemu/kvm.h | 2 ++
include/sysemu/kvm_int.h | 1 +
target/i386/sev.c | 1 +
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 931f74256e..ec0f6df7c5 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2703,7 +2703,7 @@ bool kvm_cpu_check_are_resettable(void)
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
- if (!cpu->vcpu_dirty) {
+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
int ret = kvm_arch_get_registers(cpu);
if (ret) {
error_report("Failed to get registers: %s", strerror(-ret));
@@ -2717,7 +2717,7 @@ static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
void kvm_cpu_synchronize_state(CPUState *cpu)
{
- if (!cpu->vcpu_dirty) {
+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
run_on_cpu(cpu, do_kvm_cpu_synchronize_state, RUN_ON_CPU_NULL);
}
}
@@ -2752,7 +2752,13 @@ static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
void kvm_cpu_synchronize_post_init(CPUState *cpu)
{
- run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+ if (!kvm_state->guest_state_protected) {
+ /*
+ * This runs before the machine_init_done notifiers, and is the last
+ * opportunity to synchronize the state of confidential guests.
+ */
+ run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
+ }
}
static void do_kvm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg)
@@ -4099,3 +4105,8 @@ void query_stats_schemas_cb(StatsSchemaList **result, Error **errp)
query_stats_schema_vcpu(first_cpu, &stats_args);
}
}
+
+void kvm_mark_guest_state_protected(void)
+{
+ kvm_state->guest_state_protected = true;
+}
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index fad9a7e8ff..302e8f6f1e 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -539,6 +539,8 @@ bool kvm_dirty_ring_enabled(void);
uint32_t kvm_dirty_ring_size(void);
+void kvm_mark_guest_state_protected(void);
+
/**
* kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page
* reported for the VM.
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 882e37e12c..3496be7997 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -87,6 +87,7 @@ struct KVMState
bool kernel_irqchip_required;
OnOffAuto kernel_irqchip_split;
bool sync_mmu;
+ bool guest_state_protected;
uint64_t manual_dirty_log_protect;
/* The man page (and posix) say ioctl numbers are signed int, but
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
diff --git a/target/i386/sev.c b/target/i386/sev.c
index b8f79d34d1..c49a8fd55e 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -755,6 +755,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
if (ret) {
exit(1);
}
+ kvm_mark_guest_state_protected();
}
/* query the measurement blob length */
--
2.39.3

@ -1,329 +0,0 @@
From f4b01d645926faab2cab86fadb7398c26d6b8285 Mon Sep 17 00:00:00 2001
From: Xiaoyao Li <xiaoyao.li@intel.com>
Date: Wed, 20 Mar 2024 03:39:02 -0500
Subject: [PATCH 028/100] RAMBlock: Add support of KVM private guest memfd
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [28/91] 95fdf196afcb67113834c20fa354ee1397411bfd (bonzini/rhel-qemu-kvm)
Add KVM guest_memfd support to RAMBlock so both normal hva based memory
and kvm guest memfd based private memory can be associated in one RAMBlock.
Introduce new flag RAM_GUEST_MEMFD. When it's set, it calls KVM ioctl to
create private guest_memfd during RAMBlock setup.
Allocating a new RAM_GUEST_MEMFD flag to instruct the setup of guest memfd
is more flexible and extensible than simply relying on the VM type because
in the future we may have the case that not all the memory of a VM need
guest memfd. As a benefit, it also avoid getting MachineState in memory
subsystem.
Note, RAM_GUEST_MEMFD is supposed to be set for memory backends of
confidential guests, such as TDX VM. How and when to set it for memory
backends will be implemented in the following patches.
Introduce memory_region_has_guest_memfd() to query if the MemoryRegion has
KVM guest_memfd allocated.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20240320083945.991426-7-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 15f7a80c49cb3637f62fa37fa4a17da913bd91ff)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
accel/kvm/kvm-all.c | 28 ++++++++++++++++++++++++++++
accel/stubs/kvm-stub.c | 5 +++++
include/exec/memory.h | 20 +++++++++++++++++---
include/exec/ram_addr.h | 2 +-
include/exec/ramblock.h | 1 +
include/sysemu/kvm.h | 2 ++
system/memory.c | 5 +++++
system/physmem.c | 34 +++++++++++++++++++++++++++++++---
8 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 272e945f52..a7b9a127dd 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -92,6 +92,7 @@ static bool kvm_has_guest_debug;
static int kvm_sstep_flags;
static bool kvm_immediate_exit;
static uint64_t kvm_supported_memory_attributes;
+static bool kvm_guest_memfd_supported;
static hwaddr kvm_max_slot_size = ~0;
static const KVMCapabilityInfo kvm_required_capabilites[] = {
@@ -2419,6 +2420,11 @@ static int kvm_init(MachineState *ms)
}
kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
+ kvm_guest_memfd_supported =
+ kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
+ kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
+ (kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
+
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
@@ -4138,3 +4144,25 @@ void kvm_mark_guest_state_protected(void)
{
kvm_state->guest_state_protected = true;
}
+
+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
+{
+ int fd;
+ struct kvm_create_guest_memfd guest_memfd = {
+ .size = size,
+ .flags = flags,
+ };
+
+ if (!kvm_guest_memfd_supported) {
+ error_setg(errp, "KVM does not support guest_memfd");
+ return -1;
+ }
+
+ fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_GUEST_MEMFD, &guest_memfd);
+ if (fd < 0) {
+ error_setg_errno(errp, errno, "Error creating KVM guest_memfd");
+ return -1;
+ }
+
+ return fd;
+}
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index ca38172884..8e0eb22e61 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -129,3 +129,8 @@ bool kvm_hwpoisoned_mem(void)
{
return false;
}
+
+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
+{
+ return -ENOSYS;
+}
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 8626a355b3..679a847685 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -243,6 +243,9 @@ typedef struct IOMMUTLBEvent {
/* RAM FD is opened read-only */
#define RAM_READONLY_FD (1 << 11)
+/* RAM can be private that has kvm guest memfd backend */
+#define RAM_GUEST_MEMFD (1 << 12)
+
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
IOMMUNotifierFlag flags,
hwaddr start, hwaddr end,
@@ -1307,7 +1310,8 @@ bool memory_region_init_ram_nomigrate(MemoryRegion *mr,
* @name: Region name, becomes part of RAMBlock name used in migration stream
* must be unique within any device
* @size: size of the region.
- * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE.
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE,
+ * RAM_GUEST_MEMFD.
* @errp: pointer to Error*, to store an error if it happens.
*
* Note that this function does not do anything to cause the data in the
@@ -1369,7 +1373,7 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
* (getpagesize()) will be used.
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- * RAM_READONLY_FD
+ * RAM_READONLY_FD, RAM_GUEST_MEMFD
* @path: the path in which to allocate the RAM.
* @offset: offset within the file referenced by path
* @errp: pointer to Error*, to store an error if it happens.
@@ -1399,7 +1403,7 @@ bool memory_region_init_ram_from_file(MemoryRegion *mr,
* @size: size of the region.
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- * RAM_READONLY_FD
+ * RAM_READONLY_FD, RAM_GUEST_MEMFD
* @fd: the fd to mmap.
* @offset: offset within the file referenced by fd
* @errp: pointer to Error*, to store an error if it happens.
@@ -1722,6 +1726,16 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
*/
bool memory_region_is_protected(MemoryRegion *mr);
+/**
+ * memory_region_has_guest_memfd: check whether a memory region has guest_memfd
+ * associated
+ *
+ * Returns %true if a memory region's ram_block has valid guest_memfd assigned.
+ *
+ * @mr: the memory region being queried
+ */
+bool memory_region_has_guest_memfd(MemoryRegion *mr);
+
/**
* memory_region_get_iommu: check whether a memory region is an iommu
*
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index de45ba7bc9..07c8f86375 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -110,7 +110,7 @@ long qemu_maxrampagesize(void);
* @mr: the memory region where the ram block is
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- * RAM_READONLY_FD
+ * RAM_READONLY_FD, RAM_GUEST_MEMFD
* @mem_path or @fd: specify the backing file or device
* @offset: Offset into target file
* @errp: pointer to Error*, to store an error if it happens
diff --git a/include/exec/ramblock.h b/include/exec/ramblock.h
index 848915ea5b..459c8917de 100644
--- a/include/exec/ramblock.h
+++ b/include/exec/ramblock.h
@@ -41,6 +41,7 @@ struct RAMBlock {
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
int fd;
uint64_t fd_offset;
+ int guest_memfd;
size_t page_size;
/* dirty bitmap used during migration */
unsigned long *bmap;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index f114ff6986..9e4ab7ae89 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -537,6 +537,8 @@ void kvm_mark_guest_state_protected(void);
*/
bool kvm_hwpoisoned_mem(void);
+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp);
+
int kvm_set_memory_attributes_private(hwaddr start, uint64_t size);
int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size);
diff --git a/system/memory.c b/system/memory.c
index a229a79988..c756950c0c 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1850,6 +1850,11 @@ bool memory_region_is_protected(MemoryRegion *mr)
return mr->ram && (mr->ram_block->flags & RAM_PROTECTED);
}
+bool memory_region_has_guest_memfd(MemoryRegion *mr)
+{
+ return mr->ram_block && mr->ram_block->guest_memfd >= 0;
+}
+
uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
{
uint8_t mask = mr->dirty_log_mask;
diff --git a/system/physmem.c b/system/physmem.c
index a4fe3d2bf8..f5dfa20e57 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -1808,6 +1808,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
const bool shared = qemu_ram_is_shared(new_block);
RAMBlock *block;
RAMBlock *last_block = NULL;
+ bool free_on_error = false;
ram_addr_t old_ram_size, new_ram_size;
Error *err = NULL;
@@ -1837,6 +1838,19 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
return;
}
memory_try_enable_merging(new_block->host, new_block->max_length);
+ free_on_error = true;
+ }
+ }
+
+ if (new_block->flags & RAM_GUEST_MEMFD) {
+ assert(kvm_enabled());
+ assert(new_block->guest_memfd < 0);
+
+ new_block->guest_memfd = kvm_create_guest_memfd(new_block->max_length,
+ 0, errp);
+ if (new_block->guest_memfd < 0) {
+ qemu_mutex_unlock_ramlist();
+ goto out_free;
}
}
@@ -1888,6 +1902,13 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
ram_block_notify_add(new_block->host, new_block->used_length,
new_block->max_length);
}
+ return;
+
+out_free:
+ if (free_on_error) {
+ qemu_anon_ram_free(new_block->host, new_block->max_length);
+ new_block->host = NULL;
+ }
}
#ifdef CONFIG_POSIX
@@ -1902,7 +1923,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
/* Just support these ram flags by now. */
assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_NORESERVE |
RAM_PROTECTED | RAM_NAMED_FILE | RAM_READONLY |
- RAM_READONLY_FD)) == 0);
+ RAM_READONLY_FD | RAM_GUEST_MEMFD)) == 0);
if (xen_enabled()) {
error_setg(errp, "-mem-path not supported with Xen");
@@ -1939,6 +1960,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
new_block->used_length = size;
new_block->max_length = size;
new_block->flags = ram_flags;
+ new_block->guest_memfd = -1;
new_block->host = file_ram_alloc(new_block, size, fd, !file_size, offset,
errp);
if (!new_block->host) {
@@ -2018,7 +2040,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
int align;
assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC |
- RAM_NORESERVE)) == 0);
+ RAM_NORESERVE | RAM_GUEST_MEMFD)) == 0);
assert(!host ^ (ram_flags & RAM_PREALLOC));
align = qemu_real_host_page_size();
@@ -2033,6 +2055,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
new_block->max_length = max_size;
assert(max_size >= size);
new_block->fd = -1;
+ new_block->guest_memfd = -1;
new_block->page_size = qemu_real_host_page_size();
new_block->host = host;
new_block->flags = ram_flags;
@@ -2055,7 +2078,7 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags,
MemoryRegion *mr, Error **errp)
{
- assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE)) == 0);
+ assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE | RAM_GUEST_MEMFD)) == 0);
return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, errp);
}
@@ -2083,6 +2106,11 @@ static void reclaim_ramblock(RAMBlock *block)
} else {
qemu_anon_ram_free(block->host, block->max_length);
}
+
+ if (block->guest_memfd >= 0) {
+ close(block->guest_memfd);
+ }
+
g_free(block);
}
--
2.39.3

@ -1,82 +0,0 @@
From bd289293604d6f33e9fb89196f0b19117ce81f89 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 20 Mar 2024 17:45:29 +0100
Subject: [PATCH 032/100] RAMBlock: make guest_memfd require uncoordinated
discard
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [32/91] 0c005849026c334737b88cbd20a0ac237dfca37e (bonzini/rhel-qemu-kvm)
Some subsystems like VFIO might disable ram block discard, but guest_memfd
uses discard operations to implement conversions between private and
shared memory. Because of this, sequences like the following can result
in stale IOMMU mappings:
1. allocate shared page
2. convert page shared->private
3. discard shared page
4. convert page private->shared
5. allocate shared page
6. issue DMA operations against that shared page
This is not a use-after-free, because after step 3 VFIO is still pinning
the page. However, DMA operations in step 6 will hit the old mapping
that was allocated in step 1.
Address this by taking ram_block_discard_is_enabled() into account when
deciding whether or not to discard pages.
Since kvm_convert_memory()/guest_memfd doesn't implement a
RamDiscardManager handler to convey and replay discard operations,
this is a case of uncoordinated discard, which is blocked/released
by ram_block_discard_require(). Interestingly, this function had
no use so far.
Alternative approaches would be to block discard of shared pages, but
this would cause guests to consume twice the memory if they use VFIO;
or to implement a RamDiscardManager and only block uncoordinated
discard, i.e. use ram_block_coordinated_discard_require().
[Commit message mostly by Michael Roth <michael.roth@amd.com>]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 852f0048f3ea9f14de18eb279a99fccb6d250e8f)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
system/physmem.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/system/physmem.c b/system/physmem.c
index f5dfa20e57..5ebcf5be11 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -1846,6 +1846,13 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
assert(kvm_enabled());
assert(new_block->guest_memfd < 0);
+ if (ram_block_discard_require(true) < 0) {
+ error_setg_errno(errp, errno,
+ "cannot set up private guest memory: discard currently blocked");
+ error_append_hint(errp, "Are you using assigned devices?\n");
+ goto out_free;
+ }
+
new_block->guest_memfd = kvm_create_guest_memfd(new_block->max_length,
0, errp);
if (new_block->guest_memfd < 0) {
@@ -2109,6 +2116,7 @@ static void reclaim_ramblock(RAMBlock *block)
if (block->guest_memfd >= 0) {
close(block->guest_memfd);
+ ram_block_discard_require(false);
}
g_free(block);
--
2.39.3

@ -0,0 +1,76 @@
From 5110e137294163ae43a61376485a7f610bf496f3 Mon Sep 17 00:00:00 2001
From: Shaoqin Huang <shahuang@redhat.com>
Date: Wed, 22 May 2024 03:23:28 -0400
Subject: [PATCH 8/9] RH-Author: Shaoqin Huang <shahuang@redhat.com >
RH-MergeRequest: 271: hw/arm/virt: Fix Manufacturer and Product Name in
emulated SMBIOS mode RH-Jira: RHEL-38374 RH-Acked-by: Cornelia Huck
<cohuck@redhat.com> RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com> RH-Commit: [8/8]
d1daacc6ed427094cf92a9ecc66af8171950c718 (shahuang/qemu-kvm)
---
hw/arm/virt.c | 15 +++++++++++++--
include/hw/arm/virt.h | 1 +
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 907c26c635..078098ec3a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1711,14 +1711,21 @@ static void virt_build_smbios(VirtMachineState *vms)
uint8_t *smbios_tables, *smbios_anchor;
size_t smbios_tables_len, smbios_anchor_len;
struct smbios_phys_mem_area mem_array;
+ const char *manufacturer = "QEMU";
const char *product = "QEMU Virtual Machine";
+ const char *version = vmc->smbios_old_sys_ver ? "1.0" : mc->name;
if (kvm_enabled()) {
product = "KVM Virtual Machine";
}
- smbios_set_defaults("QEMU", product,
- vmc->smbios_old_sys_ver ? "1.0" : mc->name,
+ if (!vmc->manufacturer_product_compat) {
+ manufacturer = "Red Hat";
+ product = "KVM";
+ version = mc->desc;
+ }
+
+ smbios_set_defaults(manufacturer, product, version,
NULL, NULL);
/* build the array of physical mem area from base_memmap */
@@ -3593,6 +3600,8 @@ DEFINE_VIRT_MACHINE(9, 6, 0)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
virt_rhel_machine_9_6_0_options(mc);
/* From virt_machine_9_0_options() */
@@ -3600,6 +3609,8 @@ static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
+
+ vmc->manufacturer_product_compat = true;
}
DEFINE_VIRT_MACHINE(9, 4, 0)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index a4d937ed45..2fc30a7626 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -134,6 +134,7 @@ struct VirtMachineClass {
bool no_cpu_topology;
bool no_tcg_lpa2;
bool no_ns_el2_virt_timer_irq;
+ bool manufacturer_product_compat;
};
struct VirtMachineState {
--
2.39.3

@ -1,67 +0,0 @@
From d4e6f7105b00ba2536d5d733b7c03116f28ce116 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 6 May 2024 15:06:21 -0400
Subject: [PATCH 2/5] Revert "monitor: use aio_co_reschedule_self()"
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 248: Revert "monitor: use aio_co_reschedule_self()"
RH-Jira: RHEL-34618 RHEL-38697
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/2] b6a2ebd4a69dbcd2bd56c61e7c747f8f8f42337e (kmwolf/centos-qemu-kvm)
Commit 1f25c172f837 ("monitor: use aio_co_reschedule_self()") was a code
cleanup that uses aio_co_reschedule_self() instead of open coding
coroutine rescheduling.
Bug RHEL-34618 was reported and Kevin Wolf <kwolf@redhat.com> identified
the root cause. I missed that aio_co_reschedule_self() ->
qemu_get_current_aio_context() only knows about
qemu_aio_context/IOThread AioContexts and not about iohandler_ctx. It
does not function correctly when going back from the iohandler_ctx to
qemu_aio_context.
Go back to open coding the AioContext transitions to avoid this bug.
This reverts commit 1f25c172f83704e350c0829438d832384084a74d.
Cc: qemu-stable@nongnu.org
Buglink: https://issues.redhat.com/browse/RHEL-34618
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240506190622.56095-2-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 719c6819ed9a9838520fa732f9861918dc693bda)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/qmp-dispatch.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index f3488afeef..176b549473 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -212,7 +212,8 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ
* executing the command handler so that it can make progress if it
* involves an AIO_WAIT_WHILE().
*/
- aio_co_reschedule_self(qemu_get_aio_context());
+ aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self());
+ qemu_coroutine_yield();
}
monitor_set_cur(qemu_coroutine_self(), cur_mon);
@@ -226,7 +227,9 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ
* Move back to iohandler_ctx so that nested event loops for
* qemu_aio_context don't start new monitor commands.
*/
- aio_co_reschedule_self(iohandler_get_aio_context());
+ aio_co_schedule(iohandler_get_aio_context(),
+ qemu_coroutine_self());
+ qemu_coroutine_yield();
}
} else {
/*
--
2.39.3

@ -1,38 +0,0 @@
From bcbc897cb19b3a6523de611f48f6bac6cea16c97 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 2 May 2024 13:17:03 +0200
Subject: [PATCH 2/2] Revert "x86: rhel 9.4.0 machine type compat fix"
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 237: Revert "x86: rhel 9.4.0 machine type compat fix"
RH-Jira: RHEL-30362
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 858ec153e65e96c39ca4db17ed93fd58c77dc2eb (seott1/cos-qemu-kvm)
This reverts commit c46e44f0f4e861fe412ce679b0b0204881c1c2f5.
pc-q35-rhel9.4.0 and newer should stay with SMBIOS_ENTRY_POINT_TYPE_AUTO.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/i386/pc_q35.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2f11f9af7d..2b54944c0f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -734,9 +734,6 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
- /* From pc_q35_8_2_machine_options() - use SMBIOS 3.X by default */
- pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
-
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
hw_compat_rhel_9_5_len);
}
--
2.39.3

@ -0,0 +1,56 @@
From 2b4558ec338adde1b9735128bb8d2f81db303a93 Mon Sep 17 00:00:00 2001
From: Avadhut Naik <avnaik@redhat.com>
Date: Wed, 23 Oct 2024 12:25:28 -0500
Subject: [PATCH 01/38] accel/kvm: check for KVM_CAP_READONLY_MEM on VM
RH-Author: avnaik1 <None>
RH-MergeRequest: 276: accel/kvm: check for KVM_CAP_READONLY_MEM on VM
RH-Jira: RHEL-58928
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [1/1] 1d392a9e47e68bb71dc44635c494d161585a885c (avnaik1/avnaik-qemu-kvm-fork)
JIRA: https://issues.redhat.com/browse/RHEL-58928
commit 64e0e63ea16aa0122dc0c41a0679da0ae4616208
Author: Tom Dohrmann <erbse.13@gmx.de>
Date: Tue Sep 3 06:29:53 2024 +0000
accel/kvm: check for KVM_CAP_READONLY_MEM on VM
KVM_CAP_READONLY_MEM used to be a global capability, but with the
introduction of AMD SEV-SNP confidential VMs, this extension is not
always available on all VM types [1,2].
Query the extension on the VM level instead of on the KVM level.
[1] https://patchwork.kernel.org/project/kvm/patch/20240809190319.1710470-2-seanjc@google.com/
[2] https://patchwork.kernel.org/project/kvm/patch/20240902144219.3716974-1-erbse.13@gmx.de/
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Tom Dohrmann <erbse.13@gmx.de>
Link: https://lore.kernel.org/r/20240903062953.3926498-1-erbse.13@gmx.de
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Avadhut Naik <avnaik@redhat.com>
---
accel/kvm/kvm-all.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 75d11a07b2..acc23092e7 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2603,7 +2603,7 @@ static int kvm_init(MachineState *ms)
}
kvm_readonly_mem_allowed =
- (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
+ (kvm_vm_check_extension(s, KVM_CAP_READONLY_MEM) > 0);
kvm_resamplefds_allowed =
(kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0);
--
2.39.3

@ -0,0 +1,144 @@
From 00a2dbf483a077bb31b1c9f70cced36319d22628 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Thu, 12 Sep 2024 11:48:38 +0530
Subject: [PATCH 4/9] accel/kvm: refactor dirty ring setup
RH-Author: Peter Xu <peterx@redhat.com>
RH-MergeRequest: 285: KVM: Dynamic sized kvm memslots array
RH-Jira: RHEL-57685
RH-Acked-by: Juraj Marcin <None>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [3/7] 94f345d1e7ad6437dd2ce67ca7cad224c67aa48f (peterx/qemu-kvm)
Refactor setting up of dirty ring code in kvm_init() so that is can be
reused in the future patchsets.
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/20240912061838.4501-1-anisinha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 28ed7f9761eb273e7dedcfdc0507d158106d0451)
Signed-off-by: Peter Xu <peterx@redhat.com>
---
accel/kvm/kvm-all.c | 88 +++++++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 38 deletions(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index d86d1b515a..8187ad3964 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2439,6 +2439,55 @@ static int find_kvm_machine_type(MachineState *ms)
return type;
}
+static int kvm_setup_dirty_ring(KVMState *s)
+{
+ uint64_t dirty_log_manual_caps;
+ int ret;
+
+ /*
+ * Enable KVM dirty ring if supported, otherwise fall back to
+ * dirty logging mode
+ */
+ ret = kvm_dirty_ring_init(s);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /*
+ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
+ * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
+ * page is wr-protected initially, which is against how kvm dirty ring is
+ * usage - kvm dirty ring requires all pages are wr-protected at the very
+ * beginning. Enabling this feature for dirty ring causes data corruption.
+ *
+ * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
+ * we may expect a higher stall time when starting the migration. In the
+ * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
+ * instead of clearing dirty bit, it can be a way to explicitly wr-protect
+ * guest pages.
+ */
+ if (!s->kvm_dirty_ring_size) {
+ dirty_log_manual_caps =
+ kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
+ dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
+ KVM_DIRTY_LOG_INITIALLY_SET);
+ s->manual_dirty_log_protect = dirty_log_manual_caps;
+ if (dirty_log_manual_caps) {
+ ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
+ dirty_log_manual_caps);
+ if (ret) {
+ warn_report("Trying to enable capability %"PRIu64" of "
+ "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
+ "Falling back to the legacy mode. ",
+ dirty_log_manual_caps);
+ s->manual_dirty_log_protect = 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -2458,7 +2507,6 @@ static int kvm_init(MachineState *ms)
const KVMCapabilityInfo *missing_cap;
int ret;
int type;
- uint64_t dirty_log_manual_caps;
qemu_mutex_init(&kml_slots_lock);
@@ -2570,47 +2618,11 @@ static int kvm_init(MachineState *ms)
s->coalesced_pio = s->coalesced_mmio &&
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
- /*
- * Enable KVM dirty ring if supported, otherwise fall back to
- * dirty logging mode
- */
- ret = kvm_dirty_ring_init(s);
+ ret = kvm_setup_dirty_ring(s);
if (ret < 0) {
goto err;
}
- /*
- * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
- * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
- * page is wr-protected initially, which is against how kvm dirty ring is
- * usage - kvm dirty ring requires all pages are wr-protected at the very
- * beginning. Enabling this feature for dirty ring causes data corruption.
- *
- * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log,
- * we may expect a higher stall time when starting the migration. In the
- * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too:
- * instead of clearing dirty bit, it can be a way to explicitly wr-protect
- * guest pages.
- */
- if (!s->kvm_dirty_ring_size) {
- dirty_log_manual_caps =
- kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
- dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
- KVM_DIRTY_LOG_INITIALLY_SET);
- s->manual_dirty_log_protect = dirty_log_manual_caps;
- if (dirty_log_manual_caps) {
- ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
- dirty_log_manual_caps);
- if (ret) {
- warn_report("Trying to enable capability %"PRIu64" of "
- "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
- "Falling back to the legacy mode. ",
- dirty_log_manual_caps);
- s->manual_dirty_log_protect = 0;
- }
- }
- }
-
#ifdef KVM_CAP_VCPU_EVENTS
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
#endif
--
2.39.3

@ -1,64 +0,0 @@
From 0e3934e89ad1dda21681f64ff38da69b07d1b531 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 6 May 2024 15:06:22 -0400
Subject: [PATCH 3/5] aio: warn about iohandler_ctx special casing
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 248: Revert "monitor: use aio_co_reschedule_self()"
RH-Jira: RHEL-34618 RHEL-38697
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/2] cc316d70b2c187ee0412d6560ca1a03e381a69c1 (kmwolf/centos-qemu-kvm)
The main loop has two AioContexts: qemu_aio_context and iohandler_ctx.
The main loop runs them both, but nested aio_poll() calls on
qemu_aio_context exclude iohandler_ctx.
Which one should qemu_get_current_aio_context() return when called from
the main loop? Document that it's always qemu_aio_context.
This has subtle effects on functions that use
qemu_get_current_aio_context(). For example, aio_co_reschedule_self()
does not work when moving from iohandler_ctx to qemu_aio_context because
qemu_get_current_aio_context() does not differentiate these two
AioContexts.
Document this in order to reduce the chance of future bugs.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240506190622.56095-3-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e669e800fc9ef8806af5c5578249ab758a4f8a5a)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/aio.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/block/aio.h b/include/block/aio.h
index 8378553eb9..4ee81936ed 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -629,6 +629,9 @@ void aio_co_schedule(AioContext *ctx, Coroutine *co);
*
* Move the currently running coroutine to new_ctx. If the coroutine is already
* running in new_ctx, do nothing.
+ *
+ * Note that this function cannot reschedule from iohandler_ctx to
+ * qemu_aio_context.
*/
void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx);
@@ -661,6 +664,9 @@ void aio_co_enter(AioContext *ctx, Coroutine *co);
* If called from an IOThread this will be the IOThread's AioContext. If
* called from the main thread or with the "big QEMU lock" taken it
* will be the main loop AioContext.
+ *
+ * Note that the return value is never the main loop's iohandler_ctx and the
+ * return value is the main loop AioContext instead.
*/
AioContext *qemu_get_current_aio_context(void);
--
2.39.3

@ -0,0 +1,49 @@
From 60d59db99f0527eaf0ce8d3a18d8333aa77a03f2 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 5 Sep 2024 13:53:13 +0200
Subject: [PATCH 2/9] arm: create new virt machine type for rhel 9.6
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 270: RHEL10 machine types
RH-Jira: RHEL-29002 RHEL-29003 RHEL-35587 RHEL-38411 RHEL-45141 RHEL-52318 RHEL-52320
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [2/7] 0179f5a7a177f53b58ff9b82bd09217e183f258b (seott1/cos-qemu-kvm)
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 31a71a7f45..f94be8656c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3580,15 +3580,22 @@ static void virt_machine_2_6_options(MachineClass *mc)
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0)
+
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
+ virt_rhel_machine_9_6_0_options(mc);
+
/* From virt_machine_9_0_options() */
mc->smbios_memory_device_size = 16 * GiB;
compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len);
compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0)
+DEFINE_VIRT_MACHINE(9, 4, 0)
static void virt_rhel_machine_9_2_0_options(MachineClass *mc)
{
--
2.39.3

@ -0,0 +1,45 @@
From 704596b05f7dcdfa98857b71fed295d0005d4acc Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 22 Aug 2024 17:08:26 +0200
Subject: [PATCH 5/9] arm: create virt machine type for rhel10
RH-Author: Sebastian Ott <sebott@redhat.com>
RH-MergeRequest: 270: RHEL10 machine types
RH-Jira: RHEL-29002 RHEL-29003 RHEL-35587 RHEL-38411 RHEL-45141 RHEL-52318 RHEL-52320
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Commit: [5/7] cd8f31de4cd189cd1de69e68c84d823e43473e8c (seott1/cos-qemu-kvm)
Create a new default virt machine type for rhel 10.
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f94be8656c..907c26c635 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3580,10 +3580,16 @@ static void virt_machine_2_6_options(MachineClass *mc)
DEFINE_VIRT_MACHINE(2, 6)
#endif /* disabled for RHEL */
+static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(10, 0, 0)
+
static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
{
+ virt_rhel_machine_10_0_0_options(mc);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0)
+DEFINE_VIRT_MACHINE(9, 6, 0)
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
{
--
2.39.3

@ -1,252 +0,0 @@
From 2ee645a339e9ef9cd92620a8b784d18d512326be Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:56:02 +0200
Subject: [PATCH 4/4] block: Parse filenames only when explicitly requested
RH-Author: Hana Czenczek <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-35611
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [4/4] f44c2941d4419e60f16dea3e9adca164e75aa78d
When handling image filenames from legacy options such as -drive or from
tools, these filenames are parsed for protocol prefixes, including for
the json:{} pseudo-protocol.
This behaviour is intended for filenames that come directly from the
command line and for backing files, which may come from the image file
itself. Higher level management tools generally take care to verify that
untrusted images don't contain a bad (or any) backing file reference;
'qemu-img info' is a suitable tool for this.
However, for other files that can be referenced in images, such as
qcow2 data files or VMDK extents, the string from the image file is
usually not verified by management tools - and 'qemu-img info' wouldn't
be suitable because in contrast to backing files, it already opens these
other referenced files. So here the string should be interpreted as a
literal local filename. More complex configurations need to be specified
explicitly on the command line or in QMP.
This patch changes bdrv_open_inherit() so that it only parses filenames
if a new parameter parse_filename is true. It is set for the top level
in bdrv_open(), for the file child and for the backing file child. All
other callers pass false and disable filename parsing this way.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
block.c | 90 ++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 57 insertions(+), 33 deletions(-)
diff --git a/block.c b/block.c
index 468cf5e67d..50bdd197b7 100644
--- a/block.c
+++ b/block.c
@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
+ bool parse_filename,
Error **errp);
static bool bdrv_recurse_has_child(BlockDriverState *bs,
@@ -2058,7 +2059,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
* block driver has been specified explicitly.
*/
static int bdrv_fill_options(QDict **options, const char *filename,
- int *flags, Error **errp)
+ int *flags, bool allow_parse_filename,
+ Error **errp)
{
const char *drvname;
bool protocol = *flags & BDRV_O_PROTOCOL;
@@ -2100,7 +2102,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put_str(*options, "filename", filename);
- parse_filename = true;
+ parse_filename = allow_parse_filename;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
"the same time");
@@ -3663,7 +3665,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
- &child_of_bds, bdrv_backing_role(bs), errp);
+ &child_of_bds, bdrv_backing_role(bs), true,
+ errp);
if (!backing_hd) {
bs->open_flags |= BDRV_O_NO_BACKING;
error_prepend(errp, "Could not open backing file: ");
@@ -3697,7 +3700,8 @@ free_exit:
static BlockDriverState *
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
BlockDriverState *parent, const BdrvChildClass *child_class,
- BdrvChildRole child_role, bool allow_none, Error **errp)
+ BdrvChildRole child_role, bool allow_none,
+ bool parse_filename, Error **errp)
{
BlockDriverState *bs = NULL;
QDict *image_options;
@@ -3728,7 +3732,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
}
bs = bdrv_open_inherit(filename, reference, image_options, 0,
- parent, child_class, child_role, errp);
+ parent, child_class, child_role, parse_filename,
+ errp);
if (!bs) {
goto done;
}
@@ -3738,6 +3743,33 @@ done:
return bs;
}
+static BdrvChild *bdrv_open_child_common(const char *filename,
+ QDict *options, const char *bdref_key,
+ BlockDriverState *parent,
+ const BdrvChildClass *child_class,
+ BdrvChildRole child_role,
+ bool allow_none, bool parse_filename,
+ Error **errp)
+{
+ BlockDriverState *bs;
+ BdrvChild *child;
+
+ GLOBAL_STATE_CODE();
+
+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
+ child_role, allow_none, parse_filename, errp);
+ if (bs == NULL) {
+ return NULL;
+ }
+
+ bdrv_graph_wrlock();
+ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
+ errp);
+ bdrv_graph_wrunlock();
+
+ return child;
+}
+
/*
* Opens a disk image whose options are given as BlockdevRef in another block
* device's options.
@@ -3761,27 +3793,15 @@ BdrvChild *bdrv_open_child(const char *filename,
BdrvChildRole child_role,
bool allow_none, Error **errp)
{
- BlockDriverState *bs;
- BdrvChild *child;
-
- GLOBAL_STATE_CODE();
-
- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
- child_role, allow_none, errp);
- if (bs == NULL) {
- return NULL;
- }
-
- bdrv_graph_wrlock();
- child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
- errp);
- bdrv_graph_wrunlock();
-
- return child;
+ return bdrv_open_child_common(filename, options, bdref_key, parent,
+ child_class, child_role, allow_none, false,
+ errp);
}
/*
- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
+ * This does mostly the same as bdrv_open_child(), but for opening the primary
+ * child of a node. A notable difference from bdrv_open_child() is that it
+ * enables filename parsing for protocol names (including json:).
*
* @parent can move to a different AioContext in this function.
*/
@@ -3796,8 +3816,8 @@ int bdrv_open_file_child(const char *filename,
role = parent->drv->is_filter ?
(BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
- if (!bdrv_open_child(filename, options, bdref_key, parent,
- &child_of_bds, role, false, errp))
+ if (!bdrv_open_child_common(filename, options, bdref_key, parent,
+ &child_of_bds, role, false, true, errp))
{
return -EINVAL;
}
@@ -3842,7 +3862,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
}
- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
+ errp);
obj = NULL;
qobject_unref(obj);
visit_free(v);
@@ -3932,7 +3953,7 @@ static BlockDriverState * no_coroutine_fn
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
int flags, BlockDriverState *parent,
const BdrvChildClass *child_class, BdrvChildRole child_role,
- Error **errp)
+ bool parse_filename, Error **errp)
{
int ret;
BlockBackend *file = NULL;
@@ -3980,9 +4001,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
}
/* json: syntax counts as explicit options, as if in the QDict */
- parse_json_protocol(options, &filename, &local_err);
- if (local_err) {
- goto fail;
+ if (parse_filename) {
+ parse_json_protocol(options, &filename, &local_err);
+ if (local_err) {
+ goto fail;
+ }
}
bs->explicit_options = qdict_clone_shallow(options);
@@ -4007,7 +4030,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
parent->open_flags, parent->options);
}
- ret = bdrv_fill_options(&options, filename, &flags, &local_err);
+ ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
+ &local_err);
if (ret < 0) {
goto fail;
}
@@ -4076,7 +4100,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
&child_of_bds, BDRV_CHILD_IMAGE,
- true, &local_err);
+ true, true, &local_err);
if (local_err) {
goto fail;
}
@@ -4225,7 +4249,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
GLOBAL_STATE_CODE();
return bdrv_open_inherit(filename, reference, options, flags, NULL,
- NULL, 0, errp);
+ NULL, 0, true, errp);
}
/* Return true if the NULL-terminated @list contains @str */
--
2.39.3

@ -1,330 +0,0 @@
From a67edfb4b591acdffc5b4987601a30224376996f Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 27 May 2024 11:58:50 -0400
Subject: [PATCH 4/5] block/crypto: create ciphers on demand
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 251: block/crypto: create ciphers on demand
RH-Jira: RHEL-36159
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/2] 22a4c87fef774cad98a6f5a79f27df50a208013d (stefanha/centos-stream-qemu-kvm)
Ciphers are pre-allocated by qcrypto_block_init_cipher() depending on
the given number of threads. The -device
virtio-blk-pci,iothread-vq-mapping= feature allows users to assign
multiple IOThreads to a virtio-blk device, but the association between
the virtio-blk device and the block driver happens after the block
driver is already open.
When the number of threads given to qcrypto_block_init_cipher() is
smaller than the actual number of threads at runtime, the
block->n_free_ciphers > 0 assertion in qcrypto_block_pop_cipher() can
fail.
Get rid of qcrypto_block_init_cipher() n_thread's argument and allocate
ciphers on demand.
Reported-by: Qing Wang <qinwang@redhat.com>
Buglink: https://issues.redhat.com/browse/RHEL-36159
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240527155851.892885-2-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit af206c284e4c1b17cdfb0f17e898b288c0fc1751)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
crypto/block-luks.c | 3 +-
crypto/block-qcow.c | 2 +-
crypto/block.c | 111 ++++++++++++++++++++++++++------------------
crypto/blockpriv.h | 12 +++--
4 files changed, 78 insertions(+), 50 deletions(-)
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 3ee928fb5a..3357852c0a 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1262,7 +1262,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
luks->cipher_mode,
masterkey,
luks->header.master_key_len,
- n_threads,
errp) < 0) {
goto fail;
}
@@ -1456,7 +1455,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
/* Setup the block device payload encryption objects */
if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg,
luks_opts.cipher_mode, masterkey,
- luks->header.master_key_len, 1, errp) < 0) {
+ luks->header.master_key_len, errp) < 0) {
goto error;
}
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
index 4d7cf36a8f..02305058e3 100644
--- a/crypto/block-qcow.c
+++ b/crypto/block-qcow.c
@@ -75,7 +75,7 @@ qcrypto_block_qcow_init(QCryptoBlock *block,
ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128,
QCRYPTO_CIPHER_MODE_CBC,
keybuf, G_N_ELEMENTS(keybuf),
- n_threads, errp);
+ errp);
if (ret < 0) {
ret = -ENOTSUP;
goto fail;
diff --git a/crypto/block.c b/crypto/block.c
index 506ea1d1a3..ba6d1cebc7 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qemu/lockable.h"
#include "blockpriv.h"
#include "block-qcow.h"
#include "block-luks.h"
@@ -57,6 +58,8 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
{
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
+ qemu_mutex_init(&block->mutex);
+
block->format = options->format;
if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
@@ -76,8 +79,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
return NULL;
}
- qemu_mutex_init(&block->mutex);
-
return block;
}
@@ -92,6 +93,8 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
{
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
+ qemu_mutex_init(&block->mutex);
+
block->format = options->format;
if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
@@ -111,8 +114,6 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
return NULL;
}
- qemu_mutex_init(&block->mutex);
-
return block;
}
@@ -227,37 +228,42 @@ QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block)
* This function is used only in test with one thread (it's safe to skip
* pop/push interface), so it's enough to assert it here:
*/
- assert(block->n_ciphers <= 1);
- return block->ciphers ? block->ciphers[0] : NULL;
+ assert(block->max_free_ciphers <= 1);
+ return block->free_ciphers ? block->free_ciphers[0] : NULL;
}
-static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block)
+static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block,
+ Error **errp)
{
- QCryptoCipher *cipher;
-
- qemu_mutex_lock(&block->mutex);
-
- assert(block->n_free_ciphers > 0);
- block->n_free_ciphers--;
- cipher = block->ciphers[block->n_free_ciphers];
-
- qemu_mutex_unlock(&block->mutex);
+ /* Usually there is a free cipher available */
+ WITH_QEMU_LOCK_GUARD(&block->mutex) {
+ if (block->n_free_ciphers > 0) {
+ block->n_free_ciphers--;
+ return block->free_ciphers[block->n_free_ciphers];
+ }
+ }
- return cipher;
+ /* Otherwise allocate a new cipher */
+ return qcrypto_cipher_new(block->alg, block->mode, block->key,
+ block->nkey, errp);
}
static void qcrypto_block_push_cipher(QCryptoBlock *block,
QCryptoCipher *cipher)
{
- qemu_mutex_lock(&block->mutex);
+ QEMU_LOCK_GUARD(&block->mutex);
- assert(block->n_free_ciphers < block->n_ciphers);
- block->ciphers[block->n_free_ciphers] = cipher;
- block->n_free_ciphers++;
+ if (block->n_free_ciphers == block->max_free_ciphers) {
+ block->max_free_ciphers++;
+ block->free_ciphers = g_renew(QCryptoCipher *,
+ block->free_ciphers,
+ block->max_free_ciphers);
+ }
- qemu_mutex_unlock(&block->mutex);
+ block->free_ciphers[block->n_free_ciphers] = cipher;
+ block->n_free_ciphers++;
}
@@ -265,24 +271,31 @@ int qcrypto_block_init_cipher(QCryptoBlock *block,
QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
- size_t n_threads, Error **errp)
+ Error **errp)
{
- size_t i;
+ QCryptoCipher *cipher;
- assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers);
+ assert(!block->free_ciphers && !block->max_free_ciphers &&
+ !block->n_free_ciphers);
- block->ciphers = g_new0(QCryptoCipher *, n_threads);
+ /* Stash away cipher parameters for qcrypto_block_pop_cipher() */
+ block->alg = alg;
+ block->mode = mode;
+ block->key = g_memdup2(key, nkey);
+ block->nkey = nkey;
- for (i = 0; i < n_threads; i++) {
- block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp);
- if (!block->ciphers[i]) {
- qcrypto_block_free_cipher(block);
- return -1;
- }
- block->n_ciphers++;
- block->n_free_ciphers++;
+ /*
+ * Create a new cipher to validate the parameters now. This reduces the
+ * chance of cipher creation failing at I/O time.
+ */
+ cipher = qcrypto_block_pop_cipher(block, errp);
+ if (!cipher) {
+ g_free(block->key);
+ block->key = NULL;
+ return -1;
}
+ qcrypto_block_push_cipher(block, cipher);
return 0;
}
@@ -291,19 +304,23 @@ void qcrypto_block_free_cipher(QCryptoBlock *block)
{
size_t i;
- if (!block->ciphers) {
+ g_free(block->key);
+ block->key = NULL;
+
+ if (!block->free_ciphers) {
return;
}
- assert(block->n_ciphers == block->n_free_ciphers);
+ /* All popped ciphers were eventually pushed back */
+ assert(block->n_free_ciphers == block->max_free_ciphers);
- for (i = 0; i < block->n_ciphers; i++) {
- qcrypto_cipher_free(block->ciphers[i]);
+ for (i = 0; i < block->max_free_ciphers; i++) {
+ qcrypto_cipher_free(block->free_ciphers[i]);
}
- g_free(block->ciphers);
- block->ciphers = NULL;
- block->n_ciphers = block->n_free_ciphers = 0;
+ g_free(block->free_ciphers);
+ block->free_ciphers = NULL;
+ block->max_free_ciphers = block->n_free_ciphers = 0;
}
QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block)
@@ -311,7 +328,7 @@ QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block)
/* ivgen should be accessed under mutex. However, this function is used only
* in test with one thread, so it's enough to assert it here:
*/
- assert(block->n_ciphers <= 1);
+ assert(block->max_free_ciphers <= 1);
return block->ivgen;
}
@@ -446,7 +463,10 @@ int qcrypto_block_decrypt_helper(QCryptoBlock *block,
Error **errp)
{
int ret;
- QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);
+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block, errp);
+ if (!cipher) {
+ return -1;
+ }
ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
&block->mutex, sectorsize, offset, buf,
@@ -465,7 +485,10 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block,
Error **errp)
{
int ret;
- QCryptoCipher *cipher = qcrypto_block_pop_cipher(block);
+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block, errp);
+ if (!cipher) {
+ return -1;
+ }
ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen,
&block->mutex, sectorsize, offset, buf,
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
index 836f3b4726..4bf6043d5d 100644
--- a/crypto/blockpriv.h
+++ b/crypto/blockpriv.h
@@ -32,8 +32,14 @@ struct QCryptoBlock {
const QCryptoBlockDriver *driver;
void *opaque;
- QCryptoCipher **ciphers;
- size_t n_ciphers;
+ /* Cipher parameters */
+ QCryptoCipherAlgorithm alg;
+ QCryptoCipherMode mode;
+ uint8_t *key;
+ size_t nkey;
+
+ QCryptoCipher **free_ciphers;
+ size_t max_free_ciphers;
size_t n_free_ciphers;
QCryptoIVGen *ivgen;
QemuMutex mutex;
@@ -130,7 +136,7 @@ int qcrypto_block_init_cipher(QCryptoBlock *block,
QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
- size_t n_threads, Error **errp);
+ Error **errp);
void qcrypto_block_free_cipher(QCryptoBlock *block);
--
2.39.3

@ -1,90 +0,0 @@
From 0f0a3a860a07addea21a0282556a5022b9cb8b2c Mon Sep 17 00:00:00 2001
From: Xiaoyao Li <xiaoyao.li@intel.com>
Date: Thu, 29 Feb 2024 01:00:35 -0500
Subject: [PATCH 011/100] confidential guest support: Add kvm_init() and
kvm_reset() in class
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [11/91] 21d2178178bf181a8e4d0b051f64bd983f0d0cf1 (bonzini/rhel-qemu-kvm)
Different confidential VMs in different architectures all have the same
needs to do their specific initialization (and maybe resetting) stuffs
with KVM. Currently each of them exposes individual *_kvm_init()
functions and let machine code or kvm code to call it.
To facilitate the introduction of confidential guest technology from
different x86 vendors, add two virtual functions, kvm_init() and kvm_reset()
in ConfidentialGuestSupportClass, and expose two helpers functions for
invodking them.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-Id: <20240229060038.606591-1-xiaoyao.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 41a605944e3fecae43ca18ded95ec31f28e0c7fe)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/exec/confidential-guest-support.h | 34 ++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h
index ba2dd4b5df..e5b188cffb 100644
--- a/include/exec/confidential-guest-support.h
+++ b/include/exec/confidential-guest-support.h
@@ -23,7 +23,10 @@
#include "qom/object.h"
#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
-OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT)
+OBJECT_DECLARE_TYPE(ConfidentialGuestSupport,
+ ConfidentialGuestSupportClass,
+ CONFIDENTIAL_GUEST_SUPPORT)
+
struct ConfidentialGuestSupport {
Object parent;
@@ -55,8 +58,37 @@ struct ConfidentialGuestSupport {
typedef struct ConfidentialGuestSupportClass {
ObjectClass parent;
+
+ int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
+ int (*kvm_reset)(ConfidentialGuestSupport *cgs, Error **errp);
} ConfidentialGuestSupportClass;
+static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs,
+ Error **errp)
+{
+ ConfidentialGuestSupportClass *klass;
+
+ klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
+ if (klass->kvm_init) {
+ return klass->kvm_init(cgs, errp);
+ }
+
+ return 0;
+}
+
+static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs,
+ Error **errp)
+{
+ ConfidentialGuestSupportClass *klass;
+
+ klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
+ if (klass->kvm_reset) {
+ return klass->kvm_reset(cgs, errp);
+ }
+
+ return 0;
+}
+
#endif /* !CONFIG_USER_ONLY */
#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */
--
2.39.3

@ -1,228 +0,0 @@
From 117486e0820f135f191e19f8ebb8838a98b121c6 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 27 May 2024 11:58:51 -0400
Subject: [PATCH 5/5] crypto/block: drop qcrypto_block_open() n_threads
argument
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
RH-MergeRequest: 251: block/crypto: create ciphers on demand
RH-Jira: RHEL-36159
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/2] 68290935b174b1f2b76aa857a926da9011e54abe (stefanha/centos-stream-qemu-kvm)
The n_threads argument is no longer used since the previous commit.
Remove it.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240527155851.892885-3-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 3ab0f063e58ed9224237d69c4211ca83335164c4)
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/crypto.c | 1 -
block/qcow.c | 2 +-
block/qcow2.c | 5 ++---
crypto/block-luks.c | 1 -
crypto/block-qcow.c | 6 ++----
crypto/block.c | 3 +--
crypto/blockpriv.h | 1 -
include/crypto/block.h | 2 --
tests/unit/test-crypto-block.c | 4 ----
9 files changed, 6 insertions(+), 19 deletions(-)
diff --git a/block/crypto.c b/block/crypto.c
index 21eed909c1..4eed3ffa6a 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -363,7 +363,6 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
block_crypto_read_func,
bs,
cflags,
- 1,
errp);
if (!crypto->block) {
diff --git a/block/qcow.c b/block/qcow.c
index ca8e1d5ec8..c2f89db055 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -211,7 +211,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
s->crypto = qcrypto_block_open(crypto_opts, "encrypt.",
- NULL, NULL, cflags, 1, errp);
+ NULL, NULL, cflags, errp);
if (!s->crypto) {
ret = -EINVAL;
goto fail;
diff --git a/block/qcow2.c b/block/qcow2.c
index 0e8b2f7518..0ebd455dc8 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -321,7 +321,7 @@ qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
qcow2_crypto_hdr_read_func,
- bs, cflags, QCOW2_MAX_THREADS, errp);
+ bs, cflags, errp);
if (!s->crypto) {
return -EINVAL;
}
@@ -1707,8 +1707,7 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
- NULL, NULL, cflags,
- QCOW2_MAX_THREADS, errp);
+ NULL, NULL, cflags, errp);
if (!s->crypto) {
ret = -EINVAL;
goto fail;
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 3357852c0a..5b777c15d3 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -1189,7 +1189,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
- size_t n_threads,
Error **errp)
{
QCryptoBlockLUKS *luks = NULL;
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
index 02305058e3..42e9556e42 100644
--- a/crypto/block-qcow.c
+++ b/crypto/block-qcow.c
@@ -44,7 +44,6 @@ qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED,
static int
qcrypto_block_qcow_init(QCryptoBlock *block,
const char *keysecret,
- size_t n_threads,
Error **errp)
{
char *password;
@@ -100,7 +99,6 @@ qcrypto_block_qcow_open(QCryptoBlock *block,
QCryptoBlockReadFunc readfunc G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED,
unsigned int flags,
- size_t n_threads,
Error **errp)
{
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
@@ -115,7 +113,7 @@ qcrypto_block_qcow_open(QCryptoBlock *block,
return -1;
}
return qcrypto_block_qcow_init(block, options->u.qcow.key_secret,
- n_threads, errp);
+ errp);
}
}
@@ -135,7 +133,7 @@ qcrypto_block_qcow_create(QCryptoBlock *block,
return -1;
}
/* QCow2 has no special header, since everything is hardwired */
- return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, errp);
+ return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp);
}
diff --git a/crypto/block.c b/crypto/block.c
index ba6d1cebc7..3bcc4270c3 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -53,7 +53,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
- size_t n_threads,
Error **errp)
{
QCryptoBlock *block = g_new0(QCryptoBlock, 1);
@@ -73,7 +72,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
block->driver = qcrypto_block_drivers[options->format];
if (block->driver->open(block, options, optprefix,
- readfunc, opaque, flags, n_threads, errp) < 0)
+ readfunc, opaque, flags, errp) < 0)
{
g_free(block);
return NULL;
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
index 4bf6043d5d..b8f77cb5eb 100644
--- a/crypto/blockpriv.h
+++ b/crypto/blockpriv.h
@@ -59,7 +59,6 @@ struct QCryptoBlockDriver {
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
- size_t n_threads,
Error **errp);
int (*create)(QCryptoBlock *block,
diff --git a/include/crypto/block.h b/include/crypto/block.h
index 92e823c9f2..5b5d039800 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -76,7 +76,6 @@ typedef enum {
* @readfunc: callback for reading data from the volume
* @opaque: data to pass to @readfunc
* @flags: bitmask of QCryptoBlockOpenFlags values
- * @n_threads: allow concurrent I/O from up to @n_threads threads
* @errp: pointer to a NULL-initialized error object
*
* Create a new block encryption object for an existing
@@ -113,7 +112,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
QCryptoBlockReadFunc readfunc,
void *opaque,
unsigned int flags,
- size_t n_threads,
Error **errp);
typedef enum {
diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c
index 6cfc817a92..42cfab6067 100644
--- a/tests/unit/test-crypto-block.c
+++ b/tests/unit/test-crypto-block.c
@@ -303,7 +303,6 @@ static void test_block(gconstpointer opaque)
test_block_read_func,
&header,
0,
- 1,
NULL);
g_assert(blk == NULL);
@@ -312,7 +311,6 @@ static void test_block(gconstpointer opaque)
test_block_read_func,
&header,
QCRYPTO_BLOCK_OPEN_NO_IO,
- 1,
&error_abort);
g_assert(qcrypto_block_get_cipher(blk) == NULL);
@@ -327,7 +325,6 @@ static void test_block(gconstpointer opaque)
test_block_read_func,
&header,
0,
- 1,
&error_abort);
g_assert(blk);
@@ -384,7 +381,6 @@ test_luks_bad_header(gconstpointer data)
test_block_read_func,
&buf,
0,
- 1,
&err);
g_assert(!blk);
g_assert(err);
--
2.39.3

@ -0,0 +1,76 @@
From f1359f43bbc61f31c292ca1770688b6db6b959af Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:52 -0400
Subject: [PATCH 20/38] docs/system: Update documentation for s390x IPL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [19/23] 8dfc0357ec42e9baac741670f6e7da3127de0e50 (thuth/qemu-kvm-cs9)
Update docs to show that s390x PC BIOS can support more than one boot device.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-19-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0bd107138ff0b171e3cd314dbc200950bcab2b05)
---
docs/system/bootindex.rst | 7 ++++---
docs/system/s390x/bootdevices.rst | 9 ++++++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst
index 8b057f812f..988f7b3beb 100644
--- a/docs/system/bootindex.rst
+++ b/docs/system/bootindex.rst
@@ -49,10 +49,11 @@ Limitations
-----------
Some firmware has limitations on which devices can be considered for
-booting. For instance, the PC BIOS boot specification allows only one
-disk to be bootable. If boot from disk fails for some reason, the BIOS
+booting. For instance, the x86 PC BIOS boot specification allows only one
+disk to be bootable. If boot from disk fails for some reason, the x86 BIOS
won't retry booting from other disk. It can still try to boot from
-floppy or net, though.
+floppy or net, though. In the case of s390x BIOS, the BIOS will try up to
+8 total devices, any number of which may be disks.
Sometimes, firmware cannot map the device path QEMU wants firmware to
boot from to a boot method. It doesn't happen for devices the firmware
diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst
index c97efb8fc0..1a1a764c1c 100644
--- a/docs/system/s390x/bootdevices.rst
+++ b/docs/system/s390x/bootdevices.rst
@@ -6,9 +6,7 @@ Booting with bootindex parameter
For classical mainframe guests (i.e. LPAR or z/VM installations), you always
have to explicitly specify the disk where you want to boot from (or "IPL" from,
-in s390x-speak -- IPL means "Initial Program Load"). In particular, there can
-also be only one boot device according to the architecture specification, thus
-specifying multiple boot devices is not possible (yet).
+in s390x-speak -- IPL means "Initial Program Load").
So for booting an s390x guest in QEMU, you should always mark the
device where you want to boot from with the ``bootindex`` property, for
@@ -17,6 +15,11 @@ example::
qemu-system-s390x -drive if=none,id=dr1,file=guest.qcow2 \
-device virtio-blk,drive=dr1,bootindex=1
+Multiple devices may have a bootindex. The lowest bootindex is assigned to the
+device to IPL first. If the IPL fails for the first, the device with the second
+lowest bootindex will be tried and so on until IPL is successful or there are no
+remaining boot devices to try.
+
For booting from a CD-ROM ISO image (which needs to include El-Torito boot
information in order to be bootable), it is recommended to specify a ``scsi-cd``
device, for example like this::
--
2.39.3

@ -0,0 +1,66 @@
From c8e615cf130743ee95a61d7e21bb4b753eb082fb Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:40 -0400
Subject: [PATCH 08/38] docs/system/s390x/bootdevices: Update the documentation
about network booting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [7/23] 52d357df45400b983e17cc6b1eeac691131bf5e5 (thuth/qemu-kvm-cs9)
Remove the information about the separate s390-netboot.img from
the documentation.
Co-authored by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Message-ID: <20241020012953.1380075-7-jrossi@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit ab2691b6c7ff360875e0af86ff463278f17786f5)
---
docs/system/s390x/bootdevices.rst | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst
index 1a7a18b43b..c97efb8fc0 100644
--- a/docs/system/s390x/bootdevices.rst
+++ b/docs/system/s390x/bootdevices.rst
@@ -82,23 +82,17 @@ Note that ``0`` can be used to boot the default entry.
Booting from a network device
-----------------------------
-Beside the normal guest firmware (which is loaded from the file ``s390-ccw.img``
-in the data directory of QEMU, or via the ``-bios`` option), QEMU ships with
-a small TFTP network bootloader firmware for virtio-net-ccw devices, too. This
-firmware is loaded from a file called ``s390-netboot.img`` in the QEMU data
-directory. In case you want to load it from a different filename instead,
-you can specify it via the ``-global s390-ipl.netboot_fw=filename``
-command line option.
-
-The ``bootindex`` property is especially important for booting via the network.
-If you don't specify the ``bootindex`` property here, the network bootloader
-firmware code won't get loaded into the guest memory so that the network boot
-will fail. For a successful network boot, try something like this::
+The firmware that ships with QEMU includes a small TFTP network bootloader
+for virtio-net-ccw devices. The ``bootindex`` property is especially
+important for booting via the network. If you don't specify the ``bootindex``
+property here, the network bootloader won't be taken into consideration and
+the network boot will fail. For a successful network boot, try something
+like this::
qemu-system-s390x -netdev user,id=n1,tftp=...,bootfile=... \
-device virtio-net-ccw,netdev=n1,bootindex=1
-The network bootloader firmware also has basic support for pxelinux.cfg-style
+The network bootloader also has basic support for pxelinux.cfg-style
configuration files. See the `PXELINUX Configuration page
<https://wiki.syslinux.org/wiki/index.php?title=PXELINUX#Configuration>`__
for details how to set up the configuration file on your TFTP server.
--
2.39.3

@ -0,0 +1,61 @@
From d0163127a47250170e01e39f48250a2725f531c0 Mon Sep 17 00:00:00 2001
From: Gavin Shan <gshan@redhat.com>
Date: Tue, 1 Oct 2024 16:58:57 +1000
Subject: [PATCH] hostmem: Apply merge property after the memory region is
initialized
RH-Author: Gavin Shan <gshan@redhat.com>
RH-MergeRequest: 272: hostmem: Apply merge property after the memory region is initialized
RH-Jira: RHEL-58936
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
RH-Acked-by: David Hildenbrand <david@redhat.com>
RH-Commit: [1/1] aa47bedf64698b277bb8835f4689d4f1d5eca53c (gwshan/qemu-centos)
JIRA: https://issues.redhat.com/browse/RHEL-58936
The semantic change has been introduced by commit 5becdc0ab0 ("hostmem:
simplify the code for merge and dump properties") even it clarifies that
no senmatic change has been introduced. After the commit, the merge
property can be applied even the corresponding memory region isn't
initialized yet. This leads to crash dump by the following command
lines.
# /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
-accel kvm -machine virt -cpu host \
-object memory-backend-ram,id=mem-memN0,size=4096M,merge=off
:
qemu-system-aarch64: ../system/memory.c:2419: memory_region_get_ram_ptr: \
Assertion `mr->ram_block' failed.
Fix it by applying the merge property only when the memory region is
initialized.
Message-ID: <20240915233117.478169-1-gshan@redhat.com>
Fixes: 5becdc0ab083 ("hostmem: simplify the code for merge and dump properties")
Reported-by: Zhenyu Zhang <zhenyzha@redhat.com>
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit 78c8f780d3f0d6d17aa93d6f99ff72960080fdd7)
Signed-off-by: Gavin Shan <gshan@redhat.com>
---
backends/hostmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 4e5576a4ad..181446626a 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -178,7 +178,7 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
return;
}
- if (!host_memory_backend_mr_inited(backend) &&
+ if (host_memory_backend_mr_inited(backend) &&
value != backend->merge) {
void *ptr = memory_region_get_ram_ptr(&backend->mr);
uint64_t sz = memory_region_size(&backend->mr);
--
2.39.3

@ -1,120 +0,0 @@
From 41c4083269ec772b406c6c57b496ca2011f928c7 Mon Sep 17 00:00:00 2001
From: Zhenyu Zhang <zhenyzha@redhat.com>
Date: Tue, 9 Jul 2024 23:08:59 -0400
Subject: [PATCH 2/2] hw/arm/virt: Avoid unexpected warning from Linux guest on
host with Fujitsu CPUs
RH-Author: zhenyzha <None>
RH-MergeRequest: 256: hw/arm/virt: Avoid unexpected warning from Linux guest on host with Fujitsu CPUs
RH-Jira: RHEL-39936
RH-Acked-by: Gavin Shan <gshan@redhat.com>
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Commit: [1/1] fdf156fd05b219a06e2e2ca409fff0f728c1e2cf (zhenyzha/qemu-kvm)
JIRA: https://issues.redhat.com/browse/RHEL-39936
Multiple warning messages and corresponding backtraces are observed when Linux
guest is booted on the host with Fujitsu CPUs. One of them is shown as below.
[ 0.032443] ------------[ cut here ]------------
[ 0.032446] uart-pl011 9000000.pl011: ARCH_DMA_MINALIGN smaller than
CTR_EL0.CWG (128 < 256)
[ 0.032454] WARNING: CPU: 0 PID: 1 at arch/arm64/mm/dma-mapping.c:54
arch_setup_dma_ops+0xbc/0xcc
[ 0.032470] Modules linked in:
[ 0.032475] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-452.el9.aarch64
[ 0.032481] Hardware name: linux,dummy-virt (DT)
[ 0.032484] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.032490] pc : arch_setup_dma_ops+0xbc/0xcc
[ 0.032496] lr : arch_setup_dma_ops+0xbc/0xcc
[ 0.032501] sp : ffff80008003b860
[ 0.032503] x29: ffff80008003b860 x28: 0000000000000000 x27: ffffaae4b949049c
[ 0.032510] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
[ 0.032517] x23: 0000000000000100 x22: 0000000000000000 x21: 0000000000000000
[ 0.032523] x20: 0000000100000000 x19: ffff2f06c02ea400 x18: ffffffffffffffff
[ 0.032529] x17: 00000000208a5f76 x16: 000000006589dbcb x15: ffffaae4ba071c89
[ 0.032535] x14: 0000000000000000 x13: ffffaae4ba071c84 x12: 455f525443206e61
[ 0.032541] x11: 68742072656c6c61 x10: 0000000000000029 x9 : ffffaae4b7d21da4
[ 0.032547] x8 : 0000000000000029 x7 : 4c414e494d5f414d x6 : 0000000000000029
[ 0.032553] x5 : 000000000000000f x4 : ffffaae4b9617a00 x3 : 0000000000000001
[ 0.032558] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff2f06c029be40
[ 0.032564] Call trace:
[ 0.032566] arch_setup_dma_ops+0xbc/0xcc
[ 0.032572] of_dma_configure_id+0x138/0x300
[ 0.032591] amba_dma_configure+0x34/0xc0
[ 0.032600] really_probe+0x78/0x3dc
[ 0.032614] __driver_probe_device+0x108/0x160
[ 0.032619] driver_probe_device+0x44/0x114
[ 0.032624] __device_attach_driver+0xb8/0x14c
[ 0.032629] bus_for_each_drv+0x88/0xe4
[ 0.032634] __device_attach+0xb0/0x1e0
[ 0.032638] device_initial_probe+0x18/0x20
[ 0.032643] bus_probe_device+0xa8/0xb0
[ 0.032648] device_add+0x4b4/0x6c0
[ 0.032652] amba_device_try_add.part.0+0x48/0x360
[ 0.032657] amba_device_add+0x104/0x144
[ 0.032662] of_amba_device_create.isra.0+0x100/0x1c4
[ 0.032666] of_platform_bus_create+0x294/0x35c
[ 0.032669] of_platform_populate+0x5c/0x150
[ 0.032672] of_platform_default_populate_init+0xd0/0xec
[ 0.032697] do_one_initcall+0x4c/0x2e0
[ 0.032701] do_initcalls+0x100/0x13c
[ 0.032707] kernel_init_freeable+0x1c8/0x21c
[ 0.032712] kernel_init+0x28/0x140
[ 0.032731] ret_from_fork+0x10/0x20
[ 0.032735] ---[ end trace 0000000000000000 ]---
In Linux, a check is applied to every device which is exposed through
device-tree node. The warning message is raised when the device isn't
DMA coherent and the cache line size is larger than ARCH_DMA_MINALIGN
(128 bytes). The cache line is sorted from CTR_EL0[CWG], which corresponds
to 256 bytes on the guest CPUs. The DMA coherent capability is claimed
through 'dma-coherent' in their device-tree nodes or parent nodes.
This happens even when the device doesn't implement or use DMA at all,
for legacy reasons.
Fix the issue by adding 'dma-coherent' property to the device-tree root
node, meaning all devices are capable of DMA coherent by default.
This both suppresses the spurious kernel warnings and also guards
against possible future QEMU bugs where we add a DMA-capable device
and forget to mark it as dma-coherent.
Signed-off-by: Zhenyu Zhang <zhenyzha@redhat.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Donald Dutile <ddutile@redhat.com
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-id: 20240612020506.307793-1-zhenyzha@redhat.com
[PMM: tweaked commit message]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit dda533087ad5559674ff486e7031c88dc01e0abd)
Signed-off-by: Zhenyu Zhang <zhenyzha@redhat.com>
---
hw/arm/virt.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3f0496cdb9..6ece67f11d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -330,6 +330,17 @@ static void create_fdt(VirtMachineState *vms)
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
qemu_fdt_setprop_string(fdt, "/", "model", "linux,dummy-virt");
+ /*
+ * For QEMU, all DMA is coherent. Advertising this in the root node
+ * has two benefits:
+ *
+ * - It avoids potential bugs where we forget to mark a DMA
+ * capable device as being dma-coherent
+ * - It avoids spurious warnings from the Linux kernel about
+ * devices which can't do DMA at all
+ */
+ qemu_fdt_setprop(fdt, "/", "dma-coherent", NULL, 0);
+
/* /chosen must exist for load_dtb to fill in necessary properties later */
qemu_fdt_add_subnode(fdt, "/chosen");
if (vms->dtb_randomness) {
--
2.39.3

@ -1,59 +0,0 @@
From e3360c415f7de923d27c3167260a93cb679afabe Mon Sep 17 00:00:00 2001
From: Eric Auger <eric.auger@redhat.com>
Date: Mon, 6 May 2024 15:09:43 +0200
Subject: [PATCH 1/2] hw/arm/virt: Fix spurious call to arm_virt_compat_set()
RH-Author: Eric Auger <eric.auger@redhat.com>
RH-MergeRequest: 238: hw/arm/virt: Fix spurious call to arm_virt_compat_set()
RH-Jira: RHEL-34945
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Gavin Shan <gshan@redhat.com>
RH-Commit: [1/1] a858a3e1dff12b28e14f7e4bd2b896a9f06eacbb (eauger1/centos-qemu-kvm)
JIRA: https://issues.redhat.com/browse/RHEL-34945
Status: RHEL-only
Downstream, we apply arm_rhel_compat in place of arm_virt_compat.
This is done though arm_rhel_compat_set() transparently called in
DEFINE_RHEL_MACHINE_LATEST(). So there is no need to call
arm_virt_compat_set() in rhel_machine_class_init(). Besides
this triggers a "GLib: g_ptr_array_add: assertion 'rarray' failed"
warning.
Signed-off-by: Eric Auger <eric.auger@redhat.com>
---
hw/arm/virt.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f1af9495c6..3f0496cdb9 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -85,6 +85,7 @@
#include "hw/char/pl011.h"
#include "qemu/guest-random.h"
+#if 0 /* Disabled for Red Hat Enterprise Linux */
static GlobalProperty arm_virt_compat[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
};
@@ -101,7 +102,6 @@ static void arm_virt_compat_set(MachineClass *mc)
arm_virt_compat_len);
}
-#if 0 /* Disabled for Red Hat Enterprise Linux */
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
void *data) \
@@ -3536,7 +3536,6 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
- arm_virt_compat_set(mc);
mc->family = "virt-rhel-Z";
mc->init = machvirt_init;
--
2.39.3

@ -1,73 +0,0 @@
From e74980be81d641736ea9d44d0fe9af02af63a220 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:40 -0500
Subject: [PATCH 083/100] hw/i386: Add support for loading BIOS using
guest_memfd
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [83/91] 7b77d212ef7d83b66ad9d8348179ee84e64fb911 (bonzini/rhel-qemu-kvm)
When guest_memfd is enabled, the BIOS is generally part of the initial
encrypted guest image and will be accessed as private guest memory. Add
the necessary changes to set up the associated RAM region with a
guest_memfd backend to allow for this.
Current support centers around using -bios to load the BIOS data.
Support for loading the BIOS via pflash requires additional enablement
since those interfaces rely on the use of ROM memory regions which make
use of the KVM_MEM_READONLY memslot flag, which is not supported for
guest_memfd-backed memslots.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-29-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit fc7a69e177e4ba26d11fcf47b853f85115b35a11)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/x86-common.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 35fe6eabea..6cbb76c25c 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -969,8 +969,13 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
(bios_size % 65536) != 0) {
goto bios_error;
}
- memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size,
- &error_fatal);
+ if (machine_require_guest_memfd(MACHINE(x86ms))) {
+ memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios",
+ bios_size, &error_fatal);
+ } else {
+ memory_region_init_ram(&x86ms->bios, NULL, "pc.bios",
+ bios_size, &error_fatal);
+ }
if (sev_enabled()) {
/*
* The concept of a "reset" simply doesn't exist for
@@ -991,9 +996,11 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
}
g_free(filename);
- /* map the last 128KB of the BIOS in ISA space */
- x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
- !isapc_ram_fw);
+ if (!machine_require_guest_memfd(MACHINE(x86ms))) {
+ /* map the last 128KB of the BIOS in ISA space */
+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
+ !isapc_ram_fw);
+ }
/* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory,
--
2.39.3

@ -1,106 +0,0 @@
From c1e615d6b8f609b72a94ffe6d31a9848a41744ef Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Tue, 30 Apr 2024 17:06:39 +0200
Subject: [PATCH 038/100] hw/i386: Have x86_bios_rom_init() take
X86MachineState rather than MachineState
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [38/91] 59f388b1dffc5d0aa2f0fff768194d755bc3efbb (bonzini/rhel-qemu-kvm)
The function creates and leaks two MemoryRegion objects regarding the BIOS which
will be moved into X86MachineState in the next steps to avoid the leakage.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240430150643.111976-3-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 848351840148f8c3b53ddf6210194506547d3ffd)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/microvm.c | 2 +-
hw/i386/pc_sysfw.c | 4 ++--
hw/i386/x86.c | 4 ++--
include/hw/i386/x86.h | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 61a772dfe6..fec63cacfa 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -278,7 +278,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
default_firmware = x86_machine_is_acpi_enabled(x86ms)
? MICROVM_BIOS_FILENAME
: MICROVM_QBOOT_FILENAME;
- x86_bios_rom_init(MACHINE(mms), default_firmware, get_system_memory(), true);
+ x86_bios_rom_init(x86ms, default_firmware, get_system_memory(), true);
}
static void microvm_memory_init(MicrovmMachineState *mms)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 3efabbbab2..ef7dea9798 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -206,7 +206,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
if (!pcmc->pci_enabled) {
- x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, true);
+ x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, true);
return;
}
@@ -227,7 +227,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
if (!pflash_blk[0]) {
/* Machine property pflash0 not set, use ROM mode */
- x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, false);
+ x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, false);
} else {
if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
/*
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 2a4f3ee285..6d3c72f124 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1128,7 +1128,7 @@ void x86_load_linux(X86MachineState *x86ms,
nb_option_roms++;
}
-void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
+void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw)
{
const char *bios_name;
@@ -1138,7 +1138,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
ssize_t ret;
/* BIOS load */
- bios_name = ms->firmware ?: default_firmware;
+ bios_name = MACHINE(x86ms)->firmware ?: default_firmware;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
bios_size = get_image_size(filename);
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 4dc30dcb4d..cb07618d19 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -116,7 +116,7 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
-void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
+void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw);
void x86_load_linux(X86MachineState *x86ms,
--
2.39.3

@ -1,51 +0,0 @@
From 7bb1f124413891bc5d2187f12cd19da6e794904b Mon Sep 17 00:00:00 2001
From: Xiaoyao Li <xiaoyao.li@intel.com>
Date: Wed, 3 Apr 2024 10:59:53 -0400
Subject: [PATCH 010/100] hw/i386/acpi: Set PCAT_COMPAT bit only when pic is
not disabled
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [10/91] 62110e4bf52cb3e106c8d2a902bbd31548beba00 (bonzini/rhel-qemu-kvm)
A value 1 of PCAT_COMPAT (bit 0) of MADT.Flags indicates that the system
also has a PC-AT-compatible dual-8259 setup, i.e., the PIC. When PIC
is not enabled (pic=off) for x86 machine, the PCAT_COMPAT bit needs to
be cleared. The PIC probe should then print:
[ 0.155970] Using NULL legacy PIC
However, no such log printed in guest kernel unless PCAT_COMPAT is
cleared.
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-ID: <20240403145953.3082491-1-xiaoyao.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 292dd287e78e0cbafde9d1522c729349d132d844)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/acpi-common.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c
index 20f19269da..0cc2919bb8 100644
--- a/hw/i386/acpi-common.c
+++ b/hw/i386/acpi-common.c
@@ -107,7 +107,9 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
acpi_table_begin(&table, table_data);
/* Local APIC Address */
build_append_int_noprefix(table_data, APIC_DEFAULT_ADDRESS, 4);
- build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
+ /* Flags. bit 0: PCAT_COMPAT */
+ build_append_int_noprefix(table_data,
+ x86ms->pic != ON_OFF_AUTO_OFF ? 1 : 0 , 4);
for (i = 0; i < apic_ids->len; i++) {
pc_madt_cpu_entry(i, apic_ids, table_data, false);
--
2.39.3

@ -1,164 +0,0 @@
From fd6de3c5e97bdf13a39342fc71815a20c66867ae Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Wed, 8 May 2024 19:55:07 +0200
Subject: [PATCH 043/100] hw/i386/pc_sysfw: Alias rather than copy isa-bios
region
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [43/91] f64dab2a091838a10a9b94e3d09ea11432b0809f (bonzini/rhel-qemu-kvm)
In the -bios case the "isa-bios" memory region is an alias to the BIOS mapped
to the top of the 4G memory boundary. Do the same in the -pflash case, but only
for new machine versions for migration compatibility. This establishes common
behavior and makes pflash commands work in the "isa-bios" region which some
real-world legacy bioses rely on.
Note that in the sev_enabled() case, the "isa-bios" memory region in the -pflash
case will now also point to encrypted memory, just like it already does in the
-bios case.
When running `info mtree` before and after this commit with
`qemu-system-x86_64 -S -drive \
if=pflash,format=raw,readonly=on,file=/usr/share/qemu/bios-256k.bin` and running
`diff -u before.mtree after.mtree` results in the following changes in the
memory tree:
| --- before.mtree
| +++ after.mtree
| @@ -71,7 +71,7 @@
| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci
| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios
| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff
| 00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
| 00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
| 00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
| @@ -108,7 +108,7 @@
| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci
| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios
| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff
| 00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff
| 00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff
| 00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff
| @@ -131,11 +131,14 @@
| memory-region: pc.ram
| 0000000000000000-0000000007ffffff (prio 0, ram): pc.ram
|
| +memory-region: system.flash0
| + 00000000fffc0000-00000000ffffffff (prio 0, romd): system.flash0
| +
| memory-region: pci
| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci
| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem
| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom
| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios
| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff
|
| memory-region: smram
| 00000000000a0000-00000000000bffff (prio 0, ram): alias smram-low @pc.ram 00000000000a0000-00000000000bffff
Note that in both cases the "system" memory region contains the entry
00000000fffc0000-00000000ffffffff (prio 0, romd): system.flash0
but the "system.flash0" memory region only appears standalone when "isa-bios" is
an alias.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20240508175507.22270-7-shentey@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a44ea3fa7f2aa1d809fdca1b84a52695b53d8ad0)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 1 +
hw/i386/pc_piix.c | 1 +
hw/i386/pc_q35.c | 1 +
hw/i386/pc_sysfw.c | 8 +++++++-
include/hw/i386/pc.h | 1 +
5 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 1a34bc4522..660a59c63b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1967,6 +1967,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->has_reserved_memory = true;
pcmc->enforce_aligned_dimm = true;
pcmc->enforce_amd_1tb_hole = true;
+ pcmc->isa_bios_alias = true;
/* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported
* to be used at the moment, 32K should be enough for a while. */
pcmc->acpi_data_size = 0x20000 + 0x8000;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bef3e8b73e..dbb7f2ed17 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -975,6 +975,7 @@ static void pc_machine_rhel7_options(MachineClass *m)
m->alias = "pc";
m->is_default = 1;
m->smp_props.prefer_sockets = true;
+ pcmc->isa_bios_alias = false;
}
static void pc_init_rhel760(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index dedc86eec9..f9900ad798 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -735,6 +735,7 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
pcmc->smbios_stream_product = "RHEL";
pcmc->smbios_stream_version = "9.4.0";
+ pcmc->isa_bios_alias = false;
compat_props_add(m->compat_props, pc_rhel_9_5_compat,
pc_rhel_9_5_compat_len);
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 82d37cb376..ac88ad4eb9 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -135,6 +135,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
MemoryRegion *rom_memory)
{
X86MachineState *x86ms = X86_MACHINE(pcms);
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
hwaddr total_size = 0;
int i;
BlockBackend *blk;
@@ -184,7 +185,12 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
- pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
+ if (pcmc->isa_bios_alias) {
+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem,
+ true);
+ } else {
+ pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
+ }
/* Encrypt the pflash boot ROM */
if (sev_enabled()) {
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 467e7fb52f..3f53ec73ac 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -122,6 +122,7 @@ struct PCMachineClass {
bool enforce_aligned_dimm;
bool broken_reserved_end;
bool enforce_amd_1tb_hole;
+ bool isa_bios_alias;
/* generate legacy CPU hotplug AML */
bool legacy_cpu_hotplug;
--
2.39.3

@ -1,53 +0,0 @@
From 9bf1d368c4b53139db39649833d475e097fc98d1 Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Mon, 22 Apr 2024 22:06:22 +0200
Subject: [PATCH 039/100] hw/i386/pc_sysfw: Remove unused parameter from
pc_isa_bios_init()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [39/91] c0019dc2706a8e3f40486fd4a4c0dd1fbe23237b (bonzini/rhel-qemu-kvm)
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240422200625.2768-2-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit f4b63768b91811cdcf1fb7b270587123251dfea5)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc_sysfw.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index ef7dea9798..59c7a81692 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -41,8 +41,7 @@
#define FLASH_SECTOR_SIZE 4096
static void pc_isa_bios_init(MemoryRegion *rom_memory,
- MemoryRegion *flash_mem,
- int ram_size)
+ MemoryRegion *flash_mem)
{
int isa_bios_size;
MemoryRegion *isa_bios;
@@ -186,7 +185,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
- pc_isa_bios_init(rom_memory, flash_mem, size);
+ pc_isa_bios_init(rom_memory, flash_mem);
/* Encrypt the pflash boot ROM */
if (sev_enabled()) {
--
2.39.3

@ -1,158 +0,0 @@
From e6472ff46cbed97c2a238a8ef7d321351931333a Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:30 -0500
Subject: [PATCH 070/100] hw/i386/sev: Add function to get SEV metadata from
OVMF header
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [70/91] ba818dade96119c8a51ca1fb222f4f69e2752396 (bonzini/rhel-qemu-kvm)
A recent version of OVMF expanded the reset vector GUID list to add
SEV-specific metadata GUID. The SEV metadata describes the reserved
memory regions such as the secrets and CPUID page used during the SEV-SNP
guest launch.
The pc_system_get_ovmf_sev_metadata_ptr() is used to retieve the SEV
metadata pointer from the OVMF GUID list.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-19-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f3c30c575d34122573b7370a7da5ca3a27dde481)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc_sysfw.c | 4 ++++
include/hw/i386/pc.h | 26 ++++++++++++++++++++++++++
target/i386/sev-sysemu-stub.c | 4 ++++
target/i386/sev.c | 32 ++++++++++++++++++++++++++++++++
target/i386/sev.h | 2 ++
5 files changed, 68 insertions(+)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index ac88ad4eb9..9b8671c441 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -260,6 +260,10 @@ void x86_firmware_configure(void *ptr, int size)
pc_system_parse_ovmf_flash(ptr, size);
if (sev_enabled()) {
+
+ /* Copy the SEV metadata table (if it exists) */
+ pc_system_parse_sev_metadata(ptr, size);
+
ret = sev_es_save_reset_vector(ptr, size);
if (ret) {
error_report("failed to locate and/or save reset vector");
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3f53ec73ac..94b49310f5 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -167,6 +167,32 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
#define PCI_HOST_PROP_SMM_RANGES "smm-ranges"
+typedef enum {
+ SEV_DESC_TYPE_UNDEF,
+ /* The section contains the region that must be validated by the VMM. */
+ SEV_DESC_TYPE_SNP_SEC_MEM,
+ /* The section contains the SNP secrets page */
+ SEV_DESC_TYPE_SNP_SECRETS,
+ /* The section contains address that can be used as a CPUID page */
+ SEV_DESC_TYPE_CPUID,
+
+} ovmf_sev_metadata_desc_type;
+
+typedef struct __attribute__((__packed__)) OvmfSevMetadataDesc {
+ uint32_t base;
+ uint32_t len;
+ ovmf_sev_metadata_desc_type type;
+} OvmfSevMetadataDesc;
+
+typedef struct __attribute__((__packed__)) OvmfSevMetadata {
+ uint8_t signature[4];
+ uint32_t len;
+ uint32_t version;
+ uint32_t num_desc;
+ OvmfSevMetadataDesc descs[];
+} OvmfSevMetadata;
+
+OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void);
void pc_pci_as_mapping_init(MemoryRegion *system_memory,
MemoryRegion *pci_address_space);
diff --git a/target/i386/sev-sysemu-stub.c b/target/i386/sev-sysemu-stub.c
index 96e1c15cc3..fc1c57c411 100644
--- a/target/i386/sev-sysemu-stub.c
+++ b/target/i386/sev-sysemu-stub.c
@@ -67,3 +67,7 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "SEV is not available in this QEMU\n");
}
+
+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
+{
+}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index e84e4395a5..17281bb2c7 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -597,6 +597,38 @@ SevCapability *qmp_query_sev_capabilities(Error **errp)
return sev_get_capabilities(errp);
}
+static OvmfSevMetadata *ovmf_sev_metadata_table;
+
+#define OVMF_SEV_META_DATA_GUID "dc886566-984a-4798-A75e-5585a7bf67cc"
+typedef struct __attribute__((__packed__)) OvmfSevMetadataOffset {
+ uint32_t offset;
+} OvmfSevMetadataOffset;
+
+OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void)
+{
+ return ovmf_sev_metadata_table;
+}
+
+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
+{
+ OvmfSevMetadata *metadata;
+ OvmfSevMetadataOffset *data;
+
+ if (!pc_system_ovmf_table_find(OVMF_SEV_META_DATA_GUID, (uint8_t **)&data,
+ NULL)) {
+ return;
+ }
+
+ metadata = (OvmfSevMetadata *)(flash_ptr + flash_size - data->offset);
+ if (memcmp(metadata->signature, "ASEV", 4) != 0 ||
+ metadata->len < sizeof(OvmfSevMetadata) ||
+ metadata->len > flash_size - data->offset) {
+ return;
+ }
+
+ ovmf_sev_metadata_table = g_memdup2(metadata, metadata->len);
+}
+
static SevAttestationReport *sev_get_attestation_report(const char *mnonce,
Error **errp)
{
diff --git a/target/i386/sev.h b/target/i386/sev.h
index 5dc4767b1e..cc12824dd6 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -66,4 +66,6 @@ int sev_inject_launch_secret(const char *hdr, const char *secret,
int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size);
void sev_es_set_reset_vector(CPUState *cpu);
+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size);
+
#endif
--
2.39.3

@ -1,165 +0,0 @@
From 226cf6c3d3e2fd1a35422043dbe0b73d1216df83 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:36 -0500
Subject: [PATCH 073/100] hw/i386/sev: Add support to encrypt BIOS when SEV-SNP
is enabled
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [73/91] 844afd322c12c3e8992cf6ec692c94e70747bd0c (bonzini/rhel-qemu-kvm)
As with SEV, an SNP guest requires that the BIOS be part of the initial
encrypted/measured guest payload. Extend sev_encrypt_flash() to handle
the SNP case and plumb through the GPA of the BIOS location since this
is needed for SNP.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-25-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 77d1abd91e5352ad30ae2f83790f95fa6a3c0b6b)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc_sysfw.c | 12 +++++++-----
hw/i386/x86-common.c | 2 +-
include/hw/i386/x86.h | 2 +-
target/i386/sev-sysemu-stub.c | 2 +-
target/i386/sev.c | 5 +++--
target/i386/sev.h | 2 +-
6 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 9b8671c441..7cdbafc8d2 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -148,6 +148,8 @@ static void pc_system_flash_map(PCMachineState *pcms,
assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) {
+ hwaddr gpa;
+
system_flash = pcms->flash[i];
blk = pflash_cfi01_get_blk(system_flash);
if (!blk) {
@@ -177,11 +179,11 @@ static void pc_system_flash_map(PCMachineState *pcms,
}
total_size += size;
+ gpa = 0x100000000ULL - total_size; /* where the flash is mapped */
qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks",
size / FLASH_SECTOR_SIZE);
sysbus_realize_and_unref(SYS_BUS_DEVICE(system_flash), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
- 0x100000000ULL - total_size);
+ sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, gpa);
if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
@@ -196,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (sev_enabled()) {
flash_ptr = memory_region_get_ram_ptr(flash_mem);
flash_size = memory_region_size(flash_mem);
- x86_firmware_configure(flash_ptr, flash_size);
+ x86_firmware_configure(gpa, flash_ptr, flash_size);
}
}
}
@@ -249,7 +251,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
pc_system_flash_cleanup_unused(pcms);
}
-void x86_firmware_configure(void *ptr, int size)
+void x86_firmware_configure(hwaddr gpa, void *ptr, int size)
{
int ret;
@@ -270,6 +272,6 @@ void x86_firmware_configure(void *ptr, int size)
exit(1);
}
- sev_encrypt_flash(ptr, size, &error_fatal);
+ sev_encrypt_flash(gpa, ptr, size, &error_fatal);
}
}
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 67b03c913a..35fe6eabea 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -981,7 +981,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
*/
void *ptr = memory_region_get_ram_ptr(&x86ms->bios);
load_image_size(filename, ptr, bios_size);
- x86_firmware_configure(ptr, bios_size);
+ x86_firmware_configure(0x100000000ULL - bios_size, ptr, bios_size);
} else {
memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw);
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index b006f16b8d..d43cb3908e 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -154,6 +154,6 @@ void ioapic_init_gsi(GSIState *gsi_state, Object *parent);
DeviceState *ioapic_init_secondary(GSIState *gsi_state);
/* pc_sysfw.c */
-void x86_firmware_configure(void *ptr, int size);
+void x86_firmware_configure(hwaddr gpa, void *ptr, int size);
#endif
diff --git a/target/i386/sev-sysemu-stub.c b/target/i386/sev-sysemu-stub.c
index fc1c57c411..d5bf886e79 100644
--- a/target/i386/sev-sysemu-stub.c
+++ b/target/i386/sev-sysemu-stub.c
@@ -42,7 +42,7 @@ void qmp_sev_inject_launch_secret(const char *packet_header, const char *secret,
error_setg(errp, "SEV is not available in this QEMU");
}
-int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
+int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
g_assert_not_reached();
}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 06401f0526..7b5c4b4874 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1484,7 +1484,7 @@ static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
}
int
-sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
+sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
@@ -1841,7 +1841,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
/* zero the excess data so the measurement can be reliably calculated */
memset(padded_ht->padding, 0, sizeof(padded_ht->padding));
- if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) {
+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
+ sizeof(*padded_ht), errp) < 0) {
ret = false;
}
diff --git a/target/i386/sev.h b/target/i386/sev.h
index cc12824dd6..858005a119 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -59,7 +59,7 @@ uint32_t sev_get_cbit_position(void);
uint32_t sev_get_reduced_phys_bits(void);
bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp);
-int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp);
+int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp);
int sev_inject_launch_secret(const char *hdr, const char *secret,
uint64_t gpa, Error **errp);
--
2.39.3

@ -1,123 +0,0 @@
From a20b2e3e52b9589ac1abc8b9b818d526c86368cf Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:39 -0500
Subject: [PATCH 082/100] hw/i386/sev: Use guest_memfd for legacy ROMs
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [82/91] a591e85e00c353009803b143c80852b8c9b1f15e (bonzini/rhel-qemu-kvm)
Current SNP guest kernels will attempt to access these regions with
with C-bit set, so guest_memfd is needed to handle that. Otherwise,
kvm_convert_memory() will fail when the guest kernel tries to access it
and QEMU attempts to call KVM_SET_MEMORY_ATTRIBUTES to set these ranges
to private.
Whether guests should actually try to access ROM regions in this way (or
need to deal with legacy ROM regions at all), is a separate issue to be
addressed on kernel side, but current SNP guest kernels will exhibit
this behavior and so this handling is needed to allow QEMU to continue
running existing SNP guest kernels.
Signed-off-by: Michael Roth <michael.roth@amd.com>
[pankaj: Added sev_snp_enabled() check]
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-28-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 413a67450750e0459efeffc3db3ba9759c3e381c)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 14 ++++++++++----
hw/i386/pc_sysfw.c | 19 +++++++++++++------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0aca0cc79e..b25d075b59 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -62,6 +62,7 @@
#include "hw/mem/memory-device.h"
#include "e820_memory_layout.h"
#include "trace.h"
+#include "sev.h"
#include CONFIG_DEVICES
#ifdef CONFIG_XEN_EMU
@@ -1173,10 +1174,15 @@ void pc_memory_init(PCMachineState *pcms,
pc_system_firmware_init(pcms, rom_memory);
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
- memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
- &error_fatal);
- if (pcmc->pci_enabled) {
- memory_region_set_readonly(option_rom_mr, true);
+ if (machine_require_guest_memfd(machine)) {
+ memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom",
+ PC_ROM_SIZE, &error_fatal);
+ } else {
+ memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
+ &error_fatal);
+ if (pcmc->pci_enabled) {
+ memory_region_set_readonly(option_rom_mr, true);
+ }
}
memory_region_add_subregion_overlap(rom_memory,
PC_ROM_MIN_VGA,
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 7cdbafc8d2..ef80281d28 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -40,8 +40,8 @@
#define FLASH_SECTOR_SIZE 4096
-static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
- MemoryRegion *flash_mem)
+static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
+ MemoryRegion *rom_memory, MemoryRegion *flash_mem)
{
int isa_bios_size;
uint64_t flash_size;
@@ -51,8 +51,13 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(flash_size, 128 * KiB);
- memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
- &error_fatal);
+ if (machine_require_guest_memfd(MACHINE(pcms))) {
+ memory_region_init_ram_guest_memfd(isa_bios, NULL, "isa-bios",
+ isa_bios_size, &error_fatal);
+ } else {
+ memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
+ &error_fatal);
+ }
memory_region_add_subregion_overlap(rom_memory,
0x100000 - isa_bios_size,
isa_bios,
@@ -65,7 +70,9 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
isa_bios_size);
- memory_region_set_readonly(isa_bios, true);
+ if (!machine_require_guest_memfd(current_machine)) {
+ memory_region_set_readonly(isa_bios, true);
+ }
}
static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms,
@@ -191,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem,
true);
} else {
- pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
+ pc_isa_bios_init(pcms, &x86ms->isa_bios, rom_memory, flash_mem);
}
/* Encrypt the pflash boot ROM */
--
2.39.3

@ -1,58 +0,0 @@
From 4331180aa09e44550ff8de781c618bae5e99bb70 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Tue, 9 Apr 2024 18:07:43 -0500
Subject: [PATCH 025/100] hw/i386/sev: Use legacy SEV VM types for older
machine types
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [25/91] 8c73cd312736ccb0818b4d3216fd13712f21f3c9 (bonzini/rhel-qemu-kvm)
Newer 9.1 machine types will default to using the KVM_SEV_INIT2 API for
creating SEV/SEV-ES going forward. However, this API results in guest
measurement changes which are generally not expected for users of these
older guest types and can cause disruption if they switch to a newer
QEMU/kernel version. Avoid this by continuing to use the older
KVM_SEV_INIT/KVM_SEV_ES_INIT APIs for older machine types.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Message-ID: <20240409230743.962513-4-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ea7fbd37537b3a598335c21ccb2ea674630fc810)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 1 +
target/i386/sev.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b9fde3cec1..1a34bc4522 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -351,6 +351,7 @@ const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat);
GlobalProperty pc_rhel_9_5_compat[] = {
/* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */
{ TYPE_X86_CPU, "guest-phys-bits", "0" },
+ { "sev-guest", "legacy-vm-type", "true" },
};
const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat);
diff --git a/target/i386/sev.c b/target/i386/sev.c
index f4ee317cb0..d30b68c11e 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1417,6 +1417,7 @@ sev_guest_instance_init(Object *obj)
object_property_add_uint32_ptr(obj, "reduced-phys-bits",
&sev->reduced_phys_bits,
OBJ_PROP_FLAG_READWRITE);
+ object_apply_compat_props(obj);
}
/* sev guest info */
--
2.39.3

File diff suppressed because it is too large Load Diff

@ -1,133 +0,0 @@
From ebf08d2a822576acfa60fbd5f552d26de1e4c4be Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Wed, 8 May 2024 19:55:04 +0200
Subject: [PATCH 040/100] hw/i386/x86: Don't leak "isa-bios" memory regions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [40/91] bb595357c6cc2d5a80bf3873853c69553c5feee5 (bonzini/rhel-qemu-kvm)
Fix the leaking in x86_bios_rom_init() and pc_isa_bios_init() by adding an
"isa_bios" attribute to X86MachineState.
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20240508175507.22270-4-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 32d3ee87a17fc91e981a23dba94855bff89f5920)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc_sysfw.c | 7 +++----
hw/i386/x86.c | 9 ++++-----
include/hw/i386/x86.h | 7 +++++++
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 59c7a81692..82d37cb376 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -40,11 +40,10 @@
#define FLASH_SECTOR_SIZE 4096
-static void pc_isa_bios_init(MemoryRegion *rom_memory,
+static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
MemoryRegion *flash_mem)
{
int isa_bios_size;
- MemoryRegion *isa_bios;
uint64_t flash_size;
void *flash_ptr, *isa_bios_ptr;
@@ -52,7 +51,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(flash_size, 128 * KiB);
- isa_bios = g_malloc(sizeof(*isa_bios));
memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
&error_fatal);
memory_region_add_subregion_overlap(rom_memory,
@@ -136,6 +134,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms)
static void pc_system_flash_map(PCMachineState *pcms,
MemoryRegion *rom_memory)
{
+ X86MachineState *x86ms = X86_MACHINE(pcms);
hwaddr total_size = 0;
int i;
BlockBackend *blk;
@@ -185,7 +184,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
- pc_isa_bios_init(rom_memory, flash_mem);
+ pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
/* Encrypt the pflash boot ROM */
if (sev_enabled()) {
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 6d3c72f124..457e8a34a5 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1133,7 +1133,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
{
const char *bios_name;
char *filename;
- MemoryRegion *bios, *isa_bios;
+ MemoryRegion *bios;
int bios_size, isa_bios_size;
ssize_t ret;
@@ -1173,14 +1173,13 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(bios_size, 128 * KiB);
- isa_bios = g_malloc(sizeof(*isa_bios));
- memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
+ memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios,
bios_size - isa_bios_size, isa_bios_size);
memory_region_add_subregion_overlap(rom_memory,
0x100000 - isa_bios_size,
- isa_bios,
+ &x86ms->isa_bios,
1);
- memory_region_set_readonly(isa_bios, !isapc_ram_fw);
+ memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw);
/* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory,
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index cb07618d19..a07de79167 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -18,6 +18,7 @@
#define HW_I386_X86_H
#include "exec/hwaddr.h"
+#include "exec/memory.h"
#include "hw/boards.h"
#include "hw/intc/ioapic.h"
@@ -52,6 +53,12 @@ struct X86MachineState {
GMappedFile *initrd_mapped_file;
HotplugHandler *acpi_dev;
+ /*
+ * Map the upper 128 KiB of the BIOS just underneath the 1 MiB address
+ * boundary.
+ */
+ MemoryRegion isa_bios;
+
/* RAM information (sizes, addresses, configuration): */
ram_addr_t below_4g_mem_size, above_4g_mem_size;
--
2.39.3

@ -1,105 +0,0 @@
From e1f2265b5f6bf5b63bf3808bb540888f3cf8badb Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Wed, 8 May 2024 19:55:05 +0200
Subject: [PATCH 041/100] hw/i386/x86: Don't leak "pc.bios" memory region
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [41/91] a9cd61d8d240134c09c46e244efb89217cadf60c (bonzini/rhel-qemu-kvm)
Fix the leaking in x86_bios_rom_init() by adding a "bios" attribute to
X86MachineState. Note that it is only used in the -bios case.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20240508175507.22270-5-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 865d95321ffc8d9941e33000b10140550f094556)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/x86.c | 13 ++++++-------
include/hw/i386/x86.h | 6 ++++++
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 457e8a34a5..29167de97d 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1133,7 +1133,6 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
{
const char *bios_name;
char *filename;
- MemoryRegion *bios;
int bios_size, isa_bios_size;
ssize_t ret;
@@ -1149,8 +1148,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
(bios_size % 65536) != 0) {
goto bios_error;
}
- bios = g_malloc(sizeof(*bios));
- memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
+ memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size,
+ &error_fatal);
if (sev_enabled()) {
/*
* The concept of a "reset" simply doesn't exist for
@@ -1159,11 +1158,11 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
* the firmware as rom to properly re-initialize on reset.
* Just go for a straight file load instead.
*/
- void *ptr = memory_region_get_ram_ptr(bios);
+ void *ptr = memory_region_get_ram_ptr(&x86ms->bios);
load_image_size(filename, ptr, bios_size);
x86_firmware_configure(ptr, bios_size);
} else {
- memory_region_set_readonly(bios, !isapc_ram_fw);
+ memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw);
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) {
goto bios_error;
@@ -1173,7 +1172,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(bios_size, 128 * KiB);
- memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios,
+ memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios,
bios_size - isa_bios_size, isa_bios_size);
memory_region_add_subregion_overlap(rom_memory,
0x100000 - isa_bios_size,
@@ -1184,7 +1183,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
/* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory,
(uint32_t)(-bios_size),
- bios);
+ &x86ms->bios);
return;
bios_error:
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index a07de79167..55c6809ae0 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -53,6 +53,12 @@ struct X86MachineState {
GMappedFile *initrd_mapped_file;
HotplugHandler *acpi_dev;
+ /*
+ * Map the whole BIOS just underneath the 4 GiB address boundary. Only used
+ * in the ROM (-bios) case.
+ */
+ MemoryRegion bios;
+
/*
* Map the upper 128 KiB of the BIOS just underneath the 1 MiB address
* boundary.
--
2.39.3

@ -1,69 +0,0 @@
From b9d0c78f04160fbc1eee6cfd94b17f1133a35d83 Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Tue, 30 Apr 2024 17:06:38 +0200
Subject: [PATCH 037/100] hw/i386/x86: Eliminate two if statements in
x86_bios_rom_init()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [37/91] 1ef6a13214e85f6ef773f5c894c720f20330912b (bonzini/rhel-qemu-kvm)
Given that memory_region_set_readonly() is a no-op when the readonlyness is
already as requested it is possible to simplify the pattern
if (condition) {
foo(true);
}
to
foo(condition);
which is shorter and allows to see the invariant of the code more easily.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20240430150643.111976-2-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 014dbdac8798799d081abc9dff3e4876ca54f49e)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/x86.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 3d5b51e92d..2a4f3ee285 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1163,9 +1163,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
load_image_size(filename, ptr, bios_size);
x86_firmware_configure(ptr, bios_size);
} else {
- if (!isapc_ram_fw) {
- memory_region_set_readonly(bios, true);
- }
+ memory_region_set_readonly(bios, !isapc_ram_fw);
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) {
goto bios_error;
@@ -1182,9 +1180,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
0x100000 - isa_bios_size,
isa_bios,
1);
- if (!isapc_ram_fw) {
- memory_region_set_readonly(isa_bios, true);
- }
+ memory_region_set_readonly(isa_bios, !isapc_ram_fw);
/* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory,
--
2.39.3

@ -1,98 +0,0 @@
From 1baf67564d4227d6ba98923217a15814c438c32b Mon Sep 17 00:00:00 2001
From: Bernhard Beschow <shentey@gmail.com>
Date: Wed, 8 May 2024 19:55:06 +0200
Subject: [PATCH 042/100] hw/i386/x86: Extract x86_isa_bios_init() from
x86_bios_rom_init()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [42/91] 1db417a5995480924f7fd0661a306f2d2bfa0a77 (bonzini/rhel-qemu-kvm)
The function is inspired by pc_isa_bios_init() and should eventually replace it.
Using x86_isa_bios_init() rather than pc_isa_bios_init() fixes pflash commands
to work in the isa-bios region.
While at it convert the magic number 0x100000 (== 1MiB) to increase readability.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20240508175507.22270-6-shentey@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 5c5ffec12c30d2017cbdee6798f54d8fad3f9656)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/x86.c | 25 ++++++++++++++++---------
include/hw/i386/x86.h | 2 ++
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 29167de97d..c61f4ebfa6 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1128,12 +1128,25 @@ void x86_load_linux(X86MachineState *x86ms,
nb_option_roms++;
}
+void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory,
+ MemoryRegion *bios, bool read_only)
+{
+ uint64_t bios_size = memory_region_size(bios);
+ uint64_t isa_bios_size = MIN(bios_size, 128 * KiB);
+
+ memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
+ bios_size - isa_bios_size, isa_bios_size);
+ memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size,
+ isa_bios, 1);
+ memory_region_set_readonly(isa_bios, read_only);
+}
+
void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw)
{
const char *bios_name;
char *filename;
- int bios_size, isa_bios_size;
+ int bios_size;
ssize_t ret;
/* BIOS load */
@@ -1171,14 +1184,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
g_free(filename);
/* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = MIN(bios_size, 128 * KiB);
- memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios,
- bios_size - isa_bios_size, isa_bios_size);
- memory_region_add_subregion_overlap(rom_memory,
- 0x100000 - isa_bios_size,
- &x86ms->isa_bios,
- 1);
- memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw);
+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
+ !isapc_ram_fw);
/* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory,
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 55c6809ae0..d7b7d3f3ce 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -129,6 +129,8 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
+void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory,
+ MemoryRegion *bios, bool read_only);
void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw);
--
2.39.3

@ -0,0 +1,270 @@
From 416ee0a87ee4bfedf07bc37d328066375b36fdc1 Mon Sep 17 00:00:00 2001
From: Jared Rossi <jrossi@linux.ibm.com>
Date: Sat, 19 Oct 2024 21:29:49 -0400
Subject: [PATCH 17/38] hw/s390x: Build an IPLB for each boot device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [16/23] 40a579b400cebd1470bb632869ad4a5581e3c41f (thuth/qemu-kvm-cs9)
Build an IPLB for any device with a bootindex (up to a maximum of 8 devices).
The IPLB chain is placed immediately before the BIOS in memory. Because this
is not a fixed address, the location of the next IPLB and number of remaining
boot devices is stored in the QIPL global variable for possible later access by
the guest during IPL.
Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20241020012953.1380075-16-jrossi@linux.ibm.com>
[thuth: Fix endianness problem when accessing the qipl structure]
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 0927875e704e93ace03bb7533c0877bf97e4bda9)
---
hw/s390x/ipl.c | 129 ++++++++++++++++++++++++++++--------
hw/s390x/ipl.h | 1 +
include/hw/s390x/ipl/qipl.h | 4 +-
3 files changed, 105 insertions(+), 29 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index d83832d975..f4576f8822 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -56,6 +56,13 @@ static bool iplb_extended_needed(void *opaque)
return ipl->iplbext_migration;
}
+/* Place the IPLB chain immediately before the BIOS in memory */
+static uint64_t find_iplb_chain_addr(uint64_t bios_addr, uint16_t count)
+{
+ return (bios_addr & TARGET_PAGE_MASK)
+ - (count * sizeof(IplParameterBlock));
+}
+
static const VMStateDescription vmstate_iplb_extended = {
.name = "ipl/iplb_extended",
.version_id = 0,
@@ -398,6 +405,17 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype)
return ccw_dev;
}
+static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain)
+{
+ S390IPLState *ipl = get_ipl_device();
+ uint16_t count = be16_to_cpu(ipl->qipl.chain_len);
+ uint64_t len = sizeof(IplParameterBlock) * count;
+ uint64_t chain_addr = find_iplb_chain_addr(ipl->bios_start_addr, count);
+
+ cpu_physical_memory_write(chain_addr, iplb_chain, len);
+ return chain_addr;
+}
+
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp)
{
int i;
@@ -428,54 +446,51 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp)
}
}
-static bool s390_gen_initial_iplb(S390IPLState *ipl)
+static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb)
{
- DeviceState *dev_st;
+ S390IPLState *ipl = get_ipl_device();
CcwDevice *ccw_dev = NULL;
SCSIDevice *sd;
int devtype;
uint8_t *lp;
- dev_st = get_boot_device(0);
- if (dev_st) {
- ccw_dev = s390_get_ccw_device(dev_st, &devtype);
- }
-
/*
* Currently allow IPL only from CCW devices.
*/
+ ccw_dev = s390_get_ccw_device(dev_st, &devtype);
if (ccw_dev) {
lp = ccw_dev->loadparm;
switch (devtype) {
case CCW_DEVTYPE_SCSI:
sd = SCSI_DEVICE(dev_st);
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
- ipl->iplb.blk0_len =
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN);
+ iplb->blk0_len =
cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI;
- ipl->iplb.scsi.lun = cpu_to_be32(sd->lun);
- ipl->iplb.scsi.target = cpu_to_be16(sd->id);
- ipl->iplb.scsi.channel = cpu_to_be16(sd->channel);
- ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3;
+ iplb->pbt = S390_IPL_TYPE_QEMU_SCSI;
+ iplb->scsi.lun = cpu_to_be32(sd->lun);
+ iplb->scsi.target = cpu_to_be16(sd->id);
+ iplb->scsi.channel = cpu_to_be16(sd->channel);
+ iplb->scsi.devno = cpu_to_be16(ccw_dev->sch->devno);
+ iplb->scsi.ssid = ccw_dev->sch->ssid & 3;
break;
case CCW_DEVTYPE_VFIO:
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_CCW;
- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+ iplb->pbt = S390_IPL_TYPE_CCW;
+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+ iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
break;
case CCW_DEVTYPE_VIRTIO_NET:
+ /* The S390IPLState netboot is true if ANY IPLB may use netboot */
ipl->netboot = true;
/* Fall through to CCW_DEVTYPE_VIRTIO case */
case CCW_DEVTYPE_VIRTIO:
- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
- ipl->iplb.blk0_len =
+ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN);
+ iplb->blk0_len =
cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN);
- ipl->iplb.pbt = S390_IPL_TYPE_CCW;
- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3;
+ iplb->pbt = S390_IPL_TYPE_CCW;
+ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno);
+ iplb->ccw.ssid = ccw_dev->sch->ssid & 3;
break;
}
@@ -484,8 +499,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm;
}
- s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm);
- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID;
+ s390_ipl_convert_loadparm((char *)lp, iplb->loadparm);
+ iplb->flags |= DIAG308_FLAGS_LP_VALID;
return true;
}
@@ -493,6 +508,62 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl)
return false;
}
+static bool s390_init_all_iplbs(S390IPLState *ipl)
+{
+ int iplb_num = 0;
+ IplParameterBlock iplb_chain[7];
+ DeviceState *dev_st = get_boot_device(0);
+ Object *machine = qdev_get_machine();
+
+ /*
+ * Parse the boot devices. Generate an IPLB for only the first boot device
+ * which will later be set with DIAG308.
+ */
+ if (!dev_st) {
+ ipl->qipl.chain_len = 0;
+ return false;
+ }
+
+ /* If no machine loadparm was defined fill it with spaces */
+ if (memcmp(S390_CCW_MACHINE(machine)->loadparm, NO_LOADPARM, 8) == 0) {
+ object_property_set_str(machine, "loadparm", " ", NULL);
+ }
+
+ iplb_num = 1;
+ s390_build_iplb(dev_st, &ipl->iplb);
+
+ /* Index any fallback boot devices */
+ while (get_boot_device(iplb_num)) {
+ iplb_num++;
+ }
+
+ if (iplb_num > MAX_BOOT_DEVS) {
+ warn_report("Excess boot devices defined! %d boot devices found, "
+ "but only the first %d will be considered.",
+ iplb_num, MAX_BOOT_DEVS);
+
+ iplb_num = MAX_BOOT_DEVS;
+ }
+
+ ipl->qipl.chain_len = cpu_to_be16(iplb_num - 1);
+
+ /*
+ * Build fallback IPLBs for any boot devices above index 0, up to a
+ * maximum amount as defined in ipl.h
+ */
+ if (iplb_num > 1) {
+ /* Start at 1 because the IPLB for boot index 0 is not chained */
+ for (int i = 1; i < iplb_num; i++) {
+ dev_st = get_boot_device(i);
+ s390_build_iplb(dev_st, &iplb_chain[i - 1]);
+ }
+
+ ipl->qipl.next_iplb = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain));
+ }
+
+ return iplb_num;
+}
+
static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
int virtio_id)
{
@@ -620,7 +691,7 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
* this is the original boot device's SCSI
* so restore IPL parameter info from it
*/
- ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+ ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb);
}
}
if (reset_type == S390_RESET_MODIFIED_CLEAR ||
@@ -714,7 +785,9 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
if (!ipl->kernel || ipl->iplb_valid) {
cpu->env.psw.addr = ipl->bios_start_addr;
if (!ipl->iplb_valid) {
- ipl->iplb_valid = s390_gen_initial_iplb(ipl);
+ ipl->iplb_valid = s390_init_all_iplbs(ipl);
+ } else {
+ ipl->qipl.chain_len = 0;
}
}
s390_ipl_set_boot_menu(ipl);
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index b670bad551..54eb48fd6e 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -20,6 +20,7 @@
#include "qom/object.h"
#define DIAG308_FLAGS_LP_VALID 0x80
+#define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */
void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp);
void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp);
diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h
index b67d2ae061..1da4f75aa8 100644
--- a/include/hw/s390x/ipl/qipl.h
+++ b/include/hw/s390x/ipl/qipl.h
@@ -32,7 +32,9 @@ struct QemuIplParameters {
uint8_t reserved1[3];
uint64_t reserved2;
uint32_t boot_menu_timeout;
- uint8_t reserved3[12];
+ uint8_t reserved3[2];
+ uint16_t chain_len;
+ uint64_t next_iplb;
} QEMU_PACKED;
typedef struct QemuIplParameters QemuIplParameters;
--
2.39.3

@ -0,0 +1,201 @@
From 36f64f38b39f2a2e0f0682f62f669d5e23074875 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Thu, 20 Jun 2024 16:59:28 +0200
Subject: [PATCH 06/38] hw/s390x: Remove the possibility to load the
s390-netboot.img binary
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [5/23] ff245b81b45ddd3a78343d1a8cfdd725a8255d87 (thuth/qemu-kvm-cs9)
Since the netboot code has now been merged into the main s390-ccw.img
binary, we don't need the separate s390-netboot.img anymore. Remove
it and the code that was responsible for loading it.
Message-Id: <20240621082422.136217-6-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 188e255bf8ed68fa64bcb63577cb100eeb326254)
---
hw/s390x/ipl.c | 55 --------------------------------------
hw/s390x/ipl.h | 12 +++------
hw/s390x/s390-virtio-ccw.c | 10 ++-----
pc-bios/meson.build | 1 -
4 files changed, 6 insertions(+), 72 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 9362de0b6f..8a0a3e6961 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -288,7 +288,6 @@ static Property s390_ipl_properties[] = {
DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
- DEFINE_PROP_STRING("netboot_fw", S390IPLState, netboot_fw),
DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration,
true),
@@ -480,56 +479,6 @@ int s390_ipl_set_loadparm(uint8_t *loadparm)
return -1;
}
-static int load_netboot_image(Error **errp)
-{
- MachineState *ms = MACHINE(qdev_get_machine());
- S390IPLState *ipl = get_ipl_device();
- char *netboot_filename;
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *mr = NULL;
- void *ram_ptr = NULL;
- int img_size = -1;
-
- mr = memory_region_find(sysmem, 0, 1).mr;
- if (!mr) {
- error_setg(errp, "Failed to find memory region at address 0");
- return -1;
- }
-
- ram_ptr = memory_region_get_ram_ptr(mr);
- if (!ram_ptr) {
- error_setg(errp, "No RAM found");
- goto unref_mr;
- }
-
- netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw);
- if (netboot_filename == NULL) {
- error_setg(errp, "Could not find network bootloader '%s'",
- ipl->netboot_fw);
- goto unref_mr;
- }
-
- img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL,
- &ipl->start_addr,
- NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL,
- false);
-
- if (img_size < 0) {
- img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size);
- ipl->start_addr = KERN_IMAGE_START;
- }
-
- if (img_size < 0) {
- error_setg(errp, "Failed to load network bootloader");
- }
-
- g_free(netboot_filename);
-
-unref_mr:
- memory_region_unref(mr);
- return img_size;
-}
-
static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb,
int virtio_id)
{
@@ -754,10 +703,6 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
ipl->iplb_valid = s390_gen_initial_iplb(ipl);
}
}
- if (ipl->netboot) {
- load_netboot_image(&error_fatal);
- ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr);
- }
s390_ipl_set_boot_menu(ipl);
s390_ipl_prepare_qipl(cpu);
}
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 57cd125769..b2105b616a 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -134,11 +134,8 @@ void s390_ipl_clear_reset_request(void);
/*
* The QEMU IPL Parameters will be stored at absolute address
* 204 (0xcc) which means it is 32-bit word aligned but not
- * double-word aligned.
- * Placement of data fields in this area must account for
- * their alignment needs. E.g., netboot_start_address must
- * have an offset of 4 + n * 8 bytes within the struct in order
- * to keep it double-word aligned.
+ * double-word aligned. Placement of 64-bit data fields in this
+ * area must account for their alignment needs.
* The total size of the struct must never exceed 28 bytes.
* This definition must be kept in sync with the definition
* in pc-bios/s390-ccw/iplb.h.
@@ -146,9 +143,9 @@ void s390_ipl_clear_reset_request(void);
struct QemuIplParameters {
uint8_t qipl_flags;
uint8_t reserved1[3];
- uint64_t netboot_start_addr;
+ uint64_t reserved2;
uint32_t boot_menu_timeout;
- uint8_t reserved2[12];
+ uint8_t reserved3[12];
} QEMU_PACKED;
typedef struct QemuIplParameters QemuIplParameters;
@@ -178,7 +175,6 @@ struct S390IPLState {
char *initrd;
char *cmdline;
char *firmware;
- char *netboot_fw;
uint8_t cssid;
uint8_t ssid;
uint16_t devno;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index b61392bac1..29a89a0c31 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -197,11 +197,10 @@ static void s390_memory_init(MemoryRegion *ram)
static void s390_init_ipl_dev(const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *firmware,
- const char *netboot_fw, bool enforce_bios)
+ bool enforce_bios)
{
Object *new = object_new(TYPE_S390_IPL);
DeviceState *dev = DEVICE(new);
- char *netboot_fw_prop;
if (kernel_filename) {
qdev_prop_set_string(dev, "kernel", kernel_filename);
@@ -212,11 +211,6 @@ static void s390_init_ipl_dev(const char *kernel_filename,
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
qdev_prop_set_string(dev, "firmware", firmware);
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
- netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort);
- if (!strlen(netboot_fw_prop)) {
- qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
- }
- g_free(netboot_fw_prop);
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
new);
object_unref(new);
@@ -284,7 +278,7 @@ static void ccw_init(MachineState *machine)
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
machine->initrd_filename,
machine->firmware ?: "s390-ccw.img",
- "s390-netboot.img", true);
+ true);
dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE);
object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index 8602b45b9b..ea85c54c86 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -66,7 +66,6 @@ blobs = [
'kvmvapic.bin',
'pvh.bin',
's390-ccw.img',
- 's390-netboot.img',
'slof.bin',
'skiboot.lid',
'palcode-clipper',
--
2.39.3

@ -0,0 +1,61 @@
From ce0d8bc163952ce177c37ea431cacf60889017f2 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Fri, 21 Jun 2024 10:24:17 +0200
Subject: [PATCH 02/38] hw/s390x/ipl: Provide more memory to the s390-ccw.img
firmware
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 278: Full boot order support for s390x [Centos 10]
RH-Jira: RHEL-58153
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/23] c33a2769b041e62285eb7840f8a7c05ac32aca7b (thuth/qemu-kvm-cs9)
We are going to link the SLOF libc into the s390-ccw.img, and this
libc needs more memory for providing space for malloc() and friends.
Thus bump the memory size that we reserve for the bios to 3 MiB
instead of only 2 MiB. While we're at it, add a proper check that
there is really enough memory assigned to the machine before blindly
using it.
Message-ID: <20240621082422.136217-3-thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit abaabb2e601adfe296a64471746a997eabcc607f)
---
hw/s390x/ipl.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index e934bf89d1..9362de0b6f 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -45,6 +45,7 @@
#define INITRD_PARM_START 0x010408UL
#define PARMFILE_START 0x001000UL
#define ZIPL_IMAGE_START 0x009000UL
+#define BIOS_MAX_SIZE 0x300000UL
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
static bool iplb_extended_needed(void *opaque)
@@ -144,7 +145,14 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* even if an external kernel has been defined.
*/
if (!ipl->kernel || ipl->enforce_bios) {
- uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;
+ uint64_t fwbase;
+
+ if (ms->ram_size < BIOS_MAX_SIZE) {
+ error_setg(errp, "not enough RAM to load the BIOS file");
+ return;
+ }
+
+ fwbase = (MIN(ms->ram_size, 0x80000000U) - BIOS_MAX_SIZE) & ~0xffffUL;
bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware);
if (bios_filename == NULL) {
--
2.39.3

@ -1,108 +0,0 @@
From c554f8768a18ceba173aedbd582c1cae43a41e2c Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Tue, 18 Jun 2024 14:19:58 +0200
Subject: [PATCH 1/2] hw/virtio: Fix the de-initialization of vhost-user
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Thomas Huth <thuth@redhat.com>
RH-MergeRequest: 255: hw/virtio: Fix the de-initialization of vhost-user devices
RH-Jira: RHEL-40708
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] c7815a249ec135993f45934cab1c1f2c038b80ea (thuth/qemu-kvm-cs9)
JIRA: https://issues.redhat.com/browse/RHEL-40708
The unrealize functions of the various vhost-user devices are
calling the corresponding vhost_*_set_status() functions with a
status of 0 to shut down the device correctly.
Now these vhost_*_set_status() functions all follow this scheme:
bool should_start = virtio_device_should_start(vdev, status);
if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) {
return;
}
if (should_start) {
/* ... do the initialization stuff ... */
} else {
/* ... do the cleanup stuff ... */
}
The problem here is virtio_device_should_start(vdev, 0) currently
always returns "true" since it internally only looks at vdev->started
instead of looking at the "status" parameter. Thus once the device
got started once, virtio_device_should_start() always returns true
and thus the vhost_*_set_status() functions return early, without
ever doing any clean-up when being called with status == 0. This
causes e.g. problems when trying to hot-plug and hot-unplug a vhost
user devices multiple times since the de-initialization step is
completely skipped during the unplug operation.
This bug has been introduced in commit 9f6bcfd99f ("hw/virtio: move
vm_running check to virtio_device_started") which replaced
should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
with
should_start = virtio_device_started(vdev, status);
which later got replaced by virtio_device_should_start(). This blocked
the possibility to set should_start to false in case the status flag
VIRTIO_CONFIG_S_DRIVER_OK was not set.
Fix it by adjusting the virtio_device_should_start() function to
only consider the status flag instead of vdev->started. Since this
function is only used in the various vhost_*_set_status() functions
for exactly the same purpose, it should be fine to fix it in this
central place there without any risk to change the behavior of other
code.
Fixes: 9f6bcfd99f ("hw/virtio: move vm_running check to virtio_device_started")
Buglink: https://issues.redhat.com/browse/RHEL-40708
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20240618121958.88673-1-thuth@redhat.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit d72479b11797c28893e1e3fc565497a9cae5ca16)
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
include/hw/virtio/virtio.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 7d5ffdc145..2eafad17b8 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -470,9 +470,9 @@ static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status)
* @vdev - the VirtIO device
* @status - the devices status bits
*
- * This is similar to virtio_device_started() but also encapsulates a
- * check on the VM status which would prevent a device starting
- * anyway.
+ * This is similar to virtio_device_started() but ignores vdev->started
+ * and also encapsulates a check on the VM status which would prevent a
+ * device from starting anyway.
*/
static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status)
{
@@ -480,7 +480,7 @@ static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status
return false;
}
- return virtio_device_started(vdev, status);
+ return status & VIRTIO_CONFIG_S_DRIVER_OK;
}
static inline void virtio_set_started(VirtIODevice *vdev, bool started)
--
2.39.3

@ -1,68 +0,0 @@
From f572a40924c7138072e387111d0f092185972477 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 9 May 2024 19:00:39 +0200
Subject: [PATCH 044/100] i386: correctly select code in hw/i386 that depends
on other components
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [44/91] 1327a5eb2b91edacf56cc4e93255cad456abbbeb (bonzini/rhel-qemu-kvm)
fw_cfg.c and vapic.c are currently included unconditionally but
depend on other components. vapic.c depends on the local APIC,
while fw_cfg.c includes a piece of AML builder code that depends
on CONFIG_ACPI.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20240509170044.190795-9-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7974e51342775c87f6e759a8c525db1045ddfa24)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/fw_cfg.c | 2 ++
hw/i386/meson.build | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index 283c3f4c16..7f97d40616 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -204,6 +204,7 @@ void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg)
fw_cfg_add_file(fw_cfg, "etc/msr_feature_control", val, sizeof(*val));
}
+#ifdef CONFIG_ACPI
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg)
{
/*
@@ -230,3 +231,4 @@ void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg)
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(scope, dev);
}
+#endif
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index d8b70ef3e9..d9da676038 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -1,12 +1,12 @@
i386_ss = ss.source_set()
i386_ss.add(files(
'fw_cfg.c',
- 'vapic.c',
'e820_memory_layout.c',
'multiboot.c',
'x86.c',
))
+i386_ss.add(when: 'CONFIG_APIC', if_true: files('vapic.c'))
i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'),
if_false: files('x86-iommu-stub.c'))
i386_ss.add(when: 'CONFIG_AMD_IOMMU', if_true: files('amd_iommu.c'),
--
2.39.3

@ -1,40 +0,0 @@
From 127f3c60668e1bd08ec00856a317cb841adf0440 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:23 -0500
Subject: [PATCH 063/100] i386/cpu: Set SEV-SNP CPUID bit when SNP enabled
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [63/91] 0f834a6897c5cdc0e29a5b1862e621f8ce309657 (bonzini/rhel-qemu-kvm)
SNP guests will rely on this bit to determine certain feature support.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-12-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7831221941cccbde922412c1550ed8b4bce7c361)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 489c853b42..13737cd703 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6822,6 +6822,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
if (sev_enabled()) {
*eax = 0x2;
*eax |= sev_es_enabled() ? 0x8 : 0;
+ *eax |= sev_snp_enabled() ? 0x10 : 0;
*ebx = sev_get_cbit_position() & 0x3f; /* EBX[5:0] */
*ebx |= (sev_get_reduced_phys_bits() & 0x3f) << 6; /* EBX[11:6] */
}
--
2.39.3

@ -1,145 +0,0 @@
From 14aa42bbacde75b2ce9a59d1267f73d613026461 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:42 -0500
Subject: [PATCH 076/100] i386/kvm: Add KVM_EXIT_HYPERCALL handling for
KVM_HC_MAP_GPA_RANGE
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [76/91] 3e1201c330dc826af1ec4650974d47053270eb16 (bonzini/rhel-qemu-kvm)
KVM_HC_MAP_GPA_RANGE will be used to send requests to userspace for
private/shared memory attribute updates requested by the guest.
Implement handling for that use-case along with some basic
infrastructure for enabling specific hypercall events.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-31-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 47e76d03b155e43beca550251a6eb7ea926c059f)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm/kvm.c | 55 ++++++++++++++++++++++++++++++++++++
target/i386/kvm/kvm_i386.h | 1 +
target/i386/kvm/trace-events | 1 +
3 files changed, 57 insertions(+)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 75e75d9772..2935e3931a 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -21,6 +21,7 @@
#include <sys/syscall.h>
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#include "standard-headers/asm-x86/kvm_para.h"
#include "hw/xen/interface/arch-x86/cpuid.h"
@@ -208,6 +209,13 @@ int kvm_get_vm_type(MachineState *ms)
return kvm_type;
}
+bool kvm_enable_hypercall(uint64_t enable_mask)
+{
+ KVMState *s = KVM_STATE(current_accel());
+
+ return !kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, enable_mask);
+}
+
bool kvm_has_smm(void)
{
return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM);
@@ -5325,6 +5333,50 @@ static bool host_supports_vmx(void)
return ecx & CPUID_EXT_VMX;
}
+/*
+ * Currently the handling here only supports use of KVM_HC_MAP_GPA_RANGE
+ * to service guest-initiated memory attribute update requests so that
+ * KVM_SET_MEMORY_ATTRIBUTES can update whether or not a page should be
+ * backed by the private memory pool provided by guest_memfd, and as such
+ * is only applicable to guest_memfd-backed guests (e.g. SNP/TDX).
+ *
+ * Other other use-cases for KVM_HC_MAP_GPA_RANGE, such as for SEV live
+ * migration, are not implemented here currently.
+ *
+ * For the guest_memfd use-case, these exits will generally be synthesized
+ * by KVM based on platform-specific hypercalls, like GHCB requests in the
+ * case of SEV-SNP, and not issued directly within the guest though the
+ * KVM_HC_MAP_GPA_RANGE hypercall. So in this case, KVM_HC_MAP_GPA_RANGE is
+ * not actually advertised to guests via the KVM CPUID feature bit, as
+ * opposed to SEV live migration where it would be. Since it is unlikely the
+ * SEV live migration use-case would be useful for guest-memfd backed guests,
+ * because private/shared page tracking is already provided through other
+ * means, these 2 use-cases should be treated as being mutually-exclusive.
+ */
+static int kvm_handle_hc_map_gpa_range(struct kvm_run *run)
+{
+ uint64_t gpa, size, attributes;
+
+ if (!machine_require_guest_memfd(current_machine))
+ return -EINVAL;
+
+ gpa = run->hypercall.args[0];
+ size = run->hypercall.args[1] * TARGET_PAGE_SIZE;
+ attributes = run->hypercall.args[2];
+
+ trace_kvm_hc_map_gpa_range(gpa, size, attributes, run->hypercall.flags);
+
+ return kvm_convert_memory(gpa, size, attributes & KVM_MAP_GPA_RANGE_ENCRYPTED);
+}
+
+static int kvm_handle_hypercall(struct kvm_run *run)
+{
+ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE)
+ return kvm_handle_hc_map_gpa_range(run);
+
+ return -EINVAL;
+}
+
#define VMX_INVALID_GUEST_STATE 0x80000021
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
@@ -5420,6 +5472,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = kvm_xen_handle_exit(cpu, &run->xen);
break;
#endif
+ case KVM_EXIT_HYPERCALL:
+ ret = kvm_handle_hypercall(run);
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 6b44844d95..34fc60774b 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -33,6 +33,7 @@
bool kvm_has_smm(void);
bool kvm_enable_x2apic(void);
bool kvm_hv_vpindex_settable(void);
+bool kvm_enable_hypercall(uint64_t enable_mask);
bool kvm_enable_sgx_provisioning(KVMState *s);
bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp);
diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events
index b365a8e8e2..74a6234ff7 100644
--- a/target/i386/kvm/trace-events
+++ b/target/i386/kvm/trace-events
@@ -5,6 +5,7 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %"
kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
+kvm_hc_map_gpa_range(uint64_t gpa, uint64_t size, uint64_t attributes, uint64_t flags) "gpa 0x%" PRIx64 " size 0x%" PRIx64 " attributes 0x%" PRIx64 " flags 0x%" PRIx64
# xen-emu.c
kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64
--
2.39.3

@ -1,536 +0,0 @@
From 5ead79f45e8e90b7a04586c89e70cb9d0b66b730 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <sean.j.christopherson@intel.com>
Date: Thu, 29 Feb 2024 01:36:43 -0500
Subject: [PATCH 004/100] i386/kvm: Move architectural CPUID leaf generation to
separate helper
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [4/91] 06ecdbcf05ad3d658273980b114f02477d0b0475 (bonzini/rhel-qemu-kvm)
Move the architectural (for lack of a better term) CPUID leaf generation
to a separate helper so that the generation code can be reused by TDX,
which needs to generate a canonical VM-scoped configuration.
For now this is just a cleanup, so keep the function static.
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-ID: <20240229063726.610065-23-xiaoyao.li@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a5acf4f26c208a05d05ef1bde65553ce2ab5e5d0)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm/kvm.c | 417 +++++++++++++++++++++---------------------
1 file changed, 211 insertions(+), 206 deletions(-)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 739f33db47..5f30b649a0 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1706,195 +1706,22 @@ static void kvm_init_nested_state(CPUX86State *env)
}
}
-int kvm_arch_init_vcpu(CPUState *cs)
+static uint32_t kvm_x86_build_cpuid(CPUX86State *env,
+ struct kvm_cpuid_entry2 *entries,
+ uint32_t cpuid_i)
{
- struct {
- struct kvm_cpuid2 cpuid;
- struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
- } cpuid_data;
- /*
- * The kernel defines these structs with padding fields so there
- * should be no extra padding in our cpuid_data struct.
- */
- QEMU_BUILD_BUG_ON(sizeof(cpuid_data) !=
- sizeof(struct kvm_cpuid2) +
- sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES);
-
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
- uint32_t limit, i, j, cpuid_i;
+ uint32_t limit, i, j;
uint32_t unused;
struct kvm_cpuid_entry2 *c;
- uint32_t signature[3];
- int kvm_base = KVM_CPUID_SIGNATURE;
- int max_nested_state_len;
- int r;
- Error *local_err = NULL;
-
- memset(&cpuid_data, 0, sizeof(cpuid_data));
-
- cpuid_i = 0;
-
- has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2);
-
- r = kvm_arch_set_tsc_khz(cs);
- if (r < 0) {
- return r;
- }
-
- /* vcpu's TSC frequency is either specified by user, or following
- * the value used by KVM if the former is not present. In the
- * latter case, we query it from KVM and record in env->tsc_khz,
- * so that vcpu's TSC frequency can be migrated later via this field.
- */
- if (!env->tsc_khz) {
- r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
- kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
- -ENOTSUP;
- if (r > 0) {
- env->tsc_khz = r;
- }
- }
-
- env->apic_bus_freq = KVM_APIC_BUS_FREQUENCY;
-
- /*
- * kvm_hyperv_expand_features() is called here for the second time in case
- * KVM_CAP_SYS_HYPERV_CPUID is not supported. While we can't possibly handle
- * 'query-cpu-model-expansion' in this case as we don't have a KVM vCPU to
- * check which Hyper-V enlightenments are supported and which are not, we
- * can still proceed and check/expand Hyper-V enlightenments here so legacy
- * behavior is preserved.
- */
- if (!kvm_hyperv_expand_features(cpu, &local_err)) {
- error_report_err(local_err);
- return -ENOSYS;
- }
-
- if (hyperv_enabled(cpu)) {
- r = hyperv_init_vcpu(cpu);
- if (r) {
- return r;
- }
-
- cpuid_i = hyperv_fill_cpuids(cs, cpuid_data.entries);
- kvm_base = KVM_CPUID_SIGNATURE_NEXT;
- has_msr_hv_hypercall = true;
- }
-
- if (cs->kvm_state->xen_version) {
-#ifdef CONFIG_XEN_EMU
- struct kvm_cpuid_entry2 *xen_max_leaf;
-
- memcpy(signature, "XenVMMXenVMM", 12);
-
- xen_max_leaf = c = &cpuid_data.entries[cpuid_i++];
- c->function = kvm_base + XEN_CPUID_SIGNATURE;
- c->eax = kvm_base + XEN_CPUID_TIME;
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
-
- c = &cpuid_data.entries[cpuid_i++];
- c->function = kvm_base + XEN_CPUID_VENDOR;
- c->eax = cs->kvm_state->xen_version;
- c->ebx = 0;
- c->ecx = 0;
- c->edx = 0;
-
- c = &cpuid_data.entries[cpuid_i++];
- c->function = kvm_base + XEN_CPUID_HVM_MSR;
- /* Number of hypercall-transfer pages */
- c->eax = 1;
- /* Hypercall MSR base address */
- if (hyperv_enabled(cpu)) {
- c->ebx = XEN_HYPERCALL_MSR_HYPERV;
- kvm_xen_init(cs->kvm_state, c->ebx);
- } else {
- c->ebx = XEN_HYPERCALL_MSR;
- }
- c->ecx = 0;
- c->edx = 0;
-
- c = &cpuid_data.entries[cpuid_i++];
- c->function = kvm_base + XEN_CPUID_TIME;
- c->eax = ((!!tsc_is_stable_and_known(env) << 1) |
- (!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << 2));
- /* default=0 (emulate if necessary) */
- c->ebx = 0;
- /* guest tsc frequency */
- c->ecx = env->user_tsc_khz;
- /* guest tsc incarnation (migration count) */
- c->edx = 0;
-
- c = &cpuid_data.entries[cpuid_i++];
- c->function = kvm_base + XEN_CPUID_HVM;
- xen_max_leaf->eax = kvm_base + XEN_CPUID_HVM;
- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 5)) {
- c->function = kvm_base + XEN_CPUID_HVM;
-
- if (cpu->xen_vapic) {
- c->eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT;
- c->eax |= XEN_HVM_CPUID_X2APIC_VIRT;
- }
-
- c->eax |= XEN_HVM_CPUID_IOMMU_MAPPINGS;
-
- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 6)) {
- c->eax |= XEN_HVM_CPUID_VCPU_ID_PRESENT;
- c->ebx = cs->cpu_index;
- }
-
- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 17)) {
- c->eax |= XEN_HVM_CPUID_UPCALL_VECTOR;
- }
- }
-
- r = kvm_xen_init_vcpu(cs);
- if (r) {
- return r;
- }
-
- kvm_base += 0x100;
-#else /* CONFIG_XEN_EMU */
- /* This should never happen as kvm_arch_init() would have died first. */
- fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n");
- abort();
-#endif
- } else if (cpu->expose_kvm) {
- memcpy(signature, "KVMKVMKVM\0\0\0", 12);
- c = &cpuid_data.entries[cpuid_i++];
- c->function = KVM_CPUID_SIGNATURE | kvm_base;
- c->eax = KVM_CPUID_FEATURES | kvm_base;
- c->ebx = signature[0];
- c->ecx = signature[1];
- c->edx = signature[2];
-
- c = &cpuid_data.entries[cpuid_i++];
- c->function = KVM_CPUID_FEATURES | kvm_base;
- c->eax = env->features[FEAT_KVM];
- c->edx = env->features[FEAT_KVM_HINTS];
- }
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
- if (cpu->kvm_pv_enforce_cpuid) {
- r = kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0, 1);
- if (r < 0) {
- fprintf(stderr,
- "failed to enable KVM_CAP_ENFORCE_PV_FEATURE_CPUID: %s",
- strerror(-r));
- abort();
- }
- }
-
for (i = 0; i <= limit; i++) {
+ j = 0;
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "unsupported level value: 0x%x\n", limit);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
-
+ c = &entries[cpuid_i++];
switch (i) {
case 2: {
/* Keep reading function 2 till all the input is received */
@@ -1908,11 +1735,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
for (j = 1; j < times; ++j) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "cpuid_data is full, no space for "
- "cpuid(eax:2):eax & 0xf = 0x%x\n", times);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
c->function = i;
c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC;
cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
@@ -1951,11 +1776,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
continue;
}
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "cpuid_data is full, no space for "
- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
}
break;
case 0x12:
@@ -1970,11 +1793,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "cpuid_data is full, no space for "
- "cpuid(eax:0x12,ecx:0x%x)\n", j);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
}
break;
case 0x7:
@@ -1991,11 +1812,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
for (j = 1; j <= times; ++j) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "cpuid_data is full, no space for "
- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
c->function = i;
c->index = j;
c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
@@ -2048,11 +1867,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
for (i = 0x80000000; i <= limit; i++) {
+ j = 0;
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
switch (i) {
case 0x8000001d:
@@ -2067,11 +1886,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
break;
}
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "cpuid_data is full, no space for "
- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
}
break;
default:
@@ -2094,11 +1911,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused);
for (i = 0xC0000000; i <= limit; i++) {
+ j = 0;
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
- fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit);
- abort();
+ goto full;
}
- c = &cpuid_data.entries[cpuid_i++];
+ c = &entries[cpuid_i++];
c->function = i;
c->flags = 0;
@@ -2106,6 +1923,194 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
}
+ return cpuid_i;
+
+full:
+ fprintf(stderr, "cpuid_data is full, no space for "
+ "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
+ abort();
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+ struct {
+ struct kvm_cpuid2 cpuid;
+ struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
+ } cpuid_data;
+ /*
+ * The kernel defines these structs with padding fields so there
+ * should be no extra padding in our cpuid_data struct.
+ */
+ QEMU_BUILD_BUG_ON(sizeof(cpuid_data) !=
+ sizeof(struct kvm_cpuid2) +
+ sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES);
+
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ uint32_t cpuid_i;
+ struct kvm_cpuid_entry2 *c;
+ uint32_t signature[3];
+ int kvm_base = KVM_CPUID_SIGNATURE;
+ int max_nested_state_len;
+ int r;
+ Error *local_err = NULL;
+
+ memset(&cpuid_data, 0, sizeof(cpuid_data));
+
+ cpuid_i = 0;
+
+ has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2);
+
+ r = kvm_arch_set_tsc_khz(cs);
+ if (r < 0) {
+ return r;
+ }
+
+ /* vcpu's TSC frequency is either specified by user, or following
+ * the value used by KVM if the former is not present. In the
+ * latter case, we query it from KVM and record in env->tsc_khz,
+ * so that vcpu's TSC frequency can be migrated later via this field.
+ */
+ if (!env->tsc_khz) {
+ r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+ kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
+ -ENOTSUP;
+ if (r > 0) {
+ env->tsc_khz = r;
+ }
+ }
+
+ env->apic_bus_freq = KVM_APIC_BUS_FREQUENCY;
+
+ /*
+ * kvm_hyperv_expand_features() is called here for the second time in case
+ * KVM_CAP_SYS_HYPERV_CPUID is not supported. While we can't possibly handle
+ * 'query-cpu-model-expansion' in this case as we don't have a KVM vCPU to
+ * check which Hyper-V enlightenments are supported and which are not, we
+ * can still proceed and check/expand Hyper-V enlightenments here so legacy
+ * behavior is preserved.
+ */
+ if (!kvm_hyperv_expand_features(cpu, &local_err)) {
+ error_report_err(local_err);
+ return -ENOSYS;
+ }
+
+ if (hyperv_enabled(cpu)) {
+ r = hyperv_init_vcpu(cpu);
+ if (r) {
+ return r;
+ }
+
+ cpuid_i = hyperv_fill_cpuids(cs, cpuid_data.entries);
+ kvm_base = KVM_CPUID_SIGNATURE_NEXT;
+ has_msr_hv_hypercall = true;
+ }
+
+ if (cs->kvm_state->xen_version) {
+#ifdef CONFIG_XEN_EMU
+ struct kvm_cpuid_entry2 *xen_max_leaf;
+
+ memcpy(signature, "XenVMMXenVMM", 12);
+
+ xen_max_leaf = c = &cpuid_data.entries[cpuid_i++];
+ c->function = kvm_base + XEN_CPUID_SIGNATURE;
+ c->eax = kvm_base + XEN_CPUID_TIME;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = kvm_base + XEN_CPUID_VENDOR;
+ c->eax = cs->kvm_state->xen_version;
+ c->ebx = 0;
+ c->ecx = 0;
+ c->edx = 0;
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = kvm_base + XEN_CPUID_HVM_MSR;
+ /* Number of hypercall-transfer pages */
+ c->eax = 1;
+ /* Hypercall MSR base address */
+ if (hyperv_enabled(cpu)) {
+ c->ebx = XEN_HYPERCALL_MSR_HYPERV;
+ kvm_xen_init(cs->kvm_state, c->ebx);
+ } else {
+ c->ebx = XEN_HYPERCALL_MSR;
+ }
+ c->ecx = 0;
+ c->edx = 0;
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = kvm_base + XEN_CPUID_TIME;
+ c->eax = ((!!tsc_is_stable_and_known(env) << 1) |
+ (!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << 2));
+ /* default=0 (emulate if necessary) */
+ c->ebx = 0;
+ /* guest tsc frequency */
+ c->ecx = env->user_tsc_khz;
+ /* guest tsc incarnation (migration count) */
+ c->edx = 0;
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = kvm_base + XEN_CPUID_HVM;
+ xen_max_leaf->eax = kvm_base + XEN_CPUID_HVM;
+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 5)) {
+ c->function = kvm_base + XEN_CPUID_HVM;
+
+ if (cpu->xen_vapic) {
+ c->eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT;
+ c->eax |= XEN_HVM_CPUID_X2APIC_VIRT;
+ }
+
+ c->eax |= XEN_HVM_CPUID_IOMMU_MAPPINGS;
+
+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 6)) {
+ c->eax |= XEN_HVM_CPUID_VCPU_ID_PRESENT;
+ c->ebx = cs->cpu_index;
+ }
+
+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 17)) {
+ c->eax |= XEN_HVM_CPUID_UPCALL_VECTOR;
+ }
+ }
+
+ r = kvm_xen_init_vcpu(cs);
+ if (r) {
+ return r;
+ }
+
+ kvm_base += 0x100;
+#else /* CONFIG_XEN_EMU */
+ /* This should never happen as kvm_arch_init() would have died first. */
+ fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n");
+ abort();
+#endif
+ } else if (cpu->expose_kvm) {
+ memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = KVM_CPUID_SIGNATURE | kvm_base;
+ c->eax = KVM_CPUID_FEATURES | kvm_base;
+ c->ebx = signature[0];
+ c->ecx = signature[1];
+ c->edx = signature[2];
+
+ c = &cpuid_data.entries[cpuid_i++];
+ c->function = KVM_CPUID_FEATURES | kvm_base;
+ c->eax = env->features[FEAT_KVM];
+ c->edx = env->features[FEAT_KVM_HINTS];
+ }
+
+ if (cpu->kvm_pv_enforce_cpuid) {
+ r = kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0, 1);
+ if (r < 0) {
+ fprintf(stderr,
+ "failed to enable KVM_CAP_ENFORCE_PV_FEATURE_CPUID: %s",
+ strerror(-r));
+ abort();
+ }
+ }
+
+ cpuid_i = kvm_x86_build_cpuid(env, cpuid_data.entries, cpuid_i);
cpuid_data.cpuid.nent = cpuid_i;
if (((env->cpuid_version >> 8)&0xF) >= 6
--
2.39.3

@ -1,91 +0,0 @@
From 03e275023b482ac79b4f92ca4ceef6de3caa634f Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 9 May 2024 19:00:40 +0200
Subject: [PATCH 045/100] i386: pc: remove unnecessary MachineClass overrides
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [45/91] c03d5b57014d0d02f6ce0cdfb19a34996d100dea (bonzini/rhel-qemu-kvm)
There is no need to override these fields of MachineClass because they are
already set to the right value in the superclass.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <20240509170044.190795-10-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b348fdcdac9f9fc70be9ae56c54e41765e9aae24)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/pc.c | 3 ---
hw/i386/x86.c | 6 +++---
include/hw/i386/x86.h | 4 ----
3 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 660a59c63b..0aca0cc79e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1979,9 +1979,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
mc->async_pf_vmexit_disable = false;
mc->get_hotplug_handler = pc_get_hotplug_handler;
mc->hotplug_allowed = pc_hotplug_allowed;
- mc->cpu_index_to_instance_props = x86_cpu_index_to_props;
- mc->get_default_cpu_node_id = x86_get_default_cpu_node_id;
- mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
mc->auto_enable_numa_with_memhp = true;
mc->auto_enable_numa_with_memdev = true;
mc->has_hotpluggable_cpus = true;
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index c61f4ebfa6..fcef652c1e 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -443,7 +443,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
numa_cpu_pre_plug(cpu_slot, dev, errp);
}
-CpuInstanceProperties
+static CpuInstanceProperties
x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -453,7 +453,7 @@ x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
return possible_cpus->cpus[cpu_index].props;
}
-int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx)
+static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx)
{
X86CPUTopoIDs topo_ids;
X86MachineState *x86ms = X86_MACHINE(ms);
@@ -467,7 +467,7 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx)
return topo_ids.pkg_id % ms->numa_state->num_nodes;
}
-const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
+static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
{
X86MachineState *x86ms = X86_MACHINE(ms);
unsigned int max_cpus = ms->smp.max_cpus;
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index d7b7d3f3ce..c2062db13f 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -114,10 +114,6 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms,
void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, Error **errp);
void x86_cpus_init(X86MachineState *pcms, int default_cpu_version);
-CpuInstanceProperties x86_cpu_index_to_props(MachineState *ms,
- unsigned cpu_index);
-int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx);
-const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms);
CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx);
void x86_rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count);
void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
--
2.39.3

@ -1,116 +0,0 @@
From 652793962000d6906e219ceae36348a476b78c28 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 31 May 2024 12:44:44 +0200
Subject: [PATCH 065/100] i386/sev: Add a class method to determine KVM VM type
for SNP guests
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [65/91] c6cbeac0a6f691138df212b80efaa9b1143fdaa8 (bonzini/rhel-qemu-kvm)
SEV guests can use either KVM_X86_DEFAULT_VM, KVM_X86_SEV_VM,
or KVM_X86_SEV_ES_VM depending on the configuration and what
the host kernel supports. SNP guests on the other hand can only
ever use KVM_X86_SNP_VM, so split determination of VM type out
into a separate class method that can be set accordingly for
sev-guest vs. sev-snp-guest objects and add handling for SNP.
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-14-pankaj.gupta@amd.com>
[Remove unnecessary function pointer declaration. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a808132f6d8e855bd83a400570ec91d2e00bebe3)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm/kvm.c | 1 +
target/i386/sev.c | 15 ++++++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 408568d053..75e75d9772 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -166,6 +166,7 @@ static const char *vm_type_name[] = {
[KVM_X86_DEFAULT_VM] = "default",
[KVM_X86_SEV_VM] = "SEV",
[KVM_X86_SEV_ES_VM] = "SEV-ES",
+ [KVM_X86_SNP_VM] = "SEV-SNP",
};
bool kvm_is_vm_type_supported(int type)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index c3daaf1ad5..072cc4f853 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -885,6 +885,11 @@ out:
return sev_common->kvm_type;
}
+static int sev_snp_kvm_type(X86ConfidentialGuest *cg)
+{
+ return KVM_X86_SNP_VM;
+}
+
static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
{
char *devname;
@@ -894,6 +899,8 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
struct sev_user_data_status status = {};
SevCommonState *sev_common = SEV_COMMON(cgs);
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
+ X86ConfidentialGuestClass *x86_klass =
+ X86_CONFIDENTIAL_GUEST_GET_CLASS(cgs);
sev_common->state = SEV_STATE_UNINIT;
@@ -964,7 +971,7 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
}
trace_kvm_sev_init();
- if (sev_kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) {
+ if (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) {
cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT;
ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error);
@@ -1441,10 +1448,8 @@ static void
sev_common_class_init(ObjectClass *oc, void *data)
{
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
- X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
klass->kvm_init = sev_common_kvm_init;
- x86_klass->kvm_type = sev_kvm_type;
object_class_property_add_str(oc, "sev-device",
sev_common_get_sev_device,
@@ -1529,10 +1534,12 @@ static void
sev_guest_class_init(ObjectClass *oc, void *data)
{
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
+ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
klass->launch_start = sev_launch_start;
klass->launch_finish = sev_launch_finish;
klass->kvm_init = sev_kvm_init;
+ x86_klass->kvm_type = sev_kvm_type;
object_class_property_add_str(oc, "dh-cert-file",
sev_guest_get_dh_cert_file,
@@ -1770,8 +1777,10 @@ static void
sev_snp_guest_class_init(ObjectClass *oc, void *data)
{
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
+ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
klass->kvm_init = sev_snp_kvm_init;
+ x86_klass->kvm_type = sev_snp_kvm_type;
object_class_property_add(oc, "policy", "uint64",
sev_snp_guest_get_policy,
--
2.39.3

@ -1,84 +0,0 @@
From 82a714b79851b5c2d1389d2fa7a01548c486a854 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:20 -0500
Subject: [PATCH 060/100] i386/sev: Add a sev_snp_enabled() helper
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [60/91] c35ead095028ccfb1e1be0fe010ca4f7688530a0 (bonzini/rhel-qemu-kvm)
Add a simple helper to check if the current guest type is SNP. Also have
SNP-enabled imply that SEV-ES is enabled as well, and fix up any places
where the sev_es_enabled() check is expecting a pure/non-SNP guest.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-9-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 99190f805dca9475fe244fbd8041961842657dc2)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 13 ++++++++++++-
target/i386/sev.h | 2 ++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index a81b3228d4..4edfedc139 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -325,12 +325,21 @@ sev_enabled(void)
return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON);
}
+bool
+sev_snp_enabled(void)
+{
+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
+
+ return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_SNP_GUEST);
+}
+
bool
sev_es_enabled(void)
{
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
- return sev_enabled() && (SEV_GUEST(cgs)->policy & SEV_POLICY_ES);
+ return sev_snp_enabled() ||
+ (sev_enabled() && SEV_GUEST(cgs)->policy & SEV_POLICY_ES);
}
uint32_t
@@ -946,7 +955,9 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
"support", __func__);
goto err;
}
+ }
+ if (sev_es_enabled() && !sev_snp_enabled()) {
if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
error_setg(errp, "%s: guest policy requires SEV-ES, but "
"host SEV-ES support unavailable",
diff --git a/target/i386/sev.h b/target/i386/sev.h
index bedc667eeb..94295ee74f 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -45,9 +45,11 @@ typedef struct SevKernelLoaderContext {
#ifdef CONFIG_SEV
bool sev_enabled(void);
bool sev_es_enabled(void);
+bool sev_snp_enabled(void);
#else
#define sev_enabled() 0
#define sev_es_enabled() 0
+#define sev_snp_enabled() 0
#endif
uint32_t sev_get_cbit_position(void);
--
2.39.3

@ -1,187 +0,0 @@
From 0e435819540b0d39da2c828aacc0f35ecaadbdf6 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:28 -0500
Subject: [PATCH 068/100] i386/sev: Add handling to encrypt/finalize guest
launch data
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [68/91] fe77931d279aa8df061823da88a320fb5f72ffea (bonzini/rhel-qemu-kvm)
Process any queued up launch data and encrypt/measure it into the SNP
guest instance prior to initial guest launch.
This also updates the KVM_SEV_SNP_LAUNCH_UPDATE call to handle partial
update responses.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-17-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9f3a6999f9730a694d7db448a99f9c9cb6515992)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 112 ++++++++++++++++++++++++++++++++++++++-
target/i386/trace-events | 2 +
2 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index e89b87d2f5..ef2e592ca7 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -756,6 +756,76 @@ out:
return ret;
}
+static const char *
+snp_page_type_to_str(int type)
+{
+ switch (type) {
+ case KVM_SEV_SNP_PAGE_TYPE_NORMAL: return "Normal";
+ case KVM_SEV_SNP_PAGE_TYPE_ZERO: return "Zero";
+ case KVM_SEV_SNP_PAGE_TYPE_UNMEASURED: return "Unmeasured";
+ case KVM_SEV_SNP_PAGE_TYPE_SECRETS: return "Secrets";
+ case KVM_SEV_SNP_PAGE_TYPE_CPUID: return "Cpuid";
+ default: return "unknown";
+ }
+}
+
+static int
+sev_snp_launch_update(SevSnpGuestState *sev_snp_guest,
+ SevLaunchUpdateData *data)
+{
+ int ret, fw_error;
+ struct kvm_sev_snp_launch_update update = {0};
+
+ if (!data->hva || !data->len) {
+ error_report("SNP_LAUNCH_UPDATE called with invalid address"
+ "/ length: %p / %lx",
+ data->hva, data->len);
+ return 1;
+ }
+
+ update.uaddr = (__u64)(unsigned long)data->hva;
+ update.gfn_start = data->gpa >> TARGET_PAGE_BITS;
+ update.len = data->len;
+ update.type = data->type;
+
+ /*
+ * KVM_SEV_SNP_LAUNCH_UPDATE requires that GPA ranges have the private
+ * memory attribute set in advance.
+ */
+ ret = kvm_set_memory_attributes_private(data->gpa, data->len);
+ if (ret) {
+ error_report("SEV-SNP: failed to configure initial"
+ "private guest memory");
+ goto out;
+ }
+
+ while (update.len || ret == -EAGAIN) {
+ trace_kvm_sev_snp_launch_update(update.uaddr, update.gfn_start <<
+ TARGET_PAGE_BITS, update.len,
+ snp_page_type_to_str(update.type));
+
+ ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd,
+ KVM_SEV_SNP_LAUNCH_UPDATE,
+ &update, &fw_error);
+ if (ret && ret != -EAGAIN) {
+ error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
+ ret, fw_error, fw_error_to_str(fw_error));
+ break;
+ }
+ }
+
+out:
+ if (!ret && update.gfn_start << TARGET_PAGE_BITS != data->gpa + data->len) {
+ error_report("SEV-SNP: expected update of GPA range %lx-%lx,"
+ "got GPA range %lx-%llx",
+ data->gpa, data->gpa + data->len, data->gpa,
+ update.gfn_start << TARGET_PAGE_BITS);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
static int
sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len)
{
@@ -901,6 +971,46 @@ sev_launch_finish(SevCommonState *sev_common)
migrate_add_blocker(&sev_mig_blocker, &error_fatal);
}
+static void
+sev_snp_launch_finish(SevCommonState *sev_common)
+{
+ int ret, error;
+ Error *local_err = NULL;
+ SevLaunchUpdateData *data;
+ SevSnpGuestState *sev_snp = SEV_SNP_GUEST(sev_common);
+ struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf;
+
+ QTAILQ_FOREACH(data, &launch_update, next) {
+ ret = sev_snp_launch_update(sev_snp, data);
+ if (ret) {
+ exit(1);
+ }
+ }
+
+ trace_kvm_sev_snp_launch_finish(sev_snp->id_block, sev_snp->id_auth,
+ sev_snp->host_data);
+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_FINISH,
+ finish, &error);
+ if (ret) {
+ error_report("SNP_LAUNCH_FINISH ret=%d fw_error=%d '%s'",
+ ret, error, fw_error_to_str(error));
+ exit(1);
+ }
+
+ sev_set_guest_state(sev_common, SEV_STATE_RUNNING);
+
+ /* add migration blocker */
+ error_setg(&sev_mig_blocker,
+ "SEV-SNP: Migration is not implemented");
+ ret = migrate_add_blocker(&sev_mig_blocker, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ error_free(sev_mig_blocker);
+ exit(1);
+ }
+}
+
+
static void
sev_vm_state_change(void *opaque, bool running, RunState state)
{
@@ -1832,10 +1942,10 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
klass->launch_start = sev_snp_launch_start;
+ klass->launch_finish = sev_snp_launch_finish;
klass->kvm_init = sev_snp_kvm_init;
x86_klass->kvm_type = sev_snp_kvm_type;
-
object_class_property_add(oc, "policy", "uint64",
sev_snp_guest_get_policy,
sev_snp_guest_set_policy, NULL, NULL);
diff --git a/target/i386/trace-events b/target/i386/trace-events
index cb26d8a925..06b44ead2e 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -12,3 +12,5 @@ kvm_sev_launch_finish(void) ""
kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d"
kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s"
kvm_sev_snp_launch_start(uint64_t policy, char *gosvw) "policy 0x%" PRIx64 " gosvw %s"
+kvm_sev_snp_launch_update(uint64_t src, uint64_t gpa, uint64_t len, const char *type) "src 0x%" PRIx64 " gpa 0x%" PRIx64 " len 0x%" PRIx64 " (%s page)"
+kvm_sev_snp_launch_finish(char *id_block, char *id_auth, char *host_data) "id_block %s id_auth %s host_data %s"
--
2.39.3

@ -1,127 +0,0 @@
From 2872c423fa44dcbf50b581a5c3feac064a0473a0 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Tue, 9 Apr 2024 18:07:41 -0500
Subject: [PATCH 024/100] i386/sev: Add 'legacy-vm-type' parameter for SEV
guest objects
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [24/91] ce35d1b09fe8aa8772ff149543f7760455c1e6b5 (bonzini/rhel-qemu-kvm)
QEMU will currently automatically make use of the KVM_SEV_INIT2 API for
initializing SEV and SEV-ES guests verses the older
KVM_SEV_INIT/KVM_SEV_ES_INIT interfaces.
However, the older interfaces will silently avoid sync'ing FPU/XSAVE
state to the VMSA prior to encryption, thus relying on behavior and
measurements that assume the related fields to be allow zero.
With KVM_SEV_INIT2, this state is now synced into the VMSA, resulting in
measurements changes and, theoretically, behaviorial changes, though the
latter are unlikely to be seen in practice.
To allow a smooth transition to the newer interface, while still
providing a mechanism to maintain backward compatibility with VMs
created using the older interfaces, provide a new command-line
parameter:
-object sev-guest,legacy-vm-type=true,...
and have it default to false.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Message-ID: <20240409230743.962513-2-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 023267334da375226720e62963df9545aa8fc2fd)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qapi/qom.json | 11 ++++++++++-
target/i386/sev.c | 18 +++++++++++++++++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/qapi/qom.json b/qapi/qom.json
index 85e6b4f84a..38dde6d785 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -898,6 +898,14 @@
# designated guest firmware page for measured boot with -kernel
# (default: false) (since 6.2)
#
+# @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM.
+# The newer KVM_SEV_INIT2 interface syncs additional vCPU
+# state when initializing the VMSA structures, which will
+# result in a different guest measurement. Set this to
+# maintain compatibility with older QEMU or kernel versions
+# that rely on legacy KVM_SEV_INIT behavior.
+# (default: false) (since 9.1)
+#
# Since: 2.12
##
{ 'struct': 'SevGuestProperties',
@@ -908,7 +916,8 @@
'*handle': 'uint32',
'*cbitpos': 'uint32',
'reduced-phys-bits': 'uint32',
- '*kernel-hashes': 'bool' } }
+ '*kernel-hashes': 'bool',
+ '*legacy-vm-type': 'bool' } }
##
# @ThreadContextProperties:
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 9dab4060b8..f4ee317cb0 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -67,6 +67,7 @@ struct SevGuestState {
uint32_t cbitpos;
uint32_t reduced_phys_bits;
bool kernel_hashes;
+ bool legacy_vm_type;
/* runtime state */
uint32_t handle;
@@ -356,6 +357,16 @@ static void sev_guest_set_kernel_hashes(Object *obj, bool value, Error **errp)
sev->kernel_hashes = value;
}
+static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp)
+{
+ return SEV_GUEST(obj)->legacy_vm_type;
+}
+
+static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp)
+{
+ SEV_GUEST(obj)->legacy_vm_type = value;
+}
+
bool
sev_enabled(void)
{
@@ -863,7 +874,7 @@ static int sev_kvm_type(X86ConfidentialGuest *cg)
}
kvm_type = (sev->policy & SEV_POLICY_ES) ? KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM;
- if (kvm_is_vm_type_supported(kvm_type)) {
+ if (kvm_is_vm_type_supported(kvm_type) && !sev->legacy_vm_type) {
sev->kvm_type = kvm_type;
} else {
sev->kvm_type = KVM_X86_DEFAULT_VM;
@@ -1381,6 +1392,11 @@ sev_guest_class_init(ObjectClass *oc, void *data)
sev_guest_set_kernel_hashes);
object_class_property_set_description(oc, "kernel-hashes",
"add kernel hashes to guest firmware for measured Linux boot");
+ object_class_property_add_bool(oc, "legacy-vm-type",
+ sev_guest_get_legacy_vm_type,
+ sev_guest_set_legacy_vm_type);
+ object_class_property_set_description(oc, "legacy-vm-type",
+ "use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions.");
}
static void
--
2.39.3

@ -1,203 +0,0 @@
From a236548a903aa8350fff9601d481b2f529c8d4a7 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Thu, 30 May 2024 06:16:21 -0500
Subject: [PATCH 061/100] i386/sev: Add sev_kvm_init() override for SEV class
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [61/91] b24fcbc8712e7394e029312229da023c63803969 (bonzini/rhel-qemu-kvm)
Some aspects of the init routine SEV are specific to SEV and not
applicable for SNP guests, so move the SEV-specific bits into
separate class method and retain only the common functionality.
Co-developed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-10-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 990da8d243a8c59dafcbed78b56a0e4ffb1605d9)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 72 +++++++++++++++++++++++++++++++++--------------
1 file changed, 51 insertions(+), 21 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 4edfedc139..5519de1c6b 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -73,6 +73,7 @@ struct SevCommonStateClass {
/* public */
int (*launch_start)(SevCommonState *sev_common);
void (*launch_finish)(SevCommonState *sev_common);
+ int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
};
/**
@@ -882,7 +883,7 @@ out:
return sev_common->kvm_type;
}
-static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
+static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(cgs);
char *devname;
@@ -892,12 +893,6 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
struct sev_user_data_status status = {};
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
- ret = ram_block_discard_disable(true);
- if (ret) {
- error_report("%s: cannot disable RAM discard", __func__);
- return -1;
- }
-
sev_common->state = SEV_STATE_UNINIT;
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
@@ -911,7 +906,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
if (host_cbitpos != sev_common->cbitpos) {
error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
__func__, host_cbitpos, sev_common->cbitpos);
- goto err;
+ return -1;
}
/*
@@ -924,7 +919,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
error_setg(errp, "%s: reduced_phys_bits check failed,"
" it should be in the range of 1 to 63, requested '%d'",
__func__, sev_common->reduced_phys_bits);
- goto err;
+ return -1;
}
devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL);
@@ -933,7 +928,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
error_setg(errp, "%s: Failed to open %s '%s'", __func__,
devname, strerror(errno));
g_free(devname);
- goto err;
+ return -1;
}
g_free(devname);
@@ -943,7 +938,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
error_setg(errp, "%s: failed to get platform status ret=%d "
"fw_error='%d: %s'", __func__, ret, fw_error,
fw_error_to_str(fw_error));
- goto err;
+ return -1;
}
sev_common->build_id = status.build;
sev_common->api_major = status.api_major;
@@ -953,7 +948,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
if (!kvm_kernel_irqchip_allowed()) {
error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip"
"support", __func__);
- goto err;
+ return -1;
}
}
@@ -962,7 +957,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
error_setg(errp, "%s: guest policy requires SEV-ES, but "
"host SEV-ES support unavailable",
__func__);
- goto err;
+ return -1;
}
}
@@ -980,25 +975,59 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
if (ret) {
error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
__func__, ret, fw_error, fw_error_to_str(fw_error));
- goto err;
+ return -1;
}
ret = klass->launch_start(sev_common);
if (ret) {
error_setg(errp, "%s: failed to create encryption context", __func__);
- goto err;
+ return -1;
+ }
+
+ if (klass->kvm_init && klass->kvm_init(cgs, errp)) {
+ return -1;
}
- ram_block_notifier_add(&sev_ram_notifier);
- qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common);
cgs->ready = true;
return 0;
-err:
- ram_block_discard_disable(false);
- return -1;
+}
+
+static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
+{
+ int ret;
+
+ /*
+ * SEV/SEV-ES rely on pinned memory to back guest RAM so discarding
+ * isn't actually possible. With SNP, only guest_memfd pages are used
+ * for private guest memory, so discarding of shared memory is still
+ * possible..
+ */
+ ret = ram_block_discard_disable(true);
+ if (ret) {
+ error_setg(errp, "%s: cannot disable RAM discard", __func__);
+ return -1;
+ }
+
+ /*
+ * SEV uses these notifiers to register/pin pages prior to guest use,
+ * but SNP relies on guest_memfd for private pages, which has its
+ * own internal mechanisms for registering/pinning private memory.
+ */
+ ram_block_notifier_add(&sev_ram_notifier);
+
+ /*
+ * The machine done notify event is used for SEV guests to get the
+ * measurement of the encrypted images. When SEV-SNP is enabled, the
+ * measurement is part of the guest attestation process where it can
+ * be collected without any reliance on the VMM. So skip registering
+ * the notifier for SNP in favor of using guest attestation instead.
+ */
+ qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
+
+ return 0;
}
int
@@ -1397,7 +1426,7 @@ sev_common_class_init(ObjectClass *oc, void *data)
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
- klass->kvm_init = sev_kvm_init;
+ klass->kvm_init = sev_common_kvm_init;
x86_klass->kvm_type = sev_kvm_type;
object_class_property_add_str(oc, "sev-device",
@@ -1486,6 +1515,7 @@ sev_guest_class_init(ObjectClass *oc, void *data)
klass->launch_start = sev_launch_start;
klass->launch_finish = sev_launch_finish;
+ klass->kvm_init = sev_kvm_init;
object_class_property_add_str(oc, "dh-cert-file",
sev_guest_get_dh_cert_file,
--
2.39.3

@ -1,94 +0,0 @@
From 35ceebdeccbf5dceb374c6f89a12e9981def570b Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Thu, 30 May 2024 06:16:22 -0500
Subject: [PATCH 062/100] i386/sev: Add snp_kvm_init() override for SNP class
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [62/91] 8fa537961c9262b99a4ffb99e1c25f080d76d1de (bonzini/rhel-qemu-kvm)
SNP does not support SMM and requires guest_memfd for
private guest memory, so add SNP specific kvm_init()
functionality in snp_kvm_init() class method.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-11-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 125b95a6d465a03ff30816eff0b1889aec01f0c3)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 5519de1c6b..6525b3c1a0 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -885,12 +885,12 @@ out:
static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
{
- SevCommonState *sev_common = SEV_COMMON(cgs);
char *devname;
int ret, fw_error, cmd;
uint32_t ebx;
uint32_t host_cbitpos;
struct sev_user_data_status status = {};
+ SevCommonState *sev_common = SEV_COMMON(cgs);
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
sev_common->state = SEV_STATE_UNINIT;
@@ -1030,6 +1030,21 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
return 0;
}
+static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ X86MachineState *x86ms = X86_MACHINE(ms);
+
+ if (x86ms->smm == ON_OFF_AUTO_AUTO) {
+ x86ms->smm = ON_OFF_AUTO_OFF;
+ } else if (x86ms->smm == ON_OFF_AUTO_ON) {
+ error_setg(errp, "SEV-SNP does not support SMM.");
+ return -1;
+ }
+
+ return 0;
+}
+
int
sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
{
@@ -1752,6 +1767,10 @@ sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp)
static void
sev_snp_guest_class_init(ObjectClass *oc, void *data)
{
+ SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
+
+ klass->kvm_init = sev_snp_kvm_init;
+
object_class_property_add(oc, "policy", "uint64",
sev_snp_guest_get_policy,
sev_snp_guest_set_policy, NULL, NULL);
@@ -1778,8 +1797,11 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
static void
sev_snp_guest_instance_init(Object *obj)
{
+ ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj);
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+ cgs->require_guest_memfd = true;
+
/* default init/start/finish params for kvm */
sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
}
--
2.39.3

@ -1,262 +0,0 @@
From 4013364679757161d6b9754bfc33ae38be0a1b7f Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:32 -0500
Subject: [PATCH 072/100] i386/sev: Add support for SNP CPUID validation
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [72/91] 080e2942552dc7de8966e69d0d0d3b8951392030 (bonzini/rhel-qemu-kvm)
SEV-SNP firmware allows a special guest page to be populated with a
table of guest CPUID values so that they can be validated through
firmware before being loaded into encrypted guest memory where they can
be used in place of hypervisor-provided values[1].
As part of SEV-SNP guest initialization, use this interface to validate
the CPUID entries reported by KVM_GET_CPUID2 prior to initial guest
start and populate the CPUID page reserved by OVMF with the resulting
encrypted data.
[1] SEV SNP Firmware ABI Specification, Rev. 0.8, 8.13.2.6
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-21-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 70943ad8e4dfbe5f77006b880290219be9d03553)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 164 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 162 insertions(+), 2 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index c57534fca2..06401f0526 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -200,6 +200,36 @@ static const char *const sev_fw_errlist[] = {
#define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
+/* <linux/kvm.h> doesn't expose this, so re-use the max from kvm.c */
+#define KVM_MAX_CPUID_ENTRIES 100
+
+typedef struct KvmCpuidInfo {
+ struct kvm_cpuid2 cpuid;
+ struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
+} KvmCpuidInfo;
+
+#define SNP_CPUID_FUNCTION_MAXCOUNT 64
+#define SNP_CPUID_FUNCTION_UNKNOWN 0xFFFFFFFF
+
+typedef struct {
+ uint32_t eax_in;
+ uint32_t ecx_in;
+ uint64_t xcr0_in;
+ uint64_t xss_in;
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint64_t reserved;
+} __attribute__((packed)) SnpCpuidFunc;
+
+typedef struct {
+ uint32_t count;
+ uint32_t reserved1;
+ uint64_t reserved2;
+ SnpCpuidFunc entries[SNP_CPUID_FUNCTION_MAXCOUNT];
+} __attribute__((packed)) SnpCpuidInfo;
+
static int
sev_ioctl(int fd, int cmd, void *data, int *error)
{
@@ -788,6 +818,35 @@ out:
return ret;
}
+static void
+sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old,
+ SnpCpuidInfo *new)
+{
+ size_t i;
+
+ if (old->count != new->count) {
+ error_report("SEV-SNP: CPUID validation failed due to count mismatch,"
+ "provided: %d, expected: %d", old->count, new->count);
+ return;
+ }
+
+ for (i = 0; i < old->count; i++) {
+ SnpCpuidFunc *old_func, *new_func;
+
+ old_func = &old->entries[i];
+ 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"
+ "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,
+ new_func->eax, new_func->ebx, new_func->ecx, new_func->edx);
+ }
+ }
+}
+
static const char *
snp_page_type_to_str(int type)
{
@@ -806,6 +865,7 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest,
SevLaunchUpdateData *data)
{
int ret, fw_error;
+ SnpCpuidInfo snp_cpuid_info;
struct kvm_sev_snp_launch_update update = {0};
if (!data->hva || !data->len) {
@@ -815,6 +875,11 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest,
return 1;
}
+ if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
+ /* Save a copy for comparison in case the LAUNCH_UPDATE fails */
+ memcpy(&snp_cpuid_info, data->hva, sizeof(snp_cpuid_info));
+ }
+
update.uaddr = (__u64)(unsigned long)data->hva;
update.gfn_start = data->gpa >> TARGET_PAGE_BITS;
update.len = data->len;
@@ -842,6 +907,11 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest,
if (ret && ret != -EAGAIN) {
error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
ret, fw_error, fw_error_to_str(fw_error));
+
+ if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
+ sev_snp_cpuid_report_mismatches(&snp_cpuid_info, data->hva);
+ error_report("SEV-SNP: failed update CPUID page");
+ }
break;
}
}
@@ -1004,7 +1074,8 @@ sev_launch_finish(SevCommonState *sev_common)
}
static int
-snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type)
+snp_launch_update_data(uint64_t gpa, void *hva,
+ uint32_t len, int type)
{
SevLaunchUpdateData *data;
@@ -1019,6 +1090,90 @@ snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type)
return 0;
}
+static int
+sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info,
+ const KvmCpuidInfo *kvm_cpuid_info)
+{
+ size_t i;
+
+ if (kvm_cpuid_info->cpuid.nent > SNP_CPUID_FUNCTION_MAXCOUNT) {
+ error_report("SEV-SNP: CPUID entry count (%d) exceeds max (%d)",
+ kvm_cpuid_info->cpuid.nent, SNP_CPUID_FUNCTION_MAXCOUNT);
+ return -1;
+ }
+
+ memset(snp_cpuid_info, 0, sizeof(*snp_cpuid_info));
+
+ for (i = 0; i < kvm_cpuid_info->cpuid.nent; i++) {
+ const struct kvm_cpuid_entry2 *kvm_cpuid_entry;
+ SnpCpuidFunc *snp_cpuid_entry;
+
+ kvm_cpuid_entry = &kvm_cpuid_info->entries[i];
+ snp_cpuid_entry = &snp_cpuid_info->entries[i];
+
+ snp_cpuid_entry->eax_in = kvm_cpuid_entry->function;
+ if (kvm_cpuid_entry->flags == KVM_CPUID_FLAG_SIGNIFCANT_INDEX) {
+ snp_cpuid_entry->ecx_in = kvm_cpuid_entry->index;
+ }
+ snp_cpuid_entry->eax = kvm_cpuid_entry->eax;
+ snp_cpuid_entry->ebx = kvm_cpuid_entry->ebx;
+ snp_cpuid_entry->ecx = kvm_cpuid_entry->ecx;
+ snp_cpuid_entry->edx = kvm_cpuid_entry->edx;
+
+ /*
+ * Guest kernels will calculate EBX themselves using the 0xD
+ * subfunctions corresponding to the individual XSAVE areas, so only
+ * encode the base XSAVE size in the initial leaves, corresponding
+ * to the initial XCR0=1 state.
+ */
+ if (snp_cpuid_entry->eax_in == 0xD &&
+ (snp_cpuid_entry->ecx_in == 0x0 || snp_cpuid_entry->ecx_in == 0x1)) {
+ snp_cpuid_entry->ebx = 0x240;
+ snp_cpuid_entry->xcr0_in = 1;
+ snp_cpuid_entry->xss_in = 0;
+ }
+ }
+
+ snp_cpuid_info->count = i;
+
+ return 0;
+}
+
+static int
+snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len)
+{
+ KvmCpuidInfo kvm_cpuid_info = {0};
+ SnpCpuidInfo snp_cpuid_info;
+ CPUState *cs = first_cpu;
+ int ret;
+ uint32_t i = 0;
+
+ assert(sizeof(snp_cpuid_info) <= cpuid_len);
+
+ /* get the cpuid list from KVM */
+ do {
+ kvm_cpuid_info.cpuid.nent = ++i;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_CPUID2, &kvm_cpuid_info);
+ } while (ret == -E2BIG);
+
+ if (ret) {
+ error_report("SEV-SNP: unable to query CPUID values for CPU: '%s'",
+ strerror(-ret));
+ return 1;
+ }
+
+ ret = sev_snp_cpuid_info_fill(&snp_cpuid_info, &kvm_cpuid_info);
+ if (ret) {
+ error_report("SEV-SNP: failed to generate CPUID table information");
+ return 1;
+ }
+
+ memcpy(hva, &snp_cpuid_info, sizeof(snp_cpuid_info));
+
+ return snp_launch_update_data(cpuid_addr, hva, cpuid_len,
+ KVM_SEV_SNP_PAGE_TYPE_CPUID);
+}
+
static int
snp_metadata_desc_to_page_type(int desc_type)
{
@@ -1053,7 +1208,12 @@ snp_populate_metadata_pages(SevSnpGuestState *sev_snp,
exit(1);
}
- ret = snp_launch_update_data(desc->base, hva, desc->len, type);
+ if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
+ ret = snp_launch_update_cpuid(desc->base, hva, desc->len);
+ } else {
+ ret = snp_launch_update_data(desc->base, hva, desc->len, type);
+ }
+
if (ret) {
error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d",
__func__, desc->base, desc->len, desc->type);
--
2.39.3

@ -1,127 +0,0 @@
From b2cfd4d89026e76ba86ea7adea323f2c3a588790 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:31 -0500
Subject: [PATCH 071/100] i386/sev: Add support for populating OVMF metadata
pages
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [71/91] b563442c0e2f6ea01937425d300b56d9e641fd57 (bonzini/rhel-qemu-kvm)
OVMF reserves various pages so they can be pre-initialized/validated
prior to launching the guest. Add support for populating these pages
with the expected content.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-20-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3d8c2a7f4806ff39423312e503737fd76c34dcae)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 17281bb2c7..c57534fca2 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1003,15 +1003,89 @@ sev_launch_finish(SevCommonState *sev_common)
migrate_add_blocker(&sev_mig_blocker, &error_fatal);
}
+static int
+snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type)
+{
+ SevLaunchUpdateData *data;
+
+ data = g_new0(SevLaunchUpdateData, 1);
+ data->gpa = gpa;
+ data->hva = hva;
+ data->len = len;
+ data->type = type;
+
+ QTAILQ_INSERT_TAIL(&launch_update, data, next);
+
+ return 0;
+}
+
+static int
+snp_metadata_desc_to_page_type(int desc_type)
+{
+ switch (desc_type) {
+ /* Add the umeasured prevalidated pages as a zero page */
+ case SEV_DESC_TYPE_SNP_SEC_MEM: return KVM_SEV_SNP_PAGE_TYPE_ZERO;
+ case SEV_DESC_TYPE_SNP_SECRETS: return KVM_SEV_SNP_PAGE_TYPE_SECRETS;
+ case SEV_DESC_TYPE_CPUID: return KVM_SEV_SNP_PAGE_TYPE_CPUID;
+ default:
+ return KVM_SEV_SNP_PAGE_TYPE_ZERO;
+ }
+}
+
+static void
+snp_populate_metadata_pages(SevSnpGuestState *sev_snp,
+ OvmfSevMetadata *metadata)
+{
+ OvmfSevMetadataDesc *desc;
+ int type, ret, i;
+ void *hva;
+ MemoryRegion *mr = NULL;
+
+ for (i = 0; i < metadata->num_desc; i++) {
+ desc = &metadata->descs[i];
+
+ type = snp_metadata_desc_to_page_type(desc->type);
+
+ hva = gpa2hva(&mr, desc->base, desc->len, NULL);
+ if (!hva) {
+ error_report("%s: Failed to get HVA for GPA 0x%x sz 0x%x",
+ __func__, desc->base, desc->len);
+ exit(1);
+ }
+
+ ret = snp_launch_update_data(desc->base, hva, desc->len, type);
+ if (ret) {
+ error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d",
+ __func__, desc->base, desc->len, desc->type);
+ exit(1);
+ }
+ }
+}
+
static void
sev_snp_launch_finish(SevCommonState *sev_common)
{
int ret, error;
Error *local_err = NULL;
+ OvmfSevMetadata *metadata;
SevLaunchUpdateData *data;
SevSnpGuestState *sev_snp = SEV_SNP_GUEST(sev_common);
struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf;
+ /*
+ * To boot the SNP guest, the hypervisor is required to populate the CPUID
+ * and Secrets page before finalizing the launch flow. The location of
+ * the secrets and CPUID page is available through the OVMF metadata GUID.
+ */
+ metadata = pc_system_get_ovmf_sev_metadata_ptr();
+ if (metadata == NULL) {
+ error_report("%s: Failed to locate SEV metadata header", __func__);
+ exit(1);
+ }
+
+ /* Populate all the metadata pages */
+ snp_populate_metadata_pages(sev_snp, metadata);
+
QTAILQ_FOREACH(data, &launch_update, next) {
ret = sev_snp_launch_update(sev_snp, data);
if (ret) {
--
2.39.3

@ -1,122 +0,0 @@
From 0f7432f2b968298b64fd243df793b176f67a538f Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:27 -0500
Subject: [PATCH 067/100] i386/sev: Add the SNP launch start context
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [67/91] 63759a25a413a7a9a7274fb4c3b8bc2528634855 (bonzini/rhel-qemu-kvm)
The SNP_LAUNCH_START is called first to create a cryptographic launch
context within the firmware.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-16-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d3107f882ec22cfb211eab7efa0c4e95f5ce11bb)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 39 +++++++++++++++++++++++++++++++++++++++
target/i386/trace-events | 1 +
2 files changed, 40 insertions(+)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 43d1c48bd9..e89b87d2f5 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -39,6 +39,7 @@
#include "confidential-guest.h"
#include "hw/i386/pc.h"
#include "exec/address-spaces.h"
+#include "qemu/queue.h"
OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON)
OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST)
@@ -115,6 +116,16 @@ struct SevSnpGuestState {
#define DEFAULT_SEV_DEVICE "/dev/sev"
#define DEFAULT_SEV_SNP_POLICY 0x30000
+typedef struct SevLaunchUpdateData {
+ QTAILQ_ENTRY(SevLaunchUpdateData) next;
+ hwaddr gpa;
+ void *hva;
+ uint64_t len;
+ int type;
+} SevLaunchUpdateData;
+
+static QTAILQ_HEAD(, SevLaunchUpdateData) launch_update;
+
#define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
typedef struct __attribute__((__packed__)) SevInfoBlock {
/* SEV-ES Reset Vector Address */
@@ -674,6 +685,31 @@ sev_read_file_base64(const char *filename, guchar **data, gsize *len)
return 0;
}
+static int
+sev_snp_launch_start(SevCommonState *sev_common)
+{
+ int fw_error, rc;
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common);
+ struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
+
+ trace_kvm_sev_snp_launch_start(start->policy,
+ sev_snp_guest->guest_visible_workarounds);
+
+ rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START,
+ start, &fw_error);
+ if (rc < 0) {
+ error_report("%s: SNP_LAUNCH_START ret=%d fw_error=%d '%s'",
+ __func__, rc, fw_error, fw_error_to_str(fw_error));
+ return 1;
+ }
+
+ QTAILQ_INIT(&launch_update);
+
+ sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE);
+
+ return 0;
+}
+
static int
sev_launch_start(SevCommonState *sev_common)
{
@@ -1003,6 +1039,7 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
}
ret = klass->launch_start(sev_common);
+
if (ret) {
error_setg(errp, "%s: failed to create encryption context", __func__);
return -1;
@@ -1794,9 +1831,11 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
+ klass->launch_start = sev_snp_launch_start;
klass->kvm_init = sev_snp_kvm_init;
x86_klass->kvm_type = sev_snp_kvm_type;
+
object_class_property_add(oc, "policy", "uint64",
sev_snp_guest_get_policy,
sev_snp_guest_set_policy, NULL, NULL);
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 2cd8726eeb..cb26d8a925 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -11,3 +11,4 @@ kvm_sev_launch_measurement(const char *value) "data %s"
kvm_sev_launch_finish(void) ""
kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d"
kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s"
+kvm_sev_snp_launch_start(uint64_t policy, char *gosvw) "policy 0x%" PRIx64 " gosvw %s"
--
2.39.3

@ -1,237 +0,0 @@
From ec786a1ec0a76775e980862d77500f5196a937e3 Mon Sep 17 00:00:00 2001
From: Dov Murik <dovmurik@linux.ibm.com>
Date: Thu, 30 May 2024 06:16:35 -0500
Subject: [PATCH 080/100] i386/sev: Allow measured direct kernel boot on SNP
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [80/91] 11c629862519c1a279566febf5a537c63c5fcf61 (bonzini/rhel-qemu-kvm)
In SNP, the hashes page designated with a specific metadata entry
published in AmdSev OVMF.
Therefore, if the user enabled kernel hashes (for measured direct boot),
QEMU should prepare the content of hashes table, and during the
processing of the metadata entry it copy the content into the designated
page and encrypt it.
Note that in SNP (unlike SEV and SEV-ES) the measurements is done in
whole 4KB pages. Therefore QEMU zeros the whole page that includes the
hashes table, and fills in the kernel hashes area in that page, and then
encrypts the whole page. The rest of the page is reserved for SEV
launch secrets which are not usable anyway on SNP.
If the user disabled kernel hashes, QEMU pre-validates the kernel hashes
page as a zero page.
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-24-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c1996992cc882b00139f78067d6a64e2ec9cb0d8)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/i386/pc.h | 2 +
target/i386/sev.c | 111 ++++++++++++++++++++++++++++++++-----------
2 files changed, 85 insertions(+), 28 deletions(-)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 94b49310f5..ee3bfb7be9 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -175,6 +175,8 @@ typedef enum {
SEV_DESC_TYPE_SNP_SECRETS,
/* The section contains address that can be used as a CPUID page */
SEV_DESC_TYPE_CPUID,
+ /* The section contains the region for kernel hashes for measured direct boot */
+ SEV_DESC_TYPE_SNP_KERNEL_HASHES = 0x10,
} ovmf_sev_metadata_desc_type;
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 3fce4c08eb..004c667ac1 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -115,6 +115,10 @@ struct SevCommonStateClass {
X86ConfidentialGuestClass parent_class;
/* public */
+ bool (*build_kernel_loader_hashes)(SevCommonState *sev_common,
+ SevHashTableDescriptor *area,
+ SevKernelLoaderContext *ctx,
+ Error **errp);
int (*launch_start)(SevCommonState *sev_common);
void (*launch_finish)(SevCommonState *sev_common);
int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len);
@@ -154,6 +158,9 @@ struct SevSnpGuestState {
struct kvm_sev_snp_launch_start kvm_start_conf;
struct kvm_sev_snp_launch_finish kvm_finish_conf;
+
+ uint32_t kernel_hashes_offset;
+ PaddedSevHashTable *kernel_hashes_data;
};
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
@@ -1189,6 +1196,23 @@ snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len)
KVM_SEV_SNP_PAGE_TYPE_CPUID);
}
+static int
+snp_launch_update_kernel_hashes(SevSnpGuestState *sev_snp, uint32_t addr,
+ void *hva, uint32_t len)
+{
+ int type = KVM_SEV_SNP_PAGE_TYPE_ZERO;
+ if (sev_snp->parent_obj.kernel_hashes) {
+ assert(sev_snp->kernel_hashes_data);
+ assert((sev_snp->kernel_hashes_offset +
+ sizeof(*sev_snp->kernel_hashes_data)) <= len);
+ memset(hva, 0, len);
+ memcpy(hva + sev_snp->kernel_hashes_offset, sev_snp->kernel_hashes_data,
+ sizeof(*sev_snp->kernel_hashes_data));
+ type = KVM_SEV_SNP_PAGE_TYPE_NORMAL;
+ }
+ return snp_launch_update_data(addr, hva, len, type);
+}
+
static int
snp_metadata_desc_to_page_type(int desc_type)
{
@@ -1225,6 +1249,9 @@ snp_populate_metadata_pages(SevSnpGuestState *sev_snp,
if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
ret = snp_launch_update_cpuid(desc->base, hva, desc->len);
+ } else if (desc->type == SEV_DESC_TYPE_SNP_KERNEL_HASHES) {
+ ret = snp_launch_update_kernel_hashes(sev_snp, desc->base, hva,
+ desc->len);
} else {
ret = snp_launch_update_data(desc->base, hva, desc->len, type);
}
@@ -1823,6 +1850,58 @@ static bool build_kernel_loader_hashes(PaddedSevHashTable *padded_ht,
return true;
}
+static bool sev_snp_build_kernel_loader_hashes(SevCommonState *sev_common,
+ SevHashTableDescriptor *area,
+ SevKernelLoaderContext *ctx,
+ Error **errp)
+{
+ /*
+ * SNP: Populate the hashes table in an area that later in
+ * snp_launch_update_kernel_hashes() will be copied to the guest memory
+ * and encrypted.
+ */
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common);
+ sev_snp_guest->kernel_hashes_offset = area->base & ~TARGET_PAGE_MASK;
+ sev_snp_guest->kernel_hashes_data = g_new0(PaddedSevHashTable, 1);
+ return build_kernel_loader_hashes(sev_snp_guest->kernel_hashes_data, ctx, errp);
+}
+
+static bool sev_build_kernel_loader_hashes(SevCommonState *sev_common,
+ SevHashTableDescriptor *area,
+ SevKernelLoaderContext *ctx,
+ Error **errp)
+{
+ PaddedSevHashTable *padded_ht;
+ hwaddr mapped_len = sizeof(*padded_ht);
+ MemTxAttrs attrs = { 0 };
+ bool ret = true;
+
+ /*
+ * Populate the hashes table in the guest's memory at the OVMF-designated
+ * area for the SEV hashes table
+ */
+ padded_ht = address_space_map(&address_space_memory, area->base,
+ &mapped_len, true, attrs);
+ if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
+ error_setg(errp, "SEV: cannot map hashes table guest memory area");
+ return false;
+ }
+
+ if (build_kernel_loader_hashes(padded_ht, ctx, errp)) {
+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
+ sizeof(*padded_ht), errp) < 0) {
+ ret = false;
+ }
+ } else {
+ ret = false;
+ }
+
+ address_space_unmap(&address_space_memory, padded_ht,
+ mapped_len, true, mapped_len);
+
+ return ret;
+}
+
/*
* Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
* which is included in SEV's initial memory measurement.
@@ -1831,11 +1910,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
{
uint8_t *data;
SevHashTableDescriptor *area;
- PaddedSevHashTable *padded_ht;
- hwaddr mapped_len = sizeof(*padded_ht);
- MemTxAttrs attrs = { 0 };
- bool ret = true;
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common);
/*
* Only add the kernel hashes if the sev-guest configuration explicitly
@@ -1858,30 +1934,7 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
return false;
}
- /*
- * Populate the hashes table in the guest's memory at the OVMF-designated
- * area for the SEV hashes table
- */
- padded_ht = address_space_map(&address_space_memory, area->base,
- &mapped_len, true, attrs);
- if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
- error_setg(errp, "SEV: cannot map hashes table guest memory area");
- return false;
- }
-
- if (build_kernel_loader_hashes(padded_ht, ctx, errp)) {
- if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
- sizeof(*padded_ht), errp) < 0) {
- ret = false;
- }
- } else {
- ret = false;
- }
-
- address_space_unmap(&address_space_memory, padded_ht,
- mapped_len, true, mapped_len);
-
- return ret;
+ return klass->build_kernel_loader_hashes(sev_common, area, ctx, errp);
}
static char *
@@ -1998,6 +2051,7 @@ sev_guest_class_init(ObjectClass *oc, void *data)
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
+ klass->build_kernel_loader_hashes = sev_build_kernel_loader_hashes;
klass->launch_start = sev_launch_start;
klass->launch_finish = sev_launch_finish;
klass->launch_update_data = sev_launch_update_data;
@@ -2242,6 +2296,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
+ klass->build_kernel_loader_hashes = sev_snp_build_kernel_loader_hashes;
klass->launch_start = sev_snp_launch_start;
klass->launch_finish = sev_snp_launch_finish;
klass->launch_update_data = sev_snp_launch_update_data;
--
2.39.3

@ -1,268 +0,0 @@
From ab6197309551bd6ddd9f8239191f68dfac23684b Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Tue, 9 Jul 2024 23:10:05 -0500
Subject: [PATCH 090/100] i386/sev: Don't allow automatic fallback to legacy
KVM_SEV*_INIT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [90/91] 2b1345faa56f993bb6e13d63e11656c784e20412 (bonzini/rhel-qemu-kvm)
Currently if the 'legacy-vm-type' property of the sev-guest object is
'on', QEMU will attempt to use the newer KVM_SEV_INIT2 kernel
interface in conjunction with the newer KVM_X86_SEV_VM and
KVM_X86_SEV_ES_VM KVM VM types.
This can lead to measurement changes if, for instance, an SEV guest was
created on a host that originally had an older kernel that didn't
support KVM_SEV_INIT2, but is booted on the same host later on after the
host kernel was upgraded.
Instead, if legacy-vm-type is 'off', QEMU should fail if the
KVM_SEV_INIT2 interface is not provided by the current host kernel.
Modify the fallback handling accordingly.
In the future, VMSA features and other flags might be added to QEMU
which will require legacy-vm-type to be 'off' because they will rely
on the newer KVM_SEV_INIT2 interface. It may be difficult to convey to
users what values of legacy-vm-type are compatible with which
features/options, so as part of this rework, switch legacy-vm-type to a
tri-state OnOffAuto option. 'auto' in this case will automatically
switch to using the newer KVM_SEV_INIT2, but only if it is required to
make use of new VMSA features or other options only available via
KVM_SEV_INIT2.
Defining 'auto' in this way would avoid inadvertantly breaking
compatibility with older kernels since it would only be used in cases
where users opt into newer features that are only available via
KVM_SEV_INIT2 and newer kernels, and provide better default behavior
than the legacy-vm-type=off behavior that was previously in place, so
make it the default for 9.1+ machine types.
Cc: Daniel P. Berrangé <berrange@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
cc: kvm@vger.kernel.org
Signed-off-by: Michael Roth <michael.roth@amd.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Link: https://lore.kernel.org/r/20240710041005.83720-1-michael.roth@amd.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9d38d9dca2a81aaf5752d45d221021ef96d496cd)
RHEL: adjust compatiility setting, applying it to 9.4 machine type
---
hw/i386/pc.c | 2 +-
qapi/qom.json | 18 ++++++----
target/i386/sev.c | 85 +++++++++++++++++++++++++++++++++++++++--------
3 files changed, 83 insertions(+), 22 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b25d075b59..e9c5ea5d8f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -352,7 +352,7 @@ const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat);
GlobalProperty pc_rhel_9_5_compat[] = {
/* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */
{ TYPE_X86_CPU, "guest-phys-bits", "0" },
- { "sev-guest", "legacy-vm-type", "true" },
+ { "sev-guest", "legacy-vm-type", "on" },
};
const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat);
diff --git a/qapi/qom.json b/qapi/qom.json
index 8bd299265e..17bd5a0cf7 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -912,12 +912,16 @@
# @handle: SEV firmware handle (default: 0)
#
# @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM.
-# The newer KVM_SEV_INIT2 interface syncs additional vCPU
-# state when initializing the VMSA structures, which will
-# result in a different guest measurement. Set this to
-# maintain compatibility with older QEMU or kernel versions
-# that rely on legacy KVM_SEV_INIT behavior.
-# (default: false) (since 9.1)
+# The newer KVM_SEV_INIT2 interface, from Linux >= 6.10, syncs
+# additional vCPU state when initializing the VMSA structures,
+# which will result in a different guest measurement. Set
+# this to 'on' to force compatibility with older QEMU or kernel
+# versions that rely on legacy KVM_SEV_INIT behavior. 'auto'
+# will behave identically to 'on', but will automatically
+# switch to using KVM_SEV_INIT2 if the user specifies any
+# additional options that require it. If set to 'off', QEMU
+# will require KVM_SEV_INIT2 unconditionally.
+# (default: off) (since 9.1)
#
# Since: 2.12
##
@@ -927,7 +931,7 @@
'*session-file': 'str',
'*policy': 'uint32',
'*handle': 'uint32',
- '*legacy-vm-type': 'bool' } }
+ '*legacy-vm-type': 'OnOffAuto' } }
##
# @SevSnpGuestProperties:
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 491fab74fd..b921defb63 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -144,7 +144,7 @@ struct SevGuestState {
uint32_t policy;
char *dh_cert_file;
char *session_file;
- bool legacy_vm_type;
+ OnOffAuto legacy_vm_type;
};
struct SevSnpGuestState {
@@ -1334,6 +1334,17 @@ sev_vm_state_change(void *opaque, bool running, RunState state)
}
}
+/*
+ * This helper is to examine sev-guest properties and determine if any options
+ * have been set which rely on the newer KVM_SEV_INIT2 interface and associated
+ * KVM VM types.
+ */
+static bool sev_init2_required(SevGuestState *sev_guest)
+{
+ /* Currently no KVM_SEV_INIT2-specific options are exposed via QEMU */
+ return false;
+}
+
static int sev_kvm_type(X86ConfidentialGuest *cg)
{
SevCommonState *sev_common = SEV_COMMON(cg);
@@ -1344,14 +1355,39 @@ static int sev_kvm_type(X86ConfidentialGuest *cg)
goto out;
}
+ /* These are the only cases where legacy VM types can be used. */
+ if (sev_guest->legacy_vm_type == ON_OFF_AUTO_ON ||
+ (sev_guest->legacy_vm_type == ON_OFF_AUTO_AUTO &&
+ !sev_init2_required(sev_guest))) {
+ sev_common->kvm_type = KVM_X86_DEFAULT_VM;
+ goto out;
+ }
+
+ /*
+ * Newer VM types are required, either explicitly via legacy-vm-type=on, or
+ * implicitly via legacy-vm-type=auto along with additional sev-guest
+ * properties that require the newer VM types.
+ */
kvm_type = (sev_guest->policy & SEV_POLICY_ES) ?
KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM;
- if (kvm_is_vm_type_supported(kvm_type) && !sev_guest->legacy_vm_type) {
- sev_common->kvm_type = kvm_type;
- } else {
- sev_common->kvm_type = KVM_X86_DEFAULT_VM;
+ if (!kvm_is_vm_type_supported(kvm_type)) {
+ if (sev_guest->legacy_vm_type == ON_OFF_AUTO_AUTO) {
+ error_report("SEV: host kernel does not support requested %s VM type, which is required "
+ "for the set of options specified. To allow use of the legacy "
+ "KVM_X86_DEFAULT_VM VM type, please disable any options that are not "
+ "compatible with the legacy VM type, or upgrade your kernel.",
+ kvm_type == KVM_X86_SEV_VM ? "KVM_X86_SEV_VM" : "KVM_X86_SEV_ES_VM");
+ } else {
+ error_report("SEV: host kernel does not support requested %s VM type. To allow use of "
+ "the legacy KVM_X86_DEFAULT_VM VM type, the 'legacy-vm-type' argument "
+ "must be set to 'on' or 'auto' for the sev-guest object.",
+ kvm_type == KVM_X86_SEV_VM ? "KVM_X86_SEV_VM" : "KVM_X86_SEV_ES_VM");
+ }
+
+ return -1;
}
+ sev_common->kvm_type = kvm_type;
out:
return sev_common->kvm_type;
}
@@ -1442,14 +1478,24 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
}
trace_kvm_sev_init();
- if (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) {
+ switch (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common))) {
+ case KVM_X86_DEFAULT_VM:
cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT;
ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error);
- } else {
+ break;
+ case KVM_X86_SEV_VM:
+ case KVM_X86_SEV_ES_VM:
+ case KVM_X86_SNP_VM: {
struct kvm_sev_init args = { 0 };
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_INIT2, &args, &fw_error);
+ break;
+ }
+ default:
+ error_setg(errp, "%s: host kernel does not support the requested SEV configuration.",
+ __func__);
+ return -1;
}
if (ret) {
@@ -2037,14 +2083,23 @@ sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
SEV_GUEST(obj)->session_file = g_strdup(value);
}
-static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp)
+static void sev_guest_get_legacy_vm_type(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
{
- return SEV_GUEST(obj)->legacy_vm_type;
+ SevGuestState *sev_guest = SEV_GUEST(obj);
+ OnOffAuto legacy_vm_type = sev_guest->legacy_vm_type;
+
+ visit_type_OnOffAuto(v, name, &legacy_vm_type, errp);
}
-static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp)
+static void sev_guest_set_legacy_vm_type(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
{
- SEV_GUEST(obj)->legacy_vm_type = value;
+ SevGuestState *sev_guest = SEV_GUEST(obj);
+
+ visit_type_OnOffAuto(v, name, &sev_guest->legacy_vm_type, errp);
}
static void
@@ -2070,9 +2125,9 @@ sev_guest_class_init(ObjectClass *oc, void *data)
sev_guest_set_session_file);
object_class_property_set_description(oc, "session-file",
"guest owners session parameters (encoded with base64)");
- object_class_property_add_bool(oc, "legacy-vm-type",
- sev_guest_get_legacy_vm_type,
- sev_guest_set_legacy_vm_type);
+ object_class_property_add(oc, "legacy-vm-type", "OnOffAuto",
+ sev_guest_get_legacy_vm_type,
+ sev_guest_set_legacy_vm_type, NULL, NULL);
object_class_property_set_description(oc, "legacy-vm-type",
"use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions.");
}
@@ -2088,6 +2143,8 @@ sev_guest_instance_init(Object *obj)
object_property_add_uint32_ptr(obj, "policy", &sev_guest->policy,
OBJ_PROP_FLAG_READWRITE);
object_apply_compat_props(obj);
+
+ sev_guest->legacy_vm_type = ON_OFF_AUTO_AUTO;
}
/* guest info specific sev/sev-es */
--
2.39.3

@ -1,46 +0,0 @@
From ebb3c3536366c383fa09b0987a4efb68d018b7b8 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:24 -0500
Subject: [PATCH 064/100] i386/sev: Don't return launch measurements for
SEV-SNP guests
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [64/91] 5a29bb2d8b5a07aec6fd271ec37345e665e9cce4 (bonzini/rhel-qemu-kvm)
For SEV-SNP guests, launch measurement is queried from within the guest
during attestation, so don't attempt to return it as part of
query-sev-launch-measure.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-13-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 73ae63b162fc1fed520f53ad200712964d7d0264)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 6525b3c1a0..c3daaf1ad5 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -795,7 +795,9 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
static char *sev_get_launch_measurement(void)
{
- SevGuestState *sev_guest = SEV_GUEST(MACHINE(qdev_get_machine())->cgs);
+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
+ SevGuestState *sev_guest =
+ (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
if (sev_guest &&
SEV_COMMON(sev_guest)->state >= SEV_STATE_LAUNCH_SECRET) {
--
2.39.3

@ -1,54 +0,0 @@
From 0612c7ed587422ec7e07c27c8ca11b89c7aa8b02 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
Date: Thu, 30 May 2024 06:16:43 -0500
Subject: [PATCH 077/100] i386/sev: Enable KVM_HC_MAP_GPA_RANGE hcall for SNP
guests
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [77/91] 3c494eb54499c24121cc2c47045626478b8bb41e (bonzini/rhel-qemu-kvm)
KVM will forward GHCB page-state change requests to userspace in the
form of KVM_HC_MAP_GPA_RANGE, so make sure the hypercall handling is
enabled for SNP guests.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-32-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e3cddff93c1f88fea3b26841e792dc0be6b6fae8)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index eaf5fc6c6b..abb63062ac 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include <linux/kvm.h>
+#include <linux/kvm_para.h>
#include <linux/psp-sev.h>
#include <sys/ioctl.h>
@@ -758,6 +759,10 @@ sev_snp_launch_start(SevCommonState *sev_common)
trace_kvm_sev_snp_launch_start(start->policy,
sev_snp_guest->guest_visible_workarounds);
+ if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) {
+ return 1;
+ }
+
rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START,
start, &fw_error);
if (rc < 0) {
--
2.39.3

@ -1,167 +0,0 @@
From eed17520567c202f53ab767bfd42cfe303838772 Mon Sep 17 00:00:00 2001
From: Dov Murik <dovmurik@linux.ibm.com>
Date: Thu, 30 May 2024 06:16:33 -0500
Subject: [PATCH 078/100] i386/sev: Extract build_kernel_loader_hashes
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [78/91] 291ea10e774178826d1afd38fc8292d67c5fd42d (bonzini/rhel-qemu-kvm)
Extract the building of the kernel hashes table out from
sev_add_kernel_loader_hashes() to allow building it in
other memory areas (for SNP support).
No functional change intended.
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-22-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 06cbd66cecaa3230cccb330facac241a677b29d5)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 102 ++++++++++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 44 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index abb63062ac..73f9406715 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1754,45 +1754,16 @@ static const QemuUUID sev_cmdline_entry_guid = {
0x4d, 0x36, 0xab, 0x2a)
};
-/*
- * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
- * which is included in SEV's initial memory measurement.
- */
-bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
+static bool build_kernel_loader_hashes(PaddedSevHashTable *padded_ht,
+ SevKernelLoaderContext *ctx,
+ Error **errp)
{
- uint8_t *data;
- SevHashTableDescriptor *area;
SevHashTable *ht;
- PaddedSevHashTable *padded_ht;
uint8_t cmdline_hash[HASH_SIZE];
uint8_t initrd_hash[HASH_SIZE];
uint8_t kernel_hash[HASH_SIZE];
uint8_t *hashp;
size_t hash_len = HASH_SIZE;
- hwaddr mapped_len = sizeof(*padded_ht);
- MemTxAttrs attrs = { 0 };
- bool ret = true;
- SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
-
- /*
- * Only add the kernel hashes if the sev-guest configuration explicitly
- * stated kernel-hashes=on.
- */
- if (!sev_common->kernel_hashes) {
- return false;
- }
-
- if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
- error_setg(errp, "SEV: kernel specified but guest firmware "
- "has no hashes table GUID");
- return false;
- }
- area = (SevHashTableDescriptor *)data;
- if (!area->base || area->size < sizeof(PaddedSevHashTable)) {
- error_setg(errp, "SEV: guest firmware hashes table area is invalid "
- "(base=0x%x size=0x%x)", area->base, area->size);
- return false;
- }
/*
* Calculate hash of kernel command-line with the terminating null byte. If
@@ -1829,16 +1800,6 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
}
assert(hash_len == HASH_SIZE);
- /*
- * Populate the hashes table in the guest's memory at the OVMF-designated
- * area for the SEV hashes table
- */
- padded_ht = address_space_map(&address_space_memory, area->base,
- &mapped_len, true, attrs);
- if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
- error_setg(errp, "SEV: cannot map hashes table guest memory area");
- return false;
- }
ht = &padded_ht->ht;
ht->guid = sev_hash_table_header_guid;
@@ -1859,8 +1820,61 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
/* zero the excess data so the measurement can be reliably calculated */
memset(padded_ht->padding, 0, sizeof(padded_ht->padding));
- if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
- sizeof(*padded_ht), errp) < 0) {
+ return true;
+}
+
+/*
+ * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
+ * which is included in SEV's initial memory measurement.
+ */
+bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
+{
+ uint8_t *data;
+ SevHashTableDescriptor *area;
+ PaddedSevHashTable *padded_ht;
+ hwaddr mapped_len = sizeof(*padded_ht);
+ MemTxAttrs attrs = { 0 };
+ bool ret = true;
+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
+
+ /*
+ * Only add the kernel hashes if the sev-guest configuration explicitly
+ * stated kernel-hashes=on.
+ */
+ if (!sev_common->kernel_hashes) {
+ return false;
+ }
+
+ if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
+ error_setg(errp, "SEV: kernel specified but guest firmware "
+ "has no hashes table GUID");
+ return false;
+ }
+
+ area = (SevHashTableDescriptor *)data;
+ if (!area->base || area->size < sizeof(PaddedSevHashTable)) {
+ error_setg(errp, "SEV: guest firmware hashes table area is invalid "
+ "(base=0x%x size=0x%x)", area->base, area->size);
+ return false;
+ }
+
+ /*
+ * Populate the hashes table in the guest's memory at the OVMF-designated
+ * area for the SEV hashes table
+ */
+ padded_ht = address_space_map(&address_space_memory, area->base,
+ &mapped_len, true, attrs);
+ if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
+ error_setg(errp, "SEV: cannot map hashes table guest memory area");
+ return false;
+ }
+
+ if (build_kernel_loader_hashes(padded_ht, ctx, errp)) {
+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
+ sizeof(*padded_ht), errp) < 0) {
+ ret = false;
+ }
+ } else {
ret = false;
}
--
2.39.3

@ -1,65 +0,0 @@
From a9530c89225fce9e381929c4cd8e372068827acf Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 24 Jun 2024 10:52:49 +0200
Subject: [PATCH 089/100] i386/sev: Fallback to the default SEV device if none
provided in sev_get_capabilities()
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [89/91] 22318c20d7102815f754cec0efaf383e05ef79c1 (bonzini/rhel-qemu-kvm)
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 <mprivozn@redhat.com>
Link: https://lore.kernel.org/r/157f93712c23818be193ce785f648f0060b33dee.1719218926.git.mprivozn@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3fb24530b2bb1346a44e17becefc9865b40a2257)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 53b7f7315b..491fab74fd 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -585,13 +585,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",
--
2.39.3

@ -1,48 +0,0 @@
From b672cdf8c10a530b5bcf6dd4489632891eb2c731 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 24 Jun 2024 10:52:48 +0200
Subject: [PATCH 088/100] i386/sev: Fix error message in sev_get_capabilities()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [88/91] ff8a8b27af02e565172ffe39d0571c234317713d (bonzini/rhel-qemu-kvm)
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 <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/r/b4648905d399780063dc70851d3d6a3cd28719a5.1719218926.git.mprivozn@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e306ae87e0ef04bc7a5dec6db693f6ea09d64d45)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 37de80adc7..53b7f7315b 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -595,7 +595,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;
}
--
2.39.3

@ -1,530 +0,0 @@
From 900859fd3445b9a71f1a9a8befda17f0c33f3923 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 30 May 2024 06:16:19 -0500
Subject: [PATCH 059/100] i386/sev: Introduce 'sev-snp-guest' object
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [59/91] 3e585113d209176c2b97ad5e4fe943f19dfdcaeb (bonzini/rhel-qemu-kvm)
SEV-SNP support relies on a different set of properties/state than the
existing 'sev-guest' object. This patch introduces the 'sev-snp-guest'
object, which can be used to configure an SEV-SNP guest. For example,
a default-configured SEV-SNP guest with no additional information
passed in for use with attestation:
-object sev-snp-guest,id=sev0
or a fully-specified SEV-SNP guest where all spec-defined binary
blobs are passed in as base64-encoded strings:
-object sev-snp-guest,id=sev0, \
policy=0x30000, \
init-flags=0, \
id-block=YWFhYWFhYWFhYWFhYWFhCg==, \
id-auth=CxHK/OKLkXGn/KpAC7Wl1FSiisWDbGTEKz..., \
author-key-enabled=on, \
host-data=LNkCWBRC5CcdGXirbNUV1OrsR28s..., \
guest-visible-workarounds=AA==, \
See the QAPI schema updates included in this patch for more usage
details.
In some cases these blobs may be up to 4096 characters, but this is
generally well below the default limit for linux hosts where
command-line sizes are defined by the sysconf-configurable ARG_MAX
value, which defaults to 2097152 characters for Ubuntu hosts, for
example.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7b34df44260b391e33bc3acf1ced30019d9aadf1)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
docs/system/i386/amd-memory-encryption.rst | 70 +++++-
qapi/qom.json | 58 +++++
target/i386/sev.c | 253 +++++++++++++++++++++
target/i386/sev.h | 1 +
4 files changed, 380 insertions(+), 2 deletions(-)
diff --git a/docs/system/i386/amd-memory-encryption.rst b/docs/system/i386/amd-memory-encryption.rst
index e9bc142bc1..748f5094ba 100644
--- a/docs/system/i386/amd-memory-encryption.rst
+++ b/docs/system/i386/amd-memory-encryption.rst
@@ -25,8 +25,8 @@ support for notifying a guest's operating system when certain types of VMEXITs
are about to occur. This allows the guest to selectively share information with
the hypervisor to satisfy the requested function.
-Launching
----------
+Launching (SEV and SEV-ES)
+--------------------------
Boot images (such as bios) must be encrypted before a guest can be booted. The
``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images: ``LAUNCH_START``,
@@ -161,6 +161,72 @@ The value of GCTX.LD is
If kernel hashes are not used, or SEV-ES is disabled, use empty blobs for
``kernel_hashes_blob`` and ``vmsas_blob`` as needed.
+Launching (SEV-SNP)
+-------------------
+Boot images (such as bios) must be encrypted before a guest can be booted. The
+``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images:
+``SNP_LAUNCH_START``, ``SNP_LAUNCH_UPDATE``, and ``SNP_LAUNCH_FINISH``. These
+three commands communicate with SEV-SNP firmware to generate a fresh memory
+encryption key for the VM, encrypt the boot images for a successful launch. For
+more details on the SEV-SNP firmware interfaces used by these commands please
+see the SEV-SNP Firmware ABI.
+
+``SNP_LAUNCH_START`` is called first to create a cryptographic launch context
+within the firmware. To create this context, the guest owner must provide a
+guest policy and other parameters as described in the SEV-SNP firmware
+specification. The launch parameters should be specified as described in the
+QAPI schema for the sev-snp-guest object.
+
+The ``SNP_LAUNCH_START`` uses the following parameters, which can be configured
+by the corresponding parameters documented in the QAPI schema for the
+'sev-snp-guest' object.
+
++--------+-------+----------+-------------------------------------------------+
+| key | type | default | meaning |
++---------------------------+-------------------------------------------------+
+| policy | hex | 0x30000 | a 64-bit guest policy |
++---------------------------+-------------------------------------------------+
+| guest-visible-workarounds | string| 0 | 16-byte base64 encoded string|
+| | | | for guest OS visible |
+| | | | workarounds. |
++---------------------------+-------------------------------------------------+
+
+``SNP_LAUNCH_UPDATE`` encrypts the memory region using the cryptographic context
+created via the ``SNP_LAUNCH_START`` command. If required, this command can be
+called multiple times to encrypt different memory regions. The command also
+calculates the measurement of the memory contents as it encrypts.
+
+``SNP_LAUNCH_FINISH`` finalizes the guest launch flow. Optionally, while
+finalizing the launch the firmware can perform checks on the launch digest
+computing through the ``SNP_LAUNCH_UPDATE``. To perform the check the user must
+supply the id block, authentication blob and host data that should be included
+in the attestation report. See the SEV-SNP spec for further details.
+
+The ``SNP_LAUNCH_FINISH`` uses the following parameters, which can be configured
+by the corresponding parameters documented in the QAPI schema for the
+'sev-snp-guest' object.
+
++--------------------+-------+----------+-------------------------------------+
+| key | type | default | meaning |
++--------------------+-------+----------+-------------------------------------+
+| id-block | string| none | base64 encoded ID block |
++--------------------+-------+----------+-------------------------------------+
+| id-auth | string| none | base64 encoded authentication |
+| | | | information |
++--------------------+-------+----------+-------------------------------------+
+| author-key-enabled | bool | 0 | auth block contains author key |
++--------------------+-------+----------+-------------------------------------+
+| host_data | string| none | host provided data |
++--------------------+-------+----------+-------------------------------------+
+
+To launch a SEV-SNP guest (additional parameters are documented in the QAPI
+schema for the 'sev-snp-guest' object)::
+
+ # ${QEMU} \
+ -machine ...,confidential-guest-support=sev0 \
+ -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1
+
+
Debugging
---------
diff --git a/qapi/qom.json b/qapi/qom.json
index 056b38f491..8bd299265e 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -929,6 +929,62 @@
'*handle': 'uint32',
'*legacy-vm-type': 'bool' } }
+##
+# @SevSnpGuestProperties:
+#
+# Properties for sev-snp-guest objects. Most of these are direct
+# arguments for the KVM_SNP_* interfaces documented in the Linux
+# kernel source under
+# Documentation/arch/x86/amd-memory-encryption.rst, which are in turn
+# closely coupled with the SNP_INIT/SNP_LAUNCH_* firmware commands
+# documented in the SEV-SNP Firmware ABI Specification (Rev 0.9).
+#
+# More usage information is also available in the QEMU source tree
+# under docs/amd-memory-encryption.
+#
+# @policy: the 'POLICY' parameter to the SNP_LAUNCH_START command, as
+# defined in the SEV-SNP firmware ABI (default: 0x30000)
+#
+# @guest-visible-workarounds: 16-byte, base64-encoded blob to report
+# hypervisor-defined workarounds, corresponding to the 'GOSVW'
+# parameter of the SNP_LAUNCH_START command defined in the SEV-SNP
+# firmware ABI (default: all-zero)
+#
+# @id-block: 96-byte, base64-encoded blob to provide the 'ID Block'
+# structure for the SNP_LAUNCH_FINISH command defined in the
+# SEV-SNP firmware ABI (default: all-zero)
+#
+# @id-auth: 4096-byte, base64-encoded blob to provide the 'ID
+# Authentication Information Structure' for the SNP_LAUNCH_FINISH
+# command defined in the SEV-SNP firmware ABI (default: all-zero)
+#
+# @author-key-enabled: true if 'id-auth' blob contains the 'AUTHOR_KEY'
+# field defined SEV-SNP firmware ABI (default: false)
+#
+# @host-data: 32-byte, base64-encoded, user-defined blob to provide to
+# the guest, as documented for the 'HOST_DATA' parameter of the
+# SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI (default:
+# all-zero)
+#
+# @vcek-disabled: Guests are by default allowed to choose between VLEK
+# (Versioned Loaded Endorsement Key) or VCEK (Versioned Chip
+# Endorsement Key) when requesting attestation reports from
+# firmware. Set this to true to disable the use of VCEK.
+# (default: false) (since: 9.1)
+#
+# Since: 9.1
+##
+{ 'struct': 'SevSnpGuestProperties',
+ 'base': 'SevCommonProperties',
+ 'data': {
+ '*policy': 'uint64',
+ '*guest-visible-workarounds': 'str',
+ '*id-block': 'str',
+ '*id-auth': 'str',
+ '*author-key-enabled': 'bool',
+ '*host-data': 'str',
+ '*vcek-disabled': 'bool' } }
+
##
# @ThreadContextProperties:
#
@@ -1007,6 +1063,7 @@
{ 'name': 'secret_keyring',
'if': 'CONFIG_SECRET_KEYRING' },
'sev-guest',
+ 'sev-snp-guest',
'thread-context',
's390-pv-guest',
'throttle-group',
@@ -1077,6 +1134,7 @@
'secret_keyring': { 'type': 'SecretKeyringProperties',
'if': 'CONFIG_SECRET_KEYRING' },
'sev-guest': 'SevGuestProperties',
+ 'sev-snp-guest': 'SevSnpGuestProperties',
'thread-context': 'ThreadContextProperties',
'throttle-group': 'ThrottleGroupProperties',
'tls-creds-anon': 'TlsCredsAnonProperties',
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 28a018ed83..a81b3228d4 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -42,6 +42,7 @@
OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON)
OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST)
+OBJECT_DECLARE_TYPE(SevSnpGuestState, SevCommonStateClass, SEV_SNP_GUEST)
struct SevCommonState {
X86ConfidentialGuest parent_obj;
@@ -96,8 +97,22 @@ struct SevGuestState {
bool legacy_vm_type;
};
+struct SevSnpGuestState {
+ SevCommonState parent_obj;
+
+ /* configuration parameters */
+ char *guest_visible_workarounds;
+ char *id_block;
+ char *id_auth;
+ char *host_data;
+
+ struct kvm_sev_snp_launch_start kvm_start_conf;
+ struct kvm_sev_snp_launch_finish kvm_finish_conf;
+};
+
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
#define DEFAULT_SEV_DEVICE "/dev/sev"
+#define DEFAULT_SEV_SNP_POLICY 0x30000
#define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
typedef struct __attribute__((__packed__)) SevInfoBlock {
@@ -1500,11 +1515,249 @@ static const TypeInfo sev_guest_info = {
.class_init = sev_guest_class_init,
};
+static void
+sev_snp_guest_get_policy(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ visit_type_uint64(v, name,
+ (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
+ errp);
+}
+
+static void
+sev_snp_guest_set_policy(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ visit_type_uint64(v, name,
+ (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
+ errp);
+}
+
+static char *
+sev_snp_guest_get_guest_visible_workarounds(Object *obj, Error **errp)
+{
+ return g_strdup(SEV_SNP_GUEST(obj)->guest_visible_workarounds);
+}
+
+static void
+sev_snp_guest_set_guest_visible_workarounds(Object *obj, const char *value,
+ Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+ struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
+ g_autofree guchar *blob;
+ gsize len;
+
+ g_free(sev_snp_guest->guest_visible_workarounds);
+
+ /* store the base64 str so we don't need to re-encode in getter */
+ sev_snp_guest->guest_visible_workarounds = g_strdup(value);
+
+ blob = qbase64_decode(sev_snp_guest->guest_visible_workarounds,
+ -1, &len, errp);
+ if (!blob) {
+ return;
+ }
+
+ if (len != sizeof(start->gosvw)) {
+ error_setg(errp, "parameter length of %lu exceeds max of %lu",
+ len, sizeof(start->gosvw));
+ return;
+ }
+
+ memcpy(start->gosvw, blob, len);
+}
+
+static char *
+sev_snp_guest_get_id_block(Object *obj, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ return g_strdup(sev_snp_guest->id_block);
+}
+
+static void
+sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
+ gsize len;
+
+ g_free(sev_snp_guest->id_block);
+ g_free((guchar *)finish->id_block_uaddr);
+
+ /* store the base64 str so we don't need to re-encode in getter */
+ sev_snp_guest->id_block = g_strdup(value);
+
+ finish->id_block_uaddr =
+ (uint64_t)qbase64_decode(sev_snp_guest->id_block, -1, &len, errp);
+
+ if (!finish->id_block_uaddr) {
+ return;
+ }
+
+ if (len != KVM_SEV_SNP_ID_BLOCK_SIZE) {
+ error_setg(errp, "parameter length of %lu not equal to %u",
+ len, KVM_SEV_SNP_ID_BLOCK_SIZE);
+ return;
+ }
+
+ finish->id_block_en = (len) ? 1 : 0;
+}
+
+static char *
+sev_snp_guest_get_id_auth(Object *obj, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ return g_strdup(sev_snp_guest->id_auth);
+}
+
+static void
+sev_snp_guest_set_id_auth(Object *obj, const char *value, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
+ gsize len;
+
+ g_free(sev_snp_guest->id_auth);
+ g_free((guchar *)finish->id_auth_uaddr);
+
+ /* store the base64 str so we don't need to re-encode in getter */
+ sev_snp_guest->id_auth = g_strdup(value);
+
+ finish->id_auth_uaddr =
+ (uint64_t)qbase64_decode(sev_snp_guest->id_auth, -1, &len, errp);
+
+ if (!finish->id_auth_uaddr) {
+ return;
+ }
+
+ if (len > KVM_SEV_SNP_ID_AUTH_SIZE) {
+ error_setg(errp, "parameter length:ID_AUTH %lu exceeds max of %u",
+ len, KVM_SEV_SNP_ID_AUTH_SIZE);
+ return;
+ }
+}
+
+static bool
+sev_snp_guest_get_author_key_enabled(Object *obj, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ return !!sev_snp_guest->kvm_finish_conf.auth_key_en;
+}
+
+static void
+sev_snp_guest_set_author_key_enabled(Object *obj, bool value, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ sev_snp_guest->kvm_finish_conf.auth_key_en = value;
+}
+
+static bool
+sev_snp_guest_get_vcek_disabled(Object *obj, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ return !!sev_snp_guest->kvm_finish_conf.vcek_disabled;
+}
+
+static void
+sev_snp_guest_set_vcek_disabled(Object *obj, bool value, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ sev_snp_guest->kvm_finish_conf.vcek_disabled = value;
+}
+
+static char *
+sev_snp_guest_get_host_data(Object *obj, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ return g_strdup(sev_snp_guest->host_data);
+}
+
+static void
+sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
+ g_autofree guchar *blob;
+ gsize len;
+
+ g_free(sev_snp_guest->host_data);
+
+ /* store the base64 str so we don't need to re-encode in getter */
+ sev_snp_guest->host_data = g_strdup(value);
+
+ blob = qbase64_decode(sev_snp_guest->host_data, -1, &len, errp);
+
+ if (!blob) {
+ return;
+ }
+
+ if (len != sizeof(finish->host_data)) {
+ error_setg(errp, "parameter length of %lu not equal to %lu",
+ len, sizeof(finish->host_data));
+ return;
+ }
+
+ memcpy(finish->host_data, blob, len);
+}
+
+static void
+sev_snp_guest_class_init(ObjectClass *oc, void *data)
+{
+ object_class_property_add(oc, "policy", "uint64",
+ sev_snp_guest_get_policy,
+ sev_snp_guest_set_policy, NULL, NULL);
+ object_class_property_add_str(oc, "guest-visible-workarounds",
+ sev_snp_guest_get_guest_visible_workarounds,
+ sev_snp_guest_set_guest_visible_workarounds);
+ object_class_property_add_str(oc, "id-block",
+ sev_snp_guest_get_id_block,
+ sev_snp_guest_set_id_block);
+ object_class_property_add_str(oc, "id-auth",
+ sev_snp_guest_get_id_auth,
+ sev_snp_guest_set_id_auth);
+ object_class_property_add_bool(oc, "author-key-enabled",
+ sev_snp_guest_get_author_key_enabled,
+ sev_snp_guest_set_author_key_enabled);
+ object_class_property_add_bool(oc, "vcek-required",
+ sev_snp_guest_get_vcek_disabled,
+ sev_snp_guest_set_vcek_disabled);
+ object_class_property_add_str(oc, "host-data",
+ sev_snp_guest_get_host_data,
+ sev_snp_guest_set_host_data);
+}
+
+static void
+sev_snp_guest_instance_init(Object *obj)
+{
+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+ /* default init/start/finish params for kvm */
+ sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
+}
+
+/* guest info specific to sev-snp */
+static const TypeInfo sev_snp_guest_info = {
+ .parent = TYPE_SEV_COMMON,
+ .name = TYPE_SEV_SNP_GUEST,
+ .instance_size = sizeof(SevSnpGuestState),
+ .class_init = sev_snp_guest_class_init,
+ .instance_init = sev_snp_guest_instance_init,
+};
+
static void
sev_register_types(void)
{
type_register_static(&sev_common_info);
type_register_static(&sev_guest_info);
+ type_register_static(&sev_snp_guest_info);
}
type_init(sev_register_types);
diff --git a/target/i386/sev.h b/target/i386/sev.h
index 668374eef3..bedc667eeb 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -22,6 +22,7 @@
#define TYPE_SEV_COMMON "sev-common"
#define TYPE_SEV_GUEST "sev-guest"
+#define TYPE_SEV_SNP_GUEST "sev-snp-guest"
#define SEV_POLICY_NODBG 0x1
#define SEV_POLICY_NOKS 0x2
--
2.39.3

@ -1,85 +0,0 @@
From be37914ae54c8aebc218cf41b37bc0ea1563daae Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 31 May 2024 12:51:44 +0200
Subject: [PATCH 074/100] i386/sev: Invoke launch_updata_data() for SEV class
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [74/91] f1b588a9ffecd6944a78186d88a6be3849698710 (bonzini/rhel-qemu-kvm)
Add launch_update_data() in SevCommonStateClass and
invoke as sev_launch_update_data() for SEV object.
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-26-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9861405a8f845133b7984322c2df0c43a45553c3)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 7b5c4b4874..8834cf9441 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -74,6 +74,7 @@ struct SevCommonStateClass {
/* public */
int (*launch_start)(SevCommonState *sev_common);
void (*launch_finish)(SevCommonState *sev_common);
+ int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len);
int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
};
@@ -929,7 +930,7 @@ out:
}
static int
-sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len)
+sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, uint8_t *addr, uint64_t len)
{
int ret, fw_error;
struct kvm_sev_launch_update_data update;
@@ -941,7 +942,7 @@ sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len)
update.uaddr = (uintptr_t)addr;
update.len = len;
trace_kvm_sev_launch_update_data(addr, len);
- ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
&update, &fw_error);
if (ret) {
error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
@@ -1487,6 +1488,7 @@ int
sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common);
if (!sev_common) {
return 0;
@@ -1494,7 +1496,9 @@ sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
/* if SEV is in update state then encrypt the data else do nothing */
if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
- int ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len);
+ int ret;
+
+ ret = klass->launch_update_data(sev_common, gpa, ptr, len);
if (ret < 0) {
error_setg(errp, "SEV: Failed to encrypt pflash rom");
return ret;
@@ -1968,6 +1972,7 @@ sev_guest_class_init(ObjectClass *oc, void *data)
klass->launch_start = sev_launch_start;
klass->launch_finish = sev_launch_finish;
+ klass->launch_update_data = sev_launch_update_data;
klass->kvm_init = sev_kvm_init;
x86_klass->kvm_type = sev_kvm_type;
--
2.39.3

@ -1,55 +0,0 @@
From 32899eb4fa5143b795b107de4857adce2cf1d434 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Thu, 30 May 2024 06:16:38 -0500
Subject: [PATCH 075/100] i386/sev: Invoke launch_updata_data() for SNP class
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [75/91] 3520af5847f8dddb6d7fe7ad5feb308230f387b9 (bonzini/rhel-qemu-kvm)
Invoke as sev_snp_launch_update_data() for SNP object.
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-27-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0765d136eba400ad1cb7cae18438bb10eace64dc)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 8834cf9441..eaf5fc6c6b 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1091,6 +1091,15 @@ snp_launch_update_data(uint64_t gpa, void *hva,
return 0;
}
+static int
+sev_snp_launch_update_data(SevCommonState *sev_common, hwaddr gpa,
+ uint8_t *ptr, uint64_t len)
+{
+ int ret = snp_launch_update_data(gpa, ptr, len,
+ KVM_SEV_SNP_PAGE_TYPE_NORMAL);
+ return ret;
+}
+
static int
sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info,
const KvmCpuidInfo *kvm_cpuid_info)
@@ -2216,6 +2225,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
klass->launch_start = sev_snp_launch_start;
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->kvm_type = sev_snp_kvm_type;
--
2.39.3

@ -1,47 +0,0 @@
From fa6076291eb45255bc2fe523399d7d0647fc5570 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Fri, 7 Jun 2024 13:36:10 -0500
Subject: [PATCH 085/100] i386/sev: Move SEV_COMMON null check before
dereferencing
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [85/91] e8d2bfd077766a5e7777b9337d0e77146f883224 (bonzini/rhel-qemu-kvm)
Fixes Coverity CID 1546886.
Fixes: 9861405a8f ("i386/sev: Invoke launch_updata_data() for SEV class")
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240607183611.1111100-3-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 48779faef3c8e2fe70bd8285bffa731bd76dc844)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 7c9df621de..f18432f58e 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -1529,11 +1529,12 @@ int
sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
{
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
- SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common);
+ SevCommonStateClass *klass;
if (!sev_common) {
return 0;
}
+ klass = SEV_COMMON_GET_CLASS(sev_common);
/* if SEV is in update state then encrypt the data else do nothing */
if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
--
2.39.3

@ -1,88 +0,0 @@
From 4d96ca893126d4c17c9fe03c76973b1d4a414f21 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Thu, 30 May 2024 06:16:18 -0500
Subject: [PATCH 058/100] i386/sev: Move sev_launch_finish to separate class
method
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [58/91] 7865710d320a6df7038ef7016d350aa9cdcea326 (bonzini/rhel-qemu-kvm)
When sev-snp-guest objects are introduced there will be a number of
differences in how the launch finish is handled compared to the existing
sev-guest object. Move sev_launch_finish() to a class method to make it
easier to implement SNP-specific launch update functionality later.
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-7-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit bce615a14aec07cab0488e5a242f6a91e641efcb)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index b2aa0d6f99..28a018ed83 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -71,6 +71,7 @@ struct SevCommonStateClass {
/* public */
int (*launch_start)(SevCommonState *sev_common);
+ void (*launch_finish)(SevCommonState *sev_common);
};
/**
@@ -801,12 +802,12 @@ static Notifier sev_machine_done_notify = {
};
static void
-sev_launch_finish(SevGuestState *sev_guest)
+sev_launch_finish(SevCommonState *sev_common)
{
int ret, error;
trace_kvm_sev_launch_finish();
- ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_FINISH, 0,
+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_FINISH, 0,
&error);
if (ret) {
error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
@@ -814,7 +815,7 @@ sev_launch_finish(SevGuestState *sev_guest)
exit(1);
}
- sev_set_guest_state(SEV_COMMON(sev_guest), SEV_STATE_RUNNING);
+ sev_set_guest_state(sev_common, SEV_STATE_RUNNING);
/* add migration blocker */
error_setg(&sev_mig_blocker,
@@ -826,10 +827,11 @@ static void
sev_vm_state_change(void *opaque, bool running, RunState state)
{
SevCommonState *sev_common = opaque;
+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(opaque);
if (running) {
if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) {
- sev_launch_finish(SEV_GUEST(sev_common));
+ klass->launch_finish(sev_common);
}
}
}
@@ -1457,6 +1459,7 @@ sev_guest_class_init(ObjectClass *oc, void *data)
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
klass->launch_start = sev_launch_start;
+ klass->launch_finish = sev_launch_finish;
object_class_property_add_str(oc, "dh-cert-file",
sev_guest_get_dh_cert_file,
--
2.39.3

@ -1,91 +0,0 @@
From a170ba2c7dbf2775eb9047779d3643a2a81bb372 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Thu, 30 May 2024 06:16:17 -0500
Subject: [PATCH 057/100] i386/sev: Move sev_launch_update to separate class
method
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [57/91] 4f31e7afaec6f2c2a7c06cda4d7d27d4037e53e0 (bonzini/rhel-qemu-kvm)
When sev-snp-guest objects are introduced there will be a number of
differences in how the launch data is handled compared to the existing
sev-guest object. Move sev_launch_start() to a class method to make it
easier to implement SNP-specific launch update functionality later.
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-6-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6600f1ac0c81cbe67faf048ea07f78542dea925f)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 33e606eea0..b2aa0d6f99 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -69,6 +69,8 @@ struct SevCommonState {
struct SevCommonStateClass {
X86ConfidentialGuestClass parent_class;
+ /* public */
+ int (*launch_start)(SevCommonState *sev_common);
};
/**
@@ -632,16 +634,16 @@ sev_read_file_base64(const char *filename, guchar **data, gsize *len)
}
static int
-sev_launch_start(SevGuestState *sev_guest)
+sev_launch_start(SevCommonState *sev_common)
{
gsize sz;
int ret = 1;
int fw_error, rc;
+ SevGuestState *sev_guest = SEV_GUEST(sev_common);
struct kvm_sev_launch_start start = {
.handle = sev_guest->handle, .policy = sev_guest->policy
};
guchar *session = NULL, *dh_cert = NULL;
- SevCommonState *sev_common = SEV_COMMON(sev_guest);
if (sev_guest->session_file) {
if (sev_read_file_base64(sev_guest->session_file, &session, &sz) < 0) {
@@ -862,6 +864,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
uint32_t ebx;
uint32_t host_cbitpos;
struct sev_user_data_status status = {};
+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
ret = ram_block_discard_disable(true);
if (ret) {
@@ -952,7 +955,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
goto err;
}
- sev_launch_start(SEV_GUEST(sev_common));
+ ret = klass->launch_start(sev_common);
if (ret) {
error_setg(errp, "%s: failed to create encryption context", __func__);
goto err;
@@ -1451,6 +1454,10 @@ static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp)
static void
sev_guest_class_init(ObjectClass *oc, void *data)
{
+ SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
+
+ klass->launch_start = sev_launch_start;
+
object_class_property_add_str(oc, "dh-cert-file",
sev_guest_get_dh_cert_file,
sev_guest_set_dh_cert_file);
--
2.39.3

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save