Compare commits
No commits in common. "c8-stream-rhel" and "c10s-aie-nv" have entirely different histories.
c8-stream-
...
c10s-aie-n
43
.gitignore
vendored
43
.gitignore
vendored
@ -1,5 +1,38 @@
|
||||
SOURCES/qemu-6.2.0.tar.xz
|
||||
SOURCES/tests_data_acpi_pc_SSDT.dimmpxm
|
||||
SOURCES/tests_data_acpi_q35_FACP.slic
|
||||
SOURCES/tests_data_acpi_q35_SSDT.dimmpxm
|
||||
SOURCES/tests_data_acpi_virt_SSDT.memhp
|
||||
/qemu-3.1.0.tar.xz
|
||||
/qemu-4.0.0.tar.xz
|
||||
/qemu-4.1.0-rc4.tar.xz
|
||||
/qemu-4.1.0.tar.xz
|
||||
/qemu-4.2.0-rc1.tar.xz
|
||||
/qemu-4.2.0-rc4.tar.xz
|
||||
/qemu-4.2.0.tar.xz
|
||||
/qemu-5.0.0-rc0.tar.xz
|
||||
/qemu-5.0.0-rc1.tar.xz
|
||||
/qemu-5.0.0-rc2.tar.xz
|
||||
/qemu-5.0.0-rc3.tar.xz
|
||||
/qemu-5.0.0-rc4.tar.xz
|
||||
/qemu-5.0.0.tar.xz
|
||||
/qemu-5.1.0.tar.xz
|
||||
/qemu-5.2.0-rc1.tar.xz
|
||||
/qemu-5.2.0-rc3.tar.xz
|
||||
/qemu-5.2.0.tar.xz
|
||||
/qemu-6.0.0.tar.xz
|
||||
/qemu-kvm*.src.rpm
|
||||
/patches.*
|
||||
/*.orig
|
||||
/qemu-6.1.0.tar.xz
|
||||
/qemu-6.2.0.tar.xz
|
||||
/qemu-7.0.0.tar.xz
|
||||
/capstone.tar.gz
|
||||
/qemu-7.1.0.tar.xz
|
||||
/qemu-7.2.0.tar.xz
|
||||
/qemu-8.0.0.tar.xz
|
||||
/qemu-8.1.0.tar.xz
|
||||
/qemu-8.2.0.tar.xz
|
||||
/qemu-9.0.0.tar.xz
|
||||
/qemu-9.1.0.tar.xz
|
||||
/qemu-10.0.0.tar.xz
|
||||
/qemu-10.1.0.tar.xz
|
||||
/IORT
|
||||
/IORT.its_off
|
||||
/IORT.smmuv3-dev
|
||||
/IORT.smmuv3-legacy
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
68cd61a466170115b88817e2d52db2cd7a92f43a SOURCES/qemu-6.2.0.tar.xz
|
||||
c4b34092bc5af1ba7febfca1477320fb024e8acd SOURCES/tests_data_acpi_pc_SSDT.dimmpxm
|
||||
19349e3517143bd1af56a5444e927ba37a111f72 SOURCES/tests_data_acpi_q35_FACP.slic
|
||||
4632d10ae8cedad4d5d760ed211f83f0dc81005d SOURCES/tests_data_acpi_q35_SSDT.dimmpxm
|
||||
ef12eed43cc357fb134db6fa3c7ffc83e222a97d SOURCES/tests_data_acpi_virt_SSDT.memhp
|
||||
123
0001-Initial-redhat-build.patch
Normal file
123
0001-Initial-redhat-build.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 67dd7ae821a4fba377f2240d4930b96df012b840 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 26 May 2021 10:56:02 +0200
|
||||
Subject: [PATCH] Initial redhat build
|
||||
|
||||
This patch introduces redhat build structure in redhat subdirectory. In addition,
|
||||
several issues are fixed in QEMU tree:
|
||||
|
||||
- Change of app name for sasl_server_init in VNC code from qemu to qemu-kvm
|
||||
- As we use qemu-kvm as name in all places, this is updated to be consistent
|
||||
- Man page renamed from qemu to qemu-kvm
|
||||
- man page is installed using make install so we have to fix it in qemu tree
|
||||
|
||||
We disable make check due to issues with some of the tests.
|
||||
|
||||
We are rebasing from qemu-kvm-10.0.0-12.el10.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
README.systemtap | 43 +++++++++++++++++++++++++
|
||||
scripts/qemu-guest-agent/fsfreeze-hook | 4 +--
|
||||
scripts/systemtap/conf.d/qemu_kvm.conf | 4 +++
|
||||
scripts/systemtap/script.d/qemu_kvm.stp | 1 +
|
||||
ui/vnc-auth-sasl.c | 2 +-
|
||||
5 files changed, 51 insertions(+), 3 deletions(-)
|
||||
create mode 100644 README.systemtap
|
||||
create mode 100644 scripts/systemtap/conf.d/qemu_kvm.conf
|
||||
create mode 100644 scripts/systemtap/script.d/qemu_kvm.stp
|
||||
|
||||
diff --git a/README.systemtap b/README.systemtap
|
||||
new file mode 100644
|
||||
index 0000000000..ad913fc990
|
||||
--- /dev/null
|
||||
+++ b/README.systemtap
|
||||
@@ -0,0 +1,43 @@
|
||||
+QEMU tracing using systemtap-initscript
|
||||
+---------------------------------------
|
||||
+
|
||||
+You can capture QEMU trace data all the time using systemtap-initscript. This
|
||||
+uses SystemTap's flight recorder mode to trace all running guests to a
|
||||
+fixed-size buffer on the host. Old trace entries are overwritten by new
|
||||
+entries when the buffer size wraps.
|
||||
+
|
||||
+1. Install the systemtap-initscript package:
|
||||
+ # yum install systemtap-initscript
|
||||
+
|
||||
+2. Install the systemtap scripts and the conf file:
|
||||
+ # cp /usr/share/qemu-kvm/systemtap/script.d/qemu_kvm.stp /etc/systemtap/script.d/
|
||||
+ # cp /usr/share/qemu-kvm/systemtap/conf.d/qemu_kvm.conf /etc/systemtap/conf.d/
|
||||
+
|
||||
+The set of trace events to enable is given in qemu_kvm.stp. This SystemTap
|
||||
+script can be customized to add or remove trace events provided in
|
||||
+/usr/share/systemtap/tapset/qemu-kvm-simpletrace.stp.
|
||||
+
|
||||
+SystemTap customizations can be made to qemu_kvm.conf to control the flight
|
||||
+recorder buffer size and whether to store traces in memory only or disk too.
|
||||
+See stap(1) for option documentation.
|
||||
+
|
||||
+3. Start the systemtap service.
|
||||
+ # service systemtap start qemu_kvm
|
||||
+
|
||||
+4. Make the service start at boot time.
|
||||
+ # chkconfig systemtap on
|
||||
+
|
||||
+5. Confirm that the service works.
|
||||
+ # service systemtap status qemu_kvm
|
||||
+ qemu_kvm is running...
|
||||
+
|
||||
+When you want to inspect the trace buffer, perform the following steps:
|
||||
+
|
||||
+1. Dump the trace buffer.
|
||||
+ # staprun -A qemu_kvm >/tmp/trace.log
|
||||
+
|
||||
+2. Start the systemtap service because the preceding step stops the service.
|
||||
+ # service systemtap start qemu_kvm
|
||||
+
|
||||
+3. Translate the trace record to readable format.
|
||||
+ # /usr/share/qemu-kvm/simpletrace.py --no-header /usr/share/qemu-kvm/trace-events /tmp/trace.log
|
||||
diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook
|
||||
index c1feb6f5ce..d5d8d4daf8 100755
|
||||
--- a/scripts/qemu-guest-agent/fsfreeze-hook
|
||||
+++ b/scripts/qemu-guest-agent/fsfreeze-hook
|
||||
@@ -7,8 +7,8 @@
|
||||
# "freeze" argument before the filesystem is frozen. And for fsfreeze-thaw
|
||||
# request, it is issued with "thaw" argument after filesystem is thawed.
|
||||
|
||||
-LOGFILE=/var/log/qga-fsfreeze-hook.log
|
||||
-FSFREEZE_D=$(dirname -- "$0")/fsfreeze-hook.d
|
||||
+LOGFILE=/var/log/qemu-ga/qga-fsfreeze-hook.log
|
||||
+FSFREEZE_D=$(dirname -- "$(realpath $0)")/fsfreeze-hook.d
|
||||
|
||||
# Check whether file $1 is a backup or rpm-generated file and should be ignored
|
||||
is_ignored_file() {
|
||||
diff --git a/scripts/systemtap/conf.d/qemu_kvm.conf b/scripts/systemtap/conf.d/qemu_kvm.conf
|
||||
new file mode 100644
|
||||
index 0000000000..372d8160a4
|
||||
--- /dev/null
|
||||
+++ b/scripts/systemtap/conf.d/qemu_kvm.conf
|
||||
@@ -0,0 +1,4 @@
|
||||
+# Force load uprobes (see BZ#1118352)
|
||||
+stap -e 'probe process("/usr/libexec/qemu-kvm").function("main") { printf("") }' -c true
|
||||
+
|
||||
+qemu_kvm_OPT="-s4" # per-CPU buffer size, in megabytes
|
||||
diff --git a/scripts/systemtap/script.d/qemu_kvm.stp b/scripts/systemtap/script.d/qemu_kvm.stp
|
||||
new file mode 100644
|
||||
index 0000000000..c04abf9449
|
||||
--- /dev/null
|
||||
+++ b/scripts/systemtap/script.d/qemu_kvm.stp
|
||||
@@ -0,0 +1 @@
|
||||
+probe qemu.kvm.simpletrace.handle_qmp_command,qemu.kvm.simpletrace.monitor_protocol_*,qemu.kvm.simpletrace.migrate_set_state {}
|
||||
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
|
||||
index 3f4cfc471d..09dafba18d 100644
|
||||
--- a/ui/vnc-auth-sasl.c
|
||||
+++ b/ui/vnc-auth-sasl.c
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
bool vnc_sasl_server_init(Error **errp)
|
||||
{
|
||||
- int saslErr = sasl_server_init(NULL, "qemu");
|
||||
+ int saslErr = sasl_server_init(NULL, "qemu-kvm");
|
||||
|
||||
if (saslErr != SASL_OK) {
|
||||
error_setg(errp, "Failed to initialize SASL auth: %s",
|
||||
847
0002-Enable-disable-devices-for-RHEL.patch
Normal file
847
0002-Enable-disable-devices-for-RHEL.patch
Normal file
@ -0,0 +1,847 @@
|
||||
From f9d8a760501e0cf4147a7d9bcf59c765745fbbe3 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 7 Dec 2022 03:05:48 -0500
|
||||
Subject: [PATCH] Enable/disable devices for RHEL
|
||||
|
||||
This commit adds all changes related to changes in supported devices.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
.../aarch64-softmmu/aarch64-rh-devices.mak | 49 ++++++++
|
||||
configs/devices/rh-virtio.mak | 10 ++
|
||||
.../riscv64-softmmu/riscv64-rh-devices.mak | 39 ++++++
|
||||
.../s390x-softmmu/s390x-rh-devices.mak | 20 +++
|
||||
.../x86_64-softmmu/x86_64-rh-devices.mak | 118 ++++++++++++++++++
|
||||
hw/arm/virt.c | 4 +
|
||||
hw/cxl/meson.build | 3 +-
|
||||
hw/ide/piix.c | 5 +-
|
||||
hw/input/pckbd.c | 2 +
|
||||
hw/net/e1000.c | 2 +
|
||||
hw/net/rtl8139.c | 4 +
|
||||
hw/usb/meson.build | 2 +-
|
||||
hw/virtio/meson.build | 6 +-
|
||||
target/arm/arm-qmp-cmds.c | 2 +
|
||||
target/arm/cpu.h | 2 +
|
||||
target/arm/cpu64.c | 7 +-
|
||||
target/arm/tcg/cpu32.c | 2 +
|
||||
target/arm/tcg/cpu64.c | 8 ++
|
||||
target/arm/tcg/meson.build | 2 +-
|
||||
target/i386/cpu.c | 20 +++
|
||||
target/riscv/cpu.c | 6 +
|
||||
target/s390x/cpu_models.c | 2 +-
|
||||
tests/qtest/arm-cpu-features.c | 4 +
|
||||
23 files changed, 311 insertions(+), 8 deletions(-)
|
||||
create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
create mode 100644 configs/devices/rh-virtio.mak
|
||||
create mode 100644 configs/devices/riscv64-softmmu/riscv64-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
|
||||
|
||||
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
new file mode 100644
|
||||
index 0000000000..855278f70e
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
@@ -0,0 +1,49 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_ARM_GIC_KVM=y
|
||||
+CONFIG_ARM_GICV3=y
|
||||
+CONFIG_ARM_GIC=y
|
||||
+CONFIG_ARM_SMMUV3=y
|
||||
+CONFIG_ARM_VIRT=y
|
||||
+CONFIG_CXL=y
|
||||
+CONFIG_CXL_MEM_DEVICE=y
|
||||
+CONFIG_EDID=y
|
||||
+CONFIG_PCI_BRIDGE=y
|
||||
+CONFIG_PCIE_PORT=y
|
||||
+CONFIG_PCIE_PCI_BRIDGE=y
|
||||
+CONFIG_PCI_DEVICES=y
|
||||
+CONFIG_PCI_TESTDEV=y
|
||||
+CONFIG_PFLASH_CFI01=y
|
||||
+CONFIG_SCSI=y
|
||||
+CONFIG_SEMIHOSTING=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI=y
|
||||
+CONFIG_USB_XHCI_PCI=y
|
||||
+CONFIG_USB_STORAGE_CORE=y
|
||||
+CONFIG_USB_STORAGE_CLASSIC=y
|
||||
+CONFIG_USB_HUB=y
|
||||
+CONFIG_USB_HID=y
|
||||
+CONFIG_VFIO=y
|
||||
+CONFIG_VFIO_PCI=y
|
||||
+CONFIG_VIRTIO_MMIO=y
|
||||
+CONFIG_VIRTIO_PCI=y
|
||||
+CONFIG_VIRTIO_MEM=y
|
||||
+CONFIG_VIRTIO_IOMMU=y
|
||||
+CONFIG_XIO3130=y
|
||||
+CONFIG_NVDIMM=y
|
||||
+CONFIG_ACPI_APEI=y
|
||||
+CONFIG_TPM=y
|
||||
+CONFIG_TPM_EMULATOR=y
|
||||
+CONFIG_TPM_TIS_SYSBUS=y
|
||||
+CONFIG_PTIMER=y
|
||||
+CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
|
||||
+CONFIG_PVPANIC_PCI=y
|
||||
+CONFIG_PXB=y
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
+CONFIG_VHOST_USER_SND=y
|
||||
+CONFIG_VHOST_USER_SCMI=y
|
||||
+CONFIG_VHOST_USER_GPU=y
|
||||
+CONFIG_UEFI_VARS=y
|
||||
diff --git a/configs/devices/rh-virtio.mak b/configs/devices/rh-virtio.mak
|
||||
new file mode 100644
|
||||
index 0000000000..94ede1b5f6
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/rh-virtio.mak
|
||||
@@ -0,0 +1,10 @@
|
||||
+CONFIG_VIRTIO=y
|
||||
+CONFIG_VIRTIO_BALLOON=y
|
||||
+CONFIG_VIRTIO_BLK=y
|
||||
+CONFIG_VIRTIO_GPU=y
|
||||
+CONFIG_VIRTIO_INPUT=y
|
||||
+CONFIG_VIRTIO_INPUT_HOST=y
|
||||
+CONFIG_VIRTIO_NET=y
|
||||
+CONFIG_VIRTIO_RNG=y
|
||||
+CONFIG_VIRTIO_SCSI=y
|
||||
+CONFIG_VIRTIO_SERIAL=y
|
||||
diff --git a/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
|
||||
new file mode 100644
|
||||
index 0000000000..b5e55de916
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
|
||||
@@ -0,0 +1,39 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_RISCV_VIRT=y
|
||||
+CONFIG_CXL=y
|
||||
+CONFIG_CXL_MEM_DEVICE=y
|
||||
+CONFIG_EDID=y
|
||||
+CONFIG_PCI_BRIDGE=y
|
||||
+CONFIG_PCIE_PORT=y
|
||||
+CONFIG_PCIE_PCI_BRIDGE=y
|
||||
+CONFIG_PCI_DEVICES=y
|
||||
+CONFIG_PCI_TESTDEV=y
|
||||
+CONFIG_PFLASH_CFI01=y
|
||||
+CONFIG_SCSI=y
|
||||
+CONFIG_SEMIHOSTING=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_XHCI=y
|
||||
+CONFIG_USB_XHCI_PCI=y
|
||||
+CONFIG_USB_STORAGE_CORE=y
|
||||
+CONFIG_USB_STORAGE_CLASSIC=y
|
||||
+CONFIG_USB_HUB=y
|
||||
+CONFIG_USB_HID=y
|
||||
+CONFIG_VFIO=y
|
||||
+CONFIG_VFIO_PCI=y
|
||||
+CONFIG_VIRTIO_MMIO=y
|
||||
+CONFIG_VIRTIO_PCI=y
|
||||
+CONFIG_VIRTIO_IOMMU=y
|
||||
+CONFIG_XIO3130=y
|
||||
+CONFIG_ACPI_APEI=y
|
||||
+CONFIG_TPM=y
|
||||
+CONFIG_TPM_EMULATOR=y
|
||||
+CONFIG_TPM_TIS_SYSBUS=y
|
||||
+CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
|
||||
+CONFIG_PVPANIC_PCI=y
|
||||
+CONFIG_PXB=y
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
+CONFIG_VHOST_USER_SND=y
|
||||
diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
new file mode 100644
|
||||
index 0000000000..834281d872
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
@@ -0,0 +1,20 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_S390_CCW_VIRTIO=y
|
||||
+CONFIG_S390_FLIC=y
|
||||
+CONFIG_S390_FLIC_KVM=y
|
||||
+CONFIG_SCLPCONSOLE=y
|
||||
+CONFIG_SCSI=y
|
||||
+CONFIG_VFIO=y
|
||||
+CONFIG_VFIO_AP=y
|
||||
+CONFIG_VFIO_CCW=y
|
||||
+CONFIG_VFIO_PCI=y
|
||||
+CONFIG_VHOST_USER=y
|
||||
+CONFIG_VIRTIO_CCW=y
|
||||
+CONFIG_VIRTIO_MEM=y
|
||||
+CONFIG_WDT_DIAG288=y
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=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
|
||||
new file mode 100644
|
||||
index 0000000000..828cb8aa6f
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
@@ -0,0 +1,118 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_ACPI=y
|
||||
+CONFIG_ACPI_PCI=y
|
||||
+CONFIG_ACPI_CPU_HOTPLUG=y
|
||||
+CONFIG_ACPI_MEMORY_HOTPLUG=y
|
||||
+CONFIG_ACPI_NVDIMM=y
|
||||
+CONFIG_ACPI_SMBUS=y
|
||||
+CONFIG_ACPI_VMGENID=y
|
||||
+CONFIG_ACPI_X86=y
|
||||
+CONFIG_ACPI_ICH9=y
|
||||
+CONFIG_AHCI=y
|
||||
+CONFIG_APIC=y
|
||||
+CONFIG_APM=y
|
||||
+CONFIG_BOCHS_DISPLAY=y
|
||||
+CONFIG_CXL=y
|
||||
+CONFIG_CXL_MEM_DEVICE=y
|
||||
+CONFIG_DIMM=y
|
||||
+CONFIG_E1000E_PCI_EXPRESS=y
|
||||
+CONFIG_E1000_PCI=y
|
||||
+CONFIG_EDU=y
|
||||
+#CONFIG_FDC=y
|
||||
+#CONFIG_FDC_SYSBUS=y
|
||||
+#CONFIG_FDC_ISA=y
|
||||
+CONFIG_FW_CFG_DMA=y
|
||||
+CONFIG_HDA=y
|
||||
+CONFIG_HYPERV=y
|
||||
+CONFIG_HYPERV_TESTDEV=y
|
||||
+CONFIG_I2C=y
|
||||
+CONFIG_I440FX=y
|
||||
+CONFIG_I8254=y
|
||||
+CONFIG_I8257=y
|
||||
+CONFIG_I8259=y
|
||||
+CONFIG_I82801B11=y
|
||||
+CONFIG_IDE_CORE=y
|
||||
+CONFIG_IDE_PCI=y
|
||||
+CONFIG_IDE_PIIX=y
|
||||
+CONFIG_IDE_DEV=y
|
||||
+CONFIG_IDE_BUS=y
|
||||
+CONFIG_IGB_PCI_EXPRESS=y
|
||||
+CONFIG_IOAPIC=y
|
||||
+CONFIG_IOH3420=y
|
||||
+CONFIG_ISA_BUS=y
|
||||
+CONFIG_ISA_DEBUG=y
|
||||
+CONFIG_ISA_TESTDEV=y
|
||||
+CONFIG_LPC_ICH9=y
|
||||
+CONFIG_MC146818RTC=y
|
||||
+CONFIG_MEM_DEVICE=y
|
||||
+CONFIG_NVDIMM=y
|
||||
+CONFIG_PAM=y
|
||||
+CONFIG_PC=y
|
||||
+CONFIG_PCI=y
|
||||
+CONFIG_PCIE_PORT=y
|
||||
+CONFIG_PCI_DEVICES=y
|
||||
+CONFIG_PCI_EXPRESS=y
|
||||
+CONFIG_PCI_EXPRESS_Q35=y
|
||||
+CONFIG_PCI_I440FX=y
|
||||
+CONFIG_PCI_TESTDEV=y
|
||||
+CONFIG_PCKBD=y
|
||||
+CONFIG_PCSPK=y
|
||||
+CONFIG_PC_ACPI=y
|
||||
+CONFIG_PC_PCI=y
|
||||
+CONFIG_PCI_BRIDGE=y
|
||||
+CONFIG_PCIE_PCI_BRIDGE=y
|
||||
+CONFIG_PFLASH_CFI01=y
|
||||
+CONFIG_PVPANIC_ISA=y
|
||||
+CONFIG_PXB=y
|
||||
+CONFIG_Q35=y
|
||||
+CONFIG_RTL8139_PCI=y
|
||||
+CONFIG_SCSI=y
|
||||
+CONFIG_SERIAL=y
|
||||
+CONFIG_SERIAL_ISA=y
|
||||
+CONFIG_SERIAL_PCI=y
|
||||
+CONFIG_SEV=y
|
||||
+CONFIG_SMBIOS=y
|
||||
+CONFIG_SMBUS_EEPROM=y
|
||||
+CONFIG_TEST_DEVICES=y
|
||||
+CONFIG_USB=y
|
||||
+CONFIG_USB_EHCI=y
|
||||
+CONFIG_USB_EHCI_PCI=y
|
||||
+CONFIG_USB_SMARTCARD=y
|
||||
+CONFIG_USB_STORAGE_CORE=y
|
||||
+CONFIG_USB_STORAGE_CLASSIC=y
|
||||
+CONFIG_USB_UHCI=y
|
||||
+CONFIG_USB_XHCI=y
|
||||
+CONFIG_USB_XHCI_NEC=y
|
||||
+CONFIG_USB_XHCI_PCI=y
|
||||
+CONFIG_USB_HUB=y
|
||||
+CONFIG_USB_HID=y
|
||||
+CONFIG_VFIO=y
|
||||
+CONFIG_VFIO_PCI=y
|
||||
+CONFIG_VGA=y
|
||||
+CONFIG_VGA_PCI=y
|
||||
+CONFIG_VHOST_USER=y
|
||||
+CONFIG_VHOST_USER_BLK=y
|
||||
+CONFIG_VIRTIO_MEM=y
|
||||
+CONFIG_VIRTIO_PCI=y
|
||||
+CONFIG_VIRTIO_VGA=y
|
||||
+CONFIG_VIRTIO_IOMMU=y
|
||||
+CONFIG_AMD_IOMMU=y
|
||||
+CONFIG_VMMOUSE=y
|
||||
+CONFIG_VMPORT=y
|
||||
+CONFIG_VTD=y
|
||||
+CONFIG_WDT_IB6300ESB=y
|
||||
+CONFIG_WDT_IB700=y
|
||||
+CONFIG_XIO3130=y
|
||||
+CONFIG_TPM=y
|
||||
+CONFIG_TPM_CRB=y
|
||||
+CONFIG_TPM_TIS_ISA=y
|
||||
+CONFIG_TPM_EMULATOR=y
|
||||
+CONFIG_SGX=y
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
+CONFIG_VHOST_USER_SND=y
|
||||
+CONFIG_VHOST_USER_GPU=y
|
||||
+CONFIG_UEFI_VARS=y
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index ef6be3660f..b525e00365 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3183,6 +3183,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
||||
static const char * const valid_cpu_types[] = {
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
#ifdef CONFIG_TCG
|
||||
ARM_CPU_TYPE_NAME("cortex-a7"),
|
||||
ARM_CPU_TYPE_NAME("cortex-a15"),
|
||||
@@ -3198,8 +3199,11 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
ARM_CPU_TYPE_NAME("neoverse-n2"),
|
||||
#endif /* TARGET_AARCH64 */
|
||||
#endif /* CONFIG_TCG */
|
||||
+#endif /* disabled for RHEL */
|
||||
#ifdef TARGET_AARCH64
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
ARM_CPU_TYPE_NAME("cortex-a53"),
|
||||
+#endif /* disabled for RHEL */
|
||||
ARM_CPU_TYPE_NAME("cortex-a57"),
|
||||
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
||||
ARM_CPU_TYPE_NAME("host"),
|
||||
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
|
||||
index 3e375f61a9..613adb3ebb 100644
|
||||
--- a/hw/cxl/meson.build
|
||||
+++ b/hw/cxl/meson.build
|
||||
@@ -6,7 +6,8 @@ system_ss.add(when: 'CONFIG_CXL',
|
||||
'cxl-host.c',
|
||||
'cxl-cdat.c',
|
||||
'cxl-events.c',
|
||||
- 'switch-mailbox-cci.c',
|
||||
+# Disabled for 8.2.0 rebase for RHEL 9.4.0
|
||||
+# 'switch-mailbox-cci.c',
|
||||
),
|
||||
if_false: files(
|
||||
'cxl-host-stubs.c',
|
||||
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
|
||||
index a0f2709c69..8c3962443b 100644
|
||||
--- a/hw/ide/piix.c
|
||||
+++ b/hw/ide/piix.c
|
||||
@@ -191,7 +191,8 @@ static void piix3_ide_class_init(ObjectClass *klass, const void *data)
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
|
||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
- dc->hotpluggable = false;
|
||||
+ /* Disabled for Red Hat Enterprise Linux: */
|
||||
+ dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo piix3_ide_info = {
|
||||
@@ -215,6 +216,8 @@ static void piix4_ide_class_init(ObjectClass *klass, const void *data)
|
||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
dc->hotpluggable = false;
|
||||
+ /* Disabled for Red Hat Enterprise Linux: */
|
||||
+ dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo piix4_ide_info = {
|
||||
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
|
||||
index 71f5f976e9..794078ed84 100644
|
||||
--- a/hw/input/pckbd.c
|
||||
+++ b/hw/input/pckbd.c
|
||||
@@ -950,6 +950,8 @@ static void i8042_class_initfn(ObjectClass *klass, const void *data)
|
||||
dc->vmsd = &vmstate_kbd_isa;
|
||||
adevc->build_dev_aml = i8042_build_aml;
|
||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||
+ /* Disabled for Red Hat Enterprise Linux: */
|
||||
+ dc->user_creatable = false;
|
||||
}
|
||||
|
||||
static const TypeInfo i8042_info = {
|
||||
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
||||
index a80a7b0cdb..7eb5a3b19d 100644
|
||||
--- a/hw/net/e1000.c
|
||||
+++ b/hw/net/e1000.c
|
||||
@@ -1732,6 +1732,7 @@ static const E1000Info e1000_devices[] = {
|
||||
.revision = 0x03,
|
||||
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
|
||||
},
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux 7 */
|
||||
{
|
||||
.name = "e1000-82544gc",
|
||||
.device_id = E1000_DEV_ID_82544GC_COPPER,
|
||||
@@ -1744,6 +1745,7 @@ static const E1000Info e1000_devices[] = {
|
||||
.revision = 0x03,
|
||||
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
|
||||
},
|
||||
+#endif
|
||||
};
|
||||
|
||||
static void e1000_register_types(void)
|
||||
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
||||
index 324fb932aa..f4dd693abb 100644
|
||||
--- a/hw/net/rtl8139.c
|
||||
+++ b/hw/net/rtl8139.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "system/dma.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
+#include "qemu/error-report.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "net/net.h"
|
||||
#include "net/eth.h"
|
||||
@@ -3363,6 +3364,9 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
|
||||
DeviceState *d = DEVICE(dev);
|
||||
uint8_t *pci_conf;
|
||||
|
||||
+ warn_report("'rtl8139' is deprecated, "
|
||||
+ "please use a different Network Interface Card");
|
||||
+
|
||||
pci_conf = dev->config;
|
||||
pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
|
||||
/* TODO: start of capability list, but no capability
|
||||
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
|
||||
index 17360a5b5a..3c4fdfc31d 100644
|
||||
--- a/hw/usb/meson.build
|
||||
+++ b/hw/usb/meson.build
|
||||
@@ -53,7 +53,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
|
||||
if cacard.found()
|
||||
usbsmartcard_ss = ss.source_set()
|
||||
usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD',
|
||||
- if_true: [cacard, files('ccid-card-emulated.c', 'ccid-card-passthru.c')])
|
||||
+ if_true: [cacard, files('ccid-card-passthru.c')])
|
||||
hw_usb_modules += {'smartcard': usbsmartcard_ss}
|
||||
endif
|
||||
|
||||
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
|
||||
index 3ea7b3cec8..3102d68bec 100644
|
||||
--- a/hw/virtio/meson.build
|
||||
+++ b/hw/virtio/meson.build
|
||||
@@ -22,7 +22,8 @@ if have_vhost
|
||||
system_virtio_ss.add(files('vhost-user-base.c'))
|
||||
|
||||
# MMIO Stubs
|
||||
- system_virtio_ss.add(files('vhost-user-device.c'))
|
||||
+# Disabled for 8.2.0 rebase for RHEL 9.4.0
|
||||
+# system_virtio_ss.add(files('vhost-user-device.c'))
|
||||
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: files('vhost-user-gpio.c'))
|
||||
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c'))
|
||||
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
|
||||
@@ -30,7 +31,8 @@ if have_vhost
|
||||
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
|
||||
|
||||
# PCI Stubs
|
||||
- system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
|
||||
+# Disabled for 8.2.0 rebase for RHEL 9.4.0
|
||||
+# system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: files('vhost-user-device-pci.c'))
|
||||
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_GPIO'],
|
||||
if_true: files('vhost-user-gpio-pci.c'))
|
||||
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'],
|
||||
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
|
||||
index d292c974c4..9bb68866e1 100644
|
||||
--- a/target/arm/arm-qmp-cmds.c
|
||||
+++ b/target/arm/arm-qmp-cmds.c
|
||||
@@ -225,6 +225,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
{
|
||||
ObjectClass *oc = data;
|
||||
+ CPUClass *cc = CPU_CLASS(oc);
|
||||
CpuDefinitionInfoList **cpu_list = user_data;
|
||||
CpuDefinitionInfo *info;
|
||||
const char *typename;
|
||||
@@ -233,6 +234,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->name = cpu_model_from_type(typename);
|
||||
info->q_typename = g_strdup(typename);
|
||||
+ info->deprecated = !!cc->deprecation_note;
|
||||
|
||||
QAPI_LIST_PREPEND(*cpu_list, info);
|
||||
}
|
||||
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||
index dc9b6dce4c..dc0da8b0ae 100644
|
||||
--- a/target/arm/cpu.h
|
||||
+++ b/target/arm/cpu.h
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "target/arm/gtimer.h"
|
||||
#include "target/arm/cpu-sysregs.h"
|
||||
|
||||
+#define RHEL_CPU_DEPRECATION "use 'host' / 'max'"
|
||||
+
|
||||
#define EXCP_UDEF 1 /* undefined instruction */
|
||||
#define EXCP_SWI 2 /* software interrupt */
|
||||
#define EXCP_PREFETCH_ABORT 3
|
||||
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||
index 26cf7e6dfa..051d5d653b 100644
|
||||
--- a/target/arm/cpu64.c
|
||||
+++ b/target/arm/cpu64.c
|
||||
@@ -698,6 +698,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||
define_cortex_a72_a57_a53_cp_reginfo(cpu);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void aarch64_a53_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@@ -759,6 +760,7 @@ static void aarch64_a53_initfn(Object *obj)
|
||||
cpu->gic_pribits = 5;
|
||||
define_cortex_a72_a57_a53_cp_reginfo(cpu);
|
||||
}
|
||||
+#endif
|
||||
|
||||
static void aarch64_host_initfn(Object *obj)
|
||||
{
|
||||
@@ -797,8 +799,11 @@ static void aarch64_max_initfn(Object *obj)
|
||||
}
|
||||
|
||||
static const ARMCPUInfo aarch64_cpus[] = {
|
||||
- { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
|
||||
+ { .name = "cortex-a57", .initfn = aarch64_a57_initfn,
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION },
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
|
||||
+#endif /* disabled for RHEL */
|
||||
{ .name = "max", .initfn = aarch64_max_initfn },
|
||||
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
||||
{ .name = "host", .initfn = aarch64_host_initfn },
|
||||
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
|
||||
index a2a23eae0d..c362759d65 100644
|
||||
--- a/target/arm/tcg/cpu32.c
|
||||
+++ b/target/arm/tcg/cpu32.c
|
||||
@@ -115,6 +115,7 @@ void aa32_max_features(ARMCPU *cpu)
|
||||
FIELD_DP32_IDREG(isar, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
/* CPU models. These are not needed for the AArch64 linux-user build. */
|
||||
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
|
||||
|
||||
@@ -1084,3 +1085,4 @@ static void arm_tcg_cpu_register_types(void)
|
||||
type_init(arm_tcg_cpu_register_types)
|
||||
|
||||
#endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */
|
||||
+#endif /* disabled for RHEL */
|
||||
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
|
||||
index 35cddbafa4..c7c464a0af 100644
|
||||
--- a/target/arm/tcg/cpu64.c
|
||||
+++ b/target/arm/tcg/cpu64.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "cpu-features.h"
|
||||
#include "cpregs.h"
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void aarch64_a35_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@@ -113,6 +114,7 @@ static void aarch64_a35_initfn(Object *obj)
|
||||
/* These values are the same with A53/A57/A72. */
|
||||
define_cortex_a72_a57_a53_cp_reginfo(cpu);
|
||||
}
|
||||
+#endif
|
||||
|
||||
static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
@@ -199,6 +201,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
|
||||
static const Property arm_cpu_lpa2_property =
|
||||
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void aarch64_a55_initfn(Object *obj)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(obj);
|
||||
@@ -1080,6 +1083,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj)
|
||||
aarch64_add_pauth_properties(obj);
|
||||
aarch64_add_sve_properties(obj);
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* -cpu max: a CPU with as many features enabled as our emulation supports.
|
||||
@@ -1310,6 +1314,7 @@ void aarch64_max_tcg_initfn(Object *obj)
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static const ARMCPUInfo aarch64_cpus[] = {
|
||||
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
|
||||
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
|
||||
@@ -1321,14 +1326,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
|
||||
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
|
||||
{ .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
|
||||
};
|
||||
+#endif
|
||||
|
||||
static void aarch64_cpu_register_types(void)
|
||||
{
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
|
||||
arm_cpu_register(&aarch64_cpus[i]);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
type_init(aarch64_cpu_register_types)
|
||||
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
|
||||
index 895facdc30..f1a9e01c51 100644
|
||||
--- a/target/arm/tcg/meson.build
|
||||
+++ b/target/arm/tcg/meson.build
|
||||
@@ -53,7 +53,7 @@ arm_system_ss.add(files(
|
||||
'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_common_ss.add(zlib)
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index 6d85149e6e..9c756a05f2 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -3163,6 +3163,7 @@ static const CPUCaches xeon_srf_cache_info = {
|
||||
},
|
||||
};
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static const CPUCaches yongfeng_cache_info = {
|
||||
.l1d_cache = &(CPUCacheInfo) {
|
||||
/* CPUID 0x4.0x0.EAX */
|
||||
@@ -3261,6 +3262,7 @@ static const CPUCaches yongfeng_cache_info = {
|
||||
.share_level = CPU_TOPOLOGY_LEVEL_DIE,
|
||||
},
|
||||
};
|
||||
+#endif
|
||||
|
||||
/* The following VMX features are not supported by KVM and are left out in the
|
||||
* CPU definitions:
|
||||
@@ -3290,9 +3292,13 @@ static const CPUCaches yongfeng_cache_info = {
|
||||
* PT in VMX operation
|
||||
*/
|
||||
|
||||
+#define RHEL_CPU_DEPRECATION \
|
||||
+ "use at least 'Haswell' / 'EPYC', or 'host' / 'max'"
|
||||
+
|
||||
static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
{
|
||||
.name = "qemu64",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_AMD,
|
||||
.family = 15,
|
||||
@@ -3311,6 +3317,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
.xlevel = 0x8000000A,
|
||||
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
|
||||
},
|
||||
+#if 0 // Deprecated CPU models are removed in RHEL-10
|
||||
{
|
||||
.name = "phenom",
|
||||
.level = 5,
|
||||
@@ -3679,8 +3686,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
.xlevel = 0x80000008,
|
||||
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
|
||||
},
|
||||
+#endif // Removal of deprecated CPU models in RHEL-10
|
||||
{
|
||||
.name = "Nehalem",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 11,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -3758,6 +3767,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "Westmere",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 11,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -3839,6 +3849,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "SandyBridge",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -3925,6 +3936,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "IvyBridge",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -5551,6 +5563,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "Denverton",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 21,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -5661,6 +5674,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "Snowridge",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 27,
|
||||
.vendor = CPUID_VENDOR_INTEL,
|
||||
.family = 6,
|
||||
@@ -5842,6 +5856,7 @@ 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",
|
||||
.level = 5,
|
||||
@@ -5909,8 +5924,10 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
.xlevel = 0x80000008,
|
||||
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
|
||||
},
|
||||
+#endif
|
||||
{
|
||||
.name = "Opteron_G4",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_AMD,
|
||||
.family = 21,
|
||||
@@ -5943,6 +5960,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{
|
||||
.name = "Opteron_G5",
|
||||
+ .deprecation_note = RHEL_CPU_DEPRECATION,
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_AMD,
|
||||
.family = 21,
|
||||
@@ -6420,6 +6438,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ /* end of list */ }
|
||||
}
|
||||
},
|
||||
+#if 0 // Disabled for Red Hat Enterprise Linux
|
||||
{
|
||||
.name = "YongFeng",
|
||||
.level = 0x1F,
|
||||
@@ -6565,6 +6584,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ /* end of list */ }
|
||||
}
|
||||
},
|
||||
+#endif
|
||||
{
|
||||
.name = "EPYC-Turin",
|
||||
.level = 0xd,
|
||||
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
|
||||
index d055ddf462..bca50a39be 100644
|
||||
--- a/target/riscv/cpu.c
|
||||
+++ b/target/riscv/cpu.c
|
||||
@@ -2035,6 +2035,7 @@ static const PropertyInfo prop_marchid = {
|
||||
.set = prop_marchid_set,
|
||||
};
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
/*
|
||||
* RVA22U64 defines some 'named features' that are cache
|
||||
* related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa
|
||||
@@ -2143,12 +2144,15 @@ static RISCVCPUProfile RVA23S64 = {
|
||||
RISCV_PROFILE_EXT_LIST_END
|
||||
}
|
||||
};
|
||||
+#endif
|
||||
|
||||
RISCVCPUProfile *riscv_profiles[] = {
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
&RVA22U64,
|
||||
&RVA22S64,
|
||||
&RVA23U64,
|
||||
&RVA23S64,
|
||||
+#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -2993,6 +2997,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
||||
.cfg.pmp_regions = 8
|
||||
),
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
#if defined(TARGET_RISCV32) || \
|
||||
(defined(TARGET_RISCV64) && !defined(CONFIG_USER_ONLY))
|
||||
DEFINE_RISCV_CPU(TYPE_RISCV_CPU_BASE32, TYPE_RISCV_DYNAMIC_CPU,
|
||||
@@ -3287,6 +3292,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
||||
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23U64, TYPE_RISCV_CPU_RV64I, RVA23U64),
|
||||
DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA23S64, TYPE_RISCV_CPU_RV64I, RVA23S64),
|
||||
#endif /* TARGET_RISCV64 */
|
||||
+#endif /* disabled for RHEL */
|
||||
};
|
||||
|
||||
DEFINE_TYPES(riscv_cpu_type_infos)
|
||||
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
|
||||
index 954a7a99a9..fe29f5c5b7 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
|
||||
CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"),
|
||||
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/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
|
||||
index eb8ddebffb..2d3304bb4a 100644
|
||||
--- a/tests/qtest/arm-cpu-features.c
|
||||
+++ b/tests/qtest/arm-cpu-features.c
|
||||
@@ -459,8 +459,10 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
|
||||
|
||||
/* Test expected feature presence/absence for some cpu types */
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
|
||||
assert_has_not_feature(qts, "cortex-a15", "aarch64");
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
/* Enabling and disabling pmu should always work. */
|
||||
assert_has_feature_enabled(qts, "max", "pmu");
|
||||
@@ -477,6 +479,7 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
assert_has_feature_enabled(qts, "cortex-a57", "pmu");
|
||||
assert_has_feature_enabled(qts, "cortex-a57", "aarch64");
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
assert_has_feature_enabled(qts, "a64fx", "pmu");
|
||||
assert_has_feature_enabled(qts, "a64fx", "aarch64");
|
||||
/*
|
||||
@@ -489,6 +492,7 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
"{ 'sve384': true }");
|
||||
assert_error(qts, "a64fx", "cannot enable sve640",
|
||||
"{ 'sve640': true }");
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
sve_tests_default(qts, "max");
|
||||
pauth_tests_default(qts, "max");
|
||||
530
0003-Machine-type-related-general-changes.patch
Normal file
530
0003-Machine-type-related-general-changes.patch
Normal file
@ -0,0 +1,530 @@
|
||||
From 2a4e74aaa600b6acbab1fa25637f1bc10ca789ed Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 11 Jan 2019 09:54:45 +0100
|
||||
Subject: [PATCH] Machine type related general changes
|
||||
|
||||
This patch is first part of original "Add RHEL machine types" patch we
|
||||
split to allow easier review. It contains changes not related to any
|
||||
architecture.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
hw/acpi/piix4.c | 2 +-
|
||||
hw/arm/virt.c | 2 +-
|
||||
hw/core/machine.c | 145 +++++++++++++++++++++++++++++++++++
|
||||
hw/i386/fw_cfg.c | 3 +-
|
||||
hw/net/rtl8139.c | 4 +-
|
||||
hw/riscv/virt.c | 4 +-
|
||||
hw/smbios/smbios.c | 46 ++++++++++-
|
||||
hw/usb/hcd-xhci-pci.c | 54 +++++++++----
|
||||
hw/usb/hcd-xhci-pci.h | 1 +
|
||||
hw/virtio/virtio-mem.c | 3 +-
|
||||
include/hw/boards.h | 31 ++++++++
|
||||
include/hw/firmware/smbios.h | 4 +-
|
||||
include/hw/i386/pc.h | 3 +
|
||||
13 files changed, 277 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
|
||||
index 7a18f18dda..2b3678b8c6 100644
|
||||
--- a/hw/acpi/piix4.c
|
||||
+++ b/hw/acpi/piix4.c
|
||||
@@ -245,7 +245,7 @@ static bool vmstate_test_migrate_acpi_index(void *opaque, int version_id)
|
||||
static const VMStateDescription vmstate_acpi = {
|
||||
.name = "piix4_pm",
|
||||
.version_id = 3,
|
||||
- .minimum_version_id = 3,
|
||||
+ .minimum_version_id = 2,
|
||||
.post_load = vmstate_acpi_post_load,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index b525e00365..1800981317 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1755,7 +1755,7 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
product = "KVM Virtual Machine";
|
||||
}
|
||||
|
||||
- smbios_set_defaults("QEMU", product, mc->name);
|
||||
+ smbios_set_defaults("QEMU", product, mc->name, NULL, NULL);
|
||||
|
||||
/* build the array of physical mem area from base_memmap */
|
||||
mem_array.address = vms->memmap[VIRT_MEM].base;
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index bd47527479..2a1a42cebc 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -288,6 +288,151 @@ GlobalProperty hw_compat_2_6[] = {
|
||||
};
|
||||
const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6);
|
||||
|
||||
+/*
|
||||
+ * RHEL only: machine types for previous major releases are deprecated
|
||||
+ */
|
||||
+const char *rhel_old_machine_deprecation =
|
||||
+ "machine types for previous major releases are deprecated";
|
||||
+
|
||||
+GlobalProperty hw_compat_rhel_10_2[] = {
|
||||
+ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
|
||||
+ { "scsi-hd", "dpofua", "off" },
|
||||
+ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
|
||||
+ { "vfio-pci", "x-migration-load-config-after-iter", "off" },
|
||||
+ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
|
||||
+ { "ramfb", "use-legacy-x86-rom", "true"},
|
||||
+ /* hw_compat_rhel_10_2 from hw_compat_10_0 */
|
||||
+ { "vfio-pci-nohotplug", "use-legacy-x86-rom", "true" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_10_2_len = G_N_ELEMENTS(hw_compat_10_0);
|
||||
+
|
||||
+GlobalProperty hw_compat_rhel_10_1[] = {
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_1 */
|
||||
+ { TYPE_PCI_DEVICE, "x-pcie-ext-tag", "false" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ {"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"},
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "virtio-balloon-pci", "vectors", "0" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "virtio-balloon-pci-transitional", "vectors", "0" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "virtio-balloon-pci-non-transitional", "vectors", "0" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "virtio-mem-pci", "vectors", "0" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "migration", "multifd-clean-tls-termination", "false" },
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "migration", "send-switchover-start", "off"},
|
||||
+ /* hw_compat_rhel_10_1 from hw_compat_9_2 */
|
||||
+ { "vfio-pci", "x-migration-multifd-transfer", "off" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_10_1_len = G_N_ELEMENTS(hw_compat_rhel_10_1);
|
||||
+
|
||||
+
|
||||
+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);
|
||||
+
|
||||
+/* Apply this to all RHEL9 boards going backward and forward */
|
||||
+GlobalProperty hw_compat_rhel_9[] = {
|
||||
+ /* supported by userspace, but RHEL 9 *kernels* do not support USO. */
|
||||
+ { TYPE_VIRTIO_NET, "host_uso", "off"},
|
||||
+ { TYPE_VIRTIO_NET, "guest_uso4", "off"},
|
||||
+ { TYPE_VIRTIO_NET, "guest_uso6", "off"},
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_len = G_N_ELEMENTS(hw_compat_rhel_9);
|
||||
+
|
||||
+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[] = {
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_0 */
|
||||
+ { TYPE_VIRTIO_NET, "host_uso", "off"},
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_0 */
|
||||
+ { TYPE_VIRTIO_NET, "guest_uso4", "off"},
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_0 */
|
||||
+ { TYPE_VIRTIO_NET, "guest_uso6", "off"},
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_1 */
|
||||
+ { TYPE_PCI_BRIDGE, "x-pci-express-writeable-slt-bug", "true" },
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_1 */
|
||||
+ { "ramfb", "x-migrate", "off" },
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_1 */
|
||||
+ { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
|
||||
+ /* hw_compat_rhel_9_4 from hw_compat_8_1 */
|
||||
+ { "igb", "x-pcie-flr-init", "off" },
|
||||
+ /* hw_compat_rhel_9_4 jira RHEL-24045 */
|
||||
+ { "virtio-mem", "dynamic-memslots", "off" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_4_len = G_N_ELEMENTS(hw_compat_rhel_9_4);
|
||||
+
|
||||
+GlobalProperty hw_compat_rhel_9_3[] = {
|
||||
+ /* hw_compat_rhel_9_3 from hw_compat_8_0 */
|
||||
+ { "migration", "multifd-flush-after-each-section", "on"},
|
||||
+ /* hw_compat_rhel_9_3 from hw_compat_8_0 */
|
||||
+ { TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_3_len = G_N_ELEMENTS(hw_compat_rhel_9_3);
|
||||
+
|
||||
+GlobalProperty hw_compat_rhel_9_2[] = {
|
||||
+ /* hw_compat_rhel_9_2 from hw_compat_7_2 */
|
||||
+ { "e1000e", "migrate-timadj", "off" },
|
||||
+ /* hw_compat_rhel_9_2 from hw_compat_7_2 */
|
||||
+ { "virtio-mem", "x-early-migration", "false" },
|
||||
+ /* hw_compat_rhel_9_2 from hw_compat_7_2 */
|
||||
+ { "migration", "x-preempt-pre-7-2", "true" },
|
||||
+ /* hw_compat_rhel_9_2 from hw_compat_7_2 */
|
||||
+ { TYPE_PCI_DEVICE, "x-pcie-err-unc-mask", "off" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_2_len = G_N_ELEMENTS(hw_compat_rhel_9_2);
|
||||
+
|
||||
+/*
|
||||
+ * Mostly the same as hw_compat_7_0
|
||||
+ */
|
||||
+GlobalProperty hw_compat_rhel_9_1[] = {
|
||||
+ /* hw_compat_rhel_9_1 from hw_compat_7_0 */
|
||||
+ { "arm-gicv3-common", "force-8-bit-prio", "on" },
|
||||
+ /* hw_compat_rhel_9_1 from hw_compat_7_0 */
|
||||
+ { "nvme-ns", "eui64-default", "on"},
|
||||
+ /* hw_compat_rhel_9_1 from hw_compat_7_1 */
|
||||
+ { "virtio-device", "queue_reset", "false" },
|
||||
+ /* hw_compat_rhel_9_1 bz 2155749 */
|
||||
+ { "virtio-rng-pci", "vectors", "0" },
|
||||
+ /* hw_compat_rhel_9_1 bz 2162569 */
|
||||
+ { "virtio-rng-pci-transitional", "vectors", "0" },
|
||||
+ { "virtio-rng-pci-non-transitional", "vectors", "0" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_1_len = G_N_ELEMENTS(hw_compat_rhel_9_1);
|
||||
+
|
||||
+/*
|
||||
+ * Mostly the same as hw_compat_6_2
|
||||
+ */
|
||||
+GlobalProperty hw_compat_rhel_9_0[] = {
|
||||
+ /* hw_compat_rhel_9_0 from hw_compat_6_2 */
|
||||
+ { "PIIX4_PM", "x-not-migrate-acpi-index", "on"},
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_0_len = G_N_ELEMENTS(hw_compat_rhel_9_0);
|
||||
+
|
||||
MachineState *current_machine;
|
||||
|
||||
static char *machine_get_kernel(Object *obj, Error **errp)
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 5c0bcd5f8a..07df7281d2 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -75,7 +75,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
|
||||
if (pcmc->smbios_defaults) {
|
||||
/* 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_stream_product, pcmc->smbios_stream_version);
|
||||
}
|
||||
|
||||
/* tell smbios about cpuid version and features */
|
||||
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
||||
index f4dd693abb..ac3a7376ad 100644
|
||||
--- a/hw/net/rtl8139.c
|
||||
+++ b/hw/net/rtl8139.c
|
||||
@@ -3173,7 +3173,7 @@ static int rtl8139_pre_save(void *opaque)
|
||||
|
||||
static const VMStateDescription vmstate_rtl8139 = {
|
||||
.name = "rtl8139",
|
||||
- .version_id = 5,
|
||||
+ .version_id = 4,
|
||||
.minimum_version_id = 3,
|
||||
.post_load = rtl8139_post_load,
|
||||
.pre_save = rtl8139_pre_save,
|
||||
@@ -3254,7 +3254,9 @@ static const VMStateDescription vmstate_rtl8139 = {
|
||||
VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State),
|
||||
VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State),
|
||||
VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State),
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */
|
||||
VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5),
|
||||
+#endif
|
||||
VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State),
|
||||
VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
|
||||
|
||||
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
|
||||
index 47e573f85a..ab5a9ec613 100644
|
||||
--- a/hw/riscv/virt.c
|
||||
+++ b/hw/riscv/virt.c
|
||||
@@ -1402,7 +1402,7 @@ static void virt_build_smbios(RISCVVirtState *s)
|
||||
product = "KVM Virtual Machine";
|
||||
}
|
||||
|
||||
- smbios_set_defaults("QEMU", product, mc->name);
|
||||
+ smbios_set_defaults("QEMU", product, mc->name, NULL, NULL);
|
||||
|
||||
if (riscv_is_32bit(&s->soc[0])) {
|
||||
smbios_set_default_processor_family(0x200);
|
||||
@@ -1920,7 +1920,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
mc->desc = "RISC-V VirtIO board";
|
||||
mc->init = virt_machine_init;
|
||||
mc->max_cpus = VIRT_CPUS_MAX;
|
||||
- mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
|
||||
+ mc->default_cpu_type = TYPE_RISCV_CPU_MAX;
|
||||
mc->block_default_type = IF_VIRTIO;
|
||||
mc->no_cdrom = 1;
|
||||
mc->pci_allow_0_address = true;
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 1ac063cfb4..03f7a00ed1 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -39,6 +39,10 @@ size_t usr_blobs_len;
|
||||
static unsigned usr_table_max;
|
||||
static unsigned usr_table_cnt;
|
||||
|
||||
+/* Set to true for modern Windows 10 HardwareID-6 compat */
|
||||
+static bool smbios_type2_required;
|
||||
+
|
||||
+
|
||||
uint8_t *smbios_tables;
|
||||
size_t smbios_tables_len;
|
||||
unsigned smbios_table_max;
|
||||
@@ -627,7 +631,7 @@ static void smbios_build_type_1_table(void)
|
||||
|
||||
static void smbios_build_type_2_table(void)
|
||||
{
|
||||
- SMBIOS_BUILD_TABLE_PRE(2, T2_BASE, false); /* optional */
|
||||
+ SMBIOS_BUILD_TABLE_PRE(2, T2_BASE, smbios_type2_required);
|
||||
|
||||
SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
|
||||
SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
|
||||
@@ -1015,15 +1019,51 @@ void smbios_set_default_processor_family(uint16_t processor_family)
|
||||
}
|
||||
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
- const char *version)
|
||||
+ const char *version,
|
||||
+ const char *stream_product,
|
||||
+ const char *stream_version)
|
||||
{
|
||||
smbios_have_defaults = true;
|
||||
|
||||
+ /*
|
||||
+ * If @stream_product & @stream_version are non-NULL, then
|
||||
+ * we're following rules for new Windows driver support.
|
||||
+ * The data we have to report is defined in this doc:
|
||||
+ *
|
||||
+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/install/specifying-hardware-ids-for-a-computer
|
||||
+ *
|
||||
+ * The Windows drivers are written to expect use of the
|
||||
+ * scheme documented as "HardwareID-6" against Windows 10,
|
||||
+ * which uses SMBIOS System (Type 1) and Base Board (Type 2)
|
||||
+ * tables and will match on
|
||||
+ *
|
||||
+ * System Manufacturer = Red Hat (@manufacturer)
|
||||
+ * System SKU Number = 8.2.0 (@stream_version)
|
||||
+ * Baseboard Manufacturer = Red Hat (@manufacturer)
|
||||
+ * Baseboard Product = RHEL-AV (@stream_product)
|
||||
+ *
|
||||
+ * NB, SKU must be changed with each RHEL-AV release
|
||||
+ *
|
||||
+ * Other fields can be freely used by applications using
|
||||
+ * QEMU. For example apps can use the "System product"
|
||||
+ * and "System version" to identify themselves.
|
||||
+ *
|
||||
+ * We get 'System Manufacturer' and 'Baseboard Manufacturer'
|
||||
+ */
|
||||
SMBIOS_SET_DEFAULT(smbios_type1.manufacturer, manufacturer);
|
||||
SMBIOS_SET_DEFAULT(smbios_type1.product, product);
|
||||
SMBIOS_SET_DEFAULT(smbios_type1.version, version);
|
||||
+ SMBIOS_SET_DEFAULT(smbios_type1.family, "Red Hat Enterprise Linux");
|
||||
+ if (stream_version != NULL) {
|
||||
+ SMBIOS_SET_DEFAULT(smbios_type1.sku, stream_version);
|
||||
+ }
|
||||
SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
|
||||
- SMBIOS_SET_DEFAULT(type2.product, product);
|
||||
+ if (stream_product != NULL) {
|
||||
+ SMBIOS_SET_DEFAULT(type2.product, stream_product);
|
||||
+ smbios_type2_required = true;
|
||||
+ } else {
|
||||
+ SMBIOS_SET_DEFAULT(type2.product, product);
|
||||
+ }
|
||||
SMBIOS_SET_DEFAULT(type2.version, version);
|
||||
SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
|
||||
SMBIOS_SET_DEFAULT(type3.version, version);
|
||||
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
|
||||
index b93c80b09d..f4a2f1a1de 100644
|
||||
--- a/hw/usb/hcd-xhci-pci.c
|
||||
+++ b/hw/usb/hcd-xhci-pci.c
|
||||
@@ -120,6 +120,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* RH bz 1912846 */
|
||||
+static bool usb_xhci_pci_add_msi(struct PCIDevice *dev, Error **errp)
|
||||
+{
|
||||
+ int ret;
|
||||
+ Error *err = NULL;
|
||||
+ XHCIPciState *s = XHCI_PCI(dev);
|
||||
+
|
||||
+ ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err);
|
||||
+ /*
|
||||
+ * Any error other than -ENOTSUP(board's MSI support is broken)
|
||||
+ * is a programming error
|
||||
+ */
|
||||
+ assert(!ret || ret == -ENOTSUP);
|
||||
+ if (ret && s->msi == ON_OFF_AUTO_ON) {
|
||||
+ /* Can't satisfy user's explicit msi=on request, fail */
|
||||
+ error_append_hint(&err, "You have to use msi=auto (default) or "
|
||||
+ "msi=off with this machine type.\n");
|
||||
+ error_propagate(errp, err);
|
||||
+ return true;
|
||||
+ }
|
||||
+ assert(!err || s->msi == ON_OFF_AUTO_AUTO);
|
||||
+ /* With msi=auto, we fall back to MSI off silently */
|
||||
+ error_free(err);
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
@@ -144,23 +171,12 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
|
||||
s->xhci.nec_quirks = true;
|
||||
}
|
||||
|
||||
- if (s->msi != ON_OFF_AUTO_OFF) {
|
||||
- ret = msi_init(dev, 0x70, s->xhci.numintrs, true, false, &err);
|
||||
- /*
|
||||
- * Any error other than -ENOTSUP(board's MSI support is broken)
|
||||
- * is a programming error
|
||||
- */
|
||||
- assert(!ret || ret == -ENOTSUP);
|
||||
- if (ret && s->msi == ON_OFF_AUTO_ON) {
|
||||
- /* Can't satisfy user's explicit msi=on request, fail */
|
||||
- error_append_hint(&err, "You have to use msi=auto (default) or "
|
||||
- "msi=off with this machine type.\n");
|
||||
+ if (s->msi != ON_OFF_AUTO_OFF && s->rh_late_msi_cap) {
|
||||
+ /* This gives the behaviour from 5.2.0 onwards, lspci shows 90,a0,70 */
|
||||
+ if (usb_xhci_pci_add_msi(dev, &err)) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
- assert(!err || s->msi == ON_OFF_AUTO_AUTO);
|
||||
- /* With msi=auto, we fall back to MSI off silently */
|
||||
- error_free(err);
|
||||
}
|
||||
pci_register_bar(dev, 0,
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
@@ -172,6 +188,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
|
||||
assert(ret > 0);
|
||||
}
|
||||
|
||||
+ /* RH bz 1912846 */
|
||||
+ if (s->msi != ON_OFF_AUTO_OFF && !s->rh_late_msi_cap) {
|
||||
+ /* This gives the older RH machine behaviour, lspci shows 90,70,a0 */
|
||||
+ if (usb_xhci_pci_add_msi(dev, &err)) {
|
||||
+ error_propagate(errp, err);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
if (s->msix != ON_OFF_AUTO_OFF) {
|
||||
/* TODO check for errors, and should fail when msix=on */
|
||||
msix_init(dev, s->xhci.numintrs,
|
||||
@@ -221,6 +245,8 @@ static const Property xhci_pci_properties[] = {
|
||||
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
|
||||
DEFINE_PROP_BOOL("conditional-intr-mapping", XHCIPciState,
|
||||
conditional_intr_mapping, false),
|
||||
+ /* RH bz 1912846 */
|
||||
+ DEFINE_PROP_BOOL("x-rh-late-msi-cap", XHCIPciState, rh_late_msi_cap, true),
|
||||
};
|
||||
|
||||
static void xhci_class_init(ObjectClass *klass, const void *data)
|
||||
diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h
|
||||
index 5b61ae8455..3170db064b 100644
|
||||
--- a/hw/usb/hcd-xhci-pci.h
|
||||
+++ b/hw/usb/hcd-xhci-pci.h
|
||||
@@ -41,6 +41,7 @@ typedef struct XHCIPciState {
|
||||
OnOffAuto msi;
|
||||
OnOffAuto msix;
|
||||
bool conditional_intr_mapping;
|
||||
+ bool rh_late_msi_cap; /* bz 1912846 */
|
||||
} XHCIPciState;
|
||||
|
||||
#endif
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index c46f6f9c3e..1805597879 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -1699,8 +1699,9 @@ static const Property virtio_mem_properties[] = {
|
||||
#endif
|
||||
DEFINE_PROP_BOOL(VIRTIO_MEM_EARLY_MIGRATION_PROP, VirtIOMEM,
|
||||
early_migration, true),
|
||||
+ /* RHEL: default-enable "dynamic-memslots" (jira RHEL-24045) */
|
||||
DEFINE_PROP_BOOL(VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP, VirtIOMEM,
|
||||
- dynamic_memslots, false),
|
||||
+ dynamic_memslots, true),
|
||||
};
|
||||
|
||||
static uint64_t virtio_mem_rdm_get_min_granularity(const RamDiscardManager *rdm,
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index f94713e6e2..a434b21909 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -863,4 +863,35 @@ extern const size_t hw_compat_2_7_len;
|
||||
extern GlobalProperty hw_compat_2_6[];
|
||||
extern const size_t hw_compat_2_6_len;
|
||||
|
||||
+extern GlobalProperty hw_compat_rhel_10_2[];
|
||||
+extern const size_t hw_compat_rhel_10_2_len;
|
||||
+
|
||||
+extern GlobalProperty hw_compat_rhel_10_1[];
|
||||
+extern const size_t hw_compat_rhel_10_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[];
|
||||
+extern const size_t hw_compat_rhel_9_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;
|
||||
+
|
||||
+extern GlobalProperty hw_compat_rhel_9_3[];
|
||||
+extern const size_t hw_compat_rhel_9_3_len;
|
||||
+
|
||||
+extern GlobalProperty hw_compat_rhel_9_2[];
|
||||
+extern const size_t hw_compat_rhel_9_2_len;
|
||||
+
|
||||
+extern GlobalProperty hw_compat_rhel_9_1[];
|
||||
+extern const size_t hw_compat_rhel_9_1_len;
|
||||
+
|
||||
+extern GlobalProperty hw_compat_rhel_9_0[];
|
||||
+extern const size_t hw_compat_rhel_9_0_len;
|
||||
+
|
||||
+extern const char *rhel_old_machine_deprecation;
|
||||
#endif
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index f066ab7262..e805d25fbe 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -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_defaults(const char *manufacturer, const char *product,
|
||||
- const char *version);
|
||||
+ const char *version,
|
||||
+ const char *stream_product,
|
||||
+ const char *stream_version);
|
||||
void smbios_set_default_processor_family(uint16_t processor_family);
|
||||
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index 79b72c54dd..3b4ea24c20 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -103,6 +103,9 @@ struct PCMachineClass {
|
||||
bool smbios_defaults;
|
||||
bool smbios_legacy_mode;
|
||||
SmbiosEntryPointType default_smbios_ep_type;
|
||||
+ /* New fields needed for Windows HardwareID-6 matching */
|
||||
+ const char *smbios_stream_product;
|
||||
+ const char *smbios_stream_version;
|
||||
|
||||
/* RAM / address space compat: */
|
||||
bool gigabyte_align;
|
||||
33
0004-meson-temporarily-disable-Wunused-function.patch
Normal file
33
0004-meson-temporarily-disable-Wunused-function.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From a55eca67d3d95bf1db0e82ba1eaca5006419a9c4 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: [PATCH] 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)
|
||||
- New patch
|
||||
---
|
||||
meson.build | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 50c774a195..0e0120a613 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -757,6 +757,7 @@ warn_flags = [
|
||||
'-Wno-string-plus-int',
|
||||
'-Wno-tautological-type-limit-compare',
|
||||
'-Wno-typedef-redefinition',
|
||||
+ '-Wno-unused-function',
|
||||
]
|
||||
|
||||
if host_os != 'darwin'
|
||||
@ -0,0 +1,99 @@
|
||||
From 8bb638561d3ad36be896d7648385d4fdb7bef0df Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 10 Jul 2024 02:25:51 -0400
|
||||
Subject: [PATCH] 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):
|
||||
- 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 | 3 +++
|
||||
4 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 1800981317..e6e98fef1c 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3459,6 +3459,7 @@ static void machvirt_machine_init(void)
|
||||
}
|
||||
type_init(machvirt_machine_init);
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void virt_machine_10_1_options(MachineClass *mc)
|
||||
{
|
||||
}
|
||||
@@ -3634,3 +3635,4 @@ static void virt_machine_4_1_options(MachineClass *mc)
|
||||
mc->auto_enable_numa_with_memhp = false;
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(4, 1)
|
||||
+#endif /* disabled for RHEL */
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index c03324281b..acf010e20f 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -475,6 +475,7 @@ static void pc_i440fx_init(MachineState *machine)
|
||||
#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
|
||||
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor);
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void pc_i440fx_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
@@ -802,6 +803,7 @@ static void pc_i440fx_machine_2_6_options(MachineClass *m)
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(2, 6);
|
||||
+#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 b309b2b378..2203ffd67e 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -374,6 +374,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_10_1_options(MachineClass *m)
|
||||
{
|
||||
pc_q35_machine_options(m);
|
||||
@@ -685,3 +686,4 @@ static void pc_q35_machine_2_6_options(MachineClass *m)
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(2, 6);
|
||||
+#endif /* Disabled for Red Hat Enterprise Linux */
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index a79bd13275..2fca2bcf4d 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -911,6 +911,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_10_1_instance_options(MachineState *machine)
|
||||
{
|
||||
}
|
||||
@@ -1167,6 +1168,8 @@ static void ccw_machine_4_2_class_options(MachineClass *mc)
|
||||
}
|
||||
DEFINE_CCW_MACHINE(4, 2);
|
||||
|
||||
+#endif /* disabled for RHEL */
|
||||
+
|
||||
static void ccw_machine_register_types(void)
|
||||
{
|
||||
type_register_static(&ccw_machine_info);
|
||||
185
0006-Adapt-versioned-machine-type-macros-for-RHEL.patch
Normal file
185
0006-Adapt-versioned-machine-type-macros-for-RHEL.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From 840ad52f0446382a948c97456ba94db17241c2de 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: [PATCH] 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>
|
||||
---
|
||||
docs/conf.py | 4 ++--
|
||||
include/hw/boards.h | 39 ++++++++++++++---------------------
|
||||
meson.build | 1 +
|
||||
meson_options.txt | 2 ++
|
||||
scripts/meson-buildoptions.sh | 2 ++
|
||||
5 files changed, 23 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/docs/conf.py b/docs/conf.py
|
||||
index f892a6e1da..0b8861e4bf 100644
|
||||
--- a/docs/conf.py
|
||||
+++ b/docs/conf.py
|
||||
@@ -140,8 +140,8 @@
|
||||
# MACHINE_VER_DELETION_MAJOR & MACHINE_VER_DEPRECATION_MAJOR
|
||||
# defined in include/hw/boards.h and the introductory text in
|
||||
# docs/about/deprecated.rst
|
||||
-ver_machine_deprecation_version = "%d.%d.0" % (major - 3, minor)
|
||||
-ver_machine_deletion_version = "%d.%d.0" % (major - 6, minor)
|
||||
+ver_machine_deprecation_version = "%d.%d.0" % (major - 1, minor)
|
||||
+ver_machine_deletion_version = "%d.%d.0" % (major - 2, minor)
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index a434b21909..da2fc92ce8 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -577,16 +577,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__, \
|
||||
@@ -614,16 +614,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__, \
|
||||
@@ -642,17 +642,16 @@ struct MachineState {
|
||||
* and ver_machine_deletion_version logic in docs/conf.py and
|
||||
* the text in docs/about/deprecated.rst
|
||||
*/
|
||||
-#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_CURRENT_EXPIRED(cutoff, major, minor) \
|
||||
(((QEMU_VERSION_MAJOR - major) > cutoff) || \
|
||||
@@ -683,12 +682,7 @@ struct MachineState {
|
||||
* If this ever changes the logic below will need modifying....
|
||||
*/
|
||||
#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \
|
||||
- ((QEMU_VERSION_MICRO < 50 && \
|
||||
- _MACHINE_VER_IS_CURRENT_EXPIRED(cutoff, major, minor)) || \
|
||||
- (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR < 2 && \
|
||||
- _MACHINE_VER_IS_NEXT_MINOR_EXPIRED(cutoff, major, minor)) || \
|
||||
- (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR == 2 && \
|
||||
- _MACHINE_VER_IS_NEXT_MAJOR_EXPIRED(cutoff, major, minor)))
|
||||
+ ((RHEL_VERSION - major) >= cutoff)
|
||||
|
||||
#define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \
|
||||
_MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
|
||||
@@ -750,10 +744,9 @@ 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
|
||||
+ * It will automatically avoid registration of machines
|
||||
+ * that should have been deleted at the start of this
|
||||
+ * RHEL release
|
||||
*/
|
||||
#define MACHINE_VER_DELETION(...) \
|
||||
do { \
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 0e0120a613..23494666d9 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -2636,6 +2636,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 fff1521e58..f45d7ded45 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 0ebe6bc52a..4146dbc88d 100644
|
||||
--- a/scripts/meson-buildoptions.sh
|
||||
+++ b/scripts/meson-buildoptions.sh
|
||||
@@ -75,6 +75,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' [QEMU]'
|
||||
printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer'
|
||||
printf "%s\n" ' --rtsig-map=VALUE default value of QEMU_RTSIG_MAP [NULL]'
|
||||
+ 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'
|
||||
@@ -465,6 +466,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 ;;
|
||||
--rtsig-map=*) quote_sh "-Drtsig_map=$2" ;;
|
||||
34
0007-Increase-deletion-schedule-to-4-releases.patch
Normal file
34
0007-Increase-deletion-schedule-to-4-releases.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 3d48892605114ddc144dca5b2f34e1ea5a7f1cb1 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: [PATCH] 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)
|
||||
- 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 da2fc92ce8..aca254ea18 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -642,7 +642,7 @@ struct MachineState {
|
||||
* and ver_machine_deletion_version logic in docs/conf.py and
|
||||
* the text in docs/about/deprecated.rst
|
||||
*/
|
||||
-#define MACHINE_VER_DELETION_MAJOR 2
|
||||
+#define MACHINE_VER_DELETION_MAJOR 4
|
||||
#define MACHINE_VER_DEPRECATION_MAJOR 1
|
||||
|
||||
/*
|
||||
368
0008-Add-downstream-aarch64-versioned-virt-machine-types.patch
Normal file
368
0008-Add-downstream-aarch64-versioned-virt-machine-types.patch
Normal file
@ -0,0 +1,368 @@
|
||||
From 48f8e990ce9175426e1d2c33c3ef64cbb06300ed 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: [PATCH] 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>
|
||||
---
|
||||
hw/arm/virt.c | 154 +++++++++++++++++++++++++++++++++++++-----
|
||||
include/hw/arm/virt.h | 1 +
|
||||
2 files changed, 137 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index e6e98fef1c..d37d1bb3cf 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -97,6 +97,32 @@ static GlobalProperty arm_virt_compat[] = {
|
||||
};
|
||||
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
|
||||
+/*
|
||||
+ * RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
|
||||
+ * since qemu will setup the VM with pauth when KVM supports it we
|
||||
+ * have to disable it for virt-rhel9* to support upgrades / migration.
|
||||
+ */
|
||||
+GlobalProperty arm_rhel9_compat[] = {
|
||||
+ {TYPE_ARM_CPU, "pauth", "off", .optional = true},
|
||||
+};
|
||||
+const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_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()
|
||||
@@ -106,6 +132,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, ...) \
|
||||
@@ -116,10 +144,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__) = \
|
||||
@@ -135,10 +164,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 */
|
||||
@@ -1746,16 +1775,26 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(vms);
|
||||
MachineState *ms = MACHINE(vms);
|
||||
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(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 = mc->name;
|
||||
|
||||
if (kvm_enabled()) {
|
||||
product = "KVM Virtual Machine";
|
||||
}
|
||||
|
||||
- smbios_set_defaults("QEMU", product, mc->name, NULL, NULL);
|
||||
+ 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 */
|
||||
mem_array.address = vms->memmap[VIRT_MEM].base;
|
||||
@@ -2517,6 +2556,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);
|
||||
@@ -2544,6 +2584,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)
|
||||
{
|
||||
@@ -2559,6 +2600,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);
|
||||
@@ -2572,6 +2614,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)
|
||||
{
|
||||
@@ -2664,6 +2707,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);
|
||||
@@ -2677,6 +2721,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)
|
||||
{
|
||||
@@ -2760,6 +2805,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);
|
||||
@@ -2773,6 +2819,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)
|
||||
{
|
||||
@@ -3213,16 +3260,16 @@ static void virt_machine_class_init(ObjectClass *oc, const 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;
|
||||
+ /* Maximum supported VCPU count for all virt-rhel* machines */
|
||||
+ mc->max_cpus = 384;
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
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);
|
||||
+#endif
|
||||
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
|
||||
#ifdef CONFIG_TPM
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||
@@ -3234,11 +3281,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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;
|
||||
@@ -3263,6 +3306,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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",
|
||||
@@ -3275,6 +3319,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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);
|
||||
@@ -3282,12 +3327,14 @@ static void virt_machine_class_init(ObjectClass *oc, const 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,
|
||||
@@ -3323,7 +3370,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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",
|
||||
@@ -3343,11 +3390,13 @@ static void virt_machine_class_init(ObjectClass *oc, const 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);
|
||||
@@ -3355,6 +3404,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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);
|
||||
@@ -3367,6 +3417,7 @@ static void virt_machine_class_init(ObjectClass *oc, const 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,
|
||||
@@ -3636,3 +3687,70 @@ static void virt_machine_4_1_options(MachineClass *mc)
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(4, 1)
|
||||
#endif /* disabled for RHEL */
|
||||
+
|
||||
+static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
|
||||
+{
|
||||
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
||||
+
|
||||
+ /* QEMU 9.1 and earlier have only a stage-1 SMMU, not a nested s1+2 one */
|
||||
+ vmc->no_nested_smmu = true;
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_2, hw_compat_rhel_10_2_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
|
||||
+}
|
||||
+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);
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len);
|
||||
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
+}
|
||||
+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() */
|
||||
+ 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);
|
||||
+
|
||||
+ vmc->manufacturer_product_compat = true;
|
||||
+}
|
||||
+DEFINE_VIRT_MACHINE(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)
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index 365a28b082..94c79d6c6d 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -132,6 +132,7 @@ struct VirtMachineClass {
|
||||
bool no_tcg_lpa2;
|
||||
bool no_ns_el2_virt_timer_irq;
|
||||
bool no_nested_smmu;
|
||||
+ bool manufacturer_product_compat;
|
||||
};
|
||||
|
||||
struct VirtMachineState {
|
||||
260
0009-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch
Normal file
260
0009-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch
Normal file
@ -0,0 +1,260 @@
|
||||
From d944ff2722e07a8829b918ec1e414fd7a1421ca1 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: [PATCH] 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):
|
||||
- Convert to new DEFINE_CCW_MACHINE macros
|
||||
|
||||
Rebase notes (10.0.0):
|
||||
- Use upstream compat
|
||||
- Disabled relaxed-translation for older types
|
||||
|
||||
Rebase notes (10.1.0):
|
||||
- Use rebase compat
|
||||
|
||||
Merged patches (9.1.0):
|
||||
- 043ad5ce97 Add upstream compatibility bits (partial)
|
||||
- 04596b496e s390x: remove deprecated rhel machine types
|
||||
|
||||
Merged patches (10.0.0 rc0):
|
||||
- 03502faf70 Add upstream compatibility bits (partial)
|
||||
- d27437e5ba redhat: Add QEMU 9.1 compat handling to the s390x machine types
|
||||
- 926a9d0ca2 redhat: Add rhel9.6.0 and rhel10.0.0 machine types
|
||||
- d93fcb3940 virtio-net: disable USO for all RHEL9 (partial)
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 106 +++++++++++++++++++++++++++++--
|
||||
target/s390x/cpu_models.c | 11 ++++
|
||||
target/s390x/cpu_models.h | 2 +
|
||||
target/s390x/cpu_models_system.c | 2 +
|
||||
4 files changed, 116 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 2fca2bcf4d..9be423858d 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -716,6 +716,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 */
|
||||
@@ -735,6 +736,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)
|
||||
{
|
||||
@@ -883,7 +885,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__) ")"; \
|
||||
mc->init = MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__); \
|
||||
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
|
||||
if (latest) { \
|
||||
@@ -904,11 +906,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 */
|
||||
@@ -1170,6 +1172,100 @@ DEFINE_CCW_MACHINE(4, 2);
|
||||
|
||||
#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)
|
||||
+{
|
||||
+ S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
||||
+ static GlobalProperty compat[] = {
|
||||
+ { TYPE_S390_PCI_DEVICE, "relaxed-translation", "off", },
|
||||
+ };
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_2, hw_compat_rhel_10_2_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
|
||||
+ s390mc->use_cpi = false;
|
||||
+}
|
||||
+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);
|
||||
+
|
||||
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
+}
|
||||
+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)
|
||||
+{
|
||||
+ static GlobalProperty compat[] = {
|
||||
+ { 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(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 fe29f5c5b7..2a7fc949a4 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
|
||||
@@ -931,22 +934,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, const void *data)
|
||||
static void s390_base_cpu_model_class_init(ObjectClass *oc, const 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, const 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, const void *data)
|
||||
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
|
||||
index f701bc0b53..670a567c67 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_system.c b/target/s390x/cpu_models_system.c
|
||||
index 5b84604867..d715bdc870 100644
|
||||
--- a/target/s390x/cpu_models_system.c
|
||||
+++ b/target/s390x/cpu_models_system.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;
|
||||
485
0010-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch
Normal file
485
0010-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch
Normal file
@ -0,0 +1,485 @@
|
||||
From a4d11d87c642d697cdacf5eaf5cd6a6d2a0bbe0e 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:41 +0100
|
||||
Subject: [PATCH] Add downstream x86_64 versioned 'pc' & 'q35' machine types
|
||||
|
||||
Adding changes to add RHEL machine types for x86_64 architecture.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 2 +-
|
||||
hw/i386/pc.c | 70 ++++++++++++++++++++-
|
||||
hw/i386/pc_piix.c | 55 +++++++++++++++--
|
||||
hw/i386/pc_q35.c | 123 ++++++++++++++++++++++++++++++++++---
|
||||
include/hw/boards.h | 2 +
|
||||
include/hw/i386/pc.h | 21 +++++++
|
||||
target/i386/kvm/kvm-cpu.c | 1 +
|
||||
target/i386/kvm/kvm.c | 4 ++
|
||||
tests/qtest/meson.build | 2 +-
|
||||
tests/qtest/pvpanic-test.c | 5 +-
|
||||
10 files changed, 267 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 07df7281d2..8009f5f31f 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -75,7 +75,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
|
||||
if (pcmc->smbios_defaults) {
|
||||
/* These values are guest ABI, do not change */
|
||||
- smbios_set_defaults("QEMU", mc->desc, mc->name,
|
||||
+ smbios_set_defaults("Red Hat", "KVM", mc->desc,
|
||||
pcmc->smbios_stream_product, pcmc->smbios_stream_version);
|
||||
}
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 2f58e73d33..439abe8f46 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -273,6 +273,72 @@ const size_t pc_compat_2_6_len = G_N_ELEMENTS(pc_compat_2_6);
|
||||
*/
|
||||
#define PC_FW_DATA (0x20000 + 0x8000)
|
||||
|
||||
+/* This macro is for changes to properties that are RHEL specific,
|
||||
+ * different to the current upstream and to be applied to the latest
|
||||
+ * machine type.
|
||||
+ */
|
||||
+GlobalProperty pc_rhel_compat[] = {
|
||||
+ /* we don't support s3/s4 suspend */
|
||||
+ { "PIIX4_PM", "disable_s3", "1" },
|
||||
+ { "PIIX4_PM", "disable_s4", "1" },
|
||||
+ { "ICH9-LPC", "disable_s3", "1" },
|
||||
+ { "ICH9-LPC", "disable_s4", "1" },
|
||||
+
|
||||
+ { TYPE_X86_CPU, "host-phys-bits", "on" },
|
||||
+ { TYPE_X86_CPU, "host-phys-bits-limit", "48" },
|
||||
+ { TYPE_X86_CPU, "vmx-entry-load-perf-global-ctrl", "off" },
|
||||
+ { TYPE_X86_CPU, "vmx-exit-load-perf-global-ctrl", "off" },
|
||||
+ /* bz 1508330 */
|
||||
+ { "vfio-pci", "x-no-geforce-quirks", "on" },
|
||||
+ /* bz 1941397 */
|
||||
+ { TYPE_X86_CPU, "kvm-asyncpf-int", "on" },
|
||||
+};
|
||||
+const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat);
|
||||
+
|
||||
+GlobalProperty pc_rhel_10_2_compat[] = {
|
||||
+ /* pc_rhel_10_2_compat from pc_compat_10_0 */
|
||||
+ { TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
+ { TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
+};
|
||||
+const size_t pc_rhel_10_2_compat_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
+
|
||||
+GlobalProperty pc_rhel_10_1_compat[] = {
|
||||
+ /* pc_rhel_10_1_compat from pc_compat_9_1 */
|
||||
+ { "ICH9-LPC", "x-smi-swsmi-timer", "off" },
|
||||
+ { "ICH9-LPC", "x-smi-periodic-timer", "off" },
|
||||
+ { TYPE_INTEL_IOMMU_DEVICE, "stale-tm", "on" },
|
||||
+ { TYPE_INTEL_IOMMU_DEVICE, "aw-bits", "39" },
|
||||
+};
|
||||
+const size_t pc_rhel_10_1_compat_len = G_N_ELEMENTS(pc_rhel_10_1_compat);
|
||||
+
|
||||
+GlobalProperty pc_rhel_10_0_compat[] = {
|
||||
+ /* pc_rhel_10_0_compat from pc_compat_9_0 */
|
||||
+ { TYPE_X86_CPU, "x-amd-topoext-features-only", "false" },
|
||||
+ { TYPE_X86_CPU, "x-l1-cache-per-thread", "false" },
|
||||
+ { TYPE_X86_CPU, "guest-phys-bits", "0" },
|
||||
+ { "sev-guest", "legacy-vm-type", "on" },
|
||||
+ { TYPE_X86_CPU, "legacy-multi-node", "on" },
|
||||
+};
|
||||
+const size_t pc_rhel_10_0_compat_len = G_N_ELEMENTS(pc_rhel_10_0_compat);
|
||||
+
|
||||
+GlobalProperty pc_rhel_9_3_compat[] = {
|
||||
+ /* pc_rhel_9_3_compat from pc_compat_8_0 */
|
||||
+ { "virtio-mem", "unplugged-inaccessible", "auto" },
|
||||
+};
|
||||
+const size_t pc_rhel_9_3_compat_len = G_N_ELEMENTS(pc_rhel_9_3_compat);
|
||||
+
|
||||
+GlobalProperty pc_rhel_9_2_compat[] = {
|
||||
+ /* pc_rhel_9_2_compat from pc_compat_7_2 */
|
||||
+ { "ICH9-LPC", "noreboot", "true" },
|
||||
+};
|
||||
+const size_t pc_rhel_9_2_compat_len = G_N_ELEMENTS(pc_rhel_9_2_compat);
|
||||
+
|
||||
+GlobalProperty pc_rhel_9_0_compat[] = {
|
||||
+ /* pc_rhel_9_0_compat from pc_compat_6_2 */
|
||||
+ { "virtio-mem", "unplugged-inaccessible", "off" },
|
||||
+};
|
||||
+const size_t pc_rhel_9_0_compat_len = G_N_ELEMENTS(pc_rhel_9_0_compat);
|
||||
+
|
||||
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
|
||||
{
|
||||
GSIState *s;
|
||||
@@ -1754,6 +1820,7 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
|
||||
pcmc->kvmclock_create_always = true;
|
||||
x86mc->apic_xrupt_override = true;
|
||||
assert(!mc->get_hotplug_handler);
|
||||
+ mc->async_pf_vmexit_disable = false;
|
||||
mc->get_hotplug_handler = pc_get_hotplug_handler;
|
||||
mc->hotplug_allowed = pc_hotplug_allowed;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
@@ -1761,7 +1828,8 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
|
||||
mc->has_hotpluggable_cpus = true;
|
||||
mc->default_boot_order = "cad";
|
||||
mc->block_default_type = IF_IDE;
|
||||
- mc->max_cpus = 255;
|
||||
+ /* 240: max CPU count for RHEL */
|
||||
+ mc->max_cpus = 240;
|
||||
mc->reset = pc_machine_reset;
|
||||
mc->wakeup = pc_machine_wakeup;
|
||||
hc->pre_plug = pc_machine_device_pre_plug_cb;
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index acf010e20f..d546c4a8a9 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "system/xen.h"
|
||||
+#include "migration/migration.h"
|
||||
#ifdef CONFIG_XEN
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
#include "hw/xen/xen_pt.h"
|
||||
@@ -469,11 +470,11 @@ static void pc_i440fx_init(MachineState *machine)
|
||||
pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
|
||||
}
|
||||
|
||||
-#define DEFINE_I440FX_MACHINE(major, minor) \
|
||||
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor);
|
||||
+#define DEFINE_I440FX_MACHINE(major, minor, micro) \
|
||||
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor, micro);
|
||||
|
||||
-#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
|
||||
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor);
|
||||
+#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor, micro) \
|
||||
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor, micro);
|
||||
|
||||
#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void pc_i440fx_machine_options(MachineClass *m)
|
||||
@@ -853,3 +854,49 @@ static void xenfv_machine_3_1_options(MachineClass *m)
|
||||
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
|
||||
xenfv_machine_3_1_options);
|
||||
#endif
|
||||
+
|
||||
+/* Red Hat Enterprise Linux machine types */
|
||||
+
|
||||
+static void pc_machine_rhel10_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ ObjectClass *oc = OBJECT_CLASS(m);
|
||||
+ pcmc->default_south_bridge = TYPE_PIIX3_DEVICE;
|
||||
+ pcmc->pci_root_uid = 0;
|
||||
+ pcmc->default_cpu_version = 1;
|
||||
+
|
||||
+ m->family = "pc_piix_Y";
|
||||
+ m->default_machine_opts = "firmware=bios-256k.bin";
|
||||
+ m->default_display = "std";
|
||||
+ m->default_nic = "e1000";
|
||||
+ m->no_parallel = 1;
|
||||
+ m->no_floppy = 1;
|
||||
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
|
||||
+
|
||||
+ object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption",
|
||||
+ &PCSouthBridgeOption_lookup,
|
||||
+ pc_get_south_bridge,
|
||||
+ pc_set_south_bridge);
|
||||
+ object_class_property_set_description(oc, "x-south-bridge",
|
||||
+ "Use a different south bridge than PIIX3");
|
||||
+ compat_props_add(m->compat_props,
|
||||
+ pc_piix_compat_defaults, pc_piix_compat_defaults_len);
|
||||
+}
|
||||
+
|
||||
+static void pc_i440fx_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
+{
|
||||
+ pc_machine_rhel10_options(m);
|
||||
+
|
||||
+ m->desc = "RHEL 10.0.0 PC (i440FX + PIIX, 1996)";
|
||||
+ m->deprecation_reason = rhel_old_machine_deprecation;
|
||||
+
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_10_2,
|
||||
+ hw_compat_rhel_10_2_len);
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_10_1,
|
||||
+ hw_compat_rhel_10_1_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_10_2_compat,
|
||||
+ pc_rhel_10_2_compat_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_10_1_compat,
|
||||
+ pc_rhel_10_1_compat_len);
|
||||
+}
|
||||
+DEFINE_I440FX_MACHINE_AS_LATEST(10, 0, 0);
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index 2203ffd67e..e5d10c0335 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -340,11 +340,11 @@ static void pc_q35_init(MachineState *machine)
|
||||
#endif
|
||||
}
|
||||
|
||||
-#define DEFINE_Q35_MACHINE(major, minor) \
|
||||
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor);
|
||||
+#define DEFINE_Q35_MACHINE(major, minor, micro) \
|
||||
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro);
|
||||
|
||||
-#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor) \
|
||||
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor);
|
||||
+#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor, micro) \
|
||||
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor, micro);
|
||||
|
||||
#define DEFINE_Q35_MACHINE_BUGFIX(major, minor, micro) \
|
||||
DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro);
|
||||
@@ -355,21 +355,21 @@ static void pc_q35_machine_options(MachineClass *m)
|
||||
pcmc->pci_root_uid = 0;
|
||||
pcmc->default_cpu_version = 1;
|
||||
|
||||
- m->family = "pc_q35";
|
||||
- m->desc = "Standard PC (Q35 + ICH9, 2009)";
|
||||
+ m->family = "pc_q35_Z";
|
||||
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_display = "std";
|
||||
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->no_parallel = 1;
|
||||
+ m->alias = "q35";
|
||||
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_RAMFB_DEVICE);
|
||||
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
|
||||
machine_class_allow_dynamic_sysbus_dev(m, TYPE_UEFI_VARS_X64);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
|
||||
compat_props_add(m->compat_props,
|
||||
pc_q35_compat_defaults, pc_q35_compat_defaults_len);
|
||||
}
|
||||
@@ -687,3 +687,108 @@ static void pc_q35_machine_2_6_options(MachineClass *m)
|
||||
|
||||
DEFINE_Q35_MACHINE(2, 6);
|
||||
#endif /* Disabled for Red Hat Enterprise Linux */
|
||||
+
|
||||
+/* Red Hat Enterprise Linux machine types */
|
||||
+
|
||||
+static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_machine_options(m);
|
||||
+ m->desc = "RHEL-10.0.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "10.0.0";
|
||||
+
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_10_2,
|
||||
+ hw_compat_rhel_10_2_len);
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_10_1,
|
||||
+ hw_compat_rhel_10_1_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_10_2_compat,
|
||||
+ pc_rhel_10_2_compat_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_10_1_compat,
|
||||
+ pc_rhel_10_1_compat_len);
|
||||
+}
|
||||
+DEFINE_Q35_MACHINE_AS_LATEST(10, 0, 0);
|
||||
+
|
||||
+static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_rhel_machine_10_0_0_options(m);
|
||||
+ m->desc = "RHEL-9.6.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "9.6.0";
|
||||
+
|
||||
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
+}
|
||||
+
|
||||
+DEFINE_Q35_MACHINE(9, 6, 0);
|
||||
+
|
||||
+static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_rhel_machine_9_6_0_options(m);
|
||||
+
|
||||
+ /* older RHEL machines continue to support 710 vcpus */
|
||||
+ m->max_cpus = 710;
|
||||
+ m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
|
||||
+ 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,
|
||||
+ hw_compat_rhel_9_5_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_10_0_compat,
|
||||
+ pc_rhel_10_0_compat_len);
|
||||
+}
|
||||
+
|
||||
+DEFINE_Q35_MACHINE(9, 4, 0);
|
||||
+
|
||||
+static void pc_q35_rhel_machine_9_2_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_rhel_machine_9_4_0_options(m);
|
||||
+ m->desc = "RHEL-9.2.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "9.2.0";
|
||||
+
|
||||
+ /* From pc_q35_8_0_machine_options() */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||
+ /* From pc_q35_8_1_machine_options() */
|
||||
+ pcmc->broken_32bit_mem_addr_check = true;
|
||||
+
|
||||
+ 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,
|
||||
+ hw_compat_rhel_9_3_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_9_3_compat,
|
||||
+ pc_rhel_9_3_compat_len);
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9_2,
|
||||
+ hw_compat_rhel_9_2_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_9_2_compat,
|
||||
+ pc_rhel_9_2_compat_len);
|
||||
+}
|
||||
+
|
||||
+DEFINE_Q35_MACHINE(9, 2, 0);
|
||||
+
|
||||
+static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_rhel_machine_9_2_0_options(m);
|
||||
+ m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "9.0.0";
|
||||
+ pcmc->enforce_amd_1tb_hole = false;
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9_1,
|
||||
+ hw_compat_rhel_9_1_len);
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9_0,
|
||||
+ hw_compat_rhel_9_0_len);
|
||||
+ compat_props_add(m->compat_props, pc_rhel_9_0_compat,
|
||||
+ pc_rhel_9_0_compat_len);
|
||||
+}
|
||||
+
|
||||
+DEFINE_Q35_MACHINE(9, 0, 0);
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index aca254ea18..22c3abd51e 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -308,6 +308,8 @@ struct MachineClass {
|
||||
strList *allowed_dynamic_sysbus_devices;
|
||||
bool auto_enable_numa_with_memhp;
|
||||
bool auto_enable_numa_with_memdev;
|
||||
+ /* RHEL only */
|
||||
+ bool async_pf_vmexit_disable;
|
||||
bool ignore_boot_device_suffixes;
|
||||
bool smbus_no_migration_support;
|
||||
bool nvdimm_supported;
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index 3b4ea24c20..633df2fcf8 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -301,6 +301,27 @@ extern const size_t pc_compat_2_7_len;
|
||||
extern GlobalProperty pc_compat_2_6[];
|
||||
extern const size_t pc_compat_2_6_len;
|
||||
|
||||
+extern GlobalProperty pc_rhel_compat[];
|
||||
+extern const size_t pc_rhel_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_10_2_compat[];
|
||||
+extern const size_t pc_rhel_10_2_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_10_1_compat[];
|
||||
+extern const size_t pc_rhel_10_1_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_10_0_compat[];
|
||||
+extern const size_t pc_rhel_10_0_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_9_3_compat[];
|
||||
+extern const size_t pc_rhel_9_3_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_9_2_compat[];
|
||||
+extern const size_t pc_rhel_9_2_compat_len;
|
||||
+
|
||||
+extern GlobalProperty pc_rhel_9_0_compat[];
|
||||
+extern const size_t pc_rhel_9_0_compat_len;
|
||||
+
|
||||
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
|
||||
static void pc_machine_##suffix##_class_init(ObjectClass *oc, \
|
||||
const void *data) \
|
||||
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
|
||||
index 89a7953659..74c0b036e3 100644
|
||||
--- a/target/i386/kvm/kvm-cpu.c
|
||||
+++ b/target/i386/kvm/kvm-cpu.c
|
||||
@@ -175,6 +175,7 @@ static PropValue kvm_default_props[] = {
|
||||
{ "acpi", "off" },
|
||||
{ "monitor", "off" },
|
||||
{ "svm", "off" },
|
||||
+ { "kvm-pv-unhalt", "on" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
|
||||
index 369626f8c8..0eb39d22d6 100644
|
||||
--- a/target/i386/kvm/kvm.c
|
||||
+++ b/target/i386/kvm/kvm.c
|
||||
@@ -4389,6 +4389,7 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
|
||||
int ret, i;
|
||||
uint64_t mtrr_top_bits;
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||
|
||||
kvm_msr_buf_reset(cpu);
|
||||
|
||||
@@ -4786,6 +4787,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
break;
|
||||
case MSR_KVM_ASYNC_PF_EN:
|
||||
env->async_pf_en_msr = msrs[i].data;
|
||||
+ if (mc->async_pf_vmexit_disable) {
|
||||
+ env->async_pf_en_msr &= ~(1ULL << 2);
|
||||
+ }
|
||||
break;
|
||||
case MSR_KVM_ASYNC_PF_INT:
|
||||
env->async_pf_int_msr = msrs[i].data;
|
||||
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
|
||||
index 669d07c06b..b96aa06084 100644
|
||||
--- a/tests/qtest/meson.build
|
||||
+++ b/tests/qtest/meson.build
|
||||
@@ -49,6 +49,7 @@ qtests_filter = \
|
||||
(get_option('default_devices') and host_os != 'windows' ? ['test-filter-mirror'] : []) + \
|
||||
(get_option('default_devices') and host_os != 'windows' ? ['test-filter-redirector'] : [])
|
||||
|
||||
+# RHEL: Removed intel-iommu-test as it's not working with 10.0 machine type
|
||||
qtests_i386 = \
|
||||
(slirp.found() ? ['pxe-test'] : []) + \
|
||||
qtests_filter + \
|
||||
@@ -94,7 +95,6 @@ qtests_i386 = \
|
||||
(config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \
|
||||
- (config_all_devices.has_key('CONFIG_VTD') ? ['intel-iommu-test'] : []) + \
|
||||
(host_os != 'windows' and \
|
||||
config_all_devices.has_key('CONFIG_ACPI_ERST') ? ['erst-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_PCIE_PORT') and \
|
||||
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
|
||||
index 5606baf47b..094c56b0cd 100644
|
||||
--- a/tests/qtest/pvpanic-test.c
|
||||
+++ b/tests/qtest/pvpanic-test.c
|
||||
@@ -18,7 +18,7 @@ static void test_panic_nopause(void)
|
||||
QDict *response, *data;
|
||||
QTestState *qts;
|
||||
|
||||
- qts = qtest_init("-device pvpanic -action panic=none");
|
||||
+ qts = qtest_init("-M q35 -device pvpanic -action panic=none");
|
||||
|
||||
val = qtest_inb(qts, 0x505);
|
||||
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
|
||||
@@ -41,7 +41,8 @@ static void test_panic(void)
|
||||
QDict *response, *data;
|
||||
QTestState *qts;
|
||||
|
||||
- qts = qtest_init("-device pvpanic -action panic=pause");
|
||||
+ /* RHEL: Use q35 */
|
||||
+ qts = qtest_init("-M q35 -device pvpanic -action panic=pause");
|
||||
|
||||
val = qtest_inb(qts, 0x505);
|
||||
g_assert_cmpuint(val, ==, PVPANIC_EVENTS);
|
||||
55
0011-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch
Normal file
55
0011-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 6eb636192635d165336534dbbe312145958df5a6 Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Bolognani <abologna@redhat.com>
|
||||
Date: Tue, 10 Jun 2025 14:27:29 +0200
|
||||
Subject: [PATCH] Disable virtio-net-pci romfile loading on riscv64
|
||||
|
||||
RH-Author: Andrea Bolognani <None>
|
||||
RH-MergeRequest: 373: Various small fixes
|
||||
RH-Jira: RHEL-96057
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [4/4] b490ef3c3ab6a47f90c67016f685e19a65d97100 (abologna/centos-stream-qemu-kvm)
|
||||
|
||||
Same motivation for disabling it as on aarch64.
|
||||
|
||||
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
|
||||
|
||||
Patch-name: kvm-Disable-virtio-net-pci-romfile-loading-on-riscv64.patch
|
||||
Patch-id: 51
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/riscv/virt.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
|
||||
index ab5a9ec613..3b187d6c98 100644
|
||||
--- a/hw/riscv/virt.c
|
||||
+++ b/hw/riscv/virt.c
|
||||
@@ -59,6 +59,18 @@
|
||||
#include "hw/virtio/virtio-iommu.h"
|
||||
#include "hw/uefi/var-service-api.h"
|
||||
|
||||
+/*
|
||||
+ * virtio-net-pci variant romfiles are not needed because edk2 does
|
||||
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
|
||||
+ * on rhel/riscv64.
|
||||
+ */
|
||||
+static GlobalProperty riscv_virt_compat[] = {
|
||||
+ {"virtio-net-pci", "romfile", "" },
|
||||
+ {"virtio-net-pci-transitional", "romfile", "" },
|
||||
+ {"virtio-net-pci-non-transitional", "romfile", "" },
|
||||
+};
|
||||
+const size_t riscv_virt_compat_len = G_N_ELEMENTS(riscv_virt_compat);
|
||||
+
|
||||
/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
|
||||
static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
|
||||
{
|
||||
@@ -1978,6 +1990,9 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
NULL, NULL);
|
||||
object_class_property_set_description(oc, "iommu-sys",
|
||||
"Enable IOMMU platform device");
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, riscv_virt_compat,
|
||||
+ riscv_virt_compat_len);
|
||||
}
|
||||
|
||||
static const TypeInfo virt_machine_typeinfo = {
|
||||
29
0012-Revert-meson-temporarily-disable-Wunused-function.patch
Normal file
29
0012-Revert-meson-temporarily-disable-Wunused-function.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 299a99e5714de89647c0fac650026682b365c040 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: [PATCH] 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 23494666d9..ef2e5be6e2 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -757,7 +757,6 @@ warn_flags = [
|
||||
'-Wno-string-plus-int',
|
||||
'-Wno-tautological-type-limit-compare',
|
||||
'-Wno-typedef-redefinition',
|
||||
- '-Wno-unused-function',
|
||||
]
|
||||
|
||||
if host_os != 'darwin'
|
||||
346
0013-Enable-make-check.patch
Normal file
346
0013-Enable-make-check.patch
Normal file
@ -0,0 +1,346 @@
|
||||
From 0cc1623ce4c79af21ce7a3e8c3b67315ff9e3e7b Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 2 Sep 2020 09:39:41 +0200
|
||||
Subject: [PATCH] Enable make check
|
||||
|
||||
Fixing tests after device disabling and machine types changes and enabling
|
||||
make check run during build.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
tests/functional/meson.build | 2 +-
|
||||
tests/functional/test_aarch64_tcg_plugins.py | 4 +--
|
||||
tests/qemu-iotests/meson.build | 34 ++++++++++----------
|
||||
tests/qemu-iotests/testenv.py | 3 ++
|
||||
tests/qtest/bios-tables-test.c | 10 ++++++
|
||||
tests/qtest/fuzz-e1000e-test.c | 2 +-
|
||||
tests/qtest/fuzz-virtio-scsi-test.c | 2 +-
|
||||
tests/qtest/intel-hda-test.c | 2 +-
|
||||
tests/qtest/libqos/meson.build | 2 +-
|
||||
tests/qtest/lpc-ich9-test.c | 2 +-
|
||||
tests/qtest/machine-none-test.c | 2 +-
|
||||
tests/qtest/meson.build | 1 -
|
||||
tests/qtest/pvpanic-test.c | 2 +-
|
||||
tests/qtest/riscv-csr-test.c | 4 +++
|
||||
tests/qtest/virtio-net-failover.c | 1 +
|
||||
15 files changed, 45 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
|
||||
index 311c6f1806..c7f9051c90 100644
|
||||
--- a/tests/functional/meson.build
|
||||
+++ b/tests/functional/meson.build
|
||||
@@ -319,7 +319,7 @@ tests_sparc64_system_thorough = [
|
||||
|
||||
tests_x86_64_system_quick = [
|
||||
'cpu_queries',
|
||||
- 'mem_addr_space',
|
||||
+# 'mem_addr_space',
|
||||
'migration',
|
||||
'pc_cpu_hotplug_props',
|
||||
'virtio_version',
|
||||
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/test_aarch64_tcg_plugins.py
|
||||
index cb7e9298fb..9efa826b01 100755
|
||||
--- a/tests/functional/test_aarch64_tcg_plugins.py
|
||||
+++ b/tests/functional/test_aarch64_tcg_plugins.py
|
||||
@@ -64,7 +64,7 @@ class PluginKernelNormal(PluginKernelBase):
|
||||
|
||||
def test_aarch64_virt_insn(self):
|
||||
self.set_machine('virt')
|
||||
- self.cpu='cortex-a53'
|
||||
+ self.cpu='cortex-a57'
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'console=ttyAMA0')
|
||||
@@ -90,7 +90,7 @@ def test_aarch64_virt_insn(self):
|
||||
|
||||
def test_aarch64_virt_insn_icount(self):
|
||||
self.set_machine('virt')
|
||||
- self.cpu='cortex-a53'
|
||||
+ self.cpu='cortex-a57'
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'console=ttyAMA0')
|
||||
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
|
||||
index fad340ad59..3c0d5241f6 100644
|
||||
--- a/tests/qemu-iotests/meson.build
|
||||
+++ b/tests/qemu-iotests/meson.build
|
||||
@@ -51,21 +51,21 @@ foreach format, speed: qemu_iotests_formats
|
||||
check: true,
|
||||
)
|
||||
|
||||
- foreach item: rc.stdout().strip().split()
|
||||
- args = [qemu_iotests_check_cmd,
|
||||
- '-tap', '-' + format, item,
|
||||
- '--source-dir', meson.current_source_dir(),
|
||||
- '--build-dir', meson.current_build_dir()]
|
||||
- # Some individual tests take as long as 45 seconds
|
||||
- # Bump the timeout to 3 minutes for some headroom
|
||||
- # on slow machines to minimize spurious failures
|
||||
- test('io-' + format + '-' + item,
|
||||
- python,
|
||||
- args: args,
|
||||
- depends: qemu_iotests_binaries,
|
||||
- env: qemu_iotests_env,
|
||||
- protocol: 'tap',
|
||||
- timeout: 180,
|
||||
- suite: suites)
|
||||
- endforeach
|
||||
+# foreach item: rc.stdout().strip().split()
|
||||
+# args = [qemu_iotests_check_cmd,
|
||||
+# '-tap', '-' + format, item,
|
||||
+# '--source-dir', meson.current_source_dir(),
|
||||
+# '--build-dir', meson.current_build_dir()]
|
||||
+# # Some individual tests take as long as 45 seconds
|
||||
+# # Bump the timeout to 3 minutes for some headroom
|
||||
+# # on slow machines to minimize spurious failures
|
||||
+# test('io-' + format + '-' + item,
|
||||
+# python,
|
||||
+# args: args,
|
||||
+# depends: qemu_iotests_binaries,
|
||||
+# env: qemu_iotests_env,
|
||||
+# protocol: 'tap',
|
||||
+# timeout: 180,
|
||||
+# suite: suites)
|
||||
+# endforeach
|
||||
endforeach
|
||||
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
|
||||
index 6326e46b7b..bc849ae9cf 100644
|
||||
--- a/tests/qemu-iotests/testenv.py
|
||||
+++ b/tests/qemu-iotests/testenv.py
|
||||
@@ -252,6 +252,9 @@ def __init__(self, source_dir: str, build_dir: str,
|
||||
if self.qemu_prog.endswith(f'qemu-system-{suffix}'):
|
||||
self.qemu_options += f' -machine {machine}'
|
||||
|
||||
+ if self.qemu_prog.endswith('qemu-system-x86_64'):
|
||||
+ self.qemu_options += ' -cpu Nehalem'
|
||||
+
|
||||
# QEMU_DEFAULT_MACHINE
|
||||
self.qemu_default_machine = get_default_machine(self.qemu_prog)
|
||||
|
||||
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
|
||||
index e7e6926c81..386196edc8 100644
|
||||
--- a/tests/qtest/bios-tables-test.c
|
||||
+++ b/tests/qtest/bios-tables-test.c
|
||||
@@ -1755,6 +1755,7 @@ static void test_acpi_microvm_ioapic2_tcg(void)
|
||||
free_test_data(&data);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void test_acpi_riscv64_virt_tcg_numamem(void)
|
||||
{
|
||||
test_data data = {
|
||||
@@ -1780,6 +1781,7 @@ static void test_acpi_riscv64_virt_tcg_numamem(void)
|
||||
&data);
|
||||
free_test_data(&data);
|
||||
}
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
static void test_acpi_aarch64_virt_tcg_numamem(void)
|
||||
{
|
||||
@@ -1856,6 +1858,7 @@ static void test_acpi_aarch64_virt_tcg_acpi_spcr(void)
|
||||
free_test_data(&data);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void test_acpi_riscv64_virt_tcg_acpi_spcr(void)
|
||||
{
|
||||
test_data data = {
|
||||
@@ -1874,6 +1877,7 @@ static void test_acpi_riscv64_virt_tcg_acpi_spcr(void)
|
||||
"-machine spcr=off", &data);
|
||||
free_test_data(&data);
|
||||
}
|
||||
+#endif
|
||||
|
||||
static void test_acpi_tcg_acpi_hmat(const char *machine, const char *arch)
|
||||
{
|
||||
@@ -2171,6 +2175,7 @@ static void test_acpi_microvm_acpi_erst(void)
|
||||
}
|
||||
#endif /* CONFIG_POSIX */
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void test_acpi_riscv64_virt_tcg(void)
|
||||
{
|
||||
test_data data = {
|
||||
@@ -2192,6 +2197,7 @@ static void test_acpi_riscv64_virt_tcg(void)
|
||||
test_acpi_one("-cpu rva22s64 ", &data);
|
||||
free_test_data(&data);
|
||||
}
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
static void test_acpi_aarch64_virt_tcg(void)
|
||||
{
|
||||
@@ -2526,6 +2532,7 @@ static void test_acpi_aarch64_virt_oem_fields(void)
|
||||
g_free(args);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
#define LOONGARCH64_INIT_TEST_DATA(data) \
|
||||
test_data data = { \
|
||||
.machine = "virt", \
|
||||
@@ -2594,6 +2601,7 @@ static void test_acpi_loongarch64_virt_oem_fields(void)
|
||||
free_test_data(&data);
|
||||
g_free(args);
|
||||
}
|
||||
+#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -2769,6 +2777,7 @@ int main(int argc, char *argv[])
|
||||
qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
|
||||
}
|
||||
}
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
} else if (strcmp(arch, "riscv64") == 0) {
|
||||
if (has_tcg && qtest_has_device("virtio-blk-pci")) {
|
||||
qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg);
|
||||
@@ -2788,6 +2797,7 @@ int main(int argc, char *argv[])
|
||||
qtest_add_func("acpi/virt/oem-fields",
|
||||
test_acpi_loongarch64_virt_oem_fields);
|
||||
}
|
||||
+#endif /* disabled for RHEL */
|
||||
}
|
||||
ret = g_test_run();
|
||||
boot_sector_cleanup(disk);
|
||||
diff --git a/tests/qtest/fuzz-e1000e-test.c b/tests/qtest/fuzz-e1000e-test.c
|
||||
index 5052883fb6..8242190170 100644
|
||||
--- a/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)
|
||||
{
|
||||
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-rhel9.4.0");
|
||||
|
||||
qtest_outl(s, 0xcf8, 0x80001010);
|
||||
qtest_outl(s, 0xcfc, 0xe1020000);
|
||||
diff --git a/tests/qtest/fuzz-virtio-scsi-test.c b/tests/qtest/fuzz-virtio-scsi-test.c
|
||||
index e37b48b2cc..9f1965b530 100644
|
||||
--- a/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)
|
||||
{
|
||||
QTestState *s;
|
||||
|
||||
- s = qtest_init("-M pc-q35-5.2 -m 512M "
|
||||
+ s = qtest_init("-M pc-q35-rhel9.4.0 -m 512M "
|
||||
"-device virtio-scsi,num_queues=8,addr=03.0 ");
|
||||
|
||||
qtest_outl(s, 0xcf8, 0x80001811);
|
||||
diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c
|
||||
index 663bb6c485..2efc43e3f7 100644
|
||||
--- a/tests/qtest/intel-hda-test.c
|
||||
+++ b/tests/qtest/intel-hda-test.c
|
||||
@@ -42,7 +42,7 @@ static void test_issue542_ich6(void)
|
||||
{
|
||||
QTestState *s;
|
||||
|
||||
- s = qtest_init("-nographic -nodefaults -M pc-q35-6.2 "
|
||||
+ s = qtest_init("-nographic -nodefaults -M pc-q35-rhel9.0.0 "
|
||||
AUDIODEV
|
||||
"-device intel-hda,id=" HDA_ID CODEC_DEVICES);
|
||||
|
||||
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
|
||||
index 1ddaf7b095..1cb403e90d 100644
|
||||
--- a/tests/qtest/libqos/meson.build
|
||||
+++ b/tests/qtest/libqos/meson.build
|
||||
@@ -43,7 +43,7 @@ libqos_srcs = files(
|
||||
'virtio-rng.c',
|
||||
'virtio-scsi.c',
|
||||
'virtio-serial.c',
|
||||
- 'virtio-iommu.c',
|
||||
+# 'virtio-iommu.c',
|
||||
'virtio-gpio.c',
|
||||
'virtio-scmi.c',
|
||||
'generic-pcihost.c',
|
||||
diff --git a/tests/qtest/lpc-ich9-test.c b/tests/qtest/lpc-ich9-test.c
|
||||
index 8ac95b89f7..0e118b76eb 100644
|
||||
--- a/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)
|
||||
{
|
||||
QTestState *s;
|
||||
|
||||
- s = qtest_init("-M pc-q35-5.0 "
|
||||
+ s = qtest_init("-M pc-q35-rhel9.4.0 "
|
||||
"-nographic -monitor none -serial none");
|
||||
|
||||
qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */
|
||||
diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
|
||||
index b6a87d27ed..423ba12159 100644
|
||||
--- a/tests/qtest/machine-none-test.c
|
||||
+++ b/tests/qtest/machine-none-test.c
|
||||
@@ -49,7 +49,7 @@ static struct arch2cpu cpus_map[] = {
|
||||
{ "xtensa", "dc233c" },
|
||||
{ "xtensaeb", "fsf" },
|
||||
{ "hppa", "hppa" },
|
||||
- { "riscv64", "rv64" },
|
||||
+ { "riscv64", "max" },
|
||||
{ "riscv32", "rv32" },
|
||||
{ "rx", "rx62n" },
|
||||
{ "loongarch64", "la464"},
|
||||
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
|
||||
index b96aa06084..ef44ffaf78 100644
|
||||
--- a/tests/qtest/meson.build
|
||||
+++ b/tests/qtest/meson.build
|
||||
@@ -91,7 +91,6 @@ qtests_i386 = \
|
||||
(config_all_devices.has_key('CONFIG_LSI_SCSI_PCI') ? ['fuzz-lsi53c895a-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_VIRTIO_SCSI') ? ['fuzz-virtio-scsi-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_VIRTIO_BALLOON') ? ['virtio-balloon-test'] : []) + \
|
||||
- (config_all_devices.has_key('CONFIG_Q35') ? ['q35-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_ESP_PCI') ? ['am53c974-test'] : []) + \
|
||||
diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c
|
||||
index 094c56b0cd..338f94dcd9 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/riscv-csr-test.c b/tests/qtest/riscv-csr-test.c
|
||||
index ff5c29e6c6..cc3b08a976 100644
|
||||
--- a/tests/qtest/riscv-csr-test.c
|
||||
+++ b/tests/qtest/riscv-csr-test.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#define CSR_MVENDORID 0xf11
|
||||
#define CSR_MISELECT 0x350
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void run_test_csr(void)
|
||||
{
|
||||
uint64_t res;
|
||||
@@ -45,12 +46,15 @@ static void run_test_csr(void)
|
||||
|
||||
qtest_quit(qts);
|
||||
}
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
qtest_add_func("/cpu/csr", run_test_csr);
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c
|
||||
index 5baf81c3e6..aa87bf5698 100644
|
||||
--- a/tests/qtest/virtio-net-failover.c
|
||||
+++ b/tests/qtest/virtio-net-failover.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#define PCI_SEL_BASE 0x0010
|
||||
|
||||
#define BASE_MACHINE "-M q35 -nodefaults " \
|
||||
+ "-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=on " \
|
||||
"-device pcie-root-port,id=root0,addr=0x1,bus=pcie.0,chassis=1 " \
|
||||
"-device pcie-root-port,id=root1,addr=0x2,bus=pcie.0,chassis=2 "
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
From e9ebc159a9acf108e1ec6f622be3f256cf14aba7 Mon Sep 17 00:00:00 2001
|
||||
From 0da2ce92246aec2de87b314ed91f188f1b0bfbbd Mon Sep 17 00:00:00 2001
|
||||
From: Bandan Das <bsd@redhat.com>
|
||||
Date: Tue, 3 Dec 2013 20:05:13 +0100
|
||||
Subject: vfio: cap number of devices that can be assigned
|
||||
Subject: [PATCH] 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>
|
||||
@ -22,42 +22,66 @@ for other uses. Stepping down a bit, the number 32 arbitrarily
|
||||
matches the number of slots on a PCI bus and is also a nice power
|
||||
of two.
|
||||
|
||||
Count of slots increased to 509 later so we could increase limit
|
||||
to 64 as some usecases require more than 32 devices.
|
||||
|
||||
Signed-off-by: Bandan Das <bsd@redhat.com>
|
||||
|
||||
Rebase notes (2.8.0):
|
||||
- removed return value for vfio_realize (commit 1a22aca)
|
||||
Rebase changes (8.2.0):
|
||||
- Update to upstream changes
|
||||
|
||||
Merged patches (2.9.0):
|
||||
- 17eb774 vfio: Use error_setg when reporting max assigned device overshoot
|
||||
|
||||
Merged patches (4.1.0-rc3):
|
||||
- 2b89558 vfio: increase the cap on number of assigned devices to 64
|
||||
Rebased notes (10.1.0)
|
||||
- Update to upstream changes
|
||||
- Introduced vfio_device_count()
|
||||
---
|
||||
hw/vfio/pci.c | 29 ++++++++++++++++++++++++++++-
|
||||
hw/vfio/pci.h | 1 +
|
||||
2 files changed, 29 insertions(+), 1 deletion(-)
|
||||
hw/vfio/container.c | 14 ++++++++++++++
|
||||
hw/vfio/pci.c | 21 +++++++++++++++++++++
|
||||
hw/vfio/pci.h | 1 +
|
||||
include/hw/vfio/vfio-device.h | 1 +
|
||||
4 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
|
||||
index 3e13feaa74..b912b9396b 100644
|
||||
--- a/hw/vfio/container.c
|
||||
+++ b/hw/vfio/container.c
|
||||
@@ -44,6 +44,20 @@ typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
|
||||
static VFIOGroupList vfio_group_list =
|
||||
QLIST_HEAD_INITIALIZER(vfio_group_list);
|
||||
|
||||
+int vfio_device_count(void)
|
||||
+{
|
||||
+ int i = 0;
|
||||
+ VFIOGroup *group;
|
||||
+ VFIODevice *vbasedev_iter;
|
||||
+
|
||||
+ QLIST_FOREACH(group, &vfio_group_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
|
||||
+ i++;
|
||||
+ }
|
||||
+ }
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
static int vfio_ram_block_discard_disable(VFIOContainer *container, bool state)
|
||||
{
|
||||
switch (container->iommu_type) {
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index 7b45353ce2..eb725a3aee 100644
|
||||
index 07257d0fa0..48da233cb2 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -45,6 +45,9 @@
|
||||
|
||||
#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
|
||||
@@ -52,6 +52,9 @@
|
||||
/* Protected by BQL */
|
||||
static KVMRouteChange vfio_route_change;
|
||||
|
||||
+/* RHEL only: Set once for the first assigned dev */
|
||||
+static uint16_t device_limit;
|
||||
+
|
||||
static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
|
||||
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
|
||||
|
||||
@@ -2807,9 +2810,30 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
|
||||
ssize_t len;
|
||||
struct stat st;
|
||||
int groupid;
|
||||
- int i, ret;
|
||||
+ int ret, i = 0;
|
||||
bool is_mdev;
|
||||
static void vfio_msi_disable_common(VFIOPCIDevice *vdev);
|
||||
@@ -3355,6 +3358,21 @@ static void vfio_pci_realize(PCIDevice *pdev, Error **errp)
|
||||
char uuid[UUID_STR_LEN];
|
||||
g_autofree char *name = NULL;
|
||||
|
||||
+ if (device_limit && device_limit != vdev->assigned_device_limit) {
|
||||
+ error_setg(errp, "Assigned device limit has been redefined. "
|
||||
@ -68,22 +92,16 @@ index 7b45353ce2..eb725a3aee 100644
|
||||
+ device_limit = vdev->assigned_device_limit;
|
||||
+ }
|
||||
+
|
||||
+ QLIST_FOREACH(group, &vfio_group_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
|
||||
+ i++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i >= vdev->assigned_device_limit) {
|
||||
+ if (vfio_device_count() >= vdev->assigned_device_limit) {
|
||||
+ error_setg(errp, "Maximum supported vfio devices (%d) "
|
||||
+ "already attached", vdev->assigned_device_limit);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!vdev->vbasedev.sysfsdev) {
|
||||
if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
|
||||
if (!(~vdev->host.domain || ~vdev->host.bus ||
|
||||
~vdev->host.slot || ~vdev->host.function)) {
|
||||
@@ -3246,6 +3270,9 @@ static Property vfio_pci_dev_properties[] = {
|
||||
@@ -3687,6 +3705,9 @@ static const Property vfio_pci_dev_properties[] = {
|
||||
DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
|
||||
DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
|
||||
no_geforce_quirks, false),
|
||||
@ -94,10 +112,10 @@ index 7b45353ce2..eb725a3aee 100644
|
||||
false),
|
||||
DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
|
||||
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
|
||||
index 64777516d1..e0fe6ca97e 100644
|
||||
index 810a842f4a..81555d8774 100644
|
||||
--- a/hw/vfio/pci.h
|
||||
+++ b/hw/vfio/pci.h
|
||||
@@ -139,6 +139,7 @@ struct VFIOPCIDevice {
|
||||
@@ -145,6 +145,7 @@ struct VFIOPCIDevice {
|
||||
EventNotifier err_notifier;
|
||||
EventNotifier req_notifier;
|
||||
int (*resetfn)(struct VFIOPCIDevice *);
|
||||
@ -105,6 +123,15 @@ index 64777516d1..e0fe6ca97e 100644
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
uint32_t sub_vendor_id;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
|
||||
index 6e4d5ccdac..9290774299 100644
|
||||
--- a/include/hw/vfio/vfio-device.h
|
||||
+++ b/include/hw/vfio/vfio-device.h
|
||||
@@ -140,6 +140,7 @@ struct VFIODeviceOps {
|
||||
#define strwriteerror(ret) \
|
||||
(ret < 0 ? strerror(-ret) : "short write")
|
||||
|
||||
+int vfio_device_count(void);
|
||||
void vfio_device_irq_disable(VFIODevice *vbasedev, int index);
|
||||
void vfio_device_irq_unmask(VFIODevice *vbasedev, int index);
|
||||
void vfio_device_irq_mask(VFIODevice *vbasedev, int index);
|
||||
@ -1,30 +1,21 @@
|
||||
From b736b0c41dd62ed6f874a7b33ca1d4f9ceab4573 Mon Sep 17 00:00:00 2001
|
||||
From 82d41e31ab3a068793c14288bc5dff21cabf1aa8 Mon Sep 17 00:00:00 2001
|
||||
From: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Date: Wed, 4 Dec 2013 18:53:17 +0100
|
||||
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>
|
||||
Subject: [PATCH] Add support statement to -help output
|
||||
|
||||
Add support statement to -help output, reporting direct qemu-kvm usage
|
||||
as unsupported by Red Hat, and advising users to use libvirt instead.
|
||||
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
---
|
||||
softmmu/vl.c | 9 +++++++++
|
||||
system/vl.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||
index 620a1f1367..d46b8fb4ab 100644
|
||||
--- a/softmmu/vl.c
|
||||
+++ b/softmmu/vl.c
|
||||
@@ -827,9 +827,17 @@ static void version(void)
|
||||
diff --git a/system/vl.c b/system/vl.c
|
||||
index 3b7057e6c6..d3e6158753 100644
|
||||
--- a/system/vl.c
|
||||
+++ b/system/vl.c
|
||||
@@ -872,9 +872,17 @@ static void version(void)
|
||||
QEMU_COPYRIGHT "\n");
|
||||
}
|
||||
|
||||
@ -41,8 +32,8 @@ index 620a1f1367..d46b8fb4ab 100644
|
||||
+ print_rh_warning();
|
||||
printf("usage: %s [options] [disk_image]\n\n"
|
||||
"'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
|
||||
error_get_progname());
|
||||
@@ -855,6 +863,7 @@ static void help(int exitcode)
|
||||
g_get_prgname());
|
||||
@@ -900,6 +908,7 @@ static void help(int exitcode)
|
||||
"\n"
|
||||
QEMU_HELP_BOTTOM "\n");
|
||||
|
||||
@ -50,6 +41,3 @@ index 620a1f1367..d46b8fb4ab 100644
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From c17ca305893c976061a94fd5058ef5a53493e41a Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 8 Jul 2020 08:35:50 +0200
|
||||
Subject: [PATCH] Use qemu-kvm in documentation instead of qemu-system-<arch>
|
||||
|
||||
We change the name and location of qemu-kvm binaries. Update documentation
|
||||
to reflect this change. Only architectures available in RHEL are updated.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
docs/defs.rst.inc | 4 ++--
|
||||
qemu-options.hx | 10 +++++-----
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/docs/defs.rst.inc b/docs/defs.rst.inc
|
||||
index 52d6454b93..d74dbdeca9 100644
|
||||
--- a/docs/defs.rst.inc
|
||||
+++ b/docs/defs.rst.inc
|
||||
@@ -9,7 +9,7 @@
|
||||
but the manpages will end up misrendered with following normal text
|
||||
incorrectly in boldface.
|
||||
|
||||
-.. |qemu_system| replace:: qemu-system-x86_64
|
||||
-.. |qemu_system_x86| replace:: qemu-system-x86_64
|
||||
+.. |qemu_system| replace:: qemu-kvm
|
||||
+.. |qemu_system_x86| replace:: qemu-kvm
|
||||
.. |I2C| replace:: I\ :sup:`2`\ C
|
||||
.. |I2S| replace:: I\ :sup:`2`\ S
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index ab23f14d21..3837456a61 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -3858,11 +3858,11 @@ SRST
|
||||
|
||||
::
|
||||
|
||||
- qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
|
||||
- -numa node,memdev=mem \
|
||||
- -chardev socket,id=chr0,path=/path/to/socket \
|
||||
- -netdev type=vhost-user,id=net0,chardev=chr0 \
|
||||
- -device virtio-net-pci,netdev=net0
|
||||
+ qemu-kvm -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
|
||||
+ -numa node,memdev=mem \
|
||||
+ -chardev socket,id=chr0,path=/path/to/socket \
|
||||
+ -netdev type=vhost-user,id=net0,chardev=chr0 \
|
||||
+ -device virtio-net-pci,netdev=net0
|
||||
|
||||
``-netdev vhost-vdpa[,vhostdev=/path/to/dev][,vhostfd=h]``
|
||||
Establish a vhost-vdpa netdev.
|
||||
@ -0,0 +1,55 @@
|
||||
From d4a2e3344ea9e909a3262ac569fc0e5fab49562b Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 20 Aug 2021 18:25:12 +0200
|
||||
Subject: [PATCH] qcow2: Deprecation warning when opening v2 images rw
|
||||
|
||||
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
|
||||
do so unintentionally. Warn about it and suggest upgrading during the
|
||||
RHEL 9 timeframe so that the code can possibly be disabled in RHEL 10.
|
||||
|
||||
The warning is restricted to read-write mode and the system emulator.
|
||||
The primary motivation for not having it in qemu-img is that 'qemu-img
|
||||
amend' for upgrades would warn otherwise. It also avoids having to make
|
||||
too many changes to the test suite.
|
||||
|
||||
bdrv_uses_whitelist() is used as a proxy for deciding whether we are
|
||||
running in a tool or the system emulator. This is not entirely clean,
|
||||
but it's what is available and the same function qcow2_do_open() already
|
||||
uses it this way for another warning.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/qcow2.c | 6 ++++++
|
||||
tests/qemu-iotests/common.filter | 1 +
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/block/qcow2.c b/block/qcow2.c
|
||||
index 4aa9f9e068..6df65aab93 100644
|
||||
--- a/block/qcow2.c
|
||||
+++ b/block/qcow2.c
|
||||
@@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
}
|
||||
+ if (header.version < 3 && !bdrv_is_read_only(bs) && bdrv_uses_whitelist()) {
|
||||
+ warn_report_once("qcow2 v2 images are deprecated and may not be "
|
||||
+ "supported in future versions. Please consider "
|
||||
+ "upgrading the image with 'qemu-img amend "
|
||||
+ "-o compat=v3'.");
|
||||
+ }
|
||||
|
||||
s->qcow_version = header.version;
|
||||
|
||||
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
|
||||
index 511a55b1e8..35c0fc0d20 100644
|
||||
--- a/tests/qemu-iotests/common.filter
|
||||
+++ b/tests/qemu-iotests/common.filter
|
||||
@@ -83,6 +83,7 @@ _filter_qemu()
|
||||
{
|
||||
gsed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
|
||||
-e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' \
|
||||
+ -e "/qcow2 v2 images are deprecated/d" \
|
||||
-e $'s#\r##' # QEMU monitor uses \r\n line endings
|
||||
}
|
||||
|
||||
43
0018-file-posix-Define-DM_MPATH_PROBE_PATHS.patch
Normal file
43
0018-file-posix-Define-DM_MPATH_PROBE_PATHS.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From fa1f21136ad5acb144c56dbfd0c4fb74d1a9b3e6 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Tue, 29 Apr 2025 17:05:41 +0200
|
||||
Subject: [PATCH] file-posix: Define DM_MPATH_PROBE_PATHS
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 370: file-posix: Fix multipath failover with SCSI passthrough
|
||||
RH-Jira: RHEL-65852
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [1/2] 6680f4a3f15a768b1ca51aafea452c3d0886f12e (kmwolf/centos-qemu-kvm)
|
||||
|
||||
While the kernel side isn't merged yet and we're still using old kernel
|
||||
headers, just define DM_MPATH_PROBE_PATHS manually.
|
||||
|
||||
This is a downstream-only patch that can be removed after the next minor
|
||||
release.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-file-posix-Define-DM_MPATH_PROBE_PATHS.patch
|
||||
Patch-id: 41
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
block/file-posix.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||
index 8c738674ce..cb2e94d7db 100644
|
||||
--- a/block/file-posix.c
|
||||
+++ b/block/file-posix.c
|
||||
@@ -156,6 +156,11 @@
|
||||
*/
|
||||
#define SG_IO_MAX_RETRIES 8
|
||||
|
||||
+/* TODO Remove this when the kernel side is merged */
|
||||
+#if !defined(DM_MPATH_PROBE_PATHS) && defined(DM_GET_TARGET_VERSION)
|
||||
+#define DM_MPATH_PROBE_PATHS _IO(DM_IOCTL, DM_GET_TARGET_VERSION_CMD + 1)
|
||||
+#endif
|
||||
+
|
||||
typedef struct BDRVRawState {
|
||||
int fd;
|
||||
bool use_lock;
|
||||
@ -0,0 +1,70 @@
|
||||
From dedb116d88615adedd6b651e5fb22083b86857b0 Mon Sep 17 00:00:00 2001
|
||||
From: Laurent Vivier <lvivier@redhat.com>
|
||||
Date: Thu, 7 Aug 2025 13:08:06 +0200
|
||||
Subject: [PATCH] e1000e: Prevent crash from legacy interrupt firing after
|
||||
MSI-X enable
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Laurent Vivier <lvivier@redhat.com>
|
||||
RH-MergeRequest: 403: e1000e: Prevent crash from legacy interrupt firing after MSI-X enable
|
||||
RH-Jira: RHEL-112882
|
||||
RH-Acked-by: Cindy Lu <lulu@redhat.com>
|
||||
RH-Acked-by: Jason Wang <jasowang@redhat.com>
|
||||
RH-Commit: [1/1] 8241a58b76307f27ad3d3b3b2106e00b153b7b53 (lvivier/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-112882
|
||||
|
||||
A race condition between guest driver actions and QEMU timers can lead
|
||||
to an assertion failure when the guest switches the e1000e from legacy
|
||||
interrupt mode to MSI-X. If a legacy interrupt delay timer (TIDV or
|
||||
RDTR) is active, but the guest enables MSI-X before the timer fires,
|
||||
the pending interrupt cause can trigger an assert in
|
||||
e1000e_intmgr_collect_delayed_causes().
|
||||
|
||||
This patch removes the assertion and executes the code that clears the
|
||||
pending legacy causes. This change is safe and introduces no unintended
|
||||
behavioral side effects, as it only alters a state that previously led
|
||||
to termination.
|
||||
|
||||
- when core->delayed_causes == 0 the function was already a no-op and
|
||||
remains so.
|
||||
|
||||
- when core->delayed_causes != 0 the function would previously
|
||||
crash due to the assertion failure. The patch now defines a safe
|
||||
outcome by clearing the cause and returning. Since behavior after
|
||||
the assertion never existed, this simply corrects the crash.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1863
|
||||
Suggested-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
||||
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
||||
Acked-by: Jason Wang <jasowang@redhat.com>
|
||||
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
||||
Message-ID: <20250807110806.409065-1-lvivier@redhat.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
(cherry picked from commit 8e4649cac9bcddc050d2df07908075e9e69bccc7)
|
||||
|
||||
Patch-name: kvm-e1000e-Prevent-crash-from-legacy-interrupt-firing-af.patch
|
||||
Patch-id: 22
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/net/e1000e_core.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
|
||||
index 2413858790..06657bb3ac 100644
|
||||
--- a/hw/net/e1000e_core.c
|
||||
+++ b/hw/net/e1000e_core.c
|
||||
@@ -341,11 +341,6 @@ e1000e_intmgr_collect_delayed_causes(E1000ECore *core)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
- if (msix_enabled(core->owner)) {
|
||||
- assert(core->delayed_causes == 0);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
res = core->delayed_causes;
|
||||
core->delayed_causes = 0;
|
||||
|
||||
155
0020-arm-kvm-report-registers-we-failed-to-set.patch
Normal file
155
0020-arm-kvm-report-registers-we-failed-to-set.patch
Normal file
@ -0,0 +1,155 @@
|
||||
From f98acf4248abc79bf08a72ff018a496de9389eef Mon Sep 17 00:00:00 2001
|
||||
From: Cornelia Huck <cohuck@redhat.com>
|
||||
Date: Thu, 11 Sep 2025 17:41:59 +0200
|
||||
Subject: [PATCH] arm/kvm: report registers we failed to set
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 410: arm/kvm: report registers we failed to set
|
||||
RH-Jira: RHEL-119368
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [1/1] 82b4496284ff0a4dd2dd0eae7bb1cf114dded61e (eauger1/centos-qemu-kvm)
|
||||
|
||||
If we fail migration because of a mismatch of some registers between
|
||||
source and destination, the error message is not very informative:
|
||||
|
||||
qemu-system-aarch64: error while loading state for instance 0x0 ofdevice 'cpu'
|
||||
qemu-system-aarch64: Failed to put registers after init: Invalid argument
|
||||
|
||||
At least try to give the user a hint which registers had a problem,
|
||||
even if they cannot really do anything about it right now.
|
||||
|
||||
Sample output:
|
||||
|
||||
Could not set register op0:3 op1:0 crn:0 crm:0 op2:0 to c00fac31 (is 413fd0c1)
|
||||
|
||||
We could be even more helpful once we support writable ID registers,
|
||||
at which point the user might actually be able to configure something
|
||||
that is migratable.
|
||||
|
||||
Suggested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Sebastian Ott <sebott@redhat.com>
|
||||
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
|
||||
Message-id: 20250911154159.158046-1-cohuck@redhat.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 19f6dcfe6b8b2a3523362812fc696ab83050d316)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-arm-kvm-report-registers-we-failed-to-set.patch
|
||||
Patch-id: 23
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/arm/kvm.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 86 insertions(+)
|
||||
|
||||
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
|
||||
index 6672344855..c1ec6654ca 100644
|
||||
--- a/target/arm/kvm.c
|
||||
+++ b/target/arm/kvm.c
|
||||
@@ -900,6 +900,58 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
|
||||
return ok;
|
||||
}
|
||||
|
||||
+/* pretty-print a KVM register */
|
||||
+#define CP_REG_ARM64_SYSREG_OP(_reg, _op) \
|
||||
+ ((uint8_t)((_reg & CP_REG_ARM64_SYSREG_ ## _op ## _MASK) >> \
|
||||
+ CP_REG_ARM64_SYSREG_ ## _op ## _SHIFT))
|
||||
+
|
||||
+static gchar *kvm_print_sve_register_name(uint64_t regidx)
|
||||
+{
|
||||
+ uint16_t sve_reg = regidx & 0x000000000000ffff;
|
||||
+
|
||||
+ if (regidx == KVM_REG_ARM64_SVE_VLS) {
|
||||
+ return g_strdup_printf("SVE VLS");
|
||||
+ }
|
||||
+ /* zreg, preg, ffr */
|
||||
+ switch (sve_reg & 0xfc00) {
|
||||
+ case 0:
|
||||
+ return g_strdup_printf("SVE zreg n:%d slice:%d",
|
||||
+ (sve_reg & 0x03e0) >> 5, sve_reg & 0x001f);
|
||||
+ case 0x04:
|
||||
+ return g_strdup_printf("SVE preg n:%d slice:%d",
|
||||
+ (sve_reg & 0x01e0) >> 5, sve_reg & 0x001f);
|
||||
+ case 0x06:
|
||||
+ return g_strdup_printf("SVE ffr slice:%d", sve_reg & 0x001f);
|
||||
+ default:
|
||||
+ return g_strdup_printf("SVE ???");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static gchar *kvm_print_register_name(uint64_t regidx)
|
||||
+{
|
||||
+ switch ((regidx & KVM_REG_ARM_COPROC_MASK)) {
|
||||
+ case KVM_REG_ARM_CORE:
|
||||
+ return g_strdup_printf("core reg %"PRIx64, regidx);
|
||||
+ case KVM_REG_ARM_DEMUX:
|
||||
+ return g_strdup_printf("demuxed reg %"PRIx64, regidx);
|
||||
+ case KVM_REG_ARM64_SYSREG:
|
||||
+ return g_strdup_printf("op0:%d op1:%d crn:%d crm:%d op2:%d",
|
||||
+ CP_REG_ARM64_SYSREG_OP(regidx, OP0),
|
||||
+ CP_REG_ARM64_SYSREG_OP(regidx, OP1),
|
||||
+ CP_REG_ARM64_SYSREG_OP(regidx, CRN),
|
||||
+ CP_REG_ARM64_SYSREG_OP(regidx, CRM),
|
||||
+ CP_REG_ARM64_SYSREG_OP(regidx, OP2));
|
||||
+ case KVM_REG_ARM_FW:
|
||||
+ return g_strdup_printf("fw reg %d", (int)(regidx & 0xffff));
|
||||
+ case KVM_REG_ARM64_SVE:
|
||||
+ return kvm_print_sve_register_name(regidx);
|
||||
+ case KVM_REG_ARM_FW_FEAT_BMAP:
|
||||
+ return g_strdup_printf("fw feat reg %d", (int)(regidx & 0xffff));
|
||||
+ default:
|
||||
+ return g_strdup_printf("%"PRIx64, regidx);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
@@ -927,11 +979,45 @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
|
||||
g_assert_not_reached();
|
||||
}
|
||||
if (ret) {
|
||||
+ gchar *reg_str = kvm_print_register_name(regidx);
|
||||
+
|
||||
/* We might fail for "unknown register" and also for
|
||||
* "you tried to set a register which is constant with
|
||||
* a different value from what it actually contains".
|
||||
*/
|
||||
ok = false;
|
||||
+ switch (ret) {
|
||||
+ case -ENOENT:
|
||||
+ error_report("Could not set register %s: unknown to KVM",
|
||||
+ reg_str);
|
||||
+ break;
|
||||
+ case -EINVAL:
|
||||
+ if ((regidx & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
|
||||
+ if (!kvm_get_one_reg(cs, regidx, &v32)) {
|
||||
+ error_report("Could not set register %s to %x (is %x)",
|
||||
+ reg_str, (uint32_t)cpu->cpreg_values[i],
|
||||
+ v32);
|
||||
+ } else {
|
||||
+ error_report("Could not set register %s to %x",
|
||||
+ reg_str, (uint32_t)cpu->cpreg_values[i]);
|
||||
+ }
|
||||
+ } else /* U64 */ {
|
||||
+ uint64_t v64;
|
||||
+
|
||||
+ if (!kvm_get_one_reg(cs, regidx, &v64)) {
|
||||
+ error_report("Could not set register %s to %"PRIx64" (is %"PRIx64")",
|
||||
+ reg_str, cpu->cpreg_values[i], v64);
|
||||
+ } else {
|
||||
+ error_report("Could not set register %s to %"PRIx64,
|
||||
+ reg_str, cpu->cpreg_values[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ error_report("Could not set register %s: %s",
|
||||
+ reg_str, strerror(-ret));
|
||||
+ }
|
||||
+ g_free(reg_str);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
@ -0,0 +1,74 @@
|
||||
From 103e764a9c557b38b03f23928bb9f20aeaec9b52 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Wed, 24 Sep 2025 11:51:53 -0400
|
||||
Subject: [PATCH] pcie_sriov: make pcie_sriov_pf_exit() safe on non-SR-IOV
|
||||
devices
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 408: pcie_sriov: make pcie_sriov_pf_exit() safe on non-SR-IOV devices
|
||||
RH-Jira: RHEL-116443
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] a4fea6ad073c9fa5fdc7f20b3dfeab4e4acef73f (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
Commit 3f9cfaa92c96 ("virtio-pci: Implement SR-IOV PF") added an
|
||||
unconditional call from virtio_pci_exit() to pcie_sriov_pf_exit().
|
||||
|
||||
pcie_sriov_pf_exit() reads from the SR-IOV Capability in Configuration
|
||||
Space:
|
||||
|
||||
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
|
||||
...
|
||||
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This results in undefined behavior when dev->exp.sriov_cap is 0 because
|
||||
this is not an SR-IOV device. For example, unparent_vfs() segfaults when
|
||||
total_vfs happens to be non-zero.
|
||||
|
||||
Fix this by returning early from pcie_sriov_pf_exit() when
|
||||
dev->exp.sriov_cap is 0 because this is not an SR-IOV device.
|
||||
|
||||
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
||||
Cc: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reported-by: Qing Wang <qinwang@redhat.com>
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-116443
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
||||
Fixes: cab1398a60eb ("pcie_sriov: Reuse SR-IOV VF device instances")
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Message-ID: <20250924155153.579495-1-stefanha@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry picked from commit bab681f752048c3bc22d561b1d314c7ec16419c9)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
|
||||
Patch-name: kvm-pcie_sriov-make-pcie_sriov_pf_exit-safe-on-non-SR-IO.patch
|
||||
Patch-id: 24
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/pci/pcie_sriov.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
|
||||
index 8a4bf0d6f7..cf1b5b5c05 100644
|
||||
--- a/hw/pci/pcie_sriov.c
|
||||
+++ b/hw/pci/pcie_sriov.c
|
||||
@@ -195,7 +195,9 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
|
||||
|
||||
void pcie_sriov_pf_exit(PCIDevice *dev)
|
||||
{
|
||||
- uint8_t *cfg = dev->config + dev->exp.sriov_cap;
|
||||
+ if (dev->exp.sriov_cap == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (dev->exp.sriov_pf.vf_user_created) {
|
||||
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
|
||||
@@ -211,6 +213,8 @@ void pcie_sriov_pf_exit(PCIDevice *dev)
|
||||
pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id);
|
||||
}
|
||||
} else {
|
||||
+ uint8_t *cfg = dev->config + dev->exp.sriov_cap;
|
||||
+
|
||||
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
|
||||
}
|
||||
}
|
||||
135
0022-target-i386-add-compatibility-property-for-arch_capa.patch
Normal file
135
0022-target-i386-add-compatibility-property-for-arch_capa.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From e1328dd999ee518164a5620b23b9d4fb698a0daa Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Thu, 9 Oct 2025 16:49:59 +0200
|
||||
Subject: [PATCH] target/i386: add compatibility property for arch_capabilities
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 411: fix x86-64 migration regression in QEMU 10.1
|
||||
RH-Jira: RHEL-120253
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/2] 6bfa7c38398623ac7c3392c0ad17312e6f641f4d (bonzini/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120253
|
||||
|
||||
Prior to v10.1, if requested by user, arch-capabilities is always on
|
||||
despite the fact that CPUID advertises it to be off/unvailable.
|
||||
This causes a migration issue for VMs that are run on a machine
|
||||
without arch-capabilities and expect this feature to be present
|
||||
on the destination host with QEMU 10.1.
|
||||
|
||||
Add a compatibility property to restore the legacy behavior for all
|
||||
machines with version prior to 10.1.
|
||||
|
||||
To preserve the functionality (added by 10.1) of turning off
|
||||
ARCH_CAPABILITIES where Windows does not like it, use directly
|
||||
the guest CPU vendor: x86_cpu_get_supported_feature_word is not
|
||||
KVM-specific and therefore should not necessarily use the host
|
||||
CPUID.
|
||||
|
||||
Co-authored-by: Hector Cao <hector.cao@canonical.com>
|
||||
Signed-off-by: Hector Cao <hector.cao@canonical.com>
|
||||
Fixes: d3a24134e37 ("target/i386: do not expose ARCH_CAPABILITIES on AMD CPU", 2025-07-17)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit e9efa4a77168ac2816bf9471f878252ce6224710)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-add-compatibility-property-for-arch_capa.patch
|
||||
Patch-id: 25
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc.c | 2 ++
|
||||
target/i386/cpu.c | 17 +++++++++++++++++
|
||||
target/i386/cpu.h | 6 ++++++
|
||||
target/i386/kvm/kvm.c | 6 +-----
|
||||
4 files changed, 26 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 439abe8f46..625a89d097 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -84,6 +84,7 @@
|
||||
GlobalProperty pc_compat_10_0[] = {
|
||||
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
+ { TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
};
|
||||
const size_t pc_compat_10_0_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
|
||||
@@ -299,6 +300,7 @@ GlobalProperty pc_rhel_10_2_compat[] = {
|
||||
/* pc_rhel_10_2_compat from pc_compat_10_0 */
|
||||
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
+ { TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
};
|
||||
const size_t pc_rhel_10_2_compat_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index 9c756a05f2..de288dc5ac 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -7559,6 +7559,20 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
|
||||
#endif
|
||||
break;
|
||||
|
||||
+ case FEAT_7_0_EDX:
|
||||
+ /*
|
||||
+ * Windows does not like ARCH_CAPABILITIES on AMD machines at all.
|
||||
+ * Do not show the fake ARCH_CAPABILITIES MSR that KVM sets up,
|
||||
+ * except if needed for migration.
|
||||
+ *
|
||||
+ * When arch_cap_always_on is removed, this tweak can move to
|
||||
+ * kvm_arch_get_supported_cpuid.
|
||||
+ */
|
||||
+ if (cpu && IS_AMD_CPU(&cpu->env) && !cpu->arch_cap_always_on) {
|
||||
+ unavail = CPUID_7_0_EDX_ARCH_CAPABILITIES;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -10024,6 +10038,9 @@ static const Property x86_cpu_properties[] = {
|
||||
true),
|
||||
DEFINE_PROP_BOOL("x-l1-cache-per-thread", X86CPU, l1_cache_per_core, true),
|
||||
DEFINE_PROP_BOOL("x-force-cpuid-0x1f", X86CPU, force_cpuid_0x1f, false),
|
||||
+
|
||||
+ DEFINE_PROP_BOOL("x-arch-cap-always-on", X86CPU,
|
||||
+ arch_cap_always_on, false),
|
||||
};
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index f977fc49a7..b966bc997c 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -2314,6 +2314,12 @@ struct ArchCPU {
|
||||
/* Forcefully disable KVM PV features not exposed in guest CPUIDs */
|
||||
bool kvm_pv_enforce_cpuid;
|
||||
|
||||
+ /*
|
||||
+ * Expose arch-capabilities unconditionally even on AMD models, for backwards
|
||||
+ * compatibility with QEMU <10.1.
|
||||
+ */
|
||||
+ bool arch_cap_always_on;
|
||||
+
|
||||
/* Number of physical address bits supported */
|
||||
uint32_t phys_bits;
|
||||
|
||||
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
|
||||
index 0eb39d22d6..baa2f80beb 100644
|
||||
--- a/target/i386/kvm/kvm.c
|
||||
+++ b/target/i386/kvm/kvm.c
|
||||
@@ -503,12 +503,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
|
||||
* Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
|
||||
* We can detect the bug by checking if MSR_IA32_ARCH_CAPABILITIES is
|
||||
* returned by KVM_GET_MSR_INDEX_LIST.
|
||||
- *
|
||||
- * But also, because Windows does not like ARCH_CAPABILITIES on AMD
|
||||
- * mcahines at all, do not show the fake ARCH_CAPABILITIES MSR that
|
||||
- * KVM sets up.
|
||||
*/
|
||||
- if (!has_msr_arch_capabs || !(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES)) {
|
||||
+ if (!has_msr_arch_capabs) {
|
||||
ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES;
|
||||
}
|
||||
} else if (function == 7 && index == 1 && reg == R_EAX) {
|
||||
116
0023-target-i386-add-compatibility-property-for-pdcm-feat.patch
Normal file
116
0023-target-i386-add-compatibility-property-for-pdcm-feat.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 0bf7082e44f311902726b90b0b38dd2602dcc118 Mon Sep 17 00:00:00 2001
|
||||
From: Hector Cao <hector.cao@canonical.com>
|
||||
Date: Tue, 23 Sep 2025 12:16:41 +0200
|
||||
Subject: [PATCH] target/i386: add compatibility property for pdcm feature
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 411: fix x86-64 migration regression in QEMU 10.1
|
||||
RH-Jira: RHEL-120253
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/2] 9d76b45215d7ae2bc5ea2e61fe01780059d6d44c (bonzini/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120253
|
||||
|
||||
The pdcm feature is supposed to be disabled when PMU is not
|
||||
available. Up until v10.1, pdcm feature is enabled even when PMU
|
||||
is off. This behavior has been fixed but this change breaks the
|
||||
migration of VMs that are run with QEMU < 10.0 and expect the pdcm
|
||||
feature to be enabled on the destination host.
|
||||
|
||||
This commit restores the legacy behavior for machines with version
|
||||
prior to 10.1 to allow the migration from older QEMU to QEMU 10.1.
|
||||
|
||||
Signed-off-by: Hector Cao <hector.cao@canonical.com>
|
||||
Link: https://lore.kernel.org/r/20250910115733.21149-3-hector.cao@canonical.com
|
||||
Fixes: e68ec298090 ("i386/cpu: Move adjustment of CPUID_EXT_PDCM before feature_dependencies[] check", 2025-06-20)
|
||||
[Move property from migration object to CPU. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 6529f31e0dccadb532c80b36e3efe7aef83f9cad)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-add-compatibility-property-for-pdcm-feat.patch
|
||||
Patch-id: 26
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc.c | 2 ++
|
||||
target/i386/cpu.c | 15 ++++++++++++---
|
||||
target/i386/cpu.h | 6 ++++++
|
||||
3 files changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 625a89d097..446d4a7c93 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -85,6 +85,7 @@ GlobalProperty pc_compat_10_0[] = {
|
||||
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
{ TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
+ { TYPE_X86_CPU, "x-pdcm-on-even-without-pmu", "true" },
|
||||
};
|
||||
const size_t pc_compat_10_0_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
|
||||
@@ -301,6 +302,7 @@ GlobalProperty pc_rhel_10_2_compat[] = {
|
||||
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
{ TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
+ { TYPE_X86_CPU, "x-pdcm-on-even-without-pmu", "true" },
|
||||
};
|
||||
const size_t pc_rhel_10_2_compat_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index de288dc5ac..dfcdfd3da6 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -7928,6 +7928,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
/* Fixup overflow: max value for bits 23-16 is 255. */
|
||||
*ebx |= MIN(num, 255) << 16;
|
||||
}
|
||||
+ if (cpu->pdcm_on_even_without_pmu) {
|
||||
+ if (!cpu->enable_pmu) {
|
||||
+ *ecx &= ~CPUID_EXT_PDCM;
|
||||
+ }
|
||||
+ }
|
||||
break;
|
||||
case 2: { /* cache info: needed for Pentium Pro compatibility */
|
||||
const CPUCaches *caches;
|
||||
@@ -8978,9 +8983,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
- /* PDCM is fixed1 bit for TDX */
|
||||
- if (!cpu->enable_pmu && !is_tdx_vm()) {
|
||||
- env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
|
||||
+ if (!cpu->pdcm_on_even_without_pmu) {
|
||||
+ /* PDCM is fixed1 bit for TDX */
|
||||
+ if (!cpu->enable_pmu && !is_tdx_vm()) {
|
||||
+ env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
|
||||
+ }
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
|
||||
@@ -10041,6 +10048,8 @@ static const Property x86_cpu_properties[] = {
|
||||
|
||||
DEFINE_PROP_BOOL("x-arch-cap-always-on", X86CPU,
|
||||
arch_cap_always_on, false),
|
||||
+ DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU,
|
||||
+ pdcm_on_even_without_pmu, false),
|
||||
};
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index b966bc997c..2187e61654 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -2320,6 +2320,12 @@ struct ArchCPU {
|
||||
*/
|
||||
bool arch_cap_always_on;
|
||||
|
||||
+ /*
|
||||
+ * Backwards compatibility with QEMU <10.1. The PDCM feature is now disabled when
|
||||
+ * PMU is not available, but prior to 10.1 it was enabled even if PMU is off.
|
||||
+ */
|
||||
+ bool pdcm_on_even_without_pmu;
|
||||
+
|
||||
/* Number of physical address bits supported */
|
||||
uint32_t phys_bits;
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
From f8640da2e54f79ca5966e8390c0bd3b5a40c2581 Mon Sep 17 00:00:00 2001
|
||||
From: Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
Date: Thu, 16 Oct 2025 14:17:07 +0200
|
||||
Subject: [PATCH] qapi/machine-s390x: add QAPI event SCLP_CPI_INFO_AVAILABLE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 412: Add -rhel9.8.0 and -rhel10.2.0 s390x machine types and enable the CPI feature
|
||||
RH-Jira: RHEL-104009 RHEL-105823 RHEL-73008
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/3] 24789cc7501d22168819bf459f7d880deba8b403 (thuth/qemu-kvm-cs)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-73008
|
||||
|
||||
Add QAPI event SCLP_CPI_INFO_AVAILABLE to notify the availability
|
||||
of Control-Program Identification data in QOM.
|
||||
|
||||
Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
Suggested-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-ID: <20251016121708.334133-1-shalini@linux.ibm.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
(cherry picked from commit 0ce63280dc6fe9fce1d89922f2d17dcae77827e6)
|
||||
|
||||
Patch-name: kvm-qapi-machine-s390x-add-QAPI-event-SCLP_CPI_INFO_AVAI.patch
|
||||
Patch-id: 27
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/s390x/sclpcpi.c | 4 ++++
|
||||
qapi/machine-s390x.json | 21 +++++++++++++++++++++
|
||||
2 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/hw/s390x/sclpcpi.c b/hw/s390x/sclpcpi.c
|
||||
index 7aa039d510..68fc1b809b 100644
|
||||
--- a/hw/s390x/sclpcpi.c
|
||||
+++ b/hw/s390x/sclpcpi.c
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "hw/s390x/event-facility.h"
|
||||
#include "hw/s390x/ebcdic.h"
|
||||
#include "qapi/qapi-visit-machine.h"
|
||||
+#include "qapi/qapi-events-machine-s390x.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
typedef struct Data {
|
||||
@@ -106,6 +107,9 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
|
||||
e->timestamp = qemu_clock_get_ns(QEMU_CLOCK_HOST);
|
||||
|
||||
cpim->ebh.flags = SCLP_EVENT_BUFFER_ACCEPTED;
|
||||
+
|
||||
+ qapi_event_send_sclp_cpi_info_available();
|
||||
+
|
||||
return SCLP_RC_NORMAL_COMPLETION;
|
||||
}
|
||||
|
||||
diff --git a/qapi/machine-s390x.json b/qapi/machine-s390x.json
|
||||
index 966dbd61d2..8412668b67 100644
|
||||
--- a/qapi/machine-s390x.json
|
||||
+++ b/qapi/machine-s390x.json
|
||||
@@ -119,3 +119,24 @@
|
||||
{ 'command': 'query-s390x-cpu-polarization', 'returns': 'CpuPolarizationInfo',
|
||||
'features': [ 'unstable' ]
|
||||
}
|
||||
+
|
||||
+##
|
||||
+# @SCLP_CPI_INFO_AVAILABLE:
|
||||
+#
|
||||
+# Emitted when the Control-Program Identification data is available
|
||||
+# in the QOM tree.
|
||||
+#
|
||||
+# Features:
|
||||
+#
|
||||
+# @unstable: This event is experimental.
|
||||
+#
|
||||
+# Since: 10.2
|
||||
+#
|
||||
+# .. qmp-example::
|
||||
+#
|
||||
+# <- { "event": "SCLP_CPI_INFO_AVAILABLE",
|
||||
+# "timestamp": { "seconds": 1401385907, "microseconds": 422329 } }
|
||||
+##
|
||||
+{ 'event': 'SCLP_CPI_INFO_AVAILABLE',
|
||||
+ 'features': [ 'unstable' ]
|
||||
+}
|
||||
77
0025-tests-functional-add-tests-for-SCLP-event-CPI.patch
Normal file
77
0025-tests-functional-add-tests-for-SCLP-event-CPI.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From fdb8dcb26a3840f4ddf03c37389d6ffc80c4b5ba Mon Sep 17 00:00:00 2001
|
||||
From: Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
Date: Thu, 16 Oct 2025 14:17:08 +0200
|
||||
Subject: [PATCH] tests/functional: add tests for SCLP event CPI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 412: Add -rhel9.8.0 and -rhel10.2.0 s390x machine types and enable the CPI feature
|
||||
RH-Jira: RHEL-104009 RHEL-105823 RHEL-73008
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/3] 7ff3e50bf038921d4514db88ef147ba92f960780 (thuth/qemu-kvm-cs)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-73008
|
||||
|
||||
Add tests for SCLP event type Control-Program Identification.
|
||||
|
||||
Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
Suggested-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
|
||||
Reviewed-by Thomas Huth <thuth@redhat.com>
|
||||
Message-ID: <20251016121708.334133-2-shalini@linux.ibm.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
(cherry picked from commit bc436b739c3c8683ef5e8c22391952dcaa95242e)
|
||||
|
||||
Patch-name: kvm-tests-functional-add-tests-for-SCLP-event-CPI.patch
|
||||
Patch-id: 28
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
tests/functional/test_s390x_ccw_virtio.py | 26 +++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/tests/functional/test_s390x_ccw_virtio.py b/tests/functional/test_s390x_ccw_virtio.py
|
||||
index 453711aa0f..0455337856 100755
|
||||
--- a/tests/functional/test_s390x_ccw_virtio.py
|
||||
+++ b/tests/functional/test_s390x_ccw_virtio.py
|
||||
@@ -15,6 +15,7 @@
|
||||
import tempfile
|
||||
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
+from qemu_test import exec_command
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
@@ -270,5 +271,30 @@ def test_s390x_fedora(self):
|
||||
'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do'
|
||||
' sleep 1 ; done', 'Start virtcrypto_remove.')
|
||||
|
||||
+ # Test SCLP event Control-Program Identification (CPI)
|
||||
+ cpi = '/sys/firmware/cpi/'
|
||||
+ sclpcpi = '/machine/sclp/s390-sclp-event-facility/sclpcpi'
|
||||
+ self.log.info("Test SCLP event CPI")
|
||||
+ exec_command(self, 'echo TESTVM > ' + cpi + 'system_name')
|
||||
+ exec_command(self, 'echo LINUX > ' + cpi + 'system_type')
|
||||
+ exec_command(self, 'echo TESTPLEX > ' + cpi + 'sysplex_name')
|
||||
+ exec_command(self, 'echo 0x001a000000060b00 > ' + cpi + 'system_level')
|
||||
+ exec_command_and_wait_for_pattern(self,
|
||||
+ 'echo 1 > ' + cpi + 'set', ':/#')
|
||||
+ try:
|
||||
+ event = self.vm.event_wait('SCLP_CPI_INFO_AVAILABLE')
|
||||
+ except TimeoutError:
|
||||
+ self.fail('Timed out waiting for the SCLP_CPI_INFO_AVAILABLE event')
|
||||
+ ts = self.vm.cmd('qom-get', path=sclpcpi, property='timestamp')
|
||||
+ self.assertNotEqual(ts, 0)
|
||||
+ name = self.vm.cmd('qom-get', path=sclpcpi, property='system_name')
|
||||
+ self.assertEqual(name.strip(), 'TESTVM')
|
||||
+ typ = self.vm.cmd('qom-get', path=sclpcpi, property='system_type')
|
||||
+ self.assertEqual(typ.strip(), 'LINUX')
|
||||
+ sysplex = self.vm.cmd('qom-get', path=sclpcpi, property='sysplex_name')
|
||||
+ self.assertEqual(sysplex.strip(), 'TESTPLEX')
|
||||
+ level = self.vm.cmd('qom-get', path=sclpcpi, property='system_level')
|
||||
+ self.assertEqual(level, 0x001a000000060b00)
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
||||
100
0026-redhat-Add-new-rhel9.8.0-and-rhel10.2.0-machine-type.patch
Normal file
100
0026-redhat-Add-new-rhel9.8.0-and-rhel10.2.0-machine-type.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From 79a55b8fb1b4dace565ceedee8f4b5dbcc5e1210 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Thu, 18 Sep 2025 17:41:25 +0200
|
||||
Subject: [PATCH] redhat: Add new -rhel9.8.0 and -rhel10.2.0 machine types on
|
||||
s390x
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 412: Add -rhel9.8.0 and -rhel10.2.0 s390x machine types and enable the CPI feature
|
||||
RH-Jira: RHEL-104009 RHEL-105823 RHEL-73008
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [3/3] e9ad89069cb4b9badb1b5f57d78a043c64411b65 (thuth/qemu-kvm-cs)
|
||||
|
||||
Upstream Status: RHEL only
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-105823
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-104009
|
||||
|
||||
Add new -rhel9.8.0 and -rhel10.2.0 machine types that enable the
|
||||
CPI feature and have the "relaxed-translation" for PCI passthrough
|
||||
devices enabled by default.
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Patch-name: kvm-redhat-Add-new-rhel9.8.0-and-rhel10.2.0-machine-type.patch
|
||||
Patch-id: 29
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 34 +++++++++++++++++++++++++++++++---
|
||||
1 file changed, 31 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 9be423858d..4937a0c3b8 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -1172,8 +1172,18 @@ DEFINE_CCW_MACHINE(4, 2);
|
||||
|
||||
#endif /* disabled for RHEL */
|
||||
|
||||
+static void ccw_rhel_machine_10_2_0_instance_options(MachineState *machine)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void ccw_rhel_machine_10_2_0_class_options(MachineClass *mc)
|
||||
+{
|
||||
+}
|
||||
+DEFINE_CCW_MACHINE_AS_LATEST(10, 2, 0);
|
||||
+
|
||||
static void ccw_rhel_machine_10_0_0_instance_options(MachineState *machine)
|
||||
{
|
||||
+ ccw_rhel_machine_10_2_0_instance_options(machine);
|
||||
}
|
||||
|
||||
static void ccw_rhel_machine_10_0_0_class_options(MachineClass *mc)
|
||||
@@ -1183,12 +1193,28 @@ static void ccw_rhel_machine_10_0_0_class_options(MachineClass *mc)
|
||||
{ TYPE_S390_PCI_DEVICE, "relaxed-translation", "off", },
|
||||
};
|
||||
|
||||
+ ccw_rhel_machine_10_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_10_2, hw_compat_rhel_10_2_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
|
||||
s390mc->use_cpi = false;
|
||||
}
|
||||
-DEFINE_CCW_MACHINE_AS_LATEST(10, 0, 0);
|
||||
+DEFINE_CCW_MACHINE(10, 0, 0);
|
||||
+
|
||||
+static void ccw_rhel_machine_9_8_0_instance_options(MachineState *machine)
|
||||
+{
|
||||
+ ccw_rhel_machine_10_2_0_instance_options(machine);
|
||||
+}
|
||||
+
|
||||
+static void ccw_rhel_machine_9_8_0_class_options(MachineClass *mc)
|
||||
+{
|
||||
+ ccw_rhel_machine_10_2_0_class_options(mc);
|
||||
+
|
||||
+ /* NB: remember to copy this line to the *latest* RHEL 9 machine */
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
+}
|
||||
+DEFINE_CCW_MACHINE(9, 8, 0);
|
||||
|
||||
static void ccw_rhel_machine_9_6_0_instance_options(MachineState *machine)
|
||||
{
|
||||
@@ -1197,9 +1223,11 @@ static void ccw_rhel_machine_9_6_0_instance_options(MachineState *machine)
|
||||
|
||||
static void ccw_rhel_machine_9_6_0_class_options(MachineClass *mc)
|
||||
{
|
||||
+ /*
|
||||
+ * NB: -rhel9.6 was on a par with -rhel10.0, so we derive from that
|
||||
+ * instead of deriving from the 9.8 machine type
|
||||
+ */
|
||||
ccw_rhel_machine_10_0_0_class_options(mc);
|
||||
-
|
||||
- /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
}
|
||||
DEFINE_CCW_MACHINE(9, 6, 0);
|
||||
254
0027-vfio-rename-field-to-num_initial_regions.patch
Normal file
254
0027-vfio-rename-field-to-num_initial_regions.patch
Normal file
@ -0,0 +1,254 @@
|
||||
From 60e7ac0c41c27dfefeb68b53ce76ebd7f1a1e1be Mon Sep 17 00:00:00 2001
|
||||
From: John Levon <john.levon@nutanix.com>
|
||||
Date: Tue, 14 Oct 2025 17:12:26 +0200
|
||||
Subject: [PATCH] vfio: rename field to "num_initial_regions"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Cédric Le Goater <clg@redhat.com>
|
||||
RH-MergeRequest: 414: Fixes for vfio region cache
|
||||
RH-Jira: RHEL-118810
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/2] 62524d77e79b6a57c4e61762cd61449280e4f2cd (clegoate/qemu-kvm-centos)
|
||||
|
||||
We set VFIODevice::num_regions at initialization time, and do not
|
||||
otherwise refresh it. As it is valid in theory for a VFIO device to
|
||||
later increase the number of supported regions, rename the field to
|
||||
"num_initial_regions" to better reflect its semantics.
|
||||
|
||||
Signed-off-by: John Levon <john.levon@nutanix.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Alex Williamson <alex@shazbot.org>
|
||||
Link: https://lore.kernel.org/qemu-devel/20251014151227.2298892-2-john.levon@nutanix.com
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit aaca725884b57c9245528a0afb3f32e078543faf)
|
||||
|
||||
Conflicts: Modified hw/core/sysbus-fdt.c and hw/vfio/platform.c
|
||||
|
||||
Patch-name: kvm-vfio-rename-field-to-num_initial_regions.patch
|
||||
Patch-id: 30
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/core/sysbus-fdt.c | 14 +++++++-------
|
||||
hw/vfio-user/device.c | 2 +-
|
||||
hw/vfio/ccw.c | 4 ++--
|
||||
hw/vfio/device.c | 12 ++++++------
|
||||
hw/vfio/iommufd.c | 3 ++-
|
||||
hw/vfio/pci.c | 4 ++--
|
||||
hw/vfio/platform.c | 10 +++++-----
|
||||
include/hw/vfio/vfio-device.h | 2 +-
|
||||
8 files changed, 26 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
|
||||
index c339a27875..1e1966813f 100644
|
||||
--- a/hw/core/sysbus-fdt.c
|
||||
+++ b/hw/core/sysbus-fdt.c
|
||||
@@ -236,15 +236,15 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
|
||||
qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0);
|
||||
|
||||
- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ reg_attr = g_new(uint32_t, vbasedev->num_initial_regions * 2);
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
|
||||
reg_attr[2 * i] = cpu_to_be32(mmio_base);
|
||||
reg_attr[2 * i + 1] = cpu_to_be32(
|
||||
memory_region_size(vdev->regions[i]->mem));
|
||||
}
|
||||
qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
|
||||
- vbasedev->num_regions * 2 * sizeof(uint32_t));
|
||||
+ vbasedev->num_initial_regions * 2 * sizeof(uint32_t));
|
||||
|
||||
irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
|
||||
for (i = 0; i < vbasedev->num_irqs; i++) {
|
||||
@@ -330,7 +330,7 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
|
||||
g_free(dt_name);
|
||||
|
||||
- if (vbasedev->num_regions != 5) {
|
||||
+ if (vbasedev->num_initial_regions != 5) {
|
||||
error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
|
||||
exit(1);
|
||||
}
|
||||
@@ -374,15 +374,15 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
guest_clock_phandles[0],
|
||||
guest_clock_phandles[1]);
|
||||
|
||||
- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ reg_attr = g_new(uint32_t, vbasedev->num_initial_regions * 2);
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
|
||||
reg_attr[2 * i] = cpu_to_be32(mmio_base);
|
||||
reg_attr[2 * i + 1] = cpu_to_be32(
|
||||
memory_region_size(vdev->regions[i]->mem));
|
||||
}
|
||||
qemu_fdt_setprop(guest_fdt, nodename, "reg", reg_attr,
|
||||
- vbasedev->num_regions * 2 * sizeof(uint32_t));
|
||||
+ vbasedev->num_initial_regions * 2 * sizeof(uint32_t));
|
||||
|
||||
irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
|
||||
for (i = 0; i < vbasedev->num_irqs; i++) {
|
||||
diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c
|
||||
index 0609a7dc25..64ef35b320 100644
|
||||
--- a/hw/vfio-user/device.c
|
||||
+++ b/hw/vfio-user/device.c
|
||||
@@ -134,7 +134,7 @@ static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev,
|
||||
VFIOUserFDs fds = { 0, 1, fd};
|
||||
int ret;
|
||||
|
||||
- if (info->index > vbasedev->num_regions) {
|
||||
+ if (info->index > vbasedev->num_initial_regions) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
|
||||
index 9560b8d851..4d9588e7aa 100644
|
||||
--- a/hw/vfio/ccw.c
|
||||
+++ b/hw/vfio/ccw.c
|
||||
@@ -484,9 +484,9 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
|
||||
* We always expect at least the I/O region to be present. We also
|
||||
* may have a variable number of regions governed by capabilities.
|
||||
*/
|
||||
- if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
|
||||
+ if (vdev->num_initial_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
|
||||
error_setg(errp, "vfio: too few regions (%u), expected at least %u",
|
||||
- vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
|
||||
+ vdev->num_initial_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
|
||||
index 52a1996dc4..0b459c0f7c 100644
|
||||
--- a/hw/vfio/device.c
|
||||
+++ b/hw/vfio/device.c
|
||||
@@ -257,7 +257,7 @@ int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type,
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
struct vfio_info_cap_header *hdr;
|
||||
struct vfio_region_info_cap_type *cap_type;
|
||||
|
||||
@@ -466,7 +466,7 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer,
|
||||
int i;
|
||||
|
||||
vbasedev->num_irqs = info->num_irqs;
|
||||
- vbasedev->num_regions = info->num_regions;
|
||||
+ vbasedev->num_initial_regions = info->num_regions;
|
||||
vbasedev->flags = info->flags;
|
||||
vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET);
|
||||
|
||||
@@ -476,10 +476,10 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer,
|
||||
QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next);
|
||||
|
||||
vbasedev->reginfo = g_new0(struct vfio_region_info *,
|
||||
- vbasedev->num_regions);
|
||||
+ vbasedev->num_initial_regions);
|
||||
if (vbasedev->use_region_fds) {
|
||||
- vbasedev->region_fds = g_new0(int, vbasedev->num_regions);
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ vbasedev->region_fds = g_new0(int, vbasedev->num_initial_regions);
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
vbasedev->region_fds[i] = -1;
|
||||
}
|
||||
}
|
||||
@@ -489,7 +489,7 @@ void vfio_device_unprepare(VFIODevice *vbasedev)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
g_free(vbasedev->reginfo[i]);
|
||||
if (vbasedev->region_fds != NULL && vbasedev->region_fds[i] != -1) {
|
||||
close(vbasedev->region_fds[i]);
|
||||
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
|
||||
index 48c590b6a9..dbcd861b27 100644
|
||||
--- a/hw/vfio/iommufd.c
|
||||
+++ b/hw/vfio/iommufd.c
|
||||
@@ -668,7 +668,8 @@ found_container:
|
||||
vfio_iommufd_cpr_register_device(vbasedev);
|
||||
|
||||
trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs,
|
||||
- vbasedev->num_regions, vbasedev->flags);
|
||||
+ vbasedev->num_initial_regions,
|
||||
+ vbasedev->flags);
|
||||
return true;
|
||||
|
||||
err_listener_register:
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index 48da233cb2..9486521a90 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -2933,9 +2933,9 @@ bool vfio_pci_populate_device(VFIOPCIDevice *vdev, Error **errp)
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (vbasedev->num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
|
||||
+ if (vbasedev->num_initial_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
|
||||
error_setg(errp, "unexpected number of io regions %u",
|
||||
- vbasedev->num_regions);
|
||||
+ vbasedev->num_initial_regions);
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
|
||||
index 5c1795a26f..c9349ba7b7 100644
|
||||
--- a/hw/vfio/platform.c
|
||||
+++ b/hw/vfio/platform.c
|
||||
@@ -148,7 +148,7 @@ static void vfio_mmap_set_enabled(VFIOPlatformDevice *vdev, bool enabled)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < vdev->vbasedev.num_regions; i++) {
|
||||
+ for (i = 0; i < vdev->vbasedev.num_initial_regions; i++) {
|
||||
vfio_region_mmaps_set_enabled(vdev->regions[i], enabled);
|
||||
}
|
||||
}
|
||||
@@ -453,9 +453,9 @@ static bool vfio_populate_device(VFIODevice *vbasedev, Error **errp)
|
||||
return false;
|
||||
}
|
||||
|
||||
- vdev->regions = g_new0(VFIORegion *, vbasedev->num_regions);
|
||||
+ vdev->regions = g_new0(VFIORegion *, vbasedev->num_initial_regions);
|
||||
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
char *name = g_strdup_printf("VFIO %s region %d\n", vbasedev->name, i);
|
||||
|
||||
vdev->regions[i] = g_new0(VFIORegion, 1);
|
||||
@@ -499,7 +499,7 @@ irq_err:
|
||||
g_free(intp);
|
||||
}
|
||||
reg_error:
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
if (vdev->regions[i]) {
|
||||
vfio_region_finalize(vdev->regions[i]);
|
||||
}
|
||||
@@ -608,7 +608,7 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
- for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
+ for (i = 0; i < vbasedev->num_initial_regions; i++) {
|
||||
if (vfio_region_mmap(vdev->regions[i])) {
|
||||
warn_report("%s mmap unsupported, performance may be slow",
|
||||
memory_region_name(vdev->regions[i]->mem));
|
||||
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
|
||||
index 9290774299..df81d319b2 100644
|
||||
--- a/include/hw/vfio/vfio-device.h
|
||||
+++ b/include/hw/vfio/vfio-device.h
|
||||
@@ -74,7 +74,7 @@ typedef struct VFIODevice {
|
||||
VFIODeviceOps *ops;
|
||||
VFIODeviceIOOps *io_ops;
|
||||
unsigned int num_irqs;
|
||||
- unsigned int num_regions;
|
||||
+ unsigned int num_initial_regions;
|
||||
unsigned int flags;
|
||||
VFIOMigration *migration;
|
||||
Error *migration_blocker;
|
||||
@ -0,0 +1,84 @@
|
||||
From 2541098f271ffc71046a2bd398043691cf82b2f2 Mon Sep 17 00:00:00 2001
|
||||
From: John Levon <john.levon@nutanix.com>
|
||||
Date: Tue, 14 Oct 2025 17:12:27 +0200
|
||||
Subject: [PATCH] vfio: only check region info cache for initial regions
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Cédric Le Goater <clg@redhat.com>
|
||||
RH-MergeRequest: 414: Fixes for vfio region cache
|
||||
RH-Jira: RHEL-118810
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/2] 30b628642ee153e7da612e43aead3c6cd2de9769 (clegoate/qemu-kvm-centos)
|
||||
|
||||
It is semantically valid for a VFIO device to increase the number of
|
||||
regions after initialization. In this case, we'd attempt to check for
|
||||
cached region info past the size of the ->reginfo array. Check for the
|
||||
region index and skip the cache in these cases.
|
||||
|
||||
This also works around some VGPU use cases which appear to be a bug,
|
||||
where VFIO_DEVICE_QUERY_GFX_PLANE returns a region index beyond the
|
||||
reported ->num_regions.
|
||||
|
||||
Fixes: 95cdb024 ("vfio: add region info cache")
|
||||
Signed-off-by: John Levon <john.levon@nutanix.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Alex Williamson <alex@shazbot.org>
|
||||
Link: https://lore.kernel.org/qemu-devel/20251014151227.2298892-3-john.levon@nutanix.com
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit ecbe424a63c9f860a901d6a4a75724b046abd796)
|
||||
|
||||
Patch-name: kvm-vfio-only-check-region-info-cache-for-initial-region.patch
|
||||
Patch-id: 31
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/vfio/device.c | 27 +++++++++++++++++++--------
|
||||
1 file changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
|
||||
index 0b459c0f7c..7ebf41c95e 100644
|
||||
--- a/hw/vfio/device.c
|
||||
+++ b/hw/vfio/device.c
|
||||
@@ -205,10 +205,19 @@ int vfio_device_get_region_info(VFIODevice *vbasedev, int index,
|
||||
int fd = -1;
|
||||
int ret;
|
||||
|
||||
- /* check cache */
|
||||
- if (vbasedev->reginfo[index] != NULL) {
|
||||
- *info = vbasedev->reginfo[index];
|
||||
- return 0;
|
||||
+ /*
|
||||
+ * We only set up the region info cache for the initial number of regions.
|
||||
+ *
|
||||
+ * Since a VFIO device may later increase the number of regions then use
|
||||
+ * such regions with an index past ->num_initial_regions, don't attempt to
|
||||
+ * use the info cache in those cases.
|
||||
+ */
|
||||
+ if (index < vbasedev->num_initial_regions) {
|
||||
+ /* check cache */
|
||||
+ if (vbasedev->reginfo[index] != NULL) {
|
||||
+ *info = vbasedev->reginfo[index];
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
*info = g_malloc0(argsz);
|
||||
@@ -236,10 +245,12 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
- /* fill cache */
|
||||
- vbasedev->reginfo[index] = *info;
|
||||
- if (vbasedev->region_fds != NULL) {
|
||||
- vbasedev->region_fds[index] = fd;
|
||||
+ if (index < vbasedev->num_initial_regions) {
|
||||
+ /* fill cache */
|
||||
+ vbasedev->reginfo[index] = *info;
|
||||
+ if (vbasedev->region_fds != NULL) {
|
||||
+ vbasedev->region_fds[index] = fd;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -0,0 +1,51 @@
|
||||
From a75749cb933cbb6d1b6cce5dd8b283242069215e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Wed, 29 Oct 2025 15:53:41 +0100
|
||||
Subject: [PATCH] arm: create new rhel 10.2 specific virt machine type
|
||||
|
||||
RH-Author: Sebastian Ott <sebott@redhat.com>
|
||||
RH-MergeRequest: 416: x86, arm: create new rhel 9.8, 10.2 specific machine types
|
||||
RH-Jira: RHEL-105826 RHEL-105828
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [1/4] 829eed93aefddcc4684ddacff3cd6ff3f991f442 (seott1/cos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
|
||||
Patch-name: kvm-arm-create-new-rhel-10.2-specific-virt-machine-type.patch
|
||||
Patch-id: 32
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
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 d37d1bb3cf..e68979d2c5 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3688,16 +3688,23 @@ static void virt_machine_4_1_options(MachineClass *mc)
|
||||
DEFINE_VIRT_MACHINE(4, 1)
|
||||
#endif /* disabled for RHEL */
|
||||
|
||||
+static void virt_rhel_machine_10_2_0_options(MachineClass *mc)
|
||||
+{
|
||||
+}
|
||||
+DEFINE_VIRT_MACHINE_AS_LATEST(10, 2, 0)
|
||||
+
|
||||
static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
|
||||
{
|
||||
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
||||
|
||||
+ virt_rhel_machine_10_2_0_options(mc);
|
||||
+
|
||||
/* QEMU 9.1 and earlier have only a stage-1 SMMU, not a nested s1+2 one */
|
||||
vmc->no_nested_smmu = true;
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_10_2, hw_compat_rhel_10_2_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
|
||||
}
|
||||
-DEFINE_VIRT_MACHINE_AS_LATEST(10, 0, 0)
|
||||
+DEFINE_VIRT_MACHINE(10, 0, 0)
|
||||
|
||||
static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
|
||||
{
|
||||
@ -0,0 +1,50 @@
|
||||
From 5ac559365c62f3b6f38b3ebfaab4b9dbf1a0888f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Wed, 29 Oct 2025 16:05:12 +0100
|
||||
Subject: [PATCH] arm: create new rhel 9.8 specific virt machine type
|
||||
|
||||
RH-Author: Sebastian Ott <sebott@redhat.com>
|
||||
RH-MergeRequest: 416: x86, arm: create new rhel 9.8, 10.2 specific machine types
|
||||
RH-Jira: RHEL-105826 RHEL-105828
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [2/4] fb3fc4decafd0c6e94ef31c0120b843512089573 (seott1/cos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
|
||||
Patch-name: kvm-arm-create-new-rhel-9.8-specific-virt-machine-type.patch
|
||||
Patch-id: 33
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt.c | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index e68979d2c5..dcdd53043e 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3706,14 +3706,19 @@ static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(10, 0, 0)
|
||||
|
||||
-static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
|
||||
+static void virt_rhel_machine_9_8_0_options(MachineClass *mc)
|
||||
{
|
||||
- virt_rhel_machine_10_0_0_options(mc);
|
||||
-
|
||||
+ /* NB: remember to move these lines to the *latest* RHEL 9 machine */
|
||||
compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len);
|
||||
- /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
}
|
||||
+DEFINE_VIRT_MACHINE(9, 8, 0)
|
||||
+
|
||||
+static void virt_rhel_machine_9_6_0_options(MachineClass *mc)
|
||||
+{
|
||||
+ virt_rhel_machine_10_0_0_options(mc);
|
||||
+ virt_rhel_machine_9_8_0_options(mc);
|
||||
+}
|
||||
DEFINE_VIRT_MACHINE(9, 6, 0)
|
||||
|
||||
static void virt_rhel_machine_9_4_0_options(MachineClass *mc)
|
||||
@ -0,0 +1,57 @@
|
||||
From 298dd9449200357a9563287ac036cb53283c27ae Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Wed, 29 Oct 2025 17:59:07 +0100
|
||||
Subject: [PATCH] x86: create new rhel 10.2 specific pc-q35 machine type
|
||||
|
||||
RH-Author: Sebastian Ott <sebott@redhat.com>
|
||||
RH-MergeRequest: 416: x86, arm: create new rhel 9.8, 10.2 specific machine types
|
||||
RH-Jira: RHEL-105826 RHEL-105828
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [3/4] 7f5a5fa45696e579cd08fb3869884ce9543badd5 (seott1/cos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
|
||||
Patch-name: kvm-x86-create-new-rhel-10.2-specific-pc-q35-machine-typ.patch
|
||||
Patch-id: 34
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc_q35.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index e5d10c0335..aea4735dd3 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -690,10 +690,20 @@ DEFINE_Q35_MACHINE(2, 6);
|
||||
|
||||
/* Red Hat Enterprise Linux machine types */
|
||||
|
||||
-static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
+static void pc_q35_rhel_machine_10_2_0_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_machine_options(m);
|
||||
+ m->desc = "RHEL-10.2.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "10.2.0";
|
||||
+}
|
||||
+DEFINE_Q35_MACHINE_AS_LATEST(10, 2, 0);
|
||||
+
|
||||
+static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_rhel_machine_10_2_0_options(m);
|
||||
m->desc = "RHEL-10.0.0 PC (Q35 + ICH9, 2009)";
|
||||
pcmc->smbios_stream_product = "RHEL";
|
||||
pcmc->smbios_stream_version = "10.0.0";
|
||||
@@ -707,7 +717,7 @@ static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
compat_props_add(m->compat_props, pc_rhel_10_1_compat,
|
||||
pc_rhel_10_1_compat_len);
|
||||
}
|
||||
-DEFINE_Q35_MACHINE_AS_LATEST(10, 0, 0);
|
||||
+DEFINE_Q35_MACHINE(10, 0, 0);
|
||||
|
||||
static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m)
|
||||
{
|
||||
@ -0,0 +1,57 @@
|
||||
From 77cd3055b005a8a0e83d8684c630beea6fd0e805 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Wed, 29 Oct 2025 18:05:21 +0100
|
||||
Subject: [PATCH] x86: create new rhel 9.8 specific pc-q35 machine type
|
||||
|
||||
RH-Author: Sebastian Ott <sebott@redhat.com>
|
||||
RH-MergeRequest: 416: x86, arm: create new rhel 9.8, 10.2 specific machine types
|
||||
RH-Jira: RHEL-105826 RHEL-105828
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [4/4] 2bfa55e063b4551e8e3299cf4f7aa2520943076a (seott1/cos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
|
||||
Patch-name: kvm-x86-create-new-rhel-9.8-specific-pc-q35-machine-type.patch
|
||||
Patch-id: 35
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc_q35.c | 17 ++++++++++++++---
|
||||
1 file changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index aea4735dd3..efbb5695c2 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -719,16 +719,27 @@ static void pc_q35_rhel_machine_10_0_0_options(MachineClass *m)
|
||||
}
|
||||
DEFINE_Q35_MACHINE(10, 0, 0);
|
||||
|
||||
+static void pc_q35_rhel_machine_9_8_0_options(MachineClass *m)
|
||||
+{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+ pc_q35_machine_options(m);
|
||||
+ m->desc = "RHEL-9.8.0 PC (Q35 + ICH9, 2009)";
|
||||
+ pcmc->smbios_stream_product = "RHEL";
|
||||
+ pcmc->smbios_stream_version = "9.8.0";
|
||||
+
|
||||
+ /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
+}
|
||||
+DEFINE_Q35_MACHINE(9, 8, 0);
|
||||
+
|
||||
static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_rhel_machine_10_0_0_options(m);
|
||||
+ pc_q35_rhel_machine_9_8_0_options(m);
|
||||
m->desc = "RHEL-9.6.0 PC (Q35 + ICH9, 2009)";
|
||||
pcmc->smbios_stream_product = "RHEL";
|
||||
pcmc->smbios_stream_version = "9.6.0";
|
||||
-
|
||||
- /* NB: remember to move this line to the *latest* RHEL 9 machine */
|
||||
- compat_props_add(m->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len);
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(9, 6, 0);
|
||||
63
0033-rh-enable-CONFIG_USB_STORAGE_BOT.patch
Normal file
63
0033-rh-enable-CONFIG_USB_STORAGE_BOT.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 627b1afca71a6e0a7db77c310fe0d1db53818dd2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||
Date: Mon, 3 Nov 2025 14:35:38 +0400
|
||||
Subject: [PATCH] rh: enable CONFIG_USB_STORAGE_BOT
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-MergeRequest: 417: rh: enable CONFIG_USB_STORAGE_BOT
|
||||
RH-Jira: RHEL-101929
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] 612acd1d19c799c7441f63548648eb70b9e1dfd6 (marcandre.lureau-rh/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-101929
|
||||
|
||||
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
|
||||
Patch-name: kvm-rh-enable-CONFIG_USB_STORAGE_BOT.patch
|
||||
Patch-id: 36
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
|
||||
configs/devices/riscv64-softmmu/riscv64-rh-devices.mak | 1 +
|
||||
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
|
||||
3 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
index 855278f70e..92d0b322d0 100644
|
||||
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
@@ -19,6 +19,7 @@ CONFIG_SEMIHOSTING=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI=y
|
||||
CONFIG_USB_XHCI_PCI=y
|
||||
+CONFIG_USB_STORAGE_BOT=y
|
||||
CONFIG_USB_STORAGE_CORE=y
|
||||
CONFIG_USB_STORAGE_CLASSIC=y
|
||||
CONFIG_USB_HUB=y
|
||||
diff --git a/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
|
||||
index b5e55de916..5ac051f90b 100644
|
||||
--- a/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
|
||||
+++ b/configs/devices/riscv64-softmmu/riscv64-rh-devices.mak
|
||||
@@ -15,6 +15,7 @@ CONFIG_SEMIHOSTING=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI=y
|
||||
CONFIG_USB_XHCI_PCI=y
|
||||
+CONFIG_USB_STORAGE_BOT=y
|
||||
CONFIG_USB_STORAGE_CORE=y
|
||||
CONFIG_USB_STORAGE_CLASSIC=y
|
||||
CONFIG_USB_HUB=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
|
||||
index 828cb8aa6f..1f244f766d 100644
|
||||
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
@@ -79,6 +79,7 @@ CONFIG_USB=y
|
||||
CONFIG_USB_EHCI=y
|
||||
CONFIG_USB_EHCI_PCI=y
|
||||
CONFIG_USB_SMARTCARD=y
|
||||
+CONFIG_USB_STORAGE_BOT=y
|
||||
CONFIG_USB_STORAGE_CORE=y
|
||||
CONFIG_USB_STORAGE_CLASSIC=y
|
||||
CONFIG_USB_UHCI=y
|
||||
@ -1,19 +1,19 @@
|
||||
From c8540f2b17b85d539b50915f50aff4a4c817921f Mon Sep 17 00:00:00 2001
|
||||
From 74a15bd54e8c1fb1821d3b69d88f17fc1032e533 Mon Sep 17 00:00:00 2001
|
||||
From: Jon Maloy <jmaloy@redhat.com>
|
||||
Date: Tue, 4 Nov 2025 17:23:29 -0500
|
||||
Subject: [PATCH 1/2] io: move websock resource release to close method
|
||||
Subject: [PATCH] io: move websock resource release to close method
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-MergeRequest: 499: io: fix use after free in websocket handshake code
|
||||
RH-Jira: RHEL-120119
|
||||
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Commit: [1/2] 20cbfece57dcbef55caebf33812065465de567df (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
|
||||
RH-MergeRequest: 419: io: move websock resource release to close method
|
||||
RH-Jira: RHEL-120116
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/2] ca3067b2afed8d770626436b77fdd90bd5cb22e7 (jmaloy/jmaloy-qemu-kvm-2)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120119
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120116
|
||||
CVE: CVE-2025-11234
|
||||
|
||||
commit 322c3c4f3abee616a18b3bfe563ec29dd67eae63
|
||||
@ -40,15 +40,19 @@ Date: Tue Sep 30 11:58:35 2025 +0100
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
||||
|
||||
Patch-name: kvm-io-move-websock-resource-release-to-close-method.patch
|
||||
Patch-id: 37
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
io/channel-websock.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/io/channel-websock.c b/io/channel-websock.c
|
||||
index 13c94f2afe..ade319cb71 100644
|
||||
index 08ddb274f0..a19b902ff9 100644
|
||||
--- a/io/channel-websock.c
|
||||
+++ b/io/channel-websock.c
|
||||
@@ -921,13 +921,13 @@ static void qio_channel_websock_finalize(Object *obj)
|
||||
@@ -922,13 +922,13 @@ static void qio_channel_websock_finalize(Object *obj)
|
||||
buffer_free(&ioc->encinput);
|
||||
buffer_free(&ioc->encoutput);
|
||||
buffer_free(&ioc->rawinput);
|
||||
@ -63,7 +67,7 @@ index 13c94f2afe..ade319cb71 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -1218,6 +1218,15 @@ static int qio_channel_websock_close(QIOChannel *ioc,
|
||||
@@ -1219,6 +1219,15 @@ static int qio_channel_websock_close(QIOChannel *ioc,
|
||||
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
|
||||
|
||||
trace_qio_channel_websock_close(ioc);
|
||||
@ -79,6 +83,3 @@ index 13c94f2afe..ade319cb71 100644
|
||||
return qio_channel_close(wioc->master, errp);
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
From b57e930ad6e2e2aea35c046a2a5ea6b04c472c5b Mon Sep 17 00:00:00 2001
|
||||
From 87b6a747f5d8bd592976dfe3182a3b5798784f7d Mon Sep 17 00:00:00 2001
|
||||
From: Jon Maloy <jmaloy@redhat.com>
|
||||
Date: Tue, 4 Nov 2025 17:28:47 -0500
|
||||
Subject: [PATCH 2/2] io: fix use after free in websocket handshake code
|
||||
Subject: [PATCH] io: fix use after free in websocket handshake code
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-MergeRequest: 499: io: fix use after free in websocket handshake code
|
||||
RH-Jira: RHEL-120119
|
||||
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Commit: [2/2] d9a0db83d83e8275decdba615338a9dee3a8d33c (redhat/rhel/src/qemu-kvm/jons-qemu-kvm-2)
|
||||
RH-MergeRequest: 419: io: move websock resource release to close method
|
||||
RH-Jira: RHEL-120116
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/2] acdb5414387815a8b2f0a84a151990875947e855 (jmaloy/jmaloy-qemu-kvm-2)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120119
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120116
|
||||
CVE: CVE-2025-11234
|
||||
|
||||
commit b7a1f2ca45c7865b9e98e02ae605a65fc9458ae9
|
||||
@ -90,6 +90,10 @@ Date: Tue Sep 30 12:03:15 2025 +0100
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
||||
|
||||
Patch-name: kvm-io-fix-use-after-free-in-websocket-handshake-code.patch
|
||||
Patch-id: 38
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/io/channel-websock.h | 3 ++-
|
||||
io/channel-websock.c | 22 ++++++++++++++++------
|
||||
@ -110,7 +114,7 @@ index e180827c57..6700cf8946 100644
|
||||
gboolean io_eof;
|
||||
uint8_t opcode;
|
||||
diff --git a/io/channel-websock.c b/io/channel-websock.c
|
||||
index ade319cb71..1b80d77f7d 100644
|
||||
index a19b902ff9..ec5e09f9ab 100644
|
||||
--- a/io/channel-websock.c
|
||||
+++ b/io/channel-websock.c
|
||||
@@ -545,6 +545,7 @@ static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
|
||||
@ -146,7 +150,7 @@ index ade319cb71..1b80d77f7d 100644
|
||||
wioc->master,
|
||||
G_IO_OUT,
|
||||
qio_channel_websock_handshake_send,
|
||||
@@ -906,11 +909,12 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
|
||||
@@ -907,11 +910,12 @@ void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
|
||||
|
||||
trace_qio_channel_websock_handshake_start(ioc);
|
||||
trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
|
||||
@ -164,7 +168,7 @@ index ade319cb71..1b80d77f7d 100644
|
||||
}
|
||||
|
||||
|
||||
@@ -921,6 +925,9 @@ static void qio_channel_websock_finalize(Object *obj)
|
||||
@@ -922,6 +926,9 @@ static void qio_channel_websock_finalize(Object *obj)
|
||||
buffer_free(&ioc->encinput);
|
||||
buffer_free(&ioc->encoutput);
|
||||
buffer_free(&ioc->rawinput);
|
||||
@ -174,7 +178,7 @@ index ade319cb71..1b80d77f7d 100644
|
||||
if (ioc->io_tag) {
|
||||
g_source_remove(ioc->io_tag);
|
||||
}
|
||||
@@ -1221,6 +1228,9 @@ static int qio_channel_websock_close(QIOChannel *ioc,
|
||||
@@ -1222,6 +1229,9 @@ static int qio_channel_websock_close(QIOChannel *ioc,
|
||||
buffer_free(&wioc->encinput);
|
||||
buffer_free(&wioc->encoutput);
|
||||
buffer_free(&wioc->rawinput);
|
||||
@ -184,6 +188,3 @@ index ade319cb71..1b80d77f7d 100644
|
||||
if (wioc->io_tag) {
|
||||
g_clear_handle_id(&wioc->io_tag, g_source_remove);
|
||||
}
|
||||
--
|
||||
2.50.1
|
||||
|
||||
48
0036-vfio-Disable-VFIO-migration-with-MultiFD-support.patch
Normal file
48
0036-vfio-Disable-VFIO-migration-with-MultiFD-support.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 5aa680dc7371173d2ac1c1fb7cdd393819f44dca Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Thu, 6 Nov 2025 16:39:53 +0100
|
||||
Subject: [PATCH] vfio: Disable VFIO migration with MultiFD support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Cédric Le Goater <clg@redhat.com>
|
||||
RH-MergeRequest: 421: vfio: Disable VFIO migration with MultiFD support
|
||||
RH-Jira: RHEL-126573
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Commit: [1/1] b3ec6731c96e5650c66ece6e3b8728a7b94353f2 (clegoate/qemu-kvm-centos)
|
||||
|
||||
QEMU 10.0 extends VFIO migration with MultiFD support, which can be
|
||||
controlled through the 'vfio-pci' device property
|
||||
'x-migration-multifd-transfer'. By default, this property is set to
|
||||
'auto', meaning its activation depends on the availability of other
|
||||
related features. However, it should be set to 'off' in RHEL until
|
||||
more testing has been completed.
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
|
||||
Patch-name: kvm-vfio-Disable-VFIO-migration-with-MultiFD-support.patch
|
||||
Patch-id: 39
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/vfio/pci.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index 9486521a90..83ecffb535 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -3686,10 +3686,11 @@ static const Property vfio_pci_dev_properties[] = {
|
||||
igd_legacy_mode, ON_OFF_AUTO_AUTO),
|
||||
DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
|
||||
vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
|
||||
+ /* RHEL only. Disable VFIO migration with MultiFD support */
|
||||
DEFINE_PROP("x-migration-multifd-transfer", VFIOPCIDevice,
|
||||
vbasedev.migration_multifd_transfer,
|
||||
vfio_pci_migration_multifd_transfer_prop, OnOffAuto,
|
||||
- .set_default = true, .defval.i = ON_OFF_AUTO_AUTO),
|
||||
+ .set_default = true, .defval.i = ON_OFF_AUTO_OFF),
|
||||
DEFINE_PROP_ON_OFF_AUTO("x-migration-load-config-after-iter", VFIOPCIDevice,
|
||||
vbasedev.migration_load_config_after_iter,
|
||||
ON_OFF_AUTO_AUTO),
|
||||
@ -0,0 +1,67 @@
|
||||
From 58cba97a715fa3f506234e718191fcc34286f333 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Fri, 7 Nov 2025 05:23:16 -0500
|
||||
Subject: [PATCH] hw/arm/virt: Use ACPI PCI hotplug by default from 10.2
|
||||
onwards
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 422: hw/arm/virt: Use ACPI PCI hotplug by default from 10.2 onwards
|
||||
RH-Jira: RHEL-67323
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Commit: [1/1] 4539ba6526fef80adb9893a643eb001449397447 (eauger1/centos-qemu-kvm)
|
||||
|
||||
UPSTREAM: RHEL-only
|
||||
|
||||
Use ACPI PCI hotplug by default from 10.2 onwards. For older
|
||||
rhel10 machine types and all rhel9 machine types ACPI PCI hotplug
|
||||
is kept disabled.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-Use-ACPI-PCI-hotplug-by-default-from-10..patch
|
||||
Patch-id: 40
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index dcdd53043e..542d702513 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -94,9 +94,15 @@
|
||||
|
||||
static GlobalProperty arm_virt_compat[] = {
|
||||
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
|
||||
+ { TYPE_ACPI_GED, "acpi-pci-hotplug-with-bridge-support", "on" },
|
||||
};
|
||||
static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
|
||||
+GlobalProperty arm_acpi_pci_hp_disabled_compat[] = {
|
||||
+ { TYPE_ACPI_GED, "acpi-pci-hotplug-with-bridge-support", "off" },
|
||||
+};
|
||||
+static const size_t arm_acpi_pci_hp_disabled_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
+
|
||||
/*
|
||||
* RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
|
||||
* since qemu will setup the VM with pauth when KVM supports it we
|
||||
@@ -104,6 +110,7 @@ static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
*/
|
||||
GlobalProperty arm_rhel9_compat[] = {
|
||||
{TYPE_ARM_CPU, "pauth", "off", .optional = true},
|
||||
+ {TYPE_ACPI_GED, "acpi-pci-hotplug-with-bridge-support", "off" },
|
||||
};
|
||||
const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_compat);
|
||||
|
||||
@@ -3701,6 +3708,8 @@ static void virt_rhel_machine_10_0_0_options(MachineClass *mc)
|
||||
|
||||
/* QEMU 9.1 and earlier have only a stage-1 SMMU, not a nested s1+2 one */
|
||||
vmc->no_nested_smmu = true;
|
||||
+ compat_props_add(mc->compat_props, arm_acpi_pci_hp_disabled_compat,
|
||||
+ arm_acpi_pci_hp_disabled_compat_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_10_2, hw_compat_rhel_10_2_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len);
|
||||
}
|
||||
132
0038-hw-arm-smmu-common-Check-SMMU-has-PCIe-Root-Complex-.patch
Normal file
132
0038-hw-arm-smmu-common-Check-SMMU-has-PCIe-Root-Complex-.patch
Normal file
@ -0,0 +1,132 @@
|
||||
From b8a9e338fb98883ba262f04320502d778753d427 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:23 +0100
|
||||
Subject: [PATCH] hw/arm/smmu-common: Check SMMU has PCIe Root Complex
|
||||
association
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [1/11] 9e7a87070ebfef643848d31fe66f5b4e82bfe0cf (eauger1/centos-qemu-kvm)
|
||||
|
||||
We only allow default PCIe Root Complex(pcie.0) or pxb-pcie based extra
|
||||
root complexes to be associated with SMMU.
|
||||
|
||||
Although this change does not affect functionality at present, it is
|
||||
required when we add support for user-creatable SMMUv3 devices in
|
||||
future patches.
|
||||
|
||||
Note: Added a specific check to identify pxb-pcie to avoid matching
|
||||
pxb-cxl host bridges, which are also of type PCI_HOST_BRIDGE. This
|
||||
restriction can be relaxed once support for CXL devices on arm/virt
|
||||
is added and validated with SMMUv3.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Message-id: 20250829082543.7680-2-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit d9e6b8424fd2523a0361972d5dd841471879479c)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-smmu-common-Check-SMMU-has-PCIe-Root-Complex-.patch
|
||||
Patch-id: 41
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/smmu-common.c | 31 ++++++++++++++++++++++++++---
|
||||
hw/pci-bridge/pci_expander_bridge.c | 1 -
|
||||
include/hw/pci/pci_bridge.h | 1 +
|
||||
3 files changed, 29 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
|
||||
index 0dcaf2f589..7f64ea48d0 100644
|
||||
--- a/hw/arm/smmu-common.c
|
||||
+++ b/hw/arm/smmu-common.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "trace.h"
|
||||
#include "exec/target_page.h"
|
||||
#include "hw/core/cpu.h"
|
||||
+#include "hw/pci/pci_bridge.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/jhash.h"
|
||||
@@ -925,6 +926,7 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SMMUState *s = ARM_SMMU(dev);
|
||||
SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
|
||||
+ PCIBus *pci_bus = s->primary_bus;
|
||||
Error *local_err = NULL;
|
||||
|
||||
sbc->parent_realize(dev, &local_err);
|
||||
@@ -937,11 +939,34 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
|
||||
g_free, g_free);
|
||||
s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
|
||||
|
||||
- if (s->primary_bus) {
|
||||
- pci_setup_iommu(s->primary_bus, &smmu_ops, s);
|
||||
- } else {
|
||||
+ if (!pci_bus) {
|
||||
error_setg(errp, "SMMU is not attached to any PCI bus!");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We only allow default PCIe Root Complex(pcie.0) or pxb-pcie based extra
|
||||
+ * root complexes to be associated with SMMU.
|
||||
+ */
|
||||
+ if (pci_bus_is_express(pci_bus) && pci_bus_is_root(pci_bus) &&
|
||||
+ object_dynamic_cast(OBJECT(pci_bus)->parent, TYPE_PCI_HOST_BRIDGE)) {
|
||||
+ /*
|
||||
+ * This condition matches either the default pcie.0, pxb-pcie, or
|
||||
+ * pxb-cxl. For both pxb-pcie and pxb-cxl, parent_dev will be set.
|
||||
+ * Currently, we don't allow pxb-cxl as it requires further
|
||||
+ * verification. Therefore, make sure this is indeed pxb-pcie.
|
||||
+ */
|
||||
+ if (pci_bus->parent_dev) {
|
||||
+ if (!object_dynamic_cast(OBJECT(pci_bus), TYPE_PXB_PCIE_BUS)) {
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+ }
|
||||
+ pci_setup_iommu(pci_bus, &smmu_ops, s);
|
||||
+ return;
|
||||
}
|
||||
+out_err:
|
||||
+ error_setg(errp, "SMMU should be attached to a default PCIe root complex"
|
||||
+ "(pcie.0) or a pxb-pcie based root complex");
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
|
||||
index 3a29dfefc2..1bcceddbc4 100644
|
||||
--- a/hw/pci-bridge/pci_expander_bridge.c
|
||||
+++ b/hw/pci-bridge/pci_expander_bridge.c
|
||||
@@ -34,7 +34,6 @@ typedef struct PXBBus PXBBus;
|
||||
DECLARE_INSTANCE_CHECKER(PXBBus, PXB_BUS,
|
||||
TYPE_PXB_BUS)
|
||||
|
||||
-#define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
|
||||
DECLARE_INSTANCE_CHECKER(PXBBus, PXB_PCIE_BUS,
|
||||
TYPE_PXB_PCIE_BUS)
|
||||
|
||||
diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
|
||||
index 8cdacbc4e1..a055fd8d32 100644
|
||||
--- a/include/hw/pci/pci_bridge.h
|
||||
+++ b/include/hw/pci/pci_bridge.h
|
||||
@@ -104,6 +104,7 @@ typedef struct PXBPCIEDev {
|
||||
PXBDev parent_obj;
|
||||
} PXBPCIEDev;
|
||||
|
||||
+#define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
|
||||
#define TYPE_PXB_CXL_BUS "pxb-cxl-bus"
|
||||
#define TYPE_PXB_DEV "pxb"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(PXBDev, PXB_DEV)
|
||||
292
0039-hw-arm-virt-acpi-build-Re-arrange-SMMUv3-IORT-build.patch
Normal file
292
0039-hw-arm-virt-acpi-build-Re-arrange-SMMUv3-IORT-build.patch
Normal file
@ -0,0 +1,292 @@
|
||||
From 49538761679e13a5d2c37466e06f79be153aa17f Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:24 +0100
|
||||
Subject: [PATCH] hw/arm/virt-acpi-build: Re-arrange SMMUv3 IORT build
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [2/11] 73e2dd4f48ffaf614c79241bc73cbb0457849131 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Introduce a new struct AcpiIortSMMUv3Dev to hold all the information
|
||||
required for SMMUv3 IORT node and use that for populating the node.
|
||||
|
||||
The current machine wide SMMUv3 is named as legacy SMMUv3 as we will
|
||||
soon add support for user-creatable SMMUv3 devices. These changes will
|
||||
be useful to have common code paths when we add that support.
|
||||
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Message-id: 20250829082543.7680-3-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 0e6a5bfb0eb17f57fb923b7905bd1435204bdd62)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-acpi-build-Re-arrange-SMMUv3-IORT-build.patch
|
||||
Patch-id: 42
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt-acpi-build.c | 137 ++++++++++++++++++++++++++-------------
|
||||
hw/arm/virt.c | 1 +
|
||||
include/hw/arm/virt.h | 1 +
|
||||
3 files changed, 94 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index b01fc4f8ef..bef4fabe56 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -305,29 +305,65 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
|
||||
return idmap_a->input_base - idmap_b->input_base;
|
||||
}
|
||||
|
||||
+typedef struct AcpiIortSMMUv3Dev {
|
||||
+ int irq;
|
||||
+ hwaddr base;
|
||||
+ GArray *rc_smmu_idmaps;
|
||||
+ /* Offset of the SMMUv3 IORT Node relative to the start of the IORT */
|
||||
+ size_t offset;
|
||||
+} AcpiIortSMMUv3Dev;
|
||||
+
|
||||
+/*
|
||||
+ * Populate the struct AcpiIortSMMUv3Dev for the legacy SMMUv3 and
|
||||
+ * return the total number of associated idmaps.
|
||||
+ */
|
||||
+static int populate_smmuv3_legacy_dev(GArray *sdev_blob)
|
||||
+{
|
||||
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
|
||||
+ AcpiIortSMMUv3Dev sdev;
|
||||
+
|
||||
+ sdev.rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
+ object_child_foreach_recursive(object_get_root(), iort_host_bridges,
|
||||
+ sdev.rc_smmu_idmaps);
|
||||
+ /*
|
||||
+ * There can be only one legacy SMMUv3("iommu=smmuv3") as it is a machine
|
||||
+ * wide one. Since it may cover multiple PCIe RCs(based on "bypass_iommu"
|
||||
+ * property), may have multiple SMMUv3 idmaps. Sort it by input_base.
|
||||
+ */
|
||||
+ g_array_sort(sdev.rc_smmu_idmaps, iort_idmap_compare);
|
||||
+
|
||||
+ sdev.base = vms->memmap[VIRT_SMMU].base;
|
||||
+ sdev.irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
|
||||
+ g_array_append_val(sdev_blob, sdev);
|
||||
+ return sdev.rc_smmu_idmaps->len;
|
||||
+}
|
||||
+
|
||||
/* Compute ID ranges (RIDs) from RC that are directed to the ITS Group node */
|
||||
-static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmu_idmaps)
|
||||
+static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmuv3_devs)
|
||||
{
|
||||
AcpiIortIdMapping *idmap;
|
||||
AcpiIortIdMapping next_range = {0};
|
||||
+ AcpiIortSMMUv3Dev *sdev;
|
||||
|
||||
- /*
|
||||
- * Based on the RID ranges that are directed to the SMMU, determine the
|
||||
- * bypassed RID ranges, i.e., the ones that are directed to the ITS Group
|
||||
- * node and do not pass through the SMMU, by subtracting the SMMU-bound
|
||||
- * ranges from the full RID range (0x0000–0xFFFF).
|
||||
- */
|
||||
- for (int i = 0; i < smmu_idmaps->len; i++) {
|
||||
- idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
|
||||
+ for (int i = 0; i < smmuv3_devs->len; i++) {
|
||||
+ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
|
||||
+ /*
|
||||
+ * Based on the RID ranges that are directed to the SMMU, determine the
|
||||
+ * bypassed RID ranges, i.e., the ones that are directed to the ITS
|
||||
+ * Group node and do not pass through the SMMU, by subtracting the
|
||||
+ * SMMU-bound ranges from the full RID range (0x0000–0xFFFF).
|
||||
+ */
|
||||
+ for (int j = 0; j < sdev->rc_smmu_idmaps->len; j++) {
|
||||
+ idmap = &g_array_index(sdev->rc_smmu_idmaps, AcpiIortIdMapping, j);
|
||||
|
||||
- if (next_range.input_base < idmap->input_base) {
|
||||
- next_range.id_count = idmap->input_base - next_range.input_base;
|
||||
- g_array_append_val(its_idmaps, next_range);
|
||||
- }
|
||||
+ if (next_range.input_base < idmap->input_base) {
|
||||
+ next_range.id_count = idmap->input_base - next_range.input_base;
|
||||
+ g_array_append_val(its_idmaps, next_range);
|
||||
+ }
|
||||
|
||||
- next_range.input_base = idmap->input_base + idmap->id_count;
|
||||
+ next_range.input_base = idmap->input_base + idmap->id_count;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
/*
|
||||
* Append the last RC -> ITS ID mapping.
|
||||
*
|
||||
@@ -341,7 +377,6 @@ static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmu_idmaps)
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
/*
|
||||
* Input Output Remapping Table (IORT)
|
||||
* Conforms to "IO Remapping Table System Software on ARM Platforms",
|
||||
@@ -351,9 +386,12 @@ static void
|
||||
build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
{
|
||||
int i, nb_nodes, rc_mapping_count;
|
||||
- size_t node_size, smmu_offset = 0;
|
||||
+ AcpiIortSMMUv3Dev *sdev;
|
||||
+ size_t node_size;
|
||||
+ int num_smmus = 0;
|
||||
uint32_t id = 0;
|
||||
- GArray *rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
+ int rc_smmu_idmaps_len = 0;
|
||||
+ GArray *smmuv3_devs = g_array_new(false, true, sizeof(AcpiIortSMMUv3Dev));
|
||||
GArray *rc_its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
|
||||
AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id,
|
||||
@@ -361,22 +399,21 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
/* Table 2 The IORT */
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
- if (vms->iommu == VIRT_IOMMU_SMMUV3) {
|
||||
- object_child_foreach_recursive(object_get_root(),
|
||||
- iort_host_bridges, rc_smmu_idmaps);
|
||||
-
|
||||
- /* Sort the smmu idmap by input_base */
|
||||
- g_array_sort(rc_smmu_idmaps, iort_idmap_compare);
|
||||
+ if (vms->legacy_smmuv3_present) {
|
||||
+ rc_smmu_idmaps_len = populate_smmuv3_legacy_dev(smmuv3_devs);
|
||||
+ }
|
||||
|
||||
- nb_nodes = 2; /* RC and SMMUv3 */
|
||||
- rc_mapping_count = rc_smmu_idmaps->len;
|
||||
+ num_smmus = smmuv3_devs->len;
|
||||
+ if (num_smmus) {
|
||||
+ nb_nodes = num_smmus + 1; /* RC and SMMUv3 */
|
||||
+ rc_mapping_count = rc_smmu_idmaps_len;
|
||||
|
||||
if (vms->its) {
|
||||
/*
|
||||
* Knowing the ID ranges from the RC to the SMMU, it's possible to
|
||||
* determine the ID ranges from RC that go directly to ITS.
|
||||
*/
|
||||
- create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps);
|
||||
+ create_rc_its_idmaps(rc_its_idmaps, smmuv3_devs);
|
||||
|
||||
nb_nodes++; /* ITS */
|
||||
rc_mapping_count += rc_its_idmaps->len;
|
||||
@@ -411,9 +448,10 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4);
|
||||
}
|
||||
|
||||
- if (vms->iommu == VIRT_IOMMU_SMMUV3) {
|
||||
- int irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
|
||||
+ for (i = 0; i < num_smmus; i++) {
|
||||
+ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
|
||||
int smmu_mapping_count, offset_to_id_array;
|
||||
+ int irq = sdev->irq;
|
||||
|
||||
if (vms->its) {
|
||||
smmu_mapping_count = 1; /* ITS Group node */
|
||||
@@ -422,7 +460,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
smmu_mapping_count = 0; /* No ID mappings */
|
||||
offset_to_id_array = 0; /* No ID mappings array */
|
||||
}
|
||||
- smmu_offset = table_data->len - table.table_offset;
|
||||
+ sdev->offset = table_data->len - table.table_offset;
|
||||
/* Table 9 SMMUv3 Format */
|
||||
build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */
|
||||
node_size = SMMU_V3_ENTRY_SIZE +
|
||||
@@ -435,7 +473,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
/* Reference to ID Array */
|
||||
build_append_int_noprefix(table_data, offset_to_id_array, 4);
|
||||
/* Base address */
|
||||
- build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8);
|
||||
+ build_append_int_noprefix(table_data, sdev->base, 8);
|
||||
/* Flags */
|
||||
build_append_int_noprefix(table_data, 1 /* COHACC Override */, 4);
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
@@ -486,21 +524,26 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
|
||||
|
||||
/* Output Reference */
|
||||
- if (vms->iommu == VIRT_IOMMU_SMMUV3) {
|
||||
+ if (num_smmus) {
|
||||
AcpiIortIdMapping *range;
|
||||
|
||||
- /*
|
||||
- * Map RIDs (input) from RC to SMMUv3 nodes: RC -> SMMUv3.
|
||||
- *
|
||||
- * N.B.: The mapping from SMMUv3 to ITS Group node (SMMUv3 -> ITS) is
|
||||
- * defined in the SMMUv3 table, where all SMMUv3 IDs are mapped to the
|
||||
- * ITS Group node, if ITS is available.
|
||||
- */
|
||||
- for (i = 0; i < rc_smmu_idmaps->len; i++) {
|
||||
- range = &g_array_index(rc_smmu_idmaps, AcpiIortIdMapping, i);
|
||||
- /* Output IORT node is the SMMUv3 node. */
|
||||
- build_iort_id_mapping(table_data, range->input_base,
|
||||
- range->id_count, smmu_offset);
|
||||
+ for (i = 0; i < num_smmus; i++) {
|
||||
+ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
|
||||
+
|
||||
+ /*
|
||||
+ * Map RIDs (input) from RC to SMMUv3 nodes: RC -> SMMUv3.
|
||||
+ *
|
||||
+ * N.B.: The mapping from SMMUv3 to ITS Group node (SMMUv3 -> ITS)
|
||||
+ * is defined in the SMMUv3 table, where all SMMUv3 IDs are mapped
|
||||
+ * to the ITS Group node, if ITS is available.
|
||||
+ */
|
||||
+ for (int j = 0; j < sdev->rc_smmu_idmaps->len; j++) {
|
||||
+ range = &g_array_index(sdev->rc_smmu_idmaps,
|
||||
+ AcpiIortIdMapping, j);
|
||||
+ /* Output IORT node is the SMMUv3 node. */
|
||||
+ build_iort_id_mapping(table_data, range->input_base,
|
||||
+ range->id_count, sdev->offset);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (vms->its) {
|
||||
@@ -525,8 +568,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
}
|
||||
|
||||
acpi_table_end(linker, &table);
|
||||
- g_array_free(rc_smmu_idmaps, true);
|
||||
g_array_free(rc_its_idmaps, true);
|
||||
+ for (i = 0; i < num_smmus; i++) {
|
||||
+ sdev = &g_array_index(smmuv3_devs, AcpiIortSMMUv3Dev, i);
|
||||
+ g_array_free(sdev->rc_smmu_idmaps, true);
|
||||
+ }
|
||||
+ g_array_free(smmuv3_devs, true);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 542d702513..0cc9e5f068 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1686,6 +1686,7 @@ static void create_pcie(VirtMachineState *vms)
|
||||
qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map",
|
||||
0x0, vms->iommu_phandle, 0x0, 0x10000);
|
||||
}
|
||||
+ vms->legacy_smmuv3_present = true;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index 94c79d6c6d..98b877c8b9 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -180,6 +180,7 @@ struct VirtMachineState {
|
||||
char *oem_table_id;
|
||||
bool ns_el2_virt_timer_irq;
|
||||
CXLState cxl_devices_state;
|
||||
+ bool legacy_smmuv3_present;
|
||||
};
|
||||
|
||||
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
|
||||
171
0040-hw-arm-virt-acpi-build-Update-IORT-for-multiple-smmu.patch
Normal file
171
0040-hw-arm-virt-acpi-build-Update-IORT-for-multiple-smmu.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From 90910403b2dc85fa6f2106a6bd75f1eee123f359 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:25 +0100
|
||||
Subject: [PATCH] hw/arm/virt-acpi-build: Update IORT for multiple smmuv3
|
||||
devices
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [3/11] 9cb15768a319676af16cd2cdef8b8fabfa7b6f13 (eauger1/centos-qemu-kvm)
|
||||
|
||||
With the soon to be introduced user-creatable SMMUv3 devices for
|
||||
virt, it is possible to have multiple SMMUv3 devices associated
|
||||
with different PCIe root complexes.
|
||||
|
||||
Update IORT nodes accordingly.
|
||||
|
||||
An example IORT Id mappings for a Qemu virt machine with two
|
||||
PCIe Root Complexes each assocaited with a SMMUv3 will
|
||||
be something like below,
|
||||
|
||||
-device arm-smmuv3,primary-bus=pcie.0,id=smmuv3.0
|
||||
-device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1
|
||||
...
|
||||
|
||||
+--------------------+ +--------------------+
|
||||
| Root Complex 0 | | Root Complex 1 |
|
||||
| | | |
|
||||
| Requestor IDs | | Requestor IDs |
|
||||
| 0x0000 - 0x00FF | | 0x0100 - 0x01FF |
|
||||
+---------+----------+ +---------+----------+
|
||||
| |
|
||||
| |
|
||||
| Stream ID Mapping |
|
||||
v v
|
||||
+--------------------+ +--------------------+
|
||||
| SMMUv3 Node 0 | | SMMUv3 Node 1 |
|
||||
| | | |
|
||||
| Stream IDs 0x0000- | | Stream IDs 0x0100- |
|
||||
| 0x00FF mapped from | | 0x01FF mapped from |
|
||||
| RC0 Requestor IDs | | RC1 Requestor IDs |
|
||||
+--------------------+ +--------------------+
|
||||
| |
|
||||
| |
|
||||
+----------------+---------------+
|
||||
|
|
||||
|Device ID Mapping
|
||||
v
|
||||
+----------------------------+
|
||||
| ITS Node 0 |
|
||||
| |
|
||||
| Device IDs: |
|
||||
| 0x0000 - 0x00FF (from RC0) |
|
||||
| 0x0100 - 0x01FF (from RC1) |
|
||||
| 0x0200 - 0xFFFF (No SMMU) |
|
||||
+----------------------------+
|
||||
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Message-id: 20250829082543.7680-4-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 01e9a18730e6f56f713ed074603a8b0f2982ed26)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-acpi-build-Update-IORT-for-multiple-smmu.patch
|
||||
Patch-id: 43
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt-acpi-build.c | 64 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 64 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index bef4fabe56..96830f7c4e 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/acpi/tpm.h"
|
||||
#include "hw/acpi/hmat.h"
|
||||
+#include "hw/arm/smmuv3.h"
|
||||
#include "hw/cxl/cxl.h"
|
||||
#include "hw/pci/pcie_host.h"
|
||||
#include "hw/pci/pci.h"
|
||||
@@ -338,6 +339,67 @@ static int populate_smmuv3_legacy_dev(GArray *sdev_blob)
|
||||
return sdev.rc_smmu_idmaps->len;
|
||||
}
|
||||
|
||||
+static int smmuv3_dev_idmap_compare(gconstpointer a, gconstpointer b)
|
||||
+{
|
||||
+ AcpiIortSMMUv3Dev *sdev_a = (AcpiIortSMMUv3Dev *)a;
|
||||
+ AcpiIortSMMUv3Dev *sdev_b = (AcpiIortSMMUv3Dev *)b;
|
||||
+ AcpiIortIdMapping *map_a = &g_array_index(sdev_a->rc_smmu_idmaps,
|
||||
+ AcpiIortIdMapping, 0);
|
||||
+ AcpiIortIdMapping *map_b = &g_array_index(sdev_b->rc_smmu_idmaps,
|
||||
+ AcpiIortIdMapping, 0);
|
||||
+ return map_a->input_base - map_b->input_base;
|
||||
+}
|
||||
+
|
||||
+static int iort_smmuv3_devices(Object *obj, void *opaque)
|
||||
+{
|
||||
+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine());
|
||||
+ GArray *sdev_blob = opaque;
|
||||
+ AcpiIortIdMapping idmap;
|
||||
+ PlatformBusDevice *pbus;
|
||||
+ AcpiIortSMMUv3Dev sdev;
|
||||
+ int min_bus, max_bus;
|
||||
+ SysBusDevice *sbdev;
|
||||
+ PCIBus *bus;
|
||||
+
|
||||
+ if (!object_dynamic_cast(obj, TYPE_ARM_SMMUV3)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ bus = PCI_BUS(object_property_get_link(obj, "primary-bus", &error_abort));
|
||||
+ pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
|
||||
+ sbdev = SYS_BUS_DEVICE(obj);
|
||||
+ sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
+ sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base;
|
||||
+ sdev.irq = platform_bus_get_irqn(pbus, sbdev, 0);
|
||||
+ sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS];
|
||||
+ sdev.irq += ARM_SPI_BASE;
|
||||
+
|
||||
+ pci_bus_range(bus, &min_bus, &max_bus);
|
||||
+ sdev.rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
+ idmap.input_base = min_bus << 8,
|
||||
+ idmap.id_count = (max_bus - min_bus + 1) << 8,
|
||||
+ g_array_append_val(sdev.rc_smmu_idmaps, idmap);
|
||||
+ g_array_append_val(sdev_blob, sdev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Populate the struct AcpiIortSMMUv3Dev for all SMMUv3 devices and
|
||||
+ * return the total number of idmaps.
|
||||
+ */
|
||||
+static int populate_smmuv3_dev(GArray *sdev_blob)
|
||||
+{
|
||||
+ object_child_foreach_recursive(object_get_root(),
|
||||
+ iort_smmuv3_devices, sdev_blob);
|
||||
+ /* Sort the smmuv3 devices(if any) by smmu idmap input_base */
|
||||
+ g_array_sort(sdev_blob, smmuv3_dev_idmap_compare);
|
||||
+ /*
|
||||
+ * Since each SMMUv3 dev is assocaited with specific host bridge,
|
||||
+ * total number of idmaps equals to total number of smmuv3 devices.
|
||||
+ */
|
||||
+ return sdev_blob->len;
|
||||
+}
|
||||
+
|
||||
/* Compute ID ranges (RIDs) from RC that are directed to the ITS Group node */
|
||||
static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmuv3_devs)
|
||||
{
|
||||
@@ -401,6 +463,8 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
|
||||
if (vms->legacy_smmuv3_present) {
|
||||
rc_smmu_idmaps_len = populate_smmuv3_legacy_dev(smmuv3_devs);
|
||||
+ } else {
|
||||
+ rc_smmu_idmaps_len = populate_smmuv3_dev(smmuv3_devs);
|
||||
}
|
||||
|
||||
num_smmus = smmuv3_devs->len;
|
||||
119
0041-hw-arm-virt-Factor-out-common-SMMUV3-dt-bindings-cod.patch
Normal file
119
0041-hw-arm-virt-Factor-out-common-SMMUV3-dt-bindings-cod.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From cb1057c9f94d149a6ddc2c9310ab6bd4ec260538 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:26 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Factor out common SMMUV3 dt bindings code
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [4/11] db5d2a44f4cd1583c839b93ae551a2ddbd68b83b (eauger1/centos-qemu-kvm)
|
||||
|
||||
No functional changes intended. This will be useful when we
|
||||
add support for user-creatable smmuv3 device.
|
||||
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Message-id: 20250829082543.7680-5-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 7a276b7570266ec39611f9d91089741ec7e9295b)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-Factor-out-common-SMMUV3-dt-bindings-cod.patch
|
||||
Patch-id: 44
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt.c | 54 +++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 29 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 0cc9e5f068..9b95a7c9a9 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1479,19 +1479,43 @@ static void create_pcie_irq_map(const MachineState *ms,
|
||||
0x7 /* PCI irq */);
|
||||
}
|
||||
|
||||
+static void create_smmuv3_dt_bindings(const VirtMachineState *vms, hwaddr base,
|
||||
+ hwaddr size, int irq)
|
||||
+{
|
||||
+ char *node;
|
||||
+ const char compat[] = "arm,smmu-v3";
|
||||
+ const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
|
||||
+ MachineState *ms = MACHINE(vms);
|
||||
+
|
||||
+ node = g_strdup_printf("/smmuv3@%" PRIx64, base);
|
||||
+ qemu_fdt_add_subnode(ms->fdt, node);
|
||||
+ qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat));
|
||||
+ qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", 2, base, 2, size);
|
||||
+
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, node, "interrupts",
|
||||
+ GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
+ GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
+ GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
+ GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
||||
+
|
||||
+ qemu_fdt_setprop(ms->fdt, node, "interrupt-names", irq_names,
|
||||
+ sizeof(irq_names));
|
||||
+
|
||||
+ qemu_fdt_setprop(ms->fdt, node, "dma-coherent", NULL, 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, node, "#iommu-cells", 1);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, node, "phandle", vms->iommu_phandle);
|
||||
+ g_free(node);
|
||||
+}
|
||||
+
|
||||
static void create_smmu(const VirtMachineState *vms,
|
||||
PCIBus *bus)
|
||||
{
|
||||
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||
- char *node;
|
||||
- const char compat[] = "arm,smmu-v3";
|
||||
int irq = vms->irqmap[VIRT_SMMU];
|
||||
int i;
|
||||
hwaddr base = vms->memmap[VIRT_SMMU].base;
|
||||
hwaddr size = vms->memmap[VIRT_SMMU].size;
|
||||
- const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
|
||||
DeviceState *dev;
|
||||
- MachineState *ms = MACHINE(vms);
|
||||
|
||||
if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) {
|
||||
return;
|
||||
@@ -1510,27 +1534,7 @@ static void create_smmu(const VirtMachineState *vms,
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
||||
qdev_get_gpio_in(vms->gic, irq + i));
|
||||
}
|
||||
-
|
||||
- node = g_strdup_printf("/smmuv3@%" PRIx64, base);
|
||||
- qemu_fdt_add_subnode(ms->fdt, node);
|
||||
- qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat));
|
||||
- qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", 2, base, 2, size);
|
||||
-
|
||||
- qemu_fdt_setprop_cells(ms->fdt, node, "interrupts",
|
||||
- GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
- GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
- GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
|
||||
- GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
||||
-
|
||||
- qemu_fdt_setprop(ms->fdt, node, "interrupt-names", irq_names,
|
||||
- sizeof(irq_names));
|
||||
-
|
||||
- qemu_fdt_setprop(ms->fdt, node, "dma-coherent", NULL, 0);
|
||||
-
|
||||
- qemu_fdt_setprop_cell(ms->fdt, node, "#iommu-cells", 1);
|
||||
-
|
||||
- qemu_fdt_setprop_cell(ms->fdt, node, "phandle", vms->iommu_phandle);
|
||||
- g_free(node);
|
||||
+ create_smmuv3_dt_bindings(vms, base, size, irq);
|
||||
}
|
||||
|
||||
static void create_virtio_iommu_dt_bindings(VirtMachineState *vms)
|
||||
62
0042-hw-arm-virt-Add-an-SMMU_IO_LEN-macro.patch
Normal file
62
0042-hw-arm-virt-Add-an-SMMU_IO_LEN-macro.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 2a43ed7e5472ba40c08cb5784fd1aadae9774c0e Mon Sep 17 00:00:00 2001
|
||||
From: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:27 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Add an SMMU_IO_LEN macro
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [5/11] 72c82e228bb256db07fbe28728ad47dbd8b04dc3 (eauger1/centos-qemu-kvm)
|
||||
|
||||
This is useful as the subsequent support for new SMMUv3 dev will also
|
||||
use the same.
|
||||
|
||||
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-6-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 466197fc7a25658f9187d538c26887f5738d1ac9)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-Add-an-SMMU_IO_LEN-macro.patch
|
||||
Patch-id: 45
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 9b95a7c9a9..b435efafe1 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -186,6 +186,9 @@ static void arm_virt_compat_set(MachineClass *mc)
|
||||
#define LEGACY_RAMLIMIT_GB 255
|
||||
#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
|
||||
|
||||
+/* MMIO region size for SMMUv3 */
|
||||
+#define SMMU_IO_LEN 0x20000
|
||||
+
|
||||
/* Addresses and sizes of our components.
|
||||
* 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
|
||||
* 128MB..256MB is used for miscellaneous device I/O.
|
||||
@@ -217,7 +220,7 @@ static const MemMapEntry base_memmap[] = {
|
||||
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
|
||||
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
|
||||
[VIRT_UART1] = { 0x09040000, 0x00001000 },
|
||||
- [VIRT_SMMU] = { 0x09050000, 0x00020000 },
|
||||
+ [VIRT_SMMU] = { 0x09050000, SMMU_IO_LEN },
|
||||
[VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
|
||||
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
|
||||
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
|
||||
151
0043-hw-pci-Introduce-pci_setup_iommu_per_bus-for-per-bus.patch
Normal file
151
0043-hw-pci-Introduce-pci_setup_iommu_per_bus-for-per-bus.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From fc47a08ea593b2fdb1d872f40237a818dabad4fc Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:28 +0100
|
||||
Subject: [PATCH] hw/pci: Introduce pci_setup_iommu_per_bus() for per-bus IOMMU
|
||||
ops retrieval
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [6/11] 0c41f77254cd66a3648c14c5d4ba2dfdbd396665 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Currently, pci_setup_iommu() registers IOMMU ops for a given PCIBus.
|
||||
However, when retrieving IOMMU ops for a device using
|
||||
pci_device_get_iommu_bus_devfn(), the function checks the parent_dev
|
||||
and fetches IOMMU ops from the parent device, even if the current
|
||||
bus does not have any associated IOMMU ops.
|
||||
|
||||
This behavior works for now because QEMU's IOMMU implementations are
|
||||
globally scoped, and host bridges rely on the bypass_iommu property
|
||||
to skip IOMMU translation when needed.
|
||||
|
||||
However, this model will break with the soon to be introduced
|
||||
arm-smmuv3 device, which allows users to associate the IOMMU
|
||||
with a specific PCIe root complex (e.g., the default pcie.0
|
||||
or a pxb-pcie root complex).
|
||||
|
||||
For example, consider the following setup with multiple root
|
||||
complexes:
|
||||
|
||||
-device arm-smmuv3,primary-bus=pcie.0,id=smmuv3.0 \
|
||||
...
|
||||
-device pxb-pcie,id=pcie.1,bus_nr=8,bus=pcie.0 \
|
||||
-device pcie-root-port,id=pcie.port1,bus=pcie.1 \
|
||||
-device virtio-net-pci,bus=pcie.port1
|
||||
|
||||
In Qemu, pxb-pcie acts as a special root complex whose parent is
|
||||
effectively the default root complex(pcie.0). Hence, though pcie.1
|
||||
has no associated SMMUv3 as per above, pci_device_get_iommu_bus_devfn()
|
||||
will incorrectly return the IOMMU ops from pcie.0 due to the fallback
|
||||
via parent_dev.
|
||||
|
||||
To fix this, introduce a new helper pci_setup_iommu_per_bus() that
|
||||
explicitly sets the new iommu_per_bus field in the PCIBus structure.
|
||||
This helper will be used in a subsequent patch that adds support for
|
||||
the new arm-smmuv3 device.
|
||||
|
||||
Update pci_device_get_iommu_bus_devfn() to use iommu_per_bus when
|
||||
determining the correct IOMMU ops, ensuring accurate behavior for
|
||||
per-bus IOMMUs.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Message-id: 20250829082543.7680-7-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 951bc76fb669eab96cc60e38a50097ad4435163e)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-pci-Introduce-pci_setup_iommu_per_bus-for-per-bus.patch
|
||||
Patch-id: 46
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/pci/pci.c | 31 +++++++++++++++++++++++++++++++
|
||||
include/hw/pci/pci.h | 2 ++
|
||||
include/hw/pci/pci_bus.h | 1 +
|
||||
3 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
|
||||
index c70b5ceeba..0012cc12e7 100644
|
||||
--- a/hw/pci/pci.c
|
||||
+++ b/hw/pci/pci.c
|
||||
@@ -2909,6 +2909,19 @@ static void pci_device_get_iommu_bus_devfn(PCIDevice *dev,
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * When multiple PCI Express Root Buses are defined using pxb-pcie,
|
||||
+ * the IOMMU configuration may be specific to each root bus. However,
|
||||
+ * pxb-pcie acts as a special root complex whose parent is effectively
|
||||
+ * the default root complex(pcie.0). Ensure that we retrieve the
|
||||
+ * correct IOMMU ops(if any) in such cases.
|
||||
+ */
|
||||
+ if (pci_bus_is_express(iommu_bus) && pci_bus_is_root(iommu_bus)) {
|
||||
+ if (parent_bus->iommu_per_bus) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
iommu_bus = parent_bus;
|
||||
}
|
||||
|
||||
@@ -3169,6 +3182,24 @@ void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque)
|
||||
bus->iommu_opaque = opaque;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Similar to pci_setup_iommu(), but sets iommu_per_bus to true,
|
||||
+ * indicating that the IOMMU is specific to this bus. This is used by
|
||||
+ * IOMMU implementations that are tied to a specific PCIe root complex.
|
||||
+ *
|
||||
+ * In QEMU, pxb-pcie behaves as a special root complex whose parent is
|
||||
+ * effectively the default root complex (pcie.0). The iommu_per_bus
|
||||
+ * is checked in pci_device_get_iommu_bus_devfn() to ensure the correct
|
||||
+ * IOMMU ops are returned, avoiding the use of the parent’s IOMMU when
|
||||
+ * it's not appropriate.
|
||||
+ */
|
||||
+void pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops,
|
||||
+ void *opaque)
|
||||
+{
|
||||
+ pci_setup_iommu(bus, ops, opaque);
|
||||
+ bus->iommu_per_bus = true;
|
||||
+}
|
||||
+
|
||||
static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
|
||||
{
|
||||
Range *range = opaque;
|
||||
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
|
||||
index 6b7d3ac8a3..6bccb25ac2 100644
|
||||
--- a/include/hw/pci/pci.h
|
||||
+++ b/include/hw/pci/pci.h
|
||||
@@ -773,6 +773,8 @@ int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid,
|
||||
*/
|
||||
void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
|
||||
|
||||
+void pci_setup_iommu_per_bus(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque);
|
||||
+
|
||||
pcibus_t pci_bar_address(PCIDevice *d,
|
||||
int reg, uint8_t type, pcibus_t size);
|
||||
|
||||
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
|
||||
index 2261312546..c738446788 100644
|
||||
--- a/include/hw/pci/pci_bus.h
|
||||
+++ b/include/hw/pci/pci_bus.h
|
||||
@@ -35,6 +35,7 @@ struct PCIBus {
|
||||
enum PCIBusFlags flags;
|
||||
const PCIIOMMUOps *iommu_ops;
|
||||
void *iommu_opaque;
|
||||
+ bool iommu_per_bus;
|
||||
uint8_t devfn_min;
|
||||
uint32_t slot_reserved_mask;
|
||||
pci_set_irq_fn set_irq;
|
||||
215
0044-hw-arm-virt-Allow-user-creatable-SMMUv3-dev-instanti.patch
Normal file
215
0044-hw-arm-virt-Allow-user-creatable-SMMUv3-dev-instanti.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From fa04930d828fa4de32a5ecae907fdbf316d88509 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:29 +0100
|
||||
Subject: [PATCH] hw/arm/virt: Allow user-creatable SMMUv3 dev instantiation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [7/11] 8f4a03c34d5c699023b3916f4919caf669f7a87c (eauger1/centos-qemu-kvm)
|
||||
|
||||
Allow cold-plugging of an SMMUv3 device on the virt machine when no
|
||||
global (legacy) SMMUv3 is present or when a virtio-iommu is specified.
|
||||
|
||||
This user-created SMMUv3 device is tied to a specific PCI bus provided
|
||||
by the user, so ensure the IOMMU ops are configured accordingly.
|
||||
|
||||
Due to current limitations in QEMU’s device tree support, specifically
|
||||
its inability to properly present pxb-pcie based root complexes and
|
||||
their devices, the device tree support for the new SMMUv3 device is
|
||||
limited to cases where it is attached to the default pcie.0 root complex.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nathan Chen <nathanc@nvidia.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-8-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 66d2f665e163cf1afccd171e3c16f8d3acb3d94a)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-arm-virt-Allow-user-creatable-SMMUv3-dev-instanti.patch
|
||||
Patch-id: 47
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/smmu-common.c | 8 +++++-
|
||||
hw/arm/smmuv3.c | 2 ++
|
||||
hw/arm/virt.c | 51 ++++++++++++++++++++++++++++++++++++
|
||||
hw/core/sysbus-fdt.c | 3 +++
|
||||
include/hw/arm/smmu-common.h | 1 +
|
||||
5 files changed, 64 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
|
||||
index 7f64ea48d0..62a7612184 100644
|
||||
--- a/hw/arm/smmu-common.c
|
||||
+++ b/hw/arm/smmu-common.c
|
||||
@@ -961,7 +961,12 @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
- pci_setup_iommu(pci_bus, &smmu_ops, s);
|
||||
+
|
||||
+ if (s->smmu_per_bus) {
|
||||
+ pci_setup_iommu_per_bus(pci_bus, &smmu_ops, s);
|
||||
+ } else {
|
||||
+ pci_setup_iommu(pci_bus, &smmu_ops, s);
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
out_err:
|
||||
@@ -986,6 +991,7 @@ static void smmu_base_reset_exit(Object *obj, ResetType type)
|
||||
|
||||
static const Property smmu_dev_properties[] = {
|
||||
DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0),
|
||||
+ DEFINE_PROP_BOOL("smmu_per_bus", SMMUState, smmu_per_bus, false),
|
||||
DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus,
|
||||
TYPE_PCI_BUS, PCIBus *),
|
||||
};
|
||||
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
|
||||
index ab67972353..bcf8af8dc7 100644
|
||||
--- a/hw/arm/smmuv3.c
|
||||
+++ b/hw/arm/smmuv3.c
|
||||
@@ -1996,6 +1996,8 @@ static void smmuv3_class_init(ObjectClass *klass, const void *data)
|
||||
device_class_set_parent_realize(dc, smmu_realize,
|
||||
&c->parent_realize);
|
||||
device_class_set_props(dc, smmuv3_properties);
|
||||
+ dc->hotpluggable = false;
|
||||
+ dc->user_creatable = true;
|
||||
}
|
||||
|
||||
static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index b435efafe1..e8e64fe7fe 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
+#include "hw/pci/pci_bus.h"
|
||||
#include "hw/pci-host/gpex.h"
|
||||
#include "hw/pci-bridge/pci_expander_bridge.h"
|
||||
#include "hw/virtio/virtio-pci.h"
|
||||
@@ -1510,6 +1511,29 @@ static void create_smmuv3_dt_bindings(const VirtMachineState *vms, hwaddr base,
|
||||
g_free(node);
|
||||
}
|
||||
|
||||
+static void create_smmuv3_dev_dtb(VirtMachineState *vms,
|
||||
+ DeviceState *dev, PCIBus *bus)
|
||||
+{
|
||||
+ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
|
||||
+ SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
|
||||
+ int irq = platform_bus_get_irqn(pbus, sbdev, 0);
|
||||
+ hwaddr base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
+ MachineState *ms = MACHINE(vms);
|
||||
+
|
||||
+ if (!(vms->bootinfo.firmware_loaded && virt_is_acpi_enabled(vms)) &&
|
||||
+ strcmp("pcie.0", bus->qbus.name)) {
|
||||
+ warn_report("SMMUv3 device only supported with pcie.0 for DT");
|
||||
+ return;
|
||||
+ }
|
||||
+ base += vms->memmap[VIRT_PLATFORM_BUS].base;
|
||||
+ irq += vms->irqmap[VIRT_PLATFORM_BUS];
|
||||
+
|
||||
+ vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ create_smmuv3_dt_bindings(vms, base, SMMU_IO_LEN, irq);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, vms->pciehb_nodename, "iommu-map",
|
||||
+ 0x0, vms->iommu_phandle, 0x0, 0x10000);
|
||||
+}
|
||||
+
|
||||
static void create_smmu(const VirtMachineState *vms,
|
||||
PCIBus *bus)
|
||||
{
|
||||
@@ -3057,6 +3081,16 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
|
||||
qlist_append_str(reserved_regions, resv_prop_str);
|
||||
qdev_prop_set_array(dev, "reserved-regions", reserved_regions);
|
||||
g_free(resv_prop_str);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_SMMUV3)) {
|
||||
+ if (vms->legacy_smmuv3_present || vms->iommu == VIRT_IOMMU_VIRTIO) {
|
||||
+ error_setg(errp, "virt machine already has %s set. "
|
||||
+ "Doesn't support incompatible iommus",
|
||||
+ (vms->legacy_smmuv3_present) ?
|
||||
+ "iommu=smmuv3" : "virtio-iommu");
|
||||
+ } else if (vms->iommu == VIRT_IOMMU_NONE) {
|
||||
+ /* The new SMMUv3 device is specific to the PCI bus */
|
||||
+ object_property_set_bool(OBJECT(dev), "smmu_per_bus", true, NULL);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3080,6 +3114,22 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
virtio_md_pci_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
|
||||
}
|
||||
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_SMMUV3)) {
|
||||
+ if (!vms->legacy_smmuv3_present && vms->platform_bus_dev) {
|
||||
+ PCIBus *bus;
|
||||
+
|
||||
+ bus = PCI_BUS(object_property_get_link(OBJECT(dev), "primary-bus",
|
||||
+ &error_abort));
|
||||
+ if (pci_bus_bypass_iommu(bus)) {
|
||||
+ error_setg(errp, "Bypass option cannot be set for SMMUv3 "
|
||||
+ "associated PCIe RC");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ create_smmuv3_dev_dtb(vms, dev, bus);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
|
||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||
|
||||
@@ -3286,6 +3336,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
|
||||
#endif
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
|
||||
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ARM_SMMUV3);
|
||||
#ifdef CONFIG_TPM
|
||||
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
|
||||
#endif
|
||||
diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c
|
||||
index 1e1966813f..673e083d31 100644
|
||||
--- a/hw/core/sysbus-fdt.c
|
||||
+++ b/hw/core/sysbus-fdt.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "system/device_tree.h"
|
||||
#include "system/tpm.h"
|
||||
+#include "hw/arm/smmuv3.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/vfio/vfio-platform.h"
|
||||
#include "hw/vfio/vfio-calxeda-xgmac.h"
|
||||
@@ -518,6 +519,8 @@ static const BindingEntry bindings[] = {
|
||||
#ifdef CONFIG_TPM
|
||||
TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node),
|
||||
#endif
|
||||
+ /* No generic DT support for smmuv3 dev. Support added for arm virt only */
|
||||
+ TYPE_BINDING(TYPE_ARM_SMMUV3, no_fdt_node),
|
||||
TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
|
||||
TYPE_BINDING(TYPE_UEFI_VARS_SYSBUS, add_uefi_vars_node),
|
||||
TYPE_BINDING("", NULL), /* last element */
|
||||
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
|
||||
index e5e2d09294..80d0fecfde 100644
|
||||
--- a/include/hw/arm/smmu-common.h
|
||||
+++ b/include/hw/arm/smmu-common.h
|
||||
@@ -161,6 +161,7 @@ struct SMMUState {
|
||||
QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
|
||||
uint8_t bus_num;
|
||||
PCIBus *primary_bus;
|
||||
+ bool smmu_per_bus; /* SMMU is specific to the primary_bus */
|
||||
};
|
||||
|
||||
struct SMMUBaseClass {
|
||||
54
0045-qemu-options.hx-Document-the-arm-smmuv3-device.patch
Normal file
54
0045-qemu-options.hx-Document-the-arm-smmuv3-device.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From b6fd153e384990dabf068c5c893140d88edcaa40 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:30 +0100
|
||||
Subject: [PATCH] qemu-options.hx: Document the arm-smmuv3 device
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [8/11] 775310b784fd7631a58e8bab1e8fcc36973fceca (eauger1/centos-qemu-kvm)
|
||||
|
||||
Now that arm,virt can have user-creatable smmuv3 devices, document it.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-9-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 73d3d0187bc6b482d8b15116edce1475c7975b89)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-qemu-options.hx-Document-the-arm-smmuv3-device.patch
|
||||
Patch-id: 48
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
qemu-options.hx | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 3837456a61..5f146c1860 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -1231,6 +1231,13 @@ SRST
|
||||
``aw-bits=val`` (val between 32 and 64, default depends on machine)
|
||||
This decides the address width of the IOVA address space.
|
||||
|
||||
+``-device arm-smmuv3,primary-bus=id``
|
||||
+ This is only supported by ``-machine virt`` (ARM).
|
||||
+
|
||||
+ ``primary-bus=id``
|
||||
+ Accepts either the default root complex (pcie.0) or a
|
||||
+ pxb-pcie based root complex.
|
||||
+
|
||||
ERST
|
||||
|
||||
DEF("name", HAS_ARG, QEMU_OPTION_name,
|
||||
67
0046-bios-tables-test-Allow-for-smmuv3-test-data.patch
Normal file
67
0046-bios-tables-test-Allow-for-smmuv3-test-data.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From b1a804dc528b237d127a99ca6bc25f352e542fc4 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:31 +0100
|
||||
Subject: [PATCH] bios-tables-test: Allow for smmuv3 test data.
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [9/11] cf98e2e7589b794775c1d9c4f564e3cd536b886e (eauger1/centos-qemu-kvm)
|
||||
|
||||
The tests to be added exercise both legacy(iommu=smmuv3) and new
|
||||
-device arm-smmuv3,.. cases.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-10-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit c69520c13d6ea45a69a7a49361806fa05b19046d)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-bios-tables-test-Allow-for-smmuv3-test-data.patch
|
||||
Patch-id: 49
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev | 0
|
||||
tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy | 0
|
||||
tests/data/acpi/aarch64/virt/IORT.smmuv3-dev | 0
|
||||
tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy | 0
|
||||
tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
|
||||
5 files changed, 4 insertions(+)
|
||||
create mode 100644 tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev
|
||||
create mode 100644 tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy
|
||||
create mode 100644 tests/data/acpi/aarch64/virt/IORT.smmuv3-dev
|
||||
create mode 100644 tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy
|
||||
|
||||
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev b/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy
|
||||
new file mode 100644
|
||||
index 0000000000..e69de29bb2
|
||||
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
index dfb8523c8b..2e3e3ccdce 100644
|
||||
--- a/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
@@ -1 +1,5 @@
|
||||
/* List of comma-separated changed AML files to ignore */
|
||||
+"tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy",
|
||||
+"tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev",
|
||||
+"tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy",
|
||||
+"tests/data/acpi/aarch64/virt/IORT.smmuv3-dev",
|
||||
161
0047-qtest-bios-tables-test-Add-tests-for-legacy-smmuv3-a.patch
Normal file
161
0047-qtest-bios-tables-test-Add-tests-for-legacy-smmuv3-a.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From bdd38feb47a92951cd32a33e8fcd8626aa5ff5e0 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:32 +0100
|
||||
Subject: [PATCH] qtest/bios-tables-test: Add tests for legacy smmuv3 and
|
||||
smmuv3 device
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [10/11] 101ed34313636fdc11f7fbdedbe2f91671b84c4b (eauger1/centos-qemu-kvm)
|
||||
|
||||
For the legacy SMMUv3 test, the setup includes three PCIe Root Complexes,
|
||||
one of which has bypass_iommu enabled. The generated IORT table contains
|
||||
a single SMMUv3 node, a Root Complex(RC) node and 1 ITS node.
|
||||
RC node features 4 ID mappings, of which 2 points to SMMU node and the
|
||||
remaining ones points to ITS.
|
||||
|
||||
pcie.0 -> {SMMU0} -> {ITS}
|
||||
{RC} pcie.1 -> {SMMU0} -> {ITS}
|
||||
pcie.2 -> {ITS}
|
||||
[all other ids] -> {ITS}
|
||||
|
||||
For the -device arm-smmuv3,... test, the configuration also includes three
|
||||
Root Complexes, with two connected to separate SMMUv3 devices.
|
||||
The resulting IORT table contains 1 RC node, 2 SMMU nodes and 1 ITS node.
|
||||
RC node features 4 ID mappings. 2 of them target the 2 SMMU nodes while
|
||||
the others targets the ITS.
|
||||
|
||||
pcie.0 -> {SMMU0} -> {ITS}
|
||||
{RC} pcie.1 -> {SMMU1} -> {ITS}
|
||||
pcie.2 -> {ITS}
|
||||
[all other ids] -> {ITS}
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-11-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 3f8cd046c151c471d9a34181320f4a7d3f72b32a)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-qtest-bios-tables-test-Add-tests-for-legacy-smmuv3-a.patch
|
||||
Patch-id: 50
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
tests/qtest/bios-tables-test.c | 86 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 86 insertions(+)
|
||||
|
||||
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
|
||||
index 386196edc8..a384aac1be 100644
|
||||
--- a/tests/qtest/bios-tables-test.c
|
||||
+++ b/tests/qtest/bios-tables-test.c
|
||||
@@ -2343,6 +2343,86 @@ static void test_acpi_aarch64_virt_viot(void)
|
||||
free_test_data(&data);
|
||||
}
|
||||
|
||||
+static void test_acpi_aarch64_virt_smmuv3_legacy(void)
|
||||
+{
|
||||
+ test_data data = {
|
||||
+ .machine = "virt",
|
||||
+ .arch = "aarch64",
|
||||
+ .tcg_only = true,
|
||||
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
|
||||
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
|
||||
+ .ram_start = 0x40000000ULL,
|
||||
+ .scan_len = 128ULL * MiB,
|
||||
+ };
|
||||
+
|
||||
+ /*
|
||||
+ * cdrom is plugged into scsi controller to avoid conflict
|
||||
+ * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb() for
|
||||
+ * details.
|
||||
+ *
|
||||
+ * The setup includes three PCIe root complexes, one of which has
|
||||
+ * bypass_iommu enabled. The generated IORT table contains a single
|
||||
+ * SMMUv3 node and a Root Complex node with three ID mappings. Two
|
||||
+ * of the ID mappings have output references pointing to the SMMUv3
|
||||
+ * node and the remaining one points to ITS.
|
||||
+ */
|
||||
+ data.variant = ".smmuv3-legacy";
|
||||
+ test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1"
|
||||
+ " -device virtio-scsi-pci,id=scsi0,bus=pci.1"
|
||||
+ " -drive file="
|
||||
+ "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2,"
|
||||
+ "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on"
|
||||
+ " -device scsi-cd,bus=scsi0.0,scsi-id=0,"
|
||||
+ "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1"
|
||||
+ " -cpu cortex-a57"
|
||||
+ " -M iommu=smmuv3"
|
||||
+ " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10"
|
||||
+ " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20,bypass_iommu=on",
|
||||
+ &data);
|
||||
+ free_test_data(&data);
|
||||
+}
|
||||
+
|
||||
+static void test_acpi_aarch64_virt_smmuv3_dev(void)
|
||||
+{
|
||||
+ test_data data = {
|
||||
+ .machine = "virt",
|
||||
+ .arch = "aarch64",
|
||||
+ .tcg_only = true,
|
||||
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
|
||||
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
|
||||
+ .ram_start = 0x40000000ULL,
|
||||
+ .scan_len = 128ULL * MiB,
|
||||
+ };
|
||||
+
|
||||
+ /*
|
||||
+ * cdrom is plugged into scsi controller to avoid conflict
|
||||
+ * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb()
|
||||
+ * for details.
|
||||
+ *
|
||||
+ * The setup includes three PCie root complexes, two of which are
|
||||
+ * connected to separate SMMUv3 devices. The resulting IORT table
|
||||
+ * contains two SMMUv3 nodes and a Root Complex node with ID mappings
|
||||
+ * of which two of the ID mappings have output references pointing
|
||||
+ * to two different SMMUv3 nodes and the remaining ones pointing to
|
||||
+ * ITS.
|
||||
+ */
|
||||
+ data.variant = ".smmuv3-dev";
|
||||
+ test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1"
|
||||
+ " -device virtio-scsi-pci,id=scsi0,bus=pci.1"
|
||||
+ " -drive file="
|
||||
+ "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2,"
|
||||
+ "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on"
|
||||
+ " -device scsi-cd,bus=scsi0.0,scsi-id=0,"
|
||||
+ "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1"
|
||||
+ " -cpu cortex-a57"
|
||||
+ " -device arm-smmuv3,primary-bus=pcie.0,id=smmuv3.0"
|
||||
+ " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10"
|
||||
+ " -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1"
|
||||
+ " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20",
|
||||
+ &data);
|
||||
+ free_test_data(&data);
|
||||
+}
|
||||
+
|
||||
#ifndef _WIN32
|
||||
# define DEV_NULL "/dev/null"
|
||||
#else
|
||||
@@ -2776,6 +2856,12 @@ int main(int argc, char *argv[])
|
||||
if (qtest_has_device("virtio-iommu-pci")) {
|
||||
qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
|
||||
}
|
||||
+ qtest_add_func("acpi/virt/smmuv3-legacy",
|
||||
+ test_acpi_aarch64_virt_smmuv3_legacy);
|
||||
+ if (qtest_has_device("arm-smmuv3")) {
|
||||
+ qtest_add_func("acpi/virt/smmuv3-dev",
|
||||
+ test_acpi_aarch64_virt_smmuv3_dev);
|
||||
+ }
|
||||
}
|
||||
#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
} else if (strcmp(arch, "riscv64") == 0) {
|
||||
295
0048-qtest-bios-tables-test-Update-tables-for-smmuv3-test.patch
Normal file
295
0048-qtest-bios-tables-test-Update-tables-for-smmuv3-test.patch
Normal file
@ -0,0 +1,295 @@
|
||||
From be2f82165c36208d01117404382ad0fee35e4ce0 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Date: Fri, 29 Aug 2025 09:25:33 +0100
|
||||
Subject: [PATCH] qtest/bios-tables-test: Update tables for smmuv3 tests
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 423: hw/arm/virt: Add support for user creatable SMMUv3 device
|
||||
RH-Jira: RHEL-73800
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Donald Dutile <None>
|
||||
RH-Commit: [11/11] 88cb1daec4e92b759f12a96daacd46fc4656eacd (eauger1/centos-qemu-kvm)
|
||||
|
||||
For the legacy smmuv3 test case, generated IORT has a single SMMUv3 node,
|
||||
a Root Complex(RC) node and 1 ITS node.
|
||||
RC node features 4 ID mappings, of which 2 points to SMMU node and the
|
||||
remaining ones points to ITS.
|
||||
|
||||
pcie.0 -> {SMMU0} -> {ITS}
|
||||
{RC} pcie.1 -> {SMMU0} -> {ITS}
|
||||
pcie.2 -> {ITS}
|
||||
[all other ids] -> {ITS}
|
||||
|
||||
...
|
||||
[030h 0048 1] Type : 00
|
||||
[031h 0049 2] Length : 0018
|
||||
[033h 0051 1] Revision : 01
|
||||
[034h 0052 4] Identifier : 00000000
|
||||
[038h 0056 4] Mapping Count : 00000000
|
||||
[03Ch 0060 4] Mapping Offset : 00000000
|
||||
|
||||
[040h 0064 4] ItsCount : 00000001
|
||||
[044h 0068 4] Identifiers : 00000000
|
||||
|
||||
[048h 0072 1] Type : 04
|
||||
[049h 0073 2] Length : 0058
|
||||
[04Bh 0075 1] Revision : 04
|
||||
[04Ch 0076 4] Identifier : 00000001
|
||||
[050h 0080 4] Mapping Count : 00000001
|
||||
[054h 0084 4] Mapping Offset : 00000044
|
||||
|
||||
[058h 0088 8] Base Address : 0000000009050000
|
||||
[060h 0096 4] Flags (decoded below) : 00000001
|
||||
COHACC Override : 1
|
||||
HTTU Override : 0
|
||||
Proximity Domain Valid : 0
|
||||
[064h 0100 4] Reserved : 00000000
|
||||
[068h 0104 8] VATOS Address : 0000000000000000
|
||||
[070h 0112 4] Model : 00000000
|
||||
[074h 0116 4] Event GSIV : 0000006A
|
||||
[078h 0120 4] PRI GSIV : 0000006B
|
||||
[07Ch 0124 4] GERR GSIV : 0000006D
|
||||
[080h 0128 4] Sync GSIV : 0000006C
|
||||
[084h 0132 4] Proximity Domain : 00000000
|
||||
[088h 0136 4] Device ID Mapping Index : 00000000
|
||||
|
||||
[08Ch 0140 4] Input base : 00000000
|
||||
[090h 0144 4] ID Count : 0000FFFF
|
||||
[094h 0148 4] Output Base : 00000000
|
||||
[098h 0152 4] Output Reference : 00000030
|
||||
[09Ch 0156 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[0A0h 0160 1] Type : 02
|
||||
[0A1h 0161 2] Length : 0074
|
||||
[0A3h 0163 1] Revision : 03
|
||||
[0A4h 0164 4] Identifier : 00000002
|
||||
[0A8h 0168 4] Mapping Count : 00000004
|
||||
[0ACh 0172 4] Mapping Offset : 00000024
|
||||
|
||||
[0B0h 0176 8] Memory Properties : [IORT Memory Access Properties]
|
||||
[0B0h 0176 4] Cache Coherency : 00000001
|
||||
[0B4h 0180 1] Hints (decoded below) : 00
|
||||
Transient : 0
|
||||
Write Allocate : 0
|
||||
Read Allocate : 0
|
||||
Override : 0
|
||||
[0B5h 0181 2] Reserved : 0000
|
||||
[0B7h 0183 1] Memory Flags (decoded below) : 03
|
||||
Coherency : 1
|
||||
Device Attribute : 1
|
||||
[0B8h 0184 4] ATS Attribute : 00000000
|
||||
[0BCh 0188 4] PCI Segment Number : 00000000
|
||||
[0C0h 0192 1] Memory Size Limit : 40
|
||||
[0C1h 0193 2] PASID Capabilities : 0000
|
||||
[0C3h 0195 1] Reserved : 00
|
||||
|
||||
[0C4h 0196 4] Input base : 00000000
|
||||
[0C8h 0200 4] ID Count : 000001FF
|
||||
[0CCh 0204 4] Output Base : 00000000
|
||||
[0D0h 0208 4] Output Reference : 00000048
|
||||
[0D4h 0212 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[0D8h 0216 4] Input base : 00001000
|
||||
[0DCh 0220 4] ID Count : 000000FF
|
||||
[0E0h 0224 4] Output Base : 00001000
|
||||
[0E4h 0228 4] Output Reference : 00000048
|
||||
[0E8h 0232 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[0ECh 0236 4] Input base : 00000200
|
||||
[0F0h 0240 4] ID Count : 00000DFF
|
||||
[0F4h 0244 4] Output Base : 00000200
|
||||
[0F8h 0248 4] Output Reference : 00000030
|
||||
[0FCh 0252 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[100h 0256 4] Input base : 00001100
|
||||
[104h 0260 4] ID Count : 0000EEFF
|
||||
[108h 0264 4] Output Base : 00001100
|
||||
[10Ch 0268 4] Output Reference : 00000030
|
||||
[110h 0272 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
For the smmuv3-dev test case, IORT has 2 SMMUV3 nodes,
|
||||
1 RC node and 1 ITS node.
|
||||
RC node features 4 ID mappings. 2 of them target the 2
|
||||
SMMU nodes while the others targets the ITS.
|
||||
|
||||
pcie.0 -> {SMMU0} -> {ITS}
|
||||
{RC} pcie.1 -> {SMMU1} -> {ITS}
|
||||
pcie.2 -> {ITS}
|
||||
[all other ids] -> {ITS}
|
||||
...
|
||||
[030h 0048 1] Type : 00
|
||||
[031h 0049 2] Length : 0018
|
||||
[033h 0051 1] Revision : 01
|
||||
[034h 0052 4] Identifier : 00000000
|
||||
[038h 0056 4] Mapping Count : 00000000
|
||||
[03Ch 0060 4] Mapping Offset : 00000000
|
||||
|
||||
[040h 0064 4] ItsCount : 00000001
|
||||
[044h 0068 4] Identifiers : 00000000
|
||||
|
||||
[048h 0072 1] Type : 04
|
||||
[049h 0073 2] Length : 0058
|
||||
[04Bh 0075 1] Revision : 04
|
||||
[04Ch 0076 4] Identifier : 00000001
|
||||
[050h 0080 4] Mapping Count : 00000001
|
||||
[054h 0084 4] Mapping Offset : 00000044
|
||||
|
||||
[058h 0088 8] Base Address : 000000000C000000
|
||||
[060h 0096 4] Flags (decoded below) : 00000001
|
||||
COHACC Override : 1
|
||||
HTTU Override : 0
|
||||
Proximity Domain Valid : 0
|
||||
[064h 0100 4] Reserved : 00000000
|
||||
[068h 0104 8] VATOS Address : 0000000000000000
|
||||
[070h 0112 4] Model : 00000000
|
||||
[074h 0116 4] Event GSIV : 00000090
|
||||
[078h 0120 4] PRI GSIV : 00000091
|
||||
[07Ch 0124 4] GERR GSIV : 00000093
|
||||
[080h 0128 4] Sync GSIV : 00000092
|
||||
[084h 0132 4] Proximity Domain : 00000000
|
||||
[088h 0136 4] Device ID Mapping Index : 00000000
|
||||
|
||||
[08Ch 0140 4] Input base : 00000000
|
||||
[090h 0144 4] ID Count : 0000FFFF
|
||||
[094h 0148 4] Output Base : 00000000
|
||||
[098h 0152 4] Output Reference : 00000030
|
||||
[09Ch 0156 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[0A0h 0160 1] Type : 04
|
||||
[0A1h 0161 2] Length : 0058
|
||||
[0A3h 0163 1] Revision : 04
|
||||
[0A4h 0164 4] Identifier : 00000002
|
||||
[0A8h 0168 4] Mapping Count : 00000001
|
||||
[0ACh 0172 4] Mapping Offset : 00000044
|
||||
|
||||
[0B0h 0176 8] Base Address : 000000000C020000
|
||||
[0B8h 0184 4] Flags (decoded below) : 00000001
|
||||
COHACC Override : 1
|
||||
HTTU Override : 0
|
||||
Proximity Domain Valid : 0
|
||||
[0BCh 0188 4] Reserved : 00000000
|
||||
[0C0h 0192 8] VATOS Address : 0000000000000000
|
||||
[0C8h 0200 4] Model : 00000000
|
||||
[0CCh 0204 4] Event GSIV : 00000094
|
||||
[0D0h 0208 4] PRI GSIV : 00000095
|
||||
[0D4h 0212 4] GERR GSIV : 00000097
|
||||
[0D8h 0216 4] Sync GSIV : 00000096
|
||||
[0DCh 0220 4] Proximity Domain : 00000000
|
||||
[0E0h 0224 4] Device ID Mapping Index : 00000000
|
||||
|
||||
[0E4h 0228 4] Input base : 00000000
|
||||
[0E8h 0232 4] ID Count : 0000FFFF
|
||||
[0ECh 0236 4] Output Base : 00000000
|
||||
[0F0h 0240 4] Output Reference : 00000030
|
||||
[0F4h 0244 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[0F8h 0248 1] Type : 02
|
||||
[0F9h 0249 2] Length : 0074
|
||||
[0FBh 0251 1] Revision : 03
|
||||
[0FCh 0252 4] Identifier : 00000003
|
||||
[100h 0256 4] Mapping Count : 00000004
|
||||
[104h 0260 4] Mapping Offset : 00000024
|
||||
|
||||
[108h 0264 8] Memory Properties : [IORT Memory Access Properties]
|
||||
[108h 0264 4] Cache Coherency : 00000001
|
||||
[10Ch 0268 1] Hints (decoded below) : 00
|
||||
Transient : 0
|
||||
Write Allocate : 0
|
||||
Read Allocate : 0
|
||||
Override : 0
|
||||
[10Dh 0269 2] Reserved : 0000
|
||||
[10Fh 0271 1] Memory Flags (decoded below) : 03
|
||||
Coherency : 1
|
||||
Device Attribute : 1
|
||||
[110h 0272 4] ATS Attribute : 00000000
|
||||
[114h 0276 4] PCI Segment Number : 00000000
|
||||
[118h 0280 1] Memory Size Limit : 40
|
||||
[119h 0281 2] PASID Capabilities : 0000
|
||||
[11Bh 0283 1] Reserved : 00
|
||||
|
||||
[11Ch 0284 4] Input base : 00000000
|
||||
[120h 0288 4] ID Count : 000001FF
|
||||
[124h 0292 4] Output Base : 00000000
|
||||
[128h 0296 4] Output Reference : 00000048
|
||||
[12Ch 0300 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[130h 0304 4] Input base : 00001000
|
||||
[134h 0308 4] ID Count : 000000FF
|
||||
[138h 0312 4] Output Base : 00001000
|
||||
[13Ch 0316 4] Output Reference : 000000A0
|
||||
[140h 0320 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[144h 0324 4] Input base : 00000200
|
||||
[148h 0328 4] ID Count : 00000DFF
|
||||
[14Ch 0332 4] Output Base : 00000200
|
||||
[150h 0336 4] Output Reference : 00000030
|
||||
[154h 0340 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
[158h 0344 4] Input base : 00001100
|
||||
[15Ch 0348 4] ID Count : 0000EEFF
|
||||
[160h 0352 4] Output Base : 00001100
|
||||
[164h 0356 4] Output Reference : 00000030
|
||||
[168h 0360 4] Flags (decoded below) : 00000000
|
||||
Single Mapping : 0
|
||||
|
||||
Note: DSDT changes are not described here as it is not impacted by the
|
||||
way the SMMUv3 is instantiated.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
|
||||
Reviewed-by: Donald Dutile <ddutile@redhat.com>
|
||||
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Message-id: 20250829082543.7680-12-skolothumtho@nvidia.com
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit d35146a6606cf6ebb4e24bb97dfc0330f074f6e3)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
|
||||
Patch-name: kvm-qtest-bios-tables-test-Update-tables-for-smmuv3-test.patch
|
||||
Patch-id: 51
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev | Bin 0 -> 10230 bytes
|
||||
tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy | Bin 0 -> 10230 bytes
|
||||
tests/data/acpi/aarch64/virt/IORT.smmuv3-dev | Bin 0 -> 364 bytes
|
||||
tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy | Bin 0 -> 276 bytes
|
||||
tests/qtest/bios-tables-test-allowed-diff.h | 4 ----
|
||||
5 files changed, 4 deletions(-)
|
||||
|
||||
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev
|
||||
index e69de29bb2..53d4c07f42 100644
|
||||
Binary files a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev and b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev differ
|
||||
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy
|
||||
index e69de29bb2..53d4c07f42 100644
|
||||
Binary files a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy and b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy differ
|
||||
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev b/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev
|
||||
index e69de29bb2..67be268f62 100644
|
||||
Binary files a/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev and b/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev differ
|
||||
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy
|
||||
index e69de29bb2..41981a449f 100644
|
||||
Binary files a/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy and b/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy differ
|
||||
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
index 2e3e3ccdce..dfb8523c8b 100644
|
||||
--- a/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
|
||||
@@ -1,5 +1 @@
|
||||
/* List of comma-separated changed AML files to ignore */
|
||||
-"tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy",
|
||||
-"tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev",
|
||||
-"tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy",
|
||||
-"tests/data/acpi/aarch64/virt/IORT.smmuv3-dev",
|
||||
31
0049-qtest-Do-not-run-bios-tables-test-on-aarch64.patch
Normal file
31
0049-qtest-Do-not-run-bios-tables-test-on-aarch64.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 010f0f393976a1422f16a7252d6fcd986671b8d7 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 14 Nov 2025 06:46:07 +0100
|
||||
Subject: [PATCH] qtest: Do not run bios-tables-test on aarch64
|
||||
|
||||
We do several disruptive downstream only changes that make
|
||||
bios-tables-test to fail. Disabling it for now.
|
||||
|
||||
This is done to enable fixing RHEL-126573 and RHEL-67323.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
|
||||
Patch-name: kvm-qtest-Do-not-run-bios-tables-test-on-aarch64.patch
|
||||
Patch-id: 52
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
tests/qtest/meson.build | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
|
||||
index ef44ffaf78..13b52ea41a 100644
|
||||
--- a/tests/qtest/meson.build
|
||||
+++ b/tests/qtest/meson.build
|
||||
@@ -252,7 +252,6 @@ qtests_arm = \
|
||||
|
||||
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
|
||||
qtests_aarch64 = \
|
||||
- (cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) + \
|
||||
(config_all_accel.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? \
|
||||
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
|
||||
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
|
||||
126
0050-ram-block-attributes-fix-interaction-with-hugetlb-me.patch
Normal file
126
0050-ram-block-attributes-fix-interaction-with-hugetlb-me.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 1e83cccb197114db68fa625c40f396ee159bb3a2 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Wed, 19 Nov 2025 12:51:32 +0100
|
||||
Subject: [PATCH] ram-block-attributes: fix interaction with hugetlb memory
|
||||
backends
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 426: Fix hugetlb memory backends in confidential VMs
|
||||
RH-Jira: RHEL-126708
|
||||
RH-Acked-by: Bandan Das <bdas@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Acked-by: Peter Xu <peterx@redhat.com>
|
||||
RH-Commit: [1/2] 050a6c78989db4ba3111fb903647270c7ab12e53 (bonzini/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-126708
|
||||
|
||||
Currently, CoCo VMs can perform conversion at the base page granularity,
|
||||
which is the granularity that has to be tracked. In relevant setups, the
|
||||
target page size is assumed to be equal to the host page size, thus
|
||||
fixing the block size to the host page size.
|
||||
|
||||
However, since private memory and shared memory have different backend
|
||||
at present, users can specify shared memory with a hugetlbfs backend
|
||||
while private memory with guest_memfd backend only supports 4K page
|
||||
size. In this scenario, ram_block->page_size is different from the host
|
||||
page size which will trigger an assertion when retrieving the block
|
||||
size.
|
||||
|
||||
To address this, return the host page size directly to relax the
|
||||
restriction. This changes fixes a regression of using hugetlbfs backend
|
||||
for shared memory within CoCo VMs, with or without VFIO devices' presence.
|
||||
|
||||
Acked-by: David Hildenbrand <david@redhat.com>
|
||||
Tested-by: Farrah Chen <farrah.chen@intel.com>
|
||||
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251023095526.48365-2-chenyi.qiang@intel.com
|
||||
[peterx: fix subject, per david]
|
||||
Cc: qemu-stable <qemu-stable@nongnu.org>
|
||||
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||
(cherry picked from commit 8922a758b29251d9009ec509e7f580b76509ab3d)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-ram-block-attributes-fix-interaction-with-hugetlb-me.patch
|
||||
Patch-id: 53
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
system/ram-block-attributes.c | 18 ++++++++----------
|
||||
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c
|
||||
index 68e8a02703..a7579de5b4 100644
|
||||
--- a/system/ram-block-attributes.c
|
||||
+++ b/system/ram-block-attributes.c
|
||||
@@ -22,16 +22,14 @@ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RamBlockAttributes,
|
||||
{ })
|
||||
|
||||
static size_t
|
||||
-ram_block_attributes_get_block_size(const RamBlockAttributes *attr)
|
||||
+ram_block_attributes_get_block_size(void)
|
||||
{
|
||||
/*
|
||||
* Because page conversion could be manipulated in the size of at least 4K
|
||||
* or 4K aligned, Use the host page size as the granularity to track the
|
||||
* memory attribute.
|
||||
*/
|
||||
- g_assert(attr && attr->ram_block);
|
||||
- g_assert(attr->ram_block->page_size == qemu_real_host_page_size());
|
||||
- return attr->ram_block->page_size;
|
||||
+ return qemu_real_host_page_size();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +38,7 @@ ram_block_attributes_rdm_is_populated(const RamDiscardManager *rdm,
|
||||
const MemoryRegionSection *section)
|
||||
{
|
||||
const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm);
|
||||
- const size_t block_size = ram_block_attributes_get_block_size(attr);
|
||||
+ const size_t block_size = ram_block_attributes_get_block_size();
|
||||
const uint64_t first_bit = section->offset_within_region / block_size;
|
||||
const uint64_t last_bit =
|
||||
first_bit + int128_get64(section->size) / block_size - 1;
|
||||
@@ -81,7 +79,7 @@ ram_block_attributes_for_each_populated_section(const RamBlockAttributes *attr,
|
||||
{
|
||||
unsigned long first_bit, last_bit;
|
||||
uint64_t offset, size;
|
||||
- const size_t block_size = ram_block_attributes_get_block_size(attr);
|
||||
+ const size_t block_size = ram_block_attributes_get_block_size();
|
||||
int ret = 0;
|
||||
|
||||
first_bit = section->offset_within_region / block_size;
|
||||
@@ -122,7 +120,7 @@ ram_block_attributes_for_each_discarded_section(const RamBlockAttributes *attr,
|
||||
{
|
||||
unsigned long first_bit, last_bit;
|
||||
uint64_t offset, size;
|
||||
- const size_t block_size = ram_block_attributes_get_block_size(attr);
|
||||
+ const size_t block_size = ram_block_attributes_get_block_size();
|
||||
int ret = 0;
|
||||
|
||||
first_bit = section->offset_within_region / block_size;
|
||||
@@ -163,7 +161,7 @@ ram_block_attributes_rdm_get_min_granularity(const RamDiscardManager *rdm,
|
||||
const RamBlockAttributes *attr = RAM_BLOCK_ATTRIBUTES(rdm);
|
||||
|
||||
g_assert(mr == attr->ram_block->mr);
|
||||
- return ram_block_attributes_get_block_size(attr);
|
||||
+ return ram_block_attributes_get_block_size();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -265,7 +263,7 @@ ram_block_attributes_is_valid_range(RamBlockAttributes *attr, uint64_t offset,
|
||||
g_assert(mr);
|
||||
|
||||
uint64_t region_size = memory_region_size(mr);
|
||||
- const size_t block_size = ram_block_attributes_get_block_size(attr);
|
||||
+ const size_t block_size = ram_block_attributes_get_block_size();
|
||||
|
||||
if (!QEMU_IS_ALIGNED(offset, block_size) ||
|
||||
!QEMU_IS_ALIGNED(size, block_size)) {
|
||||
@@ -322,7 +320,7 @@ int ram_block_attributes_state_change(RamBlockAttributes *attr,
|
||||
uint64_t offset, uint64_t size,
|
||||
bool to_discard)
|
||||
{
|
||||
- const size_t block_size = ram_block_attributes_get_block_size(attr);
|
||||
+ const size_t block_size = ram_block_attributes_get_block_size();
|
||||
const unsigned long first_bit = offset / block_size;
|
||||
const unsigned long nbits = size / block_size;
|
||||
const unsigned long last_bit = first_bit + nbits - 1;
|
||||
@ -0,0 +1,47 @@
|
||||
From 5752a9e1aeb36ba0819cce747a15ec74eb8b8d98 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Wed, 19 Nov 2025 12:51:32 +0100
|
||||
Subject: [PATCH] ram-block-attributes: Unify the retrieval of the block size
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 426: Fix hugetlb memory backends in confidential VMs
|
||||
RH-Jira: RHEL-126708
|
||||
RH-Acked-by: Bandan Das <bdas@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Acked-by: Peter Xu <peterx@redhat.com>
|
||||
RH-Commit: [2/2] 0d6f2045a97f04348c4d07ef331e42f47eaba160 (bonzini/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-126708
|
||||
|
||||
There's an existing helper function designed to obtain the block size.
|
||||
Modify ram_block_attribute_create() to use this function for
|
||||
consistency.
|
||||
|
||||
Tested-by: Farrah Chen <farrah.chen@intel.com>
|
||||
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
|
||||
Link: https://lore.kernel.org/r/20251023095526.48365-3-chenyi.qiang@intel.com
|
||||
[peterx: fix double spaces, per david]
|
||||
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||
(cherry picked from commit b2ceb87b1a210d91a29d525590eb164d1121b8a1)
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-ram-block-attributes-Unify-the-retrieval-of-the-bloc.patch
|
||||
Patch-id: 54
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
system/ram-block-attributes.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/system/ram-block-attributes.c b/system/ram-block-attributes.c
|
||||
index a7579de5b4..fb7c5c2746 100644
|
||||
--- a/system/ram-block-attributes.c
|
||||
+++ b/system/ram-block-attributes.c
|
||||
@@ -390,7 +390,7 @@ int ram_block_attributes_state_change(RamBlockAttributes *attr,
|
||||
|
||||
RamBlockAttributes *ram_block_attributes_create(RAMBlock *ram_block)
|
||||
{
|
||||
- const int block_size = qemu_real_host_page_size();
|
||||
+ const int block_size = ram_block_attributes_get_block_size();
|
||||
RamBlockAttributes *attr;
|
||||
MemoryRegion *mr = ram_block->mr;
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
From cd7ee8d8043415d89a80a6e75c2d58afae270038 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Tue, 18 Nov 2025 18:40:47 +0100
|
||||
Subject: [PATCH] hw/s390x: Fix a possible crash with passed-through virtio
|
||||
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: 427: s390x: Fix a possible crash with passed-through virtio devices
|
||||
RH-Jira: RHEL-128085
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Commit: [1/1] a368a65a46a8d85f7ae83cfb5af23b1a341ea9d4 (thuth/qemu-kvm-cs)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-128085
|
||||
|
||||
Consider the following nested setup: An L1 host uses some virtio device
|
||||
(e.g. virtio-keyboard) for the L2 guest, and this L2 guest passes this
|
||||
device through to the L3 guest. Since the L3 guest sees a virtio device,
|
||||
it might send virtio notifications to the QEMU in L2 for that device.
|
||||
But since the QEMU in L2 defined this device as vfio-ccw, the function
|
||||
handle_virtio_ccw_notify() cannot handle this and crashes: It calls
|
||||
virtio_ccw_get_vdev() that casts sch->driver_data into a VirtioCcwDevice,
|
||||
but since "sch" belongs to a vfio-ccw device, that driver_data rather
|
||||
points to a CcwDevice instead. So as soon as QEMU tries to use some
|
||||
VirtioCcwDevice specific data from that device, we've lost.
|
||||
|
||||
We must not take virtio notifications for such devices. Thus fix the
|
||||
issue by adding a check to the handle_virtio_ccw_notify() handler to
|
||||
refuse all devices that are not our own virtio devices. Like in the
|
||||
other branches that detect wrong settings, we return -EINVAL from the
|
||||
function, which will later be placed in GPR2 to inform the guest about
|
||||
the error.
|
||||
|
||||
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Tested-by: Eric Farman <farman@linux.ibm.com>
|
||||
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
|
||||
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-ID: <20251118174047.73103-1-thuth@redhat.com>
|
||||
(cherry picked from commit e5cb62e7b6f99d45a42f0cd358d76d6ee2cef5cd)
|
||||
|
||||
Patch-name: kvm-hw-s390x-Fix-a-possible-crash-with-passed-through-vi.patch
|
||||
Patch-id: 55
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/s390x/s390-hypercall.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/hw/s390x/s390-hypercall.c b/hw/s390x/s390-hypercall.c
|
||||
index ac1b08b2cd..508dd97ca0 100644
|
||||
--- a/hw/s390x/s390-hypercall.c
|
||||
+++ b/hw/s390x/s390-hypercall.c
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
+#include "qemu/error-report.h"
|
||||
#include "cpu.h"
|
||||
#include "hw/s390x/s390-virtio-ccw.h"
|
||||
#include "hw/s390x/s390-hypercall.h"
|
||||
@@ -42,6 +43,19 @@ static int handle_virtio_ccw_notify(uint64_t subch_id, uint64_t data)
|
||||
if (!sch || !css_subch_visible(sch)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
+ if (sch->id.cu_type != VIRTIO_CCW_CU_TYPE) {
|
||||
+ /*
|
||||
+ * This might happen in nested setups: If the L1 host defined the
|
||||
+ * L2 guest with a virtio device (e.g. virtio-keyboard), and the
|
||||
+ * L2 guest passes this device through to the L3 guest, the L3 guest
|
||||
+ * might send virtio notifications to the QEMU in L2 for that device.
|
||||
+ * But since the QEMU in L2 defined this device as vfio-ccw, it's not
|
||||
+ * a VirtIODevice that we can handle here!
|
||||
+ */
|
||||
+ warn_report_once("Got virtio notification for unsupported device "
|
||||
+ "on subchannel %02x.%1x.%04x!", cssid, ssid, schid);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
vdev = virtio_ccw_get_vdev(sch);
|
||||
if (vq_idx >= VIRTIO_QUEUE_MAX || !virtio_queue_get_num(vdev, vq_idx)) {
|
||||
@ -0,0 +1,38 @@
|
||||
From eaa84431d740547a719a11020feda8ae0ef8834a Mon Sep 17 00:00:00 2001
|
||||
From: Yanghang Liu <yanghliu@redhat.com>
|
||||
Date: Mon, 24 Nov 2025 23:02:37 +0800
|
||||
Subject: [PATCH] Fix the typo of vfio-pci device's enable-migration option
|
||||
|
||||
RH-Author: YangHang Liu <None>
|
||||
RH-MergeRequest: 428: RHEL10: Fix the typo of vfio-pci device's enable-migration option
|
||||
RH-Jira: RHEL-130704
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] bcf8b2089f687d02b5f0a48dd1e3dfc4664946e0 (yanghliu/qemu-kvm)
|
||||
|
||||
Signed-off-by: Yanghang Liu <yanghliu@redhat.com>
|
||||
Reported-by: Mario Casquero <mcasquer@redhat.com>
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
(cherry picked from commit 5f9ac963735598c1efbdce9c4a09f0a64e13d613)
|
||||
Signed-off-by: Yanghang Liu <yanghliu@redhat.com>
|
||||
|
||||
Patch-name: kvm-Fix-the-typo-of-vfio-pci-device-s-enable-migration-o.patch
|
||||
Patch-id: 56
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/vfio/pci.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index 83ecffb535..7c057ee2f9 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -3847,7 +3847,7 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, const void *data)
|
||||
"(DEBUG)");
|
||||
object_class_property_set_description(klass, /* 5.2, 8.0 non-experimetal */
|
||||
"enable-migration",
|
||||
- "Enale device migration. Also requires a host VFIO PCI "
|
||||
+ "Enable device migration. Also requires a host VFIO PCI "
|
||||
"variant or mdev driver with migration support enabled");
|
||||
object_class_property_set_description(klass, /* 8.1 */
|
||||
"vf-token",
|
||||
178
0054-pcie_sriov-Fix-broken-MMIO-accesses-from-SR-IOV-VFs.patch
Normal file
178
0054-pcie_sriov-Fix-broken-MMIO-accesses-from-SR-IOV-VFs.patch
Normal file
@ -0,0 +1,178 @@
|
||||
From 4bf5116601e58a07863c88426ab408dcc26e0331 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Bergamini <damien.bergamini@eviden.com>
|
||||
Date: Mon, 1 Sep 2025 15:14:23 +0000
|
||||
Subject: [PATCH] pcie_sriov: Fix broken MMIO accesses from SR-IOV VFs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Laurent Vivier <lvivier@redhat.com>
|
||||
RH-MergeRequest: 431: pcie_sriov: Fix broken MMIO accesses from SR-IOV VFs
|
||||
RH-Jira: RHEL-120115
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Commit: [1/1] b6bb40d37376db589852cb07a915d6f0eae29f67 (lvivier/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-120115
|
||||
|
||||
Starting with commit cab1398a60eb, SR-IOV VFs are realized as soon as
|
||||
pcie_sriov_pf_init() is called. Because pcie_sriov_pf_init() must be
|
||||
called before pcie_sriov_pf_init_vf_bar(), the VF BARs types won't be
|
||||
known when the VF realize function calls pcie_sriov_vf_register_bar().
|
||||
|
||||
This breaks the memory regions of the VFs (for instance with igbvf):
|
||||
|
||||
$ lspci
|
||||
...
|
||||
Region 0: Memory at 281a00000 (64-bit, prefetchable) [virtual] [size=16K]
|
||||
Region 3: Memory at 281a20000 (64-bit, prefetchable) [virtual] [size=16K]
|
||||
|
||||
$ info mtree
|
||||
...
|
||||
address-space: pci_bridge_pci_mem
|
||||
0000000000000000-ffffffffffffffff (prio 0, i/o): pci_bridge_pci
|
||||
0000000081a00000-0000000081a03fff (prio 1, i/o): igbvf-mmio
|
||||
0000000081a20000-0000000081a23fff (prio 1, i/o): igbvf-msix
|
||||
|
||||
and causes MMIO accesses to fail:
|
||||
|
||||
Invalid write at addr 0x281A01520, size 4, region '(null)', reason: rejected
|
||||
Invalid read at addr 0x281A00C40, size 4, region '(null)', reason: rejected
|
||||
|
||||
To fix this, VF BARs are now registered with pci_register_bar() which
|
||||
has a type parameter and pcie_sriov_vf_register_bar() is removed.
|
||||
|
||||
Fixes: cab1398a60eb ("pcie_sriov: Reuse SR-IOV VF device instances")
|
||||
Signed-off-by: Damien Bergamini <damien.bergamini@eviden.com>
|
||||
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
|
||||
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Message-ID: <20250901151314.1038020-1-clement.mathieu--drif@eviden.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry picked from commit 2e54e5fda779a7ba45578884276dca62462f7a06)
|
||||
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
||||
|
||||
Patch-name: kvm-pcie_sriov-Fix-broken-MMIO-accesses-from-SR-IOV-VFs.patch
|
||||
Patch-id: 57
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
docs/pcie_sriov.txt | 5 ++---
|
||||
hw/net/igbvf.c | 6 ++++--
|
||||
hw/nvme/ctrl.c | 8 ++------
|
||||
hw/pci/pci.c | 3 ---
|
||||
hw/pci/pcie_sriov.c | 11 -----------
|
||||
include/hw/pci/pcie_sriov.h | 4 ----
|
||||
6 files changed, 8 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/docs/pcie_sriov.txt b/docs/pcie_sriov.txt
|
||||
index ab2142807f..00d7bd93fd 100644
|
||||
--- a/docs/pcie_sriov.txt
|
||||
+++ b/docs/pcie_sriov.txt
|
||||
@@ -72,8 +72,7 @@ setting up a BAR for a VF.
|
||||
2) Similarly in the implementation of the virtual function, you need to
|
||||
make it a PCI Express device and add a similar set of capabilities
|
||||
except for the SR/IOV capability. Then you need to set up the VF BARs as
|
||||
- subregions of the PFs SR/IOV VF BARs by calling
|
||||
- pcie_sriov_vf_register_bar() instead of the normal pci_register_bar() call:
|
||||
+ subregions of the PFs SR/IOV VF BARs by calling pci_register_bar():
|
||||
|
||||
pci_your_vf_dev_realize( ... )
|
||||
{
|
||||
@@ -83,7 +82,7 @@ setting up a BAR for a VF.
|
||||
pcie_ari_init(d, 0x100);
|
||||
...
|
||||
memory_region_init(mr, ... )
|
||||
- pcie_sriov_vf_register_bar(d, bar_nr, mr);
|
||||
+ pci_register_bar(d, bar_nr, bar_type, mr);
|
||||
...
|
||||
}
|
||||
|
||||
diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c
|
||||
index 31d72c4977..9b0db8f841 100644
|
||||
--- a/hw/net/igbvf.c
|
||||
+++ b/hw/net/igbvf.c
|
||||
@@ -251,10 +251,12 @@ static void igbvf_pci_realize(PCIDevice *dev, Error **errp)
|
||||
|
||||
memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio",
|
||||
IGBVF_MMIO_SIZE);
|
||||
- pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio);
|
||||
+ pci_register_bar(dev, IGBVF_MMIO_BAR_IDX, PCI_BASE_ADDRESS_MEM_TYPE_64 |
|
||||
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio);
|
||||
|
||||
memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZE);
|
||||
- pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix);
|
||||
+ pci_register_bar(dev, IGBVF_MSIX_BAR_IDX, PCI_BASE_ADDRESS_MEM_TYPE_64 |
|
||||
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &s->msix);
|
||||
|
||||
ret = msix_init(dev, IGBVF_MSIX_VEC_NUM, &s->msix, IGBVF_MSIX_BAR_IDX, 0,
|
||||
&s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp);
|
||||
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
|
||||
index f5ee6bf260..cd81f73997 100644
|
||||
--- a/hw/nvme/ctrl.c
|
||||
+++ b/hw/nvme/ctrl.c
|
||||
@@ -8708,12 +8708,8 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
|
||||
msix_table_offset);
|
||||
memory_region_add_subregion(&n->bar0, 0, &n->iomem);
|
||||
|
||||
- if (pci_is_vf(pci_dev)) {
|
||||
- pcie_sriov_vf_register_bar(pci_dev, 0, &n->bar0);
|
||||
- } else {
|
||||
- pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
- PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
|
||||
- }
|
||||
+ pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
+ PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
|
||||
|
||||
ret = msix_init(pci_dev, nr_vectors,
|
||||
&n->bar0, 0, msix_table_offset,
|
||||
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
|
||||
index 0012cc12e7..d2ebb066e1 100644
|
||||
--- a/hw/pci/pci.c
|
||||
+++ b/hw/pci/pci.c
|
||||
@@ -1490,9 +1490,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
|
||||
: pci_get_bus(pci_dev)->address_space_mem;
|
||||
|
||||
if (pci_is_vf(pci_dev)) {
|
||||
- PCIDevice *pf = pci_dev->exp.sriov_vf.pf;
|
||||
- assert(!pf || type == pf->exp.sriov_pf.vf_bar_type[region_num]);
|
||||
-
|
||||
r->addr = pci_bar_address(pci_dev, region_num, r->type, r->size);
|
||||
if (r->addr != PCI_BAR_UNMAPPED) {
|
||||
memory_region_add_subregion_overlap(r->address_space,
|
||||
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
|
||||
index cf1b5b5c05..c4f88f0975 100644
|
||||
--- a/hw/pci/pcie_sriov.c
|
||||
+++ b/hw/pci/pcie_sriov.c
|
||||
@@ -246,17 +246,6 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
|
||||
dev->exp.sriov_pf.vf_bar_type[region_num] = type;
|
||||
}
|
||||
|
||||
-void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
|
||||
- MemoryRegion *memory)
|
||||
-{
|
||||
- uint8_t type;
|
||||
-
|
||||
- assert(dev->exp.sriov_vf.pf);
|
||||
- type = dev->exp.sriov_vf.pf->exp.sriov_pf.vf_bar_type[region_num];
|
||||
-
|
||||
- return pci_register_bar(dev, region_num, type, memory);
|
||||
-}
|
||||
-
|
||||
static gint compare_vf_devfns(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return (*(PCIDevice **)a)->devfn - (*(PCIDevice **)b)->devfn;
|
||||
diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h
|
||||
index aeaa38cf34..b0ea6a62c7 100644
|
||||
--- a/include/hw/pci/pcie_sriov.h
|
||||
+++ b/include/hw/pci/pcie_sriov.h
|
||||
@@ -37,10 +37,6 @@ void pcie_sriov_pf_exit(PCIDevice *dev);
|
||||
void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
|
||||
uint8_t type, dma_addr_t size);
|
||||
|
||||
-/* Instantiate a bar for a VF */
|
||||
-void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
|
||||
- MemoryRegion *memory);
|
||||
-
|
||||
/**
|
||||
* pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
|
||||
* VFs, adding ARI to PF
|
||||
45
0055-arm-fix-oob-access-in-compat-handling.patch
Normal file
45
0055-arm-fix-oob-access-in-compat-handling.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From fa0a758781fc63888c9af9a585928217fd07c140 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Tue, 25 Nov 2025 09:19:30 +0100
|
||||
Subject: [PATCH] arm: fix oob access in compat handling
|
||||
|
||||
RH-Author: Sebastian Ott <sebott@redhat.com>
|
||||
RH-MergeRequest: 430: arm: fix oob access in compat handling
|
||||
RH-Jira: RHEL-130478
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Commit: [1/1] 5d6ab0821b0ffce732862969f275aa50f6917bf1 (seott1/cos-qemu-kvm)
|
||||
|
||||
Upstream: RHEL only
|
||||
Fixes: 58cba97a "hw/arm/virt: Use ACPI PCI hotplug by default from 10.2 onwards"
|
||||
|
||||
Due to incorrect length information arm_acpi_pci_hp_disabled_compat[]
|
||||
was accessed out of bounds. This led to the weird side effect that the
|
||||
1st member of arm_rhel9_compat[] was applied to the virt-rhel10.0
|
||||
machine type causing migration failures. Fix the length.
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
|
||||
Patch-name: kvm-arm-fix-oob-access-in-compat-handling.patch
|
||||
Patch-id: 58
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/arm/virt.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index e8e64fe7fe..1cfb386f64 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -102,7 +102,8 @@ static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
GlobalProperty arm_acpi_pci_hp_disabled_compat[] = {
|
||||
{ TYPE_ACPI_GED, "acpi-pci-hotplug-with-bridge-support", "off" },
|
||||
};
|
||||
-static const size_t arm_acpi_pci_hp_disabled_compat_len = G_N_ELEMENTS(arm_virt_compat);
|
||||
+static const size_t arm_acpi_pci_hp_disabled_compat_len =
|
||||
+ G_N_ELEMENTS(arm_acpi_pci_hp_disabled_compat);
|
||||
|
||||
/*
|
||||
* RHEL9 kernels have pauth disabled while RHEL10 has it enabled,
|
||||
@ -0,0 +1,74 @@
|
||||
From bd02d862e6cdce44a5bf0052db5bf3e6f599934d Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Wed, 19 Nov 2025 18:27:20 +0100
|
||||
Subject: [PATCH] block-backend: Fix race when resuming queued requests
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 432: block-backend: Fix race when resuming queued requests [c10s]
|
||||
RH-Jira: RHEL-129540
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [1/1] fa7ead79ae44d89054ed574deb3fbd196536fef3 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
When new requests arrive at a BlockBackend that is currently drained,
|
||||
these requests are queued until the drain section ends.
|
||||
|
||||
There is a race window between blk_root_drained_end() waking up a queued
|
||||
request in an iothread from the main thread and blk_wait_while_drained()
|
||||
actually being woken up in the iothread and calling blk_inc_in_flight().
|
||||
If the BlockBackend is drained again during this window, drain won't
|
||||
wait for this request and it will sneak in when the BlockBackend is
|
||||
already supposed to be quiesced. This causes assertion failures in
|
||||
bdrv_drain_all_begin() and can have other unintended consequences.
|
||||
|
||||
Fix this by increasing the in_flight counter immediately when scheduling
|
||||
the request to be resumed so that the next drain will wait for it to
|
||||
complete.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reported-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20251119172720.135424-1-kwolf@redhat.com>
|
||||
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Tested-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
|
||||
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 8eeaa706ba73251063cb80d87ae838d2d5b08e9a)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-block-backend-Fix-race-when-resuming-queued-requests.patch
|
||||
Patch-id: 59
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
block/block-backend.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/block/block-backend.c b/block/block-backend.c
|
||||
index f8d6ba65c1..d6df369188 100644
|
||||
--- a/block/block-backend.c
|
||||
+++ b/block/block-backend.c
|
||||
@@ -1318,9 +1318,9 @@ static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
|
||||
* section.
|
||||
*/
|
||||
qemu_mutex_lock(&blk->queued_requests_lock);
|
||||
+ /* blk_root_drained_end() has the corresponding blk_inc_in_flight() */
|
||||
blk_dec_in_flight(blk);
|
||||
qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
|
||||
- blk_inc_in_flight(blk);
|
||||
qemu_mutex_unlock(&blk->queued_requests_lock);
|
||||
}
|
||||
}
|
||||
@@ -2767,9 +2767,11 @@ static void blk_root_drained_end(BdrvChild *child)
|
||||
blk->dev_ops->drained_end(blk->dev_opaque);
|
||||
}
|
||||
qemu_mutex_lock(&blk->queued_requests_lock);
|
||||
- while (qemu_co_enter_next(&blk->queued_requests,
|
||||
- &blk->queued_requests_lock)) {
|
||||
+ while (!qemu_co_queue_empty(&blk->queued_requests)) {
|
||||
/* Resume all queued requests */
|
||||
+ blk_inc_in_flight(blk);
|
||||
+ qemu_co_enter_next(&blk->queued_requests,
|
||||
+ &blk->queued_requests_lock);
|
||||
}
|
||||
qemu_mutex_unlock(&blk->queued_requests_lock);
|
||||
}
|
||||
123
0057-file-posix-Handle-suspended-dm-multipath-better-for-.patch
Normal file
123
0057-file-posix-Handle-suspended-dm-multipath-better-for-.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 0078d9aa02c830ca38a68a1e5b794227c6542c3c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 28 Nov 2025 23:14:40 +0100
|
||||
Subject: [PATCH] file-posix: Handle suspended dm-multipath better for SG_IO
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 436: file-posix: Handle suspended dm-multipath better for SG_IO
|
||||
RH-Jira: RHEL-121543
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [1/1] f90d36aba5b374dcb9d5986f968c2dbde4bdd18d (kmwolf/centos-qemu-kvm)
|
||||
|
||||
When introducing DM_MPATH_PROBE_PATHS, we already anticipated that
|
||||
dm-multipath devices might be suspended for a short time when the DM
|
||||
tables are reloaded and that they return -EAGAIN in this case. We then
|
||||
wait for a millisecond and retry.
|
||||
|
||||
However, meanwhile it has also turned out that libmpathpersist (which is
|
||||
used by qemu-pr-helper) may need to perform more complex recovery
|
||||
operations to get reservations back to expected state if a path failure
|
||||
happened in the middle of a PR operation. In this case, the device is
|
||||
suspended for a longer time compared to the case we originally expected.
|
||||
|
||||
This patch changes hdev_co_ioctl() to treat -EAGAIN separately so that
|
||||
it doesn't result in an immediate failure if the device is suspended for
|
||||
more than 1ms, and moves to incremental backoff to cover both quick and
|
||||
slow cases without excessive delays.
|
||||
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-121543
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20251128221440.89125-1-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 2c3165a1a61c299b4a3ae30899e1cc738d20e004)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-file-posix-Handle-suspended-dm-multipath-better-for-.patch
|
||||
Patch-id: 60
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
block/file-posix.c | 56 ++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 34 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||
index cb2e94d7db..ffca37130b 100644
|
||||
--- a/block/file-posix.c
|
||||
+++ b/block/file-posix.c
|
||||
@@ -4289,25 +4289,8 @@ hdev_open_Mac_error:
|
||||
static bool coroutine_fn sgio_path_error(int ret, sg_io_hdr_t *io_hdr)
|
||||
{
|
||||
if (ret < 0) {
|
||||
- switch (ret) {
|
||||
- case -ENODEV:
|
||||
- return true;
|
||||
- case -EAGAIN:
|
||||
- /*
|
||||
- * The device is probably suspended. This happens while the dm table
|
||||
- * is reloaded, e.g. because a path is added or removed. This is an
|
||||
- * operation that should complete within 1ms, so just wait a bit and
|
||||
- * retry.
|
||||
- *
|
||||
- * If the device was suspended for another reason, we'll wait and
|
||||
- * retry SG_IO_MAX_RETRIES times. This is a tolerable delay before
|
||||
- * we return an error and potentially stop the VM.
|
||||
- */
|
||||
- qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000);
|
||||
- return true;
|
||||
- default:
|
||||
- return false;
|
||||
- }
|
||||
+ /* Path errors sometimes result in -ENODEV */
|
||||
+ return ret == -ENODEV;
|
||||
}
|
||||
|
||||
if (io_hdr->host_status != SCSI_HOST_OK) {
|
||||
@@ -4376,6 +4359,7 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
RawPosixAIOData acb;
|
||||
+ uint64_t eagain_sleep_ns = 1 * SCALE_MS;
|
||||
int retries = SG_IO_MAX_RETRIES;
|
||||
int ret;
|
||||
|
||||
@@ -4404,9 +4388,37 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
},
|
||||
};
|
||||
|
||||
- do {
|
||||
- ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
|
||||
- } while (req == SG_IO && retries-- && hdev_co_ioctl_sgio_retry(&acb, ret));
|
||||
+retry:
|
||||
+ ret = raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
|
||||
+ if (req == SG_IO && s->use_mpath) {
|
||||
+ if (ret == -EAGAIN && eagain_sleep_ns < NANOSECONDS_PER_SECOND) {
|
||||
+ /*
|
||||
+ * If this is a multipath device, it is probably suspended.
|
||||
+ *
|
||||
+ * This can happen while the dm table is reloaded, e.g. because a
|
||||
+ * path is added or removed. This is an operation that should
|
||||
+ * complete within 1ms, so just wait a bit and retry.
|
||||
+ *
|
||||
+ * There are also some cases in which libmpathpersist must recover
|
||||
+ * from path failure during its operation, which can leave the
|
||||
+ * device suspended for a bit longer while the library brings back
|
||||
+ * reservations into the expected state.
|
||||
+ *
|
||||
+ * Use increasing delays to cover both cases without waiting
|
||||
+ * excessively, and stop after a bit more than a second (1023 ms).
|
||||
+ * This is a tolerable delay before we return an error and
|
||||
+ * potentially stop the VM.
|
||||
+ */
|
||||
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, eagain_sleep_ns);
|
||||
+ eagain_sleep_ns *= 2;
|
||||
+ goto retry;
|
||||
+ }
|
||||
+
|
||||
+ /* Even for ret == 0, the SG_IO header can contain an error */
|
||||
+ if (retries-- && hdev_co_ioctl_sgio_retry(&acb, ret)) {
|
||||
+ goto retry;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return ret;
|
||||
}
|
||||
131
0058-accel-Add-Meson-and-config-support-for-MSHV-accelera.patch
Normal file
131
0058-accel-Add-Meson-and-config-support-for-MSHV-accelera.patch
Normal file
@ -0,0 +1,131 @@
|
||||
From da2c7d5f43b53796bfc8e76ea3e9e63c617048ba Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:21 +0200
|
||||
Subject: [PATCH] accel: Add Meson and config support for MSHV accelerator
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/30] 04ab9685b09f4d837715bf624d87566f472cb6c2
|
||||
|
||||
Introduce a Meson feature option and default-config entry to allow
|
||||
building QEMU with MSHV (Microsoft Hypervisor) acceleration support.
|
||||
|
||||
This is the first step toward implementing an MSHV backend in QEMU.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-2-magnuskulke@linux.microsoft.com
|
||||
[Add error for unavailable accelerator. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 37e12da5df8eb74042f11e9e7bec8a50b8090adb)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-Add-Meson-and-config-support-for-MSHV-accelera.patch
|
||||
Patch-id: 61
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/Kconfig | 3 +++
|
||||
meson.build | 13 +++++++++++++
|
||||
meson_options.txt | 2 ++
|
||||
scripts/meson-buildoptions.sh | 3 +++
|
||||
4 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/accel/Kconfig b/accel/Kconfig
|
||||
index 4263cab722..a60f114923 100644
|
||||
--- a/accel/Kconfig
|
||||
+++ b/accel/Kconfig
|
||||
@@ -13,6 +13,9 @@ config TCG
|
||||
config KVM
|
||||
bool
|
||||
|
||||
+config MSHV
|
||||
+ bool
|
||||
+
|
||||
config XEN
|
||||
bool
|
||||
select FSDEV_9P if VIRTFS
|
||||
diff --git a/meson.build b/meson.build
|
||||
index ef2e5be6e2..96254f8075 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -334,6 +334,7 @@ elif cpu == 'x86_64'
|
||||
'CONFIG_HVF': ['x86_64-softmmu'],
|
||||
'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
|
||||
'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
|
||||
+ 'CONFIG_MSHV': ['x86_64-softmmu'],
|
||||
}
|
||||
endif
|
||||
|
||||
@@ -884,6 +885,14 @@ accelerators = []
|
||||
if get_option('kvm').allowed() and host_os == 'linux'
|
||||
accelerators += 'CONFIG_KVM'
|
||||
endif
|
||||
+
|
||||
+if get_option('mshv').allowed() and host_os == 'linux'
|
||||
+ if get_option('mshv').enabled() and host_machine.cpu() != 'x86_64'
|
||||
+ error('mshv accelerator requires x64_64 host')
|
||||
+ endif
|
||||
+ accelerators += 'CONFIG_MSHV'
|
||||
+endif
|
||||
+
|
||||
if get_option('whpx').allowed() and host_os == 'windows'
|
||||
if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
|
||||
error('WHPX requires 64-bit host')
|
||||
@@ -953,6 +962,9 @@ endif
|
||||
if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
|
||||
error('WHPX not available on this platform')
|
||||
endif
|
||||
+if 'CONFIG_MSHV' not in accelerators and get_option('mshv').enabled()
|
||||
+ error('mshv not available on this platform')
|
||||
+endif
|
||||
|
||||
xen = not_found
|
||||
if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
|
||||
@@ -4821,6 +4833,7 @@ if have_system
|
||||
summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
|
||||
summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
|
||||
summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
|
||||
+ summary_info += {'MSHV support': config_all_accel.has_key('CONFIG_MSHV')}
|
||||
summary_info += {'Xen support': xen.found()}
|
||||
if xen.found()
|
||||
summary_info += {'xen ctrl version': xen.version()}
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index f45d7ded45..2267dee8a0 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -73,6 +73,8 @@ option('malloc', type : 'combo', choices : ['system', 'tcmalloc', 'jemalloc'],
|
||||
|
||||
option('kvm', type: 'feature', value: 'auto',
|
||||
description: 'KVM acceleration support')
|
||||
+option('mshv', type: 'feature', value: 'auto',
|
||||
+ description: 'MSHV acceleration support')
|
||||
option('whpx', type: 'feature', value: 'auto',
|
||||
description: 'WHPX acceleration support')
|
||||
option('hvf', type: 'feature', value: 'auto',
|
||||
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||
index 4146dbc88d..9aff126c28 100644
|
||||
--- a/scripts/meson-buildoptions.sh
|
||||
+++ b/scripts/meson-buildoptions.sh
|
||||
@@ -155,6 +155,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' membarrier membarrier system call (for Linux 4.14+ or Windows'
|
||||
printf "%s\n" ' modules modules support (non Windows)'
|
||||
printf "%s\n" ' mpath Multipath persistent reservation passthrough'
|
||||
+ printf "%s\n" ' mshv MSHV acceleration support'
|
||||
printf "%s\n" ' multiprocess Out of process device emulation support'
|
||||
printf "%s\n" ' netmap netmap network backend support'
|
||||
printf "%s\n" ' nettle nettle cryptography support'
|
||||
@@ -409,6 +410,8 @@ _meson_option_parse() {
|
||||
--disable-modules) printf "%s" -Dmodules=disabled ;;
|
||||
--enable-mpath) printf "%s" -Dmpath=enabled ;;
|
||||
--disable-mpath) printf "%s" -Dmpath=disabled ;;
|
||||
+ --enable-mshv) printf "%s" -Dmshv=enabled ;;
|
||||
+ --disable-mshv) printf "%s" -Dmshv=disabled ;;
|
||||
--enable-multiprocess) printf "%s" -Dmultiprocess=enabled ;;
|
||||
--disable-multiprocess) printf "%s" -Dmultiprocess=disabled ;;
|
||||
--enable-netmap) printf "%s" -Dnetmap=enabled ;;
|
||||
150
0059-target-i386-emulate-Allow-instruction-decoding-from-.patch
Normal file
150
0059-target-i386-emulate-Allow-instruction-decoding-from-.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From b347fa5c362ac5f1fdcfa5601f4b4a36a2d3798c Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:22 +0200
|
||||
Subject: [PATCH] target/i386/emulate: Allow instruction decoding from stream
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/30] 36aa0cc1832e8162cb7bba8001b2362245cdb80b
|
||||
|
||||
Introduce a new helper function to decode x86 instructions from a
|
||||
raw instruction byte stream. MSHV delivers an instruction stream in a
|
||||
buffer of the vm_exit message. It can be used to speed up MMIO
|
||||
emulation, since instructions do not have to be fetched and translated.
|
||||
|
||||
Added "fetch_instruction()" op to x86_emul_ops() to improve
|
||||
traceability.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-3-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 1e25327b244a217078e3fa5df18322c70932f478)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-emulate-Allow-instruction-decoding-from-.patch
|
||||
Patch-id: 62
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/emulate/x86_decode.c | 27 +++++++++++++++++++++++----
|
||||
target/i386/emulate/x86_decode.h | 9 +++++++++
|
||||
target/i386/emulate/x86_emu.c | 3 ++-
|
||||
target/i386/emulate/x86_emu.h | 2 ++
|
||||
4 files changed, 36 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/target/i386/emulate/x86_decode.c b/target/i386/emulate/x86_decode.c
|
||||
index 2eca39802e..97bd6f1a3b 100644
|
||||
--- a/target/i386/emulate/x86_decode.c
|
||||
+++ b/target/i386/emulate/x86_decode.c
|
||||
@@ -71,10 +71,16 @@ static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
|
||||
VM_PANIC_EX("%s invalid size %d\n", __func__, size);
|
||||
break;
|
||||
}
|
||||
- target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len;
|
||||
- emul_ops->read_mem(env_cpu(env), &val, va, size);
|
||||
+
|
||||
+ /* copy the bytes from the instruction stream, if available */
|
||||
+ if (decode->stream && decode->len + size <= decode->stream->len) {
|
||||
+ memcpy(&val, decode->stream->bytes + decode->len, size);
|
||||
+ } else {
|
||||
+ target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len;
|
||||
+ emul_ops->fetch_instruction(env_cpu(env), &val, va, size);
|
||||
+ }
|
||||
decode->len += size;
|
||||
-
|
||||
+
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -2076,9 +2082,10 @@ static void decode_opcodes(CPUX86State *env, struct x86_decode *decode)
|
||||
}
|
||||
}
|
||||
|
||||
-uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
|
||||
+static uint32_t decode_opcode(CPUX86State *env, struct x86_decode *decode)
|
||||
{
|
||||
memset(decode, 0, sizeof(*decode));
|
||||
+
|
||||
decode_prefix(env, decode);
|
||||
set_addressing_size(env, decode);
|
||||
set_operand_size(env, decode);
|
||||
@@ -2088,6 +2095,18 @@ uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
|
||||
return decode->len;
|
||||
}
|
||||
|
||||
+uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode)
|
||||
+{
|
||||
+ return decode_opcode(env, decode);
|
||||
+}
|
||||
+
|
||||
+uint32_t decode_instruction_stream(CPUX86State *env, struct x86_decode *decode,
|
||||
+ struct x86_insn_stream *stream)
|
||||
+{
|
||||
+ decode->stream = stream;
|
||||
+ return decode_opcode(env, decode);
|
||||
+}
|
||||
+
|
||||
void init_decoder(void)
|
||||
{
|
||||
int i;
|
||||
diff --git a/target/i386/emulate/x86_decode.h b/target/i386/emulate/x86_decode.h
|
||||
index 927645af1a..1cadf3694f 100644
|
||||
--- a/target/i386/emulate/x86_decode.h
|
||||
+++ b/target/i386/emulate/x86_decode.h
|
||||
@@ -272,6 +272,11 @@ typedef struct x86_decode_op {
|
||||
};
|
||||
} x86_decode_op;
|
||||
|
||||
+typedef struct x86_insn_stream {
|
||||
+ const uint8_t *bytes;
|
||||
+ size_t len;
|
||||
+} x86_insn_stream;
|
||||
+
|
||||
typedef struct x86_decode {
|
||||
int len;
|
||||
uint8_t opcode[4];
|
||||
@@ -298,11 +303,15 @@ typedef struct x86_decode {
|
||||
struct x86_modrm modrm;
|
||||
struct x86_decode_op op[4];
|
||||
bool is_fpu;
|
||||
+
|
||||
+ x86_insn_stream *stream;
|
||||
} x86_decode;
|
||||
|
||||
uint64_t sign(uint64_t val, int size);
|
||||
|
||||
uint32_t decode_instruction(CPUX86State *env, struct x86_decode *decode);
|
||||
+uint32_t decode_instruction_stream(CPUX86State *env, struct x86_decode *decode,
|
||||
+ struct x86_insn_stream *stream);
|
||||
|
||||
void *get_reg_ref(CPUX86State *env, int reg, int rex_present,
|
||||
int is_extended, int size);
|
||||
diff --git a/target/i386/emulate/x86_emu.c b/target/i386/emulate/x86_emu.c
|
||||
index db7a7f7437..4409f7bc13 100644
|
||||
--- a/target/i386/emulate/x86_emu.c
|
||||
+++ b/target/i386/emulate/x86_emu.c
|
||||
@@ -1246,7 +1246,8 @@ static void init_cmd_handler(void)
|
||||
bool exec_instruction(CPUX86State *env, struct x86_decode *ins)
|
||||
{
|
||||
if (!_cmd_handler[ins->cmd].handler) {
|
||||
- printf("Unimplemented handler (" TARGET_FMT_lx ") for %d (%x %x) \n", env->eip,
|
||||
+ printf("Unimplemented handler (" TARGET_FMT_lx ") for %d (%x %x)\n",
|
||||
+ env->eip,
|
||||
ins->cmd, ins->opcode[0],
|
||||
ins->opcode_len > 1 ? ins->opcode[1] : 0);
|
||||
env->eip += ins->len;
|
||||
diff --git a/target/i386/emulate/x86_emu.h b/target/i386/emulate/x86_emu.h
|
||||
index a1a961284b..05686b162f 100644
|
||||
--- a/target/i386/emulate/x86_emu.h
|
||||
+++ b/target/i386/emulate/x86_emu.h
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "cpu.h"
|
||||
|
||||
struct x86_emul_ops {
|
||||
+ void (*fetch_instruction)(CPUState *cpu, void *data, target_ulong addr,
|
||||
+ int bytes);
|
||||
void (*read_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes);
|
||||
void (*write_mem)(CPUState *cpu, void *data, target_ulong addr, int bytes);
|
||||
void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc,
|
||||
432
0060-target-i386-mshv-Add-x86-decoder-emu-implementation.patch
Normal file
432
0060-target-i386-mshv-Add-x86-decoder-emu-implementation.patch
Normal file
@ -0,0 +1,432 @@
|
||||
From b49240242f3d6a007abc4027aef16cd0b2f70d8b Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:23 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Add x86 decoder/emu implementation
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [3/30] 8fa2e2f50c18532d98ef3917f624bc3e65ad167d
|
||||
|
||||
The MSHV accelerator requires a x86 decoder/emulator in userland to
|
||||
emulate MMIO instructions. This change contains the implementations for
|
||||
the generalized i386 instruction decoder/emulator.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-4-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 0daf817c80b57e58168309420abf0a8a3d2a60f6)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Add-x86-decoder-emu-implementation.patch
|
||||
Patch-id: 63
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/system/mshv.h | 25 +++
|
||||
target/i386/cpu.h | 2 +-
|
||||
target/i386/emulate/meson.build | 7 +-
|
||||
target/i386/meson.build | 2 +
|
||||
target/i386/mshv/meson.build | 7 +
|
||||
target/i386/mshv/x86.c | 297 ++++++++++++++++++++++++++++++++
|
||||
6 files changed, 337 insertions(+), 3 deletions(-)
|
||||
create mode 100644 include/system/mshv.h
|
||||
create mode 100644 target/i386/mshv/meson.build
|
||||
create mode 100644 target/i386/mshv/x86.c
|
||||
|
||||
diff --git a/include/system/mshv.h b/include/system/mshv.h
|
||||
new file mode 100644
|
||||
index 0000000000..342f1ef6a9
|
||||
--- /dev/null
|
||||
+++ b/include/system/mshv.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ * Jinank Jain <jinankjain@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef QEMU_MSHV_H
|
||||
+#define QEMU_MSHV_H
|
||||
+
|
||||
+#ifdef COMPILING_PER_TARGET
|
||||
+#ifdef CONFIG_MSHV
|
||||
+#define CONFIG_MSHV_IS_POSSIBLE
|
||||
+#endif
|
||||
+#else
|
||||
+#define CONFIG_MSHV_IS_POSSIBLE
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index 2187e61654..4b7eae43e1 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -2126,7 +2126,7 @@ typedef struct CPUArchState {
|
||||
QEMUTimer *xen_periodic_timer;
|
||||
QemuMutex xen_timers_lock;
|
||||
#endif
|
||||
-#if defined(CONFIG_HVF)
|
||||
+#if defined(CONFIG_HVF) || defined(CONFIG_MSHV)
|
||||
void *emu_mmio_buf;
|
||||
#endif
|
||||
|
||||
diff --git a/target/i386/emulate/meson.build b/target/i386/emulate/meson.build
|
||||
index 4edd4f462f..b6dafb6a5b 100644
|
||||
--- a/target/i386/emulate/meson.build
|
||||
+++ b/target/i386/emulate/meson.build
|
||||
@@ -1,5 +1,8 @@
|
||||
-i386_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
|
||||
+emulator_files = files(
|
||||
'x86_decode.c',
|
||||
'x86_emu.c',
|
||||
'x86_flags.c',
|
||||
-))
|
||||
+)
|
||||
+
|
||||
+i386_system_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: emulator_files)
|
||||
+i386_system_ss.add(when: 'CONFIG_MSHV', if_true: emulator_files)
|
||||
diff --git a/target/i386/meson.build b/target/i386/meson.build
|
||||
index 092af34e2d..89ba4912aa 100644
|
||||
--- a/target/i386/meson.build
|
||||
+++ b/target/i386/meson.build
|
||||
@@ -13,6 +13,7 @@ i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c'))
|
||||
i386_ss.add(when: 'CONFIG_HVF', if_true: files('host-cpu.c'))
|
||||
i386_ss.add(when: 'CONFIG_WHPX', if_true: files('host-cpu.c'))
|
||||
i386_ss.add(when: 'CONFIG_NVMM', if_true: files('host-cpu.c'))
|
||||
+i386_ss.add(when: 'CONFIG_MSHV', if_true: files('host-cpu.c'))
|
||||
|
||||
i386_system_ss = ss.source_set()
|
||||
i386_system_ss.add(files(
|
||||
@@ -34,6 +35,7 @@ subdir('nvmm')
|
||||
subdir('hvf')
|
||||
subdir('tcg')
|
||||
subdir('emulate')
|
||||
+subdir('mshv')
|
||||
|
||||
target_arch += {'i386': i386_ss}
|
||||
target_system_arch += {'i386': i386_system_ss}
|
||||
diff --git a/target/i386/mshv/meson.build b/target/i386/mshv/meson.build
|
||||
new file mode 100644
|
||||
index 0000000000..8ddaa7c11d
|
||||
--- /dev/null
|
||||
+++ b/target/i386/mshv/meson.build
|
||||
@@ -0,0 +1,7 @@
|
||||
+i386_mshv_ss = ss.source_set()
|
||||
+
|
||||
+i386_mshv_ss.add(files(
|
||||
+ 'x86.c',
|
||||
+))
|
||||
+
|
||||
+i386_system_ss.add_all(when: 'CONFIG_MSHV', if_true: i386_mshv_ss)
|
||||
diff --git a/target/i386/mshv/x86.c b/target/i386/mshv/x86.c
|
||||
new file mode 100644
|
||||
index 0000000000..d574b3bc52
|
||||
--- /dev/null
|
||||
+++ b/target/i386/mshv/x86.c
|
||||
@@ -0,0 +1,297 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+
|
||||
+#include "cpu.h"
|
||||
+#include "emulate/x86_decode.h"
|
||||
+#include "emulate/x86_emu.h"
|
||||
+#include "qemu/typedefs.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "system/mshv.h"
|
||||
+
|
||||
+/* RW or Exec segment */
|
||||
+static const uint8_t RWRX_SEGMENT_TYPE = 0x2;
|
||||
+static const uint8_t CODE_SEGMENT_TYPE = 0x8;
|
||||
+static const uint8_t EXPAND_DOWN_SEGMENT_TYPE = 0x4;
|
||||
+
|
||||
+typedef enum CpuMode {
|
||||
+ REAL_MODE,
|
||||
+ PROTECTED_MODE,
|
||||
+ LONG_MODE,
|
||||
+} CpuMode;
|
||||
+
|
||||
+static CpuMode cpu_mode(CPUState *cpu)
|
||||
+{
|
||||
+ enum CpuMode m = REAL_MODE;
|
||||
+
|
||||
+ if (x86_is_protected(cpu)) {
|
||||
+ m = PROTECTED_MODE;
|
||||
+
|
||||
+ if (x86_is_long_mode(cpu)) {
|
||||
+ m = LONG_MODE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return m;
|
||||
+}
|
||||
+
|
||||
+static bool segment_type_ro(const SegmentCache *seg)
|
||||
+{
|
||||
+ uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
|
||||
+ return (type_ & (~RWRX_SEGMENT_TYPE)) == 0;
|
||||
+}
|
||||
+
|
||||
+static bool segment_type_code(const SegmentCache *seg)
|
||||
+{
|
||||
+ uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
|
||||
+ return (type_ & CODE_SEGMENT_TYPE) != 0;
|
||||
+}
|
||||
+
|
||||
+static bool segment_expands_down(const SegmentCache *seg)
|
||||
+{
|
||||
+ uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
|
||||
+
|
||||
+ if (segment_type_code(seg)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return (type_ & EXPAND_DOWN_SEGMENT_TYPE) != 0;
|
||||
+}
|
||||
+
|
||||
+static uint32_t segment_limit(const SegmentCache *seg)
|
||||
+{
|
||||
+ uint32_t limit = seg->limit;
|
||||
+ uint32_t granularity = (seg->flags & DESC_G_MASK) != 0;
|
||||
+
|
||||
+ if (granularity != 0) {
|
||||
+ limit = (limit << 12) | 0xFFF;
|
||||
+ }
|
||||
+
|
||||
+ return limit;
|
||||
+}
|
||||
+
|
||||
+static uint8_t segment_db(const SegmentCache *seg)
|
||||
+{
|
||||
+ return (seg->flags >> DESC_B_SHIFT) & 1;
|
||||
+}
|
||||
+
|
||||
+static uint32_t segment_max_limit(const SegmentCache *seg)
|
||||
+{
|
||||
+ if (segment_db(seg) != 0) {
|
||||
+ return 0xFFFFFFFF;
|
||||
+ }
|
||||
+ return 0xFFFF;
|
||||
+}
|
||||
+
|
||||
+static int linearize(CPUState *cpu,
|
||||
+ target_ulong logical_addr, target_ulong *linear_addr,
|
||||
+ X86Seg seg_idx)
|
||||
+{
|
||||
+ enum CpuMode mode;
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ SegmentCache *seg = &env->segs[seg_idx];
|
||||
+ target_ulong base = seg->base;
|
||||
+ target_ulong logical_addr_32b;
|
||||
+ uint32_t limit;
|
||||
+ /* TODO: the emulator will not pass us "write" indicator yet */
|
||||
+ bool write = false;
|
||||
+
|
||||
+ mode = cpu_mode(cpu);
|
||||
+
|
||||
+ switch (mode) {
|
||||
+ case LONG_MODE:
|
||||
+ if (__builtin_add_overflow(logical_addr, base, linear_addr)) {
|
||||
+ error_report("Address overflow");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ break;
|
||||
+ case PROTECTED_MODE:
|
||||
+ case REAL_MODE:
|
||||
+ if (segment_type_ro(seg) && write) {
|
||||
+ error_report("Cannot write to read-only segment");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ logical_addr_32b = logical_addr & 0xFFFFFFFF;
|
||||
+ limit = segment_limit(seg);
|
||||
+
|
||||
+ if (segment_expands_down(seg)) {
|
||||
+ if (logical_addr_32b >= limit) {
|
||||
+ error_report("Address exceeds limit (expands down)");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ limit = segment_max_limit(seg);
|
||||
+ }
|
||||
+
|
||||
+ if (logical_addr_32b > limit) {
|
||||
+ error_report("Address exceeds limit %u", limit);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ *linear_addr = logical_addr_32b + base;
|
||||
+ break;
|
||||
+ default:
|
||||
+ error_report("Unknown cpu mode: %d", mode);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+bool x86_read_segment_descriptor(CPUState *cpu,
|
||||
+ struct x86_segment_descriptor *desc,
|
||||
+ x86_segment_selector sel)
|
||||
+{
|
||||
+ target_ulong base;
|
||||
+ uint32_t limit;
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ target_ulong gva;
|
||||
+
|
||||
+ memset(desc, 0, sizeof(*desc));
|
||||
+
|
||||
+ /* valid gdt descriptors start from index 1 */
|
||||
+ if (!sel.index && GDT_SEL == sel.ti) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (GDT_SEL == sel.ti) {
|
||||
+ base = env->gdt.base;
|
||||
+ limit = env->gdt.limit;
|
||||
+ } else {
|
||||
+ base = env->ldt.base;
|
||||
+ limit = env->ldt.limit;
|
||||
+ }
|
||||
+
|
||||
+ if (sel.index * 8 >= limit) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ gva = base + sel.index * 8;
|
||||
+ emul_ops->read_mem(cpu, desc, gva, sizeof(*desc));
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool x86_read_call_gate(CPUState *cpu, struct x86_call_gate *idt_desc,
|
||||
+ int gate)
|
||||
+{
|
||||
+ target_ulong base;
|
||||
+ uint32_t limit;
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ target_ulong gva;
|
||||
+
|
||||
+ base = env->idt.base;
|
||||
+ limit = env->idt.limit;
|
||||
+
|
||||
+ memset(idt_desc, 0, sizeof(*idt_desc));
|
||||
+ if (gate * 8 >= limit) {
|
||||
+ perror("call gate exceeds idt limit");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ gva = base + gate * 8;
|
||||
+ emul_ops->read_mem(cpu, idt_desc, gva, sizeof(*idt_desc));
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool x86_is_protected(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ uint64_t cr0 = env->cr[0];
|
||||
+
|
||||
+ return cr0 & CR0_PE_MASK;
|
||||
+}
|
||||
+
|
||||
+bool x86_is_real(CPUState *cpu)
|
||||
+{
|
||||
+ return !x86_is_protected(cpu);
|
||||
+}
|
||||
+
|
||||
+bool x86_is_v8086(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ return x86_is_protected(cpu) && (env->eflags & VM_MASK);
|
||||
+}
|
||||
+
|
||||
+bool x86_is_long_mode(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ uint64_t efer = env->efer;
|
||||
+ uint64_t lme_lma = (MSR_EFER_LME | MSR_EFER_LMA);
|
||||
+
|
||||
+ return ((efer & lme_lma) == lme_lma);
|
||||
+}
|
||||
+
|
||||
+bool x86_is_long64_mode(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented: is_long64_mode()");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+bool x86_is_paging_mode(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ uint64_t cr0 = env->cr[0];
|
||||
+
|
||||
+ return cr0 & CR0_PG_MASK;
|
||||
+}
|
||||
+
|
||||
+bool x86_is_pae_enabled(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ uint64_t cr4 = env->cr[4];
|
||||
+
|
||||
+ return cr4 & CR4_PAE_MASK;
|
||||
+}
|
||||
+
|
||||
+target_ulong linear_addr(CPUState *cpu, target_ulong addr, X86Seg seg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ target_ulong linear_addr;
|
||||
+
|
||||
+ ret = linearize(cpu, addr, &linear_addr, seg);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to linearize address");
|
||||
+ abort();
|
||||
+ }
|
||||
+
|
||||
+ return linear_addr;
|
||||
+}
|
||||
+
|
||||
+target_ulong linear_addr_size(CPUState *cpu, target_ulong addr, int size,
|
||||
+ X86Seg seg)
|
||||
+{
|
||||
+ switch (size) {
|
||||
+ case 2:
|
||||
+ addr = (uint16_t)addr;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ addr = (uint32_t)addr;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return linear_addr(cpu, addr, seg);
|
||||
+}
|
||||
+
|
||||
+target_ulong linear_rip(CPUState *cpu, target_ulong rip)
|
||||
+{
|
||||
+ return linear_addr(cpu, rip, R_CS);
|
||||
+}
|
||||
386
0061-hw-intc-Generalize-APIC-helper-names-from-kvm_-to-ac.patch
Normal file
386
0061-hw-intc-Generalize-APIC-helper-names-from-kvm_-to-ac.patch
Normal file
@ -0,0 +1,386 @@
|
||||
From 2dcc4aa67b074801ed831ec53ebeed4fc232dade Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:24 +0200
|
||||
Subject: [PATCH] hw/intc: Generalize APIC helper names from kvm_* to accel_*
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [4/30] 2622233d15ed5138cb143d2a5b54fb05c8574654
|
||||
|
||||
Rename APIC helper functions to use an accel_* prefix instead of kvm_*
|
||||
to support use by accelerators other than KVM. This is a preparatory
|
||||
step for integrating MSHV support with common APIC logic.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-5-magnuskulke@linux.microsoft.com
|
||||
[Remove dead definition of mshv_msi_via_irqfd_enabled. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 638ac1c78457dd93ccd795b9c6c2673af8c7dd21)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-intc-Generalize-APIC-helper-names-from-kvm_-to-ac.patch
|
||||
Patch-id: 64
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/accel-irq.c | 106 +++++++++++++++++++++++++++++++++++++
|
||||
accel/meson.build | 2 +-
|
||||
hw/intc/ioapic.c | 20 ++++---
|
||||
hw/virtio/virtio-pci.c | 21 ++++----
|
||||
include/system/accel-irq.h | 37 +++++++++++++
|
||||
include/system/mshv.h | 17 ++++++
|
||||
6 files changed, 185 insertions(+), 18 deletions(-)
|
||||
create mode 100644 accel/accel-irq.c
|
||||
create mode 100644 include/system/accel-irq.h
|
||||
|
||||
diff --git a/accel/accel-irq.c b/accel/accel-irq.c
|
||||
new file mode 100644
|
||||
index 0000000000..7f864e35c4
|
||||
--- /dev/null
|
||||
+++ b/accel/accel-irq.c
|
||||
@@ -0,0 +1,106 @@
|
||||
+/*
|
||||
+ * Accelerated irqchip abstraction
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/pci/msi.h"
|
||||
+
|
||||
+#include "system/kvm.h"
|
||||
+#include "system/mshv.h"
|
||||
+#include "system/accel-irq.h"
|
||||
+
|
||||
+int accel_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ return mshv_irqchip_add_msi_route(vector, dev);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ return kvm_irqchip_add_msi_route(c, vector, dev);
|
||||
+ }
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
+int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *dev)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ return mshv_irqchip_update_msi_route(vector, msg, dev);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ return kvm_irqchip_update_msi_route(kvm_state, vector, msg, dev);
|
||||
+ }
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
+void accel_irqchip_commit_route_changes(KVMRouteChange *c)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ mshv_irqchip_commit_routes();
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ kvm_irqchip_commit_route_changes(c);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void accel_irqchip_commit_routes(void)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ mshv_irqchip_commit_routes();
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ kvm_irqchip_commit_routes(kvm_state);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void accel_irqchip_release_virq(int virq)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ mshv_irqchip_release_virq(virq);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ kvm_irqchip_release_virq(kvm_state, virq);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int accel_irqchip_add_irqfd_notifier_gsi(EventNotifier *n, EventNotifier *rn,
|
||||
+ int virq)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ return mshv_irqchip_add_irqfd_notifier_gsi(n, rn, virq);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, rn, virq);
|
||||
+ }
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
+int accel_irqchip_remove_irqfd_notifier_gsi(EventNotifier *n, int virq)
|
||||
+{
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+ if (mshv_msi_via_irqfd_enabled()) {
|
||||
+ return mshv_irqchip_remove_irqfd_notifier_gsi(n, virq);
|
||||
+ }
|
||||
+#endif
|
||||
+ if (kvm_enabled()) {
|
||||
+ return kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, virq);
|
||||
+ }
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
diff --git a/accel/meson.build b/accel/meson.build
|
||||
index 25b0f100b5..6349efe682 100644
|
||||
--- a/accel/meson.build
|
||||
+++ b/accel/meson.build
|
||||
@@ -1,6 +1,6 @@
|
||||
common_ss.add(files('accel-common.c'))
|
||||
specific_ss.add(files('accel-target.c'))
|
||||
-system_ss.add(files('accel-system.c', 'accel-blocker.c', 'accel-qmp.c'))
|
||||
+system_ss.add(files('accel-system.c', 'accel-blocker.c', 'accel-qmp.c', 'accel-irq.c'))
|
||||
user_ss.add(files('accel-user.c'))
|
||||
|
||||
subdir('tcg')
|
||||
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
|
||||
index 133bef852d..e431d00311 100644
|
||||
--- a/hw/intc/ioapic.c
|
||||
+++ b/hw/intc/ioapic.c
|
||||
@@ -30,12 +30,18 @@
|
||||
#include "hw/intc/ioapic_internal.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
+#include "system/accel-irq.h"
|
||||
#include "system/kvm.h"
|
||||
#include "system/system.h"
|
||||
#include "hw/i386/apic-msidef.h"
|
||||
#include "hw/i386/x86-iommu.h"
|
||||
#include "trace.h"
|
||||
|
||||
+
|
||||
+#if defined(CONFIG_KVM) || defined(CONFIG_MSHV)
|
||||
+#define ACCEL_GSI_IRQFD_POSSIBLE
|
||||
+#endif
|
||||
+
|
||||
#define APIC_DELIVERY_MODE_SHIFT 8
|
||||
#define APIC_POLARITY_SHIFT 14
|
||||
#define APIC_TRIG_MODE_SHIFT 15
|
||||
@@ -191,10 +197,10 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
|
||||
|
||||
static void ioapic_update_kvm_routes(IOAPICCommonState *s)
|
||||
{
|
||||
-#ifdef CONFIG_KVM
|
||||
+#ifdef ACCEL_GSI_IRQFD_POSSIBLE
|
||||
int i;
|
||||
|
||||
- if (kvm_irqchip_is_split()) {
|
||||
+ if (accel_irqchip_is_split()) {
|
||||
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
||||
MSIMessage msg;
|
||||
struct ioapic_entry_info info;
|
||||
@@ -202,15 +208,15 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
|
||||
if (!info.masked) {
|
||||
msg.address = info.addr;
|
||||
msg.data = info.data;
|
||||
- kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL);
|
||||
+ accel_irqchip_update_msi_route(i, msg, NULL);
|
||||
}
|
||||
}
|
||||
- kvm_irqchip_commit_routes(kvm_state);
|
||||
+ accel_irqchip_commit_routes();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_KVM
|
||||
+#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
|
||||
static void ioapic_iec_notifier(void *private, bool global,
|
||||
uint32_t index, uint32_t mask)
|
||||
{
|
||||
@@ -428,11 +434,11 @@ static const MemoryRegionOps ioapic_io_ops = {
|
||||
|
||||
static void ioapic_machine_done_notify(Notifier *notifier, void *data)
|
||||
{
|
||||
-#ifdef CONFIG_KVM
|
||||
+#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
|
||||
IOAPICCommonState *s = container_of(notifier, IOAPICCommonState,
|
||||
machine_done);
|
||||
|
||||
- if (kvm_irqchip_is_split()) {
|
||||
+ if (accel_irqchip_is_split()) {
|
||||
X86IOMMUState *iommu = x86_iommu_get_default();
|
||||
if (iommu) {
|
||||
/* Register this IOAPIC with IOMMU IEC notifier, so that
|
||||
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
|
||||
index 767216d795..0cdc16217f 100644
|
||||
--- a/hw/virtio/virtio-pci.c
|
||||
+++ b/hw/virtio/virtio-pci.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/pci/msix.h"
|
||||
#include "hw/loader.h"
|
||||
+#include "system/accel-irq.h"
|
||||
#include "system/kvm.h"
|
||||
#include "hw/virtio/virtio-pci.h"
|
||||
#include "qemu/range.h"
|
||||
@@ -825,11 +826,11 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
|
||||
|
||||
if (irqfd->users == 0) {
|
||||
KVMRouteChange c = kvm_irqchip_begin_route_changes(kvm_state);
|
||||
- ret = kvm_irqchip_add_msi_route(&c, vector, &proxy->pci_dev);
|
||||
+ ret = accel_irqchip_add_msi_route(&c, vector, &proxy->pci_dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
- kvm_irqchip_commit_route_changes(&c);
|
||||
+ accel_irqchip_commit_route_changes(&c);
|
||||
irqfd->virq = ret;
|
||||
}
|
||||
irqfd->users++;
|
||||
@@ -841,7 +842,7 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
|
||||
{
|
||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||
if (--irqfd->users == 0) {
|
||||
- kvm_irqchip_release_virq(kvm_state, irqfd->virq);
|
||||
+ accel_irqchip_release_virq(irqfd->virq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,7 +851,7 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
|
||||
unsigned int vector)
|
||||
{
|
||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||
- return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
|
||||
+ return accel_irqchip_add_irqfd_notifier_gsi(n, NULL, irqfd->virq);
|
||||
}
|
||||
|
||||
static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
|
||||
@@ -860,7 +861,7 @@ static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
|
||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||
int ret;
|
||||
|
||||
- ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
|
||||
+ ret = accel_irqchip_remove_irqfd_notifier_gsi(n, irqfd->virq);
|
||||
assert(ret == 0);
|
||||
}
|
||||
static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
|
||||
@@ -995,12 +996,12 @@ static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
|
||||
if (proxy->vector_irqfd) {
|
||||
irqfd = &proxy->vector_irqfd[vector];
|
||||
if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
|
||||
- ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg,
|
||||
- &proxy->pci_dev);
|
||||
+ ret = accel_irqchip_update_msi_route(irqfd->virq, msg,
|
||||
+ &proxy->pci_dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
- kvm_irqchip_commit_routes(kvm_state);
|
||||
+ accel_irqchip_commit_routes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,7 +1230,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
|
||||
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
int r, n;
|
||||
bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
|
||||
- kvm_msi_via_irqfd_enabled();
|
||||
+ accel_msi_via_irqfd_enabled() ;
|
||||
|
||||
nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
|
||||
|
||||
@@ -1433,7 +1434,7 @@ static void virtio_pci_set_vector(VirtIODevice *vdev,
|
||||
uint16_t new_vector)
|
||||
{
|
||||
bool kvm_irqfd = (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
|
||||
- msix_enabled(&proxy->pci_dev) && kvm_msi_via_irqfd_enabled();
|
||||
+ msix_enabled(&proxy->pci_dev) && accel_msi_via_irqfd_enabled();
|
||||
|
||||
if (new_vector == old_vector) {
|
||||
return;
|
||||
diff --git a/include/system/accel-irq.h b/include/system/accel-irq.h
|
||||
new file mode 100644
|
||||
index 0000000000..671fb7dfdb
|
||||
--- /dev/null
|
||||
+++ b/include/system/accel-irq.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ * Accelerated irqchip abstraction
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#ifndef SYSTEM_ACCEL_IRQ_H
|
||||
+#define SYSTEM_ACCEL_IRQ_H
|
||||
+#include "hw/pci/msi.h"
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "system/kvm.h"
|
||||
+#include "system/mshv.h"
|
||||
+
|
||||
+static inline bool accel_msi_via_irqfd_enabled(void)
|
||||
+{
|
||||
+ return mshv_msi_via_irqfd_enabled() || kvm_msi_via_irqfd_enabled();
|
||||
+}
|
||||
+
|
||||
+static inline bool accel_irqchip_is_split(void)
|
||||
+{
|
||||
+ return mshv_msi_via_irqfd_enabled() || kvm_irqchip_is_split();
|
||||
+}
|
||||
+
|
||||
+int accel_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev);
|
||||
+int accel_irqchip_update_msi_route(int vector, MSIMessage msg, PCIDevice *dev);
|
||||
+void accel_irqchip_commit_route_changes(KVMRouteChange *c);
|
||||
+void accel_irqchip_commit_routes(void);
|
||||
+void accel_irqchip_release_virq(int virq);
|
||||
+int accel_irqchip_add_irqfd_notifier_gsi(EventNotifier *n, EventNotifier *rn,
|
||||
+ int virq);
|
||||
+int accel_irqchip_remove_irqfd_notifier_gsi(EventNotifier *n, int virq);
|
||||
+#endif
|
||||
diff --git a/include/system/mshv.h b/include/system/mshv.h
|
||||
index 342f1ef6a9..2a504ed81f 100644
|
||||
--- a/include/system/mshv.h
|
||||
+++ b/include/system/mshv.h
|
||||
@@ -22,4 +22,21 @@
|
||||
#define CONFIG_MSHV_IS_POSSIBLE
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_MSHV_IS_POSSIBLE
|
||||
+extern bool mshv_allowed;
|
||||
+#define mshv_enabled() (mshv_allowed)
|
||||
+#else /* CONFIG_MSHV_IS_POSSIBLE */
|
||||
+#define mshv_enabled() false
|
||||
+#endif
|
||||
+#define mshv_msi_via_irqfd_enabled() false
|
||||
+
|
||||
+/* interrupt */
|
||||
+int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev);
|
||||
+int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev);
|
||||
+void mshv_irqchip_commit_routes(void);
|
||||
+void mshv_irqchip_release_virq(int virq);
|
||||
+int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n,
|
||||
+ const EventNotifier *rn, int virq);
|
||||
+int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int virq);
|
||||
+
|
||||
#endif
|
||||
1265
0062-include-hw-hyperv-Add-MSHV-ABI-header-definitions.patch
Normal file
1265
0062-include-hw-hyperv-Add-MSHV-ABI-header-definitions.patch
Normal file
File diff suppressed because it is too large
Load Diff
330
0063-linux-headers-linux-Add-mshv.h-headers.patch
Normal file
330
0063-linux-headers-linux-Add-mshv.h-headers.patch
Normal file
@ -0,0 +1,330 @@
|
||||
From d0ad38d558917e602d8b85d0737e0dbb38c19a9c Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:26 +0200
|
||||
Subject: [PATCH] linux-headers/linux: Add mshv.h headers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [6/30] ef60621970d29f626815bdeb68bc8bdfe0061d0e
|
||||
|
||||
This file has been added to the tree by running `update-linux-header.sh`
|
||||
on linux v6.16.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-7-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit a6d6878650a0f4982918e8cd9d7ea6c3c3c681f7)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-linux-headers-linux-Add-mshv.h-headers.patch
|
||||
Patch-id: 66
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
linux-headers/linux/mshv.h | 291 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 291 insertions(+)
|
||||
create mode 100644 linux-headers/linux/mshv.h
|
||||
|
||||
diff --git a/linux-headers/linux/mshv.h b/linux-headers/linux/mshv.h
|
||||
new file mode 100644
|
||||
index 0000000000..5bc83db6a3
|
||||
--- /dev/null
|
||||
+++ b/linux-headers/linux/mshv.h
|
||||
@@ -0,0 +1,291 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
+/*
|
||||
+ * Userspace interfaces for /dev/mshv* devices and derived fds
|
||||
+ *
|
||||
+ * This file is divided into sections containing data structures and IOCTLs for
|
||||
+ * a particular set of related devices or derived file descriptors.
|
||||
+ *
|
||||
+ * The IOCTL definitions are at the end of each section. They are grouped by
|
||||
+ * device/fd, so that new IOCTLs can easily be added with a monotonically
|
||||
+ * increasing number.
|
||||
+ */
|
||||
+#ifndef _LINUX_MSHV_H
|
||||
+#define _LINUX_MSHV_H
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+#define MSHV_IOCTL 0xB8
|
||||
+
|
||||
+/*
|
||||
+ *******************************************
|
||||
+ * Entry point to main VMM APIs: /dev/mshv *
|
||||
+ *******************************************
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_PT_BIT_LAPIC,
|
||||
+ MSHV_PT_BIT_X2APIC,
|
||||
+ MSHV_PT_BIT_GPA_SUPER_PAGES,
|
||||
+ MSHV_PT_BIT_COUNT,
|
||||
+};
|
||||
+
|
||||
+#define MSHV_PT_FLAGS_MASK ((1 << MSHV_PT_BIT_COUNT) - 1)
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_PT_ISOLATION_NONE,
|
||||
+ MSHV_PT_ISOLATION_COUNT,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_create_partition - arguments for MSHV_CREATE_PARTITION
|
||||
+ * @pt_flags: Bitmask of 1 << MSHV_PT_BIT_*
|
||||
+ * @pt_isolation: MSHV_PT_ISOLATION_*
|
||||
+ *
|
||||
+ * Returns a file descriptor to act as a handle to a guest partition.
|
||||
+ * At this point the partition is not yet initialized in the hypervisor.
|
||||
+ * Some operations must be done with the partition in this state, e.g. setting
|
||||
+ * so-called "early" partition properties. The partition can then be
|
||||
+ * initialized with MSHV_INITIALIZE_PARTITION.
|
||||
+ */
|
||||
+struct mshv_create_partition {
|
||||
+ __u64 pt_flags;
|
||||
+ __u64 pt_isolation;
|
||||
+};
|
||||
+
|
||||
+/* /dev/mshv */
|
||||
+#define MSHV_CREATE_PARTITION _IOW(MSHV_IOCTL, 0x00, struct mshv_create_partition)
|
||||
+
|
||||
+/*
|
||||
+ ************************
|
||||
+ * Child partition APIs *
|
||||
+ ************************
|
||||
+ */
|
||||
+
|
||||
+struct mshv_create_vp {
|
||||
+ __u32 vp_index;
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_SET_MEM_BIT_WRITABLE,
|
||||
+ MSHV_SET_MEM_BIT_EXECUTABLE,
|
||||
+ MSHV_SET_MEM_BIT_UNMAP,
|
||||
+ MSHV_SET_MEM_BIT_COUNT
|
||||
+};
|
||||
+
|
||||
+#define MSHV_SET_MEM_FLAGS_MASK ((1 << MSHV_SET_MEM_BIT_COUNT) - 1)
|
||||
+
|
||||
+/* The hypervisor's "native" page size */
|
||||
+#define MSHV_HV_PAGE_SIZE 0x1000
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_user_mem_region - arguments for MSHV_SET_GUEST_MEMORY
|
||||
+ * @size: Size of the memory region (bytes). Must be aligned to
|
||||
+ * MSHV_HV_PAGE_SIZE
|
||||
+ * @guest_pfn: Base guest page number to map
|
||||
+ * @userspace_addr: Base address of userspace memory. Must be aligned to
|
||||
+ * MSHV_HV_PAGE_SIZE
|
||||
+ * @flags: Bitmask of 1 << MSHV_SET_MEM_BIT_*. If (1 << MSHV_SET_MEM_BIT_UNMAP)
|
||||
+ * is set, ignore other bits.
|
||||
+ * @rsvd: MBZ
|
||||
+ *
|
||||
+ * Map or unmap a region of userspace memory to Guest Physical Addresses (GPA).
|
||||
+ * Mappings can't overlap in GPA space or userspace.
|
||||
+ * To unmap, these fields must match an existing mapping.
|
||||
+ */
|
||||
+struct mshv_user_mem_region {
|
||||
+ __u64 size;
|
||||
+ __u64 guest_pfn;
|
||||
+ __u64 userspace_addr;
|
||||
+ __u8 flags;
|
||||
+ __u8 rsvd[7];
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_IRQFD_BIT_DEASSIGN,
|
||||
+ MSHV_IRQFD_BIT_RESAMPLE,
|
||||
+ MSHV_IRQFD_BIT_COUNT,
|
||||
+};
|
||||
+
|
||||
+#define MSHV_IRQFD_FLAGS_MASK ((1 << MSHV_IRQFD_BIT_COUNT) - 1)
|
||||
+
|
||||
+struct mshv_user_irqfd {
|
||||
+ __s32 fd;
|
||||
+ __s32 resamplefd;
|
||||
+ __u32 gsi;
|
||||
+ __u32 flags;
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_IOEVENTFD_BIT_DATAMATCH,
|
||||
+ MSHV_IOEVENTFD_BIT_PIO,
|
||||
+ MSHV_IOEVENTFD_BIT_DEASSIGN,
|
||||
+ MSHV_IOEVENTFD_BIT_COUNT,
|
||||
+};
|
||||
+
|
||||
+#define MSHV_IOEVENTFD_FLAGS_MASK ((1 << MSHV_IOEVENTFD_BIT_COUNT) - 1)
|
||||
+
|
||||
+struct mshv_user_ioeventfd {
|
||||
+ __u64 datamatch;
|
||||
+ __u64 addr; /* legal pio/mmio address */
|
||||
+ __u32 len; /* 1, 2, 4, or 8 bytes */
|
||||
+ __s32 fd;
|
||||
+ __u32 flags;
|
||||
+ __u8 rsvd[4];
|
||||
+};
|
||||
+
|
||||
+struct mshv_user_irq_entry {
|
||||
+ __u32 gsi;
|
||||
+ __u32 address_lo;
|
||||
+ __u32 address_hi;
|
||||
+ __u32 data;
|
||||
+};
|
||||
+
|
||||
+struct mshv_user_irq_table {
|
||||
+ __u32 nr;
|
||||
+ __u32 rsvd; /* MBZ */
|
||||
+ struct mshv_user_irq_entry entries[];
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_GPAP_ACCESS_TYPE_ACCESSED,
|
||||
+ MSHV_GPAP_ACCESS_TYPE_DIRTY,
|
||||
+ MSHV_GPAP_ACCESS_TYPE_COUNT /* Count of enum members */
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_GPAP_ACCESS_OP_NOOP,
|
||||
+ MSHV_GPAP_ACCESS_OP_CLEAR,
|
||||
+ MSHV_GPAP_ACCESS_OP_SET,
|
||||
+ MSHV_GPAP_ACCESS_OP_COUNT /* Count of enum members */
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_gpap_access_bitmap - arguments for MSHV_GET_GPAP_ACCESS_BITMAP
|
||||
+ * @access_type: MSHV_GPAP_ACCESS_TYPE_* - The type of access to record in the
|
||||
+ * bitmap
|
||||
+ * @access_op: MSHV_GPAP_ACCESS_OP_* - Allows an optional clear or set of all
|
||||
+ * the access states in the range, after retrieving the current
|
||||
+ * states.
|
||||
+ * @rsvd: MBZ
|
||||
+ * @page_count: Number of pages
|
||||
+ * @gpap_base: Base gpa page number
|
||||
+ * @bitmap_ptr: Output buffer for bitmap, at least (page_count + 7) / 8 bytes
|
||||
+ *
|
||||
+ * Retrieve a bitmap of either ACCESSED or DIRTY bits for a given range of guest
|
||||
+ * memory, and optionally clear or set the bits.
|
||||
+ */
|
||||
+struct mshv_gpap_access_bitmap {
|
||||
+ __u8 access_type;
|
||||
+ __u8 access_op;
|
||||
+ __u8 rsvd[6];
|
||||
+ __u64 page_count;
|
||||
+ __u64 gpap_base;
|
||||
+ __u64 bitmap_ptr;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_root_hvcall - arguments for MSHV_ROOT_HVCALL
|
||||
+ * @code: Hypercall code (HVCALL_*)
|
||||
+ * @reps: in: Rep count ('repcount')
|
||||
+ * out: Reps completed ('repcomp'). MBZ unless rep hvcall
|
||||
+ * @in_sz: Size of input incl rep data. <= MSHV_HV_PAGE_SIZE
|
||||
+ * @out_sz: Size of output buffer. <= MSHV_HV_PAGE_SIZE. MBZ if out_ptr is 0
|
||||
+ * @status: in: MBZ
|
||||
+ * out: HV_STATUS_* from hypercall
|
||||
+ * @rsvd: MBZ
|
||||
+ * @in_ptr: Input data buffer (struct hv_input_*). If used with partition or
|
||||
+ * vp fd, partition id field is populated by kernel.
|
||||
+ * @out_ptr: Output data buffer (optional)
|
||||
+ */
|
||||
+struct mshv_root_hvcall {
|
||||
+ __u16 code;
|
||||
+ __u16 reps;
|
||||
+ __u16 in_sz;
|
||||
+ __u16 out_sz;
|
||||
+ __u16 status;
|
||||
+ __u8 rsvd[6];
|
||||
+ __u64 in_ptr;
|
||||
+ __u64 out_ptr;
|
||||
+};
|
||||
+
|
||||
+/* Partition fds created with MSHV_CREATE_PARTITION */
|
||||
+#define MSHV_INITIALIZE_PARTITION _IO(MSHV_IOCTL, 0x00)
|
||||
+#define MSHV_CREATE_VP _IOW(MSHV_IOCTL, 0x01, struct mshv_create_vp)
|
||||
+#define MSHV_SET_GUEST_MEMORY _IOW(MSHV_IOCTL, 0x02, struct mshv_user_mem_region)
|
||||
+#define MSHV_IRQFD _IOW(MSHV_IOCTL, 0x03, struct mshv_user_irqfd)
|
||||
+#define MSHV_IOEVENTFD _IOW(MSHV_IOCTL, 0x04, struct mshv_user_ioeventfd)
|
||||
+#define MSHV_SET_MSI_ROUTING _IOW(MSHV_IOCTL, 0x05, struct mshv_user_irq_table)
|
||||
+#define MSHV_GET_GPAP_ACCESS_BITMAP _IOWR(MSHV_IOCTL, 0x06, struct mshv_gpap_access_bitmap)
|
||||
+/* Generic hypercall */
|
||||
+#define MSHV_ROOT_HVCALL _IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)
|
||||
+
|
||||
+/*
|
||||
+ ********************************
|
||||
+ * VP APIs for child partitions *
|
||||
+ ********************************
|
||||
+ */
|
||||
+
|
||||
+#define MSHV_RUN_VP_BUF_SZ 256
|
||||
+
|
||||
+/*
|
||||
+ * VP state pages may be mapped to userspace via mmap().
|
||||
+ * To specify which state page, use MSHV_VP_MMAP_OFFSET_ values multiplied by
|
||||
+ * the system page size.
|
||||
+ * e.g.
|
||||
+ * long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
+ * void *reg_page = mmap(NULL, MSHV_HV_PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
+ * MAP_SHARED, vp_fd,
|
||||
+ * MSHV_VP_MMAP_OFFSET_REGISTERS * page_size);
|
||||
+ */
|
||||
+enum {
|
||||
+ MSHV_VP_MMAP_OFFSET_REGISTERS,
|
||||
+ MSHV_VP_MMAP_OFFSET_INTERCEPT_MESSAGE,
|
||||
+ MSHV_VP_MMAP_OFFSET_GHCB,
|
||||
+ MSHV_VP_MMAP_OFFSET_COUNT
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_run_vp - argument for MSHV_RUN_VP
|
||||
+ * @msg_buf: On success, the intercept message is copied here. It can be
|
||||
+ * interpreted using the relevant hypervisor definitions.
|
||||
+ */
|
||||
+struct mshv_run_vp {
|
||||
+ __u8 msg_buf[MSHV_RUN_VP_BUF_SZ];
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ MSHV_VP_STATE_LAPIC, /* Local interrupt controller state (either arch) */
|
||||
+ MSHV_VP_STATE_XSAVE, /* XSAVE data in compacted form (x86_64) */
|
||||
+ MSHV_VP_STATE_SIMP,
|
||||
+ MSHV_VP_STATE_SIEFP,
|
||||
+ MSHV_VP_STATE_SYNTHETIC_TIMERS,
|
||||
+ MSHV_VP_STATE_COUNT,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mshv_get_set_vp_state - arguments for MSHV_[GET,SET]_VP_STATE
|
||||
+ * @type: MSHV_VP_STATE_*
|
||||
+ * @rsvd: MBZ
|
||||
+ * @buf_sz: in: 4k page-aligned size of buffer
|
||||
+ * out: Actual size of data (on EINVAL, check this to see if buffer
|
||||
+ * was too small)
|
||||
+ * @buf_ptr: 4k page-aligned data buffer
|
||||
+ */
|
||||
+struct mshv_get_set_vp_state {
|
||||
+ __u8 type;
|
||||
+ __u8 rsvd[3];
|
||||
+ __u32 buf_sz;
|
||||
+ __u64 buf_ptr;
|
||||
+};
|
||||
+
|
||||
+/* VP fds created with MSHV_CREATE_VP */
|
||||
+#define MSHV_RUN_VP _IOR(MSHV_IOCTL, 0x00, struct mshv_run_vp)
|
||||
+#define MSHV_GET_VP_STATE _IOWR(MSHV_IOCTL, 0x01, struct mshv_get_set_vp_state)
|
||||
+#define MSHV_SET_VP_STATE _IOWR(MSHV_IOCTL, 0x02, struct mshv_get_set_vp_state)
|
||||
+/*
|
||||
+ * Generic hypercall
|
||||
+ * Defined above in partition IOCTLs, avoid redefining it here
|
||||
+ * #define MSHV_ROOT_HVCALL _IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)
|
||||
+ */
|
||||
+
|
||||
+#endif
|
||||
292
0064-accel-mshv-Add-accelerator-skeleton.patch
Normal file
292
0064-accel-mshv-Add-accelerator-skeleton.patch
Normal file
@ -0,0 +1,292 @@
|
||||
From 22dc2eb8f036f562d7867d1827c4c66f4488a48e Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Thu, 2 Oct 2025 18:25:02 +0200
|
||||
Subject: [PATCH] accel/mshv: Add accelerator skeleton
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [7/30] 2bf55db3c9fbc6ce5964090f192be3699ae2ea00
|
||||
|
||||
Introduce the initial scaffold for the MSHV (Microsoft Hypervisor)
|
||||
accelerator backend. This includes the basic directory structure and
|
||||
stub implementations needed to integrate with QEMU's accelerator
|
||||
framework.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-8-magnuskulke@linux.microsoft.com
|
||||
[Move include of linux/mshv.h in the per-target section; create
|
||||
include/system/mshv_int.h. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit d0d2918f968c55628e17e2733b799fcefb50f16b)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-Add-accelerator-skeleton.patch
|
||||
Patch-id: 67
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/meson.build | 1 +
|
||||
accel/mshv/meson.build | 6 ++
|
||||
accel/mshv/mshv-all.c | 144 ++++++++++++++++++++++++++++++++++++++
|
||||
include/system/mshv.h | 12 ++++
|
||||
include/system/mshv_int.h | 41 +++++++++++
|
||||
5 files changed, 204 insertions(+)
|
||||
create mode 100644 accel/mshv/meson.build
|
||||
create mode 100644 accel/mshv/mshv-all.c
|
||||
create mode 100644 include/system/mshv_int.h
|
||||
|
||||
diff --git a/accel/meson.build b/accel/meson.build
|
||||
index 6349efe682..983dfd0bd5 100644
|
||||
--- a/accel/meson.build
|
||||
+++ b/accel/meson.build
|
||||
@@ -10,6 +10,7 @@ if have_system
|
||||
subdir('kvm')
|
||||
subdir('xen')
|
||||
subdir('stubs')
|
||||
+ subdir('mshv')
|
||||
endif
|
||||
|
||||
# qtest
|
||||
diff --git a/accel/mshv/meson.build b/accel/mshv/meson.build
|
||||
new file mode 100644
|
||||
index 0000000000..4c03ac7921
|
||||
--- /dev/null
|
||||
+++ b/accel/mshv/meson.build
|
||||
@@ -0,0 +1,6 @@
|
||||
+mshv_ss = ss.source_set()
|
||||
+mshv_ss.add(if_true: files(
|
||||
+ 'mshv-all.c'
|
||||
+))
|
||||
+
|
||||
+specific_ss.add_all(when: 'CONFIG_MSHV', if_true: mshv_ss)
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
new file mode 100644
|
||||
index 0000000000..ae12f0f58b
|
||||
--- /dev/null
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Ziqiao Zhou <ziqiaozhou@microsoft.com>
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ * Jinank Jain <jinankjain@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "qemu/event_notifier.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "qemu/main-loop.h"
|
||||
+#include "hw/boards.h"
|
||||
+
|
||||
+#include "hw/hyperv/hvhdk.h"
|
||||
+#include "hw/hyperv/hvhdk_mini.h"
|
||||
+#include "hw/hyperv/hvgdk.h"
|
||||
+#include "linux/mshv.h"
|
||||
+
|
||||
+#include "qemu/accel.h"
|
||||
+#include "qemu/guest-random.h"
|
||||
+#include "accel/accel-ops.h"
|
||||
+#include "accel/accel-cpu-ops.h"
|
||||
+#include "system/cpus.h"
|
||||
+#include "system/runstate.h"
|
||||
+#include "system/accel-blocker.h"
|
||||
+#include "system/address-spaces.h"
|
||||
+#include "system/mshv.h"
|
||||
+#include "system/mshv_int.h"
|
||||
+#include "system/reset.h"
|
||||
+#include "trace.h"
|
||||
+#include <err.h>
|
||||
+#include <stdint.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+
|
||||
+#define TYPE_MSHV_ACCEL ACCEL_CLASS_NAME("mshv")
|
||||
+
|
||||
+DECLARE_INSTANCE_CHECKER(MshvState, MSHV_STATE, TYPE_MSHV_ACCEL)
|
||||
+
|
||||
+bool mshv_allowed;
|
||||
+
|
||||
+MshvState *mshv_state;
|
||||
+
|
||||
+static int mshv_init(AccelState *as, MachineState *ms)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_start_vcpu_thread(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_cpu_synchronize_post_init(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_cpu_synchronize_post_reset(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_cpu_synchronize_pre_loadvm(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_cpu_synchronize(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static bool mshv_cpus_are_resettable(void)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void mshv_accel_class_init(ObjectClass *oc, const void *data)
|
||||
+{
|
||||
+ AccelClass *ac = ACCEL_CLASS(oc);
|
||||
+
|
||||
+ ac->name = "MSHV";
|
||||
+ ac->init_machine = mshv_init;
|
||||
+ ac->allowed = &mshv_allowed;
|
||||
+}
|
||||
+
|
||||
+static void mshv_accel_instance_init(Object *obj)
|
||||
+{
|
||||
+ MshvState *s = MSHV_STATE(obj);
|
||||
+
|
||||
+ s->vm = 0;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo mshv_accel_type = {
|
||||
+ .name = TYPE_MSHV_ACCEL,
|
||||
+ .parent = TYPE_ACCEL,
|
||||
+ .instance_init = mshv_accel_instance_init,
|
||||
+ .class_init = mshv_accel_class_init,
|
||||
+ .instance_size = sizeof(MshvState),
|
||||
+};
|
||||
+
|
||||
+static void mshv_accel_ops_class_init(ObjectClass *oc, const void *data)
|
||||
+{
|
||||
+ AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
|
||||
+
|
||||
+ ops->create_vcpu_thread = mshv_start_vcpu_thread;
|
||||
+ ops->synchronize_post_init = mshv_cpu_synchronize_post_init;
|
||||
+ ops->synchronize_post_reset = mshv_cpu_synchronize_post_reset;
|
||||
+ ops->synchronize_state = mshv_cpu_synchronize;
|
||||
+ ops->synchronize_pre_loadvm = mshv_cpu_synchronize_pre_loadvm;
|
||||
+ ops->cpus_are_resettable = mshv_cpus_are_resettable;
|
||||
+ ops->handle_interrupt = generic_handle_interrupt;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo mshv_accel_ops_type = {
|
||||
+ .name = ACCEL_OPS_NAME("mshv"),
|
||||
+ .parent = TYPE_ACCEL_OPS,
|
||||
+ .class_init = mshv_accel_ops_class_init,
|
||||
+ .abstract = true,
|
||||
+};
|
||||
+
|
||||
+static void mshv_type_init(void)
|
||||
+{
|
||||
+ type_register_static(&mshv_accel_type);
|
||||
+ type_register_static(&mshv_accel_ops_type);
|
||||
+}
|
||||
+
|
||||
+type_init(mshv_type_init);
|
||||
diff --git a/include/system/mshv.h b/include/system/mshv.h
|
||||
index 2a504ed81f..434ea9682e 100644
|
||||
--- a/include/system/mshv.h
|
||||
+++ b/include/system/mshv.h
|
||||
@@ -14,8 +14,17 @@
|
||||
#ifndef QEMU_MSHV_H
|
||||
#define QEMU_MSHV_H
|
||||
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qemu/accel.h"
|
||||
+#include "hw/hyperv/hyperv-proto.h"
|
||||
+#include "hw/hyperv/hvhdk.h"
|
||||
+#include "qapi/qapi-types-common.h"
|
||||
+#include "system/memory.h"
|
||||
+#include "accel/accel-ops.h"
|
||||
+
|
||||
#ifdef COMPILING_PER_TARGET
|
||||
#ifdef CONFIG_MSHV
|
||||
+#include <linux/mshv.h>
|
||||
#define CONFIG_MSHV_IS_POSSIBLE
|
||||
#endif
|
||||
#else
|
||||
@@ -30,6 +39,9 @@ extern bool mshv_allowed;
|
||||
#endif
|
||||
#define mshv_msi_via_irqfd_enabled() false
|
||||
|
||||
+typedef struct MshvState MshvState;
|
||||
+extern MshvState *mshv_state;
|
||||
+
|
||||
/* interrupt */
|
||||
int mshv_irqchip_add_msi_route(int vector, PCIDevice *dev);
|
||||
int mshv_irqchip_update_msi_route(int virq, MSIMessage msg, PCIDevice *dev);
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
new file mode 100644
|
||||
index 0000000000..132491b599
|
||||
--- /dev/null
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Ziqiao Zhou <ziqiaozhou@microsoft.com>
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ * Jinank Jain <jinankjain@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef QEMU_MSHV_INT_H
|
||||
+#define QEMU_MSHV_INT_H
|
||||
+
|
||||
+struct AccelCPUState {
|
||||
+ int cpufd;
|
||||
+ bool dirty;
|
||||
+};
|
||||
+
|
||||
+typedef struct MshvMemoryListener {
|
||||
+ MemoryListener listener;
|
||||
+ int as_id;
|
||||
+} MshvMemoryListener;
|
||||
+
|
||||
+typedef struct MshvAddressSpace {
|
||||
+ MshvMemoryListener *ml;
|
||||
+ AddressSpace *as;
|
||||
+} MshvAddressSpace;
|
||||
+
|
||||
+struct MshvState {
|
||||
+ AccelState parent_obj;
|
||||
+ int vm;
|
||||
+ MshvMemoryListener memory_listener;
|
||||
+ /* number of listeners */
|
||||
+ int nr_as;
|
||||
+ MshvAddressSpace *as;
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
173
0065-accel-mshv-Register-memory-region-listeners.patch
Normal file
173
0065-accel-mshv-Register-memory-region-listeners.patch
Normal file
@ -0,0 +1,173 @@
|
||||
From 49e8b7e37e4e481be6a821ec6482c4e8b04e4573 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:28 +0200
|
||||
Subject: [PATCH] accel/mshv: Register memory region listeners
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [8/30] ecd0d05d8f04c400ad1d9c428f89b23b12889968
|
||||
|
||||
Add memory listener hooks for the MSHV accelerator to track guest
|
||||
memory regions. This enables the backend to respond to region
|
||||
additions, removals and will be used to manage guest memory mappings
|
||||
inside the hypervisor.
|
||||
|
||||
Actually registering physical memory in the hypervisor is still stubbed
|
||||
out.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-9-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 5006ea1344d134356a9b2e1afd521cf8df0c6a85)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-Register-memory-region-listeners.patch
|
||||
Patch-id: 68
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mem.c | 25 +++++++++++++++
|
||||
accel/mshv/meson.build | 1 +
|
||||
accel/mshv/mshv-all.c | 67 +++++++++++++++++++++++++++++++++++++--
|
||||
include/system/mshv_int.h | 4 +++
|
||||
4 files changed, 95 insertions(+), 2 deletions(-)
|
||||
create mode 100644 accel/mshv/mem.c
|
||||
|
||||
diff --git a/accel/mshv/mem.c b/accel/mshv/mem.c
|
||||
new file mode 100644
|
||||
index 0000000000..9889918c31
|
||||
--- /dev/null
|
||||
+++ b/accel/mshv/mem.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "system/address-spaces.h"
|
||||
+#include "system/mshv.h"
|
||||
+#include "system/mshv_int.h"
|
||||
+
|
||||
+void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
+ bool add)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
diff --git a/accel/mshv/meson.build b/accel/mshv/meson.build
|
||||
index 4c03ac7921..8a6beb3fb1 100644
|
||||
--- a/accel/mshv/meson.build
|
||||
+++ b/accel/mshv/meson.build
|
||||
@@ -1,5 +1,6 @@
|
||||
mshv_ss = ss.source_set()
|
||||
mshv_ss.add(if_true: files(
|
||||
+ 'mem.c',
|
||||
'mshv-all.c'
|
||||
))
|
||||
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index ae12f0f58b..a684a36677 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -49,10 +49,73 @@ bool mshv_allowed;
|
||||
|
||||
MshvState *mshv_state;
|
||||
|
||||
+static void mem_region_add(MemoryListener *listener,
|
||||
+ MemoryRegionSection *section)
|
||||
+{
|
||||
+ MshvMemoryListener *mml;
|
||||
+ mml = container_of(listener, MshvMemoryListener, listener);
|
||||
+ memory_region_ref(section->mr);
|
||||
+ mshv_set_phys_mem(mml, section, true);
|
||||
+}
|
||||
+
|
||||
+static void mem_region_del(MemoryListener *listener,
|
||||
+ MemoryRegionSection *section)
|
||||
+{
|
||||
+ MshvMemoryListener *mml;
|
||||
+ mml = container_of(listener, MshvMemoryListener, listener);
|
||||
+ mshv_set_phys_mem(mml, section, false);
|
||||
+ memory_region_unref(section->mr);
|
||||
+}
|
||||
+
|
||||
+static MemoryListener mshv_memory_listener = {
|
||||
+ .name = "mshv",
|
||||
+ .priority = MEMORY_LISTENER_PRIORITY_ACCEL,
|
||||
+ .region_add = mem_region_add,
|
||||
+ .region_del = mem_region_del,
|
||||
+};
|
||||
+
|
||||
+static MemoryListener mshv_io_listener = {
|
||||
+ .name = "mshv", .priority = MEMORY_LISTENER_PRIORITY_DEV_BACKEND,
|
||||
+ /* MSHV does not support PIO eventfd */
|
||||
+};
|
||||
+
|
||||
+static void register_mshv_memory_listener(MshvState *s, MshvMemoryListener *mml,
|
||||
+ AddressSpace *as, int as_id,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ mml->listener = mshv_memory_listener;
|
||||
+ mml->listener.name = name;
|
||||
+ memory_listener_register(&mml->listener, as);
|
||||
+ for (i = 0; i < s->nr_as; ++i) {
|
||||
+ if (!s->as[i].as) {
|
||||
+ s->as[i].as = as;
|
||||
+ s->as[i].ml = mml;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int mshv_init(AccelState *as, MachineState *ms)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ MshvState *s;
|
||||
+ s = MSHV_STATE(as);
|
||||
+
|
||||
+ accel_blocker_init();
|
||||
+
|
||||
+ s->vm = 0;
|
||||
+
|
||||
+ s->nr_as = 1;
|
||||
+ s->as = g_new0(MshvAddressSpace, s->nr_as);
|
||||
+
|
||||
+ mshv_state = s;
|
||||
+
|
||||
+ register_mshv_memory_listener(s, &s->memory_listener, &address_space_memory,
|
||||
+ 0, "mshv-memory");
|
||||
+ memory_listener_register(&mshv_io_listener, &address_space_io);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mshv_start_vcpu_thread(CPUState *cpu)
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index 132491b599..cfa177ff72 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -38,4 +38,8 @@ struct MshvState {
|
||||
MshvAddressSpace *as;
|
||||
};
|
||||
|
||||
+/* memory */
|
||||
+void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
+ bool add);
|
||||
+
|
||||
#endif
|
||||
1303
0066-accel-mshv-Initialize-VM-partition.patch
Normal file
1303
0066-accel-mshv-Initialize-VM-partition.patch
Normal file
File diff suppressed because it is too large
Load Diff
219
0067-treewide-rename-qemu_wait_io_event-qemu_wait_io_even.patch
Normal file
219
0067-treewide-rename-qemu_wait_io_event-qemu_wait_io_even.patch
Normal file
@ -0,0 +1,219 @@
|
||||
From d6f3367b197d060d35aeeb781828d0ca4e3dc584 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Tue, 2 Sep 2025 07:17:09 +0200
|
||||
Subject: [PATCH] treewide: rename qemu_wait_io_event/qemu_wait_io_event_common
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [10/30] 501e99aab6fb49429b23c688cffbecdf283c89dd
|
||||
|
||||
Do so before extending it to the user-mode emulators, where there is no
|
||||
such thing as an "I/O thread".
|
||||
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 871de7078fcaf597605576b97b32fab14722ea43)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Conflicts: (due to missing cpu exit/interrupt_request refactoring)
|
||||
cpu-common.c
|
||||
include/hw/core/cpu.h
|
||||
|
||||
Patch-name: kvm-treewide-rename-qemu_wait_io_event-qemu_wait_io_even.patch
|
||||
Patch-id: 70
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/dummy-cpus.c | 2 +-
|
||||
accel/hvf/hvf-accel-ops.c | 2 +-
|
||||
accel/kvm/kvm-accel-ops.c | 2 +-
|
||||
accel/tcg/tcg-accel-ops-mttcg.c | 2 +-
|
||||
accel/tcg/tcg-accel-ops-rr.c | 4 ++--
|
||||
cpu-common.c | 1 +
|
||||
include/hw/core/cpu.h | 9 +++++++++
|
||||
include/system/cpus.h | 4 ++--
|
||||
system/cpus.c | 6 +++---
|
||||
target/i386/nvmm/nvmm-accel-ops.c | 2 +-
|
||||
target/i386/whpx/whpx-accel-ops.c | 2 +-
|
||||
11 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/accel/dummy-cpus.c b/accel/dummy-cpus.c
|
||||
index 03cfc0fa01..225a47c31f 100644
|
||||
--- a/accel/dummy-cpus.c
|
||||
+++ b/accel/dummy-cpus.c
|
||||
@@ -57,7 +57,7 @@ static void *dummy_cpu_thread_fn(void *arg)
|
||||
qemu_sem_wait(&cpu->sem);
|
||||
#endif
|
||||
bql_lock();
|
||||
- qemu_wait_io_event(cpu);
|
||||
+ qemu_process_cpu_events(cpu);
|
||||
} while (!cpu->unplug);
|
||||
|
||||
bql_unlock();
|
||||
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
|
||||
index d488d6afba..7a27bdadb4 100644
|
||||
--- a/accel/hvf/hvf-accel-ops.c
|
||||
+++ b/accel/hvf/hvf-accel-ops.c
|
||||
@@ -198,7 +198,7 @@ static void *hvf_cpu_thread_fn(void *arg)
|
||||
cpu_handle_guest_debug(cpu);
|
||||
}
|
||||
}
|
||||
- qemu_wait_io_event(cpu);
|
||||
+ qemu_process_cpu_events(cpu);
|
||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||
|
||||
hvf_vcpu_destroy(cpu);
|
||||
diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
|
||||
index b709187c7d..65a7f76a69 100644
|
||||
--- a/accel/kvm/kvm-accel-ops.c
|
||||
+++ b/accel/kvm/kvm-accel-ops.c
|
||||
@@ -53,7 +53,7 @@ static void *kvm_vcpu_thread_fn(void *arg)
|
||||
cpu_handle_guest_debug(cpu);
|
||||
}
|
||||
}
|
||||
- qemu_wait_io_event(cpu);
|
||||
+ qemu_process_cpu_events(cpu);
|
||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||
|
||||
kvm_destroy_vcpu(cpu);
|
||||
diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
|
||||
index 337b993d3d..a3255000df 100644
|
||||
--- a/accel/tcg/tcg-accel-ops-mttcg.c
|
||||
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
|
||||
@@ -113,7 +113,7 @@ static void *mttcg_cpu_thread_fn(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
- qemu_wait_io_event(cpu);
|
||||
+ qemu_process_cpu_events(cpu);
|
||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||
|
||||
tcg_cpu_destroy(cpu);
|
||||
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
|
||||
index 6eec5c9eee..60ad1a39f0 100644
|
||||
--- a/accel/tcg/tcg-accel-ops-rr.c
|
||||
+++ b/accel/tcg/tcg-accel-ops-rr.c
|
||||
@@ -117,7 +117,7 @@ static void rr_wait_io_event(void)
|
||||
rr_start_kick_timer();
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
- qemu_wait_io_event_common(cpu);
|
||||
+ qemu_process_cpu_events_common(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ static void *rr_cpu_thread_fn(void *arg)
|
||||
/* process any pending work */
|
||||
CPU_FOREACH(cpu) {
|
||||
current_cpu = cpu;
|
||||
- qemu_wait_io_event_common(cpu);
|
||||
+ qemu_process_cpu_events_common(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/cpu-common.c b/cpu-common.c
|
||||
index ef5757d23b..8e4cbac290 100644
|
||||
--- a/cpu-common.c
|
||||
+++ b/cpu-common.c
|
||||
@@ -137,6 +137,7 @@ static void queue_work_on_cpu(CPUState *cpu, struct qemu_work_item *wi)
|
||||
wi->done = false;
|
||||
qemu_mutex_unlock(&cpu->work_mutex);
|
||||
|
||||
+ /* conflict fixup due missing exit and interrupt refactoring */
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
|
||||
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
|
||||
index 5eaf41a566..fadd6c5ac0 100644
|
||||
--- a/include/hw/core/cpu.h
|
||||
+++ b/include/hw/core/cpu.h
|
||||
@@ -422,6 +422,15 @@ struct qemu_work_item;
|
||||
* valid under cpu_list_lock.
|
||||
* @created: Indicates whether the CPU thread has been successfully created.
|
||||
* @halt_cond: condition variable sleeping threads can wait on.
|
||||
+ * @exit_request: Another thread requests the CPU to call qemu_process_cpu_events().
|
||||
+ * Should be read only by CPU thread with load-acquire, to synchronize with
|
||||
+ * other threads' store-release operation.
|
||||
+ *
|
||||
+ * In some cases, accelerator-specific code will write exit_request from
|
||||
+ * within the same thread, to "bump" the effect of qemu_cpu_kick() to
|
||||
+ * the one provided by cpu_exit(), especially when processing interrupt
|
||||
+ * flags. In this case, the write and read happen in the same thread
|
||||
+ * and the write therefore can use qemu_atomic_set().
|
||||
* @interrupt_request: Indicates a pending interrupt request.
|
||||
* @halted: Nonzero if the CPU is in suspended state.
|
||||
* @stop: Indicates a pending stop request.
|
||||
diff --git a/include/system/cpus.h b/include/system/cpus.h
|
||||
index 69be6a77a7..4aebec4870 100644
|
||||
--- a/include/system/cpus.h
|
||||
+++ b/include/system/cpus.h
|
||||
@@ -17,8 +17,8 @@ bool cpu_work_list_empty(CPUState *cpu);
|
||||
bool cpu_thread_is_idle(CPUState *cpu);
|
||||
bool all_cpu_threads_idle(void);
|
||||
bool cpu_can_run(CPUState *cpu);
|
||||
-void qemu_wait_io_event_common(CPUState *cpu);
|
||||
-void qemu_wait_io_event(CPUState *cpu);
|
||||
+void qemu_process_cpu_events_common(CPUState *cpu);
|
||||
+void qemu_process_cpu_events(CPUState *cpu);
|
||||
void cpu_thread_signal_created(CPUState *cpu);
|
||||
void cpu_thread_signal_destroyed(CPUState *cpu);
|
||||
void cpu_handle_guest_debug(CPUState *cpu);
|
||||
diff --git a/system/cpus.c b/system/cpus.c
|
||||
index 256723558d..efffbd8df6 100644
|
||||
--- a/system/cpus.c
|
||||
+++ b/system/cpus.c
|
||||
@@ -444,7 +444,7 @@ static void qemu_cpu_stop(CPUState *cpu, bool exit)
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
}
|
||||
|
||||
-void qemu_wait_io_event_common(CPUState *cpu)
|
||||
+void qemu_process_cpu_events_common(CPUState *cpu)
|
||||
{
|
||||
qatomic_set_mb(&cpu->thread_kicked, false);
|
||||
if (cpu->stop) {
|
||||
@@ -453,7 +453,7 @@ void qemu_wait_io_event_common(CPUState *cpu)
|
||||
process_queued_cpu_work(cpu);
|
||||
}
|
||||
|
||||
-void qemu_wait_io_event(CPUState *cpu)
|
||||
+void qemu_process_cpu_events(CPUState *cpu)
|
||||
{
|
||||
bool slept = false;
|
||||
|
||||
@@ -468,7 +468,7 @@ void qemu_wait_io_event(CPUState *cpu)
|
||||
qemu_plugin_vcpu_resume_cb(cpu);
|
||||
}
|
||||
|
||||
- qemu_wait_io_event_common(cpu);
|
||||
+ qemu_process_cpu_events_common(cpu);
|
||||
}
|
||||
|
||||
void cpus_kick_thread(CPUState *cpu)
|
||||
diff --git a/target/i386/nvmm/nvmm-accel-ops.c b/target/i386/nvmm/nvmm-accel-ops.c
|
||||
index 3799260bbd..c7b1d0f1d3 100644
|
||||
--- a/target/i386/nvmm/nvmm-accel-ops.c
|
||||
+++ b/target/i386/nvmm/nvmm-accel-ops.c
|
||||
@@ -51,7 +51,7 @@ static void *qemu_nvmm_cpu_thread_fn(void *arg)
|
||||
while (cpu_thread_is_idle(cpu)) {
|
||||
qemu_cond_wait_bql(cpu->halt_cond);
|
||||
}
|
||||
- qemu_wait_io_event_common(cpu);
|
||||
+ qemu_process_cpu_events_common(cpu);
|
||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||
|
||||
nvmm_destroy_vcpu(cpu);
|
||||
diff --git a/target/i386/whpx/whpx-accel-ops.c b/target/i386/whpx/whpx-accel-ops.c
|
||||
index da58805b1a..2ca4ee0263 100644
|
||||
--- a/target/i386/whpx/whpx-accel-ops.c
|
||||
+++ b/target/i386/whpx/whpx-accel-ops.c
|
||||
@@ -51,7 +51,7 @@ static void *whpx_cpu_thread_fn(void *arg)
|
||||
while (cpu_thread_is_idle(cpu)) {
|
||||
qemu_cond_wait_bql(cpu->halt_cond);
|
||||
}
|
||||
- qemu_wait_io_event_common(cpu);
|
||||
+ qemu_process_cpu_events_common(cpu);
|
||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||
|
||||
whpx_destroy_vcpu(cpu);
|
||||
418
0068-accel-mshv-Add-vCPU-creation-and-execution-loop.patch
Normal file
418
0068-accel-mshv-Add-vCPU-creation-and-execution-loop.patch
Normal file
@ -0,0 +1,418 @@
|
||||
From 2d8f8fb4690faad8f1b9a93af2aad04a0502acb2 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:30 +0200
|
||||
Subject: [PATCH] accel/mshv: Add vCPU creation and execution loop
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [11/30] e235ebda329666192a3bf95fb4fee018f5f5f10e
|
||||
|
||||
Create MSHV vCPUs using MSHV_CREATE_VP and initialize their state.
|
||||
Register the MSHV CPU execution loop loop with the QEMU accelerator
|
||||
framework to enable guest code execution.
|
||||
|
||||
The target/i386 functionality is still mostly stubbed out and will be
|
||||
populated in a later commit in this series.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-11-magnuskulke@linux.microsoft.com
|
||||
[Fix g_free/g_clear_pointer confusion; rename qemu_wait_io_event;
|
||||
mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 4dc5d4257259764b6fcd035870517fc4140d8962)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-Add-vCPU-creation-and-execution-loop.patch
|
||||
Patch-id: 71
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mshv-all.c | 186 +++++++++++++++++++++++++++++++++---
|
||||
accel/mshv/trace-events | 2 +
|
||||
include/system/mshv.h | 2 +-
|
||||
include/system/mshv_int.h | 20 ++++
|
||||
target/i386/mshv/mshv-cpu.c | 63 ++++++++++++
|
||||
5 files changed, 260 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index 653195c57c..e02421d79d 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -393,6 +393,24 @@ int mshv_hvcall(int fd, const struct mshv_root_hvcall *args)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int mshv_init_vcpu(CPUState *cpu)
|
||||
+{
|
||||
+ int vm_fd = mshv_state->vm;
|
||||
+ uint8_t vp_index = cpu->cpu_index;
|
||||
+ int ret;
|
||||
+
|
||||
+ mshv_arch_init_vcpu(cpu);
|
||||
+ cpu->accel = g_new0(AccelCPUState, 1);
|
||||
+
|
||||
+ ret = mshv_create_vcpu(vm_fd, vp_index, &cpu->accel->cpufd);
|
||||
+ if (ret < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ cpu->accel->dirty = true;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
static int mshv_init(AccelState *as, MachineState *ms)
|
||||
{
|
||||
@@ -415,6 +433,8 @@ static int mshv_init(AccelState *as, MachineState *ms)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ mshv_init_mmio_emu();
|
||||
+
|
||||
mshv_init_msicontrol();
|
||||
|
||||
ret = create_vm(mshv_fd, &vm_fd);
|
||||
@@ -444,40 +464,182 @@ static int mshv_init(AccelState *as, MachineState *ms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int mshv_destroy_vcpu(CPUState *cpu)
|
||||
+{
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+ int vm_fd = mshv_state->vm;
|
||||
+
|
||||
+ mshv_remove_vcpu(vm_fd, cpu_fd);
|
||||
+ mshv_vcpufd(cpu) = 0;
|
||||
+
|
||||
+ mshv_arch_destroy_vcpu(cpu);
|
||||
+ g_clear_pointer(&cpu->accel, g_free);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mshv_cpu_exec(CPUState *cpu)
|
||||
+{
|
||||
+ hv_message mshv_msg;
|
||||
+ enum MshvVmExit exit_reason;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ bql_unlock();
|
||||
+ cpu_exec_start(cpu);
|
||||
+
|
||||
+ do {
|
||||
+ if (cpu->accel->dirty) {
|
||||
+ ret = mshv_arch_put_registers(cpu);
|
||||
+ if (ret) {
|
||||
+ error_report("Failed to put registers after init: %s",
|
||||
+ strerror(-ret));
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ cpu->accel->dirty = false;
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_run_vcpu(mshv_state->vm, cpu, &mshv_msg, &exit_reason);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to run on vcpu %d", cpu->cpu_index);
|
||||
+ abort();
|
||||
+ }
|
||||
+
|
||||
+ switch (exit_reason) {
|
||||
+ case MshvVmExitIgnore:
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = EXCP_INTERRUPT;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (ret == 0);
|
||||
+
|
||||
+ cpu_exec_end(cpu);
|
||||
+ bql_lock();
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||
+ vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void *mshv_vcpu_thread(void *arg)
|
||||
+{
|
||||
+ CPUState *cpu = arg;
|
||||
+ int ret;
|
||||
+
|
||||
+ rcu_register_thread();
|
||||
+
|
||||
+ bql_lock();
|
||||
+ qemu_thread_get_self(cpu->thread);
|
||||
+ cpu->thread_id = qemu_get_thread_id();
|
||||
+ current_cpu = cpu;
|
||||
+ ret = mshv_init_vcpu(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to init vcpu %d", cpu->cpu_index);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* signal CPU creation */
|
||||
+ cpu_thread_signal_created(cpu);
|
||||
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
|
||||
+
|
||||
+ do {
|
||||
+ qemu_process_cpu_events(cpu);
|
||||
+ if (cpu_can_run(cpu)) {
|
||||
+ mshv_cpu_exec(cpu);
|
||||
+ }
|
||||
+ } while (!cpu->unplug || cpu_can_run(cpu));
|
||||
+
|
||||
+ mshv_destroy_vcpu(cpu);
|
||||
+cleanup:
|
||||
+ cpu_thread_signal_destroyed(cpu);
|
||||
+ bql_unlock();
|
||||
+ rcu_unregister_thread();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void mshv_start_vcpu_thread(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||
+
|
||||
+ cpu->thread = g_malloc0(sizeof(QemuThread));
|
||||
+ cpu->halt_cond = g_malloc0(sizeof(QemuCond));
|
||||
+
|
||||
+ qemu_cond_init(cpu->halt_cond);
|
||||
+
|
||||
+ trace_mshv_start_vcpu_thread(thread_name, cpu->cpu_index);
|
||||
+ qemu_thread_create(cpu->thread, thread_name, mshv_vcpu_thread, cpu,
|
||||
+ QEMU_THREAD_JOINABLE);
|
||||
+}
|
||||
+
|
||||
+static void do_mshv_cpu_synchronize_post_init(CPUState *cpu,
|
||||
+ run_on_cpu_data arg)
|
||||
+{
|
||||
+ int ret = mshv_arch_put_registers(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to put registers after init: %s", strerror(-ret));
|
||||
+ abort();
|
||||
+ }
|
||||
+
|
||||
+ cpu->accel->dirty = false;
|
||||
}
|
||||
|
||||
static void mshv_cpu_synchronize_post_init(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ run_on_cpu(cpu, do_mshv_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
|
||||
}
|
||||
|
||||
static void mshv_cpu_synchronize_post_reset(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ int ret = mshv_arch_put_registers(cpu);
|
||||
+ if (ret) {
|
||||
+ error_report("Failed to put registers after reset: %s",
|
||||
+ strerror(-ret));
|
||||
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||
+ vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||
+ }
|
||||
+ cpu->accel->dirty = false;
|
||||
+}
|
||||
+
|
||||
+static void do_mshv_cpu_synchronize_pre_loadvm(CPUState *cpu,
|
||||
+ run_on_cpu_data arg)
|
||||
+{
|
||||
+ cpu->accel->dirty = true;
|
||||
}
|
||||
|
||||
static void mshv_cpu_synchronize_pre_loadvm(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ run_on_cpu(cpu, do_mshv_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
|
||||
+}
|
||||
+
|
||||
+static void do_mshv_cpu_synchronize(CPUState *cpu, run_on_cpu_data arg)
|
||||
+{
|
||||
+ if (!cpu->accel->dirty) {
|
||||
+ int ret = mshv_load_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to load registers for vcpu %d",
|
||||
+ cpu->cpu_index);
|
||||
+
|
||||
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||
+ vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||
+ }
|
||||
+
|
||||
+ cpu->accel->dirty = true;
|
||||
+ }
|
||||
}
|
||||
|
||||
static void mshv_cpu_synchronize(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ if (!cpu->accel->dirty) {
|
||||
+ run_on_cpu(cpu, do_mshv_cpu_synchronize, RUN_ON_CPU_NULL);
|
||||
+ }
|
||||
}
|
||||
|
||||
static bool mshv_cpus_are_resettable(void)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static void mshv_accel_class_init(ObjectClass *oc, const void *data)
|
||||
diff --git a/accel/mshv/trace-events b/accel/mshv/trace-events
|
||||
index 6130c4abf8..a4dffeb24a 100644
|
||||
--- a/accel/mshv/trace-events
|
||||
+++ b/accel/mshv/trace-events
|
||||
@@ -3,6 +3,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
+mshv_start_vcpu_thread(const char* thread, uint32_t cpu) "thread=%s cpu_index=%d"
|
||||
+
|
||||
mshv_set_memory(bool add, uint64_t gpa, uint64_t size, uint64_t user_addr, bool readonly, int ret) "add=%d gpa=0x%" PRIx64 " size=0x%" PRIx64 " user=0x%" PRIx64 " readonly=%d result=%d"
|
||||
mshv_mem_ioeventfd_add(uint64_t addr, uint32_t size, uint32_t data) "addr=0x%" PRIx64 " size=%d data=0x%x"
|
||||
mshv_mem_ioeventfd_del(uint64_t addr, uint32_t size, uint32_t data) "addr=0x%" PRIx64 " size=%d data=0x%x"
|
||||
diff --git a/include/system/mshv.h b/include/system/mshv.h
|
||||
index 1011e81df4..bbc42f4dc3 100644
|
||||
--- a/include/system/mshv.h
|
||||
+++ b/include/system/mshv.h
|
||||
@@ -41,7 +41,7 @@ extern bool mshv_allowed;
|
||||
#define mshv_msi_via_irqfd_enabled() mshv_enabled()
|
||||
#else /* CONFIG_MSHV_IS_POSSIBLE */
|
||||
#define mshv_enabled() false
|
||||
-#define mshv_msi_via_irqfd_enabled() false
|
||||
+#define mshv_msi_via_irqfd_enabled() mshv_enabled()
|
||||
#endif
|
||||
|
||||
typedef struct MshvState MshvState;
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index b36124a0ea..fb80f69772 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef QEMU_MSHV_INT_H
|
||||
#define QEMU_MSHV_INT_H
|
||||
|
||||
+typedef struct hyperv_message hv_message;
|
||||
+
|
||||
struct AccelCPUState {
|
||||
int cpufd;
|
||||
bool dirty;
|
||||
@@ -44,6 +46,24 @@ typedef struct MshvMsiControl {
|
||||
GHashTable *gsi_routes;
|
||||
} MshvMsiControl;
|
||||
|
||||
+#define mshv_vcpufd(cpu) (cpu->accel->cpufd)
|
||||
+
|
||||
+/* cpu */
|
||||
+typedef enum MshvVmExit {
|
||||
+ MshvVmExitIgnore = 0,
|
||||
+ MshvVmExitShutdown = 1,
|
||||
+ MshvVmExitSpecial = 2,
|
||||
+} MshvVmExit;
|
||||
+
|
||||
+void mshv_init_mmio_emu(void);
|
||||
+int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
|
||||
+void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
+int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
|
||||
+int mshv_load_regs(CPUState *cpu);
|
||||
+int mshv_store_regs(CPUState *cpu);
|
||||
+int mshv_arch_put_registers(const CPUState *cpu);
|
||||
+void mshv_arch_init_vcpu(CPUState *cpu);
|
||||
+void mshv_arch_destroy_vcpu(CPUState *cpu);
|
||||
void mshv_arch_amend_proc_features(
|
||||
union hv_partition_synthetic_processor_features *features);
|
||||
int mshv_arch_post_init_vm(int vm_fd);
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index de0c26bc6c..02d71ebc14 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -22,15 +22,78 @@
|
||||
#include "hw/hyperv/hvgdk_mini.h"
|
||||
#include "hw/hyperv/hvhdk_mini.h"
|
||||
|
||||
+#include "cpu.h"
|
||||
+#include "emulate/x86_decode.h"
|
||||
+#include "emulate/x86_emu.h"
|
||||
+#include "emulate/x86_flags.h"
|
||||
+
|
||||
#include "trace-accel_mshv.h"
|
||||
#include "trace.h"
|
||||
|
||||
+int mshv_store_regs(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+int mshv_load_regs(CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+int mshv_arch_put_registers(const CPUState *cpu)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
void mshv_arch_amend_proc_features(
|
||||
union hv_partition_synthetic_processor_features *features)
|
||||
{
|
||||
features->access_guest_idle_reg = 1;
|
||||
}
|
||||
|
||||
+int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+void mshv_remove_vcpu(int vm_fd, int cpu_fd)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+void mshv_init_mmio_emu(void)
|
||||
+{
|
||||
+ error_report("unimplemented");
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+void mshv_arch_init_vcpu(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+
|
||||
+ env->emu_mmio_buf = g_new(char, 4096);
|
||||
+}
|
||||
+
|
||||
+void mshv_arch_destroy_vcpu(CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+
|
||||
+ g_clear_pointer(&env->emu_mmio_buf, g_free);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
|
||||
* fault to the guest if it tries to access it. It is possible to override
|
||||
76
0069-accel-mshv-Add-vCPU-signal-handling.patch
Normal file
76
0069-accel-mshv-Add-vCPU-signal-handling.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From f291987a12ea9ff0d7c3bed02fb23faea42f5523 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:31 +0200
|
||||
Subject: [PATCH] accel/mshv: Add vCPU signal handling
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [12/30] c3c9c5d9ad4d335a12c9d54499e4a2902b523441
|
||||
|
||||
Implement signal handling for MSHV vCPUs to support asynchronous
|
||||
interrupts from the main thread.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-12-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 575df4df54e060661db45e6f80293b29ea8901c1)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-Add-vCPU-signal-handling.patch
|
||||
Patch-id: 72
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mshv-all.c | 30 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index e02421d79d..fa1f8f35bd 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -524,6 +524,35 @@ static int mshv_cpu_exec(CPUState *cpu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The signal handler is triggered when QEMU's main thread receives a SIG_IPI
|
||||
+ * (SIGUSR1). This signal causes the current CPU thread to be kicked, forcing a
|
||||
+ * VM exit on the CPU. The VM exit generates an exit reason that breaks the loop
|
||||
+ * (see mshv_cpu_exec). If the exit is due to a Ctrl+A+x command, the system
|
||||
+ * will shut down. For other cases, the system will continue running.
|
||||
+ */
|
||||
+static void sa_ipi_handler(int sig)
|
||||
+{
|
||||
+ /* TODO: call IOCTL to set_immediate_exit, once implemented. */
|
||||
+
|
||||
+ qemu_cpu_kick_self();
|
||||
+}
|
||||
+
|
||||
+static void init_signal(CPUState *cpu)
|
||||
+{
|
||||
+ /* init cpu signals */
|
||||
+ struct sigaction sigact;
|
||||
+ sigset_t set;
|
||||
+
|
||||
+ memset(&sigact, 0, sizeof(sigact));
|
||||
+ sigact.sa_handler = sa_ipi_handler;
|
||||
+ sigaction(SIG_IPI, &sigact, NULL);
|
||||
+
|
||||
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
|
||||
+ sigdelset(&set, SIG_IPI);
|
||||
+ pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
+}
|
||||
+
|
||||
static void *mshv_vcpu_thread(void *arg)
|
||||
{
|
||||
CPUState *cpu = arg;
|
||||
@@ -540,6 +569,7 @@ static void *mshv_vcpu_thread(void *arg)
|
||||
error_report("Failed to init vcpu %d", cpu->cpu_index);
|
||||
goto cleanup;
|
||||
}
|
||||
+ init_signal(cpu);
|
||||
|
||||
/* signal CPU creation */
|
||||
cpu_thread_signal_created(cpu);
|
||||
77
0070-target-i386-mshv-Add-CPU-create-and-remove-logic.patch
Normal file
77
0070-target-i386-mshv-Add-CPU-create-and-remove-logic.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 8033e3b98bda1261f95770b68f6337cc6d66bf9d Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:32 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Add CPU create and remove logic
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [13/30] cdb6e3cec7a38a6328be8facbbdf19fd0fd9ec78
|
||||
|
||||
Implement MSHV-specific hooks for vCPU creation and teardown in the
|
||||
i386 target.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-13-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 4ed605c06e743b2ec0bfe35954d88b8c64dd3767)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Add-CPU-create-and-remove-logic.patch
|
||||
Patch-id: 73
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 23 +++++++++++++++++------
|
||||
1 file changed, 17 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 02d71ebc14..5069ab7a22 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "trace-accel_mshv.h"
|
||||
#include "trace.h"
|
||||
|
||||
+#include <sys/ioctl.h>
|
||||
+
|
||||
int mshv_store_regs(CPUState *cpu)
|
||||
{
|
||||
error_report("unimplemented");
|
||||
@@ -62,20 +64,29 @@ int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
|
||||
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ close(cpu_fd);
|
||||
}
|
||||
|
||||
+
|
||||
int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ int ret;
|
||||
+ struct mshv_create_vp vp_arg = {
|
||||
+ .vp_index = vp_index,
|
||||
+ };
|
||||
+ ret = ioctl(vm_fd, MSHV_CREATE_VP, &vp_arg);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to create mshv vcpu: %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *cpu_fd = ret;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void mshv_init_mmio_emu(void)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
}
|
||||
|
||||
void mshv_arch_init_vcpu(CPUState *cpu)
|
||||
189
0071-target-i386-mshv-Implement-mshv_store_regs.patch
Normal file
189
0071-target-i386-mshv-Implement-mshv_store_regs.patch
Normal file
@ -0,0 +1,189 @@
|
||||
From 2096f4c0379df09a24a0cab1fc8902bba669b632 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Thu, 2 Oct 2025 18:13:31 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Implement mshv_store_regs()
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [14/30] 2f4fe2c0b042ec06d351929a7b090e554a459be1
|
||||
|
||||
Add support for writing general-purpose registers to MSHV vCPUs
|
||||
during initialization or migration using the MSHV register interface. A
|
||||
generic set_register call is introduced to abstract the HV call over
|
||||
the various register types.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-14-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 2bd7a6aa4743ee85c77c0520e8b422b3bfeab386)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Implement-mshv_store_regs.patch
|
||||
Patch-id: 74
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/system/mshv.h | 1 +
|
||||
include/system/mshv_int.h | 2 +
|
||||
target/i386/mshv/mshv-cpu.c | 116 +++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 117 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/system/mshv.h b/include/system/mshv.h
|
||||
index bbc42f4dc3..8b1fc20c80 100644
|
||||
--- a/include/system/mshv.h
|
||||
+++ b/include/system/mshv.h
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "qemu/accel.h"
|
||||
#include "hw/hyperv/hyperv-proto.h"
|
||||
#include "hw/hyperv/hvhdk.h"
|
||||
+#include "hw/hyperv/hvgdk_mini.h"
|
||||
#include "qapi/qapi-types-common.h"
|
||||
#include "system/memory.h"
|
||||
#include "accel/accel-ops.h"
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index fb80f69772..731841af92 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -61,6 +61,8 @@ void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
|
||||
int mshv_load_regs(CPUState *cpu);
|
||||
int mshv_store_regs(CPUState *cpu);
|
||||
+int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
+ size_t n_regs);
|
||||
int mshv_arch_put_registers(const CPUState *cpu);
|
||||
void mshv_arch_init_vcpu(CPUState *cpu);
|
||||
void mshv_arch_destroy_vcpu(CPUState *cpu);
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 5069ab7a22..9ead03ca2d 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -32,12 +32,124 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
+static enum hv_register_name STANDARD_REGISTER_NAMES[18] = {
|
||||
+ HV_X64_REGISTER_RAX,
|
||||
+ HV_X64_REGISTER_RBX,
|
||||
+ HV_X64_REGISTER_RCX,
|
||||
+ HV_X64_REGISTER_RDX,
|
||||
+ HV_X64_REGISTER_RSI,
|
||||
+ HV_X64_REGISTER_RDI,
|
||||
+ HV_X64_REGISTER_RSP,
|
||||
+ HV_X64_REGISTER_RBP,
|
||||
+ HV_X64_REGISTER_R8,
|
||||
+ HV_X64_REGISTER_R9,
|
||||
+ HV_X64_REGISTER_R10,
|
||||
+ HV_X64_REGISTER_R11,
|
||||
+ HV_X64_REGISTER_R12,
|
||||
+ HV_X64_REGISTER_R13,
|
||||
+ HV_X64_REGISTER_R14,
|
||||
+ HV_X64_REGISTER_R15,
|
||||
+ HV_X64_REGISTER_RIP,
|
||||
+ HV_X64_REGISTER_RFLAGS,
|
||||
+};
|
||||
+
|
||||
+int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
+ size_t n_regs)
|
||||
+{
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+ int vp_index = cpu->cpu_index;
|
||||
+ size_t in_sz, assocs_sz;
|
||||
+ hv_input_set_vp_registers *in;
|
||||
+ struct mshv_root_hvcall args = {0};
|
||||
+ int ret;
|
||||
+
|
||||
+ /* find out the size of the struct w/ a flexible array at the tail */
|
||||
+ assocs_sz = n_regs * sizeof(hv_register_assoc);
|
||||
+ in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;
|
||||
+
|
||||
+ /* fill the input struct */
|
||||
+ in = g_malloc0(in_sz);
|
||||
+ in->vp_index = vp_index;
|
||||
+ memcpy(in->elements, assocs, assocs_sz);
|
||||
+
|
||||
+ /* create the hvcall envelope */
|
||||
+ args.code = HVCALL_SET_VP_REGISTERS;
|
||||
+ args.in_sz = in_sz;
|
||||
+ args.in_ptr = (uint64_t) in;
|
||||
+ args.reps = (uint16_t) n_regs;
|
||||
+
|
||||
+ /* perform the call */
|
||||
+ ret = mshv_hvcall(cpu_fd, &args);
|
||||
+ g_free(in);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to set registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* assert we set all registers */
|
||||
+ if (args.reps != n_regs) {
|
||||
+ error_report("Failed to set registers: expected %zu elements"
|
||||
+ ", got %u", n_regs, args.reps);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_standard_regs(const CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+ hv_register_assoc assocs[ARRAY_SIZE(STANDARD_REGISTER_NAMES)];
|
||||
+ int ret;
|
||||
+ size_t n_regs = ARRAY_SIZE(STANDARD_REGISTER_NAMES);
|
||||
+
|
||||
+ /* set names */
|
||||
+ for (size_t i = 0; i < ARRAY_SIZE(STANDARD_REGISTER_NAMES); i++) {
|
||||
+ assocs[i].name = STANDARD_REGISTER_NAMES[i];
|
||||
+ }
|
||||
+ assocs[0].value.reg64 = env->regs[R_EAX];
|
||||
+ assocs[1].value.reg64 = env->regs[R_EBX];
|
||||
+ assocs[2].value.reg64 = env->regs[R_ECX];
|
||||
+ assocs[3].value.reg64 = env->regs[R_EDX];
|
||||
+ assocs[4].value.reg64 = env->regs[R_ESI];
|
||||
+ assocs[5].value.reg64 = env->regs[R_EDI];
|
||||
+ assocs[6].value.reg64 = env->regs[R_ESP];
|
||||
+ assocs[7].value.reg64 = env->regs[R_EBP];
|
||||
+ assocs[8].value.reg64 = env->regs[R_R8];
|
||||
+ assocs[9].value.reg64 = env->regs[R_R9];
|
||||
+ assocs[10].value.reg64 = env->regs[R_R10];
|
||||
+ assocs[11].value.reg64 = env->regs[R_R11];
|
||||
+ assocs[12].value.reg64 = env->regs[R_R12];
|
||||
+ assocs[13].value.reg64 = env->regs[R_R13];
|
||||
+ assocs[14].value.reg64 = env->regs[R_R14];
|
||||
+ assocs[15].value.reg64 = env->regs[R_R15];
|
||||
+ assocs[16].value.reg64 = env->eip;
|
||||
+ lflags_to_rflags(env);
|
||||
+ assocs[17].value.reg64 = env->eflags;
|
||||
+
|
||||
+ ret = mshv_set_generic_regs(cpu, assocs, n_regs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set standard registers");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int mshv_store_regs(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = set_standard_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to store standard registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
+
|
||||
int mshv_load_regs(CPUState *cpu)
|
||||
{
|
||||
error_report("unimplemented");
|
||||
183
0072-target-i386-mshv-Implement-mshv_get_standard_regs.patch
Normal file
183
0072-target-i386-mshv-Implement-mshv_get_standard_regs.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From a60b80bb7d9969cdb0f4281c16104bf1ddc5163d Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:34 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Implement mshv_get_standard_regs()
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [15/30] ccb135407183081206513dd2de2410a9c1768f15
|
||||
|
||||
Fetch standard register state from MSHV vCPUs to support debugging,
|
||||
migration, and other introspection features in QEMU.
|
||||
|
||||
Fetch standard register state from a MHSV vCPU's. A generic get_regs()
|
||||
function and a mapper to map the different register representations are
|
||||
introduced.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-15-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 66480a048a01fc833ba153410282609f26166141)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Implement-mshv_get_standard_regs.patch
|
||||
Patch-id: 75
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/system/mshv_int.h | 1 +
|
||||
target/i386/mshv/mshv-cpu.c | 116 +++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 115 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index 731841af92..b0a79296ad 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -58,6 +58,7 @@ typedef enum MshvVmExit {
|
||||
void mshv_init_mmio_emu(void);
|
||||
int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
+int mshv_get_standard_regs(CPUState *cpu);
|
||||
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
|
||||
int mshv_load_regs(CPUState *cpu);
|
||||
int mshv_store_regs(CPUState *cpu);
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 9ead03ca2d..4e3eee113b 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -96,6 +96,66 @@ int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
|
||||
+ size_t n_regs)
|
||||
+{
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+ int vp_index = cpu->cpu_index;
|
||||
+ hv_input_get_vp_registers *in;
|
||||
+ hv_register_value *values;
|
||||
+ size_t in_sz, names_sz, values_sz;
|
||||
+ int i, ret;
|
||||
+ struct mshv_root_hvcall args = {0};
|
||||
+
|
||||
+ /* find out the size of the struct w/ a flexible array at the tail */
|
||||
+ names_sz = n_regs * sizeof(hv_register_name);
|
||||
+ in_sz = sizeof(hv_input_get_vp_registers) + names_sz;
|
||||
+
|
||||
+ /* fill the input struct */
|
||||
+ in = g_malloc0(in_sz);
|
||||
+ in->vp_index = vp_index;
|
||||
+ for (i = 0; i < n_regs; i++) {
|
||||
+ in->names[i] = assocs[i].name;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate value output buffer */
|
||||
+ values_sz = n_regs * sizeof(union hv_register_value);
|
||||
+ values = g_malloc0(values_sz);
|
||||
+
|
||||
+ /* create the hvcall envelope */
|
||||
+ args.code = HVCALL_GET_VP_REGISTERS;
|
||||
+ args.in_sz = in_sz;
|
||||
+ args.in_ptr = (uint64_t) in;
|
||||
+ args.out_sz = values_sz;
|
||||
+ args.out_ptr = (uint64_t) values;
|
||||
+ args.reps = (uint16_t) n_regs;
|
||||
+
|
||||
+ /* perform the call */
|
||||
+ ret = mshv_hvcall(cpu_fd, &args);
|
||||
+ g_free(in);
|
||||
+ if (ret < 0) {
|
||||
+ g_free(values);
|
||||
+ error_report("Failed to retrieve registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* assert we got all registers */
|
||||
+ if (args.reps != n_regs) {
|
||||
+ g_free(values);
|
||||
+ error_report("Failed to retrieve registers: expected %zu elements"
|
||||
+ ", got %u", n_regs, args.reps);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /* copy values into assoc */
|
||||
+ for (i = 0; i < n_regs; i++) {
|
||||
+ assocs[i].value = values[i];
|
||||
+ }
|
||||
+ g_free(values);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int set_standard_regs(const CPUState *cpu)
|
||||
{
|
||||
X86CPU *x86cpu = X86_CPU(cpu);
|
||||
@@ -149,11 +209,63 @@ int mshv_store_regs(CPUState *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void populate_standard_regs(const hv_register_assoc *assocs,
|
||||
+ CPUX86State *env)
|
||||
+{
|
||||
+ env->regs[R_EAX] = assocs[0].value.reg64;
|
||||
+ env->regs[R_EBX] = assocs[1].value.reg64;
|
||||
+ env->regs[R_ECX] = assocs[2].value.reg64;
|
||||
+ env->regs[R_EDX] = assocs[3].value.reg64;
|
||||
+ env->regs[R_ESI] = assocs[4].value.reg64;
|
||||
+ env->regs[R_EDI] = assocs[5].value.reg64;
|
||||
+ env->regs[R_ESP] = assocs[6].value.reg64;
|
||||
+ env->regs[R_EBP] = assocs[7].value.reg64;
|
||||
+ env->regs[R_R8] = assocs[8].value.reg64;
|
||||
+ env->regs[R_R9] = assocs[9].value.reg64;
|
||||
+ env->regs[R_R10] = assocs[10].value.reg64;
|
||||
+ env->regs[R_R11] = assocs[11].value.reg64;
|
||||
+ env->regs[R_R12] = assocs[12].value.reg64;
|
||||
+ env->regs[R_R13] = assocs[13].value.reg64;
|
||||
+ env->regs[R_R14] = assocs[14].value.reg64;
|
||||
+ env->regs[R_R15] = assocs[15].value.reg64;
|
||||
+
|
||||
+ env->eip = assocs[16].value.reg64;
|
||||
+ env->eflags = assocs[17].value.reg64;
|
||||
+ rflags_to_lflags(env);
|
||||
+}
|
||||
+
|
||||
+int mshv_get_standard_regs(CPUState *cpu)
|
||||
+{
|
||||
+ struct hv_register_assoc assocs[ARRAY_SIZE(STANDARD_REGISTER_NAMES)];
|
||||
+ int ret;
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+ size_t n_regs = ARRAY_SIZE(STANDARD_REGISTER_NAMES);
|
||||
+
|
||||
+ for (size_t i = 0; i < n_regs; i++) {
|
||||
+ assocs[i].name = STANDARD_REGISTER_NAMES[i];
|
||||
+ }
|
||||
+ ret = get_generic_regs(cpu, assocs, n_regs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to get standard registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ populate_standard_regs(assocs, env);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
int mshv_load_regs(CPUState *cpu)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mshv_get_standard_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to load standard registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int mshv_arch_put_registers(const CPUState *cpu)
|
||||
174
0073-target-i386-mshv-Implement-mshv_get_special_regs.patch
Normal file
174
0073-target-i386-mshv-Implement-mshv_get_special_regs.patch
Normal file
@ -0,0 +1,174 @@
|
||||
From f72c428f6ebc373a6cbe566a7f99db8b7d03efd0 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:35 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Implement mshv_get_special_regs()
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [16/30] 429625fae745bc6c3c9e9412741c875331a92180
|
||||
|
||||
Retrieve special registers (e.g. segment, control, and descriptor
|
||||
table registers) from MSHV vCPUs.
|
||||
|
||||
Various helper functions to map register state representations between
|
||||
Qemu and MSHV are introduced.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-16-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 0382c2c8544da66619d16988caaab8e3d9e881d4)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Implement-mshv_get_special_regs.patch
|
||||
Patch-id: 76
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/system/mshv_int.h | 1 +
|
||||
target/i386/mshv/mshv-cpu.c | 104 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 105 insertions(+)
|
||||
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index b0a79296ad..c6e6e8af30 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -59,6 +59,7 @@ void mshv_init_mmio_emu(void);
|
||||
int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
int mshv_get_standard_regs(CPUState *cpu);
|
||||
+int mshv_get_special_regs(CPUState *cpu);
|
||||
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
|
||||
int mshv_load_regs(CPUState *cpu);
|
||||
int mshv_store_regs(CPUState *cpu);
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 4e3eee113b..bc75686f82 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -53,6 +53,26 @@ static enum hv_register_name STANDARD_REGISTER_NAMES[18] = {
|
||||
HV_X64_REGISTER_RFLAGS,
|
||||
};
|
||||
|
||||
+static enum hv_register_name SPECIAL_REGISTER_NAMES[17] = {
|
||||
+ HV_X64_REGISTER_CS,
|
||||
+ HV_X64_REGISTER_DS,
|
||||
+ HV_X64_REGISTER_ES,
|
||||
+ HV_X64_REGISTER_FS,
|
||||
+ HV_X64_REGISTER_GS,
|
||||
+ HV_X64_REGISTER_SS,
|
||||
+ HV_X64_REGISTER_TR,
|
||||
+ HV_X64_REGISTER_LDTR,
|
||||
+ HV_X64_REGISTER_GDTR,
|
||||
+ HV_X64_REGISTER_IDTR,
|
||||
+ HV_X64_REGISTER_CR0,
|
||||
+ HV_X64_REGISTER_CR2,
|
||||
+ HV_X64_REGISTER_CR3,
|
||||
+ HV_X64_REGISTER_CR4,
|
||||
+ HV_X64_REGISTER_CR8,
|
||||
+ HV_X64_REGISTER_EFER,
|
||||
+ HV_X64_REGISTER_APIC_BASE,
|
||||
+};
|
||||
+
|
||||
int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
size_t n_regs)
|
||||
{
|
||||
@@ -255,6 +275,84 @@ int mshv_get_standard_regs(CPUState *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline void populate_segment_reg(const hv_x64_segment_register *hv_seg,
|
||||
+ SegmentCache *seg)
|
||||
+{
|
||||
+ memset(seg, 0, sizeof(SegmentCache));
|
||||
+
|
||||
+ seg->base = hv_seg->base;
|
||||
+ seg->limit = hv_seg->limit;
|
||||
+ seg->selector = hv_seg->selector;
|
||||
+
|
||||
+ seg->flags = (hv_seg->segment_type << DESC_TYPE_SHIFT)
|
||||
+ | (hv_seg->present * DESC_P_MASK)
|
||||
+ | (hv_seg->descriptor_privilege_level << DESC_DPL_SHIFT)
|
||||
+ | (hv_seg->_default << DESC_B_SHIFT)
|
||||
+ | (hv_seg->non_system_segment * DESC_S_MASK)
|
||||
+ | (hv_seg->_long << DESC_L_SHIFT)
|
||||
+ | (hv_seg->granularity * DESC_G_MASK)
|
||||
+ | (hv_seg->available * DESC_AVL_MASK);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static inline void populate_table_reg(const hv_x64_table_register *hv_seg,
|
||||
+ SegmentCache *tbl)
|
||||
+{
|
||||
+ memset(tbl, 0, sizeof(SegmentCache));
|
||||
+
|
||||
+ tbl->base = hv_seg->base;
|
||||
+ tbl->limit = hv_seg->limit;
|
||||
+}
|
||||
+
|
||||
+static void populate_special_regs(const hv_register_assoc *assocs,
|
||||
+ X86CPU *x86cpu)
|
||||
+{
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+
|
||||
+ populate_segment_reg(&assocs[0].value.segment, &env->segs[R_CS]);
|
||||
+ populate_segment_reg(&assocs[1].value.segment, &env->segs[R_DS]);
|
||||
+ populate_segment_reg(&assocs[2].value.segment, &env->segs[R_ES]);
|
||||
+ populate_segment_reg(&assocs[3].value.segment, &env->segs[R_FS]);
|
||||
+ populate_segment_reg(&assocs[4].value.segment, &env->segs[R_GS]);
|
||||
+ populate_segment_reg(&assocs[5].value.segment, &env->segs[R_SS]);
|
||||
+
|
||||
+ populate_segment_reg(&assocs[6].value.segment, &env->tr);
|
||||
+ populate_segment_reg(&assocs[7].value.segment, &env->ldt);
|
||||
+
|
||||
+ populate_table_reg(&assocs[8].value.table, &env->gdt);
|
||||
+ populate_table_reg(&assocs[9].value.table, &env->idt);
|
||||
+
|
||||
+ env->cr[0] = assocs[10].value.reg64;
|
||||
+ env->cr[2] = assocs[11].value.reg64;
|
||||
+ env->cr[3] = assocs[12].value.reg64;
|
||||
+ env->cr[4] = assocs[13].value.reg64;
|
||||
+
|
||||
+ cpu_set_apic_tpr(x86cpu->apic_state, assocs[14].value.reg64);
|
||||
+ env->efer = assocs[15].value.reg64;
|
||||
+ cpu_set_apic_base(x86cpu->apic_state, assocs[16].value.reg64);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int mshv_get_special_regs(CPUState *cpu)
|
||||
+{
|
||||
+ struct hv_register_assoc assocs[ARRAY_SIZE(SPECIAL_REGISTER_NAMES)];
|
||||
+ int ret;
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ size_t n_regs = ARRAY_SIZE(SPECIAL_REGISTER_NAMES);
|
||||
+
|
||||
+ for (size_t i = 0; i < n_regs; i++) {
|
||||
+ assocs[i].name = SPECIAL_REGISTER_NAMES[i];
|
||||
+ }
|
||||
+ ret = get_generic_regs(cpu, assocs, n_regs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to get special registers");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ populate_special_regs(assocs, x86cpu);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int mshv_load_regs(CPUState *cpu)
|
||||
{
|
||||
int ret;
|
||||
@@ -265,6 +363,12 @@ int mshv_load_regs(CPUState *cpu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ ret = mshv_get_special_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to load special registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
320
0074-target-i386-mshv-Implement-mshv_arch_put_registers.patch
Normal file
320
0074-target-i386-mshv-Implement-mshv_arch_put_registers.patch
Normal file
@ -0,0 +1,320 @@
|
||||
From f3e0329c1ce6d3b147baad937f0261ecb2c9f542 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:36 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Implement mshv_arch_put_registers()
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [17/30] e2648880fed0b7eb9097768c3e4cfc914baa104a
|
||||
|
||||
Write CPU register state to MSHV vCPUs. Various mapping functions to
|
||||
prepare the payload for the HV call have been implemented.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-17-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 25a1d871e0f19bbf8fee471af5fefec52465bb09)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Implement-mshv_arch_put_registers.patch
|
||||
Patch-id: 77
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/system/mshv_int.h | 15 +++
|
||||
target/i386/mshv/mshv-cpu.c | 237 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 252 insertions(+)
|
||||
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index c6e6e8af30..0ea8d504fa 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -49,6 +49,20 @@ typedef struct MshvMsiControl {
|
||||
#define mshv_vcpufd(cpu) (cpu->accel->cpufd)
|
||||
|
||||
/* cpu */
|
||||
+typedef struct MshvFPU {
|
||||
+ uint8_t fpr[8][16];
|
||||
+ uint16_t fcw;
|
||||
+ uint16_t fsw;
|
||||
+ uint8_t ftwx;
|
||||
+ uint8_t pad1;
|
||||
+ uint16_t last_opcode;
|
||||
+ uint64_t last_ip;
|
||||
+ uint64_t last_dp;
|
||||
+ uint8_t xmm[16][16];
|
||||
+ uint32_t mxcsr;
|
||||
+ uint32_t pad2;
|
||||
+} MshvFPU;
|
||||
+
|
||||
typedef enum MshvVmExit {
|
||||
MshvVmExitIgnore = 0,
|
||||
MshvVmExitShutdown = 1,
|
||||
@@ -58,6 +72,7 @@ typedef enum MshvVmExit {
|
||||
void mshv_init_mmio_emu(void);
|
||||
int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
+int mshv_configure_vcpu(const CPUState *cpu, const MshvFPU *fpu, uint64_t xcr0);
|
||||
int mshv_get_standard_regs(CPUState *cpu);
|
||||
int mshv_get_special_regs(CPUState *cpu);
|
||||
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit);
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index bc75686f82..8b10c79e54 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -73,6 +73,35 @@ static enum hv_register_name SPECIAL_REGISTER_NAMES[17] = {
|
||||
HV_X64_REGISTER_APIC_BASE,
|
||||
};
|
||||
|
||||
+static enum hv_register_name FPU_REGISTER_NAMES[26] = {
|
||||
+ HV_X64_REGISTER_XMM0,
|
||||
+ HV_X64_REGISTER_XMM1,
|
||||
+ HV_X64_REGISTER_XMM2,
|
||||
+ HV_X64_REGISTER_XMM3,
|
||||
+ HV_X64_REGISTER_XMM4,
|
||||
+ HV_X64_REGISTER_XMM5,
|
||||
+ HV_X64_REGISTER_XMM6,
|
||||
+ HV_X64_REGISTER_XMM7,
|
||||
+ HV_X64_REGISTER_XMM8,
|
||||
+ HV_X64_REGISTER_XMM9,
|
||||
+ HV_X64_REGISTER_XMM10,
|
||||
+ HV_X64_REGISTER_XMM11,
|
||||
+ HV_X64_REGISTER_XMM12,
|
||||
+ HV_X64_REGISTER_XMM13,
|
||||
+ HV_X64_REGISTER_XMM14,
|
||||
+ HV_X64_REGISTER_XMM15,
|
||||
+ HV_X64_REGISTER_FP_MMX0,
|
||||
+ HV_X64_REGISTER_FP_MMX1,
|
||||
+ HV_X64_REGISTER_FP_MMX2,
|
||||
+ HV_X64_REGISTER_FP_MMX3,
|
||||
+ HV_X64_REGISTER_FP_MMX4,
|
||||
+ HV_X64_REGISTER_FP_MMX5,
|
||||
+ HV_X64_REGISTER_FP_MMX6,
|
||||
+ HV_X64_REGISTER_FP_MMX7,
|
||||
+ HV_X64_REGISTER_FP_CONTROL_STATUS,
|
||||
+ HV_X64_REGISTER_XMM_CONTROL_STATUS,
|
||||
+};
|
||||
+
|
||||
int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
size_t n_regs)
|
||||
{
|
||||
@@ -372,8 +401,216 @@ int mshv_load_regs(CPUState *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline void populate_hv_segment_reg(SegmentCache *seg,
|
||||
+ hv_x64_segment_register *hv_reg)
|
||||
+{
|
||||
+ uint32_t flags = seg->flags;
|
||||
+
|
||||
+ hv_reg->base = seg->base;
|
||||
+ hv_reg->limit = seg->limit;
|
||||
+ hv_reg->selector = seg->selector;
|
||||
+ hv_reg->segment_type = (flags >> DESC_TYPE_SHIFT) & 0xF;
|
||||
+ hv_reg->non_system_segment = (flags & DESC_S_MASK) != 0;
|
||||
+ hv_reg->descriptor_privilege_level = (flags >> DESC_DPL_SHIFT) & 0x3;
|
||||
+ hv_reg->present = (flags & DESC_P_MASK) != 0;
|
||||
+ hv_reg->reserved = 0;
|
||||
+ hv_reg->available = (flags & DESC_AVL_MASK) != 0;
|
||||
+ hv_reg->_long = (flags >> DESC_L_SHIFT) & 0x1;
|
||||
+ hv_reg->_default = (flags >> DESC_B_SHIFT) & 0x1;
|
||||
+ hv_reg->granularity = (flags & DESC_G_MASK) != 0;
|
||||
+}
|
||||
+
|
||||
+static inline void populate_hv_table_reg(const struct SegmentCache *seg,
|
||||
+ hv_x64_table_register *hv_reg)
|
||||
+{
|
||||
+ memset(hv_reg, 0, sizeof(*hv_reg));
|
||||
+
|
||||
+ hv_reg->base = seg->base;
|
||||
+ hv_reg->limit = seg->limit;
|
||||
+}
|
||||
+
|
||||
+static int set_special_regs(const CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+ struct hv_register_assoc assocs[ARRAY_SIZE(SPECIAL_REGISTER_NAMES)];
|
||||
+ size_t n_regs = ARRAY_SIZE(SPECIAL_REGISTER_NAMES);
|
||||
+ int ret;
|
||||
+
|
||||
+ /* set names */
|
||||
+ for (size_t i = 0; i < n_regs; i++) {
|
||||
+ assocs[i].name = SPECIAL_REGISTER_NAMES[i];
|
||||
+ }
|
||||
+ populate_hv_segment_reg(&env->segs[R_CS], &assocs[0].value.segment);
|
||||
+ populate_hv_segment_reg(&env->segs[R_DS], &assocs[1].value.segment);
|
||||
+ populate_hv_segment_reg(&env->segs[R_ES], &assocs[2].value.segment);
|
||||
+ populate_hv_segment_reg(&env->segs[R_FS], &assocs[3].value.segment);
|
||||
+ populate_hv_segment_reg(&env->segs[R_GS], &assocs[4].value.segment);
|
||||
+ populate_hv_segment_reg(&env->segs[R_SS], &assocs[5].value.segment);
|
||||
+ populate_hv_segment_reg(&env->tr, &assocs[6].value.segment);
|
||||
+ populate_hv_segment_reg(&env->ldt, &assocs[7].value.segment);
|
||||
+
|
||||
+ populate_hv_table_reg(&env->gdt, &assocs[8].value.table);
|
||||
+ populate_hv_table_reg(&env->idt, &assocs[9].value.table);
|
||||
+
|
||||
+ assocs[10].value.reg64 = env->cr[0];
|
||||
+ assocs[11].value.reg64 = env->cr[2];
|
||||
+ assocs[12].value.reg64 = env->cr[3];
|
||||
+ assocs[13].value.reg64 = env->cr[4];
|
||||
+ assocs[14].value.reg64 = cpu_get_apic_tpr(x86cpu->apic_state);
|
||||
+ assocs[15].value.reg64 = env->efer;
|
||||
+ assocs[16].value.reg64 = cpu_get_apic_base(x86cpu->apic_state);
|
||||
+
|
||||
+ ret = mshv_set_generic_regs(cpu, assocs, n_regs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set special registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_fpu(const CPUState *cpu, const struct MshvFPU *regs)
|
||||
+{
|
||||
+ struct hv_register_assoc assocs[ARRAY_SIZE(FPU_REGISTER_NAMES)];
|
||||
+ union hv_register_value *value;
|
||||
+ size_t fp_i;
|
||||
+ union hv_x64_fp_control_status_register *ctrl_status;
|
||||
+ union hv_x64_xmm_control_status_register *xmm_ctrl_status;
|
||||
+ int ret;
|
||||
+ size_t n_regs = ARRAY_SIZE(FPU_REGISTER_NAMES);
|
||||
+
|
||||
+ /* first 16 registers are xmm0-xmm15 */
|
||||
+ for (size_t i = 0; i < 16; i++) {
|
||||
+ assocs[i].name = FPU_REGISTER_NAMES[i];
|
||||
+ value = &assocs[i].value;
|
||||
+ memcpy(&value->reg128, ®s->xmm[i], 16);
|
||||
+ }
|
||||
+
|
||||
+ /* next 8 registers are fp_mmx0-fp_mmx7 */
|
||||
+ for (size_t i = 16; i < 24; i++) {
|
||||
+ assocs[i].name = FPU_REGISTER_NAMES[i];
|
||||
+ fp_i = (i - 16);
|
||||
+ value = &assocs[i].value;
|
||||
+ memcpy(&value->reg128, ®s->fpr[fp_i], 16);
|
||||
+ }
|
||||
+
|
||||
+ /* last two registers are fp_control_status and xmm_control_status */
|
||||
+ assocs[24].name = FPU_REGISTER_NAMES[24];
|
||||
+ value = &assocs[24].value;
|
||||
+ ctrl_status = &value->fp_control_status;
|
||||
+ ctrl_status->fp_control = regs->fcw;
|
||||
+ ctrl_status->fp_status = regs->fsw;
|
||||
+ ctrl_status->fp_tag = regs->ftwx;
|
||||
+ ctrl_status->reserved = 0;
|
||||
+ ctrl_status->last_fp_op = regs->last_opcode;
|
||||
+ ctrl_status->last_fp_rip = regs->last_ip;
|
||||
+
|
||||
+ assocs[25].name = FPU_REGISTER_NAMES[25];
|
||||
+ value = &assocs[25].value;
|
||||
+ xmm_ctrl_status = &value->xmm_control_status;
|
||||
+ xmm_ctrl_status->xmm_status_control = regs->mxcsr;
|
||||
+ xmm_ctrl_status->xmm_status_control_mask = 0;
|
||||
+ xmm_ctrl_status->last_fp_rdp = regs->last_dp;
|
||||
+
|
||||
+ ret = mshv_set_generic_regs(cpu, assocs, n_regs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set fpu registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_xc_reg(const CPUState *cpu, uint64_t xcr0)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct hv_register_assoc assoc = {
|
||||
+ .name = HV_X64_REGISTER_XFEM,
|
||||
+ .value.reg64 = xcr0,
|
||||
+ };
|
||||
+
|
||||
+ ret = mshv_set_generic_regs(cpu, &assoc, 1);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set xcr0");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_cpu_state(const CPUState *cpu, const MshvFPU *fpu_regs,
|
||||
+ uint64_t xcr0)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = set_standard_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = set_special_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = set_fpu(cpu, fpu_regs);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ ret = set_xc_reg(cpu, xcr0);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * TODO: populate topology info:
|
||||
+ *
|
||||
+ * X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ * CPUX86State *env = &x86cpu->env;
|
||||
+ * X86CPUTopoInfo *topo_info = &env->topo_info;
|
||||
+ */
|
||||
+int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu,
|
||||
+ uint64_t xcr0)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = set_cpu_state(cpu, fpu, xcr0);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set cpu state");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int put_regs(const CPUState *cpu)
|
||||
+{
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+ MshvFPU fpu = {0};
|
||||
+ int ret;
|
||||
+
|
||||
+ memset(&fpu, 0, sizeof(fpu));
|
||||
+
|
||||
+ ret = mshv_configure_vcpu(cpu, &fpu, env->xcr0);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to configure vcpu");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int mshv_arch_put_registers(const CPUState *cpu)
|
||||
{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = put_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to put registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
error_report("unimplemented");
|
||||
abort();
|
||||
}
|
||||
184
0075-target-i386-mshv-Set-local-interrupt-controller-stat.patch
Normal file
184
0075-target-i386-mshv-Set-local-interrupt-controller-stat.patch
Normal file
@ -0,0 +1,184 @@
|
||||
From a03d8784b3b02cc0bd7ff04db10e4ebcece41b54 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:37 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Set local interrupt controller state
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [18/30] ded044d2fd9c55a149d7e71d952c10ed6ea29505
|
||||
|
||||
To set the local interrupt controller state, perform hv calls retrieving
|
||||
partition state from the hypervisor.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-18-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit ca20d46fa94887a6e42061646a71ee44cbc9adb0)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Set-local-interrupt-controller-stat.patch
|
||||
Patch-id: 78
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 117 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 117 insertions(+)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 8b10c79e54..0fe3cbb48d 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
+#include "qemu/memalign.h"
|
||||
#include "qemu/typedefs.h"
|
||||
|
||||
#include "system/mshv.h"
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "hw/hyperv/hvgdk.h"
|
||||
#include "hw/hyperv/hvgdk_mini.h"
|
||||
#include "hw/hyperv/hvhdk_mini.h"
|
||||
+#include "hw/i386/apic_internal.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "emulate/x86_decode.h"
|
||||
@@ -562,6 +564,114 @@ static int set_cpu_state(const CPUState *cpu, const MshvFPU *fpu_regs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ioctl(cpu_fd, MSHV_GET_VP_STATE, state);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to get partition state: %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int get_lapic(int cpu_fd,
|
||||
+ struct hv_local_interrupt_controller_state *state)
|
||||
+{
|
||||
+ int ret;
|
||||
+ size_t size = 4096;
|
||||
+ /* buffer aligned to 4k, as *state requires that */
|
||||
+ void *buffer = qemu_memalign(size, size);
|
||||
+ struct mshv_get_set_vp_state mshv_state = { 0 };
|
||||
+
|
||||
+ mshv_state.buf_ptr = (uint64_t) buffer;
|
||||
+ mshv_state.buf_sz = size;
|
||||
+ mshv_state.type = MSHV_VP_STATE_LAPIC;
|
||||
+
|
||||
+ ret = get_vp_state(cpu_fd, &mshv_state);
|
||||
+ if (ret == 0) {
|
||||
+ memcpy(state, buffer, sizeof(*state));
|
||||
+ }
|
||||
+ qemu_vfree(buffer);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to get lapic");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static uint32_t set_apic_delivery_mode(uint32_t reg, uint32_t mode)
|
||||
+{
|
||||
+ return ((reg) & ~0x700) | ((mode) << 8);
|
||||
+}
|
||||
+
|
||||
+static int set_vp_state(int cpu_fd, const struct mshv_get_set_vp_state *state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ioctl(cpu_fd, MSHV_SET_VP_STATE, state);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set partition state: %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_lapic(int cpu_fd,
|
||||
+ const struct hv_local_interrupt_controller_state *state)
|
||||
+{
|
||||
+ int ret;
|
||||
+ size_t size = 4096;
|
||||
+ /* buffer aligned to 4k, as *state requires that */
|
||||
+ void *buffer = qemu_memalign(size, size);
|
||||
+ struct mshv_get_set_vp_state mshv_state = { 0 };
|
||||
+
|
||||
+ if (!state) {
|
||||
+ error_report("lapic state is NULL");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(buffer, state, sizeof(*state));
|
||||
+
|
||||
+ mshv_state.buf_ptr = (uint64_t) buffer;
|
||||
+ mshv_state.buf_sz = size;
|
||||
+ mshv_state.type = MSHV_VP_STATE_LAPIC;
|
||||
+
|
||||
+ ret = set_vp_state(cpu_fd, &mshv_state);
|
||||
+ qemu_vfree(buffer);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set lapic: %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_lint(int cpu_fd)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t *lvt_lint0, *lvt_lint1;
|
||||
+
|
||||
+ struct hv_local_interrupt_controller_state lapic_state = { 0 };
|
||||
+ ret = get_lapic(cpu_fd, &lapic_state);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ lvt_lint0 = &lapic_state.apic_lvt_lint0;
|
||||
+ *lvt_lint0 = set_apic_delivery_mode(*lvt_lint0, APIC_DM_EXTINT);
|
||||
+
|
||||
+ lvt_lint1 = &lapic_state.apic_lvt_lint1;
|
||||
+ *lvt_lint1 = set_apic_delivery_mode(*lvt_lint1, APIC_DM_NMI);
|
||||
+
|
||||
+ /* TODO: should we skip setting lapic if the values are the same? */
|
||||
+
|
||||
+ return set_lapic(cpu_fd, &lapic_state);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* TODO: populate topology info:
|
||||
*
|
||||
@@ -573,6 +683,7 @@ int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu,
|
||||
uint64_t xcr0)
|
||||
{
|
||||
int ret;
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
|
||||
ret = set_cpu_state(cpu, fpu, xcr0);
|
||||
if (ret < 0) {
|
||||
@@ -580,6 +691,12 @@ int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ ret = set_lint(cpu_fd);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set lpic int");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
253
0076-target-i386-mshv-Register-CPUID-entries-with-MSHV.patch
Normal file
253
0076-target-i386-mshv-Register-CPUID-entries-with-MSHV.patch
Normal file
@ -0,0 +1,253 @@
|
||||
From 9b579f8392e7c71e60e5791f3b7980774a6253e1 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:38 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Register CPUID entries with MSHV
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [19/30] 4a1e70942d21acee2c90095afd82e9f376b87b56
|
||||
|
||||
Convert the guest CPU's CPUID model into MSHV's format and register it
|
||||
with the hypervisor. This ensures that the guest observes the correct
|
||||
CPU feature set during CPUID instructions.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-19-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 4fa04dd16216e266564606b7da582e5fce07bced)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Register-CPUID-entries-with-MSHV.patch
|
||||
Patch-id: 79
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 206 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 206 insertions(+)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 0fe3cbb48d..2b7a81274b 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -403,6 +403,206 @@ int mshv_load_regs(CPUState *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void add_cpuid_entry(GList *cpuid_entries,
|
||||
+ uint32_t function, uint32_t index,
|
||||
+ uint32_t eax, uint32_t ebx,
|
||||
+ uint32_t ecx, uint32_t edx)
|
||||
+{
|
||||
+ struct hv_cpuid_entry *entry;
|
||||
+
|
||||
+ entry = g_malloc0(sizeof(struct hv_cpuid_entry));
|
||||
+ entry->function = function;
|
||||
+ entry->index = index;
|
||||
+ entry->eax = eax;
|
||||
+ entry->ebx = ebx;
|
||||
+ entry->ecx = ecx;
|
||||
+ entry->edx = edx;
|
||||
+
|
||||
+ cpuid_entries = g_list_append(cpuid_entries, entry);
|
||||
+}
|
||||
+
|
||||
+static void collect_cpuid_entries(const CPUState *cpu, GList *cpuid_entries)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ uint32_t eax, ebx, ecx, edx;
|
||||
+ uint32_t leaf, subleaf;
|
||||
+ size_t max_leaf = 0x1F;
|
||||
+ size_t max_subleaf = 0x20;
|
||||
+
|
||||
+ uint32_t leaves_with_subleaves[] = {0x4, 0x7, 0xD, 0xF, 0x10};
|
||||
+ int n_subleaf_leaves = ARRAY_SIZE(leaves_with_subleaves);
|
||||
+
|
||||
+ /* Regular leaves without subleaves */
|
||||
+ for (leaf = 0; leaf <= max_leaf; leaf++) {
|
||||
+ bool has_subleaves = false;
|
||||
+ for (int i = 0; i < n_subleaf_leaves; i++) {
|
||||
+ if (leaf == leaves_with_subleaves[i]) {
|
||||
+ has_subleaves = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!has_subleaves) {
|
||||
+ cpu_x86_cpuid(env, leaf, 0, &eax, &ebx, &ecx, &edx);
|
||||
+ if (eax == 0 && ebx == 0 && ecx == 0 && edx == 0) {
|
||||
+ /* all zeroes indicates no more leaves */
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ add_cpuid_entry(cpuid_entries, leaf, 0, eax, ebx, ecx, edx);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ subleaf = 0;
|
||||
+ while (subleaf < max_subleaf) {
|
||||
+ cpu_x86_cpuid(env, leaf, subleaf, &eax, &ebx, &ecx, &edx);
|
||||
+
|
||||
+ if (eax == 0 && ebx == 0 && ecx == 0 && edx == 0) {
|
||||
+ /* all zeroes indicates no more leaves */
|
||||
+ break;
|
||||
+ }
|
||||
+ add_cpuid_entry(cpuid_entries, leaf, 0, eax, ebx, ecx, edx);
|
||||
+ subleaf++;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int register_intercept_result_cpuid_entry(const CPUState *cpu,
|
||||
+ uint8_t subleaf_specific,
|
||||
+ uint8_t always_override,
|
||||
+ struct hv_cpuid_entry *entry)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int vp_index = cpu->cpu_index;
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+
|
||||
+ struct hv_register_x64_cpuid_result_parameters cpuid_params = {
|
||||
+ .input.eax = entry->function,
|
||||
+ .input.ecx = entry->index,
|
||||
+ .input.subleaf_specific = subleaf_specific,
|
||||
+ .input.always_override = always_override,
|
||||
+ .input.padding = 0,
|
||||
+ /*
|
||||
+ * With regard to masks - these are to specify bits to be overwritten
|
||||
+ * The current CpuidEntry structure wouldn't allow to carry the masks
|
||||
+ * in addition to the actual register values. For this reason, the
|
||||
+ * masks are set to the exact values of the corresponding register bits
|
||||
+ * to be registered for an overwrite. To view resulting values the
|
||||
+ * hypervisor would return, HvCallGetVpCpuidValues hypercall can be
|
||||
+ * used.
|
||||
+ */
|
||||
+ .result.eax = entry->eax,
|
||||
+ .result.eax_mask = entry->eax,
|
||||
+ .result.ebx = entry->ebx,
|
||||
+ .result.ebx_mask = entry->ebx,
|
||||
+ .result.ecx = entry->ecx,
|
||||
+ .result.ecx_mask = entry->ecx,
|
||||
+ .result.edx = entry->edx,
|
||||
+ .result.edx_mask = entry->edx,
|
||||
+ };
|
||||
+ union hv_register_intercept_result_parameters parameters = {
|
||||
+ .cpuid = cpuid_params,
|
||||
+ };
|
||||
+
|
||||
+ hv_input_register_intercept_result in = {0};
|
||||
+ in.vp_index = vp_index;
|
||||
+ in.intercept_type = HV_INTERCEPT_TYPE_X64_CPUID;
|
||||
+ in.parameters = parameters;
|
||||
+
|
||||
+ struct mshv_root_hvcall args = {0};
|
||||
+ args.code = HVCALL_REGISTER_INTERCEPT_RESULT;
|
||||
+ args.in_sz = sizeof(in);
|
||||
+ args.in_ptr = (uint64_t)∈
|
||||
+
|
||||
+ ret = mshv_hvcall(cpu_fd, &args);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to register intercept result for cpuid");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int register_intercept_result_cpuid(const CPUState *cpu,
|
||||
+ struct hv_cpuid *cpuid)
|
||||
+{
|
||||
+ int ret = 0, entry_ret;
|
||||
+ struct hv_cpuid_entry *entry;
|
||||
+ uint8_t subleaf_specific, always_override;
|
||||
+
|
||||
+ for (size_t i = 0; i < cpuid->nent; i++) {
|
||||
+ entry = &cpuid->entries[i];
|
||||
+
|
||||
+ /* set defaults */
|
||||
+ subleaf_specific = 0;
|
||||
+ always_override = 1;
|
||||
+
|
||||
+ /* Intel */
|
||||
+ /* 0xb - Extended Topology Enumeration Leaf */
|
||||
+ /* 0x1f - V2 Extended Topology Enumeration Leaf */
|
||||
+ /* AMD */
|
||||
+ /* 0x8000_001e - Processor Topology Information */
|
||||
+ /* 0x8000_0026 - Extended CPU Topology */
|
||||
+ if (entry->function == 0xb
|
||||
+ || entry->function == 0x1f
|
||||
+ || entry->function == 0x8000001e
|
||||
+ || entry->function == 0x80000026) {
|
||||
+ subleaf_specific = 1;
|
||||
+ always_override = 1;
|
||||
+ } else if (entry->function == 0x00000001
|
||||
+ || entry->function == 0x80000000
|
||||
+ || entry->function == 0x80000001
|
||||
+ || entry->function == 0x80000008) {
|
||||
+ subleaf_specific = 0;
|
||||
+ always_override = 1;
|
||||
+ }
|
||||
+
|
||||
+ entry_ret = register_intercept_result_cpuid_entry(cpu, subleaf_specific,
|
||||
+ always_override,
|
||||
+ entry);
|
||||
+ if ((entry_ret < 0) && (ret == 0)) {
|
||||
+ ret = entry_ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int set_cpuid2(const CPUState *cpu)
|
||||
+{
|
||||
+ int ret;
|
||||
+ size_t n_entries, cpuid_size;
|
||||
+ struct hv_cpuid *cpuid;
|
||||
+ struct hv_cpuid_entry *entry;
|
||||
+ GList *entries = NULL;
|
||||
+
|
||||
+ collect_cpuid_entries(cpu, entries);
|
||||
+ n_entries = g_list_length(entries);
|
||||
+
|
||||
+ cpuid_size = sizeof(struct hv_cpuid)
|
||||
+ + n_entries * sizeof(struct hv_cpuid_entry);
|
||||
+
|
||||
+ cpuid = g_malloc0(cpuid_size);
|
||||
+ cpuid->nent = n_entries;
|
||||
+ cpuid->padding = 0;
|
||||
+
|
||||
+ for (size_t i = 0; i < n_entries; i++) {
|
||||
+ entry = g_list_nth_data(entries, i);
|
||||
+ cpuid->entries[i] = *entry;
|
||||
+ g_free(entry);
|
||||
+ }
|
||||
+ g_list_free(entries);
|
||||
+
|
||||
+ ret = register_intercept_result_cpuid(cpu, cpuid);
|
||||
+ g_free(cpuid);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline void populate_hv_segment_reg(SegmentCache *seg,
|
||||
hv_x64_segment_register *hv_reg)
|
||||
{
|
||||
@@ -685,6 +885,12 @@ int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu,
|
||||
int ret;
|
||||
int cpu_fd = mshv_vcpufd(cpu);
|
||||
|
||||
+ ret = set_cpuid2(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set cpuid");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
ret = set_cpu_state(cpu, fpu, xcr0);
|
||||
if (ret < 0) {
|
||||
error_report("failed to set cpu state");
|
||||
529
0077-target-i386-mshv-Register-MSRs-with-MSHV.patch
Normal file
529
0077-target-i386-mshv-Register-MSRs-with-MSHV.patch
Normal file
@ -0,0 +1,529 @@
|
||||
From 100c5e414f7867193fc2973660a6cabbf75f318f Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Thu, 2 Oct 2025 18:19:22 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Register MSRs with MSHV
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [20/30] 43ca27cba532fd1d562fa10ade6261df58af82fd
|
||||
|
||||
Build and register the guest vCPU's model-specific registers using
|
||||
the MSHV interface.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-20-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit f38e2a63e541730e114f6ed09e5f8719e388c8db)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Register-MSRs-with-MSHV.patch
|
||||
Patch-id: 80
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/meson.build | 1 +
|
||||
accel/mshv/msr.c | 375 ++++++++++++++++++++++++++++++++++++
|
||||
include/system/mshv_int.h | 17 ++
|
||||
target/i386/cpu.h | 2 +
|
||||
target/i386/mshv/mshv-cpu.c | 33 ++++
|
||||
5 files changed, 428 insertions(+)
|
||||
create mode 100644 accel/mshv/msr.c
|
||||
|
||||
diff --git a/accel/mshv/meson.build b/accel/mshv/meson.build
|
||||
index f88fc8678c..d3a2b32581 100644
|
||||
--- a/accel/mshv/meson.build
|
||||
+++ b/accel/mshv/meson.build
|
||||
@@ -2,6 +2,7 @@ mshv_ss = ss.source_set()
|
||||
mshv_ss.add(if_true: files(
|
||||
'irq.c',
|
||||
'mem.c',
|
||||
+ 'msr.c',
|
||||
'mshv-all.c'
|
||||
))
|
||||
|
||||
diff --git a/accel/mshv/msr.c b/accel/mshv/msr.c
|
||||
new file mode 100644
|
||||
index 0000000000..e6e5baef50
|
||||
--- /dev/null
|
||||
+++ b/accel/mshv/msr.c
|
||||
@@ -0,0 +1,375 @@
|
||||
+/*
|
||||
+ * QEMU MSHV support
|
||||
+ *
|
||||
+ * Copyright Microsoft, Corp. 2025
|
||||
+ *
|
||||
+ * Authors: Magnus Kulke <magnuskulke@microsoft.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "system/mshv.h"
|
||||
+#include "system/mshv_int.h"
|
||||
+#include "hw/hyperv/hvgdk_mini.h"
|
||||
+#include "linux/mshv.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+static uint32_t supported_msrs[64] = {
|
||||
+ IA32_MSR_TSC,
|
||||
+ IA32_MSR_EFER,
|
||||
+ IA32_MSR_KERNEL_GS_BASE,
|
||||
+ IA32_MSR_APIC_BASE,
|
||||
+ IA32_MSR_PAT,
|
||||
+ IA32_MSR_SYSENTER_CS,
|
||||
+ IA32_MSR_SYSENTER_ESP,
|
||||
+ IA32_MSR_SYSENTER_EIP,
|
||||
+ IA32_MSR_STAR,
|
||||
+ IA32_MSR_LSTAR,
|
||||
+ IA32_MSR_CSTAR,
|
||||
+ IA32_MSR_SFMASK,
|
||||
+ IA32_MSR_MTRR_DEF_TYPE,
|
||||
+ IA32_MSR_MTRR_PHYSBASE0,
|
||||
+ IA32_MSR_MTRR_PHYSMASK0,
|
||||
+ IA32_MSR_MTRR_PHYSBASE1,
|
||||
+ IA32_MSR_MTRR_PHYSMASK1,
|
||||
+ IA32_MSR_MTRR_PHYSBASE2,
|
||||
+ IA32_MSR_MTRR_PHYSMASK2,
|
||||
+ IA32_MSR_MTRR_PHYSBASE3,
|
||||
+ IA32_MSR_MTRR_PHYSMASK3,
|
||||
+ IA32_MSR_MTRR_PHYSBASE4,
|
||||
+ IA32_MSR_MTRR_PHYSMASK4,
|
||||
+ IA32_MSR_MTRR_PHYSBASE5,
|
||||
+ IA32_MSR_MTRR_PHYSMASK5,
|
||||
+ IA32_MSR_MTRR_PHYSBASE6,
|
||||
+ IA32_MSR_MTRR_PHYSMASK6,
|
||||
+ IA32_MSR_MTRR_PHYSBASE7,
|
||||
+ IA32_MSR_MTRR_PHYSMASK7,
|
||||
+ IA32_MSR_MTRR_FIX64K_00000,
|
||||
+ IA32_MSR_MTRR_FIX16K_80000,
|
||||
+ IA32_MSR_MTRR_FIX16K_A0000,
|
||||
+ IA32_MSR_MTRR_FIX4K_C0000,
|
||||
+ IA32_MSR_MTRR_FIX4K_C8000,
|
||||
+ IA32_MSR_MTRR_FIX4K_D0000,
|
||||
+ IA32_MSR_MTRR_FIX4K_D8000,
|
||||
+ IA32_MSR_MTRR_FIX4K_E0000,
|
||||
+ IA32_MSR_MTRR_FIX4K_E8000,
|
||||
+ IA32_MSR_MTRR_FIX4K_F0000,
|
||||
+ IA32_MSR_MTRR_FIX4K_F8000,
|
||||
+ IA32_MSR_TSC_AUX,
|
||||
+ IA32_MSR_DEBUG_CTL,
|
||||
+ HV_X64_MSR_GUEST_OS_ID,
|
||||
+ HV_X64_MSR_SINT0,
|
||||
+ HV_X64_MSR_SINT1,
|
||||
+ HV_X64_MSR_SINT2,
|
||||
+ HV_X64_MSR_SINT3,
|
||||
+ HV_X64_MSR_SINT4,
|
||||
+ HV_X64_MSR_SINT5,
|
||||
+ HV_X64_MSR_SINT6,
|
||||
+ HV_X64_MSR_SINT7,
|
||||
+ HV_X64_MSR_SINT8,
|
||||
+ HV_X64_MSR_SINT9,
|
||||
+ HV_X64_MSR_SINT10,
|
||||
+ HV_X64_MSR_SINT11,
|
||||
+ HV_X64_MSR_SINT12,
|
||||
+ HV_X64_MSR_SINT13,
|
||||
+ HV_X64_MSR_SINT14,
|
||||
+ HV_X64_MSR_SINT15,
|
||||
+ HV_X64_MSR_SCONTROL,
|
||||
+ HV_X64_MSR_SIEFP,
|
||||
+ HV_X64_MSR_SIMP,
|
||||
+ HV_X64_MSR_REFERENCE_TSC,
|
||||
+ HV_X64_MSR_EOM,
|
||||
+};
|
||||
+static const size_t msr_count = ARRAY_SIZE(supported_msrs);
|
||||
+
|
||||
+static int compare_msr_index(const void *a, const void *b)
|
||||
+{
|
||||
+ return *(uint32_t *)a - *(uint32_t *)b;
|
||||
+}
|
||||
+
|
||||
+__attribute__((constructor))
|
||||
+static void init_sorted_msr_map(void)
|
||||
+{
|
||||
+ qsort(supported_msrs, msr_count, sizeof(uint32_t), compare_msr_index);
|
||||
+}
|
||||
+
|
||||
+static int mshv_is_supported_msr(uint32_t msr)
|
||||
+{
|
||||
+ return bsearch(&msr, supported_msrs, msr_count, sizeof(uint32_t),
|
||||
+ compare_msr_index) != NULL;
|
||||
+}
|
||||
+
|
||||
+static int mshv_msr_to_hv_reg_name(uint32_t msr, uint32_t *hv_reg)
|
||||
+{
|
||||
+ switch (msr) {
|
||||
+ case IA32_MSR_TSC:
|
||||
+ *hv_reg = HV_X64_REGISTER_TSC;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_EFER:
|
||||
+ *hv_reg = HV_X64_REGISTER_EFER;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_KERNEL_GS_BASE:
|
||||
+ *hv_reg = HV_X64_REGISTER_KERNEL_GS_BASE;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_APIC_BASE:
|
||||
+ *hv_reg = HV_X64_REGISTER_APIC_BASE;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_PAT:
|
||||
+ *hv_reg = HV_X64_REGISTER_PAT;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_SYSENTER_CS:
|
||||
+ *hv_reg = HV_X64_REGISTER_SYSENTER_CS;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_SYSENTER_ESP:
|
||||
+ *hv_reg = HV_X64_REGISTER_SYSENTER_ESP;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_SYSENTER_EIP:
|
||||
+ *hv_reg = HV_X64_REGISTER_SYSENTER_EIP;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_STAR:
|
||||
+ *hv_reg = HV_X64_REGISTER_STAR;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_LSTAR:
|
||||
+ *hv_reg = HV_X64_REGISTER_LSTAR;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_CSTAR:
|
||||
+ *hv_reg = HV_X64_REGISTER_CSTAR;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_SFMASK:
|
||||
+ *hv_reg = HV_X64_REGISTER_SFMASK;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_CAP:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_CAP;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_DEF_TYPE:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_DEF_TYPE;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE0:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK0:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE1:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK1:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE2:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK2:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE3:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK3:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE4:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK4:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE5:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK5:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE6:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK6:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSBASE7:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_PHYSMASK7:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX64K_00000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX64K00000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX16K_80000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX16K80000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX16K_A0000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX16KA0000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_C0000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KC0000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_C8000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KC8000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_D0000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KD0000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_D8000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KD8000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_E0000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KE0000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_E8000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KE8000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_F0000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KF0000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MTRR_FIX4K_F8000:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_MTRR_FIX4KF8000;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_TSC_AUX:
|
||||
+ *hv_reg = HV_X64_REGISTER_TSC_AUX;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_BNDCFGS:
|
||||
+ *hv_reg = HV_X64_REGISTER_BNDCFGS;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_DEBUG_CTL:
|
||||
+ *hv_reg = HV_X64_REGISTER_DEBUG_CTL;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_TSC_ADJUST:
|
||||
+ *hv_reg = HV_X64_REGISTER_TSC_ADJUST;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_SPEC_CTRL:
|
||||
+ *hv_reg = HV_X64_REGISTER_SPEC_CTRL;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_GUEST_OS_ID:
|
||||
+ *hv_reg = HV_REGISTER_GUEST_OS_ID;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT0:
|
||||
+ *hv_reg = HV_REGISTER_SINT0;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT1:
|
||||
+ *hv_reg = HV_REGISTER_SINT1;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT2:
|
||||
+ *hv_reg = HV_REGISTER_SINT2;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT3:
|
||||
+ *hv_reg = HV_REGISTER_SINT3;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT4:
|
||||
+ *hv_reg = HV_REGISTER_SINT4;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT5:
|
||||
+ *hv_reg = HV_REGISTER_SINT5;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT6:
|
||||
+ *hv_reg = HV_REGISTER_SINT6;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT7:
|
||||
+ *hv_reg = HV_REGISTER_SINT7;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT8:
|
||||
+ *hv_reg = HV_REGISTER_SINT8;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT9:
|
||||
+ *hv_reg = HV_REGISTER_SINT9;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT10:
|
||||
+ *hv_reg = HV_REGISTER_SINT10;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT11:
|
||||
+ *hv_reg = HV_REGISTER_SINT11;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT12:
|
||||
+ *hv_reg = HV_REGISTER_SINT12;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT13:
|
||||
+ *hv_reg = HV_REGISTER_SINT13;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT14:
|
||||
+ *hv_reg = HV_REGISTER_SINT14;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SINT15:
|
||||
+ *hv_reg = HV_REGISTER_SINT15;
|
||||
+ return 0;
|
||||
+ case IA32_MSR_MISC_ENABLE:
|
||||
+ *hv_reg = HV_X64_REGISTER_MSR_IA32_MISC_ENABLE;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SCONTROL:
|
||||
+ *hv_reg = HV_REGISTER_SCONTROL;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SIEFP:
|
||||
+ *hv_reg = HV_REGISTER_SIEFP;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_SIMP:
|
||||
+ *hv_reg = HV_REGISTER_SIMP;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_REFERENCE_TSC:
|
||||
+ *hv_reg = HV_REGISTER_REFERENCE_TSC;
|
||||
+ return 0;
|
||||
+ case HV_X64_MSR_EOM:
|
||||
+ *hv_reg = HV_REGISTER_EOM;
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ error_report("failed to map MSR %u to HV register name", msr);
|
||||
+ return -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int set_msrs(const CPUState *cpu, GList *msrs)
|
||||
+{
|
||||
+ size_t n_msrs;
|
||||
+ GList *entries;
|
||||
+ MshvMsrEntry *entry;
|
||||
+ enum hv_register_name name;
|
||||
+ struct hv_register_assoc *assoc;
|
||||
+ int ret;
|
||||
+ size_t i = 0;
|
||||
+
|
||||
+ n_msrs = g_list_length(msrs);
|
||||
+ hv_register_assoc *assocs = g_new0(hv_register_assoc, n_msrs);
|
||||
+
|
||||
+ entries = msrs;
|
||||
+ for (const GList *elem = entries; elem != NULL; elem = elem->next) {
|
||||
+ entry = elem->data;
|
||||
+ ret = mshv_msr_to_hv_reg_name(entry->index, &name);
|
||||
+ if (ret < 0) {
|
||||
+ g_free(assocs);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ assoc = &assocs[i];
|
||||
+ assoc->name = name;
|
||||
+ /* the union has been initialized to 0 */
|
||||
+ assoc->value.reg64 = entry->data;
|
||||
+ i++;
|
||||
+ }
|
||||
+ ret = mshv_set_generic_regs(cpu, assocs, n_msrs);
|
||||
+ g_free(assocs);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set msrs");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs,
|
||||
+ size_t n_msrs)
|
||||
+{
|
||||
+ GList *valid_msrs = NULL;
|
||||
+ uint32_t msr_index;
|
||||
+ int ret;
|
||||
+
|
||||
+ for (size_t i = 0; i < n_msrs; i++) {
|
||||
+ msr_index = msrs[i].index;
|
||||
+ /* check whether index of msrs is in SUPPORTED_MSRS */
|
||||
+ if (mshv_is_supported_msr(msr_index)) {
|
||||
+ valid_msrs = g_list_append(valid_msrs, (void *) &msrs[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = set_msrs(cpu, valid_msrs);
|
||||
+ g_list_free(valid_msrs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index 0ea8d504fa..6649438313 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef QEMU_MSHV_INT_H
|
||||
#define QEMU_MSHV_INT_H
|
||||
|
||||
+#define MSHV_MSR_ENTRIES_COUNT 64
|
||||
+
|
||||
typedef struct hyperv_message hv_message;
|
||||
|
||||
struct AccelCPUState {
|
||||
@@ -102,6 +104,21 @@ typedef struct MshvMemoryRegion {
|
||||
void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
bool add);
|
||||
|
||||
+/* msr */
|
||||
+typedef struct MshvMsrEntry {
|
||||
+ uint32_t index;
|
||||
+ uint32_t reserved;
|
||||
+ uint64_t data;
|
||||
+} MshvMsrEntry;
|
||||
+
|
||||
+typedef struct MshvMsrEntries {
|
||||
+ MshvMsrEntry entries[MSHV_MSR_ENTRIES_COUNT];
|
||||
+ uint32_t nmsrs;
|
||||
+} MshvMsrEntries;
|
||||
+
|
||||
+int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs,
|
||||
+ size_t n_msrs);
|
||||
+
|
||||
/* interrupt */
|
||||
void mshv_init_msicontrol(void);
|
||||
int mshv_reserve_ioapic_msi_routes(int vm_fd);
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index 4b7eae43e1..8f780a3abe 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -435,9 +435,11 @@ typedef enum X86Seg {
|
||||
#define MSR_SMI_COUNT 0x34
|
||||
#define MSR_CORE_THREAD_COUNT 0x35
|
||||
#define MSR_MTRRcap 0xfe
|
||||
+#define MSR_MTRR_MEM_TYPE_WB 0x06
|
||||
#define MSR_MTRRcap_VCNT 8
|
||||
#define MSR_MTRRcap_FIXRANGE_SUPPORT (1 << 8)
|
||||
#define MSR_MTRRcap_WC_SUPPORTED (1 << 10)
|
||||
+#define MSR_MTRR_ENABLE (1 << 11)
|
||||
|
||||
#define MSR_IA32_SYSENTER_CS 0x174
|
||||
#define MSR_IA32_SYSENTER_ESP 0x175
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 2b7a81274b..1f43dfc58a 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -872,6 +872,33 @@ static int set_lint(int cpu_fd)
|
||||
return set_lapic(cpu_fd, &lapic_state);
|
||||
}
|
||||
|
||||
+static int setup_msrs(const CPUState *cpu)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t default_type = MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB;
|
||||
+
|
||||
+ /* boot msr entries */
|
||||
+ MshvMsrEntry msrs[9] = {
|
||||
+ { .index = IA32_MSR_SYSENTER_CS, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_SYSENTER_ESP, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_SYSENTER_EIP, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_STAR, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_CSTAR, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_LSTAR, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_KERNEL_GS_BASE, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_SFMASK, .data = 0x0, },
|
||||
+ { .index = IA32_MSR_MTRR_DEF_TYPE, .data = default_type, },
|
||||
+ };
|
||||
+
|
||||
+ ret = mshv_configure_msr(cpu, msrs, 9);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to setup msrs");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* TODO: populate topology info:
|
||||
*
|
||||
@@ -891,6 +918,12 @@ int mshv_configure_vcpu(const CPUState *cpu, const struct MshvFPU *fpu,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ ret = setup_msrs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to setup msrs");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
ret = set_cpu_state(cpu, fpu, xcr0);
|
||||
if (ret < 0) {
|
||||
error_report("failed to set cpu state");
|
||||
283
0078-target-i386-mshv-Integrate-x86-instruction-decoder-e.patch
Normal file
283
0078-target-i386-mshv-Integrate-x86-instruction-decoder-e.patch
Normal file
@ -0,0 +1,283 @@
|
||||
From 0f233bbf8c0eafdef5d1d4ceb9fcd5264dec029e Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:40 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Integrate x86 instruction decoder/emulator
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [21/30] c9dba7c3e0a4c896fa581b97f121a293606e074f
|
||||
|
||||
Connect the x86 instruction decoder and emulator to the MSHV backend
|
||||
to handle intercepted instructions. This enables software emulation
|
||||
of MMIO operations in MSHV guests. MSHV has a translate_gva hypercall
|
||||
that is used to accessing the physical guest memory.
|
||||
|
||||
A guest might read from unmapped memory regions (e.g. OVMF will probe
|
||||
0xfed40000 for a vTPM). In those cases 0xFF bytes is returned instead of
|
||||
aborting the execution.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-21-magnuskulke@linux.microsoft.com
|
||||
[mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 9bc6a1d29605a13c541629a651e41787af65a963)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Integrate-x86-instruction-decoder-e.patch
|
||||
Patch-id: 81
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mem.c | 65 +++++++++++++++++
|
||||
include/system/mshv_int.h | 4 ++
|
||||
target/i386/mshv/mshv-cpu.c | 135 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 204 insertions(+)
|
||||
|
||||
diff --git a/accel/mshv/mem.c b/accel/mshv/mem.c
|
||||
index a0a40eb333..e55c38d4db 100644
|
||||
--- a/accel/mshv/mem.c
|
||||
+++ b/accel/mshv/mem.c
|
||||
@@ -59,6 +59,71 @@ static int map_or_unmap(int vm_fd, const MshvMemoryRegion *mr, bool map)
|
||||
return set_guest_memory(vm_fd, ®ion);
|
||||
}
|
||||
|
||||
+static int handle_unmapped_mmio_region_read(uint64_t gpa, uint64_t size,
|
||||
+ uint8_t *data)
|
||||
+{
|
||||
+ warn_report("read from unmapped mmio region gpa=0x%lx size=%lu", gpa, size);
|
||||
+
|
||||
+ if (size == 0 || size > 8) {
|
||||
+ error_report("invalid size %lu for reading from unmapped mmio region",
|
||||
+ size);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ memset(data, 0xFF, size);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mshv_guest_mem_read(uint64_t gpa, uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode, bool instruction_fetch)
|
||||
+{
|
||||
+ int ret;
|
||||
+ MemTxAttrs memattr = { .secure = is_secure_mode };
|
||||
+
|
||||
+ if (instruction_fetch) {
|
||||
+ trace_mshv_insn_fetch(gpa, size);
|
||||
+ } else {
|
||||
+ trace_mshv_mem_read(gpa, size);
|
||||
+ }
|
||||
+
|
||||
+ ret = address_space_rw(&address_space_memory, gpa, memattr, (void *)data,
|
||||
+ size, false);
|
||||
+ if (ret == MEMTX_OK) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ret == MEMTX_DECODE_ERROR) {
|
||||
+ return handle_unmapped_mmio_region_read(gpa, size, data);
|
||||
+ }
|
||||
+
|
||||
+ error_report("failed to read guest memory at 0x%lx", gpa);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode)
|
||||
+{
|
||||
+ int ret;
|
||||
+ MemTxAttrs memattr = { .secure = is_secure_mode };
|
||||
+
|
||||
+ trace_mshv_mem_write(gpa, size);
|
||||
+ ret = address_space_rw(&address_space_memory, gpa, memattr, (void *)data,
|
||||
+ size, true);
|
||||
+ if (ret == MEMTX_OK) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ret == MEMTX_DECODE_ERROR) {
|
||||
+ warn_report("write to unmapped mmio region gpa=0x%lx size=%lu", gpa,
|
||||
+ size);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ error_report("Failed to write guest memory");
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
static int set_memory(const MshvMemoryRegion *mshv_mr, bool add)
|
||||
{
|
||||
int ret = 0;
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index 6649438313..b29d39911d 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -101,6 +101,10 @@ typedef struct MshvMemoryRegion {
|
||||
bool readonly;
|
||||
} MshvMemoryRegion;
|
||||
|
||||
+int mshv_guest_mem_read(uint64_t gpa, uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode, bool instruction_fetch);
|
||||
+int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode);
|
||||
void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
bool add);
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 1f43dfc58a..424ebdb122 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -104,6 +104,47 @@ static enum hv_register_name FPU_REGISTER_NAMES[26] = {
|
||||
HV_X64_REGISTER_XMM_CONTROL_STATUS,
|
||||
};
|
||||
|
||||
+static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa,
|
||||
+ uint64_t flags)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+ int vp_index = cpu->cpu_index;
|
||||
+
|
||||
+ hv_input_translate_virtual_address in = { 0 };
|
||||
+ hv_output_translate_virtual_address out = { 0 };
|
||||
+ struct mshv_root_hvcall args = {0};
|
||||
+ uint64_t gva_page = gva >> HV_HYP_PAGE_SHIFT;
|
||||
+
|
||||
+ in.vp_index = vp_index;
|
||||
+ in.control_flags = flags;
|
||||
+ in.gva_page = gva_page;
|
||||
+
|
||||
+ /* create the hvcall envelope */
|
||||
+ args.code = HVCALL_TRANSLATE_VIRTUAL_ADDRESS;
|
||||
+ args.in_sz = sizeof(in);
|
||||
+ args.in_ptr = (uint64_t) ∈
|
||||
+ args.out_sz = sizeof(out);
|
||||
+ args.out_ptr = (uint64_t) &out;
|
||||
+
|
||||
+ /* perform the call */
|
||||
+ ret = mshv_hvcall(cpu_fd, &args);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to invoke gva->gpa translation");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ if (out.translation_result.result_code != HV_TRANSLATE_GVA_SUCCESS) {
|
||||
+ error_report("Failed to translate gva (" TARGET_FMT_lx ") to gpa", gva);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *gpa = ((out.gpa_page << HV_HYP_PAGE_SHIFT)
|
||||
+ | (gva & ~(uint64_t)HV_HYP_PAGE_MASK));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
size_t n_regs)
|
||||
{
|
||||
@@ -1006,8 +1047,102 @@ int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int guest_mem_read_with_gva(const CPUState *cpu, uint64_t gva,
|
||||
+ uint8_t *data, uintptr_t size,
|
||||
+ bool fetch_instruction)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t gpa, flags;
|
||||
+
|
||||
+ flags = HV_TRANSLATE_GVA_VALIDATE_READ;
|
||||
+ ret = translate_gva(cpu, gva, &gpa, flags);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to translate gva to gpa");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_guest_mem_read(gpa, data, size, false, fetch_instruction);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to read from guest memory");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int guest_mem_write_with_gva(const CPUState *cpu, uint64_t gva,
|
||||
+ const uint8_t *data, uintptr_t size)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t gpa, flags;
|
||||
+
|
||||
+ flags = HV_TRANSLATE_GVA_VALIDATE_WRITE;
|
||||
+ ret = translate_gva(cpu, gva, &gpa, flags);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to translate gva to gpa");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ ret = mshv_guest_mem_write(gpa, data, size, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to write to guest memory");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void write_mem(CPUState *cpu, void *data, target_ulong addr, int bytes)
|
||||
+{
|
||||
+ if (guest_mem_write_with_gva(cpu, addr, data, bytes) < 0) {
|
||||
+ error_report("failed to write memory");
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void fetch_instruction(CPUState *cpu, void *data,
|
||||
+ target_ulong addr, int bytes)
|
||||
+{
|
||||
+ if (guest_mem_read_with_gva(cpu, addr, data, bytes, true) < 0) {
|
||||
+ error_report("failed to fetch instruction");
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void read_mem(CPUState *cpu, void *data, target_ulong addr, int bytes)
|
||||
+{
|
||||
+ if (guest_mem_read_with_gva(cpu, addr, data, bytes, false) < 0) {
|
||||
+ error_report("failed to read memory");
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void read_segment_descriptor(CPUState *cpu,
|
||||
+ struct x86_segment_descriptor *desc,
|
||||
+ enum X86Seg seg_idx)
|
||||
+{
|
||||
+ bool ret;
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ SegmentCache *seg = &env->segs[seg_idx];
|
||||
+ x86_segment_selector sel = { .sel = seg->selector & 0xFFFF };
|
||||
+
|
||||
+ ret = x86_read_segment_descriptor(cpu, desc, sel);
|
||||
+ if (ret == false) {
|
||||
+ error_report("failed to read segment descriptor");
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct x86_emul_ops mshv_x86_emul_ops = {
|
||||
+ .fetch_instruction = fetch_instruction,
|
||||
+ .read_mem = read_mem,
|
||||
+ .write_mem = write_mem,
|
||||
+ .read_segment_descriptor = read_segment_descriptor,
|
||||
+};
|
||||
+
|
||||
void mshv_init_mmio_emu(void)
|
||||
{
|
||||
+ init_decoder();
|
||||
+ init_emu(&mshv_x86_emul_ops);
|
||||
}
|
||||
|
||||
void mshv_arch_init_vcpu(CPUState *cpu)
|
||||
114
0079-target-i386-mshv-Write-MSRs-to-the-hypervisor.patch
Normal file
114
0079-target-i386-mshv-Write-MSRs-to-the-hypervisor.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 8e713b554eac614d11513364580ffc8e5723645a Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:41 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Write MSRs to the hypervisor
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [22/30] 8b9720dbc31e48c43e618a0650a21eb5a43b7954
|
||||
|
||||
Push current model-specific register (MSR) values to MSHV's vCPUs as
|
||||
part of setting state to the hypervisor.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-22-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 64118f452cbd97cd9fa790b1c15b65b435f136d2)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Write-MSRs-to-the-hypervisor.patch
|
||||
Patch-id: 82
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 68 +++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 66 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 424ebdb122..33a3ce8b11 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -998,6 +998,65 @@ static int put_regs(const CPUState *cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct MsrPair {
|
||||
+ uint32_t index;
|
||||
+ uint64_t value;
|
||||
+};
|
||||
+
|
||||
+static int put_msrs(const CPUState *cpu)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ X86CPU *x86cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86cpu->env;
|
||||
+ MshvMsrEntries *msrs = g_malloc0(sizeof(MshvMsrEntries));
|
||||
+
|
||||
+ struct MsrPair pairs[] = {
|
||||
+ { MSR_IA32_SYSENTER_CS, env->sysenter_cs },
|
||||
+ { MSR_IA32_SYSENTER_ESP, env->sysenter_esp },
|
||||
+ { MSR_IA32_SYSENTER_EIP, env->sysenter_eip },
|
||||
+ { MSR_EFER, env->efer },
|
||||
+ { MSR_PAT, env->pat },
|
||||
+ { MSR_STAR, env->star },
|
||||
+ { MSR_CSTAR, env->cstar },
|
||||
+ { MSR_LSTAR, env->lstar },
|
||||
+ { MSR_KERNELGSBASE, env->kernelgsbase },
|
||||
+ { MSR_FMASK, env->fmask },
|
||||
+ { MSR_MTRRdefType, env->mtrr_deftype },
|
||||
+ { MSR_VM_HSAVE_PA, env->vm_hsave },
|
||||
+ { MSR_SMI_COUNT, env->msr_smi_count },
|
||||
+ { MSR_IA32_PKRS, env->pkrs },
|
||||
+ { MSR_IA32_BNDCFGS, env->msr_bndcfgs },
|
||||
+ { MSR_IA32_XSS, env->xss },
|
||||
+ { MSR_IA32_UMWAIT_CONTROL, env->umwait },
|
||||
+ { MSR_IA32_TSX_CTRL, env->tsx_ctrl },
|
||||
+ { MSR_AMD64_TSC_RATIO, env->amd_tsc_scale_msr },
|
||||
+ { MSR_TSC_AUX, env->tsc_aux },
|
||||
+ { MSR_TSC_ADJUST, env->tsc_adjust },
|
||||
+ { MSR_IA32_SMBASE, env->smbase },
|
||||
+ { MSR_IA32_SPEC_CTRL, env->spec_ctrl },
|
||||
+ { MSR_VIRT_SSBD, env->virt_ssbd },
|
||||
+ };
|
||||
+
|
||||
+ if (ARRAY_SIZE(pairs) > MSHV_MSR_ENTRIES_COUNT) {
|
||||
+ error_report("MSR entries exceed maximum size");
|
||||
+ g_free(msrs);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < ARRAY_SIZE(pairs); i++) {
|
||||
+ MshvMsrEntry *entry = &msrs->entries[i];
|
||||
+ entry->index = pairs[i].index;
|
||||
+ entry->reserved = 0;
|
||||
+ entry->data = pairs[i].value;
|
||||
+ msrs->nmsrs++;
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_configure_msr(cpu, &msrs->entries[0], msrs->nmsrs);
|
||||
+ g_free(msrs);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int mshv_arch_put_registers(const CPUState *cpu)
|
||||
{
|
||||
int ret;
|
||||
@@ -1008,8 +1067,13 @@ int mshv_arch_put_registers(const CPUState *cpu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ ret = put_msrs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to put msrs");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void mshv_arch_amend_proc_features(
|
||||
490
0080-target-i386-mshv-Implement-mshv_vcpu_run.patch
Normal file
490
0080-target-i386-mshv-Implement-mshv_vcpu_run.patch
Normal file
@ -0,0 +1,490 @@
|
||||
From 4c7f452f08434460dd37f604d985588b248d7759 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:42 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Implement mshv_vcpu_run()
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [23/30] f21e5df491be51f4256237f9497fbc73f44cc386
|
||||
|
||||
Add the main vCPU execution loop for MSHV using the MSHV_RUN_VP ioctl.
|
||||
|
||||
The execution loop handles guest entry and VM exits. There are handlers for
|
||||
memory r/w, PIO and MMIO to which the exit events are dispatched.
|
||||
|
||||
In case of MMIO the i386 instruction decoder/emulator is invoked to
|
||||
perform the operation in user space.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-23-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 6dec60528c419781f1f79cd9837d5f26415a3fd7)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Implement-mshv_vcpu_run.patch
|
||||
Patch-id: 83
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 444 +++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 442 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 33a3ce8b11..7edc032cea 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -1082,10 +1082,450 @@ void mshv_arch_amend_proc_features(
|
||||
features->access_guest_idle_reg = 1;
|
||||
}
|
||||
|
||||
+static int set_memory_info(const struct hyperv_message *msg,
|
||||
+ struct hv_x64_memory_intercept_message *info)
|
||||
+{
|
||||
+ if (msg->header.message_type != HVMSG_GPA_INTERCEPT
|
||||
+ && msg->header.message_type != HVMSG_UNMAPPED_GPA
|
||||
+ && msg->header.message_type != HVMSG_UNACCEPTED_GPA) {
|
||||
+ error_report("invalid message type");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(info, msg->payload, sizeof(*info));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int emulate_instruction(CPUState *cpu,
|
||||
+ const uint8_t *insn_bytes, size_t insn_len,
|
||||
+ uint64_t gva, uint64_t gpa)
|
||||
+{
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+ struct x86_decode decode = { 0 };
|
||||
+ int ret;
|
||||
+ x86_insn_stream stream = { .bytes = insn_bytes, .len = insn_len };
|
||||
+
|
||||
+ ret = mshv_load_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to load registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ decode_instruction_stream(env, &decode, &stream);
|
||||
+ exec_instruction(env, &decode);
|
||||
+
|
||||
+ ret = mshv_store_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to store registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int handle_mmio(CPUState *cpu, const struct hyperv_message *msg,
|
||||
+ MshvVmExit *exit_reason)
|
||||
+{
|
||||
+ struct hv_x64_memory_intercept_message info = { 0 };
|
||||
+ size_t insn_len;
|
||||
+ uint8_t access_type;
|
||||
+ uint8_t *instruction_bytes;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = set_memory_info(msg, &info);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to convert message to memory info");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ insn_len = info.instruction_byte_count;
|
||||
+ access_type = info.header.intercept_access_type;
|
||||
+
|
||||
+ if (access_type == HV_X64_INTERCEPT_ACCESS_TYPE_EXECUTE) {
|
||||
+ error_report("invalid intercept access type: execute");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (insn_len > 16) {
|
||||
+ error_report("invalid mmio instruction length: %zu", insn_len);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ trace_mshv_handle_mmio(info.guest_virtual_address,
|
||||
+ info.guest_physical_address,
|
||||
+ info.instruction_byte_count, access_type);
|
||||
+
|
||||
+ instruction_bytes = info.instruction_bytes;
|
||||
+
|
||||
+ ret = emulate_instruction(cpu, instruction_bytes, insn_len,
|
||||
+ info.guest_virtual_address,
|
||||
+ info.guest_physical_address);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to emulate mmio");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *exit_reason = MshvVmExitIgnore;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_ioport_info(const struct hyperv_message *msg,
|
||||
+ hv_x64_io_port_intercept_message *info)
|
||||
+{
|
||||
+ if (msg->header.message_type != HVMSG_X64_IO_PORT_INTERCEPT) {
|
||||
+ error_report("Invalid message type");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(info, msg->payload, sizeof(*info));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_x64_registers(const CPUState *cpu, const uint32_t *names,
|
||||
+ const uint64_t *values)
|
||||
+{
|
||||
+
|
||||
+ hv_register_assoc assocs[2];
|
||||
+ int ret;
|
||||
+
|
||||
+ for (size_t i = 0; i < ARRAY_SIZE(assocs); i++) {
|
||||
+ assocs[i].name = names[i];
|
||||
+ assocs[i].value.reg64 = values[i];
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs));
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to set x64 registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline MemTxAttrs get_mem_attrs(bool is_secure_mode)
|
||||
+{
|
||||
+ MemTxAttrs memattr = {0};
|
||||
+ memattr.secure = is_secure_mode;
|
||||
+ return memattr;
|
||||
+}
|
||||
+
|
||||
+static void pio_read(uint64_t port, uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ MemTxAttrs memattr = get_mem_attrs(is_secure_mode);
|
||||
+ ret = address_space_rw(&address_space_io, port, memattr, (void *)data, size,
|
||||
+ false);
|
||||
+ if (ret != MEMTX_OK) {
|
||||
+ error_report("Failed to read from port %lx: %d", port, ret);
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int pio_write(uint64_t port, const uint8_t *data, uintptr_t size,
|
||||
+ bool is_secure_mode)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ MemTxAttrs memattr = get_mem_attrs(is_secure_mode);
|
||||
+ ret = address_space_rw(&address_space_io, port, memattr, (void *)data, size,
|
||||
+ true);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int handle_pio_non_str(const CPUState *cpu,
|
||||
+ hv_x64_io_port_intercept_message *info)
|
||||
+{
|
||||
+ size_t len = info->access_info.access_size;
|
||||
+ uint8_t access_type = info->header.intercept_access_type;
|
||||
+ int ret;
|
||||
+ uint32_t val, eax;
|
||||
+ const uint32_t eax_mask = 0xffffffffu >> (32 - len * 8);
|
||||
+ size_t insn_len;
|
||||
+ uint64_t rip, rax;
|
||||
+ uint32_t reg_names[2];
|
||||
+ uint64_t reg_values[2];
|
||||
+ uint16_t port = info->port_number;
|
||||
+
|
||||
+ if (access_type == HV_X64_INTERCEPT_ACCESS_TYPE_WRITE) {
|
||||
+ union {
|
||||
+ uint32_t u32;
|
||||
+ uint8_t bytes[4];
|
||||
+ } conv;
|
||||
+
|
||||
+ /* convert the first 4 bytes of rax to bytes */
|
||||
+ conv.u32 = (uint32_t)info->rax;
|
||||
+ /* secure mode is set to false */
|
||||
+ ret = pio_write(port, conv.bytes, len, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to write to io port");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ uint8_t data[4] = { 0 };
|
||||
+ /* secure mode is set to false */
|
||||
+ pio_read(info->port_number, data, len, false);
|
||||
+
|
||||
+ /* Preserve high bits in EAX, but clear out high bits in RAX */
|
||||
+ val = *(uint32_t *)data;
|
||||
+ eax = (((uint32_t)info->rax) & ~eax_mask) | (val & eax_mask);
|
||||
+ info->rax = (uint64_t)eax;
|
||||
+ }
|
||||
+
|
||||
+ insn_len = info->header.instruction_length;
|
||||
+
|
||||
+ /* Advance RIP and update RAX */
|
||||
+ rip = info->header.rip + insn_len;
|
||||
+ rax = info->rax;
|
||||
+
|
||||
+ reg_names[0] = HV_X64_REGISTER_RIP;
|
||||
+ reg_values[0] = rip;
|
||||
+ reg_names[1] = HV_X64_REGISTER_RAX;
|
||||
+ reg_values[1] = rax;
|
||||
+
|
||||
+ ret = set_x64_registers(cpu, reg_names, reg_values);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to set x64 registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ cpu->accel->dirty = false;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fetch_guest_state(CPUState *cpu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mshv_get_standard_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to get standard registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_get_special_regs(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to get special registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int read_memory(const CPUState *cpu, uint64_t initial_gva,
|
||||
+ uint64_t initial_gpa, uint64_t gva, uint8_t *data,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t gpa, flags;
|
||||
+
|
||||
+ if (gva == initial_gva) {
|
||||
+ gpa = initial_gpa;
|
||||
+ } else {
|
||||
+ flags = HV_TRANSLATE_GVA_VALIDATE_READ;
|
||||
+ ret = translate_gva(cpu, gva, &gpa, flags);
|
||||
+ if (ret < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = mshv_guest_mem_read(gpa, data, len, false, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to read guest mem");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int write_memory(const CPUState *cpu, uint64_t initial_gva,
|
||||
+ uint64_t initial_gpa, uint64_t gva, const uint8_t *data,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t gpa, flags;
|
||||
+
|
||||
+ if (gva == initial_gva) {
|
||||
+ gpa = initial_gpa;
|
||||
+ } else {
|
||||
+ flags = HV_TRANSLATE_GVA_VALIDATE_WRITE;
|
||||
+ ret = translate_gva(cpu, gva, &gpa, flags);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to translate gva to gpa");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ ret = mshv_guest_mem_write(gpa, data, len, false);
|
||||
+ if (ret != MEMTX_OK) {
|
||||
+ error_report("failed to write to mmio");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int handle_pio_str_write(CPUState *cpu,
|
||||
+ hv_x64_io_port_intercept_message *info,
|
||||
+ size_t repeat, uint16_t port,
|
||||
+ bool direction_flag)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t src;
|
||||
+ uint8_t data[4] = { 0 };
|
||||
+ size_t len = info->access_info.access_size;
|
||||
+
|
||||
+ src = linear_addr(cpu, info->rsi, R_DS);
|
||||
+
|
||||
+ for (size_t i = 0; i < repeat; i++) {
|
||||
+ ret = read_memory(cpu, 0, 0, src, data, len);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to read memory");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ ret = pio_write(port, data, len, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to write to io port");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ src += direction_flag ? -len : len;
|
||||
+ info->rsi += direction_flag ? -len : len;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int handle_pio_str_read(CPUState *cpu,
|
||||
+ hv_x64_io_port_intercept_message *info,
|
||||
+ size_t repeat, uint16_t port,
|
||||
+ bool direction_flag)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint64_t dst;
|
||||
+ size_t len = info->access_info.access_size;
|
||||
+ uint8_t data[4] = { 0 };
|
||||
+
|
||||
+ dst = linear_addr(cpu, info->rdi, R_ES);
|
||||
+
|
||||
+ for (size_t i = 0; i < repeat; i++) {
|
||||
+ pio_read(port, data, len, false);
|
||||
+
|
||||
+ ret = write_memory(cpu, 0, 0, dst, data, len);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to write memory");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ dst += direction_flag ? -len : len;
|
||||
+ info->rdi += direction_flag ? -len : len;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int handle_pio_str(CPUState *cpu, hv_x64_io_port_intercept_message *info)
|
||||
+{
|
||||
+ uint8_t access_type = info->header.intercept_access_type;
|
||||
+ uint16_t port = info->port_number;
|
||||
+ bool repop = info->access_info.rep_prefix == 1;
|
||||
+ size_t repeat = repop ? info->rcx : 1;
|
||||
+ size_t insn_len = info->header.instruction_length;
|
||||
+ bool direction_flag;
|
||||
+ uint32_t reg_names[3];
|
||||
+ uint64_t reg_values[3];
|
||||
+ int ret;
|
||||
+ X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
+ CPUX86State *env = &x86_cpu->env;
|
||||
+
|
||||
+ ret = fetch_guest_state(cpu);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to fetch guest state");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ direction_flag = (env->eflags & DESC_E_MASK) != 0;
|
||||
+
|
||||
+ if (access_type == HV_X64_INTERCEPT_ACCESS_TYPE_WRITE) {
|
||||
+ ret = handle_pio_str_write(cpu, info, repeat, port, direction_flag);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to handle pio str write");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ reg_names[0] = HV_X64_REGISTER_RSI;
|
||||
+ reg_values[0] = info->rsi;
|
||||
+ } else {
|
||||
+ ret = handle_pio_str_read(cpu, info, repeat, port, direction_flag);
|
||||
+ reg_names[0] = HV_X64_REGISTER_RDI;
|
||||
+ reg_values[0] = info->rdi;
|
||||
+ }
|
||||
+
|
||||
+ reg_names[1] = HV_X64_REGISTER_RIP;
|
||||
+ reg_values[1] = info->header.rip + insn_len;
|
||||
+ reg_names[2] = HV_X64_REGISTER_RAX;
|
||||
+ reg_values[2] = info->rax;
|
||||
+
|
||||
+ ret = set_x64_registers(cpu, reg_names, reg_values);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to set x64 registers");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ cpu->accel->dirty = false;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int handle_pio(CPUState *cpu, const struct hyperv_message *msg)
|
||||
+{
|
||||
+ struct hv_x64_io_port_intercept_message info = { 0 };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = set_ioport_info(msg, &info);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to convert message to ioport info");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (info.access_info.string_op) {
|
||||
+ return handle_pio_str(cpu, &info);
|
||||
+ }
|
||||
+
|
||||
+ return handle_pio_non_str(cpu, &info);
|
||||
+}
|
||||
+
|
||||
int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
|
||||
{
|
||||
- error_report("unimplemented");
|
||||
- abort();
|
||||
+ int ret;
|
||||
+ enum MshvVmExit exit_reason;
|
||||
+ int cpu_fd = mshv_vcpufd(cpu);
|
||||
+
|
||||
+ ret = ioctl(cpu_fd, MSHV_RUN_VP, msg);
|
||||
+ if (ret < 0) {
|
||||
+ return MshvVmExitShutdown;
|
||||
+ }
|
||||
+
|
||||
+ switch (msg->header.message_type) {
|
||||
+ case HVMSG_UNRECOVERABLE_EXCEPTION:
|
||||
+ return MshvVmExitShutdown;
|
||||
+ case HVMSG_UNMAPPED_GPA:
|
||||
+ case HVMSG_GPA_INTERCEPT:
|
||||
+ ret = handle_mmio(cpu, msg, &exit_reason);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to handle mmio");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return exit_reason;
|
||||
+ case HVMSG_X64_IO_PORT_INTERCEPT:
|
||||
+ ret = handle_pio(cpu, msg);
|
||||
+ if (ret < 0) {
|
||||
+ return MshvVmExitSpecial;
|
||||
+ }
|
||||
+ return MshvVmExitIgnore;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ *exit = MshvVmExitIgnore;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd)
|
||||
696
0081-accel-mshv-Handle-overlapping-mem-mappings.patch
Normal file
696
0081-accel-mshv-Handle-overlapping-mem-mappings.patch
Normal file
@ -0,0 +1,696 @@
|
||||
From ccc3eea713711a301281dd8ae0f5197cbcc7ac4a Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:43 +0200
|
||||
Subject: [PATCH] accel/mshv: Handle overlapping mem mappings
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [24/30] abe9045eadeabccae811682dccd8679f41c32cc0
|
||||
|
||||
QEMU maps certain regions into the guest multiple times, as seen in the
|
||||
trace below. Currently the MSHV kernel driver will reject those
|
||||
mappings. To workaround this, a record is kept (a static global list of
|
||||
"slots", inspired by what the HVF accelerator has implemented). An
|
||||
overlapping region is not registered at the hypervisor, and marked as
|
||||
mapped=false. If there is an UNMAPPED_GPA exit, we can look for a slot
|
||||
that is unmapped and would cover the GPA. In this case we map out the
|
||||
conflicting slot and map in the requested region.
|
||||
|
||||
mshv_set_phys_mem add=1 name=pc.bios
|
||||
mshv_map_memory => u_a=7ffff4e00000 gpa=00fffc0000 size=00040000
|
||||
mshv_set_phys_mem add=1 name=ioapic
|
||||
mshv_set_phys_mem add=1 name=hpet
|
||||
mshv_set_phys_mem add=0 name=pc.ram
|
||||
mshv_unmap_memory u_a=7fff67e00000 gpa=0000000000 size=80000000
|
||||
mshv_set_phys_mem add=1 name=pc.ram
|
||||
mshv_map_memory u_a=7fff67e00000 gpa=0000000000 size=000c0000
|
||||
mshv_set_phys_mem add=1 name=pc.rom
|
||||
mshv_map_memory u_a=7ffff4c00000 gpa=00000c0000 size=00020000
|
||||
mshv_set_phys_mem add=1 name=pc.bios
|
||||
mshv_remap_attempt => u_a=7ffff4e20000 gpa=00000e0000 size=00020000
|
||||
|
||||
The mapping table is guarded by a mutex for concurrent modification and
|
||||
RCU mechanisms for concurrent reads. Writes occur rarely, but we'll have
|
||||
to verify whether an unmapped region exist for each UNMAPPED_GPA exit,
|
||||
which happens frequently.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-24-magnuskulke@linux.microsoft.com
|
||||
[Fix format strings for trace-events; mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit efc4093358511a58846a409b965213aa1bb9f31a)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-Handle-overlapping-mem-mappings.patch
|
||||
Patch-id: 84
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mem.c | 406 +++++++++++++++++++++++++++++++++---
|
||||
accel/mshv/mshv-all.c | 2 +
|
||||
accel/mshv/trace-events | 5 +
|
||||
include/system/mshv_int.h | 22 +-
|
||||
target/i386/mshv/mshv-cpu.c | 43 ++++
|
||||
5 files changed, 448 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/accel/mshv/mem.c b/accel/mshv/mem.c
|
||||
index e55c38d4db..0e2164af3e 100644
|
||||
--- a/accel/mshv/mem.c
|
||||
+++ b/accel/mshv/mem.c
|
||||
@@ -11,7 +11,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
+#include "qemu/lockable.h"
|
||||
#include "qemu/error-report.h"
|
||||
+#include "qemu/rcu.h"
|
||||
#include "linux/mshv.h"
|
||||
#include "system/address-spaces.h"
|
||||
#include "system/mshv.h"
|
||||
@@ -20,6 +22,137 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include "trace.h"
|
||||
|
||||
+typedef struct SlotsRCUReclaim {
|
||||
+ struct rcu_head rcu;
|
||||
+ GList *old_head;
|
||||
+ MshvMemorySlot *removed_slot;
|
||||
+} SlotsRCUReclaim;
|
||||
+
|
||||
+static void rcu_reclaim_slotlist(struct rcu_head *rcu)
|
||||
+{
|
||||
+ SlotsRCUReclaim *r = container_of(rcu, SlotsRCUReclaim, rcu);
|
||||
+ g_list_free(r->old_head);
|
||||
+ g_free(r->removed_slot);
|
||||
+ g_free(r);
|
||||
+}
|
||||
+
|
||||
+static void publish_slots(GList *new_head, GList *old_head,
|
||||
+ MshvMemorySlot *removed_slot)
|
||||
+{
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+ qatomic_store_release(&manager->slots, new_head);
|
||||
+
|
||||
+ SlotsRCUReclaim *r = g_new(SlotsRCUReclaim, 1);
|
||||
+ r->old_head = old_head;
|
||||
+ r->removed_slot = removed_slot;
|
||||
+
|
||||
+ call_rcu1(&r->rcu, rcu_reclaim_slotlist);
|
||||
+}
|
||||
+
|
||||
+/* Needs to be called with mshv_state->msm.mutex held */
|
||||
+static int remove_slot(MshvMemorySlot *slot)
|
||||
+{
|
||||
+ GList *old_head, *new_head;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+ old_head = qatomic_load_acquire(&manager->slots);
|
||||
+
|
||||
+ if (!g_list_find(old_head, slot)) {
|
||||
+ error_report("slot requested for removal not found");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ new_head = g_list_copy(old_head);
|
||||
+ new_head = g_list_remove(new_head, slot);
|
||||
+ manager->n_slots--;
|
||||
+
|
||||
+ publish_slots(new_head, old_head, slot);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Needs to be called with mshv_state->msm.mutex held */
|
||||
+static MshvMemorySlot *append_slot(uint64_t gpa, uint64_t userspace_addr,
|
||||
+ uint64_t size, bool readonly)
|
||||
+{
|
||||
+ GList *old_head, *new_head;
|
||||
+ MshvMemorySlot *slot;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+
|
||||
+ old_head = qatomic_load_acquire(&manager->slots);
|
||||
+
|
||||
+ if (manager->n_slots >= MSHV_MAX_MEM_SLOTS) {
|
||||
+ error_report("no free memory slots available");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ slot = g_new0(MshvMemorySlot, 1);
|
||||
+ slot->guest_phys_addr = gpa;
|
||||
+ slot->userspace_addr = userspace_addr;
|
||||
+ slot->memory_size = size;
|
||||
+ slot->readonly = readonly;
|
||||
+
|
||||
+ new_head = g_list_copy(old_head);
|
||||
+ new_head = g_list_append(new_head, slot);
|
||||
+ manager->n_slots++;
|
||||
+
|
||||
+ publish_slots(new_head, old_head, NULL);
|
||||
+
|
||||
+ return slot;
|
||||
+}
|
||||
+
|
||||
+static int slot_overlaps(const MshvMemorySlot *slot1,
|
||||
+ const MshvMemorySlot *slot2)
|
||||
+{
|
||||
+ uint64_t start_1 = slot1->userspace_addr,
|
||||
+ start_2 = slot2->userspace_addr;
|
||||
+ size_t len_1 = slot1->memory_size,
|
||||
+ len_2 = slot2->memory_size;
|
||||
+
|
||||
+ if (slot1 == slot2) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return ranges_overlap(start_1, len_1, start_2, len_2) ? 0 : -1;
|
||||
+}
|
||||
+
|
||||
+static bool is_mapped(MshvMemorySlot *slot)
|
||||
+{
|
||||
+ /* Subsequent reads of mapped field see a fully-initialized slot */
|
||||
+ return qatomic_load_acquire(&slot->mapped);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Find slot that is:
|
||||
+ * - overlapping in userspace
|
||||
+ * - currently mapped in the guest
|
||||
+ *
|
||||
+ * Needs to be called with mshv_state->msm.mutex or RCU read lock held.
|
||||
+ */
|
||||
+static MshvMemorySlot *find_overlap_mem_slot(GList *head, MshvMemorySlot *slot)
|
||||
+{
|
||||
+ GList *found;
|
||||
+ MshvMemorySlot *overlap_slot;
|
||||
+
|
||||
+ found = g_list_find_custom(head, slot, (GCompareFunc) slot_overlaps);
|
||||
+
|
||||
+ if (!found) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ overlap_slot = found->data;
|
||||
+ if (!overlap_slot || !is_mapped(overlap_slot)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return overlap_slot;
|
||||
+}
|
||||
+
|
||||
static int set_guest_memory(int vm_fd,
|
||||
const struct mshv_user_mem_region *region)
|
||||
{
|
||||
@@ -27,38 +160,169 @@ static int set_guest_memory(int vm_fd,
|
||||
|
||||
ret = ioctl(vm_fd, MSHV_SET_GUEST_MEMORY, region);
|
||||
if (ret < 0) {
|
||||
- error_report("failed to set guest memory");
|
||||
- return -errno;
|
||||
+ error_report("failed to set guest memory: %s", strerror(errno));
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int map_or_unmap(int vm_fd, const MshvMemoryRegion *mr, bool map)
|
||||
+static int map_or_unmap(int vm_fd, const MshvMemorySlot *slot, bool map)
|
||||
{
|
||||
struct mshv_user_mem_region region = {0};
|
||||
|
||||
- region.guest_pfn = mr->guest_phys_addr >> MSHV_PAGE_SHIFT;
|
||||
- region.size = mr->memory_size;
|
||||
- region.userspace_addr = mr->userspace_addr;
|
||||
+ region.guest_pfn = slot->guest_phys_addr >> MSHV_PAGE_SHIFT;
|
||||
+ region.size = slot->memory_size;
|
||||
+ region.userspace_addr = slot->userspace_addr;
|
||||
|
||||
if (!map) {
|
||||
region.flags |= (1 << MSHV_SET_MEM_BIT_UNMAP);
|
||||
- trace_mshv_unmap_memory(mr->userspace_addr, mr->guest_phys_addr,
|
||||
- mr->memory_size);
|
||||
+ trace_mshv_unmap_memory(slot->userspace_addr, slot->guest_phys_addr,
|
||||
+ slot->memory_size);
|
||||
return set_guest_memory(vm_fd, ®ion);
|
||||
}
|
||||
|
||||
region.flags = BIT(MSHV_SET_MEM_BIT_EXECUTABLE);
|
||||
- if (!mr->readonly) {
|
||||
+ if (!slot->readonly) {
|
||||
region.flags |= BIT(MSHV_SET_MEM_BIT_WRITABLE);
|
||||
}
|
||||
|
||||
- trace_mshv_map_memory(mr->userspace_addr, mr->guest_phys_addr,
|
||||
- mr->memory_size);
|
||||
+ trace_mshv_map_memory(slot->userspace_addr, slot->guest_phys_addr,
|
||||
+ slot->memory_size);
|
||||
return set_guest_memory(vm_fd, ®ion);
|
||||
}
|
||||
|
||||
+static int slot_matches_region(const MshvMemorySlot *slot1,
|
||||
+ const MshvMemorySlot *slot2)
|
||||
+{
|
||||
+ return (slot1->guest_phys_addr == slot2->guest_phys_addr &&
|
||||
+ slot1->userspace_addr == slot2->userspace_addr &&
|
||||
+ slot1->memory_size == slot2->memory_size) ? 0 : -1;
|
||||
+}
|
||||
+
|
||||
+/* Needs to be called with mshv_state->msm.mutex held */
|
||||
+static MshvMemorySlot *find_mem_slot_by_region(uint64_t gpa, uint64_t size,
|
||||
+ uint64_t userspace_addr)
|
||||
+{
|
||||
+ MshvMemorySlot ref_slot = {
|
||||
+ .guest_phys_addr = gpa,
|
||||
+ .userspace_addr = userspace_addr,
|
||||
+ .memory_size = size,
|
||||
+ };
|
||||
+ GList *found;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+ found = g_list_find_custom(manager->slots, &ref_slot,
|
||||
+ (GCompareFunc) slot_matches_region);
|
||||
+
|
||||
+ return found ? found->data : NULL;
|
||||
+}
|
||||
+
|
||||
+static int slot_covers_gpa(const MshvMemorySlot *slot, uint64_t *gpa_p)
|
||||
+{
|
||||
+ uint64_t gpa_offset, gpa = *gpa_p;
|
||||
+
|
||||
+ gpa_offset = gpa - slot->guest_phys_addr;
|
||||
+ return (slot->guest_phys_addr <= gpa && gpa_offset < slot->memory_size)
|
||||
+ ? 0 : -1;
|
||||
+}
|
||||
+
|
||||
+/* Needs to be called with mshv_state->msm.mutex or RCU read lock held */
|
||||
+static MshvMemorySlot *find_mem_slot_by_gpa(GList *head, uint64_t gpa)
|
||||
+{
|
||||
+ GList *found;
|
||||
+ MshvMemorySlot *slot;
|
||||
+
|
||||
+ trace_mshv_find_slot_by_gpa(gpa);
|
||||
+
|
||||
+ found = g_list_find_custom(head, &gpa, (GCompareFunc) slot_covers_gpa);
|
||||
+ if (found) {
|
||||
+ slot = found->data;
|
||||
+ trace_mshv_found_slot(slot->userspace_addr, slot->guest_phys_addr,
|
||||
+ slot->memory_size);
|
||||
+ return slot;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Needs to be called with mshv_state->msm.mutex held */
|
||||
+static void set_mapped(MshvMemorySlot *slot, bool mapped)
|
||||
+{
|
||||
+ /* prior writes to mapped field becomes visible before readers see slot */
|
||||
+ qatomic_store_release(&slot->mapped, mapped);
|
||||
+}
|
||||
+
|
||||
+MshvRemapResult mshv_remap_overlap_region(int vm_fd, uint64_t gpa)
|
||||
+{
|
||||
+ MshvMemorySlot *gpa_slot, *overlap_slot;
|
||||
+ GList *head;
|
||||
+ int ret;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ /* fast path, called often by unmapped_gpa vm exit */
|
||||
+ WITH_RCU_READ_LOCK_GUARD() {
|
||||
+ assert(manager);
|
||||
+ head = qatomic_load_acquire(&manager->slots);
|
||||
+ /* return early if no slot is found */
|
||||
+ gpa_slot = find_mem_slot_by_gpa(head, gpa);
|
||||
+ if (gpa_slot == NULL) {
|
||||
+ return MshvRemapNoMapping;
|
||||
+ }
|
||||
+
|
||||
+ /* return early if no overlapping slot is found */
|
||||
+ overlap_slot = find_overlap_mem_slot(head, gpa_slot);
|
||||
+ if (overlap_slot == NULL) {
|
||||
+ return MshvRemapNoOverlap;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We'll modify the mapping list, so we need to upgrade to mutex and
|
||||
+ * recheck.
|
||||
+ */
|
||||
+ assert(manager);
|
||||
+ QEMU_LOCK_GUARD(&manager->mutex);
|
||||
+
|
||||
+ /* return early if no slot is found */
|
||||
+ gpa_slot = find_mem_slot_by_gpa(manager->slots, gpa);
|
||||
+ if (gpa_slot == NULL) {
|
||||
+ return MshvRemapNoMapping;
|
||||
+ }
|
||||
+
|
||||
+ /* return early if no overlapping slot is found */
|
||||
+ overlap_slot = find_overlap_mem_slot(manager->slots, gpa_slot);
|
||||
+ if (overlap_slot == NULL) {
|
||||
+ return MshvRemapNoOverlap;
|
||||
+ }
|
||||
+
|
||||
+ /* unmap overlapping slot */
|
||||
+ ret = map_or_unmap(vm_fd, overlap_slot, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to unmap overlap region");
|
||||
+ abort();
|
||||
+ }
|
||||
+ set_mapped(overlap_slot, false);
|
||||
+ warn_report("mapped out userspace_addr=0x%016lx gpa=0x%010lx size=0x%lx",
|
||||
+ overlap_slot->userspace_addr,
|
||||
+ overlap_slot->guest_phys_addr,
|
||||
+ overlap_slot->memory_size);
|
||||
+
|
||||
+ /* map region for gpa */
|
||||
+ ret = map_or_unmap(vm_fd, gpa_slot, true);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to map new region");
|
||||
+ abort();
|
||||
+ }
|
||||
+ set_mapped(gpa_slot, true);
|
||||
+ warn_report("mapped in userspace_addr=0x%016lx gpa=0x%010lx size=0x%lx",
|
||||
+ gpa_slot->userspace_addr, gpa_slot->guest_phys_addr,
|
||||
+ gpa_slot->memory_size);
|
||||
+
|
||||
+ return MshvRemapOk;
|
||||
+}
|
||||
+
|
||||
static int handle_unmapped_mmio_region_read(uint64_t gpa, uint64_t size,
|
||||
uint8_t *data)
|
||||
{
|
||||
@@ -124,20 +388,97 @@ int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size,
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static int set_memory(const MshvMemoryRegion *mshv_mr, bool add)
|
||||
+static int tracked_unmap(int vm_fd, uint64_t gpa, uint64_t size,
|
||||
+ uint64_t userspace_addr)
|
||||
{
|
||||
- int ret = 0;
|
||||
+ int ret;
|
||||
+ MshvMemorySlot *slot;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+
|
||||
+ QEMU_LOCK_GUARD(&manager->mutex);
|
||||
+
|
||||
+ slot = find_mem_slot_by_region(gpa, size, userspace_addr);
|
||||
+ if (!slot) {
|
||||
+ trace_mshv_skip_unset_mem(userspace_addr, gpa, size);
|
||||
+ /* no work to do */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_mapped(slot)) {
|
||||
+ /* remove slot, no need to unmap */
|
||||
+ return remove_slot(slot);
|
||||
+ }
|
||||
|
||||
- if (!mshv_mr) {
|
||||
- error_report("Invalid mshv_mr");
|
||||
+ ret = map_or_unmap(vm_fd, slot, false);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to unmap memory region");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return remove_slot(slot);
|
||||
+}
|
||||
+
|
||||
+static int tracked_map(int vm_fd, uint64_t gpa, uint64_t size, bool readonly,
|
||||
+ uint64_t userspace_addr)
|
||||
+{
|
||||
+ MshvMemorySlot *slot, *overlap_slot;
|
||||
+ int ret;
|
||||
+ MshvMemorySlotManager *manager = &mshv_state->msm;
|
||||
+
|
||||
+ assert(manager);
|
||||
+
|
||||
+ QEMU_LOCK_GUARD(&manager->mutex);
|
||||
+
|
||||
+ slot = find_mem_slot_by_region(gpa, size, userspace_addr);
|
||||
+ if (slot) {
|
||||
+ error_report("memory region already mapped at gpa=0x%lx, "
|
||||
+ "userspace_addr=0x%lx, size=0x%lx",
|
||||
+ slot->guest_phys_addr, slot->userspace_addr,
|
||||
+ slot->memory_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- trace_mshv_set_memory(add, mshv_mr->guest_phys_addr,
|
||||
- mshv_mr->memory_size,
|
||||
- mshv_mr->userspace_addr, mshv_mr->readonly,
|
||||
- ret);
|
||||
- return map_or_unmap(mshv_state->vm, mshv_mr, add);
|
||||
+ slot = append_slot(gpa, userspace_addr, size, readonly);
|
||||
+
|
||||
+ overlap_slot = find_overlap_mem_slot(manager->slots, slot);
|
||||
+ if (overlap_slot) {
|
||||
+ trace_mshv_remap_attempt(slot->userspace_addr,
|
||||
+ slot->guest_phys_addr,
|
||||
+ slot->memory_size);
|
||||
+ warn_report("attempt to map region [0x%lx-0x%lx], while "
|
||||
+ "[0x%lx-0x%lx] is already mapped in the guest",
|
||||
+ userspace_addr, userspace_addr + size - 1,
|
||||
+ overlap_slot->userspace_addr,
|
||||
+ overlap_slot->userspace_addr +
|
||||
+ overlap_slot->memory_size - 1);
|
||||
+
|
||||
+ /* do not register mem slot in hv, but record for later swap-in */
|
||||
+ set_mapped(slot, false);
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ ret = map_or_unmap(vm_fd, slot, true);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to map memory region");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ set_mapped(slot, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_memory(uint64_t gpa, uint64_t size, bool readonly,
|
||||
+ uint64_t userspace_addr, bool add)
|
||||
+{
|
||||
+ int vm_fd = mshv_state->vm;
|
||||
+
|
||||
+ if (add) {
|
||||
+ return tracked_map(vm_fd, gpa, size, readonly, userspace_addr);
|
||||
+ }
|
||||
+
|
||||
+ return tracked_unmap(vm_fd, gpa, size, userspace_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -173,7 +514,9 @@ void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
bool writable = !area->readonly && !area->rom_device;
|
||||
hwaddr start_addr, mr_offset, size;
|
||||
void *ram;
|
||||
- MshvMemoryRegion mshv_mr = {0};
|
||||
+
|
||||
+ size = align_section(section, &start_addr);
|
||||
+ trace_mshv_set_phys_mem(add, section->mr->name, start_addr);
|
||||
|
||||
size = align_section(section, &start_addr);
|
||||
trace_mshv_set_phys_mem(add, section->mr->name, start_addr);
|
||||
@@ -200,14 +543,21 @@ void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
|
||||
ram = memory_region_get_ram_ptr(area) + mr_offset;
|
||||
|
||||
- mshv_mr.guest_phys_addr = start_addr;
|
||||
- mshv_mr.memory_size = size;
|
||||
- mshv_mr.readonly = !writable;
|
||||
- mshv_mr.userspace_addr = (uint64_t)ram;
|
||||
-
|
||||
- ret = set_memory(&mshv_mr, add);
|
||||
+ ret = set_memory(start_addr, size, !writable, (uint64_t)ram, add);
|
||||
if (ret < 0) {
|
||||
- error_report("Failed to set memory region");
|
||||
+ error_report("failed to set memory region");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
+
|
||||
+void mshv_init_memory_slot_manager(MshvState *mshv_state)
|
||||
+{
|
||||
+ MshvMemorySlotManager *manager;
|
||||
+
|
||||
+ assert(mshv_state);
|
||||
+ manager = &mshv_state->msm;
|
||||
+
|
||||
+ manager->n_slots = 0;
|
||||
+ manager->slots = NULL;
|
||||
+ qemu_mutex_init(&manager->mutex);
|
||||
+}
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index fa1f8f35bd..5edfcbad9d 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -437,6 +437,8 @@ static int mshv_init(AccelState *as, MachineState *ms)
|
||||
|
||||
mshv_init_msicontrol();
|
||||
|
||||
+ mshv_init_memory_slot_manager(s);
|
||||
+
|
||||
ret = create_vm(mshv_fd, &vm_fd);
|
||||
if (ret < 0) {
|
||||
close(mshv_fd);
|
||||
diff --git a/accel/mshv/trace-events b/accel/mshv/trace-events
|
||||
index a4dffeb24a..36f0d59b38 100644
|
||||
--- a/accel/mshv/trace-events
|
||||
+++ b/accel/mshv/trace-events
|
||||
@@ -26,3 +26,8 @@ mshv_map_memory(uint64_t userspace_addr, uint64_t gpa, uint64_t size) "\tu_a=0x%
|
||||
mshv_unmap_memory(uint64_t userspace_addr, uint64_t gpa, uint64_t size) "\tu_a=0x%" PRIx64 " gpa=0x%010" PRIx64 " size=0x%08" PRIx64
|
||||
mshv_set_phys_mem(bool add, const char *name, uint64_t gpa) "\tadd=%d name=%s gpa=0x%010" PRIx64
|
||||
mshv_handle_mmio(uint64_t gva, uint64_t gpa, uint64_t size, uint8_t access_type) "\tgva=0x%" PRIx64 " gpa=0x%010" PRIx64 " size=0x%" PRIx64 " access_type=%d"
|
||||
+
|
||||
+mshv_found_slot(uint64_t userspace_addr, uint64_t gpa, uint64_t size) "\tu_a=0x%" PRIx64 " gpa=0x%010" PRIx64 " size=0x%08" PRIx64
|
||||
+mshv_skip_unset_mem(uint64_t userspace_addr, uint64_t gpa, uint64_t size) "\tu_a=0x%" PRIx64 " gpa=0x%010" PRIx64 " size=0x%08" PRIx64
|
||||
+mshv_remap_attempt(uint64_t userspace_addr, uint64_t gpa, uint64_t size) "\tu_a=0x%" PRIx64 " gpa=0x%010" PRIx64 " size=0x%08" PRIx64
|
||||
+mshv_find_slot_by_gpa(uint64_t gpa) "\tgpa=0x%010" PRIx64
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index b29d39911d..6350c69e9d 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#define MSHV_MSR_ENTRIES_COUNT 64
|
||||
|
||||
+#define MSHV_MAX_MEM_SLOTS 32
|
||||
+
|
||||
typedef struct hyperv_message hv_message;
|
||||
|
||||
struct AccelCPUState {
|
||||
@@ -33,6 +35,12 @@ typedef struct MshvAddressSpace {
|
||||
AddressSpace *as;
|
||||
} MshvAddressSpace;
|
||||
|
||||
+typedef struct MshvMemorySlotManager {
|
||||
+ size_t n_slots;
|
||||
+ GList *slots;
|
||||
+ QemuMutex mutex;
|
||||
+} MshvMemorySlotManager;
|
||||
+
|
||||
struct MshvState {
|
||||
AccelState parent_obj;
|
||||
int vm;
|
||||
@@ -41,6 +49,7 @@ struct MshvState {
|
||||
int nr_as;
|
||||
MshvAddressSpace *as;
|
||||
int fd;
|
||||
+ MshvMemorySlotManager msm;
|
||||
};
|
||||
|
||||
typedef struct MshvMsiControl {
|
||||
@@ -71,6 +80,12 @@ typedef enum MshvVmExit {
|
||||
MshvVmExitSpecial = 2,
|
||||
} MshvVmExit;
|
||||
|
||||
+typedef enum MshvRemapResult {
|
||||
+ MshvRemapOk = 0,
|
||||
+ MshvRemapNoMapping = 1,
|
||||
+ MshvRemapNoOverlap = 2,
|
||||
+} MshvRemapResult;
|
||||
+
|
||||
void mshv_init_mmio_emu(void);
|
||||
int mshv_create_vcpu(int vm_fd, uint8_t vp_index, int *cpu_fd);
|
||||
void mshv_remove_vcpu(int vm_fd, int cpu_fd);
|
||||
@@ -94,19 +109,22 @@ int mshv_hvcall(int fd, const struct mshv_root_hvcall *args);
|
||||
#endif
|
||||
|
||||
/* memory */
|
||||
-typedef struct MshvMemoryRegion {
|
||||
+typedef struct MshvMemorySlot {
|
||||
uint64_t guest_phys_addr;
|
||||
uint64_t memory_size;
|
||||
uint64_t userspace_addr;
|
||||
bool readonly;
|
||||
-} MshvMemoryRegion;
|
||||
+ bool mapped;
|
||||
+} MshvMemorySlot;
|
||||
|
||||
+MshvRemapResult mshv_remap_overlap_region(int vm_fd, uint64_t gpa);
|
||||
int mshv_guest_mem_read(uint64_t gpa, uint8_t *data, uintptr_t size,
|
||||
bool is_secure_mode, bool instruction_fetch);
|
||||
int mshv_guest_mem_write(uint64_t gpa, const uint8_t *data, uintptr_t size,
|
||||
bool is_secure_mode);
|
||||
void mshv_set_phys_mem(MshvMemoryListener *mml, MemoryRegionSection *section,
|
||||
bool add);
|
||||
+void mshv_init_memory_slot_manager(MshvState *mshv_state);
|
||||
|
||||
/* msr */
|
||||
typedef struct MshvMsrEntry {
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 7edc032cea..de87142bff 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -1170,6 +1170,43 @@ static int handle_mmio(CPUState *cpu, const struct hyperv_message *msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int handle_unmapped_mem(int vm_fd, CPUState *cpu,
|
||||
+ const struct hyperv_message *msg,
|
||||
+ MshvVmExit *exit_reason)
|
||||
+{
|
||||
+ struct hv_x64_memory_intercept_message info = { 0 };
|
||||
+ uint64_t gpa;
|
||||
+ int ret;
|
||||
+ enum MshvRemapResult remap_result;
|
||||
+
|
||||
+ ret = set_memory_info(msg, &info);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to convert message to memory info");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ gpa = info.guest_physical_address;
|
||||
+
|
||||
+ /* attempt to remap the region, in case of overlapping userspace mappings */
|
||||
+ remap_result = mshv_remap_overlap_region(vm_fd, gpa);
|
||||
+ *exit_reason = MshvVmExitIgnore;
|
||||
+
|
||||
+ switch (remap_result) {
|
||||
+ case MshvRemapNoMapping:
|
||||
+ /* if we didn't find a mapping, it is probably mmio */
|
||||
+ return handle_mmio(cpu, msg, exit_reason);
|
||||
+ case MshvRemapOk:
|
||||
+ break;
|
||||
+ case MshvRemapNoOverlap:
|
||||
+ /* This should not happen, but we are forgiving it */
|
||||
+ warn_report("found no overlap for unmapped region");
|
||||
+ *exit_reason = MshvVmExitSpecial;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int set_ioport_info(const struct hyperv_message *msg,
|
||||
hv_x64_io_port_intercept_message *info)
|
||||
{
|
||||
@@ -1507,6 +1544,12 @@ int mshv_run_vcpu(int vm_fd, CPUState *cpu, hv_message *msg, MshvVmExit *exit)
|
||||
case HVMSG_UNRECOVERABLE_EXCEPTION:
|
||||
return MshvVmExitShutdown;
|
||||
case HVMSG_UNMAPPED_GPA:
|
||||
+ ret = handle_unmapped_mem(vm_fd, cpu, msg, &exit_reason);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("failed to handle unmapped memory");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return exit_reason;
|
||||
case HVMSG_GPA_INTERCEPT:
|
||||
ret = handle_mmio(cpu, msg, &exit_reason);
|
||||
if (ret < 0) {
|
||||
170
0082-qapi-accel-Allow-to-query-mshv-capabilities.patch
Normal file
170
0082-qapi-accel-Allow-to-query-mshv-capabilities.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 10f9371fe319b86ceb363b9516438c1ee9cf9656 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen K Paladugu <prapal@microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:44 +0200
|
||||
Subject: [PATCH] qapi/accel: Allow to query mshv capabilities
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [25/30] 50d73451b735ee139ca065c15a84e5f7e77e3904
|
||||
|
||||
Allow to query mshv capabilities via query-mshv QMP and info mshv HMP commands.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Acked-by: Dr. David Alan Gilbert <dave@treblig.org>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-25-magnuskulke@linux.microsoft.com
|
||||
[Fix "since" version. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit e7b08dfb902430b4f8226d23d7cf9b2762b6fc83)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-qapi-accel-Allow-to-query-mshv-capabilities.patch
|
||||
Patch-id: 85
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hmp-commands-info.hx | 13 +++++++++++++
|
||||
hw/core/machine-hmp-cmds.c | 15 +++++++++++++++
|
||||
hw/core/machine-qmp-cmds.c | 14 ++++++++++++++
|
||||
include/monitor/hmp.h | 1 +
|
||||
include/system/hw_accel.h | 1 +
|
||||
qapi/accelerator.json | 29 +++++++++++++++++++++++++++++
|
||||
6 files changed, 73 insertions(+)
|
||||
|
||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||
index 6142f60e7b..eaaa880c1b 100644
|
||||
--- a/hmp-commands-info.hx
|
||||
+++ b/hmp-commands-info.hx
|
||||
@@ -307,6 +307,19 @@ SRST
|
||||
Show KVM information.
|
||||
ERST
|
||||
|
||||
+ {
|
||||
+ .name = "mshv",
|
||||
+ .args_type = "",
|
||||
+ .params = "",
|
||||
+ .help = "show MSHV information",
|
||||
+ .cmd = hmp_info_mshv,
|
||||
+ },
|
||||
+
|
||||
+SRST
|
||||
+ ``info mshv``
|
||||
+ Show MSHV information.
|
||||
+ERST
|
||||
+
|
||||
{
|
||||
.name = "numa",
|
||||
.args_type = "",
|
||||
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
|
||||
index 3a612e2232..682ed9f49b 100644
|
||||
--- a/hw/core/machine-hmp-cmds.c
|
||||
+++ b/hw/core/machine-hmp-cmds.c
|
||||
@@ -163,6 +163,21 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
|
||||
qapi_free_KvmInfo(info);
|
||||
}
|
||||
|
||||
+void hmp_info_mshv(Monitor *mon, const QDict *qdict)
|
||||
+{
|
||||
+ MshvInfo *info;
|
||||
+
|
||||
+ info = qmp_query_mshv(NULL);
|
||||
+ monitor_printf(mon, "mshv support: ");
|
||||
+ if (info->present) {
|
||||
+ monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
|
||||
+ } else {
|
||||
+ monitor_printf(mon, "not compiled\n");
|
||||
+ }
|
||||
+
|
||||
+ qapi_free_MshvInfo(info);
|
||||
+}
|
||||
+
|
||||
void hmp_info_uuid(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
UuidInfo *info;
|
||||
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
|
||||
index 6aca1a626e..e24bf0d97b 100644
|
||||
--- a/hw/core/machine-qmp-cmds.c
|
||||
+++ b/hw/core/machine-qmp-cmds.c
|
||||
@@ -28,6 +28,20 @@
|
||||
#include "system/runstate.h"
|
||||
#include "system/system.h"
|
||||
#include "hw/s390x/storage-keys.h"
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+/*
|
||||
+ * QMP query for MSHV
|
||||
+ */
|
||||
+MshvInfo *qmp_query_mshv(Error **errp)
|
||||
+{
|
||||
+ MshvInfo *info = g_malloc0(sizeof(*info));
|
||||
+
|
||||
+ info->enabled = mshv_enabled();
|
||||
+ info->present = accel_find("mshv");
|
||||
+
|
||||
+ return info;
|
||||
+}
|
||||
|
||||
/*
|
||||
* fast means: we NEVER interrupt vCPU threads to retrieve
|
||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||
index ae116d9804..31bd812e5f 100644
|
||||
--- a/include/monitor/hmp.h
|
||||
+++ b/include/monitor/hmp.h
|
||||
@@ -24,6 +24,7 @@ strList *hmp_split_at_comma(const char *str);
|
||||
void hmp_info_name(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_version(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_kvm(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_info_mshv(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_status(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_uuid(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_chardev(Monitor *mon, const QDict *qdict);
|
||||
diff --git a/include/system/hw_accel.h b/include/system/hw_accel.h
|
||||
index fa9228d5d2..55497edc29 100644
|
||||
--- a/include/system/hw_accel.h
|
||||
+++ b/include/system/hw_accel.h
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "hw/core/cpu.h"
|
||||
#include "system/kvm.h"
|
||||
#include "system/hvf.h"
|
||||
+#include "system/mshv.h"
|
||||
#include "system/whpx.h"
|
||||
#include "system/nvmm.h"
|
||||
|
||||
diff --git a/qapi/accelerator.json b/qapi/accelerator.json
|
||||
index fb28c8d920..664e027246 100644
|
||||
--- a/qapi/accelerator.json
|
||||
+++ b/qapi/accelerator.json
|
||||
@@ -54,3 +54,32 @@
|
||||
{ 'command': 'x-accel-stats',
|
||||
'returns': 'HumanReadableText',
|
||||
'features': [ 'unstable' ] }
|
||||
+
|
||||
+##
|
||||
+# @MshvInfo:
|
||||
+#
|
||||
+# Information about support for MSHV acceleration
|
||||
+#
|
||||
+# @enabled: true if MSHV acceleration is active
|
||||
+#
|
||||
+# @present: true if MSHV acceleration is built into this executable
|
||||
+#
|
||||
+# Since: 10.2.0
|
||||
+##
|
||||
+{ 'struct': 'MshvInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
|
||||
+
|
||||
+##
|
||||
+# @query-mshv:
|
||||
+#
|
||||
+# Return information about MSHV acceleration
|
||||
+#
|
||||
+# Returns: @MshvInfo
|
||||
+#
|
||||
+# Since: 10.0.92
|
||||
+#
|
||||
+# .. qmp-example::
|
||||
+#
|
||||
+# -> { "execute": "query-mshv" }
|
||||
+# <- { "return": { "enabled": true, "present": true } }
|
||||
+##
|
||||
+{ 'command': 'query-mshv', 'returns': 'MshvInfo' }
|
||||
194
0083-target-i386-mshv-Use-preallocated-page-for-hvcall.patch
Normal file
194
0083-target-i386-mshv-Use-preallocated-page-for-hvcall.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 8cf57c4a254598ba434e1322af26e473e1382c73 Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Thu, 2 Oct 2025 09:50:12 +0200
|
||||
Subject: [PATCH] target/i386/mshv: Use preallocated page for hvcall
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [26/30] 338fa20beaaa44e30512d49026d2a9e9dd016b53
|
||||
|
||||
There are hvcalls that are invoked during MMIO exits, the payload is of
|
||||
dynamic size. To avoid heap allocations we can use preallocated pages as
|
||||
in/out buffer for those calls. A page is reserved per vCPU and used for
|
||||
set/get register hv calls.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-26-magnuskulke@linux.microsoft.com
|
||||
[Use standard MAX_CONST macro; mshv.h/mshv_int.h split. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit e4a20afce59937073298d716cc829bdc026542dc)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-target-i386-mshv-Use-preallocated-page-for-hvcall.patch
|
||||
Patch-id: 86
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mshv-all.c | 2 +-
|
||||
include/system/mshv_int.h | 7 +++++++
|
||||
target/i386/mshv/mshv-cpu.c | 38 +++++++++++++++++++++++++------------
|
||||
3 files changed, 34 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index 5edfcbad9d..45174f7c4e 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -399,8 +399,8 @@ static int mshv_init_vcpu(CPUState *cpu)
|
||||
uint8_t vp_index = cpu->cpu_index;
|
||||
int ret;
|
||||
|
||||
- mshv_arch_init_vcpu(cpu);
|
||||
cpu->accel = g_new0(AccelCPUState, 1);
|
||||
+ mshv_arch_init_vcpu(cpu);
|
||||
|
||||
ret = mshv_create_vcpu(vm_fd, vp_index, &cpu->accel->cpufd);
|
||||
if (ret < 0) {
|
||||
diff --git a/include/system/mshv_int.h b/include/system/mshv_int.h
|
||||
index 6350c69e9d..490563c1ab 100644
|
||||
--- a/include/system/mshv_int.h
|
||||
+++ b/include/system/mshv_int.h
|
||||
@@ -20,9 +20,16 @@
|
||||
|
||||
typedef struct hyperv_message hv_message;
|
||||
|
||||
+typedef struct MshvHvCallArgs {
|
||||
+ void *base;
|
||||
+ void *input_page;
|
||||
+ void *output_page;
|
||||
+} MshvHvCallArgs;
|
||||
+
|
||||
struct AccelCPUState {
|
||||
int cpufd;
|
||||
bool dirty;
|
||||
+ MshvHvCallArgs hvcall_args;
|
||||
};
|
||||
|
||||
typedef struct MshvMemoryListener {
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index de87142bff..1f7b9cb37e 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -34,6 +34,10 @@
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
+#define MAX_REGISTER_COUNT (MAX_CONST(ARRAY_SIZE(STANDARD_REGISTER_NAMES), \
|
||||
+ MAX_CONST(ARRAY_SIZE(SPECIAL_REGISTER_NAMES), \
|
||||
+ ARRAY_SIZE(FPU_REGISTER_NAMES))))
|
||||
+
|
||||
static enum hv_register_name STANDARD_REGISTER_NAMES[18] = {
|
||||
HV_X64_REGISTER_RAX,
|
||||
HV_X64_REGISTER_RBX,
|
||||
@@ -151,7 +155,7 @@ int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
int cpu_fd = mshv_vcpufd(cpu);
|
||||
int vp_index = cpu->cpu_index;
|
||||
size_t in_sz, assocs_sz;
|
||||
- hv_input_set_vp_registers *in;
|
||||
+ hv_input_set_vp_registers *in = cpu->accel->hvcall_args.input_page;
|
||||
struct mshv_root_hvcall args = {0};
|
||||
int ret;
|
||||
|
||||
@@ -160,7 +164,7 @@ int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;
|
||||
|
||||
/* fill the input struct */
|
||||
- in = g_malloc0(in_sz);
|
||||
+ memset(in, 0, sizeof(hv_input_set_vp_registers));
|
||||
in->vp_index = vp_index;
|
||||
memcpy(in->elements, assocs, assocs_sz);
|
||||
|
||||
@@ -172,7 +176,6 @@ int mshv_set_generic_regs(const CPUState *cpu, const hv_register_assoc *assocs,
|
||||
|
||||
/* perform the call */
|
||||
ret = mshv_hvcall(cpu_fd, &args);
|
||||
- g_free(in);
|
||||
if (ret < 0) {
|
||||
error_report("Failed to set registers");
|
||||
return -1;
|
||||
@@ -193,8 +196,8 @@ static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
|
||||
{
|
||||
int cpu_fd = mshv_vcpufd(cpu);
|
||||
int vp_index = cpu->cpu_index;
|
||||
- hv_input_get_vp_registers *in;
|
||||
- hv_register_value *values;
|
||||
+ hv_input_get_vp_registers *in = cpu->accel->hvcall_args.input_page;
|
||||
+ hv_register_value *values = cpu->accel->hvcall_args.output_page;
|
||||
size_t in_sz, names_sz, values_sz;
|
||||
int i, ret;
|
||||
struct mshv_root_hvcall args = {0};
|
||||
@@ -204,15 +207,14 @@ static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
|
||||
in_sz = sizeof(hv_input_get_vp_registers) + names_sz;
|
||||
|
||||
/* fill the input struct */
|
||||
- in = g_malloc0(in_sz);
|
||||
+ memset(in, 0, sizeof(hv_input_get_vp_registers));
|
||||
in->vp_index = vp_index;
|
||||
for (i = 0; i < n_regs; i++) {
|
||||
in->names[i] = assocs[i].name;
|
||||
}
|
||||
|
||||
- /* allocate value output buffer */
|
||||
+ /* determine size of value output buffer */
|
||||
values_sz = n_regs * sizeof(union hv_register_value);
|
||||
- values = g_malloc0(values_sz);
|
||||
|
||||
/* create the hvcall envelope */
|
||||
args.code = HVCALL_GET_VP_REGISTERS;
|
||||
@@ -224,16 +226,13 @@ static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
|
||||
|
||||
/* perform the call */
|
||||
ret = mshv_hvcall(cpu_fd, &args);
|
||||
- g_free(in);
|
||||
if (ret < 0) {
|
||||
- g_free(values);
|
||||
error_report("Failed to retrieve registers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* assert we got all registers */
|
||||
if (args.reps != n_regs) {
|
||||
- g_free(values);
|
||||
error_report("Failed to retrieve registers: expected %zu elements"
|
||||
", got %u", n_regs, args.reps);
|
||||
return -1;
|
||||
@@ -243,7 +242,6 @@ static int get_generic_regs(CPUState *cpu, hv_register_assoc *assocs,
|
||||
for (i = 0; i < n_regs; i++) {
|
||||
assocs[i].value = values[i];
|
||||
}
|
||||
- g_free(values);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1696,6 +1694,19 @@ void mshv_arch_init_vcpu(CPUState *cpu)
|
||||
{
|
||||
X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
CPUX86State *env = &x86_cpu->env;
|
||||
+ AccelCPUState *state = cpu->accel;
|
||||
+ size_t page = HV_HYP_PAGE_SIZE;
|
||||
+ void *mem = qemu_memalign(page, 2 * page);
|
||||
+
|
||||
+ /* sanity check, to make sure we don't overflow the page */
|
||||
+ QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT
|
||||
+ * sizeof(hv_register_assoc)
|
||||
+ + sizeof(hv_input_get_vp_registers)
|
||||
+ > HV_HYP_PAGE_SIZE));
|
||||
+
|
||||
+ state->hvcall_args.base = mem;
|
||||
+ state->hvcall_args.input_page = mem;
|
||||
+ state->hvcall_args.output_page = (uint8_t *)mem + page;
|
||||
|
||||
env->emu_mmio_buf = g_new(char, 4096);
|
||||
}
|
||||
@@ -1704,7 +1715,10 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
|
||||
{
|
||||
X86CPU *x86_cpu = X86_CPU(cpu);
|
||||
CPUX86State *env = &x86_cpu->env;
|
||||
+ AccelCPUState *state = cpu->accel;
|
||||
|
||||
+ g_free(state->hvcall_args.base);
|
||||
+ state->hvcall_args = (MshvHvCallArgs){0};
|
||||
g_clear_pointer(&env->emu_mmio_buf, g_free);
|
||||
}
|
||||
|
||||
144
0084-docs-Add-mshv-to-documentation.patch
Normal file
144
0084-docs-Add-mshv-to-documentation.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 394307bb31702b6dece1df0d4dc14e8bd19b0bec Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:46 +0200
|
||||
Subject: [PATCH] docs: Add mshv to documentation
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [27/30] 6450fc04dede6796c6a6383904792da34fb11de1
|
||||
|
||||
Added mshv to the list of accelerators in doc text.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-27-magnuskulke@linux.microsoft.com
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 3af71a1a6a7a497df7d3026239d6136b56e3d5ab)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-docs-Add-mshv-to-documentation.patch
|
||||
Patch-id: 87
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
docs/about/build-platforms.rst | 2 +-
|
||||
docs/devel/codebase.rst | 2 +-
|
||||
docs/glossary.rst | 7 +++----
|
||||
docs/system/introduction.rst | 3 +++
|
||||
qemu-options.hx | 16 ++++++++--------
|
||||
5 files changed, 16 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst
|
||||
index 8671c3be9c..06ba0ddc9a 100644
|
||||
--- a/docs/about/build-platforms.rst
|
||||
+++ b/docs/about/build-platforms.rst
|
||||
@@ -55,7 +55,7 @@ Those hosts are officially supported, with various accelerators:
|
||||
* - SPARC
|
||||
- tcg
|
||||
* - x86
|
||||
- - hvf (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
|
||||
+ - hvf (64 bit only), mshv (64 bit only), kvm, nvmm, tcg, whpx (64 bit only), xen
|
||||
|
||||
Other host architectures are not supported. It is possible to build QEMU system
|
||||
emulation on an unsupported host architecture using the configure
|
||||
diff --git a/docs/devel/codebase.rst b/docs/devel/codebase.rst
|
||||
index 2a3143787a..69d8827117 100644
|
||||
--- a/docs/devel/codebase.rst
|
||||
+++ b/docs/devel/codebase.rst
|
||||
@@ -48,7 +48,7 @@ yet, so sometimes the source code is all you have.
|
||||
* `accel <https://gitlab.com/qemu-project/qemu/-/tree/master/accel>`_:
|
||||
Infrastructure and architecture agnostic code related to the various
|
||||
`accelerators <Accelerators>` supported by QEMU
|
||||
- (TCG, KVM, hvf, whpx, xen, nvmm).
|
||||
+ (TCG, KVM, hvf, whpx, xen, nvmm, mshv).
|
||||
Contains interfaces for operations that will be implemented per
|
||||
`target <https://gitlab.com/qemu-project/qemu/-/tree/master/target>`_.
|
||||
* `audio <https://gitlab.com/qemu-project/qemu/-/tree/master/audio>`_:
|
||||
diff --git a/docs/glossary.rst b/docs/glossary.rst
|
||||
index 4fa044bfb6..2857731bc4 100644
|
||||
--- a/docs/glossary.rst
|
||||
+++ b/docs/glossary.rst
|
||||
@@ -12,7 +12,7 @@ Accelerator
|
||||
|
||||
A specific API used to accelerate execution of guest instructions. It can be
|
||||
hardware-based, through a virtualization API provided by the host OS (kvm, hvf,
|
||||
-whpx, ...), or software-based (tcg). See this description of `supported
|
||||
+whpx, mshv, ...), or software-based (tcg). See this description of `supported
|
||||
accelerators<Accelerators>`.
|
||||
|
||||
Board
|
||||
@@ -101,9 +101,8 @@ manage a virtual machine. QEMU is a virtualizer, that interacts with various
|
||||
hypervisors.
|
||||
|
||||
In the context of QEMU, an hypervisor is an API, provided by the Host OS,
|
||||
-allowing to execute virtual machines. Linux implementation is KVM (and supports
|
||||
-Xen as well). For MacOS, it's HVF. Windows defines WHPX. And NetBSD provides
|
||||
-NVMM.
|
||||
+allowing to execute virtual machines. Linux provides a choice of KVM, Xen
|
||||
+or MSHV; MacOS provides HVF; Windows provides WHPX; NetBSD provides NVMM.
|
||||
|
||||
.. _machine:
|
||||
|
||||
diff --git a/docs/system/introduction.rst b/docs/system/introduction.rst
|
||||
index 4cd46b5b8f..9c57523b6c 100644
|
||||
--- a/docs/system/introduction.rst
|
||||
+++ b/docs/system/introduction.rst
|
||||
@@ -23,6 +23,9 @@ Tiny Code Generator (TCG) capable of emulating many CPUs.
|
||||
* - Xen
|
||||
- Linux (as dom0)
|
||||
- Arm, x86
|
||||
+ * - MSHV
|
||||
+ - Linux (as dom0)
|
||||
+ - x86
|
||||
* - Hypervisor Framework (hvf)
|
||||
- MacOS
|
||||
- x86 (64 bit only), Arm (64 bit only)
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 5f146c1860..8eca7faa94 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -28,7 +28,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
||||
"-machine [type=]name[,prop[=value][,...]]\n"
|
||||
" selects emulated machine ('-machine help' for list)\n"
|
||||
" property accel=accel1[:accel2[:...]] selects accelerator\n"
|
||||
- " supported accelerators are kvm, xen, hvf, nvmm, whpx or tcg (default: tcg)\n"
|
||||
+ " supported accelerators are kvm, xen, hvf, nvmm, whpx, mshv or tcg (default: tcg)\n"
|
||||
" vmport=on|off|auto controls emulation of vmport (default: auto)\n"
|
||||
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
|
||||
" mem-merge=on|off controls memory merge support (default: on)\n"
|
||||
@@ -66,10 +66,10 @@ SRST
|
||||
|
||||
``accel=accels1[:accels2[:...]]``
|
||||
This is used to enable an accelerator. Depending on the target
|
||||
- architecture, kvm, xen, hvf, nvmm, whpx or tcg can be available.
|
||||
- By default, tcg is used. If there is more than one accelerator
|
||||
- specified, the next one is used if the previous one fails to
|
||||
- initialize.
|
||||
+ architecture, kvm, xen, hvf, nvmm, whpx, mshv or tcg can be
|
||||
+ available. By default, tcg is used. If there is more than one
|
||||
+ accelerator specified, the next one is used if the previous one
|
||||
+ fails to initialize.
|
||||
|
||||
``vmport=on|off|auto``
|
||||
Enables emulation of VMWare IO port, for vmmouse etc. auto says
|
||||
@@ -226,7 +226,7 @@ ERST
|
||||
|
||||
DEF("accel", HAS_ARG, QEMU_OPTION_accel,
|
||||
"-accel [accel=]accelerator[,prop[=value][,...]]\n"
|
||||
- " select accelerator (kvm, xen, hvf, nvmm, whpx or tcg; use 'help' for a list)\n"
|
||||
+ " select accelerator (kvm, xen, hvf, nvmm, whpx, mshv or tcg; use 'help' for a list)\n"
|
||||
" igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n"
|
||||
" kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n"
|
||||
" kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
|
||||
@@ -241,8 +241,8 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
|
||||
SRST
|
||||
``-accel name[,prop=value[,...]]``
|
||||
This is used to enable an accelerator. Depending on the target
|
||||
- architecture, kvm, xen, hvf, nvmm, whpx or tcg can be available. By
|
||||
- default, tcg is used. If there is more than one accelerator
|
||||
+ architecture, kvm, xen, hvf, nvmm, whpx, mshv or tcg can be available.
|
||||
+ By default, tcg is used. If there is more than one accelerator
|
||||
specified, the next one is used if the previous one fails to
|
||||
initialize.
|
||||
|
||||
55
0085-MAINTAINERS-Add-maintainers-for-mshv-accelerator.patch
Normal file
55
0085-MAINTAINERS-Add-maintainers-for-mshv-accelerator.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 678f73d1b85bab0d47f11d23df186a6797b2da8e Mon Sep 17 00:00:00 2001
|
||||
From: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Date: Tue, 16 Sep 2025 18:48:47 +0200
|
||||
Subject: [PATCH] MAINTAINERS: Add maintainers for mshv accelerator
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [28/30] 0178a9a61285bd708b5f589888c36b74efd4a4bf
|
||||
|
||||
Adding Magnus Kulke and Wei Liu to the maintainers file for the
|
||||
respective folders/files.
|
||||
|
||||
Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Link: https://lore.kernel.org/r/20250916164847.77883-28-magnuskulke@linux.microsoft.com
|
||||
[Rename "MAHV CPUs" to mention x86. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 1872bd9f2dad5113b0c27d352ec49683e0953c7f)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-MAINTAINERS-Add-maintainers-for-mshv-accelerator.patch
|
||||
Patch-id: 88
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
MAINTAINERS | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index a07086ed76..d4696f00d7 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -546,6 +546,21 @@ F: target/i386/whpx/
|
||||
F: accel/stubs/whpx-stub.c
|
||||
F: include/system/whpx.h
|
||||
|
||||
+MSHV
|
||||
+M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
|
||||
+R: Wei Liu <wei.liu@kernel.org>
|
||||
+S: Supported
|
||||
+F: accel/mshv/
|
||||
+F: include/system/mshv.h
|
||||
+F: include/hw/hyperv/hvgdk*.h
|
||||
+F: include/hw/hyperv/hvhdk*.h
|
||||
+
|
||||
+X86 MSHV CPUs
|
||||
+M: Magnus Kulke <magnus.kulke@linux.microsoft.com>
|
||||
+R: Wei Liu <wei.liu@kernel.org>
|
||||
+S: Supported
|
||||
+F: target/i386/mshv/
|
||||
+
|
||||
X86 Instruction Emulator
|
||||
M: Cameron Esfahani <dirty@apple.com>
|
||||
M: Roman Bolshakov <rbolshakov@ddn.com>
|
||||
40
0086-accel-mshv-initialize-thread-name.patch
Normal file
40
0086-accel-mshv-initialize-thread-name.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 8b6f5eb5eee8bac91997ab49a0f07d7d23db387c Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Wed, 22 Oct 2025 14:52:48 +0200
|
||||
Subject: [PATCH] accel/mshv: initialize thread name
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [29/30] 3e7286070c5ce162001fd407ebb1fa3920e300fa
|
||||
|
||||
The initialization was dropped when the code was copied from existing
|
||||
accelerators. Coverity knows (CID 1641400). Fix it.
|
||||
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 2cd3c1d35a06a62b25afa80c5baf381ce4b56805)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-initialize-thread-name.patch
|
||||
Patch-id: 89
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
accel/mshv/mshv-all.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c
|
||||
index 45174f7c4e..80428d130d 100644
|
||||
--- a/accel/mshv/mshv-all.c
|
||||
+++ b/accel/mshv/mshv-all.c
|
||||
@@ -596,6 +596,9 @@ static void mshv_start_vcpu_thread(CPUState *cpu)
|
||||
{
|
||||
char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||
|
||||
+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/MSHV",
|
||||
+ cpu->cpu_index);
|
||||
+
|
||||
cpu->thread = g_malloc0(sizeof(QemuThread));
|
||||
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From 94cb07058fe3c3cfac8af7f955cf7d40a231aada Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Wed, 22 Oct 2025 14:54:30 +0200
|
||||
Subject: [PATCH] accel/mshv: use return value of handle_pio_str_read
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 437: el10: x86: enablement for Azure L1VH OCP readiness
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [30/30] 60404a4d9211cf711fd4581d9f586510c3897bd4
|
||||
|
||||
Coverity complains because we assign to ret here but
|
||||
then never read it again before we overwrite it with
|
||||
the call to set_x64_registers().
|
||||
|
||||
Analyzed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 1557adc82698416bc68033765cfffb0a0b91c6bf)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-accel-mshv-use-return-value-of-handle_pio_str_read.patch
|
||||
Patch-id: 90
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/mshv/mshv-cpu.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
|
||||
index 1f7b9cb37e..1c3db02188 100644
|
||||
--- a/target/i386/mshv/mshv-cpu.c
|
||||
+++ b/target/i386/mshv/mshv-cpu.c
|
||||
@@ -1489,6 +1489,10 @@ static int handle_pio_str(CPUState *cpu, hv_x64_io_port_intercept_message *info)
|
||||
reg_values[0] = info->rsi;
|
||||
} else {
|
||||
ret = handle_pio_str_read(cpu, info, repeat, port, direction_flag);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Failed to handle pio str read");
|
||||
+ return -1;
|
||||
+ }
|
||||
reg_names[0] = HV_X64_REGISTER_RDI;
|
||||
reg_values[0] = info->rdi;
|
||||
}
|
||||
236
0088-monitor-generalize-query-mshv-info-mshv-to-query-acc.patch
Normal file
236
0088-monitor-generalize-query-mshv-info-mshv-to-query-acc.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 94b83e4df3495f451190a26d0ae481aebf38055f Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Mon, 13 Oct 2025 12:49:04 +0200
|
||||
Subject: [PATCH] monitor: generalize query-mshv/"info mshv" to
|
||||
query-accelerators/"info accelerators"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 443: [REHL10.2] L1HV: monitor: generalize query-mshv/"info mshv" to query-accelerators/"info accelerators"
|
||||
RH-Jira: RHEL-134212
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-Commit: [1/1] af946c572c3dab34cee6399bf4438e2722dd7e44 (imammedo/qemu-kvm-cs)
|
||||
|
||||
The recently-introduced query-mshv command is a duplicate of query-kvm,
|
||||
and neither provides a full view of which accelerators are supported
|
||||
by a particular binary of QEMU and which is in use.
|
||||
|
||||
KVM was the first accelerator added to QEMU, predating QOM and TYPE_ACCEL,
|
||||
so it got a pass. But now, instead of adding a badly designed copy, solve
|
||||
the problem completely for all accelerators with a command that provides
|
||||
the whole picture:
|
||||
|
||||
>> {"execute": "query-accelerators"}
|
||||
<< {"return": {"enabled": "tcg", "present": ["kvm", "mshv", "qtest", "tcg", "xen"]}}
|
||||
|
||||
Cc: Praveen K Paladugu <prapal@microsoft.com>
|
||||
Cc: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Suggested-by: Markus Armbruster <armbru@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
(cherry picked from commit 71d5babbd6fffc7def1ecbf29f9753e3a2807761)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Patch-name: kvm-monitor-generalize-query-mshv-info-mshv-to-query-acc.patch
|
||||
Patch-id: 91
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hmp-commands-info.hx | 15 ++++++++----
|
||||
hw/core/machine-hmp-cmds.c | 23 +++++++++++--------
|
||||
hw/core/machine-qmp-cmds.c | 24 +++++++++++++------
|
||||
include/monitor/hmp.h | 2 +-
|
||||
qapi/accelerator.json | 47 +++++++++++++++++++++++++++++---------
|
||||
5 files changed, 77 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||
index eaaa880c1b..3ed636e4e8 100644
|
||||
--- a/hmp-commands-info.hx
|
||||
+++ b/hmp-commands-info.hx
|
||||
@@ -308,16 +308,21 @@ SRST
|
||||
ERST
|
||||
|
||||
{
|
||||
- .name = "mshv",
|
||||
+ .name = "accelerators",
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
- .help = "show MSHV information",
|
||||
- .cmd = hmp_info_mshv,
|
||||
+ .help = "show present and enabled information",
|
||||
+ .cmd = hmp_info_accelerators,
|
||||
},
|
||||
|
||||
SRST
|
||||
- ``info mshv``
|
||||
- Show MSHV information.
|
||||
+ ``info accelerators``
|
||||
+ Show which accelerators are compiled into a QEMU binary, and what accelerator
|
||||
+ is in use. For example::
|
||||
+
|
||||
+ kvm qtest [tcg]
|
||||
+
|
||||
+ indicates that TCG in use, and that KVM and qtest are also available.
|
||||
ERST
|
||||
|
||||
{
|
||||
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
|
||||
index 682ed9f49b..74a56600be 100644
|
||||
--- a/hw/core/machine-hmp-cmds.c
|
||||
+++ b/hw/core/machine-hmp-cmds.c
|
||||
@@ -163,19 +163,22 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
|
||||
qapi_free_KvmInfo(info);
|
||||
}
|
||||
|
||||
-void hmp_info_mshv(Monitor *mon, const QDict *qdict)
|
||||
+void hmp_info_accelerators(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
- MshvInfo *info;
|
||||
-
|
||||
- info = qmp_query_mshv(NULL);
|
||||
- monitor_printf(mon, "mshv support: ");
|
||||
- if (info->present) {
|
||||
- monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
|
||||
- } else {
|
||||
- monitor_printf(mon, "not compiled\n");
|
||||
+ AcceleratorInfo *info;
|
||||
+ AcceleratorList *accel;
|
||||
+
|
||||
+ info = qmp_query_accelerators(NULL);
|
||||
+ for (accel = info->present; accel; accel = accel->next) {
|
||||
+ char trail = accel->next ? ' ' : '\n';
|
||||
+ if (info->enabled == accel->value) {
|
||||
+ monitor_printf(mon, "[%s]%c", Accelerator_str(accel->value), trail);
|
||||
+ } else {
|
||||
+ monitor_printf(mon, "%s%c", Accelerator_str(accel->value), trail);
|
||||
+ }
|
||||
}
|
||||
|
||||
- qapi_free_MshvInfo(info);
|
||||
+ qapi_free_AcceleratorInfo(info);
|
||||
}
|
||||
|
||||
void hmp_info_uuid(Monitor *mon, const QDict *qdict)
|
||||
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
|
||||
index e24bf0d97b..51d5c230f7 100644
|
||||
--- a/hw/core/machine-qmp-cmds.c
|
||||
+++ b/hw/core/machine-qmp-cmds.c
|
||||
@@ -31,15 +31,25 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
- * QMP query for MSHV
|
||||
+ * QMP query for enabled and present accelerators
|
||||
*/
|
||||
-MshvInfo *qmp_query_mshv(Error **errp)
|
||||
+AcceleratorInfo *qmp_query_accelerators(Error **errp)
|
||||
{
|
||||
- MshvInfo *info = g_malloc0(sizeof(*info));
|
||||
-
|
||||
- info->enabled = mshv_enabled();
|
||||
- info->present = accel_find("mshv");
|
||||
-
|
||||
+ AcceleratorInfo *info = g_malloc0(sizeof(*info));
|
||||
+ AccelClass *current_class = ACCEL_GET_CLASS(current_accel());
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = ACCELERATOR__MAX; i-- > 0; ) {
|
||||
+ const char *s = Accelerator_str(i);
|
||||
+ AccelClass *this_class = accel_find(s);
|
||||
+
|
||||
+ if (this_class) {
|
||||
+ QAPI_LIST_PREPEND(info->present, i);
|
||||
+ if (this_class == current_class) {
|
||||
+ info->enabled = i;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
return info;
|
||||
}
|
||||
|
||||
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
|
||||
index 31bd812e5f..897dfaa2b6 100644
|
||||
--- a/include/monitor/hmp.h
|
||||
+++ b/include/monitor/hmp.h
|
||||
@@ -24,7 +24,7 @@ strList *hmp_split_at_comma(const char *str);
|
||||
void hmp_info_name(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_version(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_kvm(Monitor *mon, const QDict *qdict);
|
||||
-void hmp_info_mshv(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_info_accelerators(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_status(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_uuid(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_chardev(Monitor *mon, const QDict *qdict);
|
||||
diff --git a/qapi/accelerator.json b/qapi/accelerator.json
|
||||
index 664e027246..2b92060884 100644
|
||||
--- a/qapi/accelerator.json
|
||||
+++ b/qapi/accelerator.json
|
||||
@@ -56,30 +56,55 @@
|
||||
'features': [ 'unstable' ] }
|
||||
|
||||
##
|
||||
-# @MshvInfo:
|
||||
+# @Accelerator:
|
||||
#
|
||||
# Information about support for MSHV acceleration
|
||||
#
|
||||
-# @enabled: true if MSHV acceleration is active
|
||||
+# @hvf: Apple Hypervisor.framework
|
||||
#
|
||||
-# @present: true if MSHV acceleration is built into this executable
|
||||
+# @kvm: KVM
|
||||
+#
|
||||
+# @mshv: Hyper-V
|
||||
+#
|
||||
+# @nvmm: NetBSD NVMM
|
||||
+#
|
||||
+# @qtest: QTest (dummy accelerator)
|
||||
+#
|
||||
+# @tcg: TCG (dynamic translation)
|
||||
+#
|
||||
+# @whpx: Windows Hypervisor Platform
|
||||
+#
|
||||
+# @xen: Xen
|
||||
+#
|
||||
+# Since: 10.2.0
|
||||
+##
|
||||
+{ 'enum': 'Accelerator', 'data': ['hvf', 'kvm', 'mshv', 'nvmm', 'qtest', 'tcg', 'whpx', 'xen'] }
|
||||
+
|
||||
+##
|
||||
+# @AcceleratorInfo:
|
||||
+#
|
||||
+# Information about support for various accelerators
|
||||
+#
|
||||
+# @enabled: the accelerator that is in use
|
||||
+#
|
||||
+# @present: the list of accelerators that are built into this executable
|
||||
#
|
||||
# Since: 10.2.0
|
||||
##
|
||||
-{ 'struct': 'MshvInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
|
||||
+{ 'struct': 'AcceleratorInfo', 'data': {'enabled': 'Accelerator', 'present': ['Accelerator']} }
|
||||
|
||||
##
|
||||
-# @query-mshv:
|
||||
+# @query-accelerators:
|
||||
#
|
||||
-# Return information about MSHV acceleration
|
||||
+# Return information about accelerators
|
||||
#
|
||||
-# Returns: @MshvInfo
|
||||
+# Returns: @AcceleratorInfo
|
||||
#
|
||||
-# Since: 10.0.92
|
||||
+# Since: 10.2.0
|
||||
#
|
||||
# .. qmp-example::
|
||||
#
|
||||
-# -> { "execute": "query-mshv" }
|
||||
-# <- { "return": { "enabled": true, "present": true } }
|
||||
+# -> { "execute": "query-accelerators" }
|
||||
+# <- { "return": { "enabled": "mshv", "present": ["kvm", "mshv", "qtest", "tcg"] } }
|
||||
##
|
||||
-{ 'command': 'query-mshv', 'returns': 'MshvInfo' }
|
||||
+{ 'command': 'query-accelerators', 'returns': 'AcceleratorInfo' }
|
||||
99
0089-block-Improve-comments-in-BlockLimits.patch
Normal file
99
0089-block-Improve-comments-in-BlockLimits.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From 95cb09a4a0a6b81a5a5e52384a345a3379c8c674 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 24 Oct 2025 14:30:37 +0200
|
||||
Subject: [PATCH] block: Improve comments in BlockLimits
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 439: block: Expose block limits in monitor and qemu-img info
|
||||
RH-Jira: RHEL-110003
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/4] 06c55e52ff339d2bc4559b109b0a6dd625caa7f0 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Patches to expose the limits in QAPI have made clear that the existing
|
||||
documentation of BlockLimits could be improved: The meaning of
|
||||
min_mem_alignment and opt_mem_alignment could be clearer, and talking
|
||||
about better alignment values isn't helpful when we only detect these
|
||||
values and never choose them.
|
||||
|
||||
Make the changes in the BlockLimits documentation now, so that the
|
||||
patches exposing the fields in QAPI can use descriptions consistent with
|
||||
it.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20251024123041.51254-2-kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 46dd683d56b1328cb2bc923914bfd7ac590064f7)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-block-Improve-comments-in-BlockLimits.patch
|
||||
Patch-id: 92
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
include/block/block_int-common.h | 30 +++++++++++++++++-------------
|
||||
1 file changed, 17 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
|
||||
index 034c0634c8..5206f32d53 100644
|
||||
--- a/include/block/block_int-common.h
|
||||
+++ b/include/block/block_int-common.h
|
||||
@@ -817,10 +817,10 @@ typedef struct BlockLimits {
|
||||
int64_t max_pdiscard;
|
||||
|
||||
/*
|
||||
- * Optimal alignment for discard requests in bytes. A power of 2
|
||||
- * is best but not mandatory. Must be a multiple of
|
||||
- * bl.request_alignment, and must be less than max_pdiscard if
|
||||
- * that is set. May be 0 if bl.request_alignment is good enough
|
||||
+ * Optimal alignment for discard requests in bytes. Note that this doesn't
|
||||
+ * have to be a power of two. Must be a multiple of bl.request_alignment,
|
||||
+ * and must be less than max_pdiscard if that is set. May be 0 if
|
||||
+ * bl.request_alignment is good enough.
|
||||
*/
|
||||
uint32_t pdiscard_alignment;
|
||||
|
||||
@@ -831,11 +831,10 @@ typedef struct BlockLimits {
|
||||
int64_t max_pwrite_zeroes;
|
||||
|
||||
/*
|
||||
- * Optimal alignment for write zeroes requests in bytes. A power
|
||||
- * of 2 is best but not mandatory. Must be a multiple of
|
||||
- * bl.request_alignment, and must be less than max_pwrite_zeroes
|
||||
- * if that is set. May be 0 if bl.request_alignment is good
|
||||
- * enough
|
||||
+ * Optimal alignment for write zeroes requests in bytes. Note that this
|
||||
+ * doesn't have to be a power of two. Must be a multiple of
|
||||
+ * bl.request_alignment, and must be less than max_pwrite_zeroes if that is
|
||||
+ * set. May be 0 if bl.request_alignment is good enough.
|
||||
*/
|
||||
uint32_t pwrite_zeroes_alignment;
|
||||
|
||||
@@ -863,18 +862,23 @@ typedef struct BlockLimits {
|
||||
uint64_t max_hw_transfer;
|
||||
|
||||
/*
|
||||
- * Maximal number of scatter/gather elements allowed by the hardware.
|
||||
+ * Maximum number of scatter/gather elements allowed by the hardware.
|
||||
* Applies whenever transfers to the device bypass the kernel I/O
|
||||
* scheduler, for example with SG_IO. If larger than max_iov
|
||||
* or if zero, blk_get_max_hw_iov will fall back to max_iov.
|
||||
*/
|
||||
int max_hw_iov;
|
||||
|
||||
-
|
||||
- /* memory alignment, in bytes so that no bounce buffer is needed */
|
||||
+ /*
|
||||
+ * Minimal required memory alignment in bytes for zero-copy I/O to succeed.
|
||||
+ * For unaligned requests, a bounce buffer will be used.
|
||||
+ */
|
||||
size_t min_mem_alignment;
|
||||
|
||||
- /* memory alignment, in bytes, for bounce buffer */
|
||||
+ /*
|
||||
+ * Optimal memory alignment in bytes. This is the alignment used for any
|
||||
+ * buffer allocations QEMU performs internally.
|
||||
+ */
|
||||
size_t opt_mem_alignment;
|
||||
|
||||
/* maximum number of iovec elements */
|
||||
256
0090-block-Expose-block-limits-for-images-in-QMP.patch
Normal file
256
0090-block-Expose-block-limits-for-images-in-QMP.patch
Normal file
@ -0,0 +1,256 @@
|
||||
From 2b27b1a46e5c0c2eb53bf7d9d2a9759d0ffc3f2c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 24 Oct 2025 14:30:38 +0200
|
||||
Subject: [PATCH] block: Expose block limits for images in QMP
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 439: block: Expose block limits in monitor and qemu-img info
|
||||
RH-Jira: RHEL-110003
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/4] a2d45f05abd5bedbad2f10ae4dc7a5cce909a2fe (kmwolf/centos-qemu-kvm)
|
||||
|
||||
This information can be useful both for debugging and for management
|
||||
tools trying to configure guest devices with the optimal limits
|
||||
(possibly across multiple hosts). There is no reason not to make it
|
||||
available, so just add it to BlockNodeInfo.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Message-ID: <20251024123041.51254-3-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit d2634e18286a5772f04cc724e64f8b16a2124587)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-block-Expose-block-limits-for-images-in-QMP.patch
|
||||
Patch-id: 93
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
block/qapi.c | 34 ++++++++++++++--
|
||||
qapi/block-core.json | 66 ++++++++++++++++++++++++++++++++
|
||||
tests/qemu-iotests/184 | 5 ++-
|
||||
tests/qemu-iotests/184.out | 8 ----
|
||||
tests/qemu-iotests/common.filter | 3 +-
|
||||
5 files changed, 102 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/block/qapi.c b/block/qapi.c
|
||||
index 12fbf8d1b7..54521d0a68 100644
|
||||
--- a/block/qapi.c
|
||||
+++ b/block/qapi.c
|
||||
@@ -235,7 +235,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
||||
* in @info, setting @errp on error.
|
||||
*/
|
||||
static void GRAPH_RDLOCK
|
||||
-bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
||||
+bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, bool limits,
|
||||
+ Error **errp)
|
||||
{
|
||||
int64_t size;
|
||||
const char *backing_filename;
|
||||
@@ -269,6 +270,33 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
||||
info->dirty_flag = bdi.is_dirty;
|
||||
info->has_dirty_flag = true;
|
||||
}
|
||||
+
|
||||
+ if (limits) {
|
||||
+ info->limits = g_new(BlockLimitsInfo, 1);
|
||||
+ *info->limits = (BlockLimitsInfo) {
|
||||
+ .request_alignment = bs->bl.request_alignment,
|
||||
+ .has_max_discard = bs->bl.max_pdiscard != 0,
|
||||
+ .max_discard = bs->bl.max_pdiscard,
|
||||
+ .has_discard_alignment = bs->bl.pdiscard_alignment != 0,
|
||||
+ .discard_alignment = bs->bl.pdiscard_alignment,
|
||||
+ .has_max_write_zeroes = bs->bl.max_pwrite_zeroes != 0,
|
||||
+ .max_write_zeroes = bs->bl.max_pwrite_zeroes,
|
||||
+ .has_write_zeroes_alignment = bs->bl.pwrite_zeroes_alignment != 0,
|
||||
+ .write_zeroes_alignment = bs->bl.pwrite_zeroes_alignment,
|
||||
+ .has_opt_transfer = bs->bl.opt_transfer != 0,
|
||||
+ .opt_transfer = bs->bl.opt_transfer,
|
||||
+ .has_max_transfer = bs->bl.max_transfer != 0,
|
||||
+ .max_transfer = bs->bl.max_transfer,
|
||||
+ .has_max_hw_transfer = bs->bl.max_hw_transfer != 0,
|
||||
+ .max_hw_transfer = bs->bl.max_hw_transfer,
|
||||
+ .max_iov = bs->bl.max_iov,
|
||||
+ .has_max_hw_iov = bs->bl.max_hw_iov != 0,
|
||||
+ .max_hw_iov = bs->bl.max_hw_iov,
|
||||
+ .min_mem_alignment = bs->bl.min_mem_alignment,
|
||||
+ .opt_mem_alignment = bs->bl.opt_mem_alignment,
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
info->format_specific = bdrv_get_specific_info(bs, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
@@ -343,7 +371,7 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||
ImageInfo *info;
|
||||
|
||||
info = g_new0(ImageInfo, 1);
|
||||
- bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
|
||||
+ bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), true, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -397,7 +425,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||
BdrvChild *c;
|
||||
|
||||
info = g_new0(BlockGraphInfo, 1);
|
||||
- bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
|
||||
+ bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), false, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index dc6eb4ae23..2c037183f0 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -275,6 +275,69 @@
|
||||
'file': 'ImageInfoSpecificFileWrapper'
|
||||
} }
|
||||
|
||||
+##
|
||||
+# @BlockLimitsInfo:
|
||||
+#
|
||||
+# @request-alignment: Alignment requirement, in bytes, for
|
||||
+# offset/length of I/O requests.
|
||||
+#
|
||||
+# @max-discard: Maximum number of bytes that can be discarded at once.
|
||||
+# If not present, there is no specific maximum.
|
||||
+#
|
||||
+# @discard-alignment: Optimal alignment for discard requests in bytes.
|
||||
+# Note that this doesn't have to be a power of two. If not
|
||||
+# present, discards don't have a alignment requirement different
|
||||
+# from @request-alignment.
|
||||
+#
|
||||
+# @max-write-zeroes: Maximum number of bytes that can be zeroed out at
|
||||
+# once. If not present, there is no specific maximum.
|
||||
+#
|
||||
+# @write-zeroes-alignment: Optimal alignment for write zeroes requests
|
||||
+# in bytes. Note that this doesn't have to be a power of two. If
|
||||
+# not present, write_zeroes doesn't have a alignment requirement
|
||||
+# different from @request-alignment.
|
||||
+#
|
||||
+# @opt-transfer: Optimal transfer length in bytes. If not present,
|
||||
+# there is no preferred size.
|
||||
+#
|
||||
+# @max-transfer: Maximal transfer length in bytes. If not present,
|
||||
+# there is no specific maximum.
|
||||
+#
|
||||
+# @max-hw-transfer: Maximal hardware transfer length in bytes.
|
||||
+# Applies whenever transfers to the device bypass the kernel I/O
|
||||
+# scheduler, for example with SG_IO. If not present, there is no
|
||||
+# specific maximum.
|
||||
+#
|
||||
+# @max-iov: Maximum number of scatter/gather elements
|
||||
+#
|
||||
+# @max-hw-iov: Maximum number of scatter/gather elements allowed by
|
||||
+# the hardware. Applies whenever transfers to the device bypass
|
||||
+# the kernel I/O scheduler, for example with SG_IO. If not
|
||||
+# present, the hardware limits is unknown and @max-iov is always
|
||||
+# used.
|
||||
+#
|
||||
+# @min-mem-alignment: Minimal required memory alignment in bytes for
|
||||
+# zero-copy I/O to succeed. For unaligned requests, a bounce
|
||||
+# buffer will be used.
|
||||
+#
|
||||
+# @opt-mem-alignment: Optimal memory alignment in bytes. This is the
|
||||
+# alignment used for any buffer allocations QEMU performs
|
||||
+# internally.
|
||||
+##
|
||||
+{ 'struct': 'BlockLimitsInfo',
|
||||
+ 'data': { 'request-alignment': 'uint32',
|
||||
+ '*max-discard': 'uint64',
|
||||
+ '*discard-alignment': 'uint32',
|
||||
+ '*max-write-zeroes': 'uint64',
|
||||
+ '*write-zeroes-alignment': 'uint32',
|
||||
+ '*opt-transfer': 'uint32',
|
||||
+ '*max-transfer': 'uint32',
|
||||
+ '*max-hw-transfer': 'uint32',
|
||||
+ 'max-iov': 'int',
|
||||
+ '*max-hw-iov': 'int',
|
||||
+ 'min-mem-alignment': 'size',
|
||||
+ 'opt-mem-alignment': 'size' } }
|
||||
+
|
||||
##
|
||||
# @BlockNodeInfo:
|
||||
#
|
||||
@@ -304,6 +367,8 @@
|
||||
#
|
||||
# @snapshots: list of VM snapshots
|
||||
#
|
||||
+# @limits: block limits that are used for I/O on the node (Since 10.2)
|
||||
+#
|
||||
# @format-specific: structure supplying additional format-specific
|
||||
# information (since 1.7)
|
||||
#
|
||||
@@ -315,6 +380,7 @@
|
||||
'*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
|
||||
'*backing-filename': 'str', '*full-backing-filename': 'str',
|
||||
'*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
|
||||
+ '*limits': 'BlockLimitsInfo',
|
||||
'*format-specific': 'ImageInfoSpecific' } }
|
||||
|
||||
##
|
||||
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
|
||||
index e4cbcd8634..6d0afe9d38 100755
|
||||
--- a/tests/qemu-iotests/184
|
||||
+++ b/tests/qemu-iotests/184
|
||||
@@ -45,8 +45,9 @@ do_run_qemu()
|
||||
|
||||
run_qemu()
|
||||
{
|
||||
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\
|
||||
- | _filter_qemu_io | _filter_generated_node_ids
|
||||
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \
|
||||
+ | _filter_qemu_io | _filter_generated_node_ids \
|
||||
+ | _filter_img_info
|
||||
}
|
||||
|
||||
test_throttle=$($QEMU_IMG --help|grep throttle)
|
||||
diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
|
||||
index ef99bb2e9a..52692b6b3b 100644
|
||||
--- a/tests/qemu-iotests/184.out
|
||||
+++ b/tests/qemu-iotests/184.out
|
||||
@@ -41,12 +41,6 @@ Testing:
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
- "children": [
|
||||
- {
|
||||
- "node-name": "disk0",
|
||||
- "child": "file"
|
||||
- }
|
||||
- ],
|
||||
"node-name": "throttle0",
|
||||
"backing_file_depth": 1,
|
||||
"drv": "throttle",
|
||||
@@ -75,8 +69,6 @@ Testing:
|
||||
},
|
||||
"iops_wr": 0,
|
||||
"ro": false,
|
||||
- "children": [
|
||||
- ],
|
||||
"node-name": "disk0",
|
||||
"backing_file_depth": 0,
|
||||
"drv": "null-co",
|
||||
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
|
||||
index 35c0fc0d20..cd8b506dba 100644
|
||||
--- a/tests/qemu-iotests/common.filter
|
||||
+++ b/tests/qemu-iotests/common.filter
|
||||
@@ -230,6 +230,7 @@ _filter_img_info()
|
||||
discard=0
|
||||
regex_json_spec_start='^ *"format-specific": \{'
|
||||
regex_json_child_start='^ *"children": \['
|
||||
+ regex_json_limit_start='^ *"limits": \{'
|
||||
gsed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
|
||||
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
|
||||
-e "s#$TEST_DIR#TEST_DIR#g" \
|
||||
@@ -262,7 +263,7 @@ _filter_img_info()
|
||||
discard=1
|
||||
elif [[ $line =~ "Child node '/" ]]; then
|
||||
discard=1
|
||||
- elif [[ $line =~ $regex_json_spec_start ]]; then
|
||||
+ elif [[ $line =~ $regex_json_spec_start || $line =~ $regex_json_limit_start ]]; then
|
||||
discard=2
|
||||
regex_json_end="^${line%%[^ ]*}\\},? *$"
|
||||
elif [[ $line =~ $regex_json_child_start ]]; then
|
||||
241
0091-qemu-img-info-Optionally-show-block-limits.patch
Normal file
241
0091-qemu-img-info-Optionally-show-block-limits.patch
Normal file
@ -0,0 +1,241 @@
|
||||
From 70f342dce4cfe8b2fe3998ad06c5072e4481067f Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 24 Oct 2025 14:30:39 +0200
|
||||
Subject: [PATCH] qemu-img info: Optionally show block limits
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 439: block: Expose block limits in monitor and qemu-img info
|
||||
RH-Jira: RHEL-110003
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [3/4] 688d6d1617c4d5916b299f08fad0e928341c73f7 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Add a new --limits option to 'qemu-img info' that displays the block
|
||||
limits for the image and all of its children, making the information
|
||||
more accessible for human users than in QMP. This option is not enabled
|
||||
by default because it can be a lot of output that isn't usually relevant
|
||||
if you're not specifically trying to diagnose some I/O problem.
|
||||
|
||||
This makes the same information automatically also available in HMP
|
||||
'info block -v'.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Message-ID: <20251024123041.51254-4-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 5b4b3bfdfc28d2398f34194d260d6eef9a9048b4)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-qemu-img-info-Optionally-show-block-limits.patch
|
||||
Patch-id: 94
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
block/qapi.c | 34 ++++++++++++++++++++++++++++++++--
|
||||
docs/tools/qemu-img.rst | 6 +++++-
|
||||
include/block/qapi.h | 2 +-
|
||||
qemu-img-cmds.hx | 4 ++--
|
||||
qemu-img.c | 15 ++++++++++++---
|
||||
5 files changed, 52 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/block/qapi.c b/block/qapi.c
|
||||
index 54521d0a68..9f5771e019 100644
|
||||
--- a/block/qapi.c
|
||||
+++ b/block/qapi.c
|
||||
@@ -417,6 +417,7 @@ fail:
|
||||
*/
|
||||
void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||
BlockGraphInfo **p_info,
|
||||
+ bool limits,
|
||||
Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
@@ -425,7 +426,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||
BdrvChild *c;
|
||||
|
||||
info = g_new0(BlockGraphInfo, 1);
|
||||
- bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), false, errp);
|
||||
+ bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), limits, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -439,7 +440,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||
QAPI_LIST_APPEND(children_list_tail, c_info);
|
||||
|
||||
c_info->name = g_strdup(c->name);
|
||||
- bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
|
||||
+ bdrv_query_block_graph_info(c->bs, &c_info->info, limits, errp);
|
||||
if (*errp) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -936,6 +937,29 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||
visit_free(v);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Dumps the given BlockLimitsInfo object in a human-readable form,
|
||||
+ * prepending an optional prefix if the dump is not empty.
|
||||
+ */
|
||||
+static void bdrv_image_info_limits_dump(BlockLimitsInfo *limits,
|
||||
+ const char *prefix,
|
||||
+ int indentation)
|
||||
+{
|
||||
+ QObject *obj;
|
||||
+ Visitor *v = qobject_output_visitor_new(&obj);
|
||||
+
|
||||
+ visit_type_BlockLimitsInfo(v, NULL, &limits, &error_abort);
|
||||
+ visit_complete(v, &obj);
|
||||
+ if (!qobject_is_empty_dump(obj)) {
|
||||
+ if (prefix) {
|
||||
+ qemu_printf("%*s%s", indentation * 4, "", prefix);
|
||||
+ }
|
||||
+ dump_qobject(indentation + 1, obj);
|
||||
+ }
|
||||
+ qobject_unref(obj);
|
||||
+ visit_free(v);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Print the given @info object in human-readable form. Every field is indented
|
||||
* using the given @indentation (four spaces per indentation level).
|
||||
@@ -1011,6 +1035,12 @@ void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (info->limits) {
|
||||
+ bdrv_image_info_limits_dump(info->limits,
|
||||
+ "Block limits:\n",
|
||||
+ indentation);
|
||||
+ }
|
||||
+
|
||||
if (info->has_snapshots) {
|
||||
SnapshotInfoList *elem;
|
||||
|
||||
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
||||
index 5e7b85079d..fdc9ea9cf2 100644
|
||||
--- a/docs/tools/qemu-img.rst
|
||||
+++ b/docs/tools/qemu-img.rst
|
||||
@@ -503,7 +503,7 @@ Command description:
|
||||
|
||||
The size syntax is similar to :manpage:`dd(1)`'s size syntax.
|
||||
|
||||
-.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [-U] FILENAME
|
||||
+.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-U] FILENAME
|
||||
|
||||
Give information about the disk image *FILENAME*. Use it in
|
||||
particular to know the size reserved on disk which can be different
|
||||
@@ -571,6 +571,10 @@ Command description:
|
||||
``ImageInfoSpecific*`` QAPI object (e.g. ``ImageInfoSpecificQCow2``
|
||||
for qcow2 images).
|
||||
|
||||
+ *Block limits*
|
||||
+ The block limits for I/O that QEMU detected for the image.
|
||||
+ This information is only shown if the ``--limits`` option was specified.
|
||||
+
|
||||
.. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--start-offset=OFFSET] [--max-length=LEN] [--output=OFMT] [-U] FILENAME
|
||||
|
||||
Dump the metadata of image *FILENAME* and its backing file chain.
|
||||
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||
index 54c48de26a..be554e53dc 100644
|
||||
--- a/include/block/qapi.h
|
||||
+++ b/include/block/qapi.h
|
||||
@@ -42,7 +42,7 @@ bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, bool flat,
|
||||
bool skip_implicit_filters, Error **errp);
|
||||
void GRAPH_RDLOCK
|
||||
bdrv_query_block_graph_info(BlockDriverState *bs, BlockGraphInfo **p_info,
|
||||
- Error **errp);
|
||||
+ bool limits, Error **errp);
|
||||
|
||||
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
|
||||
index 2c5a8a28f9..74b66f9d42 100644
|
||||
--- a/qemu-img-cmds.hx
|
||||
+++ b/qemu-img-cmds.hx
|
||||
@@ -66,9 +66,9 @@ SRST
|
||||
ERST
|
||||
|
||||
DEF("info", img_info,
|
||||
- "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [--backing-chain] [-U] filename")
|
||||
+ "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [--backing-chain] [--limits] [-U] filename")
|
||||
SRST
|
||||
-.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [-U] FILENAME
|
||||
+.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-U] FILENAME
|
||||
ERST
|
||||
|
||||
DEF("map", img_map,
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index 7a162fdc08..5cdbeda969 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -86,6 +86,7 @@ enum {
|
||||
OPTION_BITMAPS = 275,
|
||||
OPTION_FORCE = 276,
|
||||
OPTION_SKIP_BROKEN = 277,
|
||||
+ OPTION_LIMITS = 278,
|
||||
};
|
||||
|
||||
typedef enum OutputFormat {
|
||||
@@ -3002,7 +3003,8 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
|
||||
static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||
const char *filename,
|
||||
const char *fmt,
|
||||
- bool chain, bool force_share)
|
||||
+ bool chain, bool limits,
|
||||
+ bool force_share)
|
||||
{
|
||||
BlockGraphInfoList *head = NULL;
|
||||
BlockGraphInfoList **tail = &head;
|
||||
@@ -3039,7 +3041,7 @@ static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||
* the chain manually here.
|
||||
*/
|
||||
bdrv_graph_rdlock_main_loop();
|
||||
- bdrv_query_block_graph_info(bs, &info, &err);
|
||||
+ bdrv_query_block_graph_info(bs, &info, limits, &err);
|
||||
bdrv_graph_rdunlock_main_loop();
|
||||
|
||||
if (err) {
|
||||
@@ -3088,6 +3090,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
BlockGraphInfoList *list;
|
||||
bool image_opts = false;
|
||||
bool force_share = false;
|
||||
+ bool limits = false;
|
||||
|
||||
fmt = NULL;
|
||||
for(;;) {
|
||||
@@ -3097,6 +3100,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
|
||||
{"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
|
||||
{"force-share", no_argument, 0, 'U'},
|
||||
+ {"limits", no_argument, 0, OPTION_LIMITS},
|
||||
{"output", required_argument, 0, OPTION_OUTPUT},
|
||||
{"object", required_argument, 0, OPTION_OBJECT},
|
||||
{0, 0, 0, 0}
|
||||
@@ -3119,6 +3123,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
" display information about the backing chain for copy-on-write overlays\n"
|
||||
" -U, --force-share\n"
|
||||
" open image in shared mode for concurrent access\n"
|
||||
+" --limits\n"
|
||||
+" show detected block limits (may depend on options, e.g. cache mode)\n"
|
||||
" --output human|json\n"
|
||||
" specify output format (default: human)\n"
|
||||
" --object OBJDEF\n"
|
||||
@@ -3140,6 +3146,9 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
case 'U':
|
||||
force_share = true;
|
||||
break;
|
||||
+ case OPTION_LIMITS:
|
||||
+ limits = true;
|
||||
+ break;
|
||||
case OPTION_OUTPUT:
|
||||
output_format = parse_output_format(argv[0], optarg);
|
||||
break;
|
||||
@@ -3156,7 +3165,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
filename = argv[optind++];
|
||||
|
||||
list = collect_image_info_list(image_opts, filename, fmt, chain,
|
||||
- force_share);
|
||||
+ limits, force_share);
|
||||
if (!list) {
|
||||
return 1;
|
||||
}
|
||||
154
0092-qemu-img-info-Add-cache-mode-option.patch
Normal file
154
0092-qemu-img-info-Add-cache-mode-option.patch
Normal file
@ -0,0 +1,154 @@
|
||||
From cc4a0ad4fd6ab541216e49620cdb0e4132ea7c99 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 24 Oct 2025 14:30:40 +0200
|
||||
Subject: [PATCH] qemu-img info: Add cache mode option
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 439: block: Expose block limits in monitor and qemu-img info
|
||||
RH-Jira: RHEL-110003
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [4/4] 1d7c278d70f37528be71b31fe121cc531a13dde5 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
When querying block limits, different cache modes (in particular
|
||||
O_DIRECT or not) can result in different limits. Add an option to
|
||||
'qemu-img info' that allows the user to specify a cache mode, so that
|
||||
they can get the block limits for the cache mode they intend to use with
|
||||
their VM.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20251024123041.51254-5-kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 911992fd6ec7a84c7cc82831b4bcd8a2ca5ccc76)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
Patch-name: kvm-qemu-img-info-Add-cache-mode-option.patch
|
||||
Patch-id: 95
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
docs/tools/qemu-img.rst | 2 +-
|
||||
qemu-img-cmds.hx | 4 ++--
|
||||
qemu-img.c | 25 +++++++++++++++++++++----
|
||||
3 files changed, 24 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
|
||||
index fdc9ea9cf2..558b0eb84d 100644
|
||||
--- a/docs/tools/qemu-img.rst
|
||||
+++ b/docs/tools/qemu-img.rst
|
||||
@@ -503,7 +503,7 @@ Command description:
|
||||
|
||||
The size syntax is similar to :manpage:`dd(1)`'s size syntax.
|
||||
|
||||
-.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-U] FILENAME
|
||||
+.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-t CACHE] [-U] FILENAME
|
||||
|
||||
Give information about the disk image *FILENAME*. Use it in
|
||||
particular to know the size reserved on disk which can be different
|
||||
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
|
||||
index 74b66f9d42..6bc8265cfb 100644
|
||||
--- a/qemu-img-cmds.hx
|
||||
+++ b/qemu-img-cmds.hx
|
||||
@@ -66,9 +66,9 @@ SRST
|
||||
ERST
|
||||
|
||||
DEF("info", img_info,
|
||||
- "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [--backing-chain] [--limits] [-U] filename")
|
||||
+ "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [--backing-chain] [--limits] [-t CACHE] [-U] filename")
|
||||
SRST
|
||||
-.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-U] FILENAME
|
||||
+.. option:: info [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [--backing-chain] [--limits] [-t CACHE] [-U] FILENAME
|
||||
ERST
|
||||
|
||||
DEF("map", img_map,
|
||||
diff --git a/qemu-img.c b/qemu-img.c
|
||||
index 5cdbeda969..a7791896c1 100644
|
||||
--- a/qemu-img.c
|
||||
+++ b/qemu-img.c
|
||||
@@ -3003,6 +3003,7 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
|
||||
static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||
const char *filename,
|
||||
const char *fmt,
|
||||
+ const char *cache,
|
||||
bool chain, bool limits,
|
||||
bool force_share)
|
||||
{
|
||||
@@ -3010,6 +3011,15 @@ static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||
BlockGraphInfoList **tail = &head;
|
||||
GHashTable *filenames;
|
||||
Error *err = NULL;
|
||||
+ int cache_flags = 0;
|
||||
+ bool writethrough = false;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = bdrv_parse_cache_mode(cache, &cache_flags, &writethrough);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("Invalid cache option: %s", cache);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
|
||||
|
||||
@@ -3026,8 +3036,8 @@ static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||
g_hash_table_insert(filenames, (gpointer)filename, NULL);
|
||||
|
||||
blk = img_open(image_opts, filename, fmt,
|
||||
- BDRV_O_NO_BACKING | BDRV_O_NO_IO, false, false,
|
||||
- force_share);
|
||||
+ BDRV_O_NO_BACKING | BDRV_O_NO_IO | cache_flags,
|
||||
+ writethrough, false, force_share);
|
||||
if (!blk) {
|
||||
goto err;
|
||||
}
|
||||
@@ -3087,6 +3097,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
OutputFormat output_format = OFORMAT_HUMAN;
|
||||
bool chain = false;
|
||||
const char *filename, *fmt;
|
||||
+ const char *cache = BDRV_DEFAULT_CACHE;
|
||||
BlockGraphInfoList *list;
|
||||
bool image_opts = false;
|
||||
bool force_share = false;
|
||||
@@ -3099,13 +3110,14 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
{"format", required_argument, 0, 'f'},
|
||||
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
|
||||
{"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
|
||||
+ {"cache", required_argument, 0, 't'},
|
||||
{"force-share", no_argument, 0, 'U'},
|
||||
{"limits", no_argument, 0, OPTION_LIMITS},
|
||||
{"output", required_argument, 0, OPTION_OUTPUT},
|
||||
{"object", required_argument, 0, OPTION_OBJECT},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
- c = getopt_long(argc, argv, "hf:U", long_options, NULL);
|
||||
+ c = getopt_long(argc, argv, "hf:t:U", long_options, NULL);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
@@ -3121,6 +3133,8 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
" (incompatible with -f|--format)\n"
|
||||
" --backing-chain\n"
|
||||
" display information about the backing chain for copy-on-write overlays\n"
|
||||
+" -t, --cache CACHE\n"
|
||||
+" cache mode for FILE (default: " BDRV_DEFAULT_CACHE ")\n"
|
||||
" -U, --force-share\n"
|
||||
" open image in shared mode for concurrent access\n"
|
||||
" --limits\n"
|
||||
@@ -3143,6 +3157,9 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
case OPTION_BACKING_CHAIN:
|
||||
chain = true;
|
||||
break;
|
||||
+ case 't':
|
||||
+ cache = optarg;
|
||||
+ break;
|
||||
case 'U':
|
||||
force_share = true;
|
||||
break;
|
||||
@@ -3164,7 +3181,7 @@ static int img_info(const img_cmd_t *ccmd, int argc, char **argv)
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
||||
- list = collect_image_info_list(image_opts, filename, fmt, chain,
|
||||
+ list = collect_image_info_list(image_opts, filename, fmt, cache, chain,
|
||||
limits, force_share);
|
||||
if (!list) {
|
||||
return 1;
|
||||
38
0093-rh-configs-enable-CONFIG_TDX-for-x86_64.patch
Normal file
38
0093-rh-configs-enable-CONFIG_TDX-for-x86_64.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 1e80aae75dd950911dfa06c0ea814c751342f931 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Fri, 12 Dec 2025 12:30:30 +0100
|
||||
Subject: [PATCH] rh: configs: enable CONFIG_TDX for x86_64
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 445: rh: configs: enable CONFIG_TDX for x86_64
|
||||
RH-Jira: RHEL-111853
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||
RH-Commit: [1/1] 282972aa9e4f94097c68b046f6bb09c4b03705fc (bonzini/qemu-kvm-centos)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-111853
|
||||
|
||||
TDX support is included in 10.1 but we still need to enable it,
|
||||
because RHEL is built --without-default-devices.
|
||||
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-rh-configs-enable-CONFIG_TDX-for-x86_64.patch
|
||||
Patch-id: 96
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
index 1f244f766d..9063ae1b53 100644
|
||||
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
@@ -74,6 +74,7 @@ CONFIG_SERIAL_PCI=y
|
||||
CONFIG_SEV=y
|
||||
CONFIG_SMBIOS=y
|
||||
CONFIG_SMBUS_EEPROM=y
|
||||
+CONFIG_TDX=y
|
||||
CONFIG_TEST_DEVICES=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI=y
|
||||
65
0094-block-Fix-BDS-use-after-free-during-shutdown.patch
Normal file
65
0094-block-Fix-BDS-use-after-free-during-shutdown.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From ce67b67635b76cdd7f43f21988ce2170f47425ef Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Mon, 15 Dec 2025 16:07:14 +0100
|
||||
Subject: [PATCH] block: Fix BDS use after free during shutdown
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 446: Fix crash that happens when powering-off a guest during migration
|
||||
RH-Jira: RHEL-108142
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] af2687210d89fef5c4229a84371236c2b9bbdf5b (thuth/qemu-kvm-cs)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-108142
|
||||
|
||||
During shutdown, blockdev_close_all_bdrv_states() drops any block node
|
||||
references that are still owned by the monitor (i.e. the user). However,
|
||||
in doing so, it forgot to also remove the node from monitor_bdrv_states
|
||||
(which qmp_blockdev_del() correctly does), which means that later calls
|
||||
of bdrv_first()/bdrv_next() will still return the (now stale) pointer to
|
||||
the node.
|
||||
|
||||
Usually there is no such call after this point, but in some cases it can
|
||||
happen. In the reported case, there was an ongoing migration, and the
|
||||
migration thread wasn't shut down yet: migration_shutdown() called by
|
||||
qemu_cleanup() doesn't actually wait for the migration to be shut down,
|
||||
but may just move it to MIGRATION_STATUS_CANCELLING. The next time
|
||||
migration_iteration_finish() runs, it sees the status and tries to
|
||||
re-activate all block devices that migration may have previously
|
||||
inactivated. This is where bdrv_first()/bdrv_next() get called and the
|
||||
access to the already freed node happens.
|
||||
|
||||
It is debatable if migration_shutdown() should really return before
|
||||
migration has settled, but leaving a dangling pointer in the list of
|
||||
monitor-owned block nodes is clearly a bug either way and fixing it
|
||||
solves the immediate problem, so fix it.
|
||||
|
||||
Reported-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20251215150714.130214-1-kwolf@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Tested-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 307bc43095b8ab1765fd66c26003d5da06681c05)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Patch-name: kvm-block-Fix-BDS-use-after-free-during-shutdown.patch
|
||||
Patch-id: 97
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
blockdev.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index b451fee6e1..76c8dd0573 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -685,6 +685,7 @@ void blockdev_close_all_bdrv_states(void)
|
||||
|
||||
GLOBAL_STATE_CODE();
|
||||
QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) {
|
||||
+ QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
}
|
||||
37
0095-fix-pc_rhel_10_2_compat_len.patch
Normal file
37
0095-fix-pc_rhel_10_2_compat_len.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From a04b03ae978dcec172e27cbaffaca5cfec50eb9c Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Mon, 12 Jan 2026 09:19:07 +0100
|
||||
Subject: [PATCH] fix pc_rhel_10_2_compat_len
|
||||
|
||||
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
||||
RH-MergeRequest: 447: q35: increase default tseg size
|
||||
RH-Jira: RHEL-126707
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/2] b9291186e031c0c018dfdc87960b04817421ecec (kraxel.rh/centos-src-qemu-kvm)
|
||||
|
||||
There is an (apparently) cut+paste error in the definition
|
||||
pc_rhel_10_2_compat_len variable, it calculates the length
|
||||
of the wrong array. Fix it.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
|
||||
Patch-name: kvm-fix-pc_rhel_10_2_compat_len.patch
|
||||
Patch-id: 98
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 446d4a7c93..394a84eb8a 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -304,7 +304,7 @@ GlobalProperty pc_rhel_10_2_compat[] = {
|
||||
{ TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
{ TYPE_X86_CPU, "x-pdcm-on-even-without-pmu", "true" },
|
||||
};
|
||||
-const size_t pc_rhel_10_2_compat_len = G_N_ELEMENTS(pc_compat_10_0);
|
||||
+const size_t pc_rhel_10_2_compat_len = G_N_ELEMENTS(pc_rhel_10_2_compat);
|
||||
|
||||
GlobalProperty pc_rhel_10_1_compat[] = {
|
||||
/* pc_rhel_10_1_compat from pc_compat_9_1 */
|
||||
64
0096-q35-increase-default-tseg-size.patch
Normal file
64
0096-q35-increase-default-tseg-size.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 552c6b5fb530feebcfab92b18e5ccc592ae2af2e Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Thu, 6 Nov 2025 11:56:40 +0100
|
||||
Subject: [PATCH] q35: increase default tseg size
|
||||
|
||||
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
||||
RH-MergeRequest: 447: q35: increase default tseg size
|
||||
RH-Jira: RHEL-126707
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [2/2] 8cbbb7b55e2e83bb6129b2da92179ff7b969c4ed (kraxel.rh/centos-src-qemu-kvm)
|
||||
|
||||
With virtual machines becoming larger (more CPUs, more memory) the
|
||||
memory needed by the SMM code in OVMF to manage page tables and vcpu
|
||||
state grows too.
|
||||
|
||||
Default SMM memory (aka TSEG) size is 16 MB, and this often is not
|
||||
enough. Bump it to 64 MB for new machine types.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Message-Id: <20251106105640.1642109-1-kraxel@redhat.com>
|
||||
(cherry picked from commit fa4136387928749d5a1b4fa3606ae0ce6dce75aa)
|
||||
|
||||
[ RHEL: drop compat property update for upstream machine types ]
|
||||
[ RHEL: add compat property for rhel 10.0 machine type ]
|
||||
[ NOTE: the 10.0 compat properties are used for
|
||||
rhel-9.6 + older machine types too ]
|
||||
|
||||
Resolves: RHEL-126707
|
||||
|
||||
Patch-name: kvm-q35-increase-default-tseg-size.patch
|
||||
Patch-id: 99
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/i386/pc.c | 1 +
|
||||
hw/pci-host/q35.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 394a84eb8a..27900e071b 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -299,6 +299,7 @@ const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat);
|
||||
|
||||
GlobalProperty pc_rhel_10_2_compat[] = {
|
||||
/* pc_rhel_10_2_compat from pc_compat_10_0 */
|
||||
+ { "mch", "extended-tseg-mbytes", "16" },
|
||||
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
|
||||
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
|
||||
{ TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
|
||||
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
|
||||
index 1951ae440c..a708758d36 100644
|
||||
--- a/hw/pci-host/q35.c
|
||||
+++ b/hw/pci-host/q35.c
|
||||
@@ -663,7 +663,7 @@ static void mch_realize(PCIDevice *d, Error **errp)
|
||||
|
||||
static const Property mch_props[] = {
|
||||
DEFINE_PROP_UINT16("extended-tseg-mbytes", MCHPCIState, ext_tseg_mbytes,
|
||||
- 16),
|
||||
+ 64),
|
||||
DEFINE_PROP_BOOL("smbase-smram", MCHPCIState, has_smram_at_smbase, true),
|
||||
};
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
From 1b13e3592cda0576d62195f63a9a692459218173 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Thu, 6 Nov 2025 11:51:48 +0100
|
||||
Subject: [PATCH] hw/intc/ioapic: Fix ACCEL_KERNEL_GSI_IRQFD_POSSIBLE typo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Cédric Le Goater <clg@redhat.com>
|
||||
RH-MergeRequest: 449: hw/intc/ioapic: Fix ACCEL_KERNEL_GSI_IRQFD_POSSIBLE typo
|
||||
RH-Jira: RHEL-139028
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Commit: [1/1] 61c1a3f68e0a5403a90f1d1f2cb793cc83e0cea9 (clegoate/qemu-kvm-centos)
|
||||
|
||||
Commit 638ac1c78457 introduced a regression in interrupt remapping
|
||||
when running a VM configured with an intel-iommu device and an
|
||||
assigned PCI VF. During boot, Linux reports repeated messages :
|
||||
|
||||
[ 15.416794] __common_interrupt: 2.37 No irq handler for vector
|
||||
[ 15.417266] __common_interrupt: 2.37 No irq handler for vector
|
||||
[ 15.417733] __common_interrupt: 2.37 No irq handler for vector
|
||||
[ 15.418202] __common_interrupt: 2.37 No irq handler for vector
|
||||
[ 15.418670] __common_interrupt: 2.37 No irq handler for vector
|
||||
|
||||
and may eventually hang.
|
||||
|
||||
The issue is caused by the incorrect use of the macro
|
||||
ACCEL_KERNEL_GSI_IRQFD_POSSIBLE, which should instead be
|
||||
ACCEL_GSI_IRQFD_POSSIBLE.
|
||||
|
||||
Fixes: 638ac1c78457 ("hw/intc: Generalize APIC helper names from kvm_* to accel_*")
|
||||
Cc: Magnus Kulke <magnuskulke@linux.microsoft.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-ID: <20251106105148.737093-1-clg@redhat.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
(cherry picked from commit 3abfbb571143ba865488b6c11f8ad75dda97d1a3)
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
|
||||
Patch-name: kvm-hw-intc-ioapic-Fix-ACCEL_KERNEL_GSI_IRQFD_POSSIBLE-t.patch
|
||||
Patch-id: 100
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
hw/intc/ioapic.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
|
||||
index e431d00311..38e4384648 100644
|
||||
--- a/hw/intc/ioapic.c
|
||||
+++ b/hw/intc/ioapic.c
|
||||
@@ -216,7 +216,7 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
|
||||
#endif
|
||||
}
|
||||
|
||||
-#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
|
||||
+#ifdef ACCEL_GSI_IRQFD_POSSIBLE
|
||||
static void ioapic_iec_notifier(void *private, bool global,
|
||||
uint32_t index, uint32_t mask)
|
||||
{
|
||||
@@ -434,7 +434,7 @@ static const MemoryRegionOps ioapic_io_ops = {
|
||||
|
||||
static void ioapic_machine_done_notify(Notifier *notifier, void *data)
|
||||
{
|
||||
-#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
|
||||
+#ifdef ACCEL_GSI_IRQFD_POSSIBLE
|
||||
IOAPICCommonState *s = container_of(notifier, IOAPICCommonState,
|
||||
machine_done);
|
||||
|
||||
44
0098-redhat-allow-5-level-paging-for-TDX-VMs.patch
Normal file
44
0098-redhat-allow-5-level-paging-for-TDX-VMs.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 273b5c9f7ae94d9fc31f1a72fc81062154d90f13 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Fri, 18 Jul 2025 18:03:50 +0200
|
||||
Subject: [PATCH] redhat: allow 5-level paging for TDX VMs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
RH-MergeRequest: 450: redhat: allow 5-level paging for TDX VMs
|
||||
RH-Jira: RHEL-111853
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-Commit: [1/1] d3ffac324cfbf79d99763b9d3d29797d883f4969 (bonzini/qemu-kvm-centos)
|
||||
|
||||
Without this patch, when booting a TDX guest, qemu outputs,
|
||||
|
||||
qemu-kvm: TDX requires guest CPU physical bits (48) to match host CPU physical bits (52)
|
||||
|
||||
This is due to different machine types in RHEL vs. upstream, and therefore
|
||||
must be kept forever as a delta from upstream.
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-111853
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Patch-name: kvm-redhat-allow-5-level-paging-for-TDX-VMs.patch
|
||||
Patch-id: 101
|
||||
Patch-present-in-specfile: True
|
||||
---
|
||||
target/i386/kvm/tdx.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
|
||||
index dbf0fa2c91..91fe19b7d4 100644
|
||||
--- a/target/i386/kvm/tdx.c
|
||||
+++ b/target/i386/kvm/tdx.c
|
||||
@@ -754,6 +754,7 @@ static void tdx_cpu_instance_init(X86ConfidentialGuest *cg, CPUState *cpu)
|
||||
}
|
||||
|
||||
object_property_set_bool(OBJECT(cpu), "pmu", false, &error_abort);
|
||||
+ object_property_set_int(OBJECT(cpu), "host-phys-bits-limit", 0, &error_abort);
|
||||
|
||||
/* invtsc is fixed1 for TD guest */
|
||||
object_property_set_bool(OBJECT(cpu), "invtsc", true, &error_abort);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user