* Wed Apr 24 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.0.0-1
- Rebase to QEMU 9.0.0 [RHEL-28073] - Resolves: RHEL-28073 (Rebase qemu-kvm to QEMU 9.0.0 for RHEL 9.5)
This commit is contained in:
parent
942f1fed56
commit
209f2f84bf
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,3 +28,4 @@
|
||||
/qemu-8.0.0.tar.xz
|
||||
/qemu-8.1.0.tar.xz
|
||||
/qemu-8.2.0.tar.xz
|
||||
/qemu-9.0.0.tar.xz
|
||||
|
@ -1,4 +1,4 @@
|
||||
From faae70a870156f86a5cf55ca967b15d7612941ff Mon Sep 17 00:00:00 2001
|
||||
From ea7dff3dbf979d7d8a85a16cf5187235143e1048 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 26 May 2021 10:56:02 +0200
|
||||
Subject: Initial redhat build
|
||||
@ -13,7 +13,7 @@ several issues are fixed in QEMU tree:
|
||||
|
||||
We disable make check due to issues with some of the tests.
|
||||
|
||||
This rebase is based on qemu-kvm-8.1.0-5.el9
|
||||
This rebase is based on qemu-kvm-8.2.0-11.el9
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
--
|
||||
@ -83,6 +83,12 @@ Rebase changes (8.2.0):
|
||||
- Added --disable-plugins configure option
|
||||
- Fixing frh.py strings
|
||||
|
||||
Rebase notes (9.0.0):
|
||||
- Fixed qemu-kvm binary location change
|
||||
- Remove hppa-firmware64.img
|
||||
- Package stp files for utilities
|
||||
- Download subprojects on local build
|
||||
|
||||
Merged patches (6.0.0):
|
||||
- 605758c902 Limit build on Power to qemu-img and qemu-ga only
|
||||
|
||||
@ -193,14 +199,17 @@ Merged patches (8.1.0):
|
||||
Merged patches (8.2.0):
|
||||
- cd9efa221d Enable qemu-kvm-device-usb-redirec for aarch64
|
||||
|
||||
Merged patches (9.0.0 rc0):
|
||||
- 25de053dbf spec: Enable zstd
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
.distro/Makefile | 100 +
|
||||
.distro/Makefile | 101 +
|
||||
.distro/Makefile.common | 42 +
|
||||
.distro/README.tests | 39 +
|
||||
.distro/modules-load.conf | 4 +
|
||||
.distro/qemu-guest-agent.service | 1 -
|
||||
.distro/qemu-kvm.spec.template | 4909 +++++++++++++++++++++++
|
||||
.distro/qemu-kvm.spec.template | 5170 +++++++++++++++++++++++
|
||||
.distro/rpminspect.yaml | 6 +-
|
||||
.distro/scripts/extract_build_cmd.py | 12 +
|
||||
.distro/scripts/frh.py | 4 +-
|
||||
@ -211,7 +220,7 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
scripts/systemtap/conf.d/qemu_kvm.conf | 4 +
|
||||
scripts/systemtap/script.d/qemu_kvm.stp | 1 +
|
||||
ui/vnc-auth-sasl.c | 2 +-
|
||||
16 files changed, 5168 insertions(+), 6 deletions(-)
|
||||
16 files changed, 5430 insertions(+), 6 deletions(-)
|
||||
create mode 100644 .distro/Makefile
|
||||
create mode 100644 .distro/Makefile.common
|
||||
create mode 100644 .distro/README.tests
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 048067b4618ba1fa7c8c517185d4cd3a675eba72 Mon Sep 17 00:00:00 2001
|
||||
From 780c39975b059deaee106775b6e3a240155acea3 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 7 Dec 2022 03:05:48 -0500
|
||||
Subject: Enable/disable devices for RHEL
|
||||
@ -47,6 +47,12 @@ Rebase notes (8.2.0):
|
||||
- Disable new neoverse-v2
|
||||
- Removed CONFIG_OPENGL from x86_64 config file
|
||||
|
||||
Rebase notes (9.0.0 rc0):
|
||||
- Split CONFIG_IDE_QDEV to CONFIG_IDE_DEV and CONFIG_IDE_BUS (upstream change)
|
||||
|
||||
Rebase notes (9.0.0 rc1):
|
||||
- Do not compile armv7 cpu types
|
||||
|
||||
Merged patches (6.1.0):
|
||||
- c51bf45304 Remove SPICE and QXL from x86_64-rh-devices.mak
|
||||
- 02fc745601 aarch64-rh-devices: add CONFIG_PVPANIC_PCI
|
||||
@ -74,36 +80,41 @@ Merged patches (8.1.0):
|
||||
|
||||
Merged patches (8.2.0):
|
||||
- b29f66431f Enable igb on x86_64
|
||||
|
||||
Merged patches (9.0.0 rc0):
|
||||
- 3889ede5d9 Compile IOMMUFD on x86_64
|
||||
- 0beb18451f Compile IOMMUFD on s390x
|
||||
- 2b4b13f70d Compile IOMMUFD object on aarch64
|
||||
---
|
||||
.distro/qemu-kvm.spec.template | 18 +--
|
||||
.../aarch64-softmmu/aarch64-rh-devices.mak | 41 +++++++
|
||||
.../aarch64-softmmu/aarch64-rh-devices.mak | 42 +++++++
|
||||
.../ppc64-softmmu/ppc64-rh-devices.mak | 37 ++++++
|
||||
configs/devices/rh-virtio.mak | 10 ++
|
||||
.../s390x-softmmu/s390x-rh-devices.mak | 18 +++
|
||||
.../x86_64-softmmu/x86_64-rh-devices.mak | 110 ++++++++++++++++++
|
||||
.../s390x-softmmu/s390x-rh-devices.mak | 19 +++
|
||||
.../x86_64-softmmu/x86_64-rh-devices.mak | 112 ++++++++++++++++++
|
||||
hw/arm/virt.c | 2 +
|
||||
hw/block/fdc.c | 10 ++
|
||||
hw/cpu/meson.build | 3 +-
|
||||
hw/cxl/meson.build | 3 +-
|
||||
hw/display/cirrus_vga.c | 4 +
|
||||
hw/ide/piix.c | 5 +-
|
||||
hw/ide/qdev.c | 9 ++
|
||||
hw/input/pckbd.c | 2 +
|
||||
hw/net/e1000.c | 2 +
|
||||
hw/ppc/spapr_cpu_core.c | 2 +
|
||||
hw/usb/meson.build | 2 +-
|
||||
hw/virtio/meson.build | 5 +-
|
||||
hw/virtio/meson.build | 6 +-
|
||||
target/arm/arm-qmp-cmds.c | 2 +
|
||||
target/arm/cpu.c | 4 +
|
||||
target/arm/cpu.h | 3 +
|
||||
target/arm/cpu64.c | 12 +-
|
||||
target/arm/tcg/cpu32.c | 2 +
|
||||
target/arm/tcg/cpu64.c | 8 ++
|
||||
target/arm/tcg/meson.build | 4 +-
|
||||
target/ppc/cpu-models.c | 9 ++
|
||||
target/s390x/cpu_models_sysemu.c | 3 +
|
||||
target/s390x/kvm/kvm.c | 8 ++
|
||||
tests/qtest/arm-cpu-features.c | 4 +
|
||||
28 files changed, 323 insertions(+), 15 deletions(-)
|
||||
28 files changed, 321 insertions(+), 17 deletions(-)
|
||||
create mode 100644 configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
create mode 100644 configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
|
||||
create mode 100644 configs/devices/rh-virtio.mak
|
||||
@ -112,10 +123,10 @@ Merged patches (8.2.0):
|
||||
|
||||
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..aec1831199
|
||||
index 0000000000..b0191d3c69
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
@@ -0,0 +1,41 @@
|
||||
@@ -0,0 +1,42 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_ARM_GIC_KVM=y
|
||||
@ -157,6 +168,7 @@ index 0000000000..aec1831199
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
diff --git a/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak b/configs/devices/ppc64-softmmu/ppc64-rh-devices.mak
|
||||
new file mode 100644
|
||||
index 0000000000..dbb7d30829
|
||||
@ -218,10 +230,10 @@ index 0000000000..94ede1b5f6
|
||||
+CONFIG_VIRTIO_SERIAL=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..69a799adbd
|
||||
index 0000000000..24cf6dbd03
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
@@ -0,0 +1,18 @@
|
||||
@@ -0,0 +1,19 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_PCI=y
|
||||
@ -240,12 +252,13 @@ index 0000000000..69a799adbd
|
||||
+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..ce5be73633
|
||||
index 0000000000..d60ff1bcfc
|
||||
--- /dev/null
|
||||
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
@@ -0,0 +1,110 @@
|
||||
@@ -0,0 +1,112 @@
|
||||
+include ../rh-virtio.mak
|
||||
+
|
||||
+CONFIG_ACPI=y
|
||||
@ -283,7 +296,8 @@ index 0000000000..ce5be73633
|
||||
+CONFIG_IDE_CORE=y
|
||||
+CONFIG_IDE_PCI=y
|
||||
+CONFIG_IDE_PIIX=y
|
||||
+CONFIG_IDE_QDEV=y
|
||||
+CONFIG_IDE_DEV=y
|
||||
+CONFIG_IDE_BUS=y
|
||||
+CONFIG_IGB_PCI_EXPRESS=y
|
||||
+CONFIG_IOAPIC=y
|
||||
+CONFIG_IOH3420=y
|
||||
@ -356,28 +370,29 @@ index 0000000000..ce5be73633
|
||||
+CONFIG_VHOST_VSOCK=y
|
||||
+CONFIG_VHOST_USER_VSOCK=y
|
||||
+CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index be2856c018..af9ea4dd1c 100644
|
||||
index a9a913aead..6c6d155002 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -205,6 +205,7 @@ static const int a15irqmap[] = {
|
||||
};
|
||||
|
||||
static const char *valid_cpus[] = {
|
||||
@@ -2954,6 +2954,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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"),
|
||||
@@ -219,6 +220,7 @@ static const char *valid_cpus[] = {
|
||||
ARM_CPU_TYPE_NAME("neoverse-n2"),
|
||||
#endif
|
||||
ARM_CPU_TYPE_NAME("cortex-a53"),
|
||||
ARM_CPU_TYPE_NAME("cortex-a7"),
|
||||
ARM_CPU_TYPE_NAME("cortex-a15"),
|
||||
@@ -2971,6 +2972,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
#endif /* CONFIG_TCG */
|
||||
#ifdef TARGET_AARCH64
|
||||
ARM_CPU_TYPE_NAME("cortex-a53"),
|
||||
+#endif /* disabled for RHEL */
|
||||
ARM_CPU_TYPE_NAME("cortex-a57"),
|
||||
ARM_CPU_TYPE_NAME("host"),
|
||||
ARM_CPU_TYPE_NAME("max"),
|
||||
ARM_CPU_TYPE_NAME("cortex-a57"),
|
||||
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
||||
ARM_CPU_TYPE_NAME("host"),
|
||||
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
|
||||
index d7cc4d3ec1..12d0a60905 100644
|
||||
index 6dd94e98bc..a05757fc9a 100644
|
||||
--- a/hw/block/fdc.c
|
||||
+++ b/hw/block/fdc.c
|
||||
@@ -49,6 +49,8 @@
|
||||
@ -405,7 +420,7 @@ index d7cc4d3ec1..12d0a60905 100644
|
||||
error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
|
||||
return;
|
||||
diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build
|
||||
index 6d319947ca..91962fd863 100644
|
||||
index 38cdcfbe57..e588ecfd42 100644
|
||||
--- a/hw/cpu/meson.build
|
||||
+++ b/hw/cpu/meson.build
|
||||
@@ -1,4 +1,5 @@
|
||||
@ -416,7 +431,7 @@ index 6d319947ca..91962fd863 100644
|
||||
system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c'))
|
||||
system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c'))
|
||||
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
|
||||
index ea0aebf6e3..6878f06974 100644
|
||||
index 3e375f61a9..613adb3ebb 100644
|
||||
--- a/hw/cxl/meson.build
|
||||
+++ b/hw/cxl/meson.build
|
||||
@@ -6,7 +6,8 @@ system_ss.add(when: 'CONFIG_CXL',
|
||||
@ -430,7 +445,7 @@ index ea0aebf6e3..6878f06974 100644
|
||||
if_false: files(
|
||||
'cxl-host-stubs.c',
|
||||
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
|
||||
index b80f98b6c4..0370cf8a64 100644
|
||||
index 150883a971..497365bd80 100644
|
||||
--- a/hw/display/cirrus_vga.c
|
||||
+++ b/hw/display/cirrus_vga.c
|
||||
@@ -36,6 +36,7 @@
|
||||
@ -452,10 +467,10 @@ index b80f98b6c4..0370cf8a64 100644
|
||||
* Follow real hardware, cirrus card emulated has 4 MB video memory.
|
||||
* Also accept 8 MB/16 MB for backward compatibility.
|
||||
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
|
||||
index 4e5e12935f..03ca06bb17 100644
|
||||
index 80efc633d3..9cb82b8eea 100644
|
||||
--- a/hw/ide/piix.c
|
||||
+++ b/hw/ide/piix.c
|
||||
@@ -190,7 +190,8 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
|
||||
@@ -191,7 +191,8 @@ static void piix3_ide_class_init(ObjectClass *klass, 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);
|
||||
@ -465,7 +480,7 @@ index 4e5e12935f..03ca06bb17 100644
|
||||
}
|
||||
|
||||
static const TypeInfo piix3_ide_info = {
|
||||
@@ -214,6 +215,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
||||
@@ -215,6 +216,8 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
||||
dc->hotpluggable = false;
|
||||
@ -474,57 +489,11 @@ index 4e5e12935f..03ca06bb17 100644
|
||||
}
|
||||
|
||||
static const TypeInfo piix4_ide_info = {
|
||||
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
|
||||
index 1b3b4da01d..454bfa5783 100644
|
||||
--- a/hw/ide/qdev.c
|
||||
+++ b/hw/ide/qdev.c
|
||||
@@ -283,10 +283,13 @@ static void ide_cd_realize(IDEDevice *dev, Error **errp)
|
||||
ide_dev_initfn(dev, IDE_CD, errp);
|
||||
}
|
||||
|
||||
+/* Disabled for Red Hat Enterprise Linux */
|
||||
+#if 0
|
||||
static void ide_cf_realize(IDEDevice *dev, Error **errp)
|
||||
{
|
||||
ide_dev_initfn(dev, IDE_CFATA, errp);
|
||||
}
|
||||
+#endif
|
||||
|
||||
#define DEFINE_IDE_DEV_PROPERTIES() \
|
||||
DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
|
||||
@@ -346,6 +349,8 @@ static const TypeInfo ide_cd_info = {
|
||||
.class_init = ide_cd_class_init,
|
||||
};
|
||||
|
||||
+/* Disabled for Red Hat Enterprise Linux */
|
||||
+#if 0
|
||||
static Property ide_cf_properties[] = {
|
||||
DEFINE_IDE_DEV_PROPERTIES(),
|
||||
DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf),
|
||||
@@ -371,6 +376,7 @@ static const TypeInfo ide_cf_info = {
|
||||
.instance_size = sizeof(IDEDrive),
|
||||
.class_init = ide_cf_class_init,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static void ide_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
@@ -396,7 +402,10 @@ static void ide_register_types(void)
|
||||
type_register_static(&ide_bus_info);
|
||||
type_register_static(&ide_hd_info);
|
||||
type_register_static(&ide_cd_info);
|
||||
+/* Disabled for Red Hat Enterprise Linux */
|
||||
+#if 0
|
||||
type_register_static(&ide_cf_info);
|
||||
+#endif
|
||||
type_register_static(&ide_device_type_info);
|
||||
}
|
||||
|
||||
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
|
||||
index b92b63bedc..3b6235dde6 100644
|
||||
index 74f10b640f..2e85ecf476 100644
|
||||
--- a/hw/input/pckbd.c
|
||||
+++ b/hw/input/pckbd.c
|
||||
@@ -957,6 +957,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
|
||||
@@ -952,6 +952,8 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
|
||||
dc->vmsd = &vmstate_kbd_isa;
|
||||
adevc->build_dev_aml = i8042_build_aml;
|
||||
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||
@ -534,7 +503,7 @@ index b92b63bedc..3b6235dde6 100644
|
||||
|
||||
static const TypeInfo i8042_info = {
|
||||
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
||||
index 8ffe1077f1..b3dfeeca4f 100644
|
||||
index 43f3a4a701..267f182883 100644
|
||||
--- a/hw/net/e1000.c
|
||||
+++ b/hw/net/e1000.c
|
||||
@@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = {
|
||||
@ -554,10 +523,10 @@ index 8ffe1077f1..b3dfeeca4f 100644
|
||||
|
||||
static void e1000_register_types(void)
|
||||
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
|
||||
index 91fae56573..33e0c8724c 100644
|
||||
index e7c9edd033..3b0a47a28c 100644
|
||||
--- a/hw/ppc/spapr_cpu_core.c
|
||||
+++ b/hw/ppc/spapr_cpu_core.c
|
||||
@@ -386,10 +386,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
|
||||
@@ -389,10 +389,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
|
||||
.instance_size = sizeof(SpaprCpuCore),
|
||||
.class_size = sizeof(SpaprCpuCoreClass),
|
||||
},
|
||||
@ -565,16 +534,16 @@ index 91fae56573..33e0c8724c 100644
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power5+_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power5p_v2.1"),
|
||||
+#endif
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power7+_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
|
||||
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
|
||||
index e94149ebde..4a8adbf3dc 100644
|
||||
index aac3bb35f2..5411ff35df 100644
|
||||
--- a/hw/usb/meson.build
|
||||
+++ b/hw/usb/meson.build
|
||||
@@ -52,7 +52,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
|
||||
@@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader
|
||||
if cacard.found()
|
||||
usbsmartcard_ss = ss.source_set()
|
||||
usbsmartcard_ss.add(when: 'CONFIG_USB_SMARTCARD',
|
||||
@ -584,26 +553,34 @@ index e94149ebde..4a8adbf3dc 100644
|
||||
endif
|
||||
|
||||
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
|
||||
index c0055a7832..12e1d6c67e 100644
|
||||
index d7f18c96e6..aaabbb8b0b 100644
|
||||
--- a/hw/virtio/meson.build
|
||||
+++ b/hw/virtio/meson.build
|
||||
@@ -17,8 +17,9 @@ if have_vhost
|
||||
if have_vhost_user
|
||||
# fixme - this really should be generic
|
||||
specific_virtio_ss.add(files('vhost-user.c'))
|
||||
@@ -20,7 +20,8 @@ if have_vhost
|
||||
system_virtio_ss.add(files('vhost-user-base.c'))
|
||||
|
||||
# MMIO Stubs
|
||||
- system_virtio_ss.add(files('vhost-user-device.c'))
|
||||
- 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(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'))
|
||||
@@ -28,7 +29,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'))
|
||||
endif
|
||||
if have_vhost_vdpa
|
||||
system_virtio_ss.add(files('vhost-vdpa.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 b53d5efe13..64989a02d1 100644
|
||||
index 3cc8cc738b..6f21fea1f5 100644
|
||||
--- a/target/arm/arm-qmp-cmds.c
|
||||
+++ b/target/arm/arm-qmp-cmds.c
|
||||
@@ -231,6 +231,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
@@ -223,6 +223,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
{
|
||||
ObjectClass *oc = data;
|
||||
@ -611,23 +588,23 @@ index b53d5efe13..64989a02d1 100644
|
||||
CpuDefinitionInfoList **cpu_list = user_data;
|
||||
CpuDefinitionInfo *info;
|
||||
const char *typename;
|
||||
@@ -240,6 +241,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
|
||||
info->name = g_strndup(typename,
|
||||
strlen(typename) - strlen("-" TYPE_ARM_CPU));
|
||||
@@ -231,6 +232,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.c b/target/arm/cpu.c
|
||||
index efb22a87f9..a32521ada9 100644
|
||||
index ab8d007a86..e5dce20f19 100644
|
||||
--- a/target/arm/cpu.c
|
||||
+++ b/target/arm/cpu.c
|
||||
@@ -2524,6 +2524,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
|
||||
@@ -2546,6 +2546,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
acc->info = data;
|
||||
cc->gdb_core_xml_file = "arm-core.xml";
|
||||
+
|
||||
+
|
||||
+ if (acc->info->deprecation_note) {
|
||||
+ cc->deprecation_note = acc->info->deprecation_note;
|
||||
+ }
|
||||
@ -635,10 +612,10 @@ index efb22a87f9..a32521ada9 100644
|
||||
|
||||
void arm_cpu_register(const ARMCPUInfo *info)
|
||||
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
|
||||
index a0282e0d28..7e0f0dfea7 100644
|
||||
index bc0c84873f..e9472c8bb8 100644
|
||||
--- a/target/arm/cpu.h
|
||||
+++ b/target/arm/cpu.h
|
||||
@@ -34,6 +34,8 @@
|
||||
@@ -37,6 +37,8 @@
|
||||
#define KVM_HAVE_MCE_INJECTION 1
|
||||
#endif
|
||||
|
||||
@ -647,7 +624,7 @@ index a0282e0d28..7e0f0dfea7 100644
|
||||
#define EXCP_UDEF 1 /* undefined instruction */
|
||||
#define EXCP_SWI 2 /* software interrupt */
|
||||
#define EXCP_PREFETCH_ABORT 3
|
||||
@@ -1120,6 +1122,7 @@ typedef struct ARMCPUInfo {
|
||||
@@ -1092,6 +1094,7 @@ typedef struct ARMCPUInfo {
|
||||
const char *name;
|
||||
void (*initfn)(Object *obj);
|
||||
void (*class_init)(ObjectClass *oc, void *data);
|
||||
@ -656,7 +633,7 @@ index a0282e0d28..7e0f0dfea7 100644
|
||||
|
||||
/**
|
||||
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
|
||||
index 1e9c6c85ae..10be900803 100644
|
||||
index 985b1efe16..46a4e80171 100644
|
||||
--- a/target/arm/cpu64.c
|
||||
+++ b/target/arm/cpu64.c
|
||||
@@ -648,6 +648,7 @@ static void aarch64_a57_initfn(Object *obj)
|
||||
@ -688,7 +665,7 @@ index 1e9c6c85ae..10be900803 100644
|
||||
{ .name = "max", .initfn = aarch64_max_initfn },
|
||||
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
||||
{ .name = "host", .initfn = aarch64_host_initfn },
|
||||
@@ -815,8 +820,13 @@ static void aarch64_cpu_instance_init(Object *obj)
|
||||
@@ -814,8 +819,13 @@ static void aarch64_cpu_instance_init(Object *obj)
|
||||
static void cpu_register_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
|
||||
@ -703,24 +680,24 @@ index 1e9c6c85ae..10be900803 100644
|
||||
|
||||
void aarch64_cpu_register(const ARMCPUInfo *info)
|
||||
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
|
||||
index d9e0e2a4dd..c5c639a6ea 100644
|
||||
index de8f2be941..8896295ae3 100644
|
||||
--- a/target/arm/tcg/cpu32.c
|
||||
+++ b/target/arm/tcg/cpu32.c
|
||||
@@ -98,6 +98,7 @@ void aa32_max_features(ARMCPU *cpu)
|
||||
@@ -92,6 +92,7 @@ void aa32_max_features(ARMCPU *cpu)
|
||||
cpu->isar.id_dfr1 = t;
|
||||
}
|
||||
|
||||
+#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)
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
@@ -1189,3 +1190,4 @@ static void arm_tcg_cpu_register_types(void)
|
||||
@@ -1037,3 +1038,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 fcda99e158..bd5a993ff8 100644
|
||||
index 9f7a9f3d2c..7ec6851c9c 100644
|
||||
--- a/target/arm/tcg/cpu64.c
|
||||
+++ b/target/arm/tcg/cpu64.c
|
||||
@@ -29,6 +29,7 @@
|
||||
@ -755,7 +732,7 @@ index fcda99e158..bd5a993ff8 100644
|
||||
|
||||
/*
|
||||
* -cpu max: a CPU with as many features enabled as our emulation supports.
|
||||
@@ -1259,6 +1263,7 @@ void aarch64_max_tcg_initfn(Object *obj)
|
||||
@@ -1271,6 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj)
|
||||
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
|
||||
}
|
||||
|
||||
@ -763,7 +740,7 @@ index fcda99e158..bd5a993ff8 100644
|
||||
static const ARMCPUInfo aarch64_cpus[] = {
|
||||
{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
|
||||
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
|
||||
@@ -1270,14 +1275,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
|
||||
@@ -1282,14 +1287,17 @@ static const ARMCPUInfo aarch64_cpus[] = {
|
||||
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
|
||||
{ .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
|
||||
};
|
||||
@ -781,8 +758,20 @@ index fcda99e158..bd5a993ff8 100644
|
||||
}
|
||||
|
||||
type_init(aarch64_cpu_register_types)
|
||||
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
|
||||
index 3b1a9f0fc5..6898b4de6f 100644
|
||||
--- a/target/arm/tcg/meson.build
|
||||
+++ b/target/arm/tcg/meson.build
|
||||
@@ -56,5 +56,5 @@ arm_system_ss.add(files(
|
||||
'psci.c',
|
||||
))
|
||||
|
||||
-arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
|
||||
-arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
|
||||
+#arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
|
||||
+#arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
|
||||
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
|
||||
index 7dbb47de64..69fddb05bc 100644
|
||||
index f2301b43f7..f77ebfcc81 100644
|
||||
--- a/target/ppc/cpu-models.c
|
||||
+++ b/target/ppc/cpu-models.c
|
||||
@@ -66,6 +66,7 @@
|
||||
@ -806,13 +795,13 @@ index 7dbb47de64..69fddb05bc 100644
|
||||
POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970,
|
||||
@@ -718,6 +721,7 @@
|
||||
"PowerPC 970MP v1.1")
|
||||
POWERPC_DEF("power5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P,
|
||||
POWERPC_DEF("power5p_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P,
|
||||
"POWER5+ v2.1")
|
||||
+#endif
|
||||
POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7,
|
||||
"POWER7 v2.3")
|
||||
POWERPC_DEF("power7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
|
||||
@@ -898,12 +902,15 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
|
||||
@@ -894,13 +898,16 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "7447a", "7447a_v1.2" },
|
||||
{ "7457a", "7457a_v1.2" },
|
||||
{ "apollo7pm", "7457a_v1.0" },
|
||||
@ -822,13 +811,14 @@ index 7dbb47de64..69fddb05bc 100644
|
||||
{ "970", "970_v2.2" },
|
||||
{ "970fx", "970fx_v3.1" },
|
||||
{ "970mp", "970mp_v1.1" },
|
||||
{ "power5+", "power5+_v2.1" },
|
||||
{ "power5+", "power5p_v2.1" },
|
||||
{ "power5+_v2.1", "power5p_v2.1" },
|
||||
{ "power5gs", "power5+_v2.1" },
|
||||
+#endif
|
||||
{ "power7", "power7_v2.3" },
|
||||
{ "power7+", "power7+_v2.1" },
|
||||
{ "power8e", "power8e_v2.1" },
|
||||
@@ -913,12 +920,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "power7+", "power7p_v2.1" },
|
||||
{ "power7+_v2.1", "power7p_v2.1" },
|
||||
@@ -911,12 +918,14 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "power10", "power10_v2.0" },
|
||||
#endif
|
||||
|
||||
@ -844,10 +834,10 @@ index 7dbb47de64..69fddb05bc 100644
|
||||
{ NULL, NULL }
|
||||
};
|
||||
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
|
||||
index 63981bf36b..87a4480c05 100644
|
||||
index 2d99218069..0728bfcc20 100644
|
||||
--- a/target/s390x/cpu_models_sysemu.c
|
||||
+++ b/target/s390x/cpu_models_sysemu.c
|
||||
@@ -35,6 +35,9 @@ static void check_unavailable_features(const S390CPUModel *max_model,
|
||||
@@ -34,6 +34,9 @@ static void check_unavailable_features(const S390CPUModel *max_model,
|
||||
(max_model->def->gen == model->def->gen &&
|
||||
max_model->def->ec_ga < model->def->ec_ga)) {
|
||||
list_add_feat("type", unavailable);
|
||||
@ -858,10 +848,10 @@ index 63981bf36b..87a4480c05 100644
|
||||
|
||||
/* detect missing features if any to properly report them */
|
||||
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
|
||||
index 33ab3551f4..912e493951 100644
|
||||
index 4ce809c5d4..55fb4855b1 100644
|
||||
--- a/target/s390x/kvm/kvm.c
|
||||
+++ b/target/s390x/kvm/kvm.c
|
||||
@@ -2567,6 +2567,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
|
||||
@@ -2565,6 +2565,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
|
||||
error_setg(errp, "KVM doesn't support CPU models");
|
||||
return;
|
||||
}
|
||||
@ -877,10 +867,10 @@ index 33ab3551f4..912e493951 100644
|
||||
prop.ibc = s390_ibc_from_cpu_model(model);
|
||||
/* configure cpu features indicated via STFL(e) */
|
||||
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
|
||||
index a8a4c668ad..2458cc527c 100644
|
||||
index 9d6e6190d5..f822526acb 100644
|
||||
--- a/tests/qtest/arm-cpu-features.c
|
||||
+++ b/tests/qtest/arm-cpu-features.c
|
||||
@@ -451,8 +451,10 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
@@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
|
||||
|
||||
/* Test expected feature presence/absence for some cpu types */
|
||||
@ -891,7 +881,7 @@ index a8a4c668ad..2458cc527c 100644
|
||||
|
||||
/* Enabling and disabling pmu should always work. */
|
||||
assert_has_feature_enabled(qts, "max", "pmu");
|
||||
@@ -469,6 +471,7 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
@@ -470,6 +472,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");
|
||||
|
||||
@ -899,7 +889,7 @@ index a8a4c668ad..2458cc527c 100644
|
||||
assert_has_feature_enabled(qts, "a64fx", "pmu");
|
||||
assert_has_feature_enabled(qts, "a64fx", "aarch64");
|
||||
/*
|
||||
@@ -481,6 +484,7 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
@@ -482,6 +485,7 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||
"{ 'sve384': true }");
|
||||
assert_error(qts, "a64fx", "cannot enable sve640",
|
||||
"{ 'sve640': true }");
|
||||
|
@ -1,4 +1,4 @@
|
||||
From d9ff466c980d219ebf230ea24becce294c196f1f Mon Sep 17 00:00:00 2001
|
||||
From 8e6a30073f9c1a5d6294b2d16556522453e227e7 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 11 Jan 2019 09:54:45 +0100
|
||||
Subject: Machine type related general changes
|
||||
@ -26,6 +26,12 @@ Rebase notes (7.1.0):
|
||||
Rebase notes (8.1.0):
|
||||
- Do not modify unused vga-isa.c
|
||||
|
||||
Rebase notes (9.0.0 rc0):
|
||||
- Updated smsbios handling
|
||||
|
||||
Rebase notes (9.0.0 rc4):
|
||||
- Moving downstream compat changes
|
||||
|
||||
Merged patches (6.1.0):
|
||||
- f2fb42a3c6 redhat: add missing entries in hw_compat_rhel_8_4
|
||||
- 1949ec258e hw/arm/virt: Disable PL011 clock migration through hw_compat_rhel_8_3
|
||||
@ -61,24 +67,27 @@ Merged patches (8.1.0):
|
||||
|
||||
Merged patches (8.2.0):
|
||||
- 4ee284aca9 Add machine types compat bits. (partial)
|
||||
|
||||
Merged patches (9.0.0 rc0):
|
||||
- 4b8fe42abc virtio-mem: default-enable "dynamic-memslots"
|
||||
---
|
||||
hw/acpi/piix4.c | 2 +-
|
||||
hw/arm/virt.c | 2 +-
|
||||
hw/core/machine.c | 267 +++++++++++++++++++++++++++++++++++
|
||||
hw/i386/pc_piix.c | 2 +
|
||||
hw/i386/pc_q35.c | 2 +
|
||||
hw/core/machine.c | 269 +++++++++++++++++++++++++++++++++++
|
||||
hw/i386/fw_cfg.c | 3 +-
|
||||
hw/net/rtl8139.c | 4 +-
|
||||
hw/smbios/smbios.c | 46 +++++-
|
||||
hw/timer/i8254_common.c | 2 +-
|
||||
hw/usb/hcd-xhci-pci.c | 59 ++++++--
|
||||
hw/usb/hcd-xhci-pci.h | 1 +
|
||||
hw/virtio/virtio-mem.c | 3 +-
|
||||
include/hw/boards.h | 40 ++++++
|
||||
include/hw/firmware/smbios.h | 5 +-
|
||||
include/hw/firmware/smbios.h | 4 +-
|
||||
include/hw/i386/pc.h | 3 +
|
||||
13 files changed, 413 insertions(+), 22 deletions(-)
|
||||
13 files changed, 414 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
|
||||
index dd523d2e4c..5050c0ba97 100644
|
||||
index debe1adb84..e8ddcd716e 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)
|
||||
@ -88,28 +97,28 @@ index dd523d2e4c..5050c0ba97 100644
|
||||
- .minimum_version_id = 3,
|
||||
+ .minimum_version_id = 2,
|
||||
.post_load = vmstate_acpi_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index af9ea4dd1c..62f0f7d4d6 100644
|
||||
index 6c6d155002..36e9b4b4e9 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1638,7 +1638,7 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
@@ -1651,7 +1651,7 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
|
||||
smbios_set_defaults("QEMU", product,
|
||||
vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
|
||||
- true, SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
+ true, NULL, NULL, SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
vmc->smbios_old_sys_ver ? "1.0" : mc->name,
|
||||
- true);
|
||||
+ true, 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 0c17398141..446601ee30 100644
|
||||
index 37ede0e7d4..695cb89a46 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -57,6 +57,273 @@ GlobalProperty hw_compat_7_2[] = {
|
||||
@@ -296,6 +296,275 @@ GlobalProperty hw_compat_2_1[] = {
|
||||
};
|
||||
const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
|
||||
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
|
||||
|
||||
+/*
|
||||
+ * RHEL only: machine types for previous major releases are deprecated
|
||||
@ -132,6 +141,8 @@ index 0c17398141..446601ee30 100644
|
||||
+ { "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);
|
||||
+
|
||||
@ -378,37 +389,25 @@ index 0c17398141..446601ee30 100644
|
||||
+};
|
||||
+const size_t hw_compat_rhel_7_6_len = G_N_ELEMENTS(hw_compat_rhel_7_6);
|
||||
+
|
||||
GlobalProperty hw_compat_7_1[] = {
|
||||
{ "virtio-device", "queue_reset", "false" },
|
||||
{ "virtio-rng-pci", "vectors", "0" },
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index eace854335..2a9f465619 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -238,6 +238,8 @@ static void pc_init1(MachineState *machine,
|
||||
smbios_set_defaults("QEMU", mc->desc,
|
||||
mc->name, pcmc->smbios_legacy_mode,
|
||||
pcmc->smbios_uuid_encoded,
|
||||
+ pcmc->smbios_stream_product,
|
||||
+ pcmc->smbios_stream_version,
|
||||
pcms->smbios_entry_point_type);
|
||||
}
|
||||
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index 4f3e5412f6..912cb0c0dc 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -206,6 +206,8 @@ static void pc_q35_init(MachineState *machine)
|
||||
smbios_set_defaults("QEMU", mc->desc,
|
||||
mc->name, pcmc->smbios_legacy_mode,
|
||||
pcmc->smbios_uuid_encoded,
|
||||
+ pcmc->smbios_stream_product,
|
||||
+ pcmc->smbios_stream_version,
|
||||
pcms->smbios_entry_point_type);
|
||||
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 d802d2787f..c7aa39a13e 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -64,7 +64,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
if (pcmc->smbios_defaults) {
|
||||
/* These values are guest ABI, do not change */
|
||||
smbios_set_defaults("QEMU", mc->desc, mc->name,
|
||||
- pcmc->smbios_uuid_encoded);
|
||||
+ pcmc->smbios_uuid_encoded,
|
||||
+ 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 4af8c66266..7dc12907ab 100644
|
||||
index 897c86ec41..2d0db43f49 100644
|
||||
--- a/hw/net/rtl8139.c
|
||||
+++ b/hw/net/rtl8139.c
|
||||
@@ -3169,7 +3169,7 @@ static int rtl8139_pre_save(void *opaque)
|
||||
@ -431,20 +430,21 @@ index 4af8c66266..7dc12907ab 100644
|
||||
VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State),
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 2a90601ac5..7bde23e59d 100644
|
||||
index eed5787b15..68608a3403 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -58,6 +58,9 @@ static bool smbios_legacy = true;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
/* end: legacy structures & constants for <= 2.0 machines */
|
||||
@@ -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;
|
||||
@@ -670,7 +673,7 @@ static void smbios_build_type_1_table(void)
|
||||
unsigned smbios_table_max;
|
||||
@@ -629,7 +633,7 @@ static void smbios_build_type_1_table(void)
|
||||
|
||||
static void smbios_build_type_2_table(void)
|
||||
{
|
||||
@ -453,21 +453,17 @@ index 2a90601ac5..7bde23e59d 100644
|
||||
|
||||
SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer);
|
||||
SMBIOS_TABLE_SET_STR(2, product_str, type2.product);
|
||||
@@ -985,7 +988,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
|
||||
@@ -1018,16 +1022,52 @@ void smbios_set_default_processor_family(uint16_t processor_family)
|
||||
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
const char *version, bool legacy_mode,
|
||||
- bool uuid_encoded, SmbiosEntryPointType ep_type)
|
||||
const char *version,
|
||||
- bool uuid_encoded)
|
||||
+ bool uuid_encoded,
|
||||
+ const char *stream_product,
|
||||
+ const char *stream_version,
|
||||
+ SmbiosEntryPointType ep_type)
|
||||
+ const char *stream_version)
|
||||
{
|
||||
smbios_have_defaults = true;
|
||||
smbios_legacy = legacy_mode;
|
||||
@@ -1006,11 +1012,45 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
g_free(smbios_entries);
|
||||
}
|
||||
smbios_uuid_encoded = uuid_encoded;
|
||||
|
||||
+ /*
|
||||
+ * If @stream_product & @stream_version are non-NULL, then
|
||||
@ -494,12 +490,12 @@ index 2a90601ac5..7bde23e59d 100644
|
||||
+ *
|
||||
+ * We get 'System Manufacturer' and 'Baseboard Manufacturer'
|
||||
+ */
|
||||
SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
|
||||
SMBIOS_SET_DEFAULT(type1.product, product);
|
||||
SMBIOS_SET_DEFAULT(type1.version, version);
|
||||
+ SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
|
||||
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(type1.sku, stream_version);
|
||||
+ SMBIOS_SET_DEFAULT(smbios_type1.sku, stream_version);
|
||||
+ }
|
||||
SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
|
||||
- SMBIOS_SET_DEFAULT(type2.product, product);
|
||||
@ -513,20 +509,20 @@ index 2a90601ac5..7bde23e59d 100644
|
||||
SMBIOS_SET_DEFAULT(type3.manufacturer, manufacturer);
|
||||
SMBIOS_SET_DEFAULT(type3.version, version);
|
||||
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
|
||||
index b25da448c8..0331e84398 100644
|
||||
index 28fdabc321..bad13ec224 100644
|
||||
--- a/hw/timer/i8254_common.c
|
||||
+++ b/hw/timer/i8254_common.c
|
||||
@@ -229,7 +229,7 @@ static const VMStateDescription vmstate_pit_common = {
|
||||
.pre_save = pit_dispatch_pre_save,
|
||||
.post_load = pit_dispatch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
.fields = (const VMStateField[]) {
|
||||
- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
|
||||
+ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */
|
||||
VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
|
||||
vmstate_pit_channel, PITChannelState),
|
||||
VMSTATE_INT64(channels[0].next_transition_time,
|
||||
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
|
||||
index 643d4643e4..529bad9366 100644
|
||||
index 4423983308..43b4b71fdf 100644
|
||||
--- a/hw/usb/hcd-xhci-pci.c
|
||||
+++ b/hw/usb/hcd-xhci-pci.c
|
||||
@@ -104,6 +104,33 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
|
||||
@ -636,11 +632,26 @@ index 08f70ce97c..1be7527c1b 100644
|
||||
} XHCIPciState;
|
||||
|
||||
#endif
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index ffd119ebac..0e2be2219c 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -1694,8 +1694,9 @@ static 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),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index da85f86efb..4a21eddbf9 100644
|
||||
index 8b8f6d5c00..0466f9d0f3 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -503,4 +503,44 @@ extern const size_t hw_compat_2_2_len;
|
||||
@@ -512,4 +512,44 @@ extern const size_t hw_compat_2_2_len;
|
||||
extern GlobalProperty hw_compat_2_1[];
|
||||
extern const size_t hw_compat_2_1_len;
|
||||
|
||||
@ -686,26 +697,25 @@ index da85f86efb..4a21eddbf9 100644
|
||||
+extern const char *rhel_old_machine_deprecation;
|
||||
#endif
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 7f3259a630..d24b3ccd32 100644
|
||||
index 8d3fb2fb3b..d9d6d7a169 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -294,7 +294,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp);
|
||||
@@ -332,7 +332,9 @@ 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, bool legacy_mode,
|
||||
- bool uuid_encoded, SmbiosEntryPointType ep_type);
|
||||
const char *version,
|
||||
- bool uuid_encoded);
|
||||
+ bool uuid_encoded,
|
||||
+ const char *stream_product,
|
||||
+ const char *stream_version,
|
||||
+ SmbiosEntryPointType ep_type);
|
||||
uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
|
||||
+ 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,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index a10ceeabbf..037942d233 100644
|
||||
index 27a68071d7..ebd8f973f2 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -113,6 +113,9 @@ struct PCMachineClass {
|
||||
@@ -112,6 +112,9 @@ struct PCMachineClass {
|
||||
bool smbios_legacy_mode;
|
||||
bool smbios_uuid_encoded;
|
||||
SmbiosEntryPointType default_smbios_ep_type;
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 23f614ab0b79ec1c6f65a7f0d6993bfdfc53fd23 Mon Sep 17 00:00:00 2001
|
||||
From cf398296f3fcee185a00f23de5deae57c97d648e Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 19 Oct 2018 12:53:31 +0200
|
||||
Subject: Add aarch64 machine types
|
||||
@ -30,6 +30,9 @@ Rebase notes (8.0.0):
|
||||
Rebase notes (8.1.0):
|
||||
- Added setting default_nic
|
||||
|
||||
Rebase notes (9.0.0 rc0):
|
||||
- call arm_virt_compat_set on rhel type class_init
|
||||
|
||||
Merged patches (6.2.0):
|
||||
- 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type
|
||||
- f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type
|
||||
@ -64,34 +67,67 @@ Merged patches (8.1.0):
|
||||
|
||||
Merged patches (8.2.0):
|
||||
- 4ee284aca9 Add machine types compat bits. (partial)
|
||||
|
||||
Merged patches (9.0.0 rc0):
|
||||
- 117068376a hw/arm/virt: Fix compats
|
||||
- 8bcccfabc4 hw/arm/virt: Add properties to disable high memory regions
|
||||
- 0005a8b93a hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types
|
||||
---
|
||||
hw/arm/virt.c | 250 +++++++++++++++++++++++++++++++++++++++++-
|
||||
hw/arm/virt.c | 299 +++++++++++++++++++++++++++++++++++++++++-
|
||||
include/hw/arm/virt.h | 8 ++
|
||||
2 files changed, 257 insertions(+), 1 deletion(-)
|
||||
2 files changed, 306 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 62f0f7d4d6..c541efee5e 100644
|
||||
index 36e9b4b4e9..22bc345137 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "hw/char/pl011.h"
|
||||
#include "qemu/guest-random.h"
|
||||
@@ -101,6 +101,7 @@ static void arm_virt_compat_set(MachineClass *mc)
|
||||
arm_virt_compat_len);
|
||||
}
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
|
||||
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
|
||||
void *data) \
|
||||
@@ -108,7 +109,48 @@
|
||||
@@ -128,7 +129,63 @@ static void arm_virt_compat_set(MachineClass *mc)
|
||||
DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
|
||||
#define DEFINE_VIRT_MACHINE(major, minor) \
|
||||
DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
|
||||
+#endif /* disabled for RHEL */
|
||||
+
|
||||
+/*
|
||||
+ * This variable is for changes to properties that are RHEL specific,
|
||||
+ * different to the current upstream and to be applied to the latest
|
||||
+ * machine type. They may be overriden by older machine compats.
|
||||
+ *
|
||||
+ * virtio-net-pci variant romfiles are not needed because edk2 does
|
||||
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
|
||||
+ * on rhel/aarch64.
|
||||
+ */
|
||||
+GlobalProperty arm_rhel_compat[] = {
|
||||
+ {"virtio-net-pci", "romfile", "" },
|
||||
+ {"virtio-net-pci-transitional", "romfile", "" },
|
||||
+ {"virtio-net-pci-non-transitional", "romfile", "" },
|
||||
+};
|
||||
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
|
||||
|
||||
+/*
|
||||
+ * This cannot be called from the rhel_virt_class_init() because
|
||||
+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new()
|
||||
+ * only is called on virt-rhelm.n.s non abstract class init.
|
||||
+ */
|
||||
+static void arm_rhel_compat_set(MachineClass *mc)
|
||||
+{
|
||||
+ compat_props_add(mc->compat_props, arm_rhel_compat,
|
||||
+ arm_rhel_compat_len);
|
||||
+}
|
||||
+
|
||||
+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \
|
||||
+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \
|
||||
+ void *data) \
|
||||
+ { \
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc); \
|
||||
+ arm_rhel_compat_set(mc); \
|
||||
+ rhel##m##n##s##_virt_options(mc); \
|
||||
+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \
|
||||
+ if (latest) { \
|
||||
@ -114,23 +150,10 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true)
|
||||
+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \
|
||||
+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false)
|
||||
+
|
||||
+/* 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.
|
||||
+ */
|
||||
+GlobalProperty arm_rhel_compat[] = {
|
||||
+ {
|
||||
+ .driver = "virtio-net-pci",
|
||||
+ .property = "romfile",
|
||||
+ .value = "",
|
||||
+ },
|
||||
+};
|
||||
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
|
||||
|
||||
/* Number of external interrupt lines to configure the GIC with */
|
||||
#define NUM_IRQS 256
|
||||
@@ -2341,6 +2383,7 @@ static void machvirt_init(MachineState *machine)
|
||||
@@ -2355,6 +2412,7 @@ static void machvirt_init(MachineState *machine)
|
||||
qemu_add_machine_init_done_notifier(&vms->machine_done);
|
||||
}
|
||||
|
||||
@ -138,7 +161,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
static bool virt_get_secure(Object *obj, Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(obj);
|
||||
@@ -2368,6 +2411,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
|
||||
@@ -2382,6 +2440,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp)
|
||||
|
||||
vms->virt = value;
|
||||
}
|
||||
@ -146,7 +169,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
|
||||
static bool virt_get_highmem(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -2383,6 +2427,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
|
||||
@@ -2397,6 +2456,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp)
|
||||
vms->highmem = value;
|
||||
}
|
||||
|
||||
@ -154,16 +177,23 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
static bool virt_get_compact_highmem(Object *obj, Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(obj);
|
||||
@@ -2438,7 +2483,7 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp)
|
||||
@@ -2410,6 +2470,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp)
|
||||
|
||||
vms->highmem_mmio = value;
|
||||
vms->highmem_compact = value;
|
||||
}
|
||||
-
|
||||
+#endif /* disabled for RHEL */
|
||||
|
||||
static bool virt_get_highmem_redists(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -2453,7 +2514,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp)
|
||||
vms->highmem_mmio = value;
|
||||
}
|
||||
|
||||
-
|
||||
static bool virt_get_its(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -2454,6 +2499,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
|
||||
VirtMachineState *vms = VIRT_MACHINE(obj);
|
||||
@@ -2468,6 +2528,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp)
|
||||
vms->its = value;
|
||||
}
|
||||
|
||||
@ -171,7 +201,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
static bool virt_get_dtb_randomness(Object *obj, Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(obj);
|
||||
@@ -2467,6 +2513,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
|
||||
@@ -2481,6 +2542,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp)
|
||||
|
||||
vms->dtb_randomness = value;
|
||||
}
|
||||
@ -179,7 +209,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
|
||||
static char *virt_get_oem_id(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -2550,6 +2597,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
|
||||
@@ -2564,6 +2626,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp)
|
||||
vms->ras = value;
|
||||
}
|
||||
|
||||
@ -187,7 +217,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
static bool virt_get_mte(Object *obj, Error **errp)
|
||||
{
|
||||
VirtMachineState *vms = VIRT_MACHINE(obj);
|
||||
@@ -2563,6 +2611,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
|
||||
@@ -2577,6 +2640,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
|
||||
|
||||
vms->mte = value;
|
||||
}
|
||||
@ -195,7 +225,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
|
||||
static char *virt_get_gic_version(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -2935,6 +2984,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
|
||||
@@ -2949,6 +3013,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
|
||||
return fixed_ipa ? 0 : requested_pa_size;
|
||||
}
|
||||
|
||||
@ -203,7 +233,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@@ -3405,3 +3455,201 @@ static void virt_machine_2_6_options(MachineClass *mc)
|
||||
@@ -3463,3 +3528,235 @@ static void virt_machine_2_6_options(MachineClass *mc)
|
||||
vmc->no_pmu = true;
|
||||
}
|
||||
DEFINE_VIRT_MACHINE(2, 6)
|
||||
@ -213,6 +243,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+{
|
||||
+ MachineClass *mc = MACHINE_CLASS(oc);
|
||||
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
||||
+ arm_virt_compat_set(mc);
|
||||
+
|
||||
+ mc->family = "virt-rhel-Z";
|
||||
+ mc->init = machvirt_init;
|
||||
@ -258,6 +289,28 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+ "Set on/off to enable/disable using "
|
||||
+ "physical address space above 32 bits");
|
||||
+
|
||||
+ object_class_property_add_bool(oc, "highmem-redists",
|
||||
+ virt_get_highmem_redists,
|
||||
+ virt_set_highmem_redists);
|
||||
+ object_class_property_set_description(oc, "highmem-redists",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for GICv3 or GICv4 "
|
||||
+ "redistributor");
|
||||
+
|
||||
+ object_class_property_add_bool(oc, "highmem-ecam",
|
||||
+ virt_get_highmem_ecam,
|
||||
+ virt_set_highmem_ecam);
|
||||
+ object_class_property_set_description(oc, "highmem-ecam",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for PCI ECAM");
|
||||
+
|
||||
+ object_class_property_add_bool(oc, "highmem-mmio",
|
||||
+ virt_get_highmem_mmio,
|
||||
+ virt_set_highmem_mmio);
|
||||
+ object_class_property_set_description(oc, "highmem-mmio",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for PCI MMIO");
|
||||
+
|
||||
+ object_class_property_add_str(oc, "gic-version", virt_get_gic_version,
|
||||
+ virt_set_gic_version);
|
||||
+ object_class_property_set_description(oc, "gic-version",
|
||||
@ -382,14 +435,24 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+}
|
||||
+type_init(rhel_machine_init);
|
||||
+
|
||||
+static void rhel940_virt_options(MachineClass *mc)
|
||||
+{
|
||||
+}
|
||||
+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
|
||||
+
|
||||
+static void rhel920_virt_options(MachineClass *mc)
|
||||
+{
|
||||
+ compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len);
|
||||
+ rhel940_virt_options(mc);
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
|
||||
+
|
||||
+ /* RHEL 9.4 is the first supported release */
|
||||
+ mc->deprecation_reason =
|
||||
+ "machine types for versions prior to 9.4 are deprecated";
|
||||
+}
|
||||
+DEFINE_RHEL_MACHINE_AS_LATEST(9, 2, 0)
|
||||
+DEFINE_RHEL_MACHINE(9, 2, 0)
|
||||
+
|
||||
+static void rhel900_virt_options(MachineClass *mc)
|
||||
+{
|
||||
@ -398,6 +461,7 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+ rhel920_virt_options(mc);
|
||||
+
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
|
||||
+
|
||||
+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
|
||||
+ vmc->no_tcg_lpa2 = true;
|
||||
@ -406,10 +470,10 @@ index 62f0f7d4d6..c541efee5e 100644
|
||||
+}
|
||||
+DEFINE_RHEL_MACHINE(9, 0, 0)
|
||||
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
|
||||
index f69239850e..7b8abe5645 100644
|
||||
index bb486d36b1..237fc77bda 100644
|
||||
--- a/include/hw/arm/virt.h
|
||||
+++ b/include/hw/arm/virt.h
|
||||
@@ -177,9 +177,17 @@ struct VirtMachineState {
|
||||
@@ -179,9 +179,17 @@ struct VirtMachineState {
|
||||
|
||||
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From d03cff85f5f1b69b1a66011ebaa974ece81d31bc Mon Sep 17 00:00:00 2001
|
||||
From fb905dbe5b51ed899062ef99a2dd7f238d3e3384 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 19 Oct 2018 13:27:13 +0200
|
||||
Subject: Add ppc64 machine types
|
||||
@ -34,20 +34,20 @@ Merged patches (7.1.0):
|
||||
8 files changed, 314 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
|
||||
index df09aa9d6a..ff459e1a46 100644
|
||||
index e9bc97fee0..a258d81846 100644
|
||||
--- a/hw/ppc/spapr.c
|
||||
+++ b/hw/ppc/spapr.c
|
||||
@@ -1689,6 +1689,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
|
||||
@@ -1718,6 +1718,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
pef_kvm_reset(machine->cgs, &error_fatal);
|
||||
spapr_caps_apply(spapr);
|
||||
spapr_nested_reset(spapr);
|
||||
+ if (spapr->svm_allowed) {
|
||||
+ kvmppc_svm_allow(&error_fatal);
|
||||
+ }
|
||||
|
||||
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
||||
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
|
||||
@@ -3397,6 +3400,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
|
||||
@@ -3421,6 +3424,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp)
|
||||
spapr->host_serial = g_strdup(value);
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
static void spapr_instance_init(Object *obj)
|
||||
{
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
@@ -3475,6 +3492,12 @@ static void spapr_instance_init(Object *obj)
|
||||
@@ -3499,6 +3516,12 @@ static void spapr_instance_init(Object *obj)
|
||||
spapr_get_host_serial, spapr_set_host_serial);
|
||||
object_property_set_description(obj, "host-serial",
|
||||
"Host serial number to advertise in guest device tree");
|
||||
@ -81,7 +81,7 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
}
|
||||
|
||||
static void spapr_machine_finalizefn(Object *obj)
|
||||
@@ -4734,6 +4757,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
@@ -4754,6 +4777,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
vmc->client_architecture_support = spapr_vof_client_architecture_support;
|
||||
vmc->quiesce = spapr_vof_quiesce;
|
||||
vmc->setprop = spapr_vof_setprop;
|
||||
@ -89,15 +89,15 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_machine_info = {
|
||||
@@ -4785,6 +4809,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
|
||||
@@ -4805,6 +4829,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
|
||||
} \
|
||||
type_init(spapr_machine_register_##suffix)
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
/*
|
||||
* pseries-8.2
|
||||
* pseries-9.0
|
||||
*/
|
||||
@@ -4967,6 +4992,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc)
|
||||
@@ -4998,6 +5023,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc)
|
||||
}
|
||||
|
||||
DEFINE_SPAPR_MACHINE(4_1, "4.1", false);
|
||||
@ -105,7 +105,7 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
|
||||
/*
|
||||
* pseries-4.0
|
||||
@@ -4982,6 +5008,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
|
||||
@@ -5013,6 +5039,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -114,7 +114,7 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
static void spapr_machine_4_0_class_options(MachineClass *mc)
|
||||
{
|
||||
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
|
||||
@@ -5306,6 +5334,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc)
|
||||
@@ -5338,6 +5366,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc)
|
||||
compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len);
|
||||
}
|
||||
DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
|
||||
@ -337,7 +337,7 @@ index df09aa9d6a..ff459e1a46 100644
|
||||
static void spapr_machine_register_types(void)
|
||||
{
|
||||
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
|
||||
index 33e0c8724c..9d01663f43 100644
|
||||
index 3b0a47a28c..375e0c8e45 100644
|
||||
--- a/hw/ppc/spapr_cpu_core.c
|
||||
+++ b/hw/ppc/spapr_cpu_core.c
|
||||
@@ -25,6 +25,7 @@
|
||||
@ -348,7 +348,7 @@ index 33e0c8724c..9d01663f43 100644
|
||||
|
||||
static void spapr_reset_vcpu(PowerPCCPU *cpu)
|
||||
{
|
||||
@@ -261,6 +262,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
@@ -264,6 +265,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -356,7 +356,7 @@ index 33e0c8724c..9d01663f43 100644
|
||||
|
||||
if (!qdev_realize(DEVICE(cpu), NULL, errp)) {
|
||||
return false;
|
||||
@@ -277,6 +279,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
@@ -280,6 +282,17 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
/* Set time-base frequency to 512 MHz. vhyp must be set first. */
|
||||
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
|
||||
|
||||
@ -375,10 +375,10 @@ index 33e0c8724c..9d01663f43 100644
|
||||
qdev_unrealize(DEVICE(cpu));
|
||||
return false;
|
||||
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
|
||||
index e91791a1a9..1951d8a2a0 100644
|
||||
index 4aaf23d28f..3233c54d11 100644
|
||||
--- a/include/hw/ppc/spapr.h
|
||||
+++ b/include/hw/ppc/spapr.h
|
||||
@@ -154,6 +154,7 @@ struct SpaprMachineClass {
|
||||
@@ -157,6 +157,7 @@ struct SpaprMachineClass {
|
||||
bool pre_5_2_numa_associativity;
|
||||
bool pre_6_2_numa_affinity;
|
||||
|
||||
@ -386,7 +386,7 @@ index e91791a1a9..1951d8a2a0 100644
|
||||
bool (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
|
||||
uint64_t *buid, hwaddr *pio,
|
||||
hwaddr *mmio32, hwaddr *mmio64,
|
||||
@@ -256,6 +257,9 @@ struct SpaprMachineState {
|
||||
@@ -259,6 +260,9 @@ struct SpaprMachineState {
|
||||
/* Set by -boot */
|
||||
char *boot_device;
|
||||
|
||||
@ -422,10 +422,10 @@ index ebef2cccec..ff2c00c60e 100644
|
||||
const CompatInfo *compat = compat_by_pvr(compat_pvr);
|
||||
const CompatInfo *min = compat_by_pvr(min_compat_pvr);
|
||||
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
|
||||
index 69fddb05bc..64a05aaef3 100644
|
||||
index f77ebfcc81..18e9422006 100644
|
||||
--- a/target/ppc/cpu-models.c
|
||||
+++ b/target/ppc/cpu-models.c
|
||||
@@ -748,6 +748,7 @@
|
||||
@@ -744,6 +744,7 @@
|
||||
/* PowerPC CPU aliases */
|
||||
|
||||
PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
@ -434,10 +434,10 @@ index 69fddb05bc..64a05aaef3 100644
|
||||
{ "405cr", "405crc" },
|
||||
{ "405gp", "405gpd" },
|
||||
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
|
||||
index f8101ffa29..e799a2bee6 100644
|
||||
index 67e6b2effd..11187aeb93 100644
|
||||
--- a/target/ppc/cpu.h
|
||||
+++ b/target/ppc/cpu.h
|
||||
@@ -1635,6 +1635,7 @@ static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch)
|
||||
@@ -1655,6 +1655,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch)
|
||||
|
||||
/* Compatibility modes */
|
||||
#if defined(TARGET_PPC64)
|
||||
@ -446,7 +446,7 @@ index f8101ffa29..e799a2bee6 100644
|
||||
uint32_t min_compat_pvr, uint32_t max_compat_pvr);
|
||||
bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr,
|
||||
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
|
||||
index 9b1abe2fc4..56f1c46e8e 100644
|
||||
index 8231feb2d4..59f640cf7b 100644
|
||||
--- a/target/ppc/kvm.c
|
||||
+++ b/target/ppc/kvm.c
|
||||
@@ -89,6 +89,7 @@ static int cap_large_decr;
|
||||
@ -465,7 +465,7 @@ index 9b1abe2fc4..56f1c46e8e 100644
|
||||
cap_large_decr = kvmppc_get_dec_bits();
|
||||
cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI);
|
||||
/*
|
||||
@@ -2579,6 +2581,16 @@ bool kvmppc_supports_ail_3(void)
|
||||
@@ -2564,6 +2566,16 @@ bool kvmppc_supports_ail_3(void)
|
||||
return cap_ail_mode_3;
|
||||
}
|
||||
|
||||
@ -482,7 +482,7 @@ index 9b1abe2fc4..56f1c46e8e 100644
|
||||
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
|
||||
{
|
||||
uint32_t host_pvr = mfpvr();
|
||||
@@ -2979,3 +2991,18 @@ bool kvm_arch_cpu_check_are_resettable(void)
|
||||
@@ -2964,3 +2976,18 @@ bool kvm_arch_cpu_check_are_resettable(void)
|
||||
void kvm_arch_accel_class_init(ObjectClass *oc)
|
||||
{
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 3623043d4a923bf9f541d439c76e7874cf0fa81d Mon Sep 17 00:00:00 2001
|
||||
From 04178c77cfe188b4eed9c08a0bf66842e61fe5dc Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 19 Oct 2018 13:47:32 +0200
|
||||
Subject: Add s390x machine types
|
||||
@ -49,18 +49,18 @@ Merged patches (8.2.0):
|
||||
4 files changed, 174 insertions(+)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 7262725d2e..984891b82a 100644
|
||||
index b1dcb3857f..ff753a29e0 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -855,6 +855,7 @@ bool css_migration_enabled(void)
|
||||
@@ -859,6 +859,7 @@ bool css_migration_enabled(void)
|
||||
} \
|
||||
type_init(ccw_machine_register_##suffix)
|
||||
|
||||
+#if 0 /* Disabled for Red Hat Enterprise Linux */
|
||||
static void ccw_machine_8_2_instance_options(MachineState *machine)
|
||||
static void ccw_machine_9_0_instance_options(MachineState *machine)
|
||||
{
|
||||
}
|
||||
@@ -1256,6 +1257,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
|
||||
@@ -1272,6 +1273,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc)
|
||||
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
|
||||
}
|
||||
DEFINE_CCW_MACHINE(2_4, "2.4", false);
|
||||
@ -226,7 +226,7 @@ index 7262725d2e..984891b82a 100644
|
||||
static void ccw_machine_register_types(void)
|
||||
{
|
||||
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
|
||||
index a63d990e4e..198b81f2c0 100644
|
||||
index 8ed3bb6a27..370b3b3065 100644
|
||||
--- a/target/s390x/cpu_models.c
|
||||
+++ b/target/s390x/cpu_models.c
|
||||
@@ -46,6 +46,9 @@
|
||||
@ -239,7 +239,7 @@ index a63d990e4e..198b81f2c0 100644
|
||||
static S390CPUDef s390_cpu_defs[] = {
|
||||
CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"),
|
||||
CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"),
|
||||
@@ -856,22 +859,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
|
||||
@@ -866,22 +869,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data)
|
||||
static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
S390CPUClass *xcc = S390_CPU_CLASS(oc);
|
||||
@ -284,10 +284,10 @@ index d7b8912989..1a806a97c4 100644
|
||||
|
||||
/* CPU model based on a CPU definition */
|
||||
diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c
|
||||
index 87a4480c05..28c1b0486c 100644
|
||||
index 0728bfcc20..ca2e5d91e2 100644
|
||||
--- a/target/s390x/cpu_models_sysemu.c
|
||||
+++ b/target/s390x/cpu_models_sysemu.c
|
||||
@@ -60,6 +60,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
|
||||
@@ -59,6 +59,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
|
||||
CpuDefinitionInfo *info;
|
||||
char *name = g_strdup(object_class_get_name(klass));
|
||||
S390CPUClass *scc = S390_CPU_CLASS(klass);
|
||||
@ -295,7 +295,7 @@ index 87a4480c05..28c1b0486c 100644
|
||||
|
||||
/* strip off the -s390x-cpu */
|
||||
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
|
||||
@@ -69,6 +70,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
|
||||
@@ -68,6 +69,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
|
||||
info->migration_safe = scc->is_migration_safe;
|
||||
info->q_static = scc->is_static;
|
||||
info->q_typename = g_strdup(object_class_get_name(klass));
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b432505cb28bc3b9b0c1849210ac6c63bca3fe37 Mon Sep 17 00:00:00 2001
|
||||
From 3c88acb005806ad2386ab6c94a8831151f624738 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Fri, 19 Oct 2018 13:10:31 +0200
|
||||
Subject: Add x86_64 machine types
|
||||
@ -57,23 +57,40 @@ Merged patches (8.1.0):
|
||||
Merged patches (8.2.0):
|
||||
- 4ee284aca9 Add machine types compat bits. (partial)
|
||||
- 719e2ac147 Fix x86 machine type compatibility for qemu-kvm 8.1.0
|
||||
|
||||
Merged patches (9.0.0 rc0):
|
||||
- 9149e2bc8f x86: rhel 9.2.0 machine type compat fix
|
||||
---
|
||||
hw/i386/fw_cfg.c | 2 +-
|
||||
hw/i386/pc.c | 159 ++++++++++++++++++++-
|
||||
hw/i386/pc_piix.c | 112 ++++++++++++++-
|
||||
hw/i386/pc_q35.c | 285 ++++++++++++++++++++++++++++++++++++-
|
||||
hw/i386/pc_piix.c | 109 ++++++++++++++
|
||||
hw/i386/pc_q35.c | 285 +++++++++++++++++++++++++++++++++++++
|
||||
include/hw/boards.h | 2 +
|
||||
include/hw/i386/pc.h | 33 +++++
|
||||
target/i386/cpu.c | 21 +++
|
||||
target/i386/kvm/kvm-cpu.c | 1 +
|
||||
target/i386/kvm/kvm.c | 4 +
|
||||
tests/qtest/pvpanic-test.c | 5 +-
|
||||
9 files changed, 615 insertions(+), 7 deletions(-)
|
||||
10 files changed, 617 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index c7aa39a13e..283c3f4c16 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
|
||||
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_uuid_encoded,
|
||||
pcmc->smbios_stream_product, pcmc->smbios_stream_version);
|
||||
}
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 29b9964733..a1faa9e92c 100644
|
||||
index 5c21b0c4db..4a154c1a9a 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -323,6 +323,161 @@ GlobalProperty pc_compat_2_0[] = {
|
||||
@@ -326,6 +326,161 @@ GlobalProperty pc_compat_2_0[] = {
|
||||
};
|
||||
const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0);
|
||||
|
||||
@ -235,15 +252,15 @@ index 29b9964733..a1faa9e92c 100644
|
||||
GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled)
|
||||
{
|
||||
GSIState *s;
|
||||
@@ -1826,6 +1981,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
pcmc->kvmclock_create_always = true;
|
||||
@@ -1813,6 +1968,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
pcmc->resizable_acpi_blob = 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->cpu_index_to_instance_props = x86_cpu_index_to_props;
|
||||
@@ -1836,7 +1992,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
@@ -1823,7 +1979,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->has_hotpluggable_cpus = true;
|
||||
mc->default_boot_order = "cad";
|
||||
mc->block_default_type = IF_IDE;
|
||||
@ -254,10 +271,10 @@ index 29b9964733..a1faa9e92c 100644
|
||||
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 2a9f465619..44038391fb 100644
|
||||
index 18ba076609..a647262d63 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -53,6 +53,7 @@
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/xen.h"
|
||||
@ -265,18 +282,7 @@ index 2a9f465619..44038391fb 100644
|
||||
#ifdef CONFIG_XEN
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
#include "hw/xen/xen_pt.h"
|
||||
@@ -235,8 +236,8 @@ static void pc_init1(MachineState *machine,
|
||||
if (pcmc->smbios_defaults) {
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
/* These values are guest ABI, do not change */
|
||||
- smbios_set_defaults("QEMU", mc->desc,
|
||||
- mc->name, pcmc->smbios_legacy_mode,
|
||||
+ smbios_set_defaults("Red Hat", "KVM",
|
||||
+ mc->desc, pcmc->smbios_legacy_mode,
|
||||
pcmc->smbios_uuid_encoded,
|
||||
pcmc->smbios_stream_product,
|
||||
pcmc->smbios_stream_version,
|
||||
@@ -453,6 +454,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp)
|
||||
@@ -422,6 +423,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp)
|
||||
* hw_compat_*, pc_compat_*, or * pc_*_machine_options().
|
||||
*/
|
||||
|
||||
@ -284,7 +290,7 @@ index 2a9f465619..44038391fb 100644
|
||||
static void pc_compat_2_3_fn(MachineState *machine)
|
||||
{
|
||||
X86MachineState *x86ms = X86_MACHINE(machine);
|
||||
@@ -970,3 +972,109 @@ static void xenfv_3_1_machine_options(MachineClass *m)
|
||||
@@ -951,3 +953,110 @@ static void xenfv_3_1_machine_options(MachineClass *m)
|
||||
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
|
||||
xenfv_3_1_machine_options);
|
||||
#endif
|
||||
@ -314,8 +320,7 @@ index 2a9f465619..44038391fb 100644
|
||||
+
|
||||
+static void pc_init_rhel760(MachineState *machine)
|
||||
+{
|
||||
+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
|
||||
+ TYPE_I440FX_PCI_DEVICE);
|
||||
+ pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
|
||||
+}
|
||||
+
|
||||
+static void pc_machine_rhel760_options(MachineClass *m)
|
||||
@ -339,6 +344,8 @@ index 2a9f465619..44038391fb 100644
|
||||
+ pcmc->enforce_amd_1tb_hole = false;
|
||||
+ /* From pc_i440fx_8_0_machine_options() */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||
+ /* From pc_i440fx_8_1_machine_options() */
|
||||
+ pcmc->broken_32bit_mem_addr_check = true;
|
||||
+ /* Introduced in QEMU 8.2 */
|
||||
+ pcmc->default_south_bridge = TYPE_PIIX3_DEVICE;
|
||||
+
|
||||
@ -395,21 +402,10 @@ index 2a9f465619..44038391fb 100644
|
||||
+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760,
|
||||
+ pc_machine_rhel760_options);
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index 912cb0c0dc..6387df97c8 100644
|
||||
index c7bc8a2041..e872dc7e46 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -203,8 +203,8 @@ static void pc_q35_init(MachineState *machine)
|
||||
|
||||
if (pcmc->smbios_defaults) {
|
||||
/* These values are guest ABI, do not change */
|
||||
- smbios_set_defaults("QEMU", mc->desc,
|
||||
- mc->name, pcmc->smbios_legacy_mode,
|
||||
+ smbios_set_defaults("Red Hat", "KVM",
|
||||
+ mc->desc, pcmc->smbios_legacy_mode,
|
||||
pcmc->smbios_uuid_encoded,
|
||||
pcmc->smbios_stream_product,
|
||||
pcmc->smbios_stream_version,
|
||||
@@ -363,6 +363,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
@@ -341,6 +341,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
|
||||
|
||||
|
||||
@ -417,7 +413,7 @@ index 912cb0c0dc..6387df97c8 100644
|
||||
static void pc_q35_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
@@ -699,3 +700,283 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
|
||||
@@ -693,3 +694,287 @@ static void pc_q35_2_4_machine_options(MachineClass *m)
|
||||
|
||||
DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL,
|
||||
pc_q35_2_4_machine_options);
|
||||
@ -444,6 +440,8 @@ index 912cb0c0dc..6387df97c8 100644
|
||||
+ m->alias = "q35";
|
||||
+ m->max_cpus = 710;
|
||||
+ compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
|
||||
+ compat_props_add(m->compat_props,
|
||||
+ pc_q35_compat_defaults, pc_q35_compat_defaults_len);
|
||||
+}
|
||||
+
|
||||
+static void pc_q35_init_rhel940(MachineState *machine)
|
||||
@ -480,6 +478,8 @@ index 912cb0c0dc..6387df97c8 100644
|
||||
+
|
||||
+ /* 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);
|
||||
@ -702,10 +702,10 @@ index 912cb0c0dc..6387df97c8 100644
|
||||
+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760,
|
||||
+ pc_q35_machine_rhel760_options);
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 4a21eddbf9..4edfdb0ddb 100644
|
||||
index 0466f9d0f3..46b8725c41 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -277,6 +277,8 @@ struct MachineClass {
|
||||
@@ -283,6 +283,8 @@ struct MachineClass {
|
||||
strList *allowed_dynamic_sysbus_devices;
|
||||
bool auto_enable_numa_with_memhp;
|
||||
bool auto_enable_numa_with_memdev;
|
||||
@ -715,12 +715,12 @@ index 4a21eddbf9..4edfdb0ddb 100644
|
||||
bool smbus_no_migration_support;
|
||||
bool nvdimm_supported;
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index 037942d233..37644ede7e 100644
|
||||
index ebd8f973f2..a984c951ad 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -314,6 +314,39 @@ extern const size_t pc_compat_1_4_len;
|
||||
|
||||
int pc_machine_kvm_type(MachineState *machine, const char *vm_type);
|
||||
@@ -291,6 +291,39 @@ extern const size_t pc_compat_2_1_len;
|
||||
extern GlobalProperty pc_compat_2_0[];
|
||||
extern const size_t pc_compat_2_0_len;
|
||||
|
||||
+extern GlobalProperty pc_rhel_compat[];
|
||||
+extern const size_t pc_rhel_compat_len;
|
||||
@ -759,7 +759,7 @@ index 037942d233..37644ede7e 100644
|
||||
static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
|
||||
{ \
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index cd16cb893d..93203d9b91 100644
|
||||
index 33760a2ee1..be7b0663cd 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -2190,9 +2190,13 @@ static const CPUCaches epyc_genoa_cache_info = {
|
||||
@ -925,10 +925,10 @@ index 9c791b7b05..b91af5051f 100644
|
||||
};
|
||||
|
||||
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
|
||||
index 4ce80555b4..9d41edf01e 100644
|
||||
index e68cbe9293..739f33db47 100644
|
||||
--- a/target/i386/kvm/kvm.c
|
||||
+++ b/target/i386/kvm/kvm.c
|
||||
@@ -3711,6 +3711,7 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
@@ -3715,6 +3715,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;
|
||||
@ -936,7 +936,7 @@ index 4ce80555b4..9d41edf01e 100644
|
||||
|
||||
kvm_msr_buf_reset(cpu);
|
||||
|
||||
@@ -4065,6 +4066,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
@@ -4069,6 +4070,9 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||
break;
|
||||
case MSR_KVM_ASYNC_PF_EN:
|
||||
env->async_pf_en_msr = msrs[i].data;
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 66a0510405e5142a1f9e38e0770aa0f10aed3e03 Mon Sep 17 00:00:00 2001
|
||||
From 5768cf6811842e5c59da3b752f60659a9d6b5ba1 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 2 Sep 2020 09:39:41 +0200
|
||||
Subject: Enable make check
|
||||
@ -63,10 +63,10 @@ Merged patches (8.1.0):
|
||||
13 files changed, 33 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py
|
||||
index c37afa662c..61c95a2198 100644
|
||||
index 10d99403a4..c3422ea1e4 100644
|
||||
--- a/tests/avocado/replay_kernel.py
|
||||
+++ b/tests/avocado/replay_kernel.py
|
||||
@@ -153,7 +153,7 @@ def test_aarch64_virt(self):
|
||||
@@ -166,7 +166,7 @@ def test_aarch64_virt(self):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:virt
|
||||
@ -76,7 +76,7 @@ index c37afa662c..61c95a2198 100644
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
|
||||
'/linux/releases/29/Everything/aarch64/os/images/pxeboot'
|
||||
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
|
||||
index 4cce5a5598..e9248a04a2 100644
|
||||
index 92855a02a5..87822074b6 100644
|
||||
--- a/tests/avocado/reverse_debugging.py
|
||||
+++ b/tests/avocado/reverse_debugging.py
|
||||
@@ -230,7 +230,7 @@ def test_aarch64_virt(self):
|
||||
@ -120,7 +120,7 @@ index 15fd87b2c1..f0d9d89c93 100644
|
||||
kernel_path = self._grab_aarch64_kernel()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
|
||||
index 53847cb98f..a2abdb650e 100644
|
||||
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
|
||||
@ -163,7 +163,7 @@ index 53847cb98f..a2abdb650e 100644
|
||||
+# endforeach
|
||||
endforeach
|
||||
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
|
||||
index 3ff38f2661..cab9a2bd6c 100644
|
||||
index 588f30a4f1..3929a3634f 100644
|
||||
--- a/tests/qemu-iotests/testenv.py
|
||||
+++ b/tests/qemu-iotests/testenv.py
|
||||
@@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str,
|
||||
@ -216,7 +216,7 @@ index 663bb6c485..2efc43e3f7 100644
|
||||
"-device intel-hda,id=" HDA_ID CODEC_DEVICES);
|
||||
|
||||
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
|
||||
index 90aae42a22..9bc4e41af0 100644
|
||||
index 3aed6efcb8..119613237e 100644
|
||||
--- a/tests/qtest/libqos/meson.build
|
||||
+++ b/tests/qtest/libqos/meson.build
|
||||
@@ -44,7 +44,7 @@ libqos_srcs = files(
|
||||
@ -242,10 +242,10 @@ index 8ac95b89f7..cd2102555c 100644
|
||||
|
||||
qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */
|
||||
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
|
||||
index 47dabf91d0..0bdfa3a821 100644
|
||||
index 36c5c13a7b..a2887d6057 100644
|
||||
--- a/tests/qtest/meson.build
|
||||
+++ b/tests/qtest/meson.build
|
||||
@@ -97,7 +97,6 @@ qtests_i386 = \
|
||||
@@ -101,7 +101,6 @@ qtests_i386 = \
|
||||
'drive_del-test',
|
||||
'tco-test',
|
||||
'cpu-plug-test',
|
||||
@ -254,7 +254,7 @@ index 47dabf91d0..0bdfa3a821 100644
|
||||
'migration-test',
|
||||
'test-x86-cpuid-compat',
|
||||
diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c
|
||||
index 0d40bc1f2d..4c633c1584 100644
|
||||
index 73dfabc272..a9dd304781 100644
|
||||
--- a/tests/qtest/virtio-net-failover.c
|
||||
+++ b/tests/qtest/virtio-net-failover.c
|
||||
@@ -26,6 +26,7 @@
|
||||
|
@ -1,4 +1,4 @@
|
||||
From a27cfa0b407bd806ce389a7c69d0130bcfd35244 Mon Sep 17 00:00:00 2001
|
||||
From e06a905d726fc20ea6bd95dff1bd0ffe97ebb202 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
|
||||
@ -27,7 +27,7 @@ to 64 as some usecases require more than 32 devices.
|
||||
|
||||
Signed-off-by: Bandan Das <bsd@redhat.com>
|
||||
|
||||
Rebase changes (231025):
|
||||
Rebase changes (8.2.0):
|
||||
- Update to upstream changes
|
||||
---
|
||||
hw/vfio/pci.c | 31 ++++++++++++++++++++++++++++++-
|
||||
@ -35,10 +35,10 @@ Rebase changes (231025):
|
||||
2 files changed, 31 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index c62c02f7b6..ec98080f28 100644
|
||||
index 64780d1b79..57ac63c10c 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -48,6 +48,9 @@
|
||||
@@ -50,6 +50,9 @@
|
||||
/* Protected by BQL */
|
||||
static KVMRouteChange vfio_route_change;
|
||||
|
||||
@ -48,15 +48,14 @@ index c62c02f7b6..ec98080f28 100644
|
||||
static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
|
||||
static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
|
||||
static void vfio_msi_disable_common(VFIOPCIDevice *vdev);
|
||||
@@ -3076,14 +3079,37 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
|
||||
{
|
||||
@@ -2946,13 +2949,36 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
|
||||
ERRP_GUARD();
|
||||
VFIOPCIDevice *vdev = VFIO_PCI(pdev);
|
||||
VFIODevice *vbasedev = &vdev->vbasedev;
|
||||
+ VFIODevice *vbasedev_iter;
|
||||
+ VFIOGroup *group;
|
||||
char *tmp, *subsys;
|
||||
Error *err = NULL;
|
||||
struct stat st;
|
||||
- int i, ret;
|
||||
+ int ret, i = 0;
|
||||
bool is_mdev;
|
||||
@ -84,10 +83,10 @@ index c62c02f7b6..ec98080f28 100644
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!vbasedev->sysfsdev) {
|
||||
if (vbasedev->fd < 0 && !vbasedev->sysfsdev) {
|
||||
if (!(~vdev->host.domain || ~vdev->host.bus ||
|
||||
~vdev->host.slot || ~vdev->host.function)) {
|
||||
@@ -3501,6 +3527,9 @@ static Property vfio_pci_dev_properties[] = {
|
||||
@@ -3370,6 +3396,9 @@ static 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),
|
||||
@ -98,7 +97,7 @@ index c62c02f7b6..ec98080f28 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 fba8737ab2..eb74d9de2d 100644
|
||||
index 6e64a2654e..b7de39c010 100644
|
||||
--- a/hw/vfio/pci.h
|
||||
+++ b/hw/vfio/pci.h
|
||||
@@ -142,6 +142,7 @@ struct VFIOPCIDevice {
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 424f14d123fe1043518758605d94ed5ba50e52ad Mon Sep 17 00:00:00 2001
|
||||
From b467dc6a24ef41fa574260429807711f6802a54d 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
|
||||
@ -21,10 +21,10 @@ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/system/vl.c b/system/vl.c
|
||||
index 2bcd9efb9a..93635ffc5b 100644
|
||||
index c644222982..03c3b0aa94 100644
|
||||
--- a/system/vl.c
|
||||
+++ b/system/vl.c
|
||||
@@ -870,9 +870,17 @@ static void version(void)
|
||||
@@ -869,9 +869,17 @@ static void version(void)
|
||||
QEMU_COPYRIGHT "\n");
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ index 2bcd9efb9a..93635ffc5b 100644
|
||||
printf("usage: %s [options] [disk_image]\n\n"
|
||||
"'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
|
||||
g_get_prgname());
|
||||
@@ -898,6 +906,7 @@ static void help(int exitcode)
|
||||
@@ -897,6 +905,7 @@ static void help(int exitcode)
|
||||
"\n"
|
||||
QEMU_HELP_BOTTOM "\n");
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From c683ff4a770b77dbe707413840918a46f67fa825 Mon Sep 17 00:00:00 2001
|
||||
From 20cc3a6d9bce3e40d165f865b5e398c300cae7bf Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 8 Jul 2020 08:35:50 +0200
|
||||
Subject: Use qemu-kvm in documentation instead of qemu-system-<arch>
|
||||
@ -36,10 +36,10 @@ index 52d6454b93..d74dbdeca9 100644
|
||||
.. |I2C| replace:: I\ :sup:`2`\ C
|
||||
.. |I2S| replace:: I\ :sup:`2`\ S
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 42fd09e4de..557118cb1f 100644
|
||||
index 8ce85d4559..4fc27ee2e2 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -3469,11 +3469,11 @@ SRST
|
||||
@@ -3493,11 +3493,11 @@ SRST
|
||||
|
||||
::
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 776bff1be5e98982a9bbc8345ff27274ff5b8c0f Mon Sep 17 00:00:00 2001
|
||||
From 2f9fdd21ecf2810d0d83a8125ce0cc1e75dbb13a Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Fri, 20 Aug 2021 18:25:12 +0200
|
||||
Subject: qcow2: Deprecation warning when opening v2 images rw
|
||||
@ -44,7 +44,7 @@ Rebase notes (6.1.0):
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/block/qcow2.c b/block/qcow2.c
|
||||
index 13e032bd5e..7968735346 100644
|
||||
index 956128b409..0e8b2f7518 100644
|
||||
--- a/block/qcow2.c
|
||||
+++ b/block/qcow2.c
|
||||
@@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
121
0016-Add-upstream-compatibility-bits.patch
Normal file
121
0016-Add-upstream-compatibility-bits.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 59470e8ab849f22b407f55292e540e16a8cad01a Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Wed, 20 Mar 2024 05:34:32 -0400
|
||||
Subject: Add upstream compatibility bits
|
||||
|
||||
Adding new compats structure for changes introduced during rebase to QEMU 9.0.0.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
|
||||
---
|
||||
|
||||
Rebase notes (9.0.0 rc2):
|
||||
- Add aw-bits setting for aarch compat record (overwritten for 9.4 and older)
|
||||
---
|
||||
hw/arm/virt.c | 3 +++
|
||||
hw/core/machine.c | 10 ++++++++++
|
||||
hw/i386/pc_piix.c | 3 ++-
|
||||
hw/i386/pc_q35.c | 3 +++
|
||||
hw/s390x/s390-virtio-ccw.c | 1 +
|
||||
include/hw/boards.h | 3 +++
|
||||
6 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 22bc345137..f1af9495c6 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -144,6 +144,8 @@ GlobalProperty arm_rhel_compat[] = {
|
||||
{"virtio-net-pci", "romfile", "" },
|
||||
{"virtio-net-pci-transitional", "romfile", "" },
|
||||
{"virtio-net-pci-non-transitional", "romfile", "" },
|
||||
+ /* arm_rhel_compat from arm_virt_compat, added for 9.0.0 rebase */
|
||||
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
|
||||
};
|
||||
const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
|
||||
|
||||
@@ -3728,6 +3730,7 @@ type_init(rhel_machine_init);
|
||||
|
||||
static void rhel940_virt_options(MachineClass *mc)
|
||||
{
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
|
||||
}
|
||||
DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
|
||||
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 695cb89a46..0f256d9633 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -302,6 +302,16 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
|
||||
const char *rhel_old_machine_deprecation =
|
||||
"machine types for previous major releases are deprecated";
|
||||
|
||||
+GlobalProperty hw_compat_rhel_9_5[] = {
|
||||
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
|
||||
+ { "migration", "zero-page-detection", "legacy"},
|
||||
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
|
||||
+ { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
|
||||
+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */
|
||||
+ { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
|
||||
+};
|
||||
+const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5);
|
||||
+
|
||||
GlobalProperty hw_compat_rhel_9_4[] = {
|
||||
/* hw_compat_rhel_9_4 from hw_compat_8_0 */
|
||||
{ TYPE_VIRTIO_NET, "host_uso", "off"},
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index a647262d63..6b260682eb 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -1015,7 +1015,8 @@ static void pc_machine_rhel760_options(MachineClass *m)
|
||||
object_class_property_set_description(oc, "x-south-bridge",
|
||||
"Use a different south bridge than PIIX3");
|
||||
|
||||
-
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
|
||||
+ hw_compat_rhel_9_5_len);
|
||||
compat_props_add(m->compat_props, hw_compat_rhel_9_4,
|
||||
hw_compat_rhel_9_4_len);
|
||||
compat_props_add(m->compat_props, hw_compat_rhel_9_3,
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index e872dc7e46..2b54944c0f 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -733,6 +733,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
|
||||
m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)";
|
||||
pcmc->smbios_stream_product = "RHEL";
|
||||
pcmc->smbios_stream_version = "9.4.0";
|
||||
+
|
||||
+ compat_props_add(m->compat_props, hw_compat_rhel_9_5,
|
||||
+ hw_compat_rhel_9_5_len);
|
||||
}
|
||||
|
||||
DEFINE_PC_MACHINE(q35_rhel940, "pc-q35-rhel9.4.0", pc_q35_init_rhel940,
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index ff753a29e0..9ad54682c6 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -1282,6 +1282,7 @@ static void ccw_machine_rhel940_instance_options(MachineState *machine)
|
||||
|
||||
static void ccw_machine_rhel940_class_options(MachineClass *mc)
|
||||
{
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len);
|
||||
}
|
||||
DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true);
|
||||
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 46b8725c41..cca62f906b 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -514,6 +514,9 @@ extern const size_t hw_compat_2_2_len;
|
||||
extern GlobalProperty hw_compat_2_1[];
|
||||
extern const size_t hw_compat_2_1_len;
|
||||
|
||||
+extern GlobalProperty hw_compat_rhel_9_5[];
|
||||
+extern const size_t hw_compat_rhel_9_5_len;
|
||||
+
|
||||
extern GlobalProperty hw_compat_rhel_9_4[];
|
||||
extern const size_t hw_compat_rhel_9_4_len;
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 3b9b38339346ebfaf3e8ddf0822eba1cc9e78408 Mon Sep 17 00:00:00 2001
|
||||
From: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
Date: Thu, 14 Dec 2023 04:42:01 -0500
|
||||
Subject: Introduce RHEL 9.4.0 qemu-kvm machine type for aarch64
|
||||
|
||||
Jira: https://issues.redhat.com/browse/RHEL-17168
|
||||
|
||||
Adding new machine type to support enabling new features.
|
||||
|
||||
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index c541efee5e..0b17c94ad7 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3630,14 +3630,21 @@ static void rhel_machine_init(void)
|
||||
}
|
||||
type_init(rhel_machine_init);
|
||||
|
||||
+static void rhel940_virt_options(MachineClass *mc)
|
||||
+{
|
||||
+}
|
||||
+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0)
|
||||
+
|
||||
static void rhel920_virt_options(MachineClass *mc)
|
||||
{
|
||||
+ rhel940_virt_options(mc);
|
||||
+
|
||||
compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len);
|
||||
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);
|
||||
}
|
||||
-DEFINE_RHEL_MACHINE_AS_LATEST(9, 2, 0)
|
||||
+DEFINE_RHEL_MACHINE(9, 2, 0)
|
||||
|
||||
static void rhel900_virt_options(MachineClass *mc)
|
||||
{
|
||||
--
|
||||
2.39.3
|
||||
|
30
0017-x86-rhel-9.4.0-machine-type-compat-fix.patch
Normal file
30
0017-x86-rhel-9.4.0-machine-type-compat-fix.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From ba574acacf679850e337ec2d5e7836b8277cf393 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Ott <sebott@redhat.com>
|
||||
Date: Thu, 18 Apr 2024 15:04:28 +0200
|
||||
Subject: x86: rhel 9.4.0 machine type compat fix
|
||||
|
||||
Fix up the compatibility for 9.4.0. Ensure that pc-q35-rhel9.4.0
|
||||
still uses SMBIOS 3.X by default.
|
||||
|
||||
Signed-off-by: Sebastian Ott <sebott@redhat.com>
|
||||
---
|
||||
hw/i386/pc_q35.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index 2b54944c0f..2f11f9af7d 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -734,6 +734,9 @@ static void pc_q35_machine_rhel940_options(MachineClass *m)
|
||||
pcmc->smbios_stream_product = "RHEL";
|
||||
pcmc->smbios_stream_version = "9.4.0";
|
||||
|
||||
+ /* From pc_q35_8_2_machine_options() - use SMBIOS 3.X by default */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
|
||||
+
|
||||
compat_props_add(m->compat_props, hw_compat_rhel_9_5,
|
||||
hw_compat_rhel_9_5_len);
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From 363d6aedc82314a70bdfbe9fa23b7e8fdda50138 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 12:26:19 -0500
|
||||
Subject: [PATCH 066/101] Compile IOMMUFD object on aarch64
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [65/67] 9358030fdd499c5fe122dee3bb4f114966fac9c2 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Upstream: RHEL only
|
||||
|
||||
Compiles the IOMMUFD object on aarch64 to be able to use
|
||||
the IOMMUFD VFIO backend.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
configs/devices/aarch64-softmmu/aarch64-rh-devices.mak | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
index aec1831199..b0191d3c69 100644
|
||||
--- a/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
+++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak
|
||||
@@ -39,3 +39,4 @@ CONFIG_PXB=y
|
||||
CONFIG_VHOST_VSOCK=y
|
||||
CONFIG_VHOST_USER_VSOCK=y
|
||||
CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From c1e9ddf8d0ea6d358fcaa5cacd3a91920f36e73b Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 12:33:17 -0500
|
||||
Subject: [PATCH 067/101] Compile IOMMUFD on s390x
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [66/67] d3004aafca2bb76d817ac99c3d65973b8fbd4557 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Upstream: RHEL only
|
||||
|
||||
Compiles the IOMMUFD object on s390x to be able to use
|
||||
the IOMMUFD VFIO backend.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
configs/devices/s390x-softmmu/s390x-rh-devices.mak | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
index 69a799adbd..24cf6dbd03 100644
|
||||
--- a/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
@@ -16,3 +16,4 @@ CONFIG_WDT_DIAG288=y
|
||||
CONFIG_VHOST_VSOCK=y
|
||||
CONFIG_VHOST_USER_VSOCK=y
|
||||
CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From be2c3d9bbee1bdec061c901f507bc999fa40a53e Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Thu, 11 Jan 2024 12:34:44 -0500
|
||||
Subject: [PATCH 068/101] Compile IOMMUFD on x86_64
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [67/67] 411d48a5cc7ce1f05be793fd9a89c143ce34c91a (eauger1/centos-qemu-kvm)
|
||||
|
||||
Upstream: RHEL only
|
||||
|
||||
Compiles the IOMMUFD object on s390x to be able to use
|
||||
the IOMMUFD VFIO backend.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
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 ce5be73633..ba41108e0c 100644
|
||||
--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
+++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak
|
||||
@@ -108,3 +108,4 @@ CONFIG_SGX=y
|
||||
CONFIG_VHOST_VSOCK=y
|
||||
CONFIG_VHOST_USER_VSOCK=y
|
||||
CONFIG_VHOST_USER_FS=y
|
||||
+CONFIG_IOMMUFD=y
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,155 +0,0 @@
|
||||
From 5c639f8ce65183ce8e44ee8e0230e9d627a440d7 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Wed, 21 Feb 2024 17:00:27 +0000
|
||||
Subject: [PATCH 05/20] Implement SMBIOS type 9 v2.6
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [3/18] ead230527d93938907a561cf5b985ee4f54d82b1
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
Author: Felix Wu <flwu@google.com>
|
||||
|
||||
Signed-off-by: Felix Wu <flwu@google.com>
|
||||
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
|
||||
Message-Id: <20240221170027.1027325-3-nabihestefan@google.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
(cherry picked from commit 04f143d828845d0fd52dd4a52664d81a4f5431f7)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 49 +++++++++++++++++++++++++++++++++---
|
||||
include/hw/firmware/smbios.h | 4 +++
|
||||
qemu-options.hx | 2 +-
|
||||
3 files changed, 51 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 4f5637d445..074705fa4c 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -124,7 +124,7 @@ static QTAILQ_HEAD(, type8_instance) type8 = QTAILQ_HEAD_INITIALIZER(type8);
|
||||
|
||||
/* type 9 instance for parsing */
|
||||
struct type9_instance {
|
||||
- const char *slot_designation;
|
||||
+ const char *slot_designation, *pcidev;
|
||||
uint8_t slot_type, slot_data_bus_width, current_usage, slot_length,
|
||||
slot_characteristics1, slot_characteristics2;
|
||||
uint16_t slot_id;
|
||||
@@ -427,6 +427,11 @@ static const QemuOptDesc qemu_smbios_type9_opts[] = {
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "slot characteristics2, see the spec",
|
||||
},
|
||||
+ {
|
||||
+ .name = "pci_device",
|
||||
+ .type = QEMU_OPT_STRING,
|
||||
+ .help = "PCI device, if provided."
|
||||
+ }
|
||||
};
|
||||
|
||||
static const QemuOptDesc qemu_smbios_type11_opts[] = {
|
||||
@@ -851,7 +856,7 @@ static void smbios_build_type_8_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static void smbios_build_type_9_table(void)
|
||||
+static void smbios_build_type_9_table(Error **errp)
|
||||
{
|
||||
unsigned instance = 0;
|
||||
struct type9_instance *t9;
|
||||
@@ -868,6 +873,43 @@ static void smbios_build_type_9_table(void)
|
||||
t->slot_characteristics1 = t9->slot_characteristics1;
|
||||
t->slot_characteristics2 = t9->slot_characteristics2;
|
||||
|
||||
+ if (t9->pcidev) {
|
||||
+ PCIDevice *pdev = NULL;
|
||||
+ int rc = pci_qdev_find_device(t9->pcidev, &pdev);
|
||||
+ if (rc != 0) {
|
||||
+ error_setg(errp,
|
||||
+ "No PCI device %s for SMBIOS type 9 entry %s",
|
||||
+ t9->pcidev, t9->slot_designation);
|
||||
+ return;
|
||||
+ }
|
||||
+ /*
|
||||
+ * We only handle the case were the device is attached to
|
||||
+ * the PCI root bus. The general case is more complex as
|
||||
+ * bridges are enumerated later and the table would need
|
||||
+ * to be updated at this moment.
|
||||
+ */
|
||||
+ if (!pci_bus_is_root(pci_get_bus(pdev))) {
|
||||
+ error_setg(errp,
|
||||
+ "Cannot create type 9 entry for PCI device %s: "
|
||||
+ "not attached to the root bus",
|
||||
+ t9->pcidev);
|
||||
+ return;
|
||||
+ }
|
||||
+ t->segment_group_number = cpu_to_le16(0);
|
||||
+ t->bus_number = pci_dev_bus_num(pdev);
|
||||
+ t->device_number = pdev->devfn;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Per SMBIOS spec, For slots that are not of the PCI, AGP, PCI-X,
|
||||
+ * or PCI-Express type that do not have bus/device/function
|
||||
+ * information, 0FFh should be populated in the fields of Segment
|
||||
+ * Group Number, Bus Number, Device/Function Number.
|
||||
+ */
|
||||
+ t->segment_group_number = 0xff;
|
||||
+ t->bus_number = 0xff;
|
||||
+ t->device_number = 0xff;
|
||||
+ }
|
||||
+
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
instance++;
|
||||
}
|
||||
@@ -1222,7 +1264,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
}
|
||||
|
||||
smbios_build_type_8_table();
|
||||
- smbios_build_type_9_table();
|
||||
+ smbios_build_type_9_table(errp);
|
||||
smbios_build_type_11_table();
|
||||
|
||||
#define MAX_DIMM_SZ (16 * GiB)
|
||||
@@ -1568,6 +1610,7 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
t->slot_id = qemu_opt_get_number(opts, "slot_id", 0);
|
||||
t->slot_characteristics1 = qemu_opt_get_number(opts, "slot_characteristics1", 0);
|
||||
t->slot_characteristics2 = qemu_opt_get_number(opts, "slot_characteristics2", 0);
|
||||
+ save_opt(&t->pcidev, opts, "pcidev");
|
||||
QTAILQ_INSERT_TAIL(&type9, t, next);
|
||||
return;
|
||||
}
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 6bbd5a4c20..f8dd07fe4c 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -222,6 +222,10 @@ struct smbios_type_9 {
|
||||
uint16_t slot_id;
|
||||
uint8_t slot_characteristics1;
|
||||
uint8_t slot_characteristics2;
|
||||
+ /* SMBIOS spec v2.6+ */
|
||||
+ uint16_t segment_group_number;
|
||||
+ uint8_t bus_number;
|
||||
+ uint8_t device_number;
|
||||
} QEMU_PACKED;
|
||||
|
||||
/* SMBIOS type 11 - OEM strings */
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 94cacc2c63..93364e1765 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -2710,7 +2710,7 @@ SRST
|
||||
``-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-id=%d]``
|
||||
Specify SMBIOS type 4 fields
|
||||
|
||||
-``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d]``
|
||||
+``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d][,pci_device=str]``
|
||||
Specify SMBIOS type 9 fields
|
||||
|
||||
``-smbios type=11[,value=str][,path=filename]``
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,218 +0,0 @@
|
||||
From 84fc607d678bd72397a41d706e91fa241fd97266 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Wed, 21 Feb 2024 17:00:26 +0000
|
||||
Subject: [PATCH 04/20] Implement base of SMBIOS type 9 descriptor.
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [2/18] 2678cc080bfbf3357fa2f94ceaf42fc61b690d32
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
commit: 735eee07d1f963635d3c3bf9f5e4bf1bc000870e
|
||||
Author: Felix Wu <flwu@google.com>
|
||||
|
||||
Version 2.1+.
|
||||
|
||||
Signed-off-by: Felix Wu <flwu@google.com>
|
||||
Signed-off-by: Nabih Estefan <nabihestefan@google.com>
|
||||
Message-Id: <20240221170027.1027325-2-nabihestefan@google.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 99 ++++++++++++++++++++++++++++++++++++
|
||||
include/hw/firmware/smbios.h | 13 +++++
|
||||
qemu-options.hx | 3 ++
|
||||
3 files changed, 115 insertions(+)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 7bde23e59d..4f5637d445 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -122,6 +122,16 @@ struct type8_instance {
|
||||
};
|
||||
static QTAILQ_HEAD(, type8_instance) type8 = QTAILQ_HEAD_INITIALIZER(type8);
|
||||
|
||||
+/* type 9 instance for parsing */
|
||||
+struct type9_instance {
|
||||
+ const char *slot_designation;
|
||||
+ uint8_t slot_type, slot_data_bus_width, current_usage, slot_length,
|
||||
+ slot_characteristics1, slot_characteristics2;
|
||||
+ uint16_t slot_id;
|
||||
+ QTAILQ_ENTRY(type9_instance) next;
|
||||
+};
|
||||
+static QTAILQ_HEAD(, type9_instance) type9 = QTAILQ_HEAD_INITIALIZER(type9);
|
||||
+
|
||||
static struct {
|
||||
size_t nvalues;
|
||||
char **values;
|
||||
@@ -371,6 +381,54 @@ static const QemuOptDesc qemu_smbios_type8_opts[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static const QemuOptDesc qemu_smbios_type9_opts[] = {
|
||||
+ {
|
||||
+ .name = "type",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "SMBIOS element type",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_designation",
|
||||
+ .type = QEMU_OPT_STRING,
|
||||
+ .help = "string number for reference designation",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_type",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "connector type",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_data_bus_width",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "port type",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "current_usage",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "current usage",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_length",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "system slot length",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_id",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "system slot id",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_characteristics1",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "slot characteristics1, see the spec",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "slot_characteristics2",
|
||||
+ .type = QEMU_OPT_NUMBER,
|
||||
+ .help = "slot characteristics2, see the spec",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const QemuOptDesc qemu_smbios_type11_opts[] = {
|
||||
{
|
||||
.name = "value",
|
||||
@@ -594,6 +652,7 @@ bool smbios_skip_table(uint8_t type, bool required_table)
|
||||
#define T2_BASE 0x200
|
||||
#define T3_BASE 0x300
|
||||
#define T4_BASE 0x400
|
||||
+#define T9_BASE 0x900
|
||||
#define T11_BASE 0xe00
|
||||
|
||||
#define T16_BASE 0x1000
|
||||
@@ -792,6 +851,28 @@ static void smbios_build_type_8_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
+static void smbios_build_type_9_table(void)
|
||||
+{
|
||||
+ unsigned instance = 0;
|
||||
+ struct type9_instance *t9;
|
||||
+
|
||||
+ QTAILQ_FOREACH(t9, &type9, next) {
|
||||
+ SMBIOS_BUILD_TABLE_PRE(9, T9_BASE + instance, true);
|
||||
+
|
||||
+ SMBIOS_TABLE_SET_STR(9, slot_designation, t9->slot_designation);
|
||||
+ t->slot_type = t9->slot_type;
|
||||
+ t->slot_data_bus_width = t9->slot_data_bus_width;
|
||||
+ t->current_usage = t9->current_usage;
|
||||
+ t->slot_length = t9->slot_length;
|
||||
+ t->slot_id = t9->slot_id;
|
||||
+ t->slot_characteristics1 = t9->slot_characteristics1;
|
||||
+ t->slot_characteristics2 = t9->slot_characteristics2;
|
||||
+
|
||||
+ SMBIOS_BUILD_TABLE_POST;
|
||||
+ instance++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void smbios_build_type_11_table(void)
|
||||
{
|
||||
char count_str[128];
|
||||
@@ -1141,6 +1222,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
}
|
||||
|
||||
smbios_build_type_8_table();
|
||||
+ smbios_build_type_9_table();
|
||||
smbios_build_type_11_table();
|
||||
|
||||
#define MAX_DIMM_SZ (16 * GiB)
|
||||
@@ -1472,6 +1554,23 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
t8_i->port_type = qemu_opt_get_number(opts, "port_type", 0);
|
||||
QTAILQ_INSERT_TAIL(&type8, t8_i, next);
|
||||
return;
|
||||
+ case 9: {
|
||||
+ if (!qemu_opts_validate(opts, qemu_smbios_type9_opts, errp)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ struct type9_instance *t;
|
||||
+ t = g_new0(struct type9_instance, 1);
|
||||
+ save_opt(&t->slot_designation, opts, "slot_designation");
|
||||
+ t->slot_type = qemu_opt_get_number(opts, "slot_type", 0);
|
||||
+ t->slot_data_bus_width = qemu_opt_get_number(opts, "slot_data_bus_width", 0);
|
||||
+ t->current_usage = qemu_opt_get_number(opts, "current_usage", 0);
|
||||
+ t->slot_length = qemu_opt_get_number(opts, "slot_length", 0);
|
||||
+ t->slot_id = qemu_opt_get_number(opts, "slot_id", 0);
|
||||
+ t->slot_characteristics1 = qemu_opt_get_number(opts, "slot_characteristics1", 0);
|
||||
+ t->slot_characteristics2 = qemu_opt_get_number(opts, "slot_characteristics2", 0);
|
||||
+ QTAILQ_INSERT_TAIL(&type9, t, next);
|
||||
+ return;
|
||||
+ }
|
||||
case 11:
|
||||
if (!qemu_opts_validate(opts, qemu_smbios_type11_opts, errp)) {
|
||||
return;
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index d24b3ccd32..6bbd5a4c20 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -211,6 +211,19 @@ struct smbios_type_8 {
|
||||
uint8_t port_type;
|
||||
} QEMU_PACKED;
|
||||
|
||||
+/* SMBIOS type 9 - System Slots (v2.1+) */
|
||||
+struct smbios_type_9 {
|
||||
+ struct smbios_structure_header header;
|
||||
+ uint8_t slot_designation;
|
||||
+ uint8_t slot_type;
|
||||
+ uint8_t slot_data_bus_width;
|
||||
+ uint8_t current_usage;
|
||||
+ uint8_t slot_length;
|
||||
+ uint16_t slot_id;
|
||||
+ uint8_t slot_characteristics1;
|
||||
+ uint8_t slot_characteristics2;
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
/* SMBIOS type 11 - OEM strings */
|
||||
struct smbios_type_11 {
|
||||
struct smbios_structure_header header;
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 0814f43066..94cacc2c63 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -2710,6 +2710,9 @@ SRST
|
||||
``-smbios type=4[,sock_pfx=str][,manufacturer=str][,version=str][,serial=str][,asset=str][,part=str][,processor-id=%d]``
|
||||
Specify SMBIOS type 4 fields
|
||||
|
||||
+``-smbios type=9[,slot_designation=str][,slot_type=%d][,slot_data_bus_width=%d][,current_usage=%d][,slot_length=%d][,slot_id=%d][,slot_characteristics1=%d][,slot_characteristics12=%d]``
|
||||
+ Specify SMBIOS type 9 fields
|
||||
+
|
||||
``-smbios type=11[,value=str][,path=filename]``
|
||||
Specify SMBIOS type 11 fields
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 2e0e4355b2d4edb66b7d8c198339e17940abd682 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 13:03:19 +0000
|
||||
Subject: [PATCH 2/3] Revert "chardev/char-socket: Fix TLS io channels sending
|
||||
too much data to the backend"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs
|
||||
RH-Jira: RHEL-24614
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-Commit: [2/3] 1cb3d72b86ced0f70a09dfa0d325ae8a85db1b2b (berrange/centos-src-qemu)
|
||||
|
||||
This commit results in unexpected termination of the TLS connection.
|
||||
When 'fd_can_read' returns 0, the code goes on to pass a zero length
|
||||
buffer to qio_channel_read. The TLS impl calls into gnutls_recv()
|
||||
with this zero length buffer, at which point GNUTLS returns an error
|
||||
GNUTLS_E_INVALID_REQUEST. This is treated as fatal by QEMU's TLS code
|
||||
resulting in the connection being torn down by the chardev.
|
||||
|
||||
Simply skipping the qio_channel_read when the buffer length is zero
|
||||
is also not satisfactory, as it results in a high CPU burn busy loop
|
||||
massively slowing QEMU's functionality.
|
||||
|
||||
The proper solution is to avoid tcp_chr_read being called at all
|
||||
unless the frontend is able to accept more data. This will be done
|
||||
in a followup commit.
|
||||
|
||||
This reverts commit 462945cd22d2bcd233401ed3aa167d83a8e35b05
|
||||
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit e8ee827ffdb86ebbd5f5213a1f78123c25a90864)
|
||||
---
|
||||
chardev/char-socket.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
|
||||
index f48d341ebc..51d0943fce 100644
|
||||
--- a/chardev/char-socket.c
|
||||
+++ b/chardev/char-socket.c
|
||||
@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
s->max_size <= 0) {
|
||||
return TRUE;
|
||||
}
|
||||
- len = tcp_chr_read_poll(opaque);
|
||||
- if (len > sizeof(buf)) {
|
||||
- len = sizeof(buf);
|
||||
+ len = sizeof(buf);
|
||||
+ if (len > s->max_size) {
|
||||
+ len = s->max_size;
|
||||
}
|
||||
size = tcp_chr_recv(chr, (void *)buf, len);
|
||||
if (size == 0 || (size == -1 && errno != EAGAIN)) {
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,216 +0,0 @@
|
||||
From ab5a33d57b48e35388928e388bb6e6479bc77651 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 17:08:30 +0000
|
||||
Subject: [PATCH 3/3] Revert "chardev: use a child source for qio input source"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs
|
||||
RH-Jira: RHEL-24614
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-Commit: [3/3] b58e6c19c2b11d5d28db31cf1386226fb01d195e (berrange/centos-src-qemu)
|
||||
|
||||
This reverts commit a7077b8e354d90fec26c2921aa2dea85b90dff90,
|
||||
and add comments to explain why child sources cannot be used.
|
||||
|
||||
When a GSource is added as a child of another GSource, if its
|
||||
'prepare' function indicates readiness, then the parent's
|
||||
'prepare' function will never be run. The io_watch_poll_prepare
|
||||
absolutely *must* be run on every iteration of the main loop,
|
||||
to ensure that the chardev backend doesn't feed data to the
|
||||
frontend that it is unable to consume.
|
||||
|
||||
At the time a7077b8e354d90fec26c2921aa2dea85b90dff90 was made,
|
||||
all the child GSource impls were relying on poll'ing an FD,
|
||||
so their 'prepare' functions would never indicate readiness
|
||||
ahead of poll() being invoked. So the buggy behaviour was
|
||||
not noticed and lay dormant.
|
||||
|
||||
Relatively recently the QIOChannelTLS impl introduced a
|
||||
level 2 child GSource, which checks with GNUTLS whether it
|
||||
has cached any data that was decoded but not yet consumed:
|
||||
|
||||
commit ffda5db65aef42266a5053a4be34515106c4c7ee
|
||||
Author: Antoine Damhet <antoine.damhet@shadow.tech>
|
||||
Date: Tue Nov 15 15:23:29 2022 +0100
|
||||
|
||||
io/channel-tls: fix handling of bigger read buffers
|
||||
|
||||
Since the TLS backend can read more data from the underlying QIOChannel
|
||||
we introduce a minimal child GSource to notify if we still have more
|
||||
data available to be read.
|
||||
|
||||
Signed-off-by: Antoine Damhet <antoine.damhet@shadow.tech>
|
||||
Signed-off-by: Charles Frey <charles.frey@shadow.tech>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
With this, it is now quite common for the 'prepare' function
|
||||
on a QIOChannelTLS GSource to indicate immediate readiness,
|
||||
bypassing the parent GSource 'prepare' function. IOW, the
|
||||
critical 'io_watch_poll_prepare' is being skipped on some
|
||||
iterations of the main loop. As a result chardev frontend
|
||||
asserts are now being triggered as they are fed data they
|
||||
are not ready to consume.
|
||||
|
||||
A reproducer is as follows:
|
||||
|
||||
* In terminal 1 run a GNUTLS *echo* server
|
||||
|
||||
$ gnutls-serv --echo \
|
||||
--x509cafile ca-cert.pem \
|
||||
--x509keyfile server-key.pem \
|
||||
--x509certfile server-cert.pem \
|
||||
-p 9000
|
||||
|
||||
* In terminal 2 run a QEMU guest
|
||||
|
||||
$ qemu-system-s390x \
|
||||
-nodefaults \
|
||||
-display none \
|
||||
-object tls-creds-x509,id=tls0,dir=$PWD,endpoint=client \
|
||||
-chardev socket,id=con0,host=localhost,port=9000,tls-creds=tls0 \
|
||||
-device sclpconsole,chardev=con0 \
|
||||
-hda Fedora-Cloud-Base-39-1.5.s390x.qcow2
|
||||
|
||||
After the previous patch revert, but before this patch revert,
|
||||
this scenario will crash:
|
||||
|
||||
qemu-system-s390x: ../hw/char/sclpconsole.c:73: chr_read: Assertion
|
||||
`size <= SIZE_BUFFER_VT220 - scon->iov_data_len' failed.
|
||||
|
||||
This assert indicates that 'tcp_chr_read' was called without
|
||||
'tcp_chr_read_poll' having first been checked for ability to
|
||||
receive more data
|
||||
|
||||
QEMU's use of a 'prepare' function to create/delete another
|
||||
GSource is rather a hack and not normally the kind of thing that
|
||||
is expected to be done by a GSource. There is no mechanism to
|
||||
force GLib to always run the 'prepare' function of a parent
|
||||
GSource. The best option is to simply not use the child source
|
||||
concept, and go back to the functional approach previously
|
||||
relied on.
|
||||
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Tested-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 038b4217884c6f297278bb1ec6f0463c6c8221de)
|
||||
---
|
||||
chardev/char-io.c | 56 ++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 51 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/chardev/char-io.c b/chardev/char-io.c
|
||||
index 4451128cba..dab77b112e 100644
|
||||
--- a/chardev/char-io.c
|
||||
+++ b/chardev/char-io.c
|
||||
@@ -33,6 +33,7 @@ typedef struct IOWatchPoll {
|
||||
IOCanReadHandler *fd_can_read;
|
||||
GSourceFunc fd_read;
|
||||
void *opaque;
|
||||
+ GMainContext *context;
|
||||
} IOWatchPoll;
|
||||
|
||||
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
|
||||
@@ -50,28 +51,59 @@ static gboolean io_watch_poll_prepare(GSource *source,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * We do not register the QIOChannel watch as a child GSource.
|
||||
+ * The 'prepare' function on the parent GSource will be
|
||||
+ * skipped if a child GSource's 'prepare' function indicates
|
||||
+ * readiness. We need this prepare function be guaranteed
|
||||
+ * to run on *every* iteration of the main loop, because
|
||||
+ * it is critical to ensure we remove the QIOChannel watch
|
||||
+ * if 'fd_can_read' indicates the frontend cannot receive
|
||||
+ * more data.
|
||||
+ */
|
||||
if (now_active) {
|
||||
iwp->src = qio_channel_create_watch(
|
||||
iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
|
||||
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
|
||||
- g_source_add_child_source(source, iwp->src);
|
||||
- g_source_unref(iwp->src);
|
||||
+ g_source_attach(iwp->src, iwp->context);
|
||||
} else {
|
||||
- g_source_remove_child_source(source, iwp->src);
|
||||
+ g_source_destroy(iwp->src);
|
||||
+ g_source_unref(iwp->src);
|
||||
iwp->src = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+static gboolean io_watch_poll_check(GSource *source)
|
||||
+{
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
- return G_SOURCE_CONTINUE;
|
||||
+ abort();
|
||||
+}
|
||||
+
|
||||
+static void io_watch_poll_finalize(GSource *source)
|
||||
+{
|
||||
+ /*
|
||||
+ * Due to a glib bug, removing the last reference to a source
|
||||
+ * inside a finalize callback causes recursive locking (and a
|
||||
+ * deadlock). This is not a problem inside other callbacks,
|
||||
+ * including dispatch callbacks, so we call io_remove_watch_poll
|
||||
+ * to remove this source. At this point, iwp->src must
|
||||
+ * be NULL, or we would leak it.
|
||||
+ */
|
||||
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
|
||||
+ assert(iwp->src == NULL);
|
||||
}
|
||||
|
||||
static GSourceFuncs io_watch_poll_funcs = {
|
||||
.prepare = io_watch_poll_prepare,
|
||||
+ .check = io_watch_poll_check,
|
||||
.dispatch = io_watch_poll_dispatch,
|
||||
+ .finalize = io_watch_poll_finalize,
|
||||
};
|
||||
|
||||
GSource *io_add_watch_poll(Chardev *chr,
|
||||
@@ -91,6 +123,7 @@ GSource *io_add_watch_poll(Chardev *chr,
|
||||
iwp->ioc = ioc;
|
||||
iwp->fd_read = (GSourceFunc) fd_read;
|
||||
iwp->src = NULL;
|
||||
+ iwp->context = context;
|
||||
|
||||
name = g_strdup_printf("chardev-iowatch-%s", chr->label);
|
||||
g_source_set_name((GSource *)iwp, name);
|
||||
@@ -101,10 +134,23 @@ GSource *io_add_watch_poll(Chardev *chr,
|
||||
return (GSource *)iwp;
|
||||
}
|
||||
|
||||
+static void io_remove_watch_poll(GSource *source)
|
||||
+{
|
||||
+ IOWatchPoll *iwp;
|
||||
+
|
||||
+ iwp = io_watch_poll_from_source(source);
|
||||
+ if (iwp->src) {
|
||||
+ g_source_destroy(iwp->src);
|
||||
+ g_source_unref(iwp->src);
|
||||
+ iwp->src = NULL;
|
||||
+ }
|
||||
+ g_source_destroy(&iwp->parent);
|
||||
+}
|
||||
+
|
||||
void remove_fd_in_watch(Chardev *chr)
|
||||
{
|
||||
if (chr->gsource) {
|
||||
- g_source_destroy(chr->gsource);
|
||||
+ io_remove_watch_poll(chr->gsource);
|
||||
chr->gsource = NULL;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 6b5cfed21e20b372090046a934387255ff4bda58 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:01 -0500
|
||||
Subject: [PATCH 084/101] aio: make aio_context_acquire()/aio_context_release()
|
||||
a no-op
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [15/26] 723dcada900aaf08862e8221921be22506b561a8 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
aio_context_acquire()/aio_context_release() has been replaced by
|
||||
fine-grained locking to protect state shared by multiple threads. The
|
||||
AioContext lock still plays the role of balancing locking in
|
||||
AIO_WAIT_WHILE() and many functions in QEMU either require that the
|
||||
AioContext lock is held or not held for this reason. In other words, the
|
||||
AioContext lock is purely there for consistency with itself and serves
|
||||
no real purpose anymore.
|
||||
|
||||
Stop actually acquiring/releasing the lock in
|
||||
aio_context_acquire()/aio_context_release() so that subsequent patches
|
||||
can remove callers across the codebase incrementally.
|
||||
|
||||
I have performed "make check" and qemu-iotests stress tests across
|
||||
x86-64, ppc64le, and aarch64 to confirm that there are no failures as a
|
||||
result of eliminating the lock.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-5-stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
util/async.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util/async.c b/util/async.c
|
||||
index 8f90ddc304..04ee83d220 100644
|
||||
--- a/util/async.c
|
||||
+++ b/util/async.c
|
||||
@@ -725,12 +725,12 @@ void aio_context_unref(AioContext *ctx)
|
||||
|
||||
void aio_context_acquire(AioContext *ctx)
|
||||
{
|
||||
- qemu_rec_mutex_lock(&ctx->lock);
|
||||
+ /* TODO remove this function */
|
||||
}
|
||||
|
||||
void aio_context_release(AioContext *ctx)
|
||||
{
|
||||
- qemu_rec_mutex_unlock(&ctx->lock);
|
||||
+ /* TODO remove this function */
|
||||
}
|
||||
|
||||
QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,102 +0,0 @@
|
||||
From 14913d8970090c8914dc19dad14f3b9f91985ec3 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:07 -0500
|
||||
Subject: [PATCH 090/101] aio: remove
|
||||
aio_context_acquire()/aio_context_release() API
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [21/26] 4b6d4afcac79d3248a6722b063b5fc777dc418df (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Delete these functions because nothing calls these functions anymore.
|
||||
|
||||
I introduced these APIs in commit 98563fc3ec44 ("aio: add
|
||||
aio_context_acquire() and aio_context_release()") in 2014. It's with a
|
||||
sigh of relief that I delete these APIs almost 10 years later.
|
||||
|
||||
Thanks to Paolo Bonzini's vision for multi-queue QEMU, we got an
|
||||
understanding of where the code needed to go in order to remove the
|
||||
limitations that the original dataplane and the IOThread/AioContext
|
||||
approach that followed it.
|
||||
|
||||
Emanuele Giuseppe Esposito had the splendid determination to convert
|
||||
large parts of the codebase so that they no longer needed the AioContext
|
||||
lock. This was a painstaking process, both in the actual code changes
|
||||
required and the iterations of code review that Emanuele eked out of
|
||||
Kevin and me over many months.
|
||||
|
||||
Kevin Wolf tackled multitudes of graph locking conversions to protect
|
||||
in-flight I/O from run-time changes to the block graph as well as the
|
||||
clang Thread Safety Analysis annotations that allow the compiler to
|
||||
check whether the graph lock is being used correctly.
|
||||
|
||||
And me, well, I'm just here to add some pizzazz to the QEMU multi-queue
|
||||
block layer :). Thank you to everyone who helped with this effort,
|
||||
including Eric Blake, code reviewer extraordinaire, and others who I've
|
||||
forgotten to mention.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-11-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
include/block/aio.h | 17 -----------------
|
||||
util/async.c | 10 ----------
|
||||
2 files changed, 27 deletions(-)
|
||||
|
||||
diff --git a/include/block/aio.h b/include/block/aio.h
|
||||
index f08b358077..af05512a7d 100644
|
||||
--- a/include/block/aio.h
|
||||
+++ b/include/block/aio.h
|
||||
@@ -278,23 +278,6 @@ void aio_context_ref(AioContext *ctx);
|
||||
*/
|
||||
void aio_context_unref(AioContext *ctx);
|
||||
|
||||
-/* Take ownership of the AioContext. If the AioContext will be shared between
|
||||
- * threads, and a thread does not want to be interrupted, it will have to
|
||||
- * take ownership around calls to aio_poll(). Otherwise, aio_poll()
|
||||
- * automatically takes care of calling aio_context_acquire and
|
||||
- * aio_context_release.
|
||||
- *
|
||||
- * Note that this is separate from bdrv_drained_begin/bdrv_drained_end. A
|
||||
- * thread still has to call those to avoid being interrupted by the guest.
|
||||
- *
|
||||
- * Bottom halves, timers and callbacks can be created or removed without
|
||||
- * acquiring the AioContext.
|
||||
- */
|
||||
-void aio_context_acquire(AioContext *ctx);
|
||||
-
|
||||
-/* Relinquish ownership of the AioContext. */
|
||||
-void aio_context_release(AioContext *ctx);
|
||||
-
|
||||
/**
|
||||
* aio_bh_schedule_oneshot_full: Allocate a new bottom half structure that will
|
||||
* run only once and as soon as possible.
|
||||
diff --git a/util/async.c b/util/async.c
|
||||
index dfd44ef612..460529057c 100644
|
||||
--- a/util/async.c
|
||||
+++ b/util/async.c
|
||||
@@ -719,16 +719,6 @@ void aio_context_unref(AioContext *ctx)
|
||||
g_source_unref(&ctx->source);
|
||||
}
|
||||
|
||||
-void aio_context_acquire(AioContext *ctx)
|
||||
-{
|
||||
- /* TODO remove this function */
|
||||
-}
|
||||
-
|
||||
-void aio_context_release(AioContext *ctx)
|
||||
-{
|
||||
- /* TODO remove this function */
|
||||
-}
|
||||
-
|
||||
QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext)
|
||||
|
||||
AioContext *qemu_get_current_aio_context(void)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,81 +0,0 @@
|
||||
From e1e2f3972065c4b5d6fcf37e0e1c4fb92a0d5260 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:06 -0500
|
||||
Subject: [PATCH 089/101] aio-wait: draw equivalence between AIO_WAIT_WHILE()
|
||||
and AIO_WAIT_WHILE_UNLOCKED()
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [20/26] 20e49777869714c99769263103f1b0c2c370cfcd (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Now that the AioContext lock no longer exists, AIO_WAIT_WHILE() and
|
||||
AIO_WAIT_WHILE_UNLOCKED() are equivalent.
|
||||
|
||||
A future patch will get rid of AIO_WAIT_WHILE_UNLOCKED().
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-10-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
include/block/aio-wait.h | 16 ++++------------
|
||||
1 file changed, 4 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
|
||||
index 5449b6d742..157f105916 100644
|
||||
--- a/include/block/aio-wait.h
|
||||
+++ b/include/block/aio-wait.h
|
||||
@@ -63,9 +63,6 @@ extern AioWait global_aio_wait;
|
||||
* @ctx: the aio context, or NULL if multiple aio contexts (for which the
|
||||
* caller does not hold a lock) are involved in the polling condition.
|
||||
* @cond: wait while this conditional expression is true
|
||||
- * @unlock: whether to unlock and then lock again @ctx. This applies
|
||||
- * only when waiting for another AioContext from the main loop.
|
||||
- * Otherwise it's ignored.
|
||||
*
|
||||
* Wait while a condition is true. Use this to implement synchronous
|
||||
* operations that require event loop activity.
|
||||
@@ -78,7 +75,7 @@ extern AioWait global_aio_wait;
|
||||
* wait on conditions between two IOThreads since that could lead to deadlock,
|
||||
* go via the main loop instead.
|
||||
*/
|
||||
-#define AIO_WAIT_WHILE_INTERNAL(ctx, cond, unlock) ({ \
|
||||
+#define AIO_WAIT_WHILE_INTERNAL(ctx, cond) ({ \
|
||||
bool waited_ = false; \
|
||||
AioWait *wait_ = &global_aio_wait; \
|
||||
AioContext *ctx_ = (ctx); \
|
||||
@@ -95,13 +92,7 @@ extern AioWait global_aio_wait;
|
||||
assert(qemu_get_current_aio_context() == \
|
||||
qemu_get_aio_context()); \
|
||||
while ((cond)) { \
|
||||
- if (unlock && ctx_) { \
|
||||
- aio_context_release(ctx_); \
|
||||
- } \
|
||||
aio_poll(qemu_get_aio_context(), true); \
|
||||
- if (unlock && ctx_) { \
|
||||
- aio_context_acquire(ctx_); \
|
||||
- } \
|
||||
waited_ = true; \
|
||||
} \
|
||||
} \
|
||||
@@ -109,10 +100,11 @@ extern AioWait global_aio_wait;
|
||||
waited_; })
|
||||
|
||||
#define AIO_WAIT_WHILE(ctx, cond) \
|
||||
- AIO_WAIT_WHILE_INTERNAL(ctx, cond, true)
|
||||
+ AIO_WAIT_WHILE_INTERNAL(ctx, cond)
|
||||
|
||||
+/* TODO replace this with AIO_WAIT_WHILE() in a future patch */
|
||||
#define AIO_WAIT_WHILE_UNLOCKED(ctx, cond) \
|
||||
- AIO_WAIT_WHILE_INTERNAL(ctx, cond, false)
|
||||
+ AIO_WAIT_WHILE_INTERNAL(ctx, cond)
|
||||
|
||||
/**
|
||||
* aio_wait_kick:
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,476 +0,0 @@
|
||||
From 0d8255c98b3ef6f603ff0279592d3e91de26de0e Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 16:44:00 +0800
|
||||
Subject: [PATCH 021/101] backends/iommufd: Introduce the iommufd object
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [20/67] 8a56344ab4a2126f248bfa492ccddd19265f39be (eauger1/centos-qemu-kvm)
|
||||
|
||||
Introduce an iommufd object which allows the interaction
|
||||
with the host /dev/iommu device.
|
||||
|
||||
The /dev/iommu can have been already pre-opened outside of qemu,
|
||||
in which case the fd can be passed directly along with the
|
||||
iommufd object:
|
||||
|
||||
This allows the iommufd object to be shared accross several
|
||||
subsystems (VFIO, VDPA, ...). For example, libvirt would open
|
||||
the /dev/iommu once.
|
||||
|
||||
If no fd is passed along with the iommufd object, the /dev/iommu
|
||||
is opened by the qemu code.
|
||||
|
||||
Suggested-by: Alex Williamson <alex.williamson@redhat.com>
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Tested-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 6e6d8ac62b5b38dc9d4b69ffdf073f0a0b43b7be)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
MAINTAINERS | 8 ++
|
||||
backends/Kconfig | 4 +
|
||||
backends/iommufd.c | 245 +++++++++++++++++++++++++++++++++++++++
|
||||
backends/meson.build | 1 +
|
||||
backends/trace-events | 10 ++
|
||||
include/sysemu/iommufd.h | 38 ++++++
|
||||
qapi/qom.json | 19 +++
|
||||
qemu-options.hx | 12 ++
|
||||
8 files changed, 337 insertions(+)
|
||||
create mode 100644 backends/iommufd.c
|
||||
create mode 100644 include/sysemu/iommufd.h
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 695e0bd34f..a5a446914a 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -2167,6 +2167,14 @@ F: hw/vfio/ap.c
|
||||
F: docs/system/s390x/vfio-ap.rst
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
+iommufd
|
||||
+M: Yi Liu <yi.l.liu@intel.com>
|
||||
+M: Eric Auger <eric.auger@redhat.com>
|
||||
+M: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
+S: Supported
|
||||
+F: backends/iommufd.c
|
||||
+F: include/sysemu/iommufd.h
|
||||
+
|
||||
vhost
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
diff --git a/backends/Kconfig b/backends/Kconfig
|
||||
index f35abc1609..2cb23f62fa 100644
|
||||
--- a/backends/Kconfig
|
||||
+++ b/backends/Kconfig
|
||||
@@ -1 +1,5 @@
|
||||
source tpm/Kconfig
|
||||
+
|
||||
+config IOMMUFD
|
||||
+ bool
|
||||
+ depends on VFIO
|
||||
diff --git a/backends/iommufd.c b/backends/iommufd.c
|
||||
new file mode 100644
|
||||
index 0000000000..ba58a0eb0d
|
||||
--- /dev/null
|
||||
+++ b/backends/iommufd.c
|
||||
@@ -0,0 +1,245 @@
|
||||
+/*
|
||||
+ * iommufd container backend
|
||||
+ *
|
||||
+ * Copyright (C) 2023 Intel Corporation.
|
||||
+ * Copyright Red Hat, Inc. 2023
|
||||
+ *
|
||||
+ * Authors: Yi Liu <yi.l.liu@intel.com>
|
||||
+ * Eric Auger <eric.auger@redhat.com>
|
||||
+ *
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "sysemu/iommufd.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "qapi/qmp/qerror.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "qom/object_interfaces.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+#include "monitor/monitor.h"
|
||||
+#include "trace.h"
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <linux/iommufd.h>
|
||||
+
|
||||
+static void iommufd_backend_init(Object *obj)
|
||||
+{
|
||||
+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj);
|
||||
+
|
||||
+ be->fd = -1;
|
||||
+ be->users = 0;
|
||||
+ be->owned = true;
|
||||
+ qemu_mutex_init(&be->lock);
|
||||
+}
|
||||
+
|
||||
+static void iommufd_backend_finalize(Object *obj)
|
||||
+{
|
||||
+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj);
|
||||
+
|
||||
+ if (be->owned) {
|
||||
+ close(be->fd);
|
||||
+ be->fd = -1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void iommufd_backend_set_fd(Object *obj, const char *str, Error **errp)
|
||||
+{
|
||||
+ IOMMUFDBackend *be = IOMMUFD_BACKEND(obj);
|
||||
+ int fd = -1;
|
||||
+
|
||||
+ fd = monitor_fd_param(monitor_cur(), str, errp);
|
||||
+ if (fd == -1) {
|
||||
+ error_prepend(errp, "Could not parse remote object fd %s:", str);
|
||||
+ return;
|
||||
+ }
|
||||
+ qemu_mutex_lock(&be->lock);
|
||||
+ be->fd = fd;
|
||||
+ be->owned = false;
|
||||
+ qemu_mutex_unlock(&be->lock);
|
||||
+ trace_iommu_backend_set_fd(be->fd);
|
||||
+}
|
||||
+
|
||||
+static bool iommufd_backend_can_be_deleted(UserCreatable *uc)
|
||||
+{
|
||||
+ IOMMUFDBackend *be = IOMMUFD_BACKEND(uc);
|
||||
+
|
||||
+ return !be->users;
|
||||
+}
|
||||
+
|
||||
+static void iommufd_backend_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
|
||||
+
|
||||
+ ucc->can_be_deleted = iommufd_backend_can_be_deleted;
|
||||
+
|
||||
+ object_class_property_add_str(oc, "fd", NULL, iommufd_backend_set_fd);
|
||||
+}
|
||||
+
|
||||
+int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
|
||||
+{
|
||||
+ int fd, ret = 0;
|
||||
+
|
||||
+ qemu_mutex_lock(&be->lock);
|
||||
+ if (be->users == UINT32_MAX) {
|
||||
+ error_setg(errp, "too many connections");
|
||||
+ ret = -E2BIG;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (be->owned && !be->users) {
|
||||
+ fd = qemu_open_old("/dev/iommu", O_RDWR);
|
||||
+ if (fd < 0) {
|
||||
+ error_setg_errno(errp, errno, "/dev/iommu opening failed");
|
||||
+ ret = fd;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ be->fd = fd;
|
||||
+ }
|
||||
+ be->users++;
|
||||
+out:
|
||||
+ trace_iommufd_backend_connect(be->fd, be->owned,
|
||||
+ be->users, ret);
|
||||
+ qemu_mutex_unlock(&be->lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void iommufd_backend_disconnect(IOMMUFDBackend *be)
|
||||
+{
|
||||
+ qemu_mutex_lock(&be->lock);
|
||||
+ if (!be->users) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+ be->users--;
|
||||
+ if (!be->users && be->owned) {
|
||||
+ close(be->fd);
|
||||
+ be->fd = -1;
|
||||
+ }
|
||||
+out:
|
||||
+ trace_iommufd_backend_disconnect(be->fd, be->users);
|
||||
+ qemu_mutex_unlock(&be->lock);
|
||||
+}
|
||||
+
|
||||
+int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ int ret, fd = be->fd;
|
||||
+ struct iommu_ioas_alloc alloc_data = {
|
||||
+ .size = sizeof(alloc_data),
|
||||
+ .flags = 0,
|
||||
+ };
|
||||
+
|
||||
+ ret = ioctl(fd, IOMMU_IOAS_ALLOC, &alloc_data);
|
||||
+ if (ret) {
|
||||
+ error_setg_errno(errp, errno, "Failed to allocate ioas");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ *ioas_id = alloc_data.out_ioas_id;
|
||||
+ trace_iommufd_backend_alloc_ioas(fd, *ioas_id, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id)
|
||||
+{
|
||||
+ int ret, fd = be->fd;
|
||||
+ struct iommu_destroy des = {
|
||||
+ .size = sizeof(des),
|
||||
+ .id = id,
|
||||
+ };
|
||||
+
|
||||
+ ret = ioctl(fd, IOMMU_DESTROY, &des);
|
||||
+ trace_iommufd_backend_free_id(fd, id, ret);
|
||||
+ if (ret) {
|
||||
+ error_report("Failed to free id: %u %m", id);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
|
||||
+ ram_addr_t size, void *vaddr, bool readonly)
|
||||
+{
|
||||
+ int ret, fd = be->fd;
|
||||
+ struct iommu_ioas_map map = {
|
||||
+ .size = sizeof(map),
|
||||
+ .flags = IOMMU_IOAS_MAP_READABLE |
|
||||
+ IOMMU_IOAS_MAP_FIXED_IOVA,
|
||||
+ .ioas_id = ioas_id,
|
||||
+ .__reserved = 0,
|
||||
+ .user_va = (uintptr_t)vaddr,
|
||||
+ .iova = iova,
|
||||
+ .length = size,
|
||||
+ };
|
||||
+
|
||||
+ if (!readonly) {
|
||||
+ map.flags |= IOMMU_IOAS_MAP_WRITEABLE;
|
||||
+ }
|
||||
+
|
||||
+ ret = ioctl(fd, IOMMU_IOAS_MAP, &map);
|
||||
+ trace_iommufd_backend_map_dma(fd, ioas_id, iova, size,
|
||||
+ vaddr, readonly, ret);
|
||||
+ if (ret) {
|
||||
+ ret = -errno;
|
||||
+
|
||||
+ /* TODO: Not support mapping hardware PCI BAR region for now. */
|
||||
+ if (errno == EFAULT) {
|
||||
+ warn_report("IOMMU_IOAS_MAP failed: %m, PCI BAR?");
|
||||
+ } else {
|
||||
+ error_report("IOMMU_IOAS_MAP failed: %m");
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
|
||||
+ hwaddr iova, ram_addr_t size)
|
||||
+{
|
||||
+ int ret, fd = be->fd;
|
||||
+ struct iommu_ioas_unmap unmap = {
|
||||
+ .size = sizeof(unmap),
|
||||
+ .ioas_id = ioas_id,
|
||||
+ .iova = iova,
|
||||
+ .length = size,
|
||||
+ };
|
||||
+
|
||||
+ ret = ioctl(fd, IOMMU_IOAS_UNMAP, &unmap);
|
||||
+ /*
|
||||
+ * IOMMUFD takes mapping as some kind of object, unmapping
|
||||
+ * nonexistent mapping is treated as deleting a nonexistent
|
||||
+ * object and return ENOENT. This is different from legacy
|
||||
+ * backend which allows it. vIOMMU may trigger a lot of
|
||||
+ * redundant unmapping, to avoid flush the log, treat them
|
||||
+ * as succeess for IOMMUFD just like legacy backend.
|
||||
+ */
|
||||
+ if (ret && errno == ENOENT) {
|
||||
+ trace_iommufd_backend_unmap_dma_non_exist(fd, ioas_id, iova, size, ret);
|
||||
+ ret = 0;
|
||||
+ } else {
|
||||
+ trace_iommufd_backend_unmap_dma(fd, ioas_id, iova, size, ret);
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ ret = -errno;
|
||||
+ error_report("IOMMU_IOAS_UNMAP failed: %m");
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo iommufd_backend_info = {
|
||||
+ .name = TYPE_IOMMUFD_BACKEND,
|
||||
+ .parent = TYPE_OBJECT,
|
||||
+ .instance_size = sizeof(IOMMUFDBackend),
|
||||
+ .instance_init = iommufd_backend_init,
|
||||
+ .instance_finalize = iommufd_backend_finalize,
|
||||
+ .class_size = sizeof(IOMMUFDBackendClass),
|
||||
+ .class_init = iommufd_backend_class_init,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_USER_CREATABLE },
|
||||
+ { }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void register_types(void)
|
||||
+{
|
||||
+ type_register_static(&iommufd_backend_info);
|
||||
+}
|
||||
+
|
||||
+type_init(register_types);
|
||||
diff --git a/backends/meson.build b/backends/meson.build
|
||||
index 914c7c4afb..9a5cea480d 100644
|
||||
--- a/backends/meson.build
|
||||
+++ b/backends/meson.build
|
||||
@@ -20,6 +20,7 @@ if have_vhost_user
|
||||
system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('vhost-user.c'))
|
||||
endif
|
||||
system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost.c'))
|
||||
+system_ss.add(when: 'CONFIG_IOMMUFD', if_true: files('iommufd.c'))
|
||||
if have_vhost_user_crypto
|
||||
system_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost-user.c'))
|
||||
endif
|
||||
diff --git a/backends/trace-events b/backends/trace-events
|
||||
index 652eb76a57..d45c6e31a6 100644
|
||||
--- a/backends/trace-events
|
||||
+++ b/backends/trace-events
|
||||
@@ -5,3 +5,13 @@ dbus_vmstate_pre_save(void)
|
||||
dbus_vmstate_post_load(int version_id) "version_id: %d"
|
||||
dbus_vmstate_loading(const char *id) "id: %s"
|
||||
dbus_vmstate_saving(const char *id) "id: %s"
|
||||
+
|
||||
+# iommufd.c
|
||||
+iommufd_backend_connect(int fd, bool owned, uint32_t users, int ret) "fd=%d owned=%d users=%d (%d)"
|
||||
+iommufd_backend_disconnect(int fd, uint32_t users) "fd=%d users=%d"
|
||||
+iommu_backend_set_fd(int fd) "pre-opened /dev/iommu fd=%d"
|
||||
+iommufd_backend_map_dma(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, void *vaddr, bool readonly, int ret) " iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" addr=%p readonly=%d (%d)"
|
||||
+iommufd_backend_unmap_dma_non_exist(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, int ret) " Unmap nonexistent mapping: iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" (%d)"
|
||||
+iommufd_backend_unmap_dma(int iommufd, uint32_t ioas, uint64_t iova, uint64_t size, int ret) " iommufd=%d ioas=%d iova=0x%"PRIx64" size=0x%"PRIx64" (%d)"
|
||||
+iommufd_backend_alloc_ioas(int iommufd, uint32_t ioas, int ret) " iommufd=%d ioas=%d (%d)"
|
||||
+iommufd_backend_free_id(int iommufd, uint32_t id, int ret) " iommufd=%d id=%d (%d)"
|
||||
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
|
||||
new file mode 100644
|
||||
index 0000000000..9c5524b0ed
|
||||
--- /dev/null
|
||||
+++ b/include/sysemu/iommufd.h
|
||||
@@ -0,0 +1,38 @@
|
||||
+#ifndef SYSEMU_IOMMUFD_H
|
||||
+#define SYSEMU_IOMMUFD_H
|
||||
+
|
||||
+#include "qom/object.h"
|
||||
+#include "qemu/thread.h"
|
||||
+#include "exec/hwaddr.h"
|
||||
+#include "exec/cpu-common.h"
|
||||
+
|
||||
+#define TYPE_IOMMUFD_BACKEND "iommufd"
|
||||
+OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
|
||||
+
|
||||
+struct IOMMUFDBackendClass {
|
||||
+ ObjectClass parent_class;
|
||||
+};
|
||||
+
|
||||
+struct IOMMUFDBackend {
|
||||
+ Object parent;
|
||||
+
|
||||
+ /*< protected >*/
|
||||
+ int fd; /* /dev/iommu file descriptor */
|
||||
+ bool owned; /* is the /dev/iommu opened internally */
|
||||
+ QemuMutex lock;
|
||||
+ uint32_t users;
|
||||
+
|
||||
+ /*< public >*/
|
||||
+};
|
||||
+
|
||||
+int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
|
||||
+void iommufd_backend_disconnect(IOMMUFDBackend *be);
|
||||
+
|
||||
+int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
|
||||
+ Error **errp);
|
||||
+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
|
||||
+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
|
||||
+ ram_addr_t size, void *vaddr, bool readonly);
|
||||
+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
|
||||
+ hwaddr iova, ram_addr_t size);
|
||||
+#endif
|
||||
diff --git a/qapi/qom.json b/qapi/qom.json
|
||||
index c53ef978ff..95516ba325 100644
|
||||
--- a/qapi/qom.json
|
||||
+++ b/qapi/qom.json
|
||||
@@ -794,6 +794,23 @@
|
||||
{ 'struct': 'VfioUserServerProperties',
|
||||
'data': { 'socket': 'SocketAddress', 'device': 'str' } }
|
||||
|
||||
+##
|
||||
+# @IOMMUFDProperties:
|
||||
+#
|
||||
+# Properties for iommufd objects.
|
||||
+#
|
||||
+# @fd: file descriptor name previously passed via 'getfd' command,
|
||||
+# which represents a pre-opened /dev/iommu. This allows the
|
||||
+# iommufd object to be shared accross several subsystems
|
||||
+# (VFIO, VDPA, ...), and the file descriptor to be shared
|
||||
+# with other process, e.g. DPDK. (default: QEMU opens
|
||||
+# /dev/iommu by itself)
|
||||
+#
|
||||
+# Since: 9.0
|
||||
+##
|
||||
+{ 'struct': 'IOMMUFDProperties',
|
||||
+ 'data': { '*fd': 'str' } }
|
||||
+
|
||||
##
|
||||
# @RngProperties:
|
||||
#
|
||||
@@ -934,6 +951,7 @@
|
||||
'input-barrier',
|
||||
{ 'name': 'input-linux',
|
||||
'if': 'CONFIG_LINUX' },
|
||||
+ 'iommufd',
|
||||
'iothread',
|
||||
'main-loop',
|
||||
{ 'name': 'memory-backend-epc',
|
||||
@@ -1003,6 +1021,7 @@
|
||||
'input-barrier': 'InputBarrierProperties',
|
||||
'input-linux': { 'type': 'InputLinuxProperties',
|
||||
'if': 'CONFIG_LINUX' },
|
||||
+ 'iommufd': 'IOMMUFDProperties',
|
||||
'iothread': 'IothreadProperties',
|
||||
'main-loop': 'MainLoopProperties',
|
||||
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 557118cb1f..0814f43066 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -5224,6 +5224,18 @@ SRST
|
||||
|
||||
The ``share`` boolean option is on by default with memfd.
|
||||
|
||||
+ ``-object iommufd,id=id[,fd=fd]``
|
||||
+ Creates an iommufd backend which allows control of DMA mapping
|
||||
+ through the ``/dev/iommu`` device.
|
||||
+
|
||||
+ The ``id`` parameter is a unique ID which frontends (such as
|
||||
+ vfio-pci of vdpa) will use to connect with the iommufd backend.
|
||||
+
|
||||
+ The ``fd`` parameter is an optional pre-opened file descriptor
|
||||
+ resulting from ``/dev/iommu`` opening. Usually the iommufd is shared
|
||||
+ across all subsystems, bringing the benefit of centralized
|
||||
+ reference counting.
|
||||
+
|
||||
``-object rng-builtin,id=id``
|
||||
Creates a random number generator backend which obtains entropy
|
||||
from QEMU builtin functions. The ``id`` parameter is a unique ID
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,47 +0,0 @@
|
||||
From da9a24793e876f6f2727d57f939d882be26a47b8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Fri, 22 Dec 2023 08:55:23 +0100
|
||||
Subject: [PATCH 064/101] backends/iommufd: Remove check on number of backend
|
||||
users
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [63/67] ac4d4589d1f2de5ac3f0adfd8d1f27dbf6bbfdee (eauger1/centos-qemu-kvm)
|
||||
|
||||
QOM already has a ref count on objects and it will assert much
|
||||
earlier, when INT_MAX is reached.
|
||||
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit c2ab3a6f7411c895e538e8350fee8948ac07c1a0)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
backends/iommufd.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/backends/iommufd.c b/backends/iommufd.c
|
||||
index ba58a0eb0d..393c0d9a37 100644
|
||||
--- a/backends/iommufd.c
|
||||
+++ b/backends/iommufd.c
|
||||
@@ -80,11 +80,6 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
|
||||
int fd, ret = 0;
|
||||
|
||||
qemu_mutex_lock(&be->lock);
|
||||
- if (be->users == UINT32_MAX) {
|
||||
- error_setg(errp, "too many connections");
|
||||
- ret = -E2BIG;
|
||||
- goto out;
|
||||
- }
|
||||
if (be->owned && !be->users) {
|
||||
fd = qemu_open_old("/dev/iommu", O_RDWR);
|
||||
if (fd < 0) {
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,112 +0,0 @@
|
||||
From 92aff3cc1a412de01e9563802fa48848eae5283f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Thu, 21 Dec 2023 16:58:41 +0100
|
||||
Subject: [PATCH 065/101] backends/iommufd: Remove mutex
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [64/67] 65518432b18f18ceadafe1b0698cdaa962e84f61 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Coverity reports a concurrent data access violation because be->users
|
||||
is being accessed in iommufd_backend_can_be_deleted() without holding
|
||||
the mutex.
|
||||
|
||||
However, these routines are called from the QEMU main thread when a
|
||||
device is created. In this case, the code paths should be protected by
|
||||
the BQL lock and it should be safe to drop the IOMMUFD backend mutex.
|
||||
Simply remove it.
|
||||
|
||||
Fixes: CID 1531550
|
||||
Fixes: CID 1531549
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 19368b1905b4b917e915526fcbd5bfa3f7439451)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
backends/iommufd.c | 7 -------
|
||||
include/sysemu/iommufd.h | 2 --
|
||||
2 files changed, 9 deletions(-)
|
||||
|
||||
diff --git a/backends/iommufd.c b/backends/iommufd.c
|
||||
index 393c0d9a37..1ef683c7b0 100644
|
||||
--- a/backends/iommufd.c
|
||||
+++ b/backends/iommufd.c
|
||||
@@ -29,7 +29,6 @@ static void iommufd_backend_init(Object *obj)
|
||||
be->fd = -1;
|
||||
be->users = 0;
|
||||
be->owned = true;
|
||||
- qemu_mutex_init(&be->lock);
|
||||
}
|
||||
|
||||
static void iommufd_backend_finalize(Object *obj)
|
||||
@@ -52,10 +51,8 @@ static void iommufd_backend_set_fd(Object *obj, const char *str, Error **errp)
|
||||
error_prepend(errp, "Could not parse remote object fd %s:", str);
|
||||
return;
|
||||
}
|
||||
- qemu_mutex_lock(&be->lock);
|
||||
be->fd = fd;
|
||||
be->owned = false;
|
||||
- qemu_mutex_unlock(&be->lock);
|
||||
trace_iommu_backend_set_fd(be->fd);
|
||||
}
|
||||
|
||||
@@ -79,7 +76,6 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
|
||||
{
|
||||
int fd, ret = 0;
|
||||
|
||||
- qemu_mutex_lock(&be->lock);
|
||||
if (be->owned && !be->users) {
|
||||
fd = qemu_open_old("/dev/iommu", O_RDWR);
|
||||
if (fd < 0) {
|
||||
@@ -93,13 +89,11 @@ int iommufd_backend_connect(IOMMUFDBackend *be, Error **errp)
|
||||
out:
|
||||
trace_iommufd_backend_connect(be->fd, be->owned,
|
||||
be->users, ret);
|
||||
- qemu_mutex_unlock(&be->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iommufd_backend_disconnect(IOMMUFDBackend *be)
|
||||
{
|
||||
- qemu_mutex_lock(&be->lock);
|
||||
if (!be->users) {
|
||||
goto out;
|
||||
}
|
||||
@@ -110,7 +104,6 @@ void iommufd_backend_disconnect(IOMMUFDBackend *be)
|
||||
}
|
||||
out:
|
||||
trace_iommufd_backend_disconnect(be->fd, be->users);
|
||||
- qemu_mutex_unlock(&be->lock);
|
||||
}
|
||||
|
||||
int iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
|
||||
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
|
||||
index 9c5524b0ed..9af27ebd6c 100644
|
||||
--- a/include/sysemu/iommufd.h
|
||||
+++ b/include/sysemu/iommufd.h
|
||||
@@ -2,7 +2,6 @@
|
||||
#define SYSEMU_IOMMUFD_H
|
||||
|
||||
#include "qom/object.h"
|
||||
-#include "qemu/thread.h"
|
||||
#include "exec/hwaddr.h"
|
||||
#include "exec/cpu-common.h"
|
||||
|
||||
@@ -19,7 +18,6 @@ struct IOMMUFDBackend {
|
||||
/*< protected >*/
|
||||
int fd; /* /dev/iommu file descriptor */
|
||||
bool owned; /* is the /dev/iommu opened internally */
|
||||
- QemuMutex lock;
|
||||
uint32_t users;
|
||||
|
||||
/*< public >*/
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,104 +0,0 @@
|
||||
From afa842e9fdf6e1d6e5d5785679a22779632142bd Mon Sep 17 00:00:00 2001
|
||||
From: Hanna Czenczek <hreitz@redhat.com>
|
||||
Date: Fri, 2 Feb 2024 15:47:54 +0100
|
||||
Subject: [PATCH 03/22] block-backend: Allow concurrent context changes
|
||||
|
||||
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-MergeRequest: 222: Allow concurrent BlockBackend context changes
|
||||
RH-Jira: RHEL-24593
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Commit: [1/2] 9e1b535f60f7afa94a0817dc3e71136e41631c71 (hreitz/qemu-kvm-c-9-s)
|
||||
|
||||
Since AioContext locks have been removed, a BlockBackend's AioContext
|
||||
may really change at any time (only exception is that it is often
|
||||
confined to a drained section, as noted in this patch). Therefore,
|
||||
blk_get_aio_context() cannot rely on its root node's context always
|
||||
matching that of the BlockBackend.
|
||||
|
||||
In practice, whether they match does not matter anymore anyway: Requests
|
||||
can be sent to BDSs from any context, so anyone who requests the BB's
|
||||
context should have no reason to require the root node to have the same
|
||||
context. Therefore, we can and should remove the assertion to that
|
||||
effect.
|
||||
|
||||
In addition, because the context can be set and queried from different
|
||||
threads concurrently, it has to be accessed with atomic operations.
|
||||
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-19381
|
||||
Suggested-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Message-ID: <20240202144755.671354-2-hreitz@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit ad893672027ffe26db498947d70cde6d4f58a111)
|
||||
---
|
||||
block/block-backend.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/block/block-backend.c b/block/block-backend.c
|
||||
index 209eb07528..9c4de79e6b 100644
|
||||
--- a/block/block-backend.c
|
||||
+++ b/block/block-backend.c
|
||||
@@ -44,7 +44,7 @@ struct BlockBackend {
|
||||
char *name;
|
||||
int refcnt;
|
||||
BdrvChild *root;
|
||||
- AioContext *ctx;
|
||||
+ AioContext *ctx; /* access with atomic operations only */
|
||||
DriveInfo *legacy_dinfo; /* null unless created by drive_new() */
|
||||
QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */
|
||||
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
|
||||
@@ -2414,22 +2414,22 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Return BB's current AioContext. Note that this context may change
|
||||
+ * concurrently at any time, with one exception: If the BB has a root node
|
||||
+ * attached, its context will only change through bdrv_try_change_aio_context(),
|
||||
+ * which creates a drained section. Therefore, incrementing such a BB's
|
||||
+ * in-flight counter will prevent its context from changing.
|
||||
+ */
|
||||
AioContext *blk_get_aio_context(BlockBackend *blk)
|
||||
{
|
||||
- BlockDriverState *bs;
|
||||
IO_CODE();
|
||||
|
||||
if (!blk) {
|
||||
return qemu_get_aio_context();
|
||||
}
|
||||
|
||||
- bs = blk_bs(blk);
|
||||
- if (bs) {
|
||||
- AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
|
||||
- assert(ctx == blk->ctx);
|
||||
- }
|
||||
-
|
||||
- return blk->ctx;
|
||||
+ return qatomic_read(&blk->ctx);
|
||||
}
|
||||
|
||||
int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
|
||||
@@ -2442,7 +2442,7 @@ int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
|
||||
GLOBAL_STATE_CODE();
|
||||
|
||||
if (!bs) {
|
||||
- blk->ctx = new_context;
|
||||
+ qatomic_set(&blk->ctx, new_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2471,7 +2471,7 @@ static void blk_root_set_aio_ctx_commit(void *opaque)
|
||||
AioContext *new_context = s->new_ctx;
|
||||
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
|
||||
|
||||
- blk->ctx = new_context;
|
||||
+ qatomic_set(&blk->ctx, new_context);
|
||||
if (tgm->throttle_state) {
|
||||
throttle_group_detach_aio_context(tgm);
|
||||
throttle_group_attach_aio_context(tgm, new_context);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,69 +0,0 @@
|
||||
From b1a68aebadecd7d339cf5eaffeda15099c998528 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 12 Sep 2023 19:10:37 -0400
|
||||
Subject: [PATCH 095/101] block-coroutine-wrapper: use
|
||||
qemu_get_current_aio_context()
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [26/26] cde767bcdc626e90721792e3889952057a548ac5 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Use qemu_get_current_aio_context() in mixed wrappers and coroutine
|
||||
wrappers so that code runs in the caller's AioContext instead of moving
|
||||
to the BlockDriverState's AioContext. This change is necessary for the
|
||||
multi-queue block layer where any thread can call into the block layer.
|
||||
|
||||
Most wrappers are IO_CODE where it's safe to use the current AioContext
|
||||
nowadays. BlockDrivers and the core block layer use their own locks and
|
||||
no longer depend on the AioContext lock for thread-safety.
|
||||
|
||||
The bdrv_create() wrapper invokes GLOBAL_STATE code. Using the current
|
||||
AioContext is safe because this code is only called with the BQL held
|
||||
from the main loop thread.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20230912231037.826804-6-stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
scripts/block-coroutine-wrapper.py | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py
|
||||
index c9c09fcacd..dbbde99e39 100644
|
||||
--- a/scripts/block-coroutine-wrapper.py
|
||||
+++ b/scripts/block-coroutine-wrapper.py
|
||||
@@ -92,8 +92,6 @@ def __init__(self, wrapper_type: str, return_type: str, name: str,
|
||||
f"{self.name}")
|
||||
self.target_name = f'{subsystem}_{subname}'
|
||||
|
||||
- self.ctx = self.gen_ctx()
|
||||
-
|
||||
self.get_result = 's->ret = '
|
||||
self.ret = 'return s.ret;'
|
||||
self.co_ret = 'return '
|
||||
@@ -167,7 +165,7 @@ def create_mixed_wrapper(func: FuncDecl) -> str:
|
||||
{func.co_ret}{name}({ func.gen_list('{name}') });
|
||||
}} else {{
|
||||
{struct_name} s = {{
|
||||
- .poll_state.ctx = {func.ctx},
|
||||
+ .poll_state.ctx = qemu_get_current_aio_context(),
|
||||
.poll_state.in_progress = true,
|
||||
|
||||
{ func.gen_block(' .{name} = {name},') }
|
||||
@@ -191,7 +189,7 @@ def create_co_wrapper(func: FuncDecl) -> str:
|
||||
{func.return_type} {func.name}({ func.gen_list('{decl}') })
|
||||
{{
|
||||
{struct_name} s = {{
|
||||
- .poll_state.ctx = {func.ctx},
|
||||
+ .poll_state.ctx = qemu_get_current_aio_context(),
|
||||
.poll_state.in_progress = true,
|
||||
|
||||
{ func.gen_block(' .{name} = {name},') }
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,217 +0,0 @@
|
||||
From 25cce5df341861e8ba8ec57722558e2dee3ce56a Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 14 Sep 2023 10:00:58 -0400
|
||||
Subject: [PATCH 073/101] block/file-posix: set up Linux AIO and io_uring in
|
||||
the current thread
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [4/26] 74c7daf805daefe706378308c3afeb28d861164b (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The file-posix block driver currently only sets up Linux AIO and
|
||||
io_uring in the BDS's AioContext. In the multi-queue block layer we must
|
||||
be able to submit I/O requests in AioContexts that do not have Linux AIO
|
||||
and io_uring set up yet since any thread can call into the block driver.
|
||||
|
||||
Set up Linux AIO and io_uring for the current AioContext during request
|
||||
submission. We lose the ability to return an error from
|
||||
.bdrv_file_open() when Linux AIO and io_uring setup fails (e.g. due to
|
||||
resource limits). Instead the user only gets warnings and we fall back
|
||||
to aio=threads. This is still better than a fatal error after startup.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20230914140101.1065008-2-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/file-posix.c | 103 ++++++++++++++++++++++-----------------------
|
||||
1 file changed, 51 insertions(+), 52 deletions(-)
|
||||
|
||||
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||
index b862406c71..35684f7e21 100644
|
||||
--- a/block/file-posix.c
|
||||
+++ b/block/file-posix.c
|
||||
@@ -712,17 +712,11 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
/* Currently Linux does AIO only for files opened with O_DIRECT */
|
||||
- if (s->use_linux_aio) {
|
||||
- if (!(s->open_flags & O_DIRECT)) {
|
||||
- error_setg(errp, "aio=native was specified, but it requires "
|
||||
- "cache.direct=on, which was not specified.");
|
||||
- ret = -EINVAL;
|
||||
- goto fail;
|
||||
- }
|
||||
- if (!aio_setup_linux_aio(bdrv_get_aio_context(bs), errp)) {
|
||||
- error_prepend(errp, "Unable to use native AIO: ");
|
||||
- goto fail;
|
||||
- }
|
||||
+ if (s->use_linux_aio && !(s->open_flags & O_DIRECT)) {
|
||||
+ error_setg(errp, "aio=native was specified, but it requires "
|
||||
+ "cache.direct=on, which was not specified.");
|
||||
+ ret = -EINVAL;
|
||||
+ goto fail;
|
||||
}
|
||||
#else
|
||||
if (s->use_linux_aio) {
|
||||
@@ -733,14 +727,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
#endif /* !defined(CONFIG_LINUX_AIO) */
|
||||
|
||||
-#ifdef CONFIG_LINUX_IO_URING
|
||||
- if (s->use_linux_io_uring) {
|
||||
- if (!aio_setup_linux_io_uring(bdrv_get_aio_context(bs), errp)) {
|
||||
- error_prepend(errp, "Unable to use io_uring: ");
|
||||
- goto fail;
|
||||
- }
|
||||
- }
|
||||
-#else
|
||||
+#ifndef CONFIG_LINUX_IO_URING
|
||||
if (s->use_linux_io_uring) {
|
||||
error_setg(errp, "aio=io_uring was specified, but is not supported "
|
||||
"in this build.");
|
||||
@@ -2444,6 +2431,48 @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
|
||||
return true;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_LINUX_IO_URING
|
||||
+static inline bool raw_check_linux_io_uring(BDRVRawState *s)
|
||||
+{
|
||||
+ Error *local_err = NULL;
|
||||
+ AioContext *ctx;
|
||||
+
|
||||
+ if (!s->use_linux_io_uring) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ ctx = qemu_get_current_aio_context();
|
||||
+ if (unlikely(!aio_setup_linux_io_uring(ctx, &local_err))) {
|
||||
+ error_reportf_err(local_err, "Unable to use linux io_uring, "
|
||||
+ "falling back to thread pool: ");
|
||||
+ s->use_linux_io_uring = false;
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#ifdef CONFIG_LINUX_AIO
|
||||
+static inline bool raw_check_linux_aio(BDRVRawState *s)
|
||||
+{
|
||||
+ Error *local_err = NULL;
|
||||
+ AioContext *ctx;
|
||||
+
|
||||
+ if (!s->use_linux_aio) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ ctx = qemu_get_current_aio_context();
|
||||
+ if (unlikely(!aio_setup_linux_aio(ctx, &local_err))) {
|
||||
+ error_reportf_err(local_err, "Unable to use Linux AIO, "
|
||||
+ "falling back to thread pool: ");
|
||||
+ s->use_linux_aio = false;
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr,
|
||||
uint64_t bytes, QEMUIOVector *qiov, int type)
|
||||
{
|
||||
@@ -2474,13 +2503,13 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr,
|
||||
if (s->needs_alignment && !bdrv_qiov_is_aligned(bs, qiov)) {
|
||||
type |= QEMU_AIO_MISALIGNED;
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
- } else if (s->use_linux_io_uring) {
|
||||
+ } else if (raw_check_linux_io_uring(s)) {
|
||||
assert(qiov->size == bytes);
|
||||
ret = luring_co_submit(bs, s->fd, offset, qiov, type);
|
||||
goto out;
|
||||
#endif
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
- } else if (s->use_linux_aio) {
|
||||
+ } else if (raw_check_linux_aio(s)) {
|
||||
assert(qiov->size == bytes);
|
||||
ret = laio_co_submit(s->fd, offset, qiov, type,
|
||||
s->aio_max_batch);
|
||||
@@ -2567,39 +2596,13 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
- if (s->use_linux_io_uring) {
|
||||
+ if (raw_check_linux_io_uring(s)) {
|
||||
return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH);
|
||||
}
|
||||
#endif
|
||||
return raw_thread_pool_submit(handle_aiocb_flush, &acb);
|
||||
}
|
||||
|
||||
-static void raw_aio_attach_aio_context(BlockDriverState *bs,
|
||||
- AioContext *new_context)
|
||||
-{
|
||||
- BDRVRawState __attribute__((unused)) *s = bs->opaque;
|
||||
-#ifdef CONFIG_LINUX_AIO
|
||||
- if (s->use_linux_aio) {
|
||||
- Error *local_err = NULL;
|
||||
- if (!aio_setup_linux_aio(new_context, &local_err)) {
|
||||
- error_reportf_err(local_err, "Unable to use native AIO, "
|
||||
- "falling back to thread pool: ");
|
||||
- s->use_linux_aio = false;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-#ifdef CONFIG_LINUX_IO_URING
|
||||
- if (s->use_linux_io_uring) {
|
||||
- Error *local_err = NULL;
|
||||
- if (!aio_setup_linux_io_uring(new_context, &local_err)) {
|
||||
- error_reportf_err(local_err, "Unable to use linux io_uring, "
|
||||
- "falling back to thread pool: ");
|
||||
- s->use_linux_io_uring = false;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
static void raw_close(BlockDriverState *bs)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
@@ -3896,7 +3899,6 @@ BlockDriver bdrv_file = {
|
||||
.bdrv_co_copy_range_from = raw_co_copy_range_from,
|
||||
.bdrv_co_copy_range_to = raw_co_copy_range_to,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
- .bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
@@ -4266,7 +4268,6 @@ static BlockDriver bdrv_host_device = {
|
||||
.bdrv_co_copy_range_from = raw_co_copy_range_from,
|
||||
.bdrv_co_copy_range_to = raw_co_copy_range_to,
|
||||
.bdrv_refresh_limits = raw_refresh_limits,
|
||||
- .bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
@@ -4402,7 +4403,6 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.bdrv_co_pwritev = raw_co_pwritev,
|
||||
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
|
||||
.bdrv_refresh_limits = cdrom_refresh_limits,
|
||||
- .bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
@@ -4528,7 +4528,6 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.bdrv_co_pwritev = raw_co_pwritev,
|
||||
.bdrv_co_flush_to_disk = raw_co_flush_to_disk,
|
||||
.bdrv_refresh_limits = cdrom_refresh_limits,
|
||||
- .bdrv_attach_aio_context = raw_aio_attach_aio_context,
|
||||
|
||||
.bdrv_co_truncate = raw_co_truncate,
|
||||
.bdrv_co_getlength = raw_co_getlength,
|
||||
--
|
||||
2.39.3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
From d0514c7d5d6cc1aa140119c95d5ea2c1591b01e9 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:04 -0500
|
||||
Subject: [PATCH 087/101] block: remove bdrv_co_lock()
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [18/26] a303f861ea5e84d8e89fd51e530fd0cb2da17b89 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The bdrv_co_lock() and bdrv_co_unlock() functions are already no-ops.
|
||||
Remove them.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-8-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block.c | 10 ----------
|
||||
blockdev.c | 5 -----
|
||||
include/block/block-global-state.h | 14 --------------
|
||||
3 files changed, 29 deletions(-)
|
||||
|
||||
diff --git a/block.c b/block.c
|
||||
index 91ace5d2d5..434b7f4d72 100644
|
||||
--- a/block.c
|
||||
+++ b/block.c
|
||||
@@ -7431,16 +7431,6 @@ void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx)
|
||||
bdrv_dec_in_flight(bs);
|
||||
}
|
||||
|
||||
-void coroutine_fn bdrv_co_lock(BlockDriverState *bs)
|
||||
-{
|
||||
- /* TODO removed in next patch */
|
||||
-}
|
||||
-
|
||||
-void coroutine_fn bdrv_co_unlock(BlockDriverState *bs)
|
||||
-{
|
||||
- /* TODO removed in next patch */
|
||||
-}
|
||||
-
|
||||
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
diff --git a/blockdev.c b/blockdev.c
|
||||
index 5d8b3a23eb..3a5e7222ec 100644
|
||||
--- a/blockdev.c
|
||||
+++ b/blockdev.c
|
||||
@@ -2264,18 +2264,13 @@ void coroutine_fn qmp_block_resize(const char *device, const char *node_name,
|
||||
return;
|
||||
}
|
||||
|
||||
- bdrv_co_lock(bs);
|
||||
bdrv_drained_begin(bs);
|
||||
- bdrv_co_unlock(bs);
|
||||
|
||||
old_ctx = bdrv_co_enter(bs);
|
||||
blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
|
||||
bdrv_co_leave(bs, old_ctx);
|
||||
|
||||
- bdrv_co_lock(bs);
|
||||
bdrv_drained_end(bs);
|
||||
- bdrv_co_unlock(bs);
|
||||
-
|
||||
blk_co_unref(blk);
|
||||
}
|
||||
|
||||
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
|
||||
index 0327f1c605..4ec0b217f0 100644
|
||||
--- a/include/block/block-global-state.h
|
||||
+++ b/include/block/block-global-state.h
|
||||
@@ -267,20 +267,6 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
|
||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
|
||||
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
|
||||
|
||||
-/**
|
||||
- * Locks the AioContext of @bs if it's not the current AioContext. This avoids
|
||||
- * double locking which could lead to deadlocks: This is a coroutine_fn, so we
|
||||
- * know we already own the lock of the current AioContext.
|
||||
- *
|
||||
- * May only be called in the main thread.
|
||||
- */
|
||||
-void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
|
||||
-
|
||||
-/**
|
||||
- * Unlocks the AioContext of @bs if it's not the current AioContext.
|
||||
- */
|
||||
-void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
|
||||
-
|
||||
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,411 +0,0 @@
|
||||
From dc4eb64185957a01948217814478abc450ce5f26 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:11 -0500
|
||||
Subject: [PATCH 094/101] block: remove outdated AioContext locking comments
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [25/26] 395e18fb40d28d4bc961acee1a00da7f60748076 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The AioContext lock no longer exists.
|
||||
|
||||
There is one noteworthy change:
|
||||
|
||||
- * More specifically, these functions use BDRV_POLL_WHILE(bs), which
|
||||
- * requires the caller to be either in the main thread and hold
|
||||
- * the BlockdriverState (bs) AioContext lock, or directly in the
|
||||
- * home thread that runs the bs AioContext. Calling them from
|
||||
- * another thread in another AioContext would cause deadlocks.
|
||||
+ * More specifically, these functions use BDRV_POLL_WHILE(bs), which requires
|
||||
+ * the caller to be either in the main thread or directly in the home thread
|
||||
+ * that runs the bs AioContext. Calling them from another thread in another
|
||||
+ * AioContext would cause deadlocks.
|
||||
|
||||
I am not sure whether deadlocks are still possible. Maybe they have just
|
||||
moved to the fine-grained locks that have replaced the AioContext. Since
|
||||
I am not sure if the deadlocks are gone, I have kept the substance
|
||||
unchanged and just removed mention of the AioContext.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-15-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block.c | 73 ++++++----------------------
|
||||
block/block-backend.c | 8 ---
|
||||
block/export/vhost-user-blk-server.c | 4 --
|
||||
include/block/block-common.h | 3 --
|
||||
include/block/block-io.h | 9 ++--
|
||||
include/block/block_int-common.h | 2 -
|
||||
tests/qemu-iotests/202 | 2 +-
|
||||
tests/qemu-iotests/203 | 3 +-
|
||||
8 files changed, 22 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/block.c b/block.c
|
||||
index 434b7f4d72..a097772238 100644
|
||||
--- a/block.c
|
||||
+++ b/block.c
|
||||
@@ -1616,11 +1616,6 @@ out:
|
||||
g_free(gen_node_name);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * The caller must always hold @bs AioContext lock, because this function calls
|
||||
- * bdrv_refresh_total_sectors() which polls when called from non-coroutine
|
||||
- * context.
|
||||
- */
|
||||
static int no_coroutine_fn GRAPH_UNLOCKED
|
||||
bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, const char *node_name,
|
||||
QDict *options, int open_flags, Error **errp)
|
||||
@@ -2901,7 +2896,7 @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
|
||||
* Replaces the node that a BdrvChild points to without updating permissions.
|
||||
*
|
||||
* If @new_bs is non-NULL, the parent of @child must already be drained through
|
||||
- * @child and the caller must hold the AioContext lock for @new_bs.
|
||||
+ * @child.
|
||||
*/
|
||||
static void GRAPH_WRLOCK
|
||||
bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs)
|
||||
@@ -3041,9 +3036,8 @@ static TransactionActionDrv bdrv_attach_child_common_drv = {
|
||||
*
|
||||
* Returns new created child.
|
||||
*
|
||||
- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
|
||||
- * @child_bs can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * Both @parent_bs and @child_bs can move to a different AioContext in this
|
||||
+ * function.
|
||||
*/
|
||||
static BdrvChild * GRAPH_WRLOCK
|
||||
bdrv_attach_child_common(BlockDriverState *child_bs,
|
||||
@@ -3142,9 +3136,8 @@ bdrv_attach_child_common(BlockDriverState *child_bs,
|
||||
/*
|
||||
* Function doesn't update permissions, caller is responsible for this.
|
||||
*
|
||||
- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
|
||||
- * @child_bs can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * Both @parent_bs and @child_bs can move to a different AioContext in this
|
||||
+ * function.
|
||||
*
|
||||
* After calling this function, the transaction @tran may only be completed
|
||||
* while holding a writer lock for the graph.
|
||||
@@ -3184,9 +3177,6 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs,
|
||||
*
|
||||
* On failure NULL is returned, errp is set and the reference to
|
||||
* child_bs is also dropped.
|
||||
- *
|
||||
- * The caller must hold the AioContext lock @child_bs, but not that of @ctx
|
||||
- * (unless @child_bs is already in @ctx).
|
||||
*/
|
||||
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
|
||||
const char *child_name,
|
||||
@@ -3226,9 +3216,6 @@ out:
|
||||
*
|
||||
* On failure NULL is returned, errp is set and the reference to
|
||||
* child_bs is also dropped.
|
||||
- *
|
||||
- * If @parent_bs and @child_bs are in different AioContexts, the caller must
|
||||
- * hold the AioContext lock for @child_bs, but not for @parent_bs.
|
||||
*/
|
||||
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
|
||||
BlockDriverState *child_bs,
|
||||
@@ -3418,9 +3405,8 @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
|
||||
*
|
||||
* Function doesn't update permissions, caller is responsible for this.
|
||||
*
|
||||
- * The caller must hold the AioContext lock for @child_bs. Both @parent_bs and
|
||||
- * @child_bs can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * Both @parent_bs and @child_bs can move to a different AioContext in this
|
||||
+ * function.
|
||||
*
|
||||
* After calling this function, the transaction @tran may only be completed
|
||||
* while holding a writer lock for the graph.
|
||||
@@ -3513,9 +3499,8 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
- * The caller must hold the AioContext lock for @backing_hd. Both @bs and
|
||||
- * @backing_hd can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * Both @bs and @backing_hd can move to a different AioContext in this
|
||||
+ * function.
|
||||
*
|
||||
* If a backing child is already present (i.e. we're detaching a node), that
|
||||
* child node must be drained.
|
||||
@@ -3574,8 +3559,6 @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
* itself, all options starting with "${bdref_key}." are considered part of the
|
||||
* BlockdevRef.
|
||||
*
|
||||
- * The caller must hold the main AioContext lock.
|
||||
- *
|
||||
* TODO Can this be unified with bdrv_open_image()?
|
||||
*/
|
||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
@@ -3745,9 +3728,7 @@ done:
|
||||
*
|
||||
* The BlockdevRef will be removed from the options QDict.
|
||||
*
|
||||
- * The caller must hold the lock of the main AioContext and no other AioContext.
|
||||
- * @parent can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * @parent can move to a different AioContext in this function.
|
||||
*/
|
||||
BdrvChild *bdrv_open_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
@@ -3778,9 +3759,7 @@ BdrvChild *bdrv_open_child(const char *filename,
|
||||
/*
|
||||
* Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
|
||||
*
|
||||
- * The caller must hold the lock of the main AioContext and no other AioContext.
|
||||
- * @parent can move to a different AioContext in this function. Callers must
|
||||
- * make sure that their AioContext locking is still correct after this.
|
||||
+ * @parent can move to a different AioContext in this function.
|
||||
*/
|
||||
int bdrv_open_file_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
@@ -3923,8 +3902,6 @@ out:
|
||||
* The reference parameter may be used to specify an existing block device which
|
||||
* should be opened. If specified, neither options nor a filename may be given,
|
||||
* nor can an existing BDS be reused (that is, *pbs has to be NULL).
|
||||
- *
|
||||
- * The caller must always hold the main AioContext lock.
|
||||
*/
|
||||
static BlockDriverState * no_coroutine_fn
|
||||
bdrv_open_inherit(const char *filename, const char *reference, QDict *options,
|
||||
@@ -4217,7 +4194,6 @@ close_and_fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-/* The caller must always hold the main AioContext lock. */
|
||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp)
|
||||
{
|
||||
@@ -4665,10 +4641,7 @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
*
|
||||
* Return 0 on success, otherwise return < 0 and set @errp.
|
||||
*
|
||||
- * The caller must hold the AioContext lock of @reopen_state->bs.
|
||||
* @reopen_state->bs can move to a different AioContext in this function.
|
||||
- * Callers must make sure that their AioContext locking is still correct after
|
||||
- * this.
|
||||
*/
|
||||
static int GRAPH_UNLOCKED
|
||||
bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
|
||||
@@ -4801,8 +4774,6 @@ out_rdlock:
|
||||
* It is the responsibility of the caller to then call the abort() or
|
||||
* commit() for any other BDS that have been left in a prepare() state
|
||||
*
|
||||
- * The caller must hold the AioContext lock of @reopen_state->bs.
|
||||
- *
|
||||
* After calling this function, the transaction @change_child_tran may only be
|
||||
* completed while holding a writer lock for the graph.
|
||||
*/
|
||||
@@ -5437,8 +5408,6 @@ int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
|
||||
* child.
|
||||
*
|
||||
* This function does not create any image files.
|
||||
- *
|
||||
- * The caller must hold the AioContext lock for @bs_top.
|
||||
*/
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp)
|
||||
@@ -5545,9 +5514,8 @@ static void bdrv_delete(BlockDriverState *bs)
|
||||
* after the call (even on failure), so if the caller intends to reuse the
|
||||
* dictionary, it needs to use qobject_ref() before calling bdrv_open.
|
||||
*
|
||||
- * The caller holds the AioContext lock for @bs. It must make sure that @bs
|
||||
- * stays in the same AioContext, i.e. @options must not refer to nodes in a
|
||||
- * different AioContext.
|
||||
+ * The caller must make sure that @bs stays in the same AioContext, i.e.
|
||||
+ * @options must not refer to nodes in a different AioContext.
|
||||
*/
|
||||
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
|
||||
int flags, Error **errp)
|
||||
@@ -7565,10 +7533,6 @@ static TransactionActionDrv set_aio_context = {
|
||||
*
|
||||
* Must be called from the main AioContext.
|
||||
*
|
||||
- * The caller must own the AioContext lock for the old AioContext of bs, but it
|
||||
- * must not own the AioContext lock for new_context (unless new_context is the
|
||||
- * same as the current context of bs).
|
||||
- *
|
||||
* @visited will accumulate all visited BdrvChild objects. The caller is
|
||||
* responsible for freeing the list afterwards.
|
||||
*/
|
||||
@@ -7621,13 +7585,6 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
*
|
||||
* If ignore_child is not NULL, that child (and its subgraph) will not
|
||||
* be touched.
|
||||
- *
|
||||
- * This function still requires the caller to take the bs current
|
||||
- * AioContext lock, otherwise draining will fail since AIO_WAIT_WHILE
|
||||
- * assumes the lock is always held if bs is in another AioContext.
|
||||
- * For the same reason, it temporarily also holds the new AioContext, since
|
||||
- * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too.
|
||||
- * Therefore the new AioContext lock must not be taken by the caller.
|
||||
*/
|
||||
int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
BdrvChild *ignore_child, Error **errp)
|
||||
@@ -7653,8 +7610,8 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
|
||||
/*
|
||||
* Linear phase: go through all callbacks collected in the transaction.
|
||||
- * Run all callbacks collected in the recursion to switch all nodes
|
||||
- * AioContext lock (transaction commit), or undo all changes done in the
|
||||
+ * Run all callbacks collected in the recursion to switch every node's
|
||||
+ * AioContext (transaction commit), or undo all changes done in the
|
||||
* recursion (transaction abort).
|
||||
*/
|
||||
|
||||
diff --git a/block/block-backend.c b/block/block-backend.c
|
||||
index f412bed274..209eb07528 100644
|
||||
--- a/block/block-backend.c
|
||||
+++ b/block/block-backend.c
|
||||
@@ -390,8 +390,6 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
|
||||
* Both sets of permissions can be changed later using blk_set_perm().
|
||||
*
|
||||
* Return the new BlockBackend on success, null on failure.
|
||||
- *
|
||||
- * Callers must hold the AioContext lock of @bs.
|
||||
*/
|
||||
BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
|
||||
uint64_t shared_perm, Error **errp)
|
||||
@@ -416,8 +414,6 @@ BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
|
||||
* Just as with bdrv_open(), after having called this function the reference to
|
||||
* @options belongs to the block layer (even on failure).
|
||||
*
|
||||
- * Called without holding an AioContext lock.
|
||||
- *
|
||||
* TODO: Remove @filename and @flags; it should be possible to specify a whole
|
||||
* BDS tree just by specifying the @options QDict (or @reference,
|
||||
* alternatively). At the time of adding this function, this is not possible,
|
||||
@@ -872,8 +868,6 @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
|
||||
|
||||
/*
|
||||
* Disassociates the currently associated BlockDriverState from @blk.
|
||||
- *
|
||||
- * The caller must hold the AioContext lock for the BlockBackend.
|
||||
*/
|
||||
void blk_remove_bs(BlockBackend *blk)
|
||||
{
|
||||
@@ -915,8 +909,6 @@ void blk_remove_bs(BlockBackend *blk)
|
||||
|
||||
/*
|
||||
* Associates a new BlockDriverState with @blk.
|
||||
- *
|
||||
- * Callers must hold the AioContext lock of @bs.
|
||||
*/
|
||||
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c
|
||||
index 16f48388d3..50c358e8cd 100644
|
||||
--- a/block/export/vhost-user-blk-server.c
|
||||
+++ b/block/export/vhost-user-blk-server.c
|
||||
@@ -278,7 +278,6 @@ static void vu_blk_exp_resize(void *opaque)
|
||||
vu_config_change_msg(&vexp->vu_server.vu_dev);
|
||||
}
|
||||
|
||||
-/* Called with vexp->export.ctx acquired */
|
||||
static void vu_blk_drained_begin(void *opaque)
|
||||
{
|
||||
VuBlkExport *vexp = opaque;
|
||||
@@ -287,7 +286,6 @@ static void vu_blk_drained_begin(void *opaque)
|
||||
vhost_user_server_detach_aio_context(&vexp->vu_server);
|
||||
}
|
||||
|
||||
-/* Called with vexp->export.blk AioContext acquired */
|
||||
static void vu_blk_drained_end(void *opaque)
|
||||
{
|
||||
VuBlkExport *vexp = opaque;
|
||||
@@ -300,8 +298,6 @@ static void vu_blk_drained_end(void *opaque)
|
||||
* Ensures that bdrv_drained_begin() waits until in-flight requests complete
|
||||
* and the server->co_trip coroutine has terminated. It will be restarted in
|
||||
* vhost_user_server_attach_aio_context().
|
||||
- *
|
||||
- * Called with vexp->export.ctx acquired.
|
||||
*/
|
||||
static bool vu_blk_drained_poll(void *opaque)
|
||||
{
|
||||
diff --git a/include/block/block-common.h b/include/block/block-common.h
|
||||
index d7599564db..a846023a09 100644
|
||||
--- a/include/block/block-common.h
|
||||
+++ b/include/block/block-common.h
|
||||
@@ -70,9 +70,6 @@
|
||||
* automatically takes the graph rdlock when calling the wrapped function. In
|
||||
* the same way, no_co_wrapper_bdrv_wrlock functions automatically take the
|
||||
* graph wrlock.
|
||||
- *
|
||||
- * If the first parameter of the function is a BlockDriverState, BdrvChild or
|
||||
- * BlockBackend pointer, the AioContext lock for it is taken in the wrapper.
|
||||
*/
|
||||
#define no_co_wrapper
|
||||
#define no_co_wrapper_bdrv_rdlock
|
||||
diff --git a/include/block/block-io.h b/include/block/block-io.h
|
||||
index 8eb39a858b..b49e0537dd 100644
|
||||
--- a/include/block/block-io.h
|
||||
+++ b/include/block/block-io.h
|
||||
@@ -332,11 +332,10 @@ bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
||||
* "I/O or GS" API functions. These functions can run without
|
||||
* the BQL, but only in one specific iothread/main loop.
|
||||
*
|
||||
- * More specifically, these functions use BDRV_POLL_WHILE(bs), which
|
||||
- * requires the caller to be either in the main thread and hold
|
||||
- * the BlockdriverState (bs) AioContext lock, or directly in the
|
||||
- * home thread that runs the bs AioContext. Calling them from
|
||||
- * another thread in another AioContext would cause deadlocks.
|
||||
+ * More specifically, these functions use BDRV_POLL_WHILE(bs), which requires
|
||||
+ * the caller to be either in the main thread or directly in the home thread
|
||||
+ * that runs the bs AioContext. Calling them from another thread in another
|
||||
+ * AioContext would cause deadlocks.
|
||||
*
|
||||
* Therefore, these functions are not proper I/O, because they
|
||||
* can't run in *any* iothreads, but only in a specific one.
|
||||
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
|
||||
index 4e31d161c5..151279d481 100644
|
||||
--- a/include/block/block_int-common.h
|
||||
+++ b/include/block/block_int-common.h
|
||||
@@ -1192,8 +1192,6 @@ struct BlockDriverState {
|
||||
/* The error object in use for blocking operations on backing_hd */
|
||||
Error *backing_blocker;
|
||||
|
||||
- /* Protected by AioContext lock */
|
||||
-
|
||||
/*
|
||||
* If we are reading a disk image, give its size in sectors.
|
||||
* Generally read-only; it is written to by load_snapshot and
|
||||
diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202
|
||||
index b784dcd791..13304242e5 100755
|
||||
--- a/tests/qemu-iotests/202
|
||||
+++ b/tests/qemu-iotests/202
|
||||
@@ -21,7 +21,7 @@
|
||||
# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a
|
||||
# single IOThread completes successfully. This particular command triggered a
|
||||
# hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect
|
||||
-# against regressions.
|
||||
+# against regressions even though the AioContext lock no longer exists.
|
||||
|
||||
import iotests
|
||||
|
||||
diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203
|
||||
index ab80fd0e44..1ba878522b 100755
|
||||
--- a/tests/qemu-iotests/203
|
||||
+++ b/tests/qemu-iotests/203
|
||||
@@ -21,7 +21,8 @@
|
||||
# Check that QMP 'migrate' with multiple drives on a single IOThread completes
|
||||
# successfully. This particular command triggered a hang in the source QEMU
|
||||
# process due to recursive AioContext locking in bdrv_invalidate_all() and
|
||||
-# BDRV_POLL_WHILE().
|
||||
+# BDRV_POLL_WHILE(). Protect against regressions even though the AioContext
|
||||
+# lock no longer exists.
|
||||
|
||||
import iotests
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,105 +0,0 @@
|
||||
From 95b2ffc5f01dc4309c2e747ed883d22cd1d26347 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Sat, 2 Mar 2024 17:00:23 +0100
|
||||
Subject: [PATCH 2/2] chardev/char-socket: Fix TLS io channels sending too much
|
||||
data to the backend
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 227: Fix TLS io channels sending too much data to the backend
|
||||
RH-Jira: RHEL-24614
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-Commit: [1/1] fce871914e0ce52e16a6edae0e007513f9fec1ae (thuth/qemu-kvm-cs9)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-24614
|
||||
|
||||
commit 462945cd22d2bcd233401ed3aa167d83a8e35b05
|
||||
Author: Thomas Huth <thuth@redhat.com>
|
||||
Date: Thu Feb 29 11:43:37 2024 +0100
|
||||
|
||||
chardev/char-socket: Fix TLS io channels sending too much data to the backend
|
||||
|
||||
Commit ffda5db65a ("io/channel-tls: fix handling of bigger read buffers")
|
||||
changed the behavior of the TLS io channels to schedule a second reading
|
||||
attempt if there is still incoming data pending. This caused a regression
|
||||
with backends like the sclpconsole that check in their read function that
|
||||
the sender does not try to write more bytes to it than the device can
|
||||
currently handle.
|
||||
|
||||
The problem can be reproduced like this:
|
||||
|
||||
1) In one terminal, do this:
|
||||
|
||||
mkdir qemu-pki
|
||||
cd qemu-pki
|
||||
openssl genrsa 2048 > ca-key.pem
|
||||
openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
|
||||
# enter some dummy value for the cert
|
||||
openssl genrsa 2048 > server-key.pem
|
||||
openssl req -new -x509 -nodes -days 365000 -key server-key.pem \
|
||||
-out server-cert.pem
|
||||
# enter some other dummy values for the cert
|
||||
|
||||
gnutls-serv --echo --x509cafile ca-cert.pem --x509keyfile server-key.pem \
|
||||
--x509certfile server-cert.pem -p 8338
|
||||
|
||||
2) In another terminal, do this:
|
||||
|
||||
wget https://download.fedoraproject.org/pub/fedora-secondary/releases/39/Cloud/s390x/images/Fedora-Cloud-Base-39-1.5.s390x.qcow2
|
||||
|
||||
qemu-system-s390x -nographic -nodefaults \
|
||||
-hda Fedora-Cloud-Base-39-1.5.s390x.qcow2 \
|
||||
-object tls-creds-x509,id=tls0,endpoint=client,verify-peer=false,dir=$PWD/qemu-pki \
|
||||
-chardev socket,id=tls_chardev,host=localhost,port=8338,tls-creds=tls0 \
|
||||
-device sclpconsole,chardev=tls_chardev,id=tls_serial
|
||||
|
||||
QEMU then aborts after a second or two with:
|
||||
|
||||
qemu-system-s390x: ../hw/char/sclpconsole.c:73: chr_read: Assertion
|
||||
`size <= SIZE_BUFFER_VT220 - scon->iov_data_len' failed.
|
||||
Aborted (core dumped)
|
||||
|
||||
It looks like the second read does not trigger the chr_can_read() function
|
||||
to be called before the second read, which should normally always be done
|
||||
before sending bytes to a character device to see how much it can handle,
|
||||
so the s->max_size in tcp_chr_read() still contains the old value from the
|
||||
previous read. Let's make sure that we use the up-to-date value by calling
|
||||
tcp_chr_read_poll() again here.
|
||||
|
||||
Fixes: ffda5db65a ("io/channel-tls: fix handling of bigger read buffers")
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-24614
|
||||
Reviewed-by: "Daniel P. Berrangé" <berrange@redhat.com>
|
||||
Message-ID: <20240229104339.42574-1-thuth@redhat.com>
|
||||
Reviewed-by: Antoine Damhet <antoine.damhet@blade-group.com>
|
||||
Tested-by: Antoine Damhet <antoine.damhet@blade-group.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
chardev/char-socket.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
|
||||
index 73947da188..034840593d 100644
|
||||
--- a/chardev/char-socket.c
|
||||
+++ b/chardev/char-socket.c
|
||||
@@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
s->max_size <= 0) {
|
||||
return TRUE;
|
||||
}
|
||||
- len = sizeof(buf);
|
||||
- if (len > s->max_size) {
|
||||
- len = s->max_size;
|
||||
+ len = tcp_chr_read_poll(opaque);
|
||||
+ if (len > sizeof(buf)) {
|
||||
+ len = sizeof(buf);
|
||||
}
|
||||
size = tcp_chr_recv(chr, (void *)buf, len);
|
||||
if (size == 0 || (size == -1 && errno != EAGAIN)) {
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,78 +0,0 @@
|
||||
From 4d4102f6e2f9afd6182888787ae8b570347df87d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 18:06:59 +0000
|
||||
Subject: [PATCH 1/3] chardev: lower priority of the HUP GSource in socket
|
||||
chardev
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Daniel P. Berrangé <berrange@redhat.com>
|
||||
RH-MergeRequest: 233: Fix handling of TLS sessions in chardevs
|
||||
RH-Jira: RHEL-24614
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-Commit: [1/3] 842f54349191b0206e68f35a7a80155f5a584942 (berrange/centos-src-qemu)
|
||||
|
||||
The socket chardev often has 2 GSource object registered against the
|
||||
same FD. One is registered all the time and is just intended to handle
|
||||
POLLHUP events, while the other gets registered & unregistered on the
|
||||
fly as the frontend is ready to receive more data or not.
|
||||
|
||||
It is very common for poll() to signal a POLLHUP event at the same time
|
||||
as there is pending incoming data from the disconnected client. It is
|
||||
therefore essential to process incoming data prior to processing HUP.
|
||||
The problem with having 2 GSource on the same FD is that there is no
|
||||
guaranteed ordering of execution between them, so the chardev code may
|
||||
process HUP first and thus discard data.
|
||||
|
||||
This failure scenario is non-deterministic but can be seen fairly
|
||||
reliably by reverting a7077b8e354d90fec26c2921aa2dea85b90dff90, and
|
||||
then running 'tests/unit/test-char', which will sometimes fail with
|
||||
missing data.
|
||||
|
||||
Ideally QEMU would only have 1 GSource, but that's a complex code
|
||||
refactoring job. The next best solution is to try to ensure ordering
|
||||
between the 2 GSource objects. This can be achieved by lowering the
|
||||
priority of the HUP GSource, so that it is never dispatched if the
|
||||
main GSource is also ready to dispatch. Counter-intuitively, lowering
|
||||
the priority of a GSource is done by raising its priority number.
|
||||
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 8bd8b04adc9f18904f323dff085f8b4ec77915c6)
|
||||
---
|
||||
chardev/char-socket.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
|
||||
index 034840593d..f48d341ebc 100644
|
||||
--- a/chardev/char-socket.c
|
||||
+++ b/chardev/char-socket.c
|
||||
@@ -597,6 +597,22 @@ static void update_ioc_handlers(SocketChardev *s)
|
||||
|
||||
remove_hup_source(s);
|
||||
s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
|
||||
+ /*
|
||||
+ * poll() is liable to return POLLHUP even when there is
|
||||
+ * still incoming data available to read on the FD. If
|
||||
+ * we have the hup_source at the same priority as the
|
||||
+ * main io_add_watch_poll GSource, then we might end up
|
||||
+ * processing the POLLHUP event first, closing the FD,
|
||||
+ * and as a result silently discard data we should have
|
||||
+ * read.
|
||||
+ *
|
||||
+ * By setting the hup_source to G_PRIORITY_DEFAULT + 1,
|
||||
+ * we ensure that io_add_watch_poll GSource will always
|
||||
+ * be dispatched first, thus guaranteeing we will be
|
||||
+ * able to process all incoming data before closing the
|
||||
+ * FD
|
||||
+ */
|
||||
+ g_source_set_priority(s->hup_source, G_PRIORITY_DEFAULT + 1);
|
||||
g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
|
||||
chr, NULL);
|
||||
g_source_attach(s->hup_source, chr->gcontext);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,412 +0,0 @@
|
||||
From e99c56752a1c4021a93c92b7be78856ebefaa1b3 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 14:34:29 -0400
|
||||
Subject: [PATCH 1/2] coroutine: cap per-thread local pool size
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 234: coroutine: cap per-thread local pool size
|
||||
RH-Jira: RHEL-28947
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [1/2] 5971de1c1e238457925bfb9c4bfc932de857b28d (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
The coroutine pool implementation can hit the Linux vm.max_map_count
|
||||
limit, causing QEMU to abort with "failed to allocate memory for stack"
|
||||
or "failed to set up stack guard page" during coroutine creation.
|
||||
|
||||
This happens because per-thread pools can grow to tens of thousands of
|
||||
coroutines. Each coroutine causes 2 virtual memory areas to be created.
|
||||
Eventually vm.max_map_count is reached and memory-related syscalls fail.
|
||||
The per-thread pool sizes are non-uniform and depend on past coroutine
|
||||
usage in each thread, so it's possible for one thread to have a large
|
||||
pool while another thread's pool is empty.
|
||||
|
||||
Switch to a new coroutine pool implementation with a global pool that
|
||||
grows to a maximum number of coroutines and per-thread local pools that
|
||||
are capped at hardcoded small number of coroutines.
|
||||
|
||||
This approach does not leave large numbers of coroutines pooled in a
|
||||
thread that may not use them again. In order to perform well it
|
||||
amortizes the cost of global pool accesses by working in batches of
|
||||
coroutines instead of individual coroutines.
|
||||
|
||||
The global pool is a list. Threads donate batches of coroutines to when
|
||||
they have too many and take batches from when they have too few:
|
||||
|
||||
.-----------------------------------.
|
||||
| Batch 1 | Batch 2 | Batch 3 | ... | global_pool
|
||||
`-----------------------------------'
|
||||
|
||||
Each thread has up to 2 batches of coroutines:
|
||||
|
||||
.-------------------.
|
||||
| Batch 1 | Batch 2 | per-thread local_pool (maximum 2 batches)
|
||||
`-------------------'
|
||||
|
||||
The goal of this change is to reduce the excessive number of pooled
|
||||
coroutines that cause QEMU to abort when vm.max_map_count is reached
|
||||
without losing the performance of an adequately sized coroutine pool.
|
||||
|
||||
Here are virtio-blk disk I/O benchmark results:
|
||||
|
||||
RW BLKSIZE IODEPTH OLD NEW CHANGE
|
||||
randread 4k 1 113725 117451 +3.3%
|
||||
randread 4k 8 192968 198510 +2.9%
|
||||
randread 4k 16 207138 209429 +1.1%
|
||||
randread 4k 32 212399 215145 +1.3%
|
||||
randread 4k 64 218319 221277 +1.4%
|
||||
randread 128k 1 17587 17535 -0.3%
|
||||
randread 128k 8 17614 17616 +0.0%
|
||||
randread 128k 16 17608 17609 +0.0%
|
||||
randread 128k 32 17552 17553 +0.0%
|
||||
randread 128k 64 17484 17484 +0.0%
|
||||
|
||||
See files/{fio.sh,test.xml.j2} for the benchmark configuration:
|
||||
https://gitlab.com/stefanha/virt-playbooks/-/tree/coroutine-pool-fix-sizing
|
||||
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-28947
|
||||
Reported-by: Sanjay Rao <srao@redhat.com>
|
||||
Reported-by: Boaz Ben Shabat <bbenshab@redhat.com>
|
||||
Reported-by: Joe Mario <jmario@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20240318183429.1039340-1-stefanha@redhat.com>
|
||||
(cherry picked from commit 86a637e48104ae74d8be53bed6441ce32be33433)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
util/qemu-coroutine.c | 282 +++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 223 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
|
||||
index 5fd2dbaf8b..2790959eaf 100644
|
||||
--- a/util/qemu-coroutine.c
|
||||
+++ b/util/qemu-coroutine.c
|
||||
@@ -18,39 +18,200 @@
|
||||
#include "qemu/atomic.h"
|
||||
#include "qemu/coroutine_int.h"
|
||||
#include "qemu/coroutine-tls.h"
|
||||
+#include "qemu/cutils.h"
|
||||
#include "block/aio.h"
|
||||
|
||||
-/**
|
||||
- * The minimal batch size is always 64, coroutines from the release_pool are
|
||||
- * reused as soon as there are 64 coroutines in it. The maximum pool size starts
|
||||
- * with 64 and is increased on demand so that coroutines are not deleted even if
|
||||
- * they are not immediately reused.
|
||||
- */
|
||||
enum {
|
||||
- POOL_MIN_BATCH_SIZE = 64,
|
||||
- POOL_INITIAL_MAX_SIZE = 64,
|
||||
+ COROUTINE_POOL_BATCH_MAX_SIZE = 128,
|
||||
};
|
||||
|
||||
-/** Free list to speed up creation */
|
||||
-static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
|
||||
-static unsigned int pool_max_size = POOL_INITIAL_MAX_SIZE;
|
||||
-static unsigned int release_pool_size;
|
||||
+/*
|
||||
+ * Coroutine creation and deletion is expensive so a pool of unused coroutines
|
||||
+ * is kept as a cache. When the pool has coroutines available, they are
|
||||
+ * recycled instead of creating new ones from scratch. Coroutines are added to
|
||||
+ * the pool upon termination.
|
||||
+ *
|
||||
+ * The pool is global but each thread maintains a small local pool to avoid
|
||||
+ * global pool contention. Threads fetch and return batches of coroutines from
|
||||
+ * the global pool to maintain their local pool. The local pool holds up to two
|
||||
+ * batches whereas the maximum size of the global pool is controlled by the
|
||||
+ * qemu_coroutine_inc_pool_size() API.
|
||||
+ *
|
||||
+ * .-----------------------------------.
|
||||
+ * | Batch 1 | Batch 2 | Batch 3 | ... | global_pool
|
||||
+ * `-----------------------------------'
|
||||
+ *
|
||||
+ * .-------------------.
|
||||
+ * | Batch 1 | Batch 2 | per-thread local_pool (maximum 2 batches)
|
||||
+ * `-------------------'
|
||||
+ */
|
||||
+typedef struct CoroutinePoolBatch {
|
||||
+ /* Batches are kept in a list */
|
||||
+ QSLIST_ENTRY(CoroutinePoolBatch) next;
|
||||
+
|
||||
+ /* This batch holds up to @COROUTINE_POOL_BATCH_MAX_SIZE coroutines */
|
||||
+ QSLIST_HEAD(, Coroutine) list;
|
||||
+ unsigned int size;
|
||||
+} CoroutinePoolBatch;
|
||||
+
|
||||
+typedef QSLIST_HEAD(, CoroutinePoolBatch) CoroutinePool;
|
||||
+
|
||||
+/* Host operating system limit on number of pooled coroutines */
|
||||
+static unsigned int global_pool_hard_max_size;
|
||||
+
|
||||
+static QemuMutex global_pool_lock; /* protects the following variables */
|
||||
+static CoroutinePool global_pool = QSLIST_HEAD_INITIALIZER(global_pool);
|
||||
+static unsigned int global_pool_size;
|
||||
+static unsigned int global_pool_max_size = COROUTINE_POOL_BATCH_MAX_SIZE;
|
||||
+
|
||||
+QEMU_DEFINE_STATIC_CO_TLS(CoroutinePool, local_pool);
|
||||
+QEMU_DEFINE_STATIC_CO_TLS(Notifier, local_pool_cleanup_notifier);
|
||||
|
||||
-typedef QSLIST_HEAD(, Coroutine) CoroutineQSList;
|
||||
-QEMU_DEFINE_STATIC_CO_TLS(CoroutineQSList, alloc_pool);
|
||||
-QEMU_DEFINE_STATIC_CO_TLS(unsigned int, alloc_pool_size);
|
||||
-QEMU_DEFINE_STATIC_CO_TLS(Notifier, coroutine_pool_cleanup_notifier);
|
||||
+static CoroutinePoolBatch *coroutine_pool_batch_new(void)
|
||||
+{
|
||||
+ CoroutinePoolBatch *batch = g_new(CoroutinePoolBatch, 1);
|
||||
+
|
||||
+ QSLIST_INIT(&batch->list);
|
||||
+ batch->size = 0;
|
||||
+ return batch;
|
||||
+}
|
||||
|
||||
-static void coroutine_pool_cleanup(Notifier *n, void *value)
|
||||
+static void coroutine_pool_batch_delete(CoroutinePoolBatch *batch)
|
||||
{
|
||||
Coroutine *co;
|
||||
Coroutine *tmp;
|
||||
- CoroutineQSList *alloc_pool = get_ptr_alloc_pool();
|
||||
|
||||
- QSLIST_FOREACH_SAFE(co, alloc_pool, pool_next, tmp) {
|
||||
- QSLIST_REMOVE_HEAD(alloc_pool, pool_next);
|
||||
+ QSLIST_FOREACH_SAFE(co, &batch->list, pool_next, tmp) {
|
||||
+ QSLIST_REMOVE_HEAD(&batch->list, pool_next);
|
||||
qemu_coroutine_delete(co);
|
||||
}
|
||||
+ g_free(batch);
|
||||
+}
|
||||
+
|
||||
+static void local_pool_cleanup(Notifier *n, void *value)
|
||||
+{
|
||||
+ CoroutinePool *local_pool = get_ptr_local_pool();
|
||||
+ CoroutinePoolBatch *batch;
|
||||
+ CoroutinePoolBatch *tmp;
|
||||
+
|
||||
+ QSLIST_FOREACH_SAFE(batch, local_pool, next, tmp) {
|
||||
+ QSLIST_REMOVE_HEAD(local_pool, next);
|
||||
+ coroutine_pool_batch_delete(batch);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Ensure the atexit notifier is registered */
|
||||
+static void local_pool_cleanup_init_once(void)
|
||||
+{
|
||||
+ Notifier *notifier = get_ptr_local_pool_cleanup_notifier();
|
||||
+ if (!notifier->notify) {
|
||||
+ notifier->notify = local_pool_cleanup;
|
||||
+ qemu_thread_atexit_add(notifier);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Helper to get the next unused coroutine from the local pool */
|
||||
+static Coroutine *coroutine_pool_get_local(void)
|
||||
+{
|
||||
+ CoroutinePool *local_pool = get_ptr_local_pool();
|
||||
+ CoroutinePoolBatch *batch = QSLIST_FIRST(local_pool);
|
||||
+ Coroutine *co;
|
||||
+
|
||||
+ if (unlikely(!batch)) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ co = QSLIST_FIRST(&batch->list);
|
||||
+ QSLIST_REMOVE_HEAD(&batch->list, pool_next);
|
||||
+ batch->size--;
|
||||
+
|
||||
+ if (batch->size == 0) {
|
||||
+ QSLIST_REMOVE_HEAD(local_pool, next);
|
||||
+ coroutine_pool_batch_delete(batch);
|
||||
+ }
|
||||
+ return co;
|
||||
+}
|
||||
+
|
||||
+/* Get the next batch from the global pool */
|
||||
+static void coroutine_pool_refill_local(void)
|
||||
+{
|
||||
+ CoroutinePool *local_pool = get_ptr_local_pool();
|
||||
+ CoroutinePoolBatch *batch;
|
||||
+
|
||||
+ WITH_QEMU_LOCK_GUARD(&global_pool_lock) {
|
||||
+ batch = QSLIST_FIRST(&global_pool);
|
||||
+
|
||||
+ if (batch) {
|
||||
+ QSLIST_REMOVE_HEAD(&global_pool, next);
|
||||
+ global_pool_size -= batch->size;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (batch) {
|
||||
+ QSLIST_INSERT_HEAD(local_pool, batch, next);
|
||||
+ local_pool_cleanup_init_once();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Add a batch of coroutines to the global pool */
|
||||
+static void coroutine_pool_put_global(CoroutinePoolBatch *batch)
|
||||
+{
|
||||
+ WITH_QEMU_LOCK_GUARD(&global_pool_lock) {
|
||||
+ unsigned int max = MIN(global_pool_max_size,
|
||||
+ global_pool_hard_max_size);
|
||||
+
|
||||
+ if (global_pool_size < max) {
|
||||
+ QSLIST_INSERT_HEAD(&global_pool, batch, next);
|
||||
+
|
||||
+ /* Overshooting the max pool size is allowed */
|
||||
+ global_pool_size += batch->size;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* The global pool was full, so throw away this batch */
|
||||
+ coroutine_pool_batch_delete(batch);
|
||||
+}
|
||||
+
|
||||
+/* Get the next unused coroutine from the pool or return NULL */
|
||||
+static Coroutine *coroutine_pool_get(void)
|
||||
+{
|
||||
+ Coroutine *co;
|
||||
+
|
||||
+ co = coroutine_pool_get_local();
|
||||
+ if (!co) {
|
||||
+ coroutine_pool_refill_local();
|
||||
+ co = coroutine_pool_get_local();
|
||||
+ }
|
||||
+ return co;
|
||||
+}
|
||||
+
|
||||
+static void coroutine_pool_put(Coroutine *co)
|
||||
+{
|
||||
+ CoroutinePool *local_pool = get_ptr_local_pool();
|
||||
+ CoroutinePoolBatch *batch = QSLIST_FIRST(local_pool);
|
||||
+
|
||||
+ if (unlikely(!batch)) {
|
||||
+ batch = coroutine_pool_batch_new();
|
||||
+ QSLIST_INSERT_HEAD(local_pool, batch, next);
|
||||
+ local_pool_cleanup_init_once();
|
||||
+ }
|
||||
+
|
||||
+ if (unlikely(batch->size >= COROUTINE_POOL_BATCH_MAX_SIZE)) {
|
||||
+ CoroutinePoolBatch *next = QSLIST_NEXT(batch, next);
|
||||
+
|
||||
+ /* Is the local pool full? */
|
||||
+ if (next) {
|
||||
+ QSLIST_REMOVE_HEAD(local_pool, next);
|
||||
+ coroutine_pool_put_global(batch);
|
||||
+ }
|
||||
+
|
||||
+ batch = coroutine_pool_batch_new();
|
||||
+ QSLIST_INSERT_HEAD(local_pool, batch, next);
|
||||
+ }
|
||||
+
|
||||
+ QSLIST_INSERT_HEAD(&batch->list, co, pool_next);
|
||||
+ batch->size++;
|
||||
}
|
||||
|
||||
Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
|
||||
@@ -58,31 +219,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
|
||||
Coroutine *co = NULL;
|
||||
|
||||
if (IS_ENABLED(CONFIG_COROUTINE_POOL)) {
|
||||
- CoroutineQSList *alloc_pool = get_ptr_alloc_pool();
|
||||
-
|
||||
- co = QSLIST_FIRST(alloc_pool);
|
||||
- if (!co) {
|
||||
- if (release_pool_size > POOL_MIN_BATCH_SIZE) {
|
||||
- /* Slow path; a good place to register the destructor, too. */
|
||||
- Notifier *notifier = get_ptr_coroutine_pool_cleanup_notifier();
|
||||
- if (!notifier->notify) {
|
||||
- notifier->notify = coroutine_pool_cleanup;
|
||||
- qemu_thread_atexit_add(notifier);
|
||||
- }
|
||||
-
|
||||
- /* This is not exact; there could be a little skew between
|
||||
- * release_pool_size and the actual size of release_pool. But
|
||||
- * it is just a heuristic, it does not need to be perfect.
|
||||
- */
|
||||
- set_alloc_pool_size(qatomic_xchg(&release_pool_size, 0));
|
||||
- QSLIST_MOVE_ATOMIC(alloc_pool, &release_pool);
|
||||
- co = QSLIST_FIRST(alloc_pool);
|
||||
- }
|
||||
- }
|
||||
- if (co) {
|
||||
- QSLIST_REMOVE_HEAD(alloc_pool, pool_next);
|
||||
- set_alloc_pool_size(get_alloc_pool_size() - 1);
|
||||
- }
|
||||
+ co = coroutine_pool_get();
|
||||
}
|
||||
|
||||
if (!co) {
|
||||
@@ -100,19 +237,10 @@ static void coroutine_delete(Coroutine *co)
|
||||
co->caller = NULL;
|
||||
|
||||
if (IS_ENABLED(CONFIG_COROUTINE_POOL)) {
|
||||
- if (release_pool_size < qatomic_read(&pool_max_size) * 2) {
|
||||
- QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next);
|
||||
- qatomic_inc(&release_pool_size);
|
||||
- return;
|
||||
- }
|
||||
- if (get_alloc_pool_size() < qatomic_read(&pool_max_size)) {
|
||||
- QSLIST_INSERT_HEAD(get_ptr_alloc_pool(), co, pool_next);
|
||||
- set_alloc_pool_size(get_alloc_pool_size() + 1);
|
||||
- return;
|
||||
- }
|
||||
+ coroutine_pool_put(co);
|
||||
+ } else {
|
||||
+ qemu_coroutine_delete(co);
|
||||
}
|
||||
-
|
||||
- qemu_coroutine_delete(co);
|
||||
}
|
||||
|
||||
void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co)
|
||||
@@ -223,10 +351,46 @@ AioContext *qemu_coroutine_get_aio_context(Coroutine *co)
|
||||
|
||||
void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size)
|
||||
{
|
||||
- qatomic_add(&pool_max_size, additional_pool_size);
|
||||
+ QEMU_LOCK_GUARD(&global_pool_lock);
|
||||
+ global_pool_max_size += additional_pool_size;
|
||||
}
|
||||
|
||||
void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
|
||||
{
|
||||
- qatomic_sub(&pool_max_size, removing_pool_size);
|
||||
+ QEMU_LOCK_GUARD(&global_pool_lock);
|
||||
+ global_pool_max_size -= removing_pool_size;
|
||||
+}
|
||||
+
|
||||
+static unsigned int get_global_pool_hard_max_size(void)
|
||||
+{
|
||||
+#ifdef __linux__
|
||||
+ g_autofree char *contents = NULL;
|
||||
+ int max_map_count;
|
||||
+
|
||||
+ /*
|
||||
+ * Linux processes can have up to max_map_count virtual memory areas
|
||||
+ * (VMAs). mmap(2), mprotect(2), etc fail with ENOMEM beyond this limit. We
|
||||
+ * must limit the coroutine pool to a safe size to avoid running out of
|
||||
+ * VMAs.
|
||||
+ */
|
||||
+ if (g_file_get_contents("/proc/sys/vm/max_map_count", &contents, NULL,
|
||||
+ NULL) &&
|
||||
+ qemu_strtoi(contents, NULL, 10, &max_map_count) == 0) {
|
||||
+ /*
|
||||
+ * This is a conservative upper bound that avoids exceeding
|
||||
+ * max_map_count. Leave half for non-coroutine users like library
|
||||
+ * dependencies, vhost-user, etc. Each coroutine takes up 2 VMAs so
|
||||
+ * halve the amount again.
|
||||
+ */
|
||||
+ return max_map_count / 4;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return UINT_MAX;
|
||||
+}
|
||||
+
|
||||
+static void __attribute__((constructor)) qemu_coroutine_init(void)
|
||||
+{
|
||||
+ qemu_mutex_init(&global_pool_lock);
|
||||
+ global_pool_hard_max_size = get_global_pool_hard_max_size();
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,61 +0,0 @@
|
||||
From 0aa65dc3acba481f7064df936ab49e3bceb1d5bd Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Wed, 20 Mar 2024 14:12:32 -0400
|
||||
Subject: [PATCH 2/2] coroutine: reserve 5,000 mappings
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 234: coroutine: cap per-thread local pool size
|
||||
RH-Jira: RHEL-28947
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [2/2] 78560c2b947471111cc16c313d6f38db42860a1c (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
Daniel P. Berrangé <berrange@redhat.com> pointed out that the coroutine
|
||||
pool size heuristic is very conservative. Instead of halving
|
||||
max_map_count, he suggested reserving 5,000 mappings for non-coroutine
|
||||
users based on observations of guests he has access to.
|
||||
|
||||
Fixes: 86a637e48104 ("coroutine: cap per-thread local pool size")
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Message-id: 20240320181232.1464819-1-stefanha@redhat.com
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
(cherry picked from commit 9352f80cd926fe2dde7c89b93ee33bb0356ff40e)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
util/qemu-coroutine.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
|
||||
index 2790959eaf..eb4eebefdf 100644
|
||||
--- a/util/qemu-coroutine.c
|
||||
+++ b/util/qemu-coroutine.c
|
||||
@@ -377,12 +377,17 @@ static unsigned int get_global_pool_hard_max_size(void)
|
||||
NULL) &&
|
||||
qemu_strtoi(contents, NULL, 10, &max_map_count) == 0) {
|
||||
/*
|
||||
- * This is a conservative upper bound that avoids exceeding
|
||||
- * max_map_count. Leave half for non-coroutine users like library
|
||||
- * dependencies, vhost-user, etc. Each coroutine takes up 2 VMAs so
|
||||
- * halve the amount again.
|
||||
+ * This is an upper bound that avoids exceeding max_map_count. Leave a
|
||||
+ * fixed amount for non-coroutine users like library dependencies,
|
||||
+ * vhost-user, etc. Each coroutine takes up 2 VMAs so halve the
|
||||
+ * remaining amount.
|
||||
*/
|
||||
- return max_map_count / 4;
|
||||
+ if (max_map_count > 5000) {
|
||||
+ return (max_map_count - 5000) / 2;
|
||||
+ } else {
|
||||
+ /* Disable the global pool but threads still have local pools */
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,75 +0,0 @@
|
||||
From ac9dc8ea241ef6d3a0447d696620d4d4053b71bf Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Mon, 4 Dec 2023 11:42:59 -0500
|
||||
Subject: [PATCH 080/101] dma-helpers: don't lock AioContext in dma_blk_cb()
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [11/26] a8580463ba6aee4ca248c0b947b9e72bd9e87aab (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Commit abfcd2760b3e ("dma-helpers: prevent dma_blk_cb() vs
|
||||
dma_aio_cancel() race") acquired the AioContext lock inside dma_blk_cb()
|
||||
to avoid a race with scsi_device_purge_requests() running in the main
|
||||
loop thread.
|
||||
|
||||
The SCSI code no longer calls dma_aio_cancel() from the main loop thread
|
||||
while I/O is running in the IOThread AioContext. Therefore it is no
|
||||
longer necessary to take this lock to protect DMAAIOCB fields. The
|
||||
->cb() function also does not require the lock because blk_aio_*() and
|
||||
friends do not need the AioContext lock.
|
||||
|
||||
Both hw/ide/core.c and hw/ide/macio.c also call dma_blk_io() but don't
|
||||
rely on it taking the AioContext lock, so this change is safe.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20231204164259.1515217-5-stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
system/dma-helpers.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/system/dma-helpers.c b/system/dma-helpers.c
|
||||
index 36211acc7e..528117f256 100644
|
||||
--- a/system/dma-helpers.c
|
||||
+++ b/system/dma-helpers.c
|
||||
@@ -119,13 +119,12 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||
|
||||
trace_dma_blk_cb(dbs, ret);
|
||||
|
||||
- aio_context_acquire(ctx);
|
||||
dbs->acb = NULL;
|
||||
dbs->offset += dbs->iov.size;
|
||||
|
||||
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
|
||||
dma_complete(dbs, ret);
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
dma_blk_unmap(dbs);
|
||||
|
||||
@@ -168,7 +167,7 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||
trace_dma_map_wait(dbs);
|
||||
dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs);
|
||||
cpu_register_map_client(dbs->bh);
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
|
||||
@@ -179,8 +178,6 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
|
||||
dma_blk_cb, dbs, dbs->io_func_opaque);
|
||||
assert(dbs->acb);
|
||||
-out:
|
||||
- aio_context_release(ctx);
|
||||
}
|
||||
|
||||
static void dma_aio_cancel(BlockAIOCB *acb)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,228 +0,0 @@
|
||||
From 71aa0219f7c84cbf175eb2a091d48d5fd5daa40b Mon Sep 17 00:00:00 2001
|
||||
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Date: Tue, 21 Nov 2023 16:44:26 +0800
|
||||
Subject: [PATCH 047/101] docs/devel: Add VFIO iommufd backend documentation
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [46/67] 6cf49d00e87788f894d690a985bb6798eae24505 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Suggested-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 98dad2b01931f6064c6c4b48ca3c2a1d9f542cd8)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
docs/devel/index-internals.rst | 1 +
|
||||
docs/devel/vfio-iommufd.rst | 166 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 168 insertions(+)
|
||||
create mode 100644 docs/devel/vfio-iommufd.rst
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index ca70bb4e64..0ddb20a35f 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -2176,6 +2176,7 @@ F: backends/iommufd.c
|
||||
F: include/sysemu/iommufd.h
|
||||
F: include/qemu/chardev_open.h
|
||||
F: util/chardev_open.c
|
||||
+F: docs/devel/vfio-iommufd.rst
|
||||
|
||||
vhost
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
diff --git a/docs/devel/index-internals.rst b/docs/devel/index-internals.rst
|
||||
index 6f81df92bc..3def4a138b 100644
|
||||
--- a/docs/devel/index-internals.rst
|
||||
+++ b/docs/devel/index-internals.rst
|
||||
@@ -18,5 +18,6 @@ Details about QEMU's various subsystems including how to add features to them.
|
||||
s390-dasd-ipl
|
||||
tracing
|
||||
vfio-migration
|
||||
+ vfio-iommufd
|
||||
writing-monitor-commands
|
||||
virtio-backends
|
||||
diff --git a/docs/devel/vfio-iommufd.rst b/docs/devel/vfio-iommufd.rst
|
||||
new file mode 100644
|
||||
index 0000000000..3d1c11f175
|
||||
--- /dev/null
|
||||
+++ b/docs/devel/vfio-iommufd.rst
|
||||
@@ -0,0 +1,166 @@
|
||||
+===============================
|
||||
+IOMMUFD BACKEND usage with VFIO
|
||||
+===============================
|
||||
+
|
||||
+(Same meaning for backend/container/BE)
|
||||
+
|
||||
+With the introduction of iommufd, the Linux kernel provides a generic
|
||||
+interface for user space drivers to propagate their DMA mappings to kernel
|
||||
+for assigned devices. While the legacy kernel interface is group-centric,
|
||||
+the new iommufd interface is device-centric, relying on device fd and iommufd.
|
||||
+
|
||||
+To support both interfaces in the QEMU VFIO device, introduce a base container
|
||||
+to abstract the common part of VFIO legacy and iommufd container. So that the
|
||||
+generic VFIO code can use either container.
|
||||
+
|
||||
+The base container implements generic functions such as memory_listener and
|
||||
+address space management whereas the derived container implements callbacks
|
||||
+specific to either legacy or iommufd. Each container has its own way to setup
|
||||
+secure context and dma management interface. The below diagram shows how it
|
||||
+looks like with both containers.
|
||||
+
|
||||
+::
|
||||
+
|
||||
+ VFIO AddressSpace/Memory
|
||||
+ +-------+ +----------+ +-----+ +-----+
|
||||
+ | pci | | platform | | ap | | ccw |
|
||||
+ +---+---+ +----+-----+ +--+--+ +--+--+ +----------------------+
|
||||
+ | | | | | AddressSpace |
|
||||
+ | | | | +------------+---------+
|
||||
+ +---V-----------V-----------V--------V----+ /
|
||||
+ | VFIOAddressSpace | <------------+
|
||||
+ | | | MemoryListener
|
||||
+ | VFIOContainerBase list |
|
||||
+ +-------+----------------------------+----+
|
||||
+ | |
|
||||
+ | |
|
||||
+ +-------V------+ +--------V----------+
|
||||
+ | iommufd | | vfio legacy |
|
||||
+ | container | | container |
|
||||
+ +-------+------+ +--------+----------+
|
||||
+ | |
|
||||
+ | /dev/iommu | /dev/vfio/vfio
|
||||
+ | /dev/vfio/devices/vfioX | /dev/vfio/$group_id
|
||||
+ Userspace | |
|
||||
+ ============+============================+===========================
|
||||
+ Kernel | device fd |
|
||||
+ +---------------+ | group/container fd
|
||||
+ | (BIND_IOMMUFD | | (SET_CONTAINER/SET_IOMMU)
|
||||
+ | ATTACH_IOAS) | | device fd
|
||||
+ | | |
|
||||
+ | +-------V------------V-----------------+
|
||||
+ iommufd | | vfio |
|
||||
+ (map/unmap | +---------+--------------------+-------+
|
||||
+ ioas_copy) | | | map/unmap
|
||||
+ | | |
|
||||
+ +------V------+ +-----V------+ +------V--------+
|
||||
+ | iommfd core | | device | | vfio iommu |
|
||||
+ +-------------+ +------------+ +---------------+
|
||||
+
|
||||
+* Secure Context setup
|
||||
+
|
||||
+ - iommufd BE: uses device fd and iommufd to setup secure context
|
||||
+ (bind_iommufd, attach_ioas)
|
||||
+ - vfio legacy BE: uses group fd and container fd to setup secure context
|
||||
+ (set_container, set_iommu)
|
||||
+
|
||||
+* Device access
|
||||
+
|
||||
+ - iommufd BE: device fd is opened through ``/dev/vfio/devices/vfioX``
|
||||
+ - vfio legacy BE: device fd is retrieved from group fd ioctl
|
||||
+
|
||||
+* DMA Mapping flow
|
||||
+
|
||||
+ 1. VFIOAddressSpace receives MemoryRegion add/del via MemoryListener
|
||||
+ 2. VFIO populates DMA map/unmap via the container BEs
|
||||
+ * iommufd BE: uses iommufd
|
||||
+ * vfio legacy BE: uses container fd
|
||||
+
|
||||
+Example configuration
|
||||
+=====================
|
||||
+
|
||||
+Step 1: configure the host device
|
||||
+---------------------------------
|
||||
+
|
||||
+It's exactly same as the VFIO device with legacy VFIO container.
|
||||
+
|
||||
+Step 2: configure QEMU
|
||||
+----------------------
|
||||
+
|
||||
+Interactions with the ``/dev/iommu`` are abstracted by a new iommufd
|
||||
+object (compiled in with the ``CONFIG_IOMMUFD`` option).
|
||||
+
|
||||
+Any QEMU device (e.g. VFIO device) wishing to use ``/dev/iommu`` must
|
||||
+be linked with an iommufd object. It gets a new optional property
|
||||
+named iommufd which allows to pass an iommufd object. Take ``vfio-pci``
|
||||
+device for example:
|
||||
+
|
||||
+.. code-block:: bash
|
||||
+
|
||||
+ -object iommufd,id=iommufd0
|
||||
+ -device vfio-pci,host=0000:02:00.0,iommufd=iommufd0
|
||||
+
|
||||
+Note the ``/dev/iommu`` and VFIO cdev can be externally opened by a
|
||||
+management layer. In such a case the fd is passed, the fd supports a
|
||||
+string naming the fd or a number, for example:
|
||||
+
|
||||
+.. code-block:: bash
|
||||
+
|
||||
+ -object iommufd,id=iommufd0,fd=22
|
||||
+ -device vfio-pci,iommufd=iommufd0,fd=23
|
||||
+
|
||||
+If the ``fd`` property is not passed, the fd is opened by QEMU.
|
||||
+
|
||||
+If no ``iommufd`` object is passed to the ``vfio-pci`` device, iommufd
|
||||
+is not used and the user gets the behavior based on the legacy VFIO
|
||||
+container:
|
||||
+
|
||||
+.. code-block:: bash
|
||||
+
|
||||
+ -device vfio-pci,host=0000:02:00.0
|
||||
+
|
||||
+Supported platform
|
||||
+==================
|
||||
+
|
||||
+Supports x86, ARM and s390x currently.
|
||||
+
|
||||
+Caveats
|
||||
+=======
|
||||
+
|
||||
+Dirty page sync
|
||||
+---------------
|
||||
+
|
||||
+Dirty page sync with iommufd backend is unsupported yet, live migration is
|
||||
+disabled by default. But it can be force enabled like below, low efficient
|
||||
+though.
|
||||
+
|
||||
+.. code-block:: bash
|
||||
+
|
||||
+ -object iommufd,id=iommufd0
|
||||
+ -device vfio-pci,host=0000:02:00.0,iommufd=iommufd0,enable-migration=on
|
||||
+
|
||||
+P2P DMA
|
||||
+-------
|
||||
+
|
||||
+PCI p2p DMA is unsupported as IOMMUFD doesn't support mapping hardware PCI
|
||||
+BAR region yet. Below warning shows for assigned PCI device, it's not a bug.
|
||||
+
|
||||
+.. code-block:: none
|
||||
+
|
||||
+ qemu-system-x86_64: warning: IOMMU_IOAS_MAP failed: Bad address, PCI BAR?
|
||||
+ qemu-system-x86_64: vfio_container_dma_map(0x560cb6cb1620, 0xe000000021000, 0x3000, 0x7f32ed55c000) = -14 (Bad address)
|
||||
+
|
||||
+FD passing with mdev
|
||||
+--------------------
|
||||
+
|
||||
+``vfio-pci`` device checks sysfsdev property to decide if backend is a mdev.
|
||||
+If FD passing is used, there is no way to know that and the mdev is treated
|
||||
+like a real PCI device. There is an error as below if user wants to enable
|
||||
+RAM discarding for mdev.
|
||||
+
|
||||
+.. code-block:: none
|
||||
+
|
||||
+ qemu-system-x86_64: -device vfio-pci,iommufd=iommufd0,x-balloon-allowed=on,fd=9: vfio VFIO_FD9: x-balloon-allowed only potentially compatible with mdev devices
|
||||
+
|
||||
+``vfio-ap`` and ``vfio-ccw`` devices don't have same issue as their backend
|
||||
+devices are always mdev and RAM discarding is force enabled.
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,98 +0,0 @@
|
||||
From fc69df3a70bed5722643cc16828ca20beae3a20d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:08 -0500
|
||||
Subject: [PATCH 091/101] docs: remove AioContext lock from IOThread docs
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [22/26] ab89cda483e74ded983d26e1c6e50217405e0a55 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Encourage the use of locking primitives and stop mentioning the
|
||||
AioContext lock since it is being removed.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-12-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
docs/devel/multiple-iothreads.txt | 47 +++++++++++--------------------
|
||||
1 file changed, 16 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
|
||||
index a3e949f6b3..4865196bde 100644
|
||||
--- a/docs/devel/multiple-iothreads.txt
|
||||
+++ b/docs/devel/multiple-iothreads.txt
|
||||
@@ -88,27 +88,18 @@ loop, depending on which AioContext instance the caller passes in.
|
||||
|
||||
How to synchronize with an IOThread
|
||||
-----------------------------------
|
||||
-AioContext is not thread-safe so some rules must be followed when using file
|
||||
-descriptors, event notifiers, timers, or BHs across threads:
|
||||
+Variables that can be accessed by multiple threads require some form of
|
||||
+synchronization such as qemu_mutex_lock(), rcu_read_lock(), etc.
|
||||
|
||||
-1. AioContext functions can always be called safely. They handle their
|
||||
-own locking internally.
|
||||
-
|
||||
-2. Other threads wishing to access the AioContext must use
|
||||
-aio_context_acquire()/aio_context_release() for mutual exclusion. Once the
|
||||
-context is acquired no other thread can access it or run event loop iterations
|
||||
-in this AioContext.
|
||||
-
|
||||
-Legacy code sometimes nests aio_context_acquire()/aio_context_release() calls.
|
||||
-Do not use nesting anymore, it is incompatible with the BDRV_POLL_WHILE() macro
|
||||
-used in the block layer and can lead to hangs.
|
||||
-
|
||||
-There is currently no lock ordering rule if a thread needs to acquire multiple
|
||||
-AioContexts simultaneously. Therefore, it is only safe for code holding the
|
||||
-QEMU global mutex to acquire other AioContexts.
|
||||
+AioContext functions like aio_set_fd_handler(), aio_set_event_notifier(),
|
||||
+aio_bh_new(), and aio_timer_new() are thread-safe. They can be used to trigger
|
||||
+activity in an IOThread.
|
||||
|
||||
Side note: the best way to schedule a function call across threads is to call
|
||||
-aio_bh_schedule_oneshot(). No acquire/release or locking is needed.
|
||||
+aio_bh_schedule_oneshot().
|
||||
+
|
||||
+The main loop thread can wait synchronously for a condition using
|
||||
+AIO_WAIT_WHILE().
|
||||
|
||||
AioContext and the block layer
|
||||
------------------------------
|
||||
@@ -124,22 +115,16 @@ Block layer code must therefore expect to run in an IOThread and avoid using
|
||||
old APIs that implicitly use the main loop. See the "How to program for
|
||||
IOThreads" above for information on how to do that.
|
||||
|
||||
-If main loop code such as a QMP function wishes to access a BlockDriverState
|
||||
-it must first call aio_context_acquire(bdrv_get_aio_context(bs)) to ensure
|
||||
-that callbacks in the IOThread do not run in parallel.
|
||||
-
|
||||
Code running in the monitor typically needs to ensure that past
|
||||
requests from the guest are completed. When a block device is running
|
||||
in an IOThread, the IOThread can also process requests from the guest
|
||||
(via ioeventfd). To achieve both objects, wrap the code between
|
||||
bdrv_drained_begin() and bdrv_drained_end(), thus creating a "drained
|
||||
-section". The functions must be called between aio_context_acquire()
|
||||
-and aio_context_release(). You can freely release and re-acquire the
|
||||
-AioContext within a drained section.
|
||||
-
|
||||
-Long-running jobs (usually in the form of coroutines) are best scheduled in
|
||||
-the BlockDriverState's AioContext to avoid the need to acquire/release around
|
||||
-each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier,
|
||||
-or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends,
|
||||
-can be used to get a notification whenever bdrv_try_change_aio_context() moves a
|
||||
+section".
|
||||
+
|
||||
+Long-running jobs (usually in the form of coroutines) are often scheduled in
|
||||
+the BlockDriverState's AioContext. The functions
|
||||
+bdrv_add/remove_aio_context_notifier, or alternatively
|
||||
+blk_add/remove_aio_context_notifier if you use BlockBackends, can be used to
|
||||
+get a notification whenever bdrv_try_change_aio_context() moves a
|
||||
BlockDriverState to a different AioContext.
|
||||
--
|
||||
2.39.3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,94 +0,0 @@
|
||||
From a5b4eec5f456b1ca3fe753e1d76f96cf3f8914ef Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 14:55:53 +0100
|
||||
Subject: [PATCH 01/22] hv-balloon: use get_min_alignment() to express 32 GiB
|
||||
alignment
|
||||
|
||||
RH-Author: David Hildenbrand <david@redhat.com>
|
||||
RH-MergeRequest: 221: memory-device: reintroduce memory region size check
|
||||
RH-Jira: RHEL-20341
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Commit: [1/2] cbe092fe549552928270892253b31cd8fe199825
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-20341
|
||||
|
||||
Let's implement the get_min_alignment() callback for memory devices, and
|
||||
copy for the device memory region the alignment of the host memory
|
||||
region. This mimics what virtio-mem does, and allows for re-introducing
|
||||
proper alignment checks for the memory region size (where we don't care
|
||||
about additional device requirements) in memory device core.
|
||||
|
||||
Message-ID: <20240117135554.787344-2-david@redhat.com>
|
||||
Reviewed-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit f77c5f38f49c71bc14cf1019ac92b0b95f572414)
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
---
|
||||
hw/hyperv/hv-balloon.c | 37 +++++++++++++++++++++----------------
|
||||
1 file changed, 21 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c
|
||||
index 66f297c1d7..0829c495b0 100644
|
||||
--- a/hw/hyperv/hv-balloon.c
|
||||
+++ b/hw/hyperv/hv-balloon.c
|
||||
@@ -1476,22 +1476,7 @@ static void hv_balloon_ensure_mr(HvBalloon *balloon)
|
||||
balloon->mr = g_new0(MemoryRegion, 1);
|
||||
memory_region_init(balloon->mr, OBJECT(balloon), TYPE_HV_BALLOON,
|
||||
memory_region_size(hostmem_mr));
|
||||
-
|
||||
- /*
|
||||
- * The VM can indicate an alignment up to 32 GiB. Memory device core can
|
||||
- * usually only handle/guarantee 1 GiB alignment. The user will have to
|
||||
- * specify a larger maxmem eventually.
|
||||
- *
|
||||
- * The memory device core will warn the user in case maxmem might have to be
|
||||
- * increased and will fail plugging the device if there is not sufficient
|
||||
- * space after alignment.
|
||||
- *
|
||||
- * TODO: we could do the alignment ourselves in a slightly bigger region.
|
||||
- * But this feels better, although the warning might be annoying. Maybe
|
||||
- * we can optimize that in the future (e.g., with such a device on the
|
||||
- * cmdline place/size the device memory region differently.
|
||||
- */
|
||||
- balloon->mr->align = MAX(32 * GiB, memory_region_get_alignment(hostmem_mr));
|
||||
+ balloon->mr->align = memory_region_get_alignment(hostmem_mr);
|
||||
}
|
||||
|
||||
static void hv_balloon_free_mr(HvBalloon *balloon)
|
||||
@@ -1653,6 +1638,25 @@ static MemoryRegion *hv_balloon_md_get_memory_region(MemoryDeviceState *md,
|
||||
return balloon->mr;
|
||||
}
|
||||
|
||||
+static uint64_t hv_balloon_md_get_min_alignment(const MemoryDeviceState *md)
|
||||
+{
|
||||
+ /*
|
||||
+ * The VM can indicate an alignment up to 32 GiB. Memory device core can
|
||||
+ * usually only handle/guarantee 1 GiB alignment. The user will have to
|
||||
+ * specify a larger maxmem eventually.
|
||||
+ *
|
||||
+ * The memory device core will warn the user in case maxmem might have to be
|
||||
+ * increased and will fail plugging the device if there is not sufficient
|
||||
+ * space after alignment.
|
||||
+ *
|
||||
+ * TODO: we could do the alignment ourselves in a slightly bigger region.
|
||||
+ * But this feels better, although the warning might be annoying. Maybe
|
||||
+ * we can optimize that in the future (e.g., with such a device on the
|
||||
+ * cmdline place/size the device memory region differently.
|
||||
+ */
|
||||
+ return 32 * GiB;
|
||||
+}
|
||||
+
|
||||
static void hv_balloon_md_fill_device_info(const MemoryDeviceState *md,
|
||||
MemoryDeviceInfo *info)
|
||||
{
|
||||
@@ -1765,5 +1769,6 @@ static void hv_balloon_class_init(ObjectClass *klass, void *data)
|
||||
mdc->get_memory_region = hv_balloon_md_get_memory_region;
|
||||
mdc->decide_memslots = hv_balloon_decide_memslots;
|
||||
mdc->get_memslots = hv_balloon_get_memslots;
|
||||
+ mdc->get_min_alignment = hv_balloon_md_get_min_alignment;
|
||||
mdc->fill_device_info = hv_balloon_md_fill_device_info;
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,42 +0,0 @@
|
||||
From ceaee9c4372bbdc4196cb6808515047388f7aa26 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 16:44:18 +0800
|
||||
Subject: [PATCH 039/101] hw/arm: Activate IOMMUFD for virt machines
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [38/67] 0a059ae661616e95eb8455e17f35774495cae8e7 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.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: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 0970238343af45a8b547695bfc22f18d4eb7da7e)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/arm/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
|
||||
index 3ada335a24..660f49db49 100644
|
||||
--- a/hw/arm/Kconfig
|
||||
+++ b/hw/arm/Kconfig
|
||||
@@ -8,6 +8,7 @@ config ARM_VIRT
|
||||
imply TPM_TIS_SYSBUS
|
||||
imply TPM_TIS_I2C
|
||||
imply NVDIMM
|
||||
+ imply IOMMUFD
|
||||
select ARM_GIC
|
||||
select ACPI
|
||||
select ARM_SMMUV3
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,88 +0,0 @@
|
||||
From e670722b9a6460d41497688d820d5a9a9b51d8e9 Mon Sep 17 00:00:00 2001
|
||||
From: Gavin Shan <gshan@redhat.com>
|
||||
Date: Tue, 9 Jan 2024 11:36:42 +1000
|
||||
Subject: [PATCH 001/101] hw/arm/virt: Add properties to disable high memory
|
||||
regions
|
||||
|
||||
RH-Author: Gavin Shan <gshan@redhat.com>
|
||||
RH-MergeRequest: 210: hw/arm/virt: Add properties to disable high memory regions
|
||||
RH-Jira: RHEL-19738
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Commit: [1/1] 4097ba5133a67126e30b84202cb40df4e019c5f4
|
||||
|
||||
Upstream: RHEL-only
|
||||
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=57927352
|
||||
|
||||
There are 3 high memory regions for GICv3 or GICv4 redistributor, PCI
|
||||
ECAM and PCI MMIO. Each of them has a property introduced by upstream
|
||||
commit 6a48c64eec ("hw/arm/virt: Add properties to disable high memory
|
||||
regions") so that the corresponding high memory region can be disabled.
|
||||
|
||||
It's notable that another property ("compact-highmem") introduced by
|
||||
upstream commit f40408a9fe ("hw/arm/virt: Add 'compact-highmem' property")
|
||||
so that the compact high memory region layout during assignment can be
|
||||
disabled, compatible to the old machine types. However, we don't have
|
||||
the compatible issue since the compact high memory region layout is
|
||||
always kept as disabled until RHEL9.2.0 machine type and onwards.
|
||||
|
||||
Expose those 3 properties: "highmem-redists", "highmem-ecam" and
|
||||
"highmem-mmio". The property "compact-highmem" is kept as hidden.
|
||||
|
||||
Signed-off-by: Gavin Shan <gshan@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 24 +++++++++++++++++++++++-
|
||||
1 file changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 5cab00b4cd..60f117f0d2 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -2456,6 +2456,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)
|
||||
{
|
||||
@@ -2498,7 +2499,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp)
|
||||
|
||||
vms->highmem_mmio = value;
|
||||
}
|
||||
-#endif /* disabled for RHEL */
|
||||
|
||||
static bool virt_get_its(Object *obj, Error **errp)
|
||||
{
|
||||
@@ -3521,6 +3521,28 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data)
|
||||
"Set on/off to enable/disable using "
|
||||
"physical address space above 32 bits");
|
||||
|
||||
+ object_class_property_add_bool(oc, "highmem-redists",
|
||||
+ virt_get_highmem_redists,
|
||||
+ virt_set_highmem_redists);
|
||||
+ object_class_property_set_description(oc, "highmem-redists",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for GICv3 or GICv4 "
|
||||
+ "redistributor");
|
||||
+
|
||||
+ object_class_property_add_bool(oc, "highmem-ecam",
|
||||
+ virt_get_highmem_ecam,
|
||||
+ virt_set_highmem_ecam);
|
||||
+ object_class_property_set_description(oc, "highmem-ecam",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for PCI ECAM");
|
||||
+
|
||||
+ object_class_property_add_bool(oc, "highmem-mmio",
|
||||
+ virt_get_highmem_mmio,
|
||||
+ virt_set_highmem_mmio);
|
||||
+ object_class_property_set_description(oc, "highmem-mmio",
|
||||
+ "Set on/off to enable/disable high "
|
||||
+ "memory region for PCI MMIO");
|
||||
+
|
||||
object_class_property_add_str(oc, "gic-version", virt_get_gic_version,
|
||||
virt_set_gic_version);
|
||||
object_class_property_set_description(oc, "gic-version",
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,132 +0,0 @@
|
||||
From 3f58194f8642a71c47d91d3c00a34faf44ea2c11 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Wed, 3 Jan 2024 05:57:38 -0500
|
||||
Subject: [PATCH] hw/arm/virt: Fix compats
|
||||
|
||||
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||
RH-MergeRequest: 209: hw/arm/virt: Fix compats
|
||||
RH-Jira: RHEL-17168
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [1/1] bcdf6493bbd6d7b52b0b88ff44441d22aeddfde2 (eauger1/centos-qemu-kvm)
|
||||
|
||||
arm_rhel_compat is not added for virt-rhel9.4.0 machine causing
|
||||
the efi-virtio.rom to be looked for when instantiating a virtio-net-pci
|
||||
device and it won't be found since not shipped on ARM. This is a
|
||||
regression compared to 9.2.
|
||||
|
||||
Actually we do not need any rom file for any virtio-net-pci variant
|
||||
because edk2 already brings the functionality. So for 9.4 onwards, we
|
||||
want to set romfiles to "" for all of them.
|
||||
|
||||
However at the moment we apply arm_rhel_compat from the latest
|
||||
rhel*_virt_options(). This is not aligned with the generic compat
|
||||
usage which sets compats for a given machine type to accomodate for
|
||||
changes that occured after its advent. Here we are somehow abusing
|
||||
the compat infra to set general driver options that should apply for
|
||||
all machines. On top of that this is really error prone and we have
|
||||
forgotten to add arm_rhel_compat several times in the past.
|
||||
|
||||
So let's introduce set_arm_rhel_compat() being called before any
|
||||
*virt_options in the non abstract machine class. That way the setting
|
||||
will apply to any machine type without any need to add it in any
|
||||
future machine types.
|
||||
|
||||
For < 9.4 machines we don't really care keeping non void romfiles
|
||||
for transitional and non transitional devices because anyway this was
|
||||
not working. So let's keep things simple and apply the new defaults for
|
||||
all RHEL9 machine types.
|
||||
|
||||
Finally, to follow the generic pattern we should set hw_compat_rhel_9_0
|
||||
in 9.0 machine as it is done on x86 or ccw. This has no consequence on
|
||||
aarch64 because it only contains x86 stuff but that helps understanding
|
||||
the consistency.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 43 +++++++++++++++++++++++++++++--------------
|
||||
1 file changed, 29 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 0b17c94ad7..5cab00b4cd 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -111,11 +111,39 @@
|
||||
DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
|
||||
#endif /* disabled for RHEL */
|
||||
|
||||
+/*
|
||||
+ * This variable is for changes to properties that are RHEL specific,
|
||||
+ * different to the current upstream and to be applied to the latest
|
||||
+ * machine type. They may be overriden by older machine compats.
|
||||
+ *
|
||||
+ * virtio-net-pci variant romfiles are not needed because edk2 does
|
||||
+ * fully support the pxe boot. Besides virtio romfiles are not shipped
|
||||
+ * on rhel/aarch64.
|
||||
+ */
|
||||
+GlobalProperty arm_rhel_compat[] = {
|
||||
+ {"virtio-net-pci", "romfile", "" },
|
||||
+ {"virtio-net-pci-transitional", "romfile", "" },
|
||||
+ {"virtio-net-pci-non-transitional", "romfile", "" },
|
||||
+};
|
||||
+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
|
||||
+
|
||||
+/*
|
||||
+ * This cannot be called from the rhel_virt_class_init() because
|
||||
+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new()
|
||||
+ * only is called on virt-rhelm.n.s non abstract class init.
|
||||
+ */
|
||||
+static void arm_rhel_compat_set(MachineClass *mc)
|
||||
+{
|
||||
+ compat_props_add(mc->compat_props, arm_rhel_compat,
|
||||
+ arm_rhel_compat_len);
|
||||
+}
|
||||
+
|
||||
#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \
|
||||
static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \
|
||||
void *data) \
|
||||
{ \
|
||||
MachineClass *mc = MACHINE_CLASS(oc); \
|
||||
+ arm_rhel_compat_set(mc); \
|
||||
rhel##m##n##s##_virt_options(mc); \
|
||||
mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \
|
||||
if (latest) { \
|
||||
@@ -139,19 +167,6 @@
|
||||
#define DEFINE_RHEL_MACHINE(major, minor, subminor) \
|
||||
DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false)
|
||||
|
||||
-/* 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.
|
||||
- */
|
||||
-GlobalProperty arm_rhel_compat[] = {
|
||||
- {
|
||||
- .driver = "virtio-net-pci",
|
||||
- .property = "romfile",
|
||||
- .value = "",
|
||||
- },
|
||||
-};
|
||||
-const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat);
|
||||
-
|
||||
/* Number of external interrupt lines to configure the GIC with */
|
||||
#define NUM_IRQS 256
|
||||
|
||||
@@ -3639,7 +3654,6 @@ static void rhel920_virt_options(MachineClass *mc)
|
||||
{
|
||||
rhel940_virt_options(mc);
|
||||
|
||||
- compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len);
|
||||
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);
|
||||
@@ -3653,6 +3667,7 @@ static void rhel900_virt_options(MachineClass *mc)
|
||||
rhel920_virt_options(mc);
|
||||
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len);
|
||||
+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len);
|
||||
|
||||
/* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */
|
||||
vmc->no_tcg_lpa2 = true;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 4c1d07995a7afb6fae68a7e7a8b6b6c94fa0a7bb Mon Sep 17 00:00:00 2001
|
||||
From: Cornelia Huck <cohuck@redhat.com>
|
||||
Date: Mon, 12 Feb 2024 10:37:54 +0100
|
||||
Subject: [PATCH 5/6] hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types
|
||||
|
||||
RH-Author: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-MergeRequest: 225: hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types
|
||||
RH-Jira: RHEL-24988
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Acked-by: Eric Auger <eric.auger@redhat.com>
|
||||
RH-Commit: [1/1] f15579db44808fa8a2d7bc01b3915aa59c064411 (cohuck/qemu-kvm-c9s)
|
||||
|
||||
Jira: https://issues.redhat.com/browse/RHEL-24988
|
||||
Upstream: RHEL only
|
||||
|
||||
We do not plan to support any machine types prior to 9.4.0; leave them
|
||||
in, but mark as deprecated.
|
||||
|
||||
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 60f117f0d2..943c563391 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -3679,6 +3679,10 @@ static void rhel920_virt_options(MachineClass *mc)
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len);
|
||||
compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len);
|
||||
+
|
||||
+ /* RHEL 9.4 is the first supported release */
|
||||
+ mc->deprecation_reason =
|
||||
+ "machine types for versions prior to 9.4 are deprecated";
|
||||
}
|
||||
DEFINE_RHEL_MACHINE(9, 2, 0)
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 7a6be312c11911bdd2ce82566be22a3e014947c2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 16:44:20 +0800
|
||||
Subject: [PATCH 041/101] hw/i386: Activate IOMMUFD for q35 machines
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [40/67] b15764ab24fd57389a8d219736613484acd7d29e (eauger1/centos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 64ad06f6eba66c514477f490bcba409439a480d8)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/i386/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
|
||||
index 55850791df..a1846be6f7 100644
|
||||
--- a/hw/i386/Kconfig
|
||||
+++ b/hw/i386/Kconfig
|
||||
@@ -95,6 +95,7 @@ config Q35
|
||||
imply E1000E_PCI_EXPRESS
|
||||
imply VMPORT
|
||||
imply VMMOUSE
|
||||
+ imply IOMMUFD
|
||||
select PC_PCI
|
||||
select PC_ACPI
|
||||
select PCI_EXPRESS_Q35
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,186 +0,0 @@
|
||||
From ea2e2368dcf4140be47288472f2c2a094358e0c7 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Thu, 8 Feb 2024 23:03:45 +0100
|
||||
Subject: [PATCH 03/20] hw/i386/pc: Defer smbios_set_defaults() to machine_done
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [1/18] 9d4c1d1a910fec7d310429d6fc0b10c798932db7
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
commit: a0204a5ed091dfe79aced7ec8f3ce1931fd25816
|
||||
Author: Bernhard Beschow <shentey@gmail.com>
|
||||
|
||||
Handling most of smbios data generation in the machine_done notifier is similar
|
||||
to how the ARM virt machine handles it which also calls smbios_set_defaults()
|
||||
there. The result is that all pc machines are freed from explicitly worrying
|
||||
about smbios setup.
|
||||
|
||||
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-ID: <20240208220349.4948-6-shentey@gmail.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
|
||||
Conflicts: hw/i386/pc_q35.c, hw/i386/pc_piix.c
|
||||
due to missing 4d3457fef9 (w/i386/pc: Merge pc_guest_info_init() into pc_machine_initfn())
|
||||
and different signature of smbios_set_defaults() downstream
|
||||
Fixup: hw/i386/fw_cfg.c to account for downstream changes smbios_set_defaults()
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 14 +++++++++++++-
|
||||
hw/i386/fw_cfg.h | 3 ++-
|
||||
hw/i386/pc.c | 2 +-
|
||||
hw/i386/pc_piix.c | 12 ------------
|
||||
hw/i386/pc_q35.c | 11 -----------
|
||||
include/hw/i386/pc.h | 1 -
|
||||
6 files changed, 16 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 7362daa45a..6a5466faf0 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -48,15 +48,27 @@ const char *fw_cfg_arch_key_name(uint16_t key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
|
||||
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
{
|
||||
#ifdef CONFIG_SMBIOS
|
||||
uint8_t *smbios_tables, *smbios_anchor;
|
||||
size_t smbios_tables_len, smbios_anchor_len;
|
||||
struct smbios_phys_mem_area *mem_array;
|
||||
unsigned i, array_count;
|
||||
+ MachineState *ms = MACHINE(pcms);
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(pcms);
|
||||
X86CPU *cpu = X86_CPU(ms->possible_cpus->cpus[0].cpu);
|
||||
|
||||
+ if (pcmc->smbios_defaults) {
|
||||
+ /* These values are guest ABI, do not change */
|
||||
+ smbios_set_defaults("QEMU", mc->desc, mc->name,
|
||||
+ pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded,
|
||||
+ pcmc->smbios_stream_product,
|
||||
+ pcmc->smbios_stream_version,
|
||||
+ pcms->smbios_entry_point_type);
|
||||
+ }
|
||||
+
|
||||
/* tell smbios about cpuid version and features */
|
||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h
|
||||
index 86ca7c1c0c..1e1de6b4a3 100644
|
||||
--- a/hw/i386/fw_cfg.h
|
||||
+++ b/hw/i386/fw_cfg.h
|
||||
@@ -10,6 +10,7 @@
|
||||
#define HW_I386_FW_CFG_H
|
||||
|
||||
#include "hw/boards.h"
|
||||
+#include "hw/i386/pc.h"
|
||||
#include "hw/nvram/fw_cfg.h"
|
||||
|
||||
#define FW_CFG_IO_BASE 0x510
|
||||
@@ -22,7 +23,7 @@
|
||||
FWCfgState *fw_cfg_arch_create(MachineState *ms,
|
||||
uint16_t boot_cpus,
|
||||
uint16_t apic_id_limit);
|
||||
-void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg);
|
||||
+void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg);
|
||||
void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
|
||||
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index a1faa9e92c..16de2a59e8 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -847,7 +847,7 @@ void pc_machine_done(Notifier *notifier, void *data)
|
||||
|
||||
acpi_setup();
|
||||
if (x86ms->fw_cfg) {
|
||||
- fw_cfg_build_smbios(MACHINE(pcms), x86ms->fw_cfg);
|
||||
+ fw_cfg_build_smbios(pcms, x86ms->fw_cfg);
|
||||
fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
|
||||
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
|
||||
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index 09d02cc91f..7344b35cf1 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "hw/southbridge/piix.h"
|
||||
#include "hw/display/ramfb.h"
|
||||
-#include "hw/firmware/smbios.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pci_ids.h"
|
||||
#include "hw/usb.h"
|
||||
@@ -233,17 +232,6 @@ static void pc_init1(MachineState *machine,
|
||||
|
||||
pc_guest_info_init(pcms);
|
||||
|
||||
- if (pcmc->smbios_defaults) {
|
||||
- MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
- /* These values are guest ABI, do not change */
|
||||
- smbios_set_defaults("Red Hat", "KVM",
|
||||
- mc->desc, pcmc->smbios_legacy_mode,
|
||||
- pcmc->smbios_uuid_encoded,
|
||||
- pcmc->smbios_stream_product,
|
||||
- pcmc->smbios_stream_version,
|
||||
- pcms->smbios_entry_point_type);
|
||||
- }
|
||||
-
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(pcms, system_memory, rom_memory, hole64_size);
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index c6967e1846..9a22ff5dd6 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "hw/i386/amd_iommu.h"
|
||||
#include "hw/i386/intel_iommu.h"
|
||||
#include "hw/display/ramfb.h"
|
||||
-#include "hw/firmware/smbios.h"
|
||||
#include "hw/ide/pci.h"
|
||||
#include "hw/ide/ahci.h"
|
||||
#include "hw/intc/ioapic.h"
|
||||
@@ -201,16 +200,6 @@ static void pc_q35_init(MachineState *machine)
|
||||
|
||||
pc_guest_info_init(pcms);
|
||||
|
||||
- if (pcmc->smbios_defaults) {
|
||||
- /* These values are guest ABI, do not change */
|
||||
- smbios_set_defaults("Red Hat", "KVM",
|
||||
- mc->desc, pcmc->smbios_legacy_mode,
|
||||
- pcmc->smbios_uuid_encoded,
|
||||
- pcmc->smbios_stream_product,
|
||||
- pcmc->smbios_stream_version,
|
||||
- pcms->smbios_entry_point_type);
|
||||
- }
|
||||
-
|
||||
/* create pci host bus */
|
||||
phb = OBJECT(qdev_new(TYPE_Q35_HOST_DEVICE));
|
||||
|
||||
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
|
||||
index 37644ede7e..c286c10bc3 100644
|
||||
--- a/include/hw/i386/pc.h
|
||||
+++ b/include/hw/i386/pc.h
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "hw/hotplug.h"
|
||||
#include "qom/object.h"
|
||||
#include "hw/i386/sgx-epc.h"
|
||||
-#include "hw/firmware/smbios.h"
|
||||
#include "hw/cxl/cxl.h"
|
||||
|
||||
#define HPET_INTCAP "hpet-intcap"
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,116 +0,0 @@
|
||||
From 84f378c41832602dcf9bad6167b1f532c7c53e37 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 15:03:55 +0100
|
||||
Subject: [PATCH 048/101] hw/ppc/Kconfig: Imply VFIO_PCI
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [47/67] c1a40cdab9bf62b16cb428d57a20b3e0eaa6de38 (eauger1/centos-qemu-kvm)
|
||||
|
||||
When the legacy and iommufd backends were introduced, a set of common
|
||||
vfio-pci routines were exported in pci.c for both backends to use :
|
||||
|
||||
vfio_pci_pre_reset
|
||||
vfio_pci_get_pci_hot_reset_info
|
||||
vfio_pci_host_match
|
||||
vfio_pci_post_reset
|
||||
|
||||
This introduced a build failure on PPC when --without-default-devices
|
||||
is use because VFIO is always selected in ppc/Kconfig but VFIO_PCI is
|
||||
not.
|
||||
|
||||
Use an 'imply VFIO_PCI' in ppc/Kconfig and bypass compilation of the
|
||||
VFIO EEH hooks routines defined in hw/ppc/spapr_pci_vfio.c with
|
||||
CONFIG_VFIO_PCI.
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 4278df9d1d2383b738338c857406357660f11e42)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/ppc/Kconfig | 2 +-
|
||||
hw/ppc/spapr_pci_vfio.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 37 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
|
||||
index 56f0475a8e..44263a58c4 100644
|
||||
--- a/hw/ppc/Kconfig
|
||||
+++ b/hw/ppc/Kconfig
|
||||
@@ -3,11 +3,11 @@ config PSERIES
|
||||
imply PCI_DEVICES
|
||||
imply TEST_DEVICES
|
||||
imply VIRTIO_VGA
|
||||
+ imply VFIO_PCI if LINUX # needed by spapr_pci_vfio.c
|
||||
select NVDIMM
|
||||
select DIMM
|
||||
select PCI
|
||||
select SPAPR_VSCSI
|
||||
- select VFIO if LINUX # needed by spapr_pci_vfio.c
|
||||
select XICS
|
||||
select XIVE
|
||||
select MSI_NONBROKEN
|
||||
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
|
||||
index d1d07bec46..76b2a3487b 100644
|
||||
--- a/hw/ppc/spapr_pci_vfio.c
|
||||
+++ b/hw/ppc/spapr_pci_vfio.c
|
||||
@@ -26,10 +26,12 @@
|
||||
#include "hw/pci/pci_device.h"
|
||||
#include "hw/vfio/vfio-common.h"
|
||||
#include "qemu/error-report.h"
|
||||
+#include CONFIG_DEVICES /* CONFIG_VFIO_PCI */
|
||||
|
||||
/*
|
||||
* Interfaces for IBM EEH (Enhanced Error Handling)
|
||||
*/
|
||||
+#ifdef CONFIG_VFIO_PCI
|
||||
static bool vfio_eeh_container_ok(VFIOContainer *container)
|
||||
{
|
||||
/*
|
||||
@@ -314,3 +316,37 @@ int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
|
||||
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+bool spapr_phb_eeh_available(SpaprPhbState *sphb)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void spapr_phb_vfio_reset(DeviceState *qdev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
|
||||
+ unsigned int addr, int option)
|
||||
+{
|
||||
+ return RTAS_OUT_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state)
|
||||
+{
|
||||
+ return RTAS_OUT_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option)
|
||||
+{
|
||||
+ return RTAS_OUT_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
|
||||
+{
|
||||
+ return RTAS_OUT_NOT_SUPPORTED;
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_VFIO_PCI */
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,73 +0,0 @@
|
||||
From 8f27893a37e55a31180bb66cd9eae7199911881b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Volker=20R=C3=BCmelin?= <vr_qemu@t-online.de>
|
||||
Date: Fri, 29 Dec 2023 21:38:54 +0100
|
||||
Subject: [PATCH 060/101] hw/vfio: fix iteration over global VFIODevice list
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [59/67] f926e1233c8c5ad418e8794b1a103371c9dc5eb0 (eauger1/centos-qemu-kvm)
|
||||
|
||||
Commit 3d779abafe ("vfio/common: Introduce a global VFIODevice list")
|
||||
introduced a global VFIODevice list, but forgot to update the list
|
||||
element field name when iterating over the new list. Change the code
|
||||
to use the correct list element field.
|
||||
|
||||
Fixes: 3d779abafe ("vfio/common: Introduce a global VFIODevice list")
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2061
|
||||
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
|
||||
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Eric Auger <eric.auger@redhat.com>
|
||||
(cherry picked from commit 9353b6da430f90e47f352dbf6dc31120c8914da6)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/vfio/common.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
|
||||
index 0d4d8b8416..0b3352f2a9 100644
|
||||
--- a/hw/vfio/common.c
|
||||
+++ b/hw/vfio/common.c
|
||||
@@ -73,7 +73,7 @@ bool vfio_mig_active(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
- QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) {
|
||||
if (vbasedev->migration_blocker) {
|
||||
return false;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ static bool vfio_multiple_devices_migration_is_supported(void)
|
||||
unsigned int device_num = 0;
|
||||
bool all_support_p2p = true;
|
||||
|
||||
- QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) {
|
||||
if (vbasedev->migration) {
|
||||
device_num++;
|
||||
|
||||
@@ -1366,13 +1366,13 @@ void vfio_reset_handler(void *opaque)
|
||||
{
|
||||
VFIODevice *vbasedev;
|
||||
|
||||
- QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) {
|
||||
if (vbasedev->dev->realized) {
|
||||
vbasedev->ops->vfio_compute_needs_reset(vbasedev);
|
||||
}
|
||||
}
|
||||
|
||||
- QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
|
||||
+ QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) {
|
||||
if (vbasedev->dev->realized && vbasedev->needs_reset) {
|
||||
vbasedev->ops->vfio_hot_reset_multi(vbasedev);
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,54 +0,0 @@
|
||||
From 51b8f29cddb73eb02f91af5f52a205fdd3af6583 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 21:08:59 +0100
|
||||
Subject: [PATCH 099/101] include/ui/rect.h: fix qemu_rect_init()
|
||||
mis-assignment
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 216: Fix regression in QEMU's virtio-gpu VNC sessions
|
||||
RH-Jira: RHEL-21570
|
||||
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Commit: [1/1] a9d487be04e2c1847b80c479b5cc790af81e3428 (thuth/qemu-kvm-cs9)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21570
|
||||
|
||||
commit 9d5b42beb6978dc6219d5dc029c9d453c6b8d503
|
||||
Author: Elen Avan <elen.avan@bk.ru>
|
||||
Date: Fri Dec 22 22:17:21 2023 +0300
|
||||
|
||||
include/ui/rect.h: fix qemu_rect_init() mis-assignment
|
||||
|
||||
Signed-off-by: Elen Avan <elen.avan@bk.ru>
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2051
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2050
|
||||
Fixes: a200d53b1fde "virtio-gpu: replace PIXMAN for region/rect test"
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
include/ui/rect.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/ui/rect.h b/include/ui/rect.h
|
||||
index 94898f92d0..68f05d78a8 100644
|
||||
--- a/include/ui/rect.h
|
||||
+++ b/include/ui/rect.h
|
||||
@@ -19,7 +19,7 @@ static inline void qemu_rect_init(QemuRect *rect,
|
||||
uint16_t width, uint16_t height)
|
||||
{
|
||||
rect->x = x;
|
||||
- rect->y = x;
|
||||
+ rect->y = y;
|
||||
rect->width = width;
|
||||
rect->height = height;
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,133 +0,0 @@
|
||||
From 65d58819ff7b012e43b5f1da1356b559d3f5a962 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 14 Mar 2024 17:58:25 +0100
|
||||
Subject: [PATCH 3/4] iotests: Add test for reset/AioContext switches with NBD
|
||||
exports
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 231: Fix deadlock and crash during storage migration
|
||||
RH-Jira: RHEL-28125
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [3/3] 7266acdf85271d157497bfe452aa6eeb58fbe7c6 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
This replicates the scenario in which the bug was reported.
|
||||
Unfortunately this relies on actually executing a guest (so that the
|
||||
firmware initialises the virtio-blk device and moves it to its
|
||||
configured iothread), so this can't make use of the qtest accelerator
|
||||
like most other test cases. I tried to find a different easy way to
|
||||
trigger the bug, but couldn't find one.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240314165825.40261-3-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit e8fce34eccf68a32f4ecf2c6f121ff2ac383d6bf)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
tests/qemu-iotests/tests/iothreads-nbd-export | 66 +++++++++++++++++++
|
||||
.../tests/iothreads-nbd-export.out | 19 ++++++
|
||||
2 files changed, 85 insertions(+)
|
||||
create mode 100755 tests/qemu-iotests/tests/iothreads-nbd-export
|
||||
create mode 100644 tests/qemu-iotests/tests/iothreads-nbd-export.out
|
||||
|
||||
diff --git a/tests/qemu-iotests/tests/iothreads-nbd-export b/tests/qemu-iotests/tests/iothreads-nbd-export
|
||||
new file mode 100755
|
||||
index 0000000000..037260729c
|
||||
--- /dev/null
|
||||
+++ b/tests/qemu-iotests/tests/iothreads-nbd-export
|
||||
@@ -0,0 +1,66 @@
|
||||
+#!/usr/bin/env python3
|
||||
+# group: rw quick
|
||||
+#
|
||||
+# Copyright (C) 2024 Red Hat, Inc.
|
||||
+#
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 2 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
|
||||
+
|
||||
+import time
|
||||
+import qemu
|
||||
+import iotests
|
||||
+
|
||||
+iotests.script_initialize(supported_fmts=['qcow2'],
|
||||
+ supported_platforms=['linux'])
|
||||
+
|
||||
+with iotests.FilePath('disk1.img') as path, \
|
||||
+ iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \
|
||||
+ qemu.machine.QEMUMachine(iotests.qemu_prog) as vm:
|
||||
+
|
||||
+ img_size = '10M'
|
||||
+
|
||||
+ iotests.log('Preparing disk...')
|
||||
+ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size)
|
||||
+ vm.add_args('-blockdev', f'file,node-name=disk-file,filename={path}')
|
||||
+ vm.add_args('-blockdev', 'qcow2,node-name=disk,file=disk-file')
|
||||
+ vm.add_args('-object', 'iothread,id=iothread0')
|
||||
+ vm.add_args('-device',
|
||||
+ 'virtio-blk,drive=disk,iothread=iothread0,share-rw=on')
|
||||
+
|
||||
+ iotests.log('Launching VM...')
|
||||
+ vm.add_args('-accel', 'kvm', '-accel', 'tcg')
|
||||
+ #vm.add_args('-accel', 'qtest')
|
||||
+ vm.launch()
|
||||
+
|
||||
+ iotests.log('Exporting to NBD...')
|
||||
+ iotests.log(vm.qmp('nbd-server-start',
|
||||
+ addr={'type': 'unix', 'data': {'path': nbd_sock}}))
|
||||
+ iotests.log(vm.qmp('block-export-add', type='nbd', id='exp0',
|
||||
+ node_name='disk', writable=True))
|
||||
+
|
||||
+ iotests.log('Connecting qemu-img...')
|
||||
+ qemu_io = iotests.QemuIoInteractive('-f', 'raw',
|
||||
+ f'nbd+unix:///disk?socket={nbd_sock}')
|
||||
+
|
||||
+ iotests.log('Moving the NBD export to a different iothread...')
|
||||
+ for i in range(0, 10):
|
||||
+ iotests.log(vm.qmp('system_reset'))
|
||||
+ time.sleep(0.1)
|
||||
+
|
||||
+ iotests.log('Checking that it is still alive...')
|
||||
+ iotests.log(vm.qmp('query-status'))
|
||||
+
|
||||
+ qemu_io.close()
|
||||
+ vm.shutdown()
|
||||
diff --git a/tests/qemu-iotests/tests/iothreads-nbd-export.out b/tests/qemu-iotests/tests/iothreads-nbd-export.out
|
||||
new file mode 100644
|
||||
index 0000000000..bc514e35e5
|
||||
--- /dev/null
|
||||
+++ b/tests/qemu-iotests/tests/iothreads-nbd-export.out
|
||||
@@ -0,0 +1,19 @@
|
||||
+Preparing disk...
|
||||
+Launching VM...
|
||||
+Exporting to NBD...
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+Connecting qemu-img...
|
||||
+Moving the NBD export to a different iothread...
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+{"return": {}}
|
||||
+Checking that it is still alive...
|
||||
+{"return": {"running": true, "status": "running"}}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,49 +0,0 @@
|
||||
From a9be663beaace1c31d75ca353e5d3bb0657a4f6c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 18 Jan 2024 09:48:21 -0500
|
||||
Subject: [PATCH 11/22] iotests: add filter_qmp_generated_node_ids()
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [7/17] 8dd20acc5b1e992294ed422e80897a9c221940dd (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
Add a filter function for QMP responses that contain QEMU's
|
||||
automatically generated node ids. The ids change between runs and must
|
||||
be masked in the reference output.
|
||||
|
||||
The next commit will use this new function.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20240118144823.1497953-2-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit da62b507a20510d819bcfbe8f5e573409b954006)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
tests/qemu-iotests/iotests.py | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
|
||||
index e5c5798c71..ea48af4a7b 100644
|
||||
--- a/tests/qemu-iotests/iotests.py
|
||||
+++ b/tests/qemu-iotests/iotests.py
|
||||
@@ -651,6 +651,13 @@ def _filter(_key, value):
|
||||
def filter_generated_node_ids(msg):
|
||||
return re.sub("#block[0-9]+", "NODE_NAME", msg)
|
||||
|
||||
+def filter_qmp_generated_node_ids(qmsg):
|
||||
+ def _filter(_key, value):
|
||||
+ if is_str(value):
|
||||
+ return filter_generated_node_ids(value)
|
||||
+ return value
|
||||
+ return filter_qmp(qmsg, _filter)
|
||||
+
|
||||
def filter_img_info(output: str, filename: str,
|
||||
drop_child_info: bool = True) -> str:
|
||||
lines = []
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 453da839a7d81896d03b827a95c1991a60740dc5 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 25 Jan 2024 16:21:50 +0100
|
||||
Subject: [PATCH 21/22] iotests/iothreads-stream: Use the right TimeoutError
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [17/17] ca5a512ccccb668089b726d7499562d1e294c828 (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
Since Python 3.11 asyncio.TimeoutError is an alias for TimeoutError, but
|
||||
in older versions it's not. We really have to catch asyncio.TimeoutError
|
||||
here, otherwise a slow test run will fail (as has happened multiple
|
||||
times on CI recently).
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240125152150.42389-1-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit c9c0b37ff4c11b712b21efabe8e5381d223d0295)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
tests/qemu-iotests/tests/iothreads-stream | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/qemu-iotests/tests/iothreads-stream b/tests/qemu-iotests/tests/iothreads-stream
|
||||
index 503f221f16..231195b5e8 100755
|
||||
--- a/tests/qemu-iotests/tests/iothreads-stream
|
||||
+++ b/tests/qemu-iotests/tests/iothreads-stream
|
||||
@@ -18,6 +18,7 @@
|
||||
#
|
||||
# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
|
||||
|
||||
+import asyncio
|
||||
import iotests
|
||||
|
||||
iotests.script_initialize(supported_fmts=['qcow2'],
|
||||
@@ -69,6 +70,6 @@ with iotests.FilePath('disk1.img') as base1_path, \
|
||||
# The test is done once both jobs are gone
|
||||
if finished == 2:
|
||||
break
|
||||
- except TimeoutError:
|
||||
+ except asyncio.TimeoutError:
|
||||
pass
|
||||
vm.cmd('query-jobs')
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,592 +0,0 @@
|
||||
From 70efc3bbf1f7d7b1b0c2475d9ce3bb70cc9d1cc7 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 18 Jan 2024 09:48:22 -0500
|
||||
Subject: [PATCH 12/22] iotests: port 141 to Python for reliable QMP testing
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [8/17] 0783f536508916feac4b4c39e41c22c24a2e52e7 (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
The common.qemu bash functions allow tests to interact with the QMP
|
||||
monitor of a QEMU process. I spent two days trying to update 141 when
|
||||
the order of the test output changed, but found it would still fail
|
||||
occassionally because printf() and QMP events race with synchronous QMP
|
||||
communication.
|
||||
|
||||
I gave up and ported 141 to the existing Python API for QMP tests. The
|
||||
Python API is less affected by the order in which QEMU prints output
|
||||
because it does not print all QMP traffic by default.
|
||||
|
||||
The next commit changes the order in which QMP messages are received.
|
||||
Make 141 reliable first.
|
||||
|
||||
Cc: Hanna Czenczek <hreitz@redhat.com>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20240118144823.1497953-3-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 9ee2dd4c22a3639c5462b3fc20df60c005c3de64)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
tests/qemu-iotests/141 | 307 ++++++++++++++++---------------------
|
||||
tests/qemu-iotests/141.out | 200 ++++++------------------
|
||||
2 files changed, 176 insertions(+), 331 deletions(-)
|
||||
|
||||
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
|
||||
index a37030ee17..a7d3985a02 100755
|
||||
--- a/tests/qemu-iotests/141
|
||||
+++ b/tests/qemu-iotests/141
|
||||
@@ -1,9 +1,12 @@
|
||||
-#!/usr/bin/env bash
|
||||
+#!/usr/bin/env python3
|
||||
# group: rw auto quick
|
||||
#
|
||||
# Test case for ejecting BDSs with block jobs still running on them
|
||||
#
|
||||
-# Copyright (C) 2016 Red Hat, Inc.
|
||||
+# Originally written in bash by Hanna Czenczek, ported to Python by Stefan
|
||||
+# Hajnoczi.
|
||||
+#
|
||||
+# Copyright Red Hat
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -19,177 +22,129 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
-# creator
|
||||
-owner=hreitz@redhat.com
|
||||
-
|
||||
-seq="$(basename $0)"
|
||||
-echo "QA output created by $seq"
|
||||
-
|
||||
-status=1 # failure is the default!
|
||||
-
|
||||
-_cleanup()
|
||||
-{
|
||||
- _cleanup_qemu
|
||||
- _cleanup_test_img
|
||||
- for img in "$TEST_DIR"/{b,m,o}.$IMGFMT; do
|
||||
- _rm_test_img "$img"
|
||||
- done
|
||||
-}
|
||||
-trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
-
|
||||
-# get standard environment, filters and checks
|
||||
-. ./common.rc
|
||||
-. ./common.filter
|
||||
-. ./common.qemu
|
||||
-
|
||||
-# Needs backing file and backing format support
|
||||
-_supported_fmt qcow2 qed
|
||||
-_supported_proto file
|
||||
-_supported_os Linux
|
||||
-
|
||||
-
|
||||
-test_blockjob()
|
||||
-{
|
||||
- _send_qemu_cmd $QEMU_HANDLE \
|
||||
- "{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': '$IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': '$TEST_IMG'
|
||||
- }}}" \
|
||||
- 'return'
|
||||
-
|
||||
- # If "$2" is an event, we may or may not see it before the
|
||||
- # {"return": {}}. Therefore, filter the {"return": {}} out both
|
||||
- # here and in the next command. (Naturally, if we do not see it
|
||||
- # here, we will see it before the next command can be executed,
|
||||
- # so it will appear in the next _send_qemu_cmd's output.)
|
||||
- _send_qemu_cmd $QEMU_HANDLE \
|
||||
- "$1" \
|
||||
- "$2" \
|
||||
- | _filter_img_create | _filter_qmp_empty_return
|
||||
-
|
||||
- # We want this to return an error because the block job is still running
|
||||
- _send_qemu_cmd $QEMU_HANDLE \
|
||||
- "{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}" \
|
||||
- 'error' | _filter_generated_node_ids | _filter_qmp_empty_return
|
||||
-
|
||||
- _send_qemu_cmd $QEMU_HANDLE \
|
||||
- "{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}" \
|
||||
- "$3"
|
||||
-
|
||||
- _send_qemu_cmd $QEMU_HANDLE \
|
||||
- "{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}" \
|
||||
- 'return'
|
||||
-}
|
||||
-
|
||||
-
|
||||
-TEST_IMG="$TEST_DIR/b.$IMGFMT" _make_test_img 1M
|
||||
-TEST_IMG="$TEST_DIR/m.$IMGFMT" _make_test_img -b "$TEST_DIR/b.$IMGFMT" -F $IMGFMT 1M
|
||||
-_make_test_img -b "$TEST_DIR/m.$IMGFMT" 1M -F $IMGFMT
|
||||
-
|
||||
-_launch_qemu -nodefaults
|
||||
-
|
||||
-_send_qemu_cmd $QEMU_HANDLE \
|
||||
- "{'execute': 'qmp_capabilities'}" \
|
||||
- 'return'
|
||||
-
|
||||
-echo
|
||||
-echo '=== Testing drive-backup ==='
|
||||
-echo
|
||||
-
|
||||
-# drive-backup will not send BLOCK_JOB_READY by itself, and cancelling the job
|
||||
-# will consequently result in BLOCK_JOB_CANCELLED being emitted.
|
||||
-
|
||||
-test_blockjob \
|
||||
- "{'execute': 'drive-backup',
|
||||
- 'arguments': {'job-id': 'job0',
|
||||
- 'device': 'drv0',
|
||||
- 'target': '$TEST_DIR/o.$IMGFMT',
|
||||
- 'format': '$IMGFMT',
|
||||
- 'sync': 'none'}}" \
|
||||
- 'return' \
|
||||
- '"status": "null"'
|
||||
-
|
||||
-echo
|
||||
-echo '=== Testing drive-mirror ==='
|
||||
-echo
|
||||
-
|
||||
-# drive-mirror will send BLOCK_JOB_READY basically immediately, and cancelling
|
||||
-# the job will consequently result in BLOCK_JOB_COMPLETED being emitted.
|
||||
-
|
||||
-test_blockjob \
|
||||
- "{'execute': 'drive-mirror',
|
||||
- 'arguments': {'job-id': 'job0',
|
||||
- 'device': 'drv0',
|
||||
- 'target': '$TEST_DIR/o.$IMGFMT',
|
||||
- 'format': '$IMGFMT',
|
||||
- 'sync': 'none'}}" \
|
||||
- 'BLOCK_JOB_READY' \
|
||||
- '"status": "null"'
|
||||
-
|
||||
-echo
|
||||
-echo '=== Testing active block-commit ==='
|
||||
-echo
|
||||
-
|
||||
-# An active block-commit will send BLOCK_JOB_READY basically immediately, and
|
||||
-# cancelling the job will consequently result in BLOCK_JOB_COMPLETED being
|
||||
-# emitted.
|
||||
-
|
||||
-test_blockjob \
|
||||
- "{'execute': 'block-commit',
|
||||
- 'arguments': {'job-id': 'job0', 'device': 'drv0'}}" \
|
||||
- 'BLOCK_JOB_READY' \
|
||||
- '"status": "null"'
|
||||
-
|
||||
-echo
|
||||
-echo '=== Testing non-active block-commit ==='
|
||||
-echo
|
||||
-
|
||||
-# Give block-commit something to work on, otherwise it would be done
|
||||
-# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just
|
||||
-# fine without the block job still running.
|
||||
-
|
||||
-$QEMU_IO -c 'write 0 1M' "$TEST_DIR/m.$IMGFMT" | _filter_qemu_io
|
||||
-
|
||||
-test_blockjob \
|
||||
- "{'execute': 'block-commit',
|
||||
- 'arguments': {'job-id': 'job0',
|
||||
- 'device': 'drv0',
|
||||
- 'top': '$TEST_DIR/m.$IMGFMT',
|
||||
- 'speed': 1}}" \
|
||||
- 'return' \
|
||||
- '"status": "null"'
|
||||
-
|
||||
-echo
|
||||
-echo '=== Testing block-stream ==='
|
||||
-echo
|
||||
-
|
||||
-# Give block-stream something to work on, otherwise it would be done
|
||||
-# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work just
|
||||
-# fine without the block job still running.
|
||||
-
|
||||
-$QEMU_IO -c 'write 0 1M' "$TEST_DIR/b.$IMGFMT" | _filter_qemu_io
|
||||
-
|
||||
-# With some data to stream (and @speed set to 1), block-stream will not complete
|
||||
-# until we send the block-job-cancel command.
|
||||
-
|
||||
-test_blockjob \
|
||||
- "{'execute': 'block-stream',
|
||||
- 'arguments': {'job-id': 'job0',
|
||||
- 'device': 'drv0',
|
||||
- 'speed': 1}}" \
|
||||
- 'return' \
|
||||
- '"status": "null"'
|
||||
-
|
||||
-_cleanup_qemu
|
||||
-
|
||||
-# success, all done
|
||||
-echo "*** done"
|
||||
-rm -f $seq.full
|
||||
-status=0
|
||||
+import iotests
|
||||
+
|
||||
+# Common filters to mask values that vary in the test output
|
||||
+QMP_FILTERS = [iotests.filter_qmp_testfiles, \
|
||||
+ iotests.filter_qmp_imgfmt]
|
||||
+
|
||||
+
|
||||
+class TestCase:
|
||||
+ def __init__(self, name, vm, image_path, cancel_event):
|
||||
+ self.name = name
|
||||
+ self.vm = vm
|
||||
+ self.image_path = image_path
|
||||
+ self.cancel_event = cancel_event
|
||||
+
|
||||
+ def __enter__(self):
|
||||
+ iotests.log(f'=== Testing {self.name} ===')
|
||||
+ self.vm.qmp_log('blockdev-add', \
|
||||
+ node_name='drv0', \
|
||||
+ driver=iotests.imgfmt, \
|
||||
+ file={'driver': 'file', 'filename': self.image_path}, \
|
||||
+ filters=QMP_FILTERS)
|
||||
+
|
||||
+ def __exit__(self, *exc_details):
|
||||
+ # This is expected to fail because the job still exists
|
||||
+ self.vm.qmp_log('blockdev-del', node_name='drv0', \
|
||||
+ filters=[iotests.filter_qmp_generated_node_ids])
|
||||
+
|
||||
+ self.vm.qmp_log('block-job-cancel', device='job0')
|
||||
+ event = self.vm.event_wait(self.cancel_event)
|
||||
+ iotests.log(event, filters=[iotests.filter_qmp_event])
|
||||
+
|
||||
+ # This time it succeeds
|
||||
+ self.vm.qmp_log('blockdev-del', node_name='drv0')
|
||||
+
|
||||
+ # Separate test cases in output
|
||||
+ iotests.log('')
|
||||
+
|
||||
+
|
||||
+def main() -> None:
|
||||
+ with iotests.FilePath('bottom', 'middle', 'top', 'target') as \
|
||||
+ (bottom_path, middle_path, top_path, target_path), \
|
||||
+ iotests.VM() as vm:
|
||||
+
|
||||
+ iotests.log('Creating bottom <- middle <- top backing file chain...')
|
||||
+ IMAGE_SIZE='1M'
|
||||
+ iotests.qemu_img_create('-f', iotests.imgfmt, bottom_path, IMAGE_SIZE)
|
||||
+ iotests.qemu_img_create('-f', iotests.imgfmt, \
|
||||
+ '-F', iotests.imgfmt, \
|
||||
+ '-b', bottom_path, \
|
||||
+ middle_path, \
|
||||
+ IMAGE_SIZE)
|
||||
+ iotests.qemu_img_create('-f', iotests.imgfmt, \
|
||||
+ '-F', iotests.imgfmt, \
|
||||
+ '-b', middle_path, \
|
||||
+ top_path, \
|
||||
+ IMAGE_SIZE)
|
||||
+
|
||||
+ iotests.log('Starting VM...')
|
||||
+ vm.add_args('-nodefaults')
|
||||
+ vm.launch()
|
||||
+
|
||||
+ # drive-backup will not send BLOCK_JOB_READY by itself, and cancelling
|
||||
+ # the job will consequently result in BLOCK_JOB_CANCELLED being
|
||||
+ # emitted.
|
||||
+ with TestCase('drive-backup', vm, top_path, 'BLOCK_JOB_CANCELLED'):
|
||||
+ vm.qmp_log('drive-backup', \
|
||||
+ job_id='job0', \
|
||||
+ device='drv0', \
|
||||
+ target=target_path, \
|
||||
+ format=iotests.imgfmt, \
|
||||
+ sync='none', \
|
||||
+ filters=QMP_FILTERS)
|
||||
+
|
||||
+ # drive-mirror will send BLOCK_JOB_READY basically immediately, and
|
||||
+ # cancelling the job will consequently result in BLOCK_JOB_COMPLETED
|
||||
+ # being emitted.
|
||||
+ with TestCase('drive-mirror', vm, top_path, 'BLOCK_JOB_COMPLETED'):
|
||||
+ vm.qmp_log('drive-mirror', \
|
||||
+ job_id='job0', \
|
||||
+ device='drv0', \
|
||||
+ target=target_path, \
|
||||
+ format=iotests.imgfmt, \
|
||||
+ sync='none', \
|
||||
+ filters=QMP_FILTERS)
|
||||
+ event = vm.event_wait('BLOCK_JOB_READY')
|
||||
+ assert event is not None # silence mypy
|
||||
+ iotests.log(event, filters=[iotests.filter_qmp_event])
|
||||
+
|
||||
+ # An active block-commit will send BLOCK_JOB_READY basically
|
||||
+ # immediately, and cancelling the job will consequently result in
|
||||
+ # BLOCK_JOB_COMPLETED being emitted.
|
||||
+ with TestCase('active block-commit', vm, top_path, \
|
||||
+ 'BLOCK_JOB_COMPLETED'):
|
||||
+ vm.qmp_log('block-commit', \
|
||||
+ job_id='job0', \
|
||||
+ device='drv0')
|
||||
+ event = vm.event_wait('BLOCK_JOB_READY')
|
||||
+ assert event is not None # silence mypy
|
||||
+ iotests.log(event, filters=[iotests.filter_qmp_event])
|
||||
+
|
||||
+ # Give block-commit something to work on, otherwise it would be done
|
||||
+ # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would
|
||||
+ # work just fine without the block job still running.
|
||||
+ iotests.qemu_io(middle_path, '-c', f'write 0 {IMAGE_SIZE}')
|
||||
+ with TestCase('non-active block-commit', vm, top_path, \
|
||||
+ 'BLOCK_JOB_CANCELLED'):
|
||||
+ vm.qmp_log('block-commit', \
|
||||
+ job_id='job0', \
|
||||
+ device='drv0', \
|
||||
+ top=middle_path, \
|
||||
+ speed=1, \
|
||||
+ filters=[iotests.filter_qmp_testfiles])
|
||||
+
|
||||
+ # Give block-stream something to work on, otherwise it would be done
|
||||
+ # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would
|
||||
+ # work just fine without the block job still running.
|
||||
+ iotests.qemu_io(bottom_path, '-c', f'write 0 {IMAGE_SIZE}')
|
||||
+ with TestCase('block-stream', vm, top_path, 'BLOCK_JOB_CANCELLED'):
|
||||
+ vm.qmp_log('block-stream', \
|
||||
+ job_id='job0', \
|
||||
+ device='drv0', \
|
||||
+ speed=1)
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ iotests.script_main(main, supported_fmts=['qcow2', 'qed'],
|
||||
+ supported_protocols=['file'])
|
||||
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
|
||||
index 63203d9944..91b7ba50af 100644
|
||||
--- a/tests/qemu-iotests/141.out
|
||||
+++ b/tests/qemu-iotests/141.out
|
||||
@@ -1,179 +1,69 @@
|
||||
-QA output created by 141
|
||||
-Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=1048576
|
||||
-Formatting 'TEST_DIR/m.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/b.IMGFMT backing_fmt=IMGFMT
|
||||
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.IMGFMT backing_fmt=IMGFMT
|
||||
-{'execute': 'qmp_capabilities'}
|
||||
-{"return": {}}
|
||||
-
|
||||
+Creating bottom <- middle <- top backing file chain...
|
||||
+Starting VM...
|
||||
=== Testing drive-backup ===
|
||||
-
|
||||
-{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': 'IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': 'TEST_DIR/t.IMGFMT'
|
||||
- }}}
|
||||
-{"return": {}}
|
||||
-{'execute': 'drive-backup',
|
||||
-'arguments': {'job-id': 'job0',
|
||||
-'device': 'drv0',
|
||||
-'target': 'TEST_DIR/o.IMGFMT',
|
||||
-'format': 'IMGFMT',
|
||||
-'sync': 'none'}}
|
||||
-Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "drive-backup", "arguments": {"device": "drv0", "format": "IMGFMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
|
||||
-{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}
|
||||
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
|
||||
{"return": {}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"return": {}}
|
||||
|
||||
=== Testing drive-mirror ===
|
||||
-
|
||||
-{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': 'IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': 'TEST_DIR/t.IMGFMT'
|
||||
- }}}
|
||||
-{"return": {}}
|
||||
-{'execute': 'drive-mirror',
|
||||
-'arguments': {'job-id': 'job0',
|
||||
-'device': 'drv0',
|
||||
-'target': 'TEST_DIR/o.IMGFMT',
|
||||
-'format': 'IMGFMT',
|
||||
-'sync': 'none'}}
|
||||
-Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "drive-mirror", "arguments": {"device": "drv0", "format": "IMGFMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}}
|
||||
+{"return": {}}
|
||||
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
|
||||
-{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}
|
||||
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
|
||||
{"return": {}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"return": {}}
|
||||
|
||||
=== Testing active block-commit ===
|
||||
-
|
||||
-{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': 'IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': 'TEST_DIR/t.IMGFMT'
|
||||
- }}}
|
||||
-{"return": {}}
|
||||
-{'execute': 'block-commit',
|
||||
-'arguments': {'job-id': 'job0', 'device': 'drv0'}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job0"}}
|
||||
+{"return": {}}
|
||||
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
|
||||
-{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}
|
||||
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
|
||||
{"return": {}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"return": {}}
|
||||
|
||||
=== Testing non-active block-commit ===
|
||||
-
|
||||
-wrote 1048576/1048576 bytes at offset 0
|
||||
-1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
-{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': 'IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': 'TEST_DIR/t.IMGFMT'
|
||||
- }}}
|
||||
-{"return": {}}
|
||||
-{'execute': 'block-commit',
|
||||
-'arguments': {'job-id': 'job0',
|
||||
-'device': 'drv0',
|
||||
-'top': 'TEST_DIR/m.IMGFMT',
|
||||
-'speed': 1}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job0", "speed": 1, "top": "TEST_DIR/PID-middle"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
|
||||
-{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}
|
||||
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
|
||||
{"return": {}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"return": {}}
|
||||
|
||||
=== Testing block-stream ===
|
||||
-
|
||||
-wrote 1048576/1048576 bytes at offset 0
|
||||
-1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
-{'execute': 'blockdev-add',
|
||||
- 'arguments': {
|
||||
- 'node-name': 'drv0',
|
||||
- 'driver': 'IMGFMT',
|
||||
- 'file': {
|
||||
- 'driver': 'file',
|
||||
- 'filename': 'TEST_DIR/t.IMGFMT'
|
||||
- }}}
|
||||
-{"return": {}}
|
||||
-{'execute': 'block-stream',
|
||||
-'arguments': {'job-id': 'job0',
|
||||
-'device': 'drv0',
|
||||
-'speed': 1}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}}
|
||||
+{"return": {}}
|
||||
+{"execute": "block-stream", "arguments": {"device": "drv0", "job-id": "job0", "speed": 1}}
|
||||
+{"return": {}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}}
|
||||
-{'execute': 'block-job-cancel',
|
||||
- 'arguments': {'device': 'job0'}}
|
||||
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
|
||||
{"return": {}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
|
||||
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
|
||||
-{'execute': 'blockdev-del',
|
||||
- 'arguments': {'node-name': 'drv0'}}
|
||||
+{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
|
||||
+{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}}
|
||||
{"return": {}}
|
||||
-*** done
|
||||
+
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,105 +0,0 @@
|
||||
From 4ab25b33831fa207500179bd30f29388d81e4cce Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:10 -0500
|
||||
Subject: [PATCH 093/101] job: remove outdated AioContext locking comments
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [24/26] 15ff2928be82d6905c22619458487fbb72d6044a (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The AioContext lock no longer exists.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-14-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
include/qemu/job.h | 20 --------------------
|
||||
1 file changed, 20 deletions(-)
|
||||
|
||||
diff --git a/include/qemu/job.h b/include/qemu/job.h
|
||||
index e502787dd8..9ea98b5927 100644
|
||||
--- a/include/qemu/job.h
|
||||
+++ b/include/qemu/job.h
|
||||
@@ -67,8 +67,6 @@ typedef struct Job {
|
||||
|
||||
/**
|
||||
* The completion function that will be called when the job completes.
|
||||
- * Called with AioContext lock held, since many callback implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
BlockCompletionFunc *cb;
|
||||
|
||||
@@ -264,9 +262,6 @@ struct JobDriver {
|
||||
*
|
||||
* This callback will not be invoked if the job has already failed.
|
||||
* If it fails, abort and then clean will be called.
|
||||
- *
|
||||
- * Called with AioContext lock held, since many callbacs implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
int (*prepare)(Job *job);
|
||||
|
||||
@@ -277,9 +272,6 @@ struct JobDriver {
|
||||
*
|
||||
* All jobs will complete with a call to either .commit() or .abort() but
|
||||
* never both.
|
||||
- *
|
||||
- * Called with AioContext lock held, since many callback implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
void (*commit)(Job *job);
|
||||
|
||||
@@ -290,9 +282,6 @@ struct JobDriver {
|
||||
*
|
||||
* All jobs will complete with a call to either .commit() or .abort() but
|
||||
* never both.
|
||||
- *
|
||||
- * Called with AioContext lock held, since many callback implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
void (*abort)(Job *job);
|
||||
|
||||
@@ -301,9 +290,6 @@ struct JobDriver {
|
||||
* .commit() or .abort(). Regardless of which callback is invoked after
|
||||
* completion, .clean() will always be called, even if the job does not
|
||||
* belong to a transaction group.
|
||||
- *
|
||||
- * Called with AioContext lock held, since many callbacs implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
void (*clean)(Job *job);
|
||||
|
||||
@@ -318,17 +304,12 @@ struct JobDriver {
|
||||
* READY).
|
||||
* (If the callback is NULL, the job is assumed to terminate
|
||||
* without I/O.)
|
||||
- *
|
||||
- * Called with AioContext lock held, since many callback implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
bool (*cancel)(Job *job, bool force);
|
||||
|
||||
|
||||
/**
|
||||
* Called when the job is freed.
|
||||
- * Called with AioContext lock held, since many callback implementations
|
||||
- * use bdrv_* functions that require to hold the lock.
|
||||
*/
|
||||
void (*free)(Job *job);
|
||||
};
|
||||
@@ -424,7 +405,6 @@ void job_ref_locked(Job *job);
|
||||
* Release a reference that was previously acquired with job_ref_locked() or
|
||||
* job_create(). If it's the last reference to the object, it will be freed.
|
||||
*
|
||||
- * Takes AioContext lock internally to invoke a job->driver callback.
|
||||
* Called with job lock held.
|
||||
*/
|
||||
void job_unref_locked(Job *job);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 9c2eb4ab03903bc084c53ac29b60b8d2121c9fed Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Tue, 21 Nov 2023 16:44:19 +0800
|
||||
Subject: [PATCH 040/101] kconfig: Activate IOMMUFD for s390x machines
|
||||
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: 211: IOMMUFD backend backport
|
||||
RH-Jira: RHEL-19302 RHEL-21057
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Sebastian Ott <sebott@redhat.com>
|
||||
RH-Commit: [39/67] cf0ebe770b8db5916dd35247618c0a325dc1eaab (eauger1/centos-qemu-kvm)
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
|
||||
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
(cherry picked from commit 73e2df669335047b542b67d37ade060a6ae40dd8)
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
---
|
||||
hw/s390x/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/s390x/Kconfig b/hw/s390x/Kconfig
|
||||
index 4c068d7960..26ad104485 100644
|
||||
--- a/hw/s390x/Kconfig
|
||||
+++ b/hw/s390x/Kconfig
|
||||
@@ -6,6 +6,7 @@ config S390_CCW_VIRTIO
|
||||
imply VFIO_CCW
|
||||
imply WDT_DIAG288
|
||||
imply PCIE_DEVICES
|
||||
+ imply IOMMUFD
|
||||
select PCI_EXPRESS
|
||||
select S390_FLIC
|
||||
select S390_FLIC_KVM if KVM
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,112 +0,0 @@
|
||||
From 633c6a52ac88526534466ae311522fe5447bcf91 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 14:55:54 +0100
|
||||
Subject: [PATCH 02/22] memory-device: reintroduce memory region size check
|
||||
|
||||
RH-Author: David Hildenbrand <david@redhat.com>
|
||||
RH-MergeRequest: 221: memory-device: reintroduce memory region size check
|
||||
RH-Jira: RHEL-20341
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-Commit: [2/2] e9ff2339b0c07c3f48f5834c9c80cd6d4cbc8f71
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-20341
|
||||
|
||||
We used to check that the memory region size is multiples of the overall
|
||||
requested address alignment for the device memory address.
|
||||
|
||||
We removed that check, because there are cases (i.e., hv-balloon) where
|
||||
devices unconditionally request an address alignment that has a very large
|
||||
alignment (i.e., 32 GiB), but the actual memory device size might not be
|
||||
multiples of that alignment.
|
||||
|
||||
However, this change:
|
||||
|
||||
(a) allows for some practically impossible DIMM sizes, like "1GB+1 byte".
|
||||
(b) allows for DIMMs that partially cover hugetlb pages, previously
|
||||
reported in [1].
|
||||
|
||||
Both scenarios don't make any sense: we might even waste memory.
|
||||
|
||||
So let's reintroduce that check, but only check that the
|
||||
memory region size is multiples of the memory region alignment (i.e.,
|
||||
page size, huge page size), but not any additional memory device
|
||||
requirements communicated using md->get_min_alignment().
|
||||
|
||||
The following examples now fail again as expected:
|
||||
|
||||
(a) 1M with 2M THP
|
||||
qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \
|
||||
-object memory-backend-ram,id=mem1,size=1M \
|
||||
-device pc-dimm,id=dimm1,memdev=mem1
|
||||
-> backend memory size must be multiple of 0x200000
|
||||
|
||||
(b) 1G+1byte
|
||||
|
||||
qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \
|
||||
-object memory-backend-ram,id=mem1,size=1073741825B \
|
||||
-device pc-dimm,id=dimm1,memdev=mem1
|
||||
-> backend memory size must be multiple of 0x200000
|
||||
|
||||
(c) Unliagned hugetlb size (2M)
|
||||
|
||||
qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \
|
||||
-object memory-backend-file,id=mem1,mem-path=/dev/hugepages/tmp,size=511M \
|
||||
-device pc-dimm,id=dimm1,memdev=mem1
|
||||
backend memory size must be multiple of 0x200000
|
||||
|
||||
(d) Unliagned hugetlb size (1G)
|
||||
|
||||
qemu-system-x86_64 -m 4g,maxmem=16g,slots=1 -S -nodefaults -nographic \
|
||||
-object memory-backend-file,id=mem1,mem-path=/dev/hugepages1G/tmp,size=2047M \
|
||||
-device pc-dimm,id=dimm1,memdev=mem1
|
||||
-> backend memory size must be multiple of 0x40000000
|
||||
|
||||
Note that this fix depends on a hv-balloon change to communicate its
|
||||
additional alignment requirements using get_min_alignment() instead of
|
||||
through the memory region.
|
||||
|
||||
[1] https://lkml.kernel.org/r/f77d641d500324525ac036fe1827b3070de75fc1.1701088320.git.mprivozn@redhat.com
|
||||
|
||||
Message-ID: <20240117135554.787344-3-david@redhat.com>
|
||||
Reported-by: Zhenyu Zhang <zhenyzha@redhat.com>
|
||||
Reported-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Fixes: eb1b7c4bd413 ("memory-device: Drop size alignment check")
|
||||
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
|
||||
Tested-by: Mario Casquero <mcasquer@redhat.com>
|
||||
Reviewed-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 540a1abbf0b243e4cfb4333c5d30a041f7080ba4)
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
---
|
||||
hw/mem/memory-device.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
|
||||
index a1b1af26bc..e098585cda 100644
|
||||
--- a/hw/mem/memory-device.c
|
||||
+++ b/hw/mem/memory-device.c
|
||||
@@ -374,6 +374,20 @@ void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * We always want the memory region size to be multiples of the memory
|
||||
+ * region alignment: for example, DIMMs with 1G+1byte size don't make
|
||||
+ * any sense. Note that we don't check that the size is multiples
|
||||
+ * of any additional alignment requirements the memory device might
|
||||
+ * have when it comes to the address in physical address space.
|
||||
+ */
|
||||
+ if (!QEMU_IS_ALIGNED(memory_region_size(mr),
|
||||
+ memory_region_get_alignment(mr))) {
|
||||
+ error_setg(errp, "backend memory size must be multiple of 0x%"
|
||||
+ PRIx64, memory_region_get_alignment(mr));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (legacy_align) {
|
||||
align = *legacy_align;
|
||||
} else {
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 21cadc8ed200ad9af13b217b441b9f12cd2163ee Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Wed, 13 Mar 2024 16:30:00 +0100
|
||||
Subject: [PATCH 1/4] mirror: Don't call job_pause_point() under graph lock
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 231: Fix deadlock and crash during storage migration
|
||||
RH-Jira: RHEL-28125
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [1/3] 093910fcd5ea1516d0ed48a9cd73dad6170590f3 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Calling job_pause_point() while holding the graph reader lock
|
||||
potentially results in a deadlock: bdrv_graph_wrlock() first drains
|
||||
everything, including the mirror job, which pauses it. The job is only
|
||||
unpaused at the end of the drain section, which is when the graph writer
|
||||
lock has been successfully taken. However, if the job happens to be
|
||||
paused at a pause point where it still holds the reader lock, the writer
|
||||
lock can't be taken as long as the job is still paused.
|
||||
|
||||
Mark job_pause_point() as GRAPH_UNLOCKED and fix mirror accordingly.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-28125
|
||||
Fixes: 004915a96a7a ("block: Protect bs->backing with graph_lock")
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240313153000.33121-1-kwolf@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit ae5a40e8581185654a667fbbf7e4adbc2a2a3e45)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/mirror.c | 10 ++++++----
|
||||
include/qemu/job.h | 2 +-
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index 5145eb53e1..1bdce3b657 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -479,9 +479,9 @@ static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset,
|
||||
return bytes_handled;
|
||||
}
|
||||
|
||||
-static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s)
|
||||
+static void coroutine_fn GRAPH_UNLOCKED mirror_iteration(MirrorBlockJob *s)
|
||||
{
|
||||
- BlockDriverState *source = s->mirror_top_bs->backing->bs;
|
||||
+ BlockDriverState *source;
|
||||
MirrorOp *pseudo_op;
|
||||
int64_t offset;
|
||||
/* At least the first dirty chunk is mirrored in one iteration. */
|
||||
@@ -489,6 +489,10 @@ static void coroutine_fn GRAPH_RDLOCK mirror_iteration(MirrorBlockJob *s)
|
||||
bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
|
||||
int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
|
||||
|
||||
+ bdrv_graph_co_rdlock();
|
||||
+ source = s->mirror_top_bs->backing->bs;
|
||||
+ bdrv_graph_co_rdunlock();
|
||||
+
|
||||
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
|
||||
offset = bdrv_dirty_iter_next(s->dbi);
|
||||
if (offset < 0) {
|
||||
@@ -1066,9 +1070,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||
mirror_wait_for_free_in_flight_slot(s);
|
||||
continue;
|
||||
} else if (cnt != 0) {
|
||||
- bdrv_graph_co_rdlock();
|
||||
mirror_iteration(s);
|
||||
- bdrv_graph_co_rdunlock();
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/include/qemu/job.h b/include/qemu/job.h
|
||||
index 9ea98b5927..2b873f2576 100644
|
||||
--- a/include/qemu/job.h
|
||||
+++ b/include/qemu/job.h
|
||||
@@ -483,7 +483,7 @@ void job_enter(Job *job);
|
||||
*
|
||||
* Called with job_mutex *not* held.
|
||||
*/
|
||||
-void coroutine_fn job_pause_point(Job *job);
|
||||
+void coroutine_fn GRAPH_UNLOCKED job_pause_point(Job *job);
|
||||
|
||||
/**
|
||||
* @job: The job that calls the function.
|
||||
--
|
||||
2.39.3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,95 +0,0 @@
|
||||
From dc4dd11233522d8195782a2196aaae44bd924575 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 14 Mar 2024 17:58:24 +0100
|
||||
Subject: [PATCH 2/4] nbd/server: Fix race in draining the export
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 231: Fix deadlock and crash during storage migration
|
||||
RH-Jira: RHEL-28125
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [2/3] 036e1b171986099904dee468c59d77437e3d3d61 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
When draining an NBD export, nbd_drained_begin() first sets
|
||||
client->quiescing so that nbd_client_receive_next_request() won't start
|
||||
any new request coroutines. Then nbd_drained_poll() tries to makes sure
|
||||
that we wait for any existing request coroutines by checking that
|
||||
client->nb_requests has become 0.
|
||||
|
||||
However, there is a small window between creating a new request
|
||||
coroutine and increasing client->nb_requests. If a coroutine is in this
|
||||
state, it won't be waited for and drain returns too early.
|
||||
|
||||
In the context of switching to a different AioContext, this means that
|
||||
blk_aio_attached() will see client->recv_coroutine != NULL and fail its
|
||||
assertion.
|
||||
|
||||
Fix this by increasing client->nb_requests immediately when starting the
|
||||
coroutine. Doing this after the checks if we should create a new
|
||||
coroutine is okay because client->lock is held.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: fd6afc501a01 ("nbd/server: Use drained block ops to quiesce the server")
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240314165825.40261-2-kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 9c707525cbb1dd1e56876e45c70c0c08f2876d41)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
nbd/server.c | 15 +++++++--------
|
||||
1 file changed, 7 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 941832f178..c3484cc1eb 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -3007,8 +3007,8 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
|
||||
/* Owns a reference to the NBDClient passed as opaque. */
|
||||
static coroutine_fn void nbd_trip(void *opaque)
|
||||
{
|
||||
- NBDClient *client = opaque;
|
||||
- NBDRequestData *req = NULL;
|
||||
+ NBDRequestData *req = opaque;
|
||||
+ NBDClient *client = req->client;
|
||||
NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
@@ -3037,8 +3037,6 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
goto done;
|
||||
}
|
||||
|
||||
- req = nbd_request_get(client);
|
||||
-
|
||||
/*
|
||||
* nbd_co_receive_request() returns -EAGAIN when nbd_drained_begin() has
|
||||
* set client->quiescing but by the time we get back nbd_drained_end() may
|
||||
@@ -3112,9 +3110,7 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
}
|
||||
|
||||
done:
|
||||
- if (req) {
|
||||
- nbd_request_put(req);
|
||||
- }
|
||||
+ nbd_request_put(req);
|
||||
|
||||
qemu_mutex_unlock(&client->lock);
|
||||
|
||||
@@ -3143,10 +3139,13 @@ disconnect:
|
||||
*/
|
||||
static void nbd_client_receive_next_request(NBDClient *client)
|
||||
{
|
||||
+ NBDRequestData *req;
|
||||
+
|
||||
if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS &&
|
||||
!client->quiescing) {
|
||||
nbd_client_get(client);
|
||||
- client->recv_coroutine = qemu_coroutine_create(nbd_trip, client);
|
||||
+ req = nbd_request_get(client);
|
||||
+ client->recv_coroutine = qemu_coroutine_create(nbd_trip, req);
|
||||
aio_co_schedule(client->exp->common.ctx, client->recv_coroutine);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,53 +0,0 @@
|
||||
From cd7788a857a6099206c4063e3ef69cb9e4aebcbc Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 21 Dec 2023 14:24:50 -0500
|
||||
Subject: [PATCH 070/101] nbd/server: avoid per-NBDRequest nbd_client_get/put()
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [1/26] 5acb090ac4adf4260cd9e9c5605a27012b2a33aa (kmwolf/centos-qemu-kvm)
|
||||
|
||||
nbd_trip() processes a single NBD request from start to finish and holds
|
||||
an NBDClient reference throughout. NBDRequest does not outlive the scope
|
||||
of nbd_trip(). Therefore it is unnecessary to ref/unref NBDClient for
|
||||
each NBDRequest.
|
||||
|
||||
Removing these nbd_client_get()/nbd_client_put() calls will make
|
||||
thread-safety easier in the commits that follow.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Message-ID: <20231221192452.1785567-5-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
nbd/server.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 895cf0a752..0b09ccc8dc 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -1557,7 +1557,6 @@ static NBDRequestData *nbd_request_get(NBDClient *client)
|
||||
client->nb_requests++;
|
||||
|
||||
req = g_new0(NBDRequestData, 1);
|
||||
- nbd_client_get(client);
|
||||
req->client = client;
|
||||
return req;
|
||||
}
|
||||
@@ -1578,8 +1577,6 @@ static void nbd_request_put(NBDRequestData *req)
|
||||
}
|
||||
|
||||
nbd_client_receive_next_request(client);
|
||||
-
|
||||
- nbd_client_put(client);
|
||||
}
|
||||
|
||||
static void blk_aio_attached(AioContext *ctx, void *opaque)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,373 +0,0 @@
|
||||
From bb0a6afff7f23a3ddb460dc1b2e70c06565f8a3f Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 21 Dec 2023 14:24:52 -0500
|
||||
Subject: [PATCH 072/101] nbd/server: introduce NBDClient->lock to protect
|
||||
fields
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [3/26] 49b64adaaf8b1c30f339d1ecc8ea89fb9db63f1c (kmwolf/centos-qemu-kvm)
|
||||
|
||||
NBDClient has a number of fields that are accessed by both the export
|
||||
AioContext and the main loop thread. When the AioContext lock is removed
|
||||
these fields will need another form of protection.
|
||||
|
||||
Add NBDClient->lock and protect fields that are accessed by both
|
||||
threads. Also add assertions where possible and otherwise add doc
|
||||
comments stating assumptions about which thread and lock holding.
|
||||
|
||||
Note this patch moves the client->recv_coroutine assertion from
|
||||
nbd_co_receive_request() to nbd_trip() where client->lock is held.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231221192452.1785567-7-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
nbd/server.c | 144 +++++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 111 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index e91e2e0903..941832f178 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -125,23 +125,25 @@ struct NBDClient {
|
||||
int refcount; /* atomic */
|
||||
void (*close_fn)(NBDClient *client, bool negotiated);
|
||||
|
||||
+ QemuMutex lock;
|
||||
+
|
||||
NBDExport *exp;
|
||||
QCryptoTLSCreds *tlscreds;
|
||||
char *tlsauthz;
|
||||
QIOChannelSocket *sioc; /* The underlying data channel */
|
||||
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
||||
|
||||
- Coroutine *recv_coroutine;
|
||||
+ Coroutine *recv_coroutine; /* protected by lock */
|
||||
|
||||
CoMutex send_lock;
|
||||
Coroutine *send_coroutine;
|
||||
|
||||
- bool read_yielding;
|
||||
- bool quiescing;
|
||||
+ bool read_yielding; /* protected by lock */
|
||||
+ bool quiescing; /* protected by lock */
|
||||
|
||||
QTAILQ_ENTRY(NBDClient) next;
|
||||
- int nb_requests;
|
||||
- bool closing;
|
||||
+ int nb_requests; /* protected by lock */
|
||||
+ bool closing; /* protected by lock */
|
||||
|
||||
uint32_t check_align; /* If non-zero, check for aligned client requests */
|
||||
|
||||
@@ -1415,11 +1417,18 @@ nbd_read_eof(NBDClient *client, void *buffer, size_t size, Error **errp)
|
||||
|
||||
len = qio_channel_readv(client->ioc, &iov, 1, errp);
|
||||
if (len == QIO_CHANNEL_ERR_BLOCK) {
|
||||
- client->read_yielding = true;
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ client->read_yielding = true;
|
||||
+
|
||||
+ /* Prompt main loop thread to re-run nbd_drained_poll() */
|
||||
+ aio_wait_kick();
|
||||
+ }
|
||||
qio_channel_yield(client->ioc, G_IO_IN);
|
||||
- client->read_yielding = false;
|
||||
- if (client->quiescing) {
|
||||
- return -EAGAIN;
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ client->read_yielding = false;
|
||||
+ if (client->quiescing) {
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
}
|
||||
continue;
|
||||
} else if (len < 0) {
|
||||
@@ -1528,6 +1537,7 @@ void nbd_client_put(NBDClient *client)
|
||||
blk_exp_unref(&client->exp->common);
|
||||
}
|
||||
g_free(client->contexts.bitmaps);
|
||||
+ qemu_mutex_destroy(&client->lock);
|
||||
g_free(client);
|
||||
}
|
||||
}
|
||||
@@ -1561,11 +1571,13 @@ static void client_close(NBDClient *client, bool negotiated)
|
||||
{
|
||||
assert(qemu_in_main_thread());
|
||||
|
||||
- if (client->closing) {
|
||||
- return;
|
||||
- }
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ if (client->closing) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- client->closing = true;
|
||||
+ client->closing = true;
|
||||
+ }
|
||||
|
||||
/* Force requests to finish. They will drop their own references,
|
||||
* then we'll close the socket and free the NBDClient.
|
||||
@@ -1579,6 +1591,7 @@ static void client_close(NBDClient *client, bool negotiated)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Runs in export AioContext with client->lock held */
|
||||
static NBDRequestData *nbd_request_get(NBDClient *client)
|
||||
{
|
||||
NBDRequestData *req;
|
||||
@@ -1591,6 +1604,7 @@ static NBDRequestData *nbd_request_get(NBDClient *client)
|
||||
return req;
|
||||
}
|
||||
|
||||
+/* Runs in export AioContext with client->lock held */
|
||||
static void nbd_request_put(NBDRequestData *req)
|
||||
{
|
||||
NBDClient *client = req->client;
|
||||
@@ -1614,14 +1628,18 @@ static void blk_aio_attached(AioContext *ctx, void *opaque)
|
||||
NBDExport *exp = opaque;
|
||||
NBDClient *client;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
trace_nbd_blk_aio_attached(exp->name, ctx);
|
||||
|
||||
exp->common.ctx = ctx;
|
||||
|
||||
QTAILQ_FOREACH(client, &exp->clients, next) {
|
||||
- assert(client->nb_requests == 0);
|
||||
- assert(client->recv_coroutine == NULL);
|
||||
- assert(client->send_coroutine == NULL);
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ assert(client->nb_requests == 0);
|
||||
+ assert(client->recv_coroutine == NULL);
|
||||
+ assert(client->send_coroutine == NULL);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1629,6 +1647,8 @@ static void blk_aio_detach(void *opaque)
|
||||
{
|
||||
NBDExport *exp = opaque;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
trace_nbd_blk_aio_detach(exp->name, exp->common.ctx);
|
||||
|
||||
exp->common.ctx = NULL;
|
||||
@@ -1639,8 +1659,12 @@ static void nbd_drained_begin(void *opaque)
|
||||
NBDExport *exp = opaque;
|
||||
NBDClient *client;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
QTAILQ_FOREACH(client, &exp->clients, next) {
|
||||
- client->quiescing = true;
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ client->quiescing = true;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1649,28 +1673,48 @@ static void nbd_drained_end(void *opaque)
|
||||
NBDExport *exp = opaque;
|
||||
NBDClient *client;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
QTAILQ_FOREACH(client, &exp->clients, next) {
|
||||
- client->quiescing = false;
|
||||
- nbd_client_receive_next_request(client);
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ client->quiescing = false;
|
||||
+ nbd_client_receive_next_request(client);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
+/* Runs in export AioContext */
|
||||
+static void nbd_wake_read_bh(void *opaque)
|
||||
+{
|
||||
+ NBDClient *client = opaque;
|
||||
+ qio_channel_wake_read(client->ioc);
|
||||
+}
|
||||
+
|
||||
static bool nbd_drained_poll(void *opaque)
|
||||
{
|
||||
NBDExport *exp = opaque;
|
||||
NBDClient *client;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
QTAILQ_FOREACH(client, &exp->clients, next) {
|
||||
- if (client->nb_requests != 0) {
|
||||
- /*
|
||||
- * If there's a coroutine waiting for a request on nbd_read_eof()
|
||||
- * enter it here so we don't depend on the client to wake it up.
|
||||
- */
|
||||
- if (client->recv_coroutine != NULL && client->read_yielding) {
|
||||
- qio_channel_wake_read(client->ioc);
|
||||
- }
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ if (client->nb_requests != 0) {
|
||||
+ /*
|
||||
+ * If there's a coroutine waiting for a request on nbd_read_eof()
|
||||
+ * enter it here so we don't depend on the client to wake it up.
|
||||
+ *
|
||||
+ * Schedule a BH in the export AioContext to avoid missing the
|
||||
+ * wake up due to the race between qio_channel_wake_read() and
|
||||
+ * qio_channel_yield().
|
||||
+ */
|
||||
+ if (client->recv_coroutine != NULL && client->read_yielding) {
|
||||
+ aio_bh_schedule_oneshot(nbd_export_aio_context(client->exp),
|
||||
+ nbd_wake_read_bh, client);
|
||||
+ }
|
||||
|
||||
- return true;
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,6 +1725,8 @@ static void nbd_eject_notifier(Notifier *n, void *data)
|
||||
{
|
||||
NBDExport *exp = container_of(n, NBDExport, eject_notifier);
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
blk_exp_request_shutdown(&exp->common);
|
||||
}
|
||||
|
||||
@@ -2566,7 +2612,6 @@ static int coroutine_fn nbd_co_receive_request(NBDRequestData *req,
|
||||
int ret;
|
||||
|
||||
g_assert(qemu_in_coroutine());
|
||||
- assert(client->recv_coroutine == qemu_coroutine_self());
|
||||
ret = nbd_receive_request(client, request, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@@ -2975,6 +3020,9 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
*/
|
||||
|
||||
trace_nbd_trip();
|
||||
+
|
||||
+ qemu_mutex_lock(&client->lock);
|
||||
+
|
||||
if (client->closing) {
|
||||
goto done;
|
||||
}
|
||||
@@ -2990,7 +3038,21 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
}
|
||||
|
||||
req = nbd_request_get(client);
|
||||
- ret = nbd_co_receive_request(req, &request, &local_err);
|
||||
+
|
||||
+ /*
|
||||
+ * nbd_co_receive_request() returns -EAGAIN when nbd_drained_begin() has
|
||||
+ * set client->quiescing but by the time we get back nbd_drained_end() may
|
||||
+ * have already cleared client->quiescing. In that case we try again
|
||||
+ * because nothing else will spawn an nbd_trip() coroutine until we set
|
||||
+ * client->recv_coroutine = NULL further down.
|
||||
+ */
|
||||
+ do {
|
||||
+ assert(client->recv_coroutine == qemu_coroutine_self());
|
||||
+ qemu_mutex_unlock(&client->lock);
|
||||
+ ret = nbd_co_receive_request(req, &request, &local_err);
|
||||
+ qemu_mutex_lock(&client->lock);
|
||||
+ } while (ret == -EAGAIN && !client->quiescing);
|
||||
+
|
||||
client->recv_coroutine = NULL;
|
||||
|
||||
if (client->closing) {
|
||||
@@ -3002,15 +3064,16 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
}
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
- assert(client->quiescing);
|
||||
goto done;
|
||||
}
|
||||
|
||||
nbd_client_receive_next_request(client);
|
||||
+
|
||||
if (ret == -EIO) {
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
+ qemu_mutex_unlock(&client->lock);
|
||||
qio_channel_set_cork(client->ioc, true);
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -3030,6 +3093,10 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
g_free(request.contexts->bitmaps);
|
||||
g_free(request.contexts);
|
||||
}
|
||||
+
|
||||
+ qio_channel_set_cork(client->ioc, false);
|
||||
+ qemu_mutex_lock(&client->lock);
|
||||
+
|
||||
if (ret < 0) {
|
||||
error_prepend(&local_err, "Failed to send reply: ");
|
||||
goto disconnect;
|
||||
@@ -3044,11 +3111,13 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
- qio_channel_set_cork(client->ioc, false);
|
||||
done:
|
||||
if (req) {
|
||||
nbd_request_put(req);
|
||||
}
|
||||
+
|
||||
+ qemu_mutex_unlock(&client->lock);
|
||||
+
|
||||
if (!nbd_client_put_nonzero(client)) {
|
||||
aio_co_reschedule_self(qemu_get_aio_context());
|
||||
nbd_client_put(client);
|
||||
@@ -3059,13 +3128,19 @@ disconnect:
|
||||
if (local_err) {
|
||||
error_reportf_err(local_err, "Disconnect client, due to: ");
|
||||
}
|
||||
+
|
||||
nbd_request_put(req);
|
||||
+ qemu_mutex_unlock(&client->lock);
|
||||
|
||||
aio_co_reschedule_self(qemu_get_aio_context());
|
||||
client_close(client, true);
|
||||
nbd_client_put(client);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Runs in export AioContext and main loop thread. Caller must hold
|
||||
+ * client->lock.
|
||||
+ */
|
||||
static void nbd_client_receive_next_request(NBDClient *client)
|
||||
{
|
||||
if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS &&
|
||||
@@ -3091,7 +3166,9 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
||||
return;
|
||||
}
|
||||
|
||||
- nbd_client_receive_next_request(client);
|
||||
+ WITH_QEMU_LOCK_GUARD(&client->lock) {
|
||||
+ nbd_client_receive_next_request(client);
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3108,6 +3185,7 @@ void nbd_client_new(QIOChannelSocket *sioc,
|
||||
Coroutine *co;
|
||||
|
||||
client = g_new0(NBDClient, 1);
|
||||
+ qemu_mutex_init(&client->lock);
|
||||
client->refcount = 1;
|
||||
client->tlscreds = tlscreds;
|
||||
if (tlscreds) {
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,176 +0,0 @@
|
||||
From 8b60d72532b6511b41d82d591fb4f509314ef15f Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Thu, 21 Dec 2023 14:24:51 -0500
|
||||
Subject: [PATCH 071/101] nbd/server: only traverse NBDExport->clients from
|
||||
main loop thread
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [2/26] e7794a3a5c363c7508ee505c4ba03d9ef8862ca9 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The NBD clients list is currently accessed from both the export
|
||||
AioContext and the main loop thread. When the AioContext lock is removed
|
||||
there will be nothing protecting the clients list.
|
||||
|
||||
Adding a lock around the clients list is tricky because NBDClient
|
||||
structs are refcounted and may be freed from the export AioContext or
|
||||
the main loop thread. nbd_export_request_shutdown() -> client_close() ->
|
||||
nbd_client_put() is also tricky because the list lock would be held
|
||||
while indirectly dropping references to NDBClients.
|
||||
|
||||
A simpler approach is to only allow nbd_client_put() and client_close()
|
||||
calls from the main loop thread. Then the NBD clients list is only
|
||||
accessed from the main loop thread and no fancy locking is needed.
|
||||
|
||||
nbd_trip() just needs to reschedule itself in the main loop AioContext
|
||||
before calling nbd_client_put() and client_close(). This costs more CPU
|
||||
cycles per NBD request so add nbd_client_put_nonzero() to optimize the
|
||||
common case where more references to NBDClient remain.
|
||||
|
||||
Note that nbd_client_get() can still be called from either thread, so
|
||||
make NBDClient->refcount atomic.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231221192452.1785567-6-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
nbd/server.c | 61 +++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 51 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 0b09ccc8dc..e91e2e0903 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -122,7 +122,7 @@ struct NBDMetaContexts {
|
||||
};
|
||||
|
||||
struct NBDClient {
|
||||
- int refcount;
|
||||
+ int refcount; /* atomic */
|
||||
void (*close_fn)(NBDClient *client, bool negotiated);
|
||||
|
||||
NBDExport *exp;
|
||||
@@ -1501,14 +1501,17 @@ static int coroutine_fn nbd_receive_request(NBDClient *client, NBDRequest *reque
|
||||
|
||||
#define MAX_NBD_REQUESTS 16
|
||||
|
||||
+/* Runs in export AioContext and main loop thread */
|
||||
void nbd_client_get(NBDClient *client)
|
||||
{
|
||||
- client->refcount++;
|
||||
+ qatomic_inc(&client->refcount);
|
||||
}
|
||||
|
||||
void nbd_client_put(NBDClient *client)
|
||||
{
|
||||
- if (--client->refcount == 0) {
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
+ if (qatomic_fetch_dec(&client->refcount) == 1) {
|
||||
/* The last reference should be dropped by client->close,
|
||||
* which is called by client_close.
|
||||
*/
|
||||
@@ -1529,8 +1532,35 @@ void nbd_client_put(NBDClient *client)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Tries to release the reference to @client, but only if other references
|
||||
+ * remain. This is an optimization for the common case where we want to avoid
|
||||
+ * the expense of scheduling nbd_client_put() in the main loop thread.
|
||||
+ *
|
||||
+ * Returns true upon success or false if the reference was not released because
|
||||
+ * it is the last reference.
|
||||
+ */
|
||||
+static bool nbd_client_put_nonzero(NBDClient *client)
|
||||
+{
|
||||
+ int old = qatomic_read(&client->refcount);
|
||||
+ int expected;
|
||||
+
|
||||
+ do {
|
||||
+ if (old == 1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ expected = old;
|
||||
+ old = qatomic_cmpxchg(&client->refcount, expected, expected - 1);
|
||||
+ } while (old != expected);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void client_close(NBDClient *client, bool negotiated)
|
||||
{
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
if (client->closing) {
|
||||
return;
|
||||
}
|
||||
@@ -2933,15 +2963,20 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
|
||||
static coroutine_fn void nbd_trip(void *opaque)
|
||||
{
|
||||
NBDClient *client = opaque;
|
||||
- NBDRequestData *req;
|
||||
+ NBDRequestData *req = NULL;
|
||||
NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
+ /*
|
||||
+ * Note that nbd_client_put() and client_close() must be called from the
|
||||
+ * main loop thread. Use aio_co_reschedule_self() to switch AioContext
|
||||
+ * before calling these functions.
|
||||
+ */
|
||||
+
|
||||
trace_nbd_trip();
|
||||
if (client->closing) {
|
||||
- nbd_client_put(client);
|
||||
- return;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
if (client->quiescing) {
|
||||
@@ -2949,10 +2984,9 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
* We're switching between AIO contexts. Don't attempt to receive a new
|
||||
* request and kick the main context which may be waiting for us.
|
||||
*/
|
||||
- nbd_client_put(client);
|
||||
client->recv_coroutine = NULL;
|
||||
aio_wait_kick();
|
||||
- return;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
req = nbd_request_get(client);
|
||||
@@ -3012,8 +3046,13 @@ static coroutine_fn void nbd_trip(void *opaque)
|
||||
|
||||
qio_channel_set_cork(client->ioc, false);
|
||||
done:
|
||||
- nbd_request_put(req);
|
||||
- nbd_client_put(client);
|
||||
+ if (req) {
|
||||
+ nbd_request_put(req);
|
||||
+ }
|
||||
+ if (!nbd_client_put_nonzero(client)) {
|
||||
+ aio_co_reschedule_self(qemu_get_aio_context());
|
||||
+ nbd_client_put(client);
|
||||
+ }
|
||||
return;
|
||||
|
||||
disconnect:
|
||||
@@ -3021,6 +3060,8 @@ disconnect:
|
||||
error_reportf_err(local_err, "Disconnect client, due to: ");
|
||||
}
|
||||
nbd_request_put(req);
|
||||
+
|
||||
+ aio_co_reschedule_self(qemu_get_aio_context());
|
||||
client_close(client, true);
|
||||
nbd_client_put(client);
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,115 +0,0 @@
|
||||
From 9ca64f73238d9f1b9f13d8e941ba42771a992afb Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Fri, 29 Dec 2023 14:06:05 +0100
|
||||
Subject: [PATCH 20/20] pc/q35: set SMBIOS entry point type to 'auto' by
|
||||
default
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [18/18] c7fc6ac7350bca3ff99e58620710a86218385781
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
Use smbios-entry-point-type='auto' for newer machine types as a workaround
|
||||
for Windows not detecting SMBIOS tables. Which makes QEMU pick SMBIOS tables
|
||||
based on configuration (with 2.x preferred and fallback to 3.x if the former
|
||||
isn't compatible with configuration)
|
||||
|
||||
Default compat setting of smbios-entry-point-type after series
|
||||
for pc/q35 machines:
|
||||
* 9.0-newer: 'auto'
|
||||
* 8.1-8.2: '64'
|
||||
* 8.0-older: '32'
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2008
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
|
||||
Conflicts: hw/i386/pc_piix.c hw/i386/pc_q35.c
|
||||
due to RHEL machine types
|
||||
|
||||
REHL only parts:
|
||||
Fix RHEL 'pc' machine types at SMBIOS 2.X
|
||||
for the latest RHEL 'q35' machine type use version autoselect
|
||||
which propagates to RHEL 9.4 q35 macine type while RHEL 9.2 q35 and older
|
||||
are kept at SMBIOS_ENTRY_POINT_TYPE_32 (see: pc_q35_machine_rhel920_options)
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/pc.c | 2 +-
|
||||
hw/i386/pc_piix.c | 7 +++++++
|
||||
hw/i386/pc_q35.c | 5 +++++
|
||||
3 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index ae6777fc1a..d6f267b220 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -2004,7 +2004,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->nvdimm_supported = true;
|
||||
mc->smp_props.dies_supported = true;
|
||||
mc->default_ram_id = "pc.ram";
|
||||
- pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO;
|
||||
|
||||
object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
|
||||
pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g,
|
||||
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
|
||||
index 7344b35cf1..54d1c58bce 100644
|
||||
--- a/hw/i386/pc_piix.c
|
||||
+++ b/hw/i386/pc_piix.c
|
||||
@@ -539,9 +539,14 @@ static void pc_i440fx_machine_options(MachineClass *m)
|
||||
|
||||
static void pc_i440fx_8_2_machine_options(MachineClass *m)
|
||||
{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
+
|
||||
pc_i440fx_machine_options(m);
|
||||
m->alias = "pc";
|
||||
m->is_default = true;
|
||||
+
|
||||
+ /* For pc-i44fx-8.2 and 8.1, use SMBIOS 3.X by default */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v8_2, "pc-i440fx-8.2", NULL,
|
||||
@@ -982,6 +987,8 @@ static void pc_machine_rhel7_options(MachineClass *m)
|
||||
m->alias = "pc";
|
||||
m->is_default = 1;
|
||||
m->smp_props.prefer_sockets = true;
|
||||
+ /* there aren't ne PC macine types in RHEL9, keep it at SMBIOS 2.X */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||
}
|
||||
|
||||
static void pc_init_rhel760(MachineState *machine)
|
||||
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
|
||||
index 9a22ff5dd6..cd5fb7380e 100644
|
||||
--- a/hw/i386/pc_q35.c
|
||||
+++ b/hw/i386/pc_q35.c
|
||||
@@ -377,8 +377,11 @@ static void pc_q35_machine_options(MachineClass *m)
|
||||
|
||||
static void pc_q35_8_2_machine_options(MachineClass *m)
|
||||
{
|
||||
+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_machine_options(m);
|
||||
m->alias = "q35";
|
||||
+ /* For pc-q35-8.2 and 8.1, use SMBIOS 3.X by default */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64;
|
||||
}
|
||||
|
||||
DEFINE_Q35_MACHINE(v8_2, "pc-q35-8.2", NULL,
|
||||
@@ -712,6 +715,8 @@ static void pc_q35_machine_rhel_options(MachineClass *m)
|
||||
m->alias = "q35";
|
||||
m->max_cpus = 710;
|
||||
compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len);
|
||||
+ /* use SMBIOS version autoselect by default for the latest RHEL machine */
|
||||
+ pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO;
|
||||
}
|
||||
|
||||
static void pc_q35_init_rhel940(MachineState *machine)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 03cad16743d9a4d377af66611d030eca9eda326d Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 19 Mar 2024 11:42:04 +0100
|
||||
Subject: [PATCH 4/4] pc: smbios: fixup manufacturer/product/version to match
|
||||
downstream
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 232: pc: smbios: fixup manufacturer/product/version to match downstream
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
|
||||
RH-Commit: [1/1] 9235f64acb5ff46360282e889d0aedcb13374ac1
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
commit [1] discarded RHEL only change that customizes
|
||||
SMBIOS values for manufacturer/product/version for pc/q35
|
||||
machine types.
|
||||
Fix it up by reverting back to ("Red Hat", "KVM", mc->desc)
|
||||
tuple.
|
||||
|
||||
1)
|
||||
Fixes: 208239eb2 (hw/i386/pc: Defer smbios_set_defaults() to machine_done)
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 58429bb78d..d6a24177e2 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
|
||||
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_uuid_encoded,
|
||||
pcmc->smbios_stream_product,
|
||||
pcmc->smbios_stream_version);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,167 +0,0 @@
|
||||
From f1e82fe5076b4030d385dfa49b8284899386114d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Wed, 20 Dec 2023 08:47:54 -0500
|
||||
Subject: [PATCH 08/22] qdev: add IOThreadVirtQueueMappingList property type
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [4/17] 817aa1339da8ed3814730473342ba045e66d5b51 (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
virtio-blk and virtio-scsi devices will need a way to specify the
|
||||
mapping between IOThreads and virtqueues. At the moment all virtqueues
|
||||
are assigned to a single IOThread or the main loop. This single thread
|
||||
can be a CPU bottleneck, so it is necessary to allow finer-grained
|
||||
assignment to spread the load.
|
||||
|
||||
Introduce DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST() so devices can take a
|
||||
parameter that maps virtqueues to IOThreads. The command-line syntax for
|
||||
this new property is as follows:
|
||||
|
||||
--device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0","vqs":[0,1,2]},...]}'
|
||||
|
||||
IOThreads are specified by name and virtqueues are specified by 0-based
|
||||
index.
|
||||
|
||||
It will be common to simply assign virtqueues round-robin across a set
|
||||
of IOThreads. A convenient syntax that does not require specifying
|
||||
individual virtqueue indices is available:
|
||||
|
||||
--device '{"driver":"foo","iothread-vq-mapping":[{"iothread":"iothread0"},{"iothread":"iothread1"},...]}'
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231220134755.814917-4-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit cf03a152c5d749fd0083bfe540df9524f1d2ff1d)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
hw/core/qdev-properties-system.c | 46 +++++++++++++++++++++++++++++
|
||||
include/hw/qdev-properties-system.h | 5 ++++
|
||||
qapi/virtio.json | 29 ++++++++++++++++++
|
||||
3 files changed, 80 insertions(+)
|
||||
|
||||
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
|
||||
index 73cced4626..1a396521d5 100644
|
||||
--- a/hw/core/qdev-properties-system.c
|
||||
+++ b/hw/core/qdev-properties-system.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "qapi/qapi-types-block.h"
|
||||
#include "qapi/qapi-types-machine.h"
|
||||
#include "qapi/qapi-types-migration.h"
|
||||
+#include "qapi/qapi-visit-virtio.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qemu/ctype.h"
|
||||
#include "qemu/cutils.h"
|
||||
@@ -1160,3 +1161,48 @@ const PropertyInfo qdev_prop_cpus390entitlement = {
|
||||
.set = qdev_propinfo_set_enum,
|
||||
.set_default_value = qdev_propinfo_set_default_value_enum,
|
||||
};
|
||||
+
|
||||
+/* --- IOThreadVirtQueueMappingList --- */
|
||||
+
|
||||
+static void get_iothread_vq_mapping_list(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque, Error **errp)
|
||||
+{
|
||||
+ IOThreadVirtQueueMappingList **prop_ptr =
|
||||
+ object_field_prop_ptr(obj, opaque);
|
||||
+
|
||||
+ visit_type_IOThreadVirtQueueMappingList(v, name, prop_ptr, errp);
|
||||
+}
|
||||
+
|
||||
+static void set_iothread_vq_mapping_list(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque, Error **errp)
|
||||
+{
|
||||
+ IOThreadVirtQueueMappingList **prop_ptr =
|
||||
+ object_field_prop_ptr(obj, opaque);
|
||||
+ IOThreadVirtQueueMappingList *list;
|
||||
+
|
||||
+ if (!visit_type_IOThreadVirtQueueMappingList(v, name, &list, errp)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
|
||||
+ *prop_ptr = list;
|
||||
+}
|
||||
+
|
||||
+static void release_iothread_vq_mapping_list(Object *obj,
|
||||
+ const char *name, void *opaque)
|
||||
+{
|
||||
+ IOThreadVirtQueueMappingList **prop_ptr =
|
||||
+ object_field_prop_ptr(obj, opaque);
|
||||
+
|
||||
+ qapi_free_IOThreadVirtQueueMappingList(*prop_ptr);
|
||||
+ *prop_ptr = NULL;
|
||||
+}
|
||||
+
|
||||
+const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
|
||||
+ .name = "IOThreadVirtQueueMappingList",
|
||||
+ .description = "IOThread virtqueue mapping list [{\"iothread\":\"<id>\", "
|
||||
+ "\"vqs\":[1,2,3,...]},...]",
|
||||
+ .get = get_iothread_vq_mapping_list,
|
||||
+ .set = set_iothread_vq_mapping_list,
|
||||
+ .release = release_iothread_vq_mapping_list,
|
||||
+};
|
||||
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
|
||||
index 91f7a2452d..06c359c190 100644
|
||||
--- a/include/hw/qdev-properties-system.h
|
||||
+++ b/include/hw/qdev-properties-system.h
|
||||
@@ -24,6 +24,7 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar;
|
||||
extern const PropertyInfo qdev_prop_pcie_link_speed;
|
||||
extern const PropertyInfo qdev_prop_pcie_link_width;
|
||||
extern const PropertyInfo qdev_prop_cpus390entitlement;
|
||||
+extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
|
||||
|
||||
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
|
||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
|
||||
@@ -82,4 +83,8 @@ extern const PropertyInfo qdev_prop_cpus390entitlement;
|
||||
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \
|
||||
CpuS390Entitlement)
|
||||
|
||||
+#define DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST(_name, _state, _field) \
|
||||
+ DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \
|
||||
+ IOThreadVirtQueueMappingList *)
|
||||
+
|
||||
#endif
|
||||
diff --git a/qapi/virtio.json b/qapi/virtio.json
|
||||
index e6dcee7b83..19c7c36e36 100644
|
||||
--- a/qapi/virtio.json
|
||||
+++ b/qapi/virtio.json
|
||||
@@ -928,3 +928,32 @@
|
||||
'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
|
||||
'returns': 'VirtioQueueElement',
|
||||
'features': [ 'unstable' ] }
|
||||
+
|
||||
+##
|
||||
+# @IOThreadVirtQueueMapping:
|
||||
+#
|
||||
+# Describes the subset of virtqueues assigned to an IOThread.
|
||||
+#
|
||||
+# @iothread: the id of IOThread object
|
||||
+#
|
||||
+# @vqs: an optional array of virtqueue indices that will be handled by this
|
||||
+# IOThread. When absent, virtqueues are assigned round-robin across all
|
||||
+# IOThreadVirtQueueMappings provided. Either all IOThreadVirtQueueMappings
|
||||
+# must have @vqs or none of them must have it.
|
||||
+#
|
||||
+# Since: 9.0
|
||||
+##
|
||||
+
|
||||
+{ 'struct': 'IOThreadVirtQueueMapping',
|
||||
+ 'data': { 'iothread': 'str', '*vqs': ['uint16'] } }
|
||||
+
|
||||
+##
|
||||
+# @DummyVirtioForceArrays:
|
||||
+#
|
||||
+# Not used by QMP; hack to let us use IOThreadVirtQueueMappingList internally
|
||||
+#
|
||||
+# Since: 9.0
|
||||
+##
|
||||
+
|
||||
+{ 'struct': 'DummyVirtioForceArrays',
|
||||
+ 'data': { 'unused-iothread-vq-mapping': ['IOThreadVirtQueueMapping'] } }
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,85 +0,0 @@
|
||||
From 4251aab5b2beb68d1800cd4a329361ff6f57c430 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Wed, 20 Dec 2023 08:47:52 -0500
|
||||
Subject: [PATCH 07/22] qdev-properties: alias all object class properties
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [3/17] bc5d0aafe4645dacf9277904a2b20760d6e676e1 (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
qdev_alias_all_properties() aliases a DeviceState's qdev properties onto
|
||||
an Object. This is used for VirtioPCIProxy types so that --device
|
||||
virtio-blk-pci has properties of its embedded --device virtio-blk-device
|
||||
object.
|
||||
|
||||
Currently this function is implemented using qdev properties. Change the
|
||||
function to use QOM object class properties instead. This works because
|
||||
qdev properties create QOM object class properties, but it also catches
|
||||
any QOM object class-only properties that have no qdev properties.
|
||||
|
||||
This change ensures that properties of devices are shown with --device
|
||||
foo,\? even if they are QOM object class properties.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231220134755.814917-2-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 350147a871a545ab56b4a1062c8485635d9ffc24)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
hw/core/qdev-properties.c | 18 ++++++++++--------
|
||||
include/hw/qdev-properties.h | 4 ++--
|
||||
2 files changed, 12 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
|
||||
index 840006e953..7d6fa726fd 100644
|
||||
--- a/hw/core/qdev-properties.c
|
||||
+++ b/hw/core/qdev-properties.c
|
||||
@@ -1076,16 +1076,18 @@ void device_class_set_props(DeviceClass *dc, Property *props)
|
||||
void qdev_alias_all_properties(DeviceState *target, Object *source)
|
||||
{
|
||||
ObjectClass *class;
|
||||
- Property *prop;
|
||||
+ ObjectPropertyIterator iter;
|
||||
+ ObjectProperty *prop;
|
||||
|
||||
class = object_get_class(OBJECT(target));
|
||||
- do {
|
||||
- DeviceClass *dc = DEVICE_CLASS(class);
|
||||
|
||||
- for (prop = dc->props_; prop && prop->name; prop++) {
|
||||
- object_property_add_alias(source, prop->name,
|
||||
- OBJECT(target), prop->name);
|
||||
+ object_class_property_iter_init(&iter, class);
|
||||
+ while ((prop = object_property_iter_next(&iter))) {
|
||||
+ if (object_property_find(source, prop->name)) {
|
||||
+ continue; /* skip duplicate properties */
|
||||
}
|
||||
- class = object_class_get_parent(class);
|
||||
- } while (class != object_class_by_name(TYPE_DEVICE));
|
||||
+
|
||||
+ object_property_add_alias(source, prop->name,
|
||||
+ OBJECT(target), prop->name);
|
||||
+ }
|
||||
}
|
||||
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
|
||||
index 25743a29a0..09aa04ca1e 100644
|
||||
--- a/include/hw/qdev-properties.h
|
||||
+++ b/include/hw/qdev-properties.h
|
||||
@@ -230,8 +230,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop);
|
||||
* @target: Device which has properties to be aliased
|
||||
* @source: Object to add alias properties to
|
||||
*
|
||||
- * Add alias properties to the @source object for all qdev properties on
|
||||
- * the @target DeviceState.
|
||||
+ * Add alias properties to the @source object for all properties on the @target
|
||||
+ * DeviceState.
|
||||
*
|
||||
* This is useful when @target is an internal implementation object
|
||||
* owned by @source, and you want to expose all the properties of that
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,135 +0,0 @@
|
||||
From f2fe6c7a2def488633cbb67e28ac00279d6e8de4 Mon Sep 17 00:00:00 2001
|
||||
From: Cornelia Huck <cohuck@redhat.com>
|
||||
Date: Tue, 27 Feb 2024 11:17:39 +0100
|
||||
Subject: [PATCH 1/2] qemu_init: increase NOFILE soft limit on POSIX
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-MergeRequest: 226: qemu_init: increase NOFILE soft limit on POSIX
|
||||
RH-Jira: RHEL-26049
|
||||
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Acked-by: Shaoqin Huang <None>
|
||||
RH-Commit: [1/1] cee5404aef3f6437d45a1c43bdee73a57a528bee (cohuck/qemu-kvm-c9s)
|
||||
|
||||
Jira: https://issues.redhat.com/browse/RHEL-26049
|
||||
|
||||
In many configurations, e.g. multiple vNICs with multiple queues or
|
||||
with many Ceph OSDs, the default soft limit of 1024 is not enough.
|
||||
QEMU is supposed to work fine with file descriptors >= 1024 and does
|
||||
not use select() on POSIX. Bump the soft limit to the allowed hard
|
||||
limit to avoid issues with the aforementioned configurations.
|
||||
|
||||
Of course the limit could be raised from the outside, but the man page
|
||||
of systemd.exec states about 'LimitNOFILE=':
|
||||
|
||||
> Don't use.
|
||||
> [...]
|
||||
> Typically applications should increase their soft limit to the hard
|
||||
> limit on their own, if they are OK with working with file
|
||||
> descriptors above 1023,
|
||||
|
||||
If the soft limit is already the same as the hard limit, avoid the
|
||||
superfluous setrlimit call. This can avoid a warning with a strict
|
||||
seccomp filter blocking setrlimit if NOFILE was already raised before
|
||||
executing QEMU.
|
||||
|
||||
Buglink: https://bugzilla.proxmox.com/show_bug.cgi?id=4507
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 03e471c41d8b1b6eb16c9714f387449f52fe5c1d)
|
||||
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
|
||||
---
|
||||
include/sysemu/os-posix.h | 1 +
|
||||
include/sysemu/os-win32.h | 5 +++++
|
||||
os-posix.c | 22 ++++++++++++++++++++++
|
||||
system/vl.c | 2 ++
|
||||
4 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
|
||||
index dff32ae185..b881ac6c6f 100644
|
||||
--- a/include/sysemu/os-posix.h
|
||||
+++ b/include/sysemu/os-posix.h
|
||||
@@ -51,6 +51,7 @@ bool is_daemonized(void);
|
||||
void os_daemonize(void);
|
||||
bool os_set_runas(const char *user_id);
|
||||
void os_set_chroot(const char *path);
|
||||
+void os_setup_limits(void);
|
||||
void os_setup_post(void);
|
||||
int os_mlock(void);
|
||||
|
||||
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
|
||||
index 1047d260cb..b82a5d3ad9 100644
|
||||
--- a/include/sysemu/os-win32.h
|
||||
+++ b/include/sysemu/os-win32.h
|
||||
@@ -128,6 +128,11 @@ static inline int os_mlock(void)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
+static inline void os_setup_limits(void)
|
||||
+{
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
#define fsync _commit
|
||||
|
||||
#if !defined(lseek)
|
||||
diff --git a/os-posix.c b/os-posix.c
|
||||
index 52ef6990ff..a4284e2c07 100644
|
||||
--- a/os-posix.c
|
||||
+++ b/os-posix.c
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
+#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
@@ -256,6 +257,27 @@ void os_daemonize(void)
|
||||
}
|
||||
}
|
||||
|
||||
+void os_setup_limits(void)
|
||||
+{
|
||||
+ struct rlimit nofile;
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_NOFILE, &nofile) < 0) {
|
||||
+ warn_report("unable to query NOFILE limit: %s", strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (nofile.rlim_cur == nofile.rlim_max) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ nofile.rlim_cur = nofile.rlim_max;
|
||||
+
|
||||
+ if (setrlimit(RLIMIT_NOFILE, &nofile) < 0) {
|
||||
+ warn_report("unable to set NOFILE limit: %s", strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void os_setup_post(void)
|
||||
{
|
||||
int fd = 0;
|
||||
diff --git a/system/vl.c b/system/vl.c
|
||||
index 93635ffc5b..6443b6e469 100644
|
||||
--- a/system/vl.c
|
||||
+++ b/system/vl.c
|
||||
@@ -2783,6 +2783,8 @@ void qemu_init(int argc, char **argv)
|
||||
error_init(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
+ os_setup_limits();
|
||||
+
|
||||
qemu_init_arch_modules();
|
||||
|
||||
qemu_init_subsystems();
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,106 +0,0 @@
|
||||
From 64b0180f5a52668f8ac4c444ba369231dbc4d5b9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Mon, 22 Jan 2024 09:25:53 +0100
|
||||
Subject: [PATCH 096/101] s390x/pci: avoid double enable/disable of aif
|
||||
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: 215: s390x: Fix reset ordering of passthrough ISM devices
|
||||
RH-Jira: RHEL-21169
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [1/3] ebdf8a474ea21486f5ec051683f17bae6d20f675 (clegoate/qemu-kvm-c9s)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21169
|
||||
|
||||
commit 07b2c8e034d80ff92e202405c494d2ff80fcf848
|
||||
Author: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Date: Thu Jan 18 13:51:49 2024 -0500
|
||||
|
||||
s390x/pci: avoid double enable/disable of aif
|
||||
|
||||
Use a flag to keep track of whether AIF is currently enabled. This can be
|
||||
used to avoid enabling/disabling AIF multiple times as well as to determine
|
||||
whether or not it should be disabled during reset processing.
|
||||
|
||||
Fixes: d0bc7091c2 ("s390x/pci: enable adapter event notification for interpreted devices")
|
||||
Reported-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Message-ID: <20240118185151.265329-2-mjrosato@linux.ibm.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-pci-kvm.c | 25 +++++++++++++++++++++++--
|
||||
include/hw/s390x/s390-pci-bus.h | 1 +
|
||||
2 files changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c
|
||||
index ff41e4106d..1ee510436c 100644
|
||||
--- a/hw/s390x/s390-pci-kvm.c
|
||||
+++ b/hw/s390x/s390-pci-kvm.c
|
||||
@@ -27,6 +27,7 @@ bool s390_pci_kvm_interp_allowed(void)
|
||||
|
||||
int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist)
|
||||
{
|
||||
+ int rc;
|
||||
struct kvm_s390_zpci_op args = {
|
||||
.fh = pbdev->fh,
|
||||
.op = KVM_S390_ZPCIOP_REG_AEN,
|
||||
@@ -38,15 +39,35 @@ int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist)
|
||||
.u.reg_aen.flags = (assist) ? 0 : KVM_S390_ZPCIOP_REGAEN_HOST
|
||||
};
|
||||
|
||||
- return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
|
||||
+ if (pbdev->aif) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
|
||||
+ if (rc == 0) {
|
||||
+ pbdev->aif = true;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev)
|
||||
{
|
||||
+ int rc;
|
||||
+
|
||||
struct kvm_s390_zpci_op args = {
|
||||
.fh = pbdev->fh,
|
||||
.op = KVM_S390_ZPCIOP_DEREG_AEN
|
||||
};
|
||||
|
||||
- return kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
|
||||
+ if (!pbdev->aif) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
|
||||
+ if (rc == 0) {
|
||||
+ pbdev->aif = false;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
|
||||
index b1bdbeaeb5..435e788867 100644
|
||||
--- a/include/hw/s390x/s390-pci-bus.h
|
||||
+++ b/include/hw/s390x/s390-pci-bus.h
|
||||
@@ -361,6 +361,7 @@ struct S390PCIBusDevice {
|
||||
bool unplug_requested;
|
||||
bool interp;
|
||||
bool forwarding_assist;
|
||||
+ bool aif;
|
||||
QTAILQ_ENTRY(S390PCIBusDevice) link;
|
||||
};
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,137 +0,0 @@
|
||||
From c885b17e09ab19a3e8d3b2e1765963811af6f764 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Mon, 22 Jan 2024 09:25:53 +0100
|
||||
Subject: [PATCH 098/101] s390x/pci: drive ISM reset from subsystem reset
|
||||
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: 215: s390x: Fix reset ordering of passthrough ISM devices
|
||||
RH-Jira: RHEL-21169
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [3/3] 426cf156a2c67e6dcd7483a769fa3741e2700504 (clegoate/qemu-kvm-c9s)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21169
|
||||
|
||||
commit 68c691ca99a2538d6a53a70ce8a9ce06ee307ff1
|
||||
Author: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Date: Thu Jan 18 13:51:51 2024 -0500
|
||||
|
||||
s390x/pci: drive ISM reset from subsystem reset
|
||||
|
||||
ISM devices are sensitive to manipulation of the IOMMU, so the ISM device
|
||||
needs to be reset before the vfio-pci device is reset (triggering a full
|
||||
UNMAP). In order to ensure this occurs, trigger ISM device resets from
|
||||
subsystem_reset before triggering the PCI bus reset (which will also
|
||||
trigger vfio-pci reset). This only needs to be done for ISM devices
|
||||
which were enabled for use by the guest.
|
||||
Further, ensure that AIF is disabled as part of the reset event.
|
||||
|
||||
Fixes: ef1535901a ("s390x: do a subsystem reset before the unprotect on reboot")
|
||||
Fixes: 03451953c7 ("s390x/pci: reset ISM passthrough devices on shutdown and system reset")
|
||||
Reported-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Message-ID: <20240118185151.265329-4-mjrosato@linux.ibm.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-pci-bus.c | 26 +++++++++++++++++---------
|
||||
hw/s390x/s390-virtio-ccw.c | 8 ++++++++
|
||||
include/hw/s390x/s390-pci-bus.h | 1 +
|
||||
3 files changed, 26 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
|
||||
index 347580ebac..3e57d5faca 100644
|
||||
--- a/hw/s390x/s390-pci-bus.c
|
||||
+++ b/hw/s390x/s390-pci-bus.c
|
||||
@@ -151,20 +151,12 @@ static void s390_pci_shutdown_notifier(Notifier *n, void *opaque)
|
||||
pci_device_reset(pbdev->pdev);
|
||||
}
|
||||
|
||||
-static void s390_pci_reset_cb(void *opaque)
|
||||
-{
|
||||
- S390PCIBusDevice *pbdev = opaque;
|
||||
-
|
||||
- pci_device_reset(pbdev->pdev);
|
||||
-}
|
||||
-
|
||||
static void s390_pci_perform_unplug(S390PCIBusDevice *pbdev)
|
||||
{
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
|
||||
if (pbdev->pft == ZPCI_PFT_ISM) {
|
||||
notifier_remove(&pbdev->shutdown_notifier);
|
||||
- qemu_unregister_reset(s390_pci_reset_cb, pbdev);
|
||||
}
|
||||
|
||||
/* Unplug the PCI device */
|
||||
@@ -1132,7 +1124,6 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
if (pbdev->pft == ZPCI_PFT_ISM) {
|
||||
pbdev->shutdown_notifier.notify = s390_pci_shutdown_notifier;
|
||||
qemu_register_shutdown_notifier(&pbdev->shutdown_notifier);
|
||||
- qemu_register_reset(s390_pci_reset_cb, pbdev);
|
||||
}
|
||||
} else {
|
||||
pbdev->fh |= FH_SHM_EMUL;
|
||||
@@ -1279,6 +1270,23 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1);
|
||||
}
|
||||
|
||||
+void s390_pci_ism_reset(void)
|
||||
+{
|
||||
+ S390pciState *s = s390_get_phb();
|
||||
+
|
||||
+ S390PCIBusDevice *pbdev, *next;
|
||||
+
|
||||
+ /* Trigger reset event for each passthrough ISM device currently in-use */
|
||||
+ QTAILQ_FOREACH_SAFE(pbdev, &s->zpci_devs, link, next) {
|
||||
+ if (pbdev->interp && pbdev->pft == ZPCI_PFT_ISM &&
|
||||
+ pbdev->fh & FH_MASK_ENABLE) {
|
||||
+ s390_pci_kvm_aif_disable(pbdev);
|
||||
+
|
||||
+ pci_device_reset(pbdev->pdev);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void s390_pcihost_reset(DeviceState *dev)
|
||||
{
|
||||
S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index e26ce26f5a..24f4773179 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -118,6 +118,14 @@ static void subsystem_reset(void)
|
||||
DeviceState *dev;
|
||||
int i;
|
||||
|
||||
+ /*
|
||||
+ * ISM firmware is sensitive to unexpected changes to the IOMMU, which can
|
||||
+ * occur during reset of the vfio-pci device (unmap of entire aperture).
|
||||
+ * Ensure any passthrough ISM devices are reset now, while CPUs are paused
|
||||
+ * but before vfio-pci cleanup occurs.
|
||||
+ */
|
||||
+ s390_pci_ism_reset();
|
||||
+
|
||||
for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
|
||||
dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
|
||||
if (dev) {
|
||||
diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h
|
||||
index 435e788867..2c43ea123f 100644
|
||||
--- a/include/hw/s390x/s390-pci-bus.h
|
||||
+++ b/include/hw/s390x/s390-pci-bus.h
|
||||
@@ -401,5 +401,6 @@ S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s,
|
||||
const char *target);
|
||||
S390PCIBusDevice *s390_pci_find_next_avail_dev(S390pciState *s,
|
||||
S390PCIBusDevice *pbdev);
|
||||
+void s390_pci_ism_reset(void);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,71 +0,0 @@
|
||||
From 49078bdfd4c116da3e920632ec6f7041f1b38015 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@redhat.com>
|
||||
Date: Mon, 22 Jan 2024 09:25:53 +0100
|
||||
Subject: [PATCH 097/101] s390x/pci: refresh fh before disabling aif
|
||||
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: 215: s390x: Fix reset ordering of passthrough ISM devices
|
||||
RH-Jira: RHEL-21169
|
||||
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [2/3] 3523067909c41818dfc769abdb93930833416c11 (clegoate/qemu-kvm-c9s)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21169
|
||||
|
||||
commit 30e35258e25c75c9d799c34fd89afcafffb37084
|
||||
Author: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Date: Thu Jan 18 13:51:50 2024 -0500
|
||||
|
||||
s390x/pci: refresh fh before disabling aif
|
||||
|
||||
Typically we refresh the host fh during CLP enable, however it's possible
|
||||
that the device goes through multiple reset events before the guest
|
||||
performs another CLP enable. Let's handle this for now by refreshing the
|
||||
host handle from vfio before disabling aif.
|
||||
|
||||
Fixes: 03451953c7 ("s390x/pci: reset ISM passthrough devices on shutdown and system reset")
|
||||
Reported-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
|
||||
Message-ID: <20240118185151.265329-3-mjrosato@linux.ibm.com>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Signed-off-by: Cédric Le Goater <clg@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-pci-kvm.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c
|
||||
index 1ee510436c..9eef4fc3ec 100644
|
||||
--- a/hw/s390x/s390-pci-kvm.c
|
||||
+++ b/hw/s390x/s390-pci-kvm.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "hw/s390x/s390-pci-bus.h"
|
||||
#include "hw/s390x/s390-pci-kvm.h"
|
||||
#include "hw/s390x/s390-pci-inst.h"
|
||||
+#include "hw/s390x/s390-pci-vfio.h"
|
||||
#include "cpu_models.h"
|
||||
|
||||
bool s390_pci_kvm_interp_allowed(void)
|
||||
@@ -64,6 +65,14 @@ int s390_pci_kvm_aif_disable(S390PCIBusDevice *pbdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The device may have already been reset but we still want to relinquish
|
||||
+ * the guest ISC, so always be sure to use an up-to-date host fh.
|
||||
+ */
|
||||
+ if (!s390_pci_get_host_fh(pbdev, &args.fh)) {
|
||||
+ return -EPERM;
|
||||
+ }
|
||||
+
|
||||
rc = kvm_vm_ioctl(kvm_state, KVM_S390_ZPCI_OP, &args);
|
||||
if (rc == 0) {
|
||||
pbdev->aif = false;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,124 +0,0 @@
|
||||
From 94d6458a58239b52394d58b6880509041186d5a8 Mon Sep 17 00:00:00 2001
|
||||
From: Hanna Czenczek <hreitz@redhat.com>
|
||||
Date: Fri, 2 Feb 2024 15:47:55 +0100
|
||||
Subject: [PATCH 04/22] scsi: Await request purging
|
||||
|
||||
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-MergeRequest: 222: Allow concurrent BlockBackend context changes
|
||||
RH-Jira: RHEL-24593
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Commit: [2/2] 35a89273cab0af8f999881e67d359fe1328363a0 (hreitz/qemu-kvm-c-9-s)
|
||||
|
||||
scsi_device_for_each_req_async() currently does not provide any way to
|
||||
be awaited. One of its callers is scsi_device_purge_requests(), which
|
||||
therefore currently does not guarantee that all requests are fully
|
||||
settled when it returns.
|
||||
|
||||
We want all requests to be settled, because scsi_device_purge_requests()
|
||||
is called through the unrealize path, including the one invoked by
|
||||
virtio_scsi_hotunplug() through qdev_simple_device_unplug_cb(), which
|
||||
most likely assumes that all SCSI requests are done then.
|
||||
|
||||
In fact, scsi_device_purge_requests() already contains a blk_drain(),
|
||||
but this will not fully await scsi_device_for_each_req_async(), only the
|
||||
I/O requests it potentially cancels (not the non-I/O requests).
|
||||
However, we can have scsi_device_for_each_req_async() increment the BB
|
||||
in-flight counter, and have scsi_device_for_each_req_async_bh()
|
||||
decrement it when it is done. This way, the blk_drain() will fully
|
||||
await all SCSI requests to be purged.
|
||||
|
||||
This also removes the need for scsi_device_for_each_req_async_bh() to
|
||||
double-check the current context and potentially re-schedule itself,
|
||||
should it now differ from the BB's context: Changing a BB's AioContext
|
||||
with a root node is done through bdrv_try_change_aio_context(), which
|
||||
creates a drained section. With this patch, we keep the BB in-flight
|
||||
counter elevated throughout, so we know the BB's context cannot change.
|
||||
|
||||
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Message-ID: <20240202144755.671354-3-hreitz@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 1604c0493193273e4eac547f86fbd2845e7f9af4)
|
||||
---
|
||||
hw/scsi/scsi-bus.c | 30 +++++++++++++++++++++---------
|
||||
1 file changed, 21 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
|
||||
index 5b08cbf60a..b1bf8e6433 100644
|
||||
--- a/hw/scsi/scsi-bus.c
|
||||
+++ b/hw/scsi/scsi-bus.c
|
||||
@@ -120,17 +120,13 @@ static void scsi_device_for_each_req_async_bh(void *opaque)
|
||||
SCSIRequest *next;
|
||||
|
||||
/*
|
||||
- * If the AioContext changed before this BH was called then reschedule into
|
||||
- * the new AioContext before accessing ->requests. This can happen when
|
||||
- * scsi_device_for_each_req_async() is called and then the AioContext is
|
||||
- * changed before BHs are run.
|
||||
+ * The BB cannot have changed contexts between this BH being scheduled and
|
||||
+ * now: BBs' AioContexts, when they have a node attached, can only be
|
||||
+ * changed via bdrv_try_change_aio_context(), in a drained section. While
|
||||
+ * we have the in-flight counter incremented, that drain must block.
|
||||
*/
|
||||
ctx = blk_get_aio_context(s->conf.blk);
|
||||
- if (ctx != qemu_get_current_aio_context()) {
|
||||
- aio_bh_schedule_oneshot(ctx, scsi_device_for_each_req_async_bh,
|
||||
- g_steal_pointer(&data));
|
||||
- return;
|
||||
- }
|
||||
+ assert(ctx == qemu_get_current_aio_context());
|
||||
|
||||
QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
|
||||
data->fn(req, data->fn_opaque);
|
||||
@@ -138,11 +134,16 @@ static void scsi_device_for_each_req_async_bh(void *opaque)
|
||||
|
||||
/* Drop the reference taken by scsi_device_for_each_req_async() */
|
||||
object_unref(OBJECT(s));
|
||||
+
|
||||
+ /* Paired with blk_inc_in_flight() in scsi_device_for_each_req_async() */
|
||||
+ blk_dec_in_flight(s->conf.blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule @fn() to be invoked for each enqueued request in device @s. @fn()
|
||||
* runs in the AioContext that is executing the request.
|
||||
+ * Keeps the BlockBackend's in-flight counter incremented until everything is
|
||||
+ * done, so draining it will settle all scheduled @fn() calls.
|
||||
*/
|
||||
static void scsi_device_for_each_req_async(SCSIDevice *s,
|
||||
void (*fn)(SCSIRequest *, void *),
|
||||
@@ -163,6 +164,8 @@ static void scsi_device_for_each_req_async(SCSIDevice *s,
|
||||
*/
|
||||
object_ref(OBJECT(s));
|
||||
|
||||
+ /* Paired with blk_dec_in_flight() in scsi_device_for_each_req_async_bh() */
|
||||
+ blk_inc_in_flight(s->conf.blk);
|
||||
aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk),
|
||||
scsi_device_for_each_req_async_bh,
|
||||
data);
|
||||
@@ -1728,11 +1731,20 @@ static void scsi_device_purge_one_req(SCSIRequest *req, void *opaque)
|
||||
scsi_req_cancel_async(req, NULL);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Cancel all requests, and block until they are deleted.
|
||||
+ */
|
||||
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
|
||||
{
|
||||
scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL);
|
||||
|
||||
+ /*
|
||||
+ * Await all the scsi_device_purge_one_req() calls scheduled by
|
||||
+ * scsi_device_for_each_req_async(), and all I/O requests that were
|
||||
+ * cancelled this way, but may still take a bit of time to settle.
|
||||
+ */
|
||||
blk_drain(sdev->conf.blk);
|
||||
+
|
||||
scsi_device_set_ua(sdev, sense);
|
||||
}
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,88 +0,0 @@
|
||||
From cd08d22a0da022d99fe6cfddb7de680abf66c8be Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:19:59 -0500
|
||||
Subject: [PATCH 082/101] scsi: assert that callbacks run in the correct
|
||||
AioContext
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [13/26] d2fd5065c3b72d9d2f4e37efee39fe12eba0f0a9 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Since the removal of AioContext locking, the correctness of the code
|
||||
relies on running requests from a single AioContext at any given time.
|
||||
|
||||
Add assertions that verify that callbacks are invoked in the correct
|
||||
AioContext.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-3-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/scsi/scsi-disk.c | 14 ++++++++++++++
|
||||
system/dma-helpers.c | 3 +++
|
||||
2 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||||
index 2c1bbb3530..a5048e0aaf 100644
|
||||
--- a/hw/scsi/scsi-disk.c
|
||||
+++ b/hw/scsi/scsi-disk.c
|
||||
@@ -273,6 +273,10 @@ static void scsi_aio_complete(void *opaque, int ret)
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
+ /* The request must only run in the BlockBackend's AioContext */
|
||||
+ assert(blk_get_aio_context(s->qdev.conf.blk) ==
|
||||
+ qemu_get_current_aio_context());
|
||||
+
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -370,8 +374,13 @@ static void scsi_dma_complete(void *opaque, int ret)
|
||||
|
||||
static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
|
||||
{
|
||||
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
uint32_t n;
|
||||
|
||||
+ /* The request must only run in the BlockBackend's AioContext */
|
||||
+ assert(blk_get_aio_context(s->qdev.conf.blk) ==
|
||||
+ qemu_get_current_aio_context());
|
||||
+
|
||||
assert(r->req.aiocb == NULL);
|
||||
if (scsi_disk_req_check_error(r, ret, false)) {
|
||||
goto done;
|
||||
@@ -496,8 +505,13 @@ static void scsi_read_data(SCSIRequest *req)
|
||||
|
||||
static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
|
||||
{
|
||||
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
uint32_t n;
|
||||
|
||||
+ /* The request must only run in the BlockBackend's AioContext */
|
||||
+ assert(blk_get_aio_context(s->qdev.conf.blk) ==
|
||||
+ qemu_get_current_aio_context());
|
||||
+
|
||||
assert (r->req.aiocb == NULL);
|
||||
if (scsi_disk_req_check_error(r, ret, false)) {
|
||||
goto done;
|
||||
diff --git a/system/dma-helpers.c b/system/dma-helpers.c
|
||||
index 528117f256..9b221cf94e 100644
|
||||
--- a/system/dma-helpers.c
|
||||
+++ b/system/dma-helpers.c
|
||||
@@ -119,6 +119,9 @@ static void dma_blk_cb(void *opaque, int ret)
|
||||
|
||||
trace_dma_blk_cb(dbs, ret);
|
||||
|
||||
+ /* DMAAIOCB is not thread-safe and must be accessed only from dbs->ctx */
|
||||
+ assert(ctx == qemu_get_current_aio_context());
|
||||
+
|
||||
dbs->acb = NULL;
|
||||
dbs->offset += dbs->iov.size;
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,245 +0,0 @@
|
||||
From d1d384bd24a7aeb527f4abd8a0958146544ef9bb Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Mon, 4 Dec 2023 11:42:58 -0500
|
||||
Subject: [PATCH 079/101] scsi: don't lock AioContext in I/O code path
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [10/26] b5814cec94af5c254e300646d8783672b085bac3 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
blk_aio_*() doesn't require the AioContext lock and the SCSI subsystem's
|
||||
internal state also does not anymore.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20231204164259.1515217-4-stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/scsi/scsi-disk.c | 23 -----------------------
|
||||
hw/scsi/scsi-generic.c | 20 +++-----------------
|
||||
2 files changed, 3 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||||
index 6691f5edb8..2c1bbb3530 100644
|
||||
--- a/hw/scsi/scsi-disk.c
|
||||
+++ b/hw/scsi/scsi-disk.c
|
||||
@@ -273,8 +273,6 @@ static void scsi_aio_complete(void *opaque, int ret)
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -286,7 +284,6 @@ static void scsi_aio_complete(void *opaque, int ret)
|
||||
scsi_req_complete(&r->req, GOOD);
|
||||
|
||||
done:
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
scsi_req_unref(&r->req);
|
||||
}
|
||||
|
||||
@@ -394,8 +391,6 @@ static void scsi_read_complete(void *opaque, int ret)
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -406,7 +401,6 @@ static void scsi_read_complete(void *opaque, int ret)
|
||||
trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
|
||||
}
|
||||
scsi_read_complete_noio(r, ret);
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
}
|
||||
|
||||
/* Actually issue a read to the block device. */
|
||||
@@ -448,8 +442,6 @@ static void scsi_do_read_cb(void *opaque, int ret)
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert (r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -459,7 +451,6 @@ static void scsi_do_read_cb(void *opaque, int ret)
|
||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||
}
|
||||
scsi_do_read(opaque, ret);
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
}
|
||||
|
||||
/* Read more data from scsi device into buffer. */
|
||||
@@ -533,8 +524,6 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert (r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -544,7 +533,6 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||
}
|
||||
scsi_write_complete_noio(r, ret);
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
}
|
||||
|
||||
static void scsi_write_data(SCSIRequest *req)
|
||||
@@ -1742,8 +1730,6 @@ static void scsi_unmap_complete(void *opaque, int ret)
|
||||
SCSIDiskReq *r = data->r;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -1754,7 +1740,6 @@ static void scsi_unmap_complete(void *opaque, int ret)
|
||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||
scsi_unmap_complete_noio(data, ret);
|
||||
}
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
}
|
||||
|
||||
static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
|
||||
@@ -1822,8 +1807,6 @@ static void scsi_write_same_complete(void *opaque, int ret)
|
||||
SCSIDiskReq *r = data->r;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
@@ -1847,7 +1830,6 @@ static void scsi_write_same_complete(void *opaque, int ret)
|
||||
data->sector << BDRV_SECTOR_BITS,
|
||||
&data->qiov, 0,
|
||||
scsi_write_same_complete, data);
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1857,7 +1839,6 @@ done:
|
||||
scsi_req_unref(&r->req);
|
||||
qemu_vfree(data->iov.iov_base);
|
||||
g_free(data);
|
||||
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||
}
|
||||
|
||||
static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
|
||||
@@ -2810,7 +2791,6 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
|
||||
{
|
||||
SCSIBlockReq *req = (SCSIBlockReq *)opaque;
|
||||
SCSIDiskReq *r = &req->req;
|
||||
- SCSIDevice *s = r->req.dev;
|
||||
sg_io_hdr_t *io_hdr = &req->io_header;
|
||||
|
||||
if (ret == 0) {
|
||||
@@ -2827,13 +2807,10 @@ static void scsi_block_sgio_complete(void *opaque, int ret)
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||
if (scsi_handle_rw_error(r, ret, true)) {
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
scsi_req_unref(&r->req);
|
||||
return;
|
||||
}
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
|
||||
/* Ignore error. */
|
||||
ret = 0;
|
||||
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
|
||||
index 2417f0ad84..b7b04e1d63 100644
|
||||
--- a/hw/scsi/scsi-generic.c
|
||||
+++ b/hw/scsi/scsi-generic.c
|
||||
@@ -109,15 +109,11 @@ done:
|
||||
static void scsi_command_complete(void *opaque, int ret)
|
||||
{
|
||||
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
|
||||
- SCSIDevice *s = r->req.dev;
|
||||
-
|
||||
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
scsi_command_complete_noio(r, ret);
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
}
|
||||
|
||||
static int execute_command(BlockBackend *blk,
|
||||
@@ -274,14 +270,12 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||
SCSIDevice *s = r->req.dev;
|
||||
int len;
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
if (ret || r->req.io_canceled) {
|
||||
scsi_command_complete_noio(r, ret);
|
||||
- goto done;
|
||||
+ return;
|
||||
}
|
||||
|
||||
len = r->io_header.dxfer_len - r->io_header.resid;
|
||||
@@ -320,7 +314,7 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||
r->io_header.status != GOOD ||
|
||||
len == 0) {
|
||||
scsi_command_complete_noio(r, 0);
|
||||
- goto done;
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* Snoop READ CAPACITY output to set the blocksize. */
|
||||
@@ -356,9 +350,6 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||
req_complete:
|
||||
scsi_req_data(&r->req, len);
|
||||
scsi_req_unref(&r->req);
|
||||
-
|
||||
-done:
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
}
|
||||
|
||||
/* Read more data from scsi device into buffer. */
|
||||
@@ -391,14 +382,12 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||
|
||||
trace_scsi_generic_write_complete(ret);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||
-
|
||||
assert(r->req.aiocb != NULL);
|
||||
r->req.aiocb = NULL;
|
||||
|
||||
if (ret || r->req.io_canceled) {
|
||||
scsi_command_complete_noio(r, ret);
|
||||
- goto done;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
|
||||
@@ -408,9 +397,6 @@ static void scsi_write_complete(void * opaque, int ret)
|
||||
}
|
||||
|
||||
scsi_command_complete_noio(r, ret);
|
||||
-
|
||||
-done:
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
}
|
||||
|
||||
/* Write data to a scsi device. Returns nonzero on failure.
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,307 +0,0 @@
|
||||
From 42dd1357310bd1a68d6cacaa53cd5b1d1b02880d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Mon, 4 Dec 2023 11:42:56 -0500
|
||||
Subject: [PATCH 077/101] scsi: only access SCSIDevice->requests from one
|
||||
thread
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [8/26] 9df662e82a63e93d184b5763bebbe7e43bc9dabe (kmwolf/centos-qemu-kvm)
|
||||
|
||||
Stop depending on the AioContext lock and instead access
|
||||
SCSIDevice->requests from only one thread at a time:
|
||||
- When the VM is running only the BlockBackend's AioContext may access
|
||||
the requests list.
|
||||
- When the VM is stopped only the main loop may access the requests
|
||||
list.
|
||||
|
||||
These constraints protect the requests list without the need for locking
|
||||
in the I/O code path.
|
||||
|
||||
Note that multiple IOThreads are not supported yet because the code
|
||||
assumes all SCSIRequests are executed from a single AioContext. Leave
|
||||
that as future work.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231204164259.1515217-2-stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/scsi/scsi-bus.c | 181 ++++++++++++++++++++++++++++-------------
|
||||
include/hw/scsi/scsi.h | 7 +-
|
||||
2 files changed, 131 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
|
||||
index fc4b77fdb0..b649cdf555 100644
|
||||
--- a/hw/scsi/scsi-bus.c
|
||||
+++ b/hw/scsi/scsi-bus.c
|
||||
@@ -85,6 +85,89 @@ SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int id, int lun)
|
||||
return d;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Invoke @fn() for each enqueued request in device @s. Must be called from the
|
||||
+ * main loop thread while the guest is stopped. This is only suitable for
|
||||
+ * vmstate ->put(), use scsi_device_for_each_req_async() for other cases.
|
||||
+ */
|
||||
+static void scsi_device_for_each_req_sync(SCSIDevice *s,
|
||||
+ void (*fn)(SCSIRequest *, void *),
|
||||
+ void *opaque)
|
||||
+{
|
||||
+ SCSIRequest *req;
|
||||
+ SCSIRequest *next_req;
|
||||
+
|
||||
+ assert(!runstate_is_running());
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
+ QTAILQ_FOREACH_SAFE(req, &s->requests, next, next_req) {
|
||||
+ fn(req, opaque);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+typedef struct {
|
||||
+ SCSIDevice *s;
|
||||
+ void (*fn)(SCSIRequest *, void *);
|
||||
+ void *fn_opaque;
|
||||
+} SCSIDeviceForEachReqAsyncData;
|
||||
+
|
||||
+static void scsi_device_for_each_req_async_bh(void *opaque)
|
||||
+{
|
||||
+ g_autofree SCSIDeviceForEachReqAsyncData *data = opaque;
|
||||
+ SCSIDevice *s = data->s;
|
||||
+ AioContext *ctx;
|
||||
+ SCSIRequest *req;
|
||||
+ SCSIRequest *next;
|
||||
+
|
||||
+ /*
|
||||
+ * If the AioContext changed before this BH was called then reschedule into
|
||||
+ * the new AioContext before accessing ->requests. This can happen when
|
||||
+ * scsi_device_for_each_req_async() is called and then the AioContext is
|
||||
+ * changed before BHs are run.
|
||||
+ */
|
||||
+ ctx = blk_get_aio_context(s->conf.blk);
|
||||
+ if (ctx != qemu_get_current_aio_context()) {
|
||||
+ aio_bh_schedule_oneshot(ctx, scsi_device_for_each_req_async_bh,
|
||||
+ g_steal_pointer(&data));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
|
||||
+ data->fn(req, data->fn_opaque);
|
||||
+ }
|
||||
+
|
||||
+ /* Drop the reference taken by scsi_device_for_each_req_async() */
|
||||
+ object_unref(OBJECT(s));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Schedule @fn() to be invoked for each enqueued request in device @s. @fn()
|
||||
+ * runs in the AioContext that is executing the request.
|
||||
+ */
|
||||
+static void scsi_device_for_each_req_async(SCSIDevice *s,
|
||||
+ void (*fn)(SCSIRequest *, void *),
|
||||
+ void *opaque)
|
||||
+{
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
+ SCSIDeviceForEachReqAsyncData *data =
|
||||
+ g_new(SCSIDeviceForEachReqAsyncData, 1);
|
||||
+
|
||||
+ data->s = s;
|
||||
+ data->fn = fn;
|
||||
+ data->fn_opaque = opaque;
|
||||
+
|
||||
+ /*
|
||||
+ * Hold a reference to the SCSIDevice until
|
||||
+ * scsi_device_for_each_req_async_bh() finishes.
|
||||
+ */
|
||||
+ object_ref(OBJECT(s));
|
||||
+
|
||||
+ aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk),
|
||||
+ scsi_device_for_each_req_async_bh,
|
||||
+ data);
|
||||
+}
|
||||
+
|
||||
static void scsi_device_realize(SCSIDevice *s, Error **errp)
|
||||
{
|
||||
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
|
||||
@@ -144,20 +227,18 @@ void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host,
|
||||
qbus_set_bus_hotplug_handler(BUS(bus));
|
||||
}
|
||||
|
||||
-static void scsi_dma_restart_bh(void *opaque)
|
||||
+void scsi_req_retry(SCSIRequest *req)
|
||||
{
|
||||
- SCSIDevice *s = opaque;
|
||||
- SCSIRequest *req, *next;
|
||||
-
|
||||
- qemu_bh_delete(s->bh);
|
||||
- s->bh = NULL;
|
||||
+ req->retry = true;
|
||||
+}
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
|
||||
- QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) {
|
||||
- scsi_req_ref(req);
|
||||
- if (req->retry) {
|
||||
- req->retry = false;
|
||||
- switch (req->cmd.mode) {
|
||||
+/* Called in the AioContext that is executing the request */
|
||||
+static void scsi_dma_restart_req(SCSIRequest *req, void *opaque)
|
||||
+{
|
||||
+ scsi_req_ref(req);
|
||||
+ if (req->retry) {
|
||||
+ req->retry = false;
|
||||
+ switch (req->cmd.mode) {
|
||||
case SCSI_XFER_FROM_DEV:
|
||||
case SCSI_XFER_TO_DEV:
|
||||
scsi_req_continue(req);
|
||||
@@ -166,37 +247,22 @@ static void scsi_dma_restart_bh(void *opaque)
|
||||
scsi_req_dequeue(req);
|
||||
scsi_req_enqueue(req);
|
||||
break;
|
||||
- }
|
||||
}
|
||||
- scsi_req_unref(req);
|
||||
}
|
||||
- aio_context_release(blk_get_aio_context(s->conf.blk));
|
||||
- /* Drop the reference that was acquired in scsi_dma_restart_cb */
|
||||
- object_unref(OBJECT(s));
|
||||
-}
|
||||
-
|
||||
-void scsi_req_retry(SCSIRequest *req)
|
||||
-{
|
||||
- /* No need to save a reference, because scsi_dma_restart_bh just
|
||||
- * looks at the request list. */
|
||||
- req->retry = true;
|
||||
+ scsi_req_unref(req);
|
||||
}
|
||||
|
||||
static void scsi_dma_restart_cb(void *opaque, bool running, RunState state)
|
||||
{
|
||||
SCSIDevice *s = opaque;
|
||||
|
||||
+ assert(qemu_in_main_thread());
|
||||
+
|
||||
if (!running) {
|
||||
return;
|
||||
}
|
||||
- if (!s->bh) {
|
||||
- AioContext *ctx = blk_get_aio_context(s->conf.blk);
|
||||
- /* The reference is dropped in scsi_dma_restart_bh.*/
|
||||
- object_ref(OBJECT(s));
|
||||
- s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s,
|
||||
- &DEVICE(s)->mem_reentrancy_guard);
|
||||
- qemu_bh_schedule(s->bh);
|
||||
- }
|
||||
+
|
||||
+ scsi_device_for_each_req_async(s, scsi_dma_restart_req, NULL);
|
||||
}
|
||||
|
||||
static bool scsi_bus_is_address_free(SCSIBus *bus,
|
||||
@@ -1657,15 +1723,16 @@ void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense)
|
||||
}
|
||||
}
|
||||
|
||||
+static void scsi_device_purge_one_req(SCSIRequest *req, void *opaque)
|
||||
+{
|
||||
+ scsi_req_cancel_async(req, NULL);
|
||||
+}
|
||||
+
|
||||
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
|
||||
{
|
||||
- SCSIRequest *req;
|
||||
+ scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL);
|
||||
|
||||
aio_context_acquire(blk_get_aio_context(sdev->conf.blk));
|
||||
- while (!QTAILQ_EMPTY(&sdev->requests)) {
|
||||
- req = QTAILQ_FIRST(&sdev->requests);
|
||||
- scsi_req_cancel_async(req, NULL);
|
||||
- }
|
||||
blk_drain(sdev->conf.blk);
|
||||
aio_context_release(blk_get_aio_context(sdev->conf.blk));
|
||||
scsi_device_set_ua(sdev, sense);
|
||||
@@ -1737,31 +1804,33 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
|
||||
|
||||
/* SCSI request list. For simplicity, pv points to the whole device */
|
||||
|
||||
+static void put_scsi_req(SCSIRequest *req, void *opaque)
|
||||
+{
|
||||
+ QEMUFile *f = opaque;
|
||||
+
|
||||
+ assert(!req->io_canceled);
|
||||
+ assert(req->status == -1 && req->host_status == -1);
|
||||
+ assert(req->enqueued);
|
||||
+
|
||||
+ qemu_put_sbyte(f, req->retry ? 1 : 2);
|
||||
+ qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf));
|
||||
+ qemu_put_be32s(f, &req->tag);
|
||||
+ qemu_put_be32s(f, &req->lun);
|
||||
+ if (req->bus->info->save_request) {
|
||||
+ req->bus->info->save_request(f, req);
|
||||
+ }
|
||||
+ if (req->ops->save_request) {
|
||||
+ req->ops->save_request(f, req);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
|
||||
const VMStateField *field, JSONWriter *vmdesc)
|
||||
{
|
||||
SCSIDevice *s = pv;
|
||||
- SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
|
||||
- SCSIRequest *req;
|
||||
|
||||
- QTAILQ_FOREACH(req, &s->requests, next) {
|
||||
- assert(!req->io_canceled);
|
||||
- assert(req->status == -1 && req->host_status == -1);
|
||||
- assert(req->enqueued);
|
||||
-
|
||||
- qemu_put_sbyte(f, req->retry ? 1 : 2);
|
||||
- qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf));
|
||||
- qemu_put_be32s(f, &req->tag);
|
||||
- qemu_put_be32s(f, &req->lun);
|
||||
- if (bus->info->save_request) {
|
||||
- bus->info->save_request(f, req);
|
||||
- }
|
||||
- if (req->ops->save_request) {
|
||||
- req->ops->save_request(f, req);
|
||||
- }
|
||||
- }
|
||||
+ scsi_device_for_each_req_sync(s, put_scsi_req, f);
|
||||
qemu_put_sbyte(f, 0);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
|
||||
index 3692ca82f3..10c4e8288d 100644
|
||||
--- a/include/hw/scsi/scsi.h
|
||||
+++ b/include/hw/scsi/scsi.h
|
||||
@@ -69,14 +69,19 @@ struct SCSIDevice
|
||||
{
|
||||
DeviceState qdev;
|
||||
VMChangeStateEntry *vmsentry;
|
||||
- QEMUBH *bh;
|
||||
uint32_t id;
|
||||
BlockConf conf;
|
||||
SCSISense unit_attention;
|
||||
bool sense_is_ua;
|
||||
uint8_t sense[SCSI_SENSE_BUF_SIZE];
|
||||
uint32_t sense_len;
|
||||
+
|
||||
+ /*
|
||||
+ * The requests list is only accessed from the AioContext that executes
|
||||
+ * requests or from the main loop when IOThread processing is stopped.
|
||||
+ */
|
||||
QTAILQ_HEAD(, SCSIRequest) requests;
|
||||
+
|
||||
uint32_t channel;
|
||||
uint32_t lun;
|
||||
int blocksize;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,280 +0,0 @@
|
||||
From 61d605433a5edfcc7fe836fd399106ed1e1907bb Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:05 -0500
|
||||
Subject: [PATCH 088/101] scsi: remove AioContext locking
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [19/26] 12a8e26670074a17dd2b0cfac06e0aea03b3068f (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The AioContext lock no longer has any effect. Remove it.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-9-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/scsi/scsi-bus.c | 2 --
|
||||
hw/scsi/scsi-disk.c | 31 +++++--------------------------
|
||||
hw/scsi/virtio-scsi.c | 18 ------------------
|
||||
include/hw/virtio/virtio-scsi.h | 14 --------------
|
||||
4 files changed, 5 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
|
||||
index b649cdf555..5b08cbf60a 100644
|
||||
--- a/hw/scsi/scsi-bus.c
|
||||
+++ b/hw/scsi/scsi-bus.c
|
||||
@@ -1732,9 +1732,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
|
||||
{
|
||||
scsi_device_for_each_req_async(sdev, scsi_device_purge_one_req, NULL);
|
||||
|
||||
- aio_context_acquire(blk_get_aio_context(sdev->conf.blk));
|
||||
blk_drain(sdev->conf.blk);
|
||||
- aio_context_release(blk_get_aio_context(sdev->conf.blk));
|
||||
scsi_device_set_ua(sdev, sense);
|
||||
}
|
||||
|
||||
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||||
index a5048e0aaf..61be3d395a 100644
|
||||
--- a/hw/scsi/scsi-disk.c
|
||||
+++ b/hw/scsi/scsi-disk.c
|
||||
@@ -2339,14 +2339,10 @@ static void scsi_disk_reset(DeviceState *dev)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
|
||||
uint64_t nb_sectors;
|
||||
- AioContext *ctx;
|
||||
|
||||
scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
|
||||
|
||||
- ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||||
- aio_context_acquire(ctx);
|
||||
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
|
||||
- aio_context_release(ctx);
|
||||
|
||||
nb_sectors /= s->qdev.blocksize / BDRV_SECTOR_SIZE;
|
||||
if (nb_sectors) {
|
||||
@@ -2545,15 +2541,13 @@ static void scsi_unrealize(SCSIDevice *dev)
|
||||
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
- AioContext *ctx = NULL;
|
||||
+
|
||||
/* can happen for devices without drive. The error message for missing
|
||||
* backend will be issued in scsi_realize
|
||||
*/
|
||||
if (s->qdev.conf.blk) {
|
||||
- ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||||
- aio_context_acquire(ctx);
|
||||
if (!blkconf_blocksizes(&s->qdev.conf, errp)) {
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
s->qdev.blocksize = s->qdev.conf.logical_block_size;
|
||||
@@ -2562,16 +2556,11 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||||
s->product = g_strdup("QEMU HARDDISK");
|
||||
}
|
||||
scsi_realize(&s->qdev, errp);
|
||||
-out:
|
||||
- if (ctx) {
|
||||
- aio_context_release(ctx);
|
||||
- }
|
||||
}
|
||||
|
||||
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
- AioContext *ctx;
|
||||
int ret;
|
||||
uint32_t blocksize = 2048;
|
||||
|
||||
@@ -2587,8 +2576,6 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
blocksize = dev->conf.physical_block_size;
|
||||
}
|
||||
|
||||
- ctx = blk_get_aio_context(dev->conf.blk);
|
||||
- aio_context_acquire(ctx);
|
||||
s->qdev.blocksize = blocksize;
|
||||
s->qdev.type = TYPE_ROM;
|
||||
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
|
||||
@@ -2596,7 +2583,6 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
s->product = g_strdup("QEMU CD-ROM");
|
||||
}
|
||||
scsi_realize(&s->qdev, errp);
|
||||
- aio_context_release(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -2727,7 +2713,6 @@ static int get_device_type(SCSIDiskState *s)
|
||||
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
- AioContext *ctx;
|
||||
int sg_version;
|
||||
int rc;
|
||||
|
||||
@@ -2742,9 +2727,6 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
"be removed in a future version");
|
||||
}
|
||||
|
||||
- ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||||
- aio_context_acquire(ctx);
|
||||
-
|
||||
/* check we are using a driver managing SG_IO (version 3 and after) */
|
||||
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
|
||||
if (rc < 0) {
|
||||
@@ -2752,18 +2734,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
if (rc != -EPERM) {
|
||||
error_append_hint(errp, "Is this a SCSI device?\n");
|
||||
}
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
if (sg_version < 30000) {
|
||||
error_setg(errp, "scsi generic interface too old");
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* get device type from INQUIRY data */
|
||||
rc = get_device_type(s);
|
||||
if (rc < 0) {
|
||||
error_setg(errp, "INQUIRY failed");
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* Make a guess for the block size, we'll fix it when the guest sends.
|
||||
@@ -2783,9 +2765,6 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
|
||||
scsi_realize(&s->qdev, errp);
|
||||
scsi_generic_read_device_inquiry(&s->qdev);
|
||||
-
|
||||
-out:
|
||||
- aio_context_release(ctx);
|
||||
}
|
||||
|
||||
typedef struct SCSIBlockReq {
|
||||
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
|
||||
index 4f8d35facc..ca365a70e9 100644
|
||||
--- a/hw/scsi/virtio-scsi.c
|
||||
+++ b/hw/scsi/virtio-scsi.c
|
||||
@@ -642,9 +642,7 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||
return;
|
||||
}
|
||||
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
|
||||
@@ -882,9 +880,7 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||
return;
|
||||
}
|
||||
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_handle_cmd_vq(s, vq);
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
static void virtio_scsi_get_config(VirtIODevice *vdev,
|
||||
@@ -1031,9 +1027,7 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
||||
return;
|
||||
}
|
||||
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_handle_event_vq(s, vq);
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
||||
@@ -1052,9 +1046,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
||||
},
|
||||
};
|
||||
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_push_event(s, &info);
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1071,17 +1063,13 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
|
||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||
SCSIDevice *sd = SCSI_DEVICE(dev);
|
||||
- AioContext *old_context;
|
||||
int ret;
|
||||
|
||||
if (s->ctx && !s->dataplane_fenced) {
|
||||
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
||||
return;
|
||||
}
|
||||
- old_context = blk_get_aio_context(sd->conf.blk);
|
||||
- aio_context_acquire(old_context);
|
||||
ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp);
|
||||
- aio_context_release(old_context);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1097,10 +1085,8 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
},
|
||||
};
|
||||
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_push_event(s, &info);
|
||||
scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1122,17 +1108,13 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
|
||||
|
||||
if (s->ctx) {
|
||||
- virtio_scsi_acquire(s);
|
||||
/* If other users keep the BlockBackend in the iothread, that's ok */
|
||||
blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL);
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
|
||||
- virtio_scsi_acquire(s);
|
||||
virtio_scsi_push_event(s, &info);
|
||||
scsi_bus_set_ua(&s->bus, SENSE_CODE(REPORTED_LUNS_CHANGED));
|
||||
- virtio_scsi_release(s);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
|
||||
index da8cb928d9..7f0573b1bf 100644
|
||||
--- a/include/hw/virtio/virtio-scsi.h
|
||||
+++ b/include/hw/virtio/virtio-scsi.h
|
||||
@@ -101,20 +101,6 @@ struct VirtIOSCSI {
|
||||
uint32_t host_features;
|
||||
};
|
||||
|
||||
-static inline void virtio_scsi_acquire(VirtIOSCSI *s)
|
||||
-{
|
||||
- if (s->ctx) {
|
||||
- aio_context_acquire(s->ctx);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static inline void virtio_scsi_release(VirtIOSCSI *s)
|
||||
-{
|
||||
- if (s->ctx) {
|
||||
- aio_context_release(s->ctx);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void virtio_scsi_common_realize(DeviceState *dev,
|
||||
VirtIOHandleOutput ctrl,
|
||||
VirtIOHandleOutput evt,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 9f5c6dbe907fe6227006ab51179eaa50a63559cb Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:09 -0500
|
||||
Subject: [PATCH 092/101] scsi: remove outdated AioContext lock comment
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [23/26] 96e2e7d2e6a160ce4d695060f902d21030b3b1d8 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The SCSI subsystem no longer uses the AioContext lock. Request
|
||||
processing runs exclusively in the BlockBackend's AioContext since
|
||||
"scsi: only access SCSIDevice->requests from one thread" and hence the
|
||||
lock is unnecessary.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-13-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/scsi/scsi-disk.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
|
||||
index 61be3d395a..2e7e1e9a1c 100644
|
||||
--- a/hw/scsi/scsi-disk.c
|
||||
+++ b/hw/scsi/scsi-disk.c
|
||||
@@ -355,7 +355,6 @@ done:
|
||||
scsi_req_unref(&r->req);
|
||||
}
|
||||
|
||||
-/* Called with AioContext lock held */
|
||||
static void scsi_dma_complete(void *opaque, int ret)
|
||||
{
|
||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 93cf5b82771f1d1e8182be168dae7a45d42069e9 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Mon, 4 Mar 2024 15:39:57 +0100
|
||||
Subject: [PATCH 11/20] smbios: add smbios_add_usr_blob_size() helper
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [9/18] 8c698fb9e186d2b1d2b7f75a74305f356450ad68
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
it will be used by follow up patch when legacy handling
|
||||
is moved out into a separate file.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 441517cf24..c48a290478 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -1426,6 +1426,14 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void smbios_add_usr_blob_size(size_t size)
|
||||
+{
|
||||
+ if (!usr_blobs_sizes) {
|
||||
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
|
||||
+ }
|
||||
+ g_array_append_val(usr_blobs_sizes, size);
|
||||
+}
|
||||
+
|
||||
void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
{
|
||||
const char *val;
|
||||
@@ -1473,10 +1481,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
smbios_type4_count++;
|
||||
}
|
||||
|
||||
- if (!usr_blobs_sizes) {
|
||||
- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
|
||||
- }
|
||||
- g_array_append_val(usr_blobs_sizes, size);
|
||||
+ /*
|
||||
+ * preserve blob size for legacy mode so it could build its
|
||||
+ * blobs flavor from 'usr_blobs'
|
||||
+ */
|
||||
+ smbios_add_usr_blob_size(size);
|
||||
+
|
||||
usr_blobs_len += size;
|
||||
if (size > usr_table_max) {
|
||||
usr_table_max = size;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,309 +0,0 @@
|
||||
From 15d293b706ca6c9e6ad569becda8da5f70461c30 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 13 Feb 2024 09:25:11 +0100
|
||||
Subject: [PATCH 09/20] smbios: avoid mangling user provided tables
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [7/18] fa2c7372f55f29e5834eee94ba98f19ea02e7a82
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
currently smbios_entry_add() preserves internally '-smbios type='
|
||||
options but tables provided with '-smbios file=' are stored directly
|
||||
into blob that eventually will be exposed to VM. And then later
|
||||
QEMU adds default/'-smbios type' entries on top into the same blob.
|
||||
|
||||
It makes impossible to generate tables more than once, hence
|
||||
'immutable' guard was used.
|
||||
Make it possible to regenerate final blob by storing user provided
|
||||
blobs into a dedicated area (usr_blobs) and then copy it when
|
||||
composing final blob. Which also makes handling of -smbios
|
||||
options consistent.
|
||||
|
||||
As side effect of this and previous commits there is no need to
|
||||
generate legacy smbios_entries at the time options are parsed.
|
||||
Instead compose smbios_entries on demand from usr_blobs like
|
||||
it is done for non-legacy SMBIOS tables.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Conflicts: hw/smbios/smbios.c
|
||||
caused by downstream smbios_type2_required
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 181 +++++++++++++++++++++++----------------------
|
||||
1 file changed, 93 insertions(+), 88 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 0c8c439859..d8d68716d4 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -60,6 +60,14 @@ static bool smbios_uuid_encoded = true;
|
||||
/* Set to true for modern Windows 10 HardwareID-6 compat */
|
||||
static bool smbios_type2_required;
|
||||
|
||||
+/*
|
||||
+ * SMBIOS tables provided by user with '-smbios file=<foo>' option
|
||||
+ */
|
||||
+uint8_t *usr_blobs;
|
||||
+size_t usr_blobs_len;
|
||||
+static GArray *usr_blobs_sizes;
|
||||
+static unsigned usr_table_max;
|
||||
+static unsigned usr_table_cnt;
|
||||
|
||||
uint8_t *smbios_tables;
|
||||
size_t smbios_tables_len;
|
||||
@@ -70,7 +78,6 @@ static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||
static SmbiosEntryPoint ep;
|
||||
|
||||
static int smbios_type4_count = 0;
|
||||
-static bool smbios_immutable;
|
||||
static bool smbios_have_defaults;
|
||||
static uint32_t smbios_cpuid_version, smbios_cpuid_features;
|
||||
|
||||
@@ -617,9 +624,8 @@ static void smbios_build_type_1_fields(void)
|
||||
|
||||
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
{
|
||||
- /* drop unwanted version of command-line file blob(s) */
|
||||
- g_free(smbios_tables);
|
||||
- smbios_tables = NULL;
|
||||
+ int i;
|
||||
+ size_t usr_offset;
|
||||
|
||||
/* also complain if fields were given for types > 1 */
|
||||
if (find_next_bit(have_fields_bitmap,
|
||||
@@ -629,12 +635,33 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- if (!smbios_immutable) {
|
||||
- smbios_build_type_0_fields();
|
||||
- smbios_build_type_1_fields();
|
||||
- smbios_validate_table(expected_t4_count);
|
||||
- smbios_immutable = true;
|
||||
+ g_free(smbios_entries);
|
||||
+ smbios_entries_len = sizeof(uint16_t);
|
||||
+ smbios_entries = g_malloc0(smbios_entries_len);
|
||||
+
|
||||
+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
|
||||
+ i++)
|
||||
+ {
|
||||
+ struct smbios_table *table;
|
||||
+ struct smbios_structure_header *header;
|
||||
+ size_t size = g_array_index(usr_blobs_sizes, size_t, i);
|
||||
+
|
||||
+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
|
||||
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
+ size + sizeof(*table));
|
||||
+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
|
||||
+ table->header.type = SMBIOS_TABLE_ENTRY;
|
||||
+ table->header.length = cpu_to_le16(sizeof(*table) + size);
|
||||
+ memcpy(table->data, header, size);
|
||||
+ smbios_entries_len += sizeof(*table) + size;
|
||||
+ (*(uint16_t *)smbios_entries) =
|
||||
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
+ usr_offset += size;
|
||||
}
|
||||
+
|
||||
+ smbios_build_type_0_fields();
|
||||
+ smbios_build_type_1_fields();
|
||||
+ smbios_validate_table(expected_t4_count);
|
||||
*length = smbios_entries_len;
|
||||
return smbios_entries;
|
||||
}
|
||||
@@ -1232,68 +1259,68 @@ void smbios_get_tables(MachineState *ms,
|
||||
{
|
||||
unsigned i, dimm_cnt, offset;
|
||||
|
||||
- /* drop unwanted (legacy) version of command-line file blob(s) */
|
||||
- g_free(smbios_entries);
|
||||
- smbios_entries = NULL;
|
||||
+ g_free(smbios_tables);
|
||||
+ smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
|
||||
+ smbios_tables_len = usr_blobs_len;
|
||||
+ smbios_table_max = usr_table_max;
|
||||
+ smbios_table_cnt = usr_table_cnt;
|
||||
|
||||
- if (!smbios_immutable) {
|
||||
- smbios_build_type_0_table();
|
||||
- smbios_build_type_1_table();
|
||||
- smbios_build_type_2_table();
|
||||
- smbios_build_type_3_table();
|
||||
+ smbios_build_type_0_table();
|
||||
+ smbios_build_type_1_table();
|
||||
+ smbios_build_type_2_table();
|
||||
+ smbios_build_type_3_table();
|
||||
|
||||
- assert(ms->smp.sockets >= 1);
|
||||
+ assert(ms->smp.sockets >= 1);
|
||||
|
||||
- for (i = 0; i < ms->smp.sockets; i++) {
|
||||
- smbios_build_type_4_table(ms, i);
|
||||
- }
|
||||
+ for (i = 0; i < ms->smp.sockets; i++) {
|
||||
+ smbios_build_type_4_table(ms, i);
|
||||
+ }
|
||||
|
||||
- smbios_build_type_8_table();
|
||||
- smbios_build_type_9_table(errp);
|
||||
- smbios_build_type_11_table();
|
||||
+ smbios_build_type_8_table();
|
||||
+ smbios_build_type_9_table(errp);
|
||||
+ smbios_build_type_11_table();
|
||||
|
||||
#define MAX_DIMM_SZ (16 * GiB)
|
||||
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
|
||||
: ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
|
||||
|
||||
- dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ;
|
||||
+ dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
|
||||
+ MAX_DIMM_SZ;
|
||||
|
||||
- /*
|
||||
- * The offset determines if we need to keep additional space between
|
||||
- * table 17 and table 19 header handle numbers so that they do
|
||||
- * not overlap. For example, for a VM with larger than 8 TB guest
|
||||
- * memory and DIMM like chunks of 16 GiB, the default space between
|
||||
- * the two tables (T19_BASE - T17_BASE = 512) is not enough.
|
||||
- */
|
||||
- offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
|
||||
- dimm_cnt - (T19_BASE - T17_BASE) : 0;
|
||||
+ /*
|
||||
+ * The offset determines if we need to keep additional space between
|
||||
+ * table 17 and table 19 header handle numbers so that they do
|
||||
+ * not overlap. For example, for a VM with larger than 8 TB guest
|
||||
+ * memory and DIMM like chunks of 16 GiB, the default space between
|
||||
+ * the two tables (T19_BASE - T17_BASE = 512) is not enough.
|
||||
+ */
|
||||
+ offset = (dimm_cnt > (T19_BASE - T17_BASE)) ? \
|
||||
+ dimm_cnt - (T19_BASE - T17_BASE) : 0;
|
||||
|
||||
- smbios_build_type_16_table(dimm_cnt);
|
||||
+ smbios_build_type_16_table(dimm_cnt);
|
||||
|
||||
- for (i = 0; i < dimm_cnt; i++) {
|
||||
- smbios_build_type_17_table(i, GET_DIMM_SZ);
|
||||
- }
|
||||
+ for (i = 0; i < dimm_cnt; i++) {
|
||||
+ smbios_build_type_17_table(i, GET_DIMM_SZ);
|
||||
+ }
|
||||
|
||||
- for (i = 0; i < mem_array_size; i++) {
|
||||
- smbios_build_type_19_table(i, offset, mem_array[i].address,
|
||||
- mem_array[i].length);
|
||||
- }
|
||||
+ for (i = 0; i < mem_array_size; i++) {
|
||||
+ smbios_build_type_19_table(i, offset, mem_array[i].address,
|
||||
+ mem_array[i].length);
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * make sure 16 bit handle numbers in the headers of tables 19
|
||||
- * and 32 do not overlap.
|
||||
- */
|
||||
- assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
|
||||
+ /*
|
||||
+ * make sure 16 bit handle numbers in the headers of tables 19
|
||||
+ * and 32 do not overlap.
|
||||
+ */
|
||||
+ assert((mem_array_size + offset) < (T32_BASE - T19_BASE));
|
||||
|
||||
- smbios_build_type_32_table();
|
||||
- smbios_build_type_38_table();
|
||||
- smbios_build_type_41_table(errp);
|
||||
- smbios_build_type_127_table();
|
||||
+ smbios_build_type_32_table();
|
||||
+ smbios_build_type_38_table();
|
||||
+ smbios_build_type_41_table(errp);
|
||||
+ smbios_build_type_127_table();
|
||||
|
||||
- smbios_validate_table(ms->smp.sockets);
|
||||
- smbios_entry_point_setup();
|
||||
- smbios_immutable = true;
|
||||
- }
|
||||
+ smbios_validate_table(ms->smp.sockets);
|
||||
+ smbios_entry_point_setup();
|
||||
|
||||
/* return tables blob and entry point (anchor), and their sizes */
|
||||
*tables = smbios_tables;
|
||||
@@ -1393,13 +1420,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
- assert(!smbios_immutable);
|
||||
-
|
||||
val = qemu_opt_get(opts, "file");
|
||||
if (val) {
|
||||
struct smbios_structure_header *header;
|
||||
- int size;
|
||||
- struct smbios_table *table; /* legacy mode only */
|
||||
+ size_t size;
|
||||
|
||||
if (!qemu_opts_validate(opts, qemu_smbios_file_opts, errp)) {
|
||||
return;
|
||||
@@ -1416,9 +1440,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
* (except in legacy mode, where the second '\0' is implicit and
|
||||
* will be inserted by the BIOS).
|
||||
*/
|
||||
- smbios_tables = g_realloc(smbios_tables, smbios_tables_len + size);
|
||||
- header = (struct smbios_structure_header *)(smbios_tables +
|
||||
- smbios_tables_len);
|
||||
+ usr_blobs = g_realloc(usr_blobs, usr_blobs_len + size);
|
||||
+ header = (struct smbios_structure_header *)(usr_blobs +
|
||||
+ usr_blobs_len);
|
||||
|
||||
if (load_image_size(val, (uint8_t *)header, size) != size) {
|
||||
error_setg(errp, "Failed to load SMBIOS file %s", val);
|
||||
@@ -1439,34 +1463,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
smbios_type4_count++;
|
||||
}
|
||||
|
||||
- smbios_tables_len += size;
|
||||
- if (size > smbios_table_max) {
|
||||
- smbios_table_max = size;
|
||||
+ if (!usr_blobs_sizes) {
|
||||
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
|
||||
}
|
||||
- smbios_table_cnt++;
|
||||
-
|
||||
- /* add a copy of the newly loaded blob to legacy smbios_entries */
|
||||
- /* NOTE: This code runs before smbios_set_defaults(), so we don't
|
||||
- * yet know which mode (legacy vs. aggregate-table) will be
|
||||
- * required. We therefore add the binary blob to both legacy
|
||||
- * (smbios_entries) and aggregate (smbios_tables) tables, and
|
||||
- * delete the one we don't need from smbios_set_defaults(),
|
||||
- * once we know which machine version has been requested.
|
||||
- */
|
||||
- if (!smbios_entries) {
|
||||
- smbios_entries_len = sizeof(uint16_t);
|
||||
- smbios_entries = g_malloc0(smbios_entries_len);
|
||||
+ g_array_append_val(usr_blobs_sizes, size);
|
||||
+ usr_blobs_len += size;
|
||||
+ if (size > usr_table_max) {
|
||||
+ usr_table_max = size;
|
||||
}
|
||||
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
- size + sizeof(*table));
|
||||
- table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
|
||||
- table->header.type = SMBIOS_TABLE_ENTRY;
|
||||
- table->header.length = cpu_to_le16(sizeof(*table) + size);
|
||||
- memcpy(table->data, header, size);
|
||||
- smbios_entries_len += sizeof(*table) + size;
|
||||
- (*(uint16_t *)smbios_entries) =
|
||||
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
- /* end: add a copy of the newly loaded blob to legacy smbios_entries */
|
||||
+ usr_table_cnt++;
|
||||
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,517 +0,0 @@
|
||||
From 7ebb314a4f81d6d1a7dd4980b757fb5e556f5837 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 13 Feb 2024 16:45:18 +0100
|
||||
Subject: [PATCH 13/20] smbios: build legacy mode code only for 'pc' machine
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [11/18] 06e639be03e0d151fb9bcf5f728388edcb84219a
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
basically moving code around without functional change.
|
||||
And exposing some symbols so that they could be shared
|
||||
between smbbios.c and new smbios_legacy.c
|
||||
|
||||
plus some meson magic to build smbios_legacy.c only
|
||||
for 'pc' machine and otherwise replace it with stub
|
||||
if not selected.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Conflicts: hw/smbios/smbios.c
|
||||
context change due to downstream smbios_type2_required
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/Kconfig | 1 +
|
||||
hw/smbios/Kconfig | 2 +
|
||||
hw/smbios/meson.build | 5 +
|
||||
hw/smbios/smbios.c | 163 +-----------------------------
|
||||
hw/smbios/smbios_legacy.c | 179 +++++++++++++++++++++++++++++++++
|
||||
hw/smbios/smbios_legacy_stub.c | 15 +++
|
||||
include/hw/firmware/smbios.h | 5 +
|
||||
7 files changed, 208 insertions(+), 162 deletions(-)
|
||||
create mode 100644 hw/smbios/smbios_legacy.c
|
||||
create mode 100644 hw/smbios/smbios_legacy_stub.c
|
||||
|
||||
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
|
||||
index a1846be6f7..a6ee052f9a 100644
|
||||
--- a/hw/i386/Kconfig
|
||||
+++ b/hw/i386/Kconfig
|
||||
@@ -76,6 +76,7 @@ config I440FX
|
||||
select PIIX
|
||||
select DIMM
|
||||
select SMBIOS
|
||||
+ select SMBIOS_LEGACY
|
||||
select FW_CFG_DMA
|
||||
|
||||
config ISAPC
|
||||
diff --git a/hw/smbios/Kconfig b/hw/smbios/Kconfig
|
||||
index 553adf4bfc..8d989a2f1b 100644
|
||||
--- a/hw/smbios/Kconfig
|
||||
+++ b/hw/smbios/Kconfig
|
||||
@@ -1,2 +1,4 @@
|
||||
config SMBIOS
|
||||
bool
|
||||
+config SMBIOS_LEGACY
|
||||
+ bool
|
||||
diff --git a/hw/smbios/meson.build b/hw/smbios/meson.build
|
||||
index 6eeae4b35c..fcac1d7490 100644
|
||||
--- a/hw/smbios/meson.build
|
||||
+++ b/hw/smbios/meson.build
|
||||
@@ -4,10 +4,15 @@ smbios_ss.add(when: 'CONFIG_IPMI',
|
||||
if_true: files('smbios_type_38.c'),
|
||||
if_false: files('smbios_type_38-stub.c'))
|
||||
|
||||
+smbios_ss.add(when: 'CONFIG_SMBIOS_LEGACY',
|
||||
+ if_true: files('smbios_legacy.c'),
|
||||
+ if_false: files('smbios_legacy_stub.c'))
|
||||
+
|
||||
system_ss.add_all(when: 'CONFIG_SMBIOS', if_true: smbios_ss)
|
||||
system_ss.add(when: 'CONFIG_SMBIOS', if_false: files('smbios-stub.c'))
|
||||
|
||||
system_ss.add(when: 'CONFIG_ALL', if_true: files(
|
||||
'smbios-stub.c',
|
||||
'smbios_type_38-stub.c',
|
||||
+ 'smbios_legacy_stub.c',
|
||||
))
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index eb9927335d..e40204550e 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -31,31 +31,7 @@
|
||||
#include "hw/pci/pci_device.h"
|
||||
#include "smbios_build.h"
|
||||
|
||||
-/* legacy structures and constants for <= 2.0 machines */
|
||||
-struct smbios_header {
|
||||
- uint16_t length;
|
||||
- uint8_t type;
|
||||
-} QEMU_PACKED;
|
||||
-
|
||||
-struct smbios_field {
|
||||
- struct smbios_header header;
|
||||
- uint8_t type;
|
||||
- uint16_t offset;
|
||||
- uint8_t data[];
|
||||
-} QEMU_PACKED;
|
||||
-
|
||||
-struct smbios_table {
|
||||
- struct smbios_header header;
|
||||
- uint8_t data[];
|
||||
-} QEMU_PACKED;
|
||||
-
|
||||
-#define SMBIOS_FIELD_ENTRY 0
|
||||
-#define SMBIOS_TABLE_ENTRY 1
|
||||
-
|
||||
-static uint8_t *smbios_entries;
|
||||
-static size_t smbios_entries_len;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
-/* end: legacy structures & constants for <= 2.0 machines */
|
||||
|
||||
/* Set to true for modern Windows 10 HardwareID-6 compat */
|
||||
static bool smbios_type2_required;
|
||||
@@ -65,7 +41,6 @@ static bool smbios_type2_required;
|
||||
*/
|
||||
uint8_t *usr_blobs;
|
||||
size_t usr_blobs_len;
|
||||
-static GArray *usr_blobs_sizes;
|
||||
static unsigned usr_table_max;
|
||||
static unsigned usr_table_cnt;
|
||||
|
||||
@@ -531,7 +506,7 @@ static void smbios_check_type4_count(uint32_t expected_t4_count)
|
||||
}
|
||||
}
|
||||
|
||||
-static void smbios_validate_table(void)
|
||||
+void smbios_validate_table(void)
|
||||
{
|
||||
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
|
||||
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
|
||||
@@ -541,134 +516,6 @@ static void smbios_validate_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
-/* legacy setup functions for <= 2.0 machines */
|
||||
-static void smbios_add_field(int type, int offset, const void *data, size_t len)
|
||||
-{
|
||||
- struct smbios_field *field;
|
||||
-
|
||||
- if (!smbios_entries) {
|
||||
- smbios_entries_len = sizeof(uint16_t);
|
||||
- smbios_entries = g_malloc0(smbios_entries_len);
|
||||
- }
|
||||
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
- sizeof(*field) + len);
|
||||
- field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
|
||||
- field->header.type = SMBIOS_FIELD_ENTRY;
|
||||
- field->header.length = cpu_to_le16(sizeof(*field) + len);
|
||||
-
|
||||
- field->type = type;
|
||||
- field->offset = cpu_to_le16(offset);
|
||||
- memcpy(field->data, data, len);
|
||||
-
|
||||
- smbios_entries_len += sizeof(*field) + len;
|
||||
- (*(uint16_t *)smbios_entries) =
|
||||
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
-}
|
||||
-
|
||||
-static void smbios_maybe_add_str(int type, int offset, const char *data)
|
||||
-{
|
||||
- if (data) {
|
||||
- smbios_add_field(type, offset, data, strlen(data) + 1);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void smbios_build_type_0_fields(void)
|
||||
-{
|
||||
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
|
||||
- smbios_type0.vendor);
|
||||
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
|
||||
- smbios_type0.version);
|
||||
- smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
|
||||
- bios_release_date_str),
|
||||
- smbios_type0.date);
|
||||
- if (smbios_type0.have_major_minor) {
|
||||
- smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
- system_bios_major_release),
|
||||
- &smbios_type0.major, 1);
|
||||
- smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
- system_bios_minor_release),
|
||||
- &smbios_type0.minor, 1);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void smbios_build_type_1_fields(void)
|
||||
-{
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
|
||||
- smbios_type1.manufacturer);
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
|
||||
- smbios_type1.product);
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
|
||||
- smbios_type1.version);
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
|
||||
- smbios_type1.serial);
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
|
||||
- smbios_type1.sku);
|
||||
- smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
|
||||
- smbios_type1.family);
|
||||
- if (qemu_uuid_set) {
|
||||
- /* We don't encode the UUID in the "wire format" here because this
|
||||
- * function is for legacy mode and needs to keep the guest ABI, and
|
||||
- * because we don't know what's the SMBIOS version advertised by the
|
||||
- * BIOS.
|
||||
- */
|
||||
- smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
|
||||
- &qemu_uuid, 16);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
-{
|
||||
- int i;
|
||||
- size_t usr_offset;
|
||||
-
|
||||
- /* also complain if fields were given for types > 1 */
|
||||
- if (find_next_bit(smbios_have_fields_bitmap,
|
||||
- SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
|
||||
- error_report("can't process fields for smbios "
|
||||
- "types > 1 on machine versions < 2.1!");
|
||||
- exit(1);
|
||||
- }
|
||||
-
|
||||
- if (test_bit(4, smbios_have_binfile_bitmap)) {
|
||||
- error_report("can't process table for smbios "
|
||||
- "type 4 on machine versions < 2.1!");
|
||||
- exit(1);
|
||||
- }
|
||||
-
|
||||
- g_free(smbios_entries);
|
||||
- smbios_entries_len = sizeof(uint16_t);
|
||||
- smbios_entries = g_malloc0(smbios_entries_len);
|
||||
-
|
||||
- for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
|
||||
- i++)
|
||||
- {
|
||||
- struct smbios_table *table;
|
||||
- struct smbios_structure_header *header;
|
||||
- size_t size = g_array_index(usr_blobs_sizes, size_t, i);
|
||||
-
|
||||
- header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
|
||||
- smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
- size + sizeof(*table));
|
||||
- table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
|
||||
- table->header.type = SMBIOS_TABLE_ENTRY;
|
||||
- table->header.length = cpu_to_le16(sizeof(*table) + size);
|
||||
- memcpy(table->data, header, size);
|
||||
- smbios_entries_len += sizeof(*table) + size;
|
||||
- (*(uint16_t *)smbios_entries) =
|
||||
- cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
- usr_offset += size;
|
||||
- }
|
||||
-
|
||||
- smbios_build_type_0_fields();
|
||||
- smbios_build_type_1_fields();
|
||||
- smbios_validate_table();
|
||||
- *length = smbios_entries_len;
|
||||
- return smbios_entries;
|
||||
-}
|
||||
-/* end: legacy setup functions for <= 2.0 machines */
|
||||
-
|
||||
-
|
||||
bool smbios_skip_table(uint8_t type, bool required_table)
|
||||
{
|
||||
if (test_bit(type, smbios_have_binfile_bitmap)) {
|
||||
@@ -1418,14 +1265,6 @@ static bool save_opt_list(size_t *ndest, char ***dest, QemuOpts *opts,
|
||||
return true;
|
||||
}
|
||||
|
||||
-static void smbios_add_usr_blob_size(size_t size)
|
||||
-{
|
||||
- if (!usr_blobs_sizes) {
|
||||
- usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
|
||||
- }
|
||||
- g_array_append_val(usr_blobs_sizes, size);
|
||||
-}
|
||||
-
|
||||
void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
{
|
||||
const char *val;
|
||||
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
|
||||
new file mode 100644
|
||||
index 0000000000..21f143e738
|
||||
--- /dev/null
|
||||
+++ b/hw/smbios/smbios_legacy.c
|
||||
@@ -0,0 +1,179 @@
|
||||
+/*
|
||||
+ * SMBIOS legacy support
|
||||
+ *
|
||||
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
|
||||
+ * Copyright (C) 2013 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Alex Williamson <alex.williamson@hp.com>
|
||||
+ * Markus Armbruster <armbru@redhat.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
+ * the COPYING file in the top-level directory.
|
||||
+ *
|
||||
+ * Contributions after 2012-01-13 are licensed under the terms of the
|
||||
+ * GNU GPL, version 2 or (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qemu/bswap.h"
|
||||
+#include "hw/firmware/smbios.h"
|
||||
+#include "sysemu/sysemu.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+struct smbios_header {
|
||||
+ uint16_t length;
|
||||
+ uint8_t type;
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+struct smbios_field {
|
||||
+ struct smbios_header header;
|
||||
+ uint8_t type;
|
||||
+ uint16_t offset;
|
||||
+ uint8_t data[];
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+struct smbios_table {
|
||||
+ struct smbios_header header;
|
||||
+ uint8_t data[];
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+#define SMBIOS_FIELD_ENTRY 0
|
||||
+#define SMBIOS_TABLE_ENTRY 1
|
||||
+
|
||||
+static uint8_t *smbios_entries;
|
||||
+static size_t smbios_entries_len;
|
||||
+GArray *usr_blobs_sizes;
|
||||
+
|
||||
+void smbios_add_usr_blob_size(size_t size)
|
||||
+{
|
||||
+ if (!usr_blobs_sizes) {
|
||||
+ usr_blobs_sizes = g_array_new(false, false, sizeof(size_t));
|
||||
+ }
|
||||
+ g_array_append_val(usr_blobs_sizes, size);
|
||||
+}
|
||||
+
|
||||
+static void smbios_add_field(int type, int offset, const void *data, size_t len)
|
||||
+{
|
||||
+ struct smbios_field *field;
|
||||
+
|
||||
+ if (!smbios_entries) {
|
||||
+ smbios_entries_len = sizeof(uint16_t);
|
||||
+ smbios_entries = g_malloc0(smbios_entries_len);
|
||||
+ }
|
||||
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
+ sizeof(*field) + len);
|
||||
+ field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
|
||||
+ field->header.type = SMBIOS_FIELD_ENTRY;
|
||||
+ field->header.length = cpu_to_le16(sizeof(*field) + len);
|
||||
+
|
||||
+ field->type = type;
|
||||
+ field->offset = cpu_to_le16(offset);
|
||||
+ memcpy(field->data, data, len);
|
||||
+
|
||||
+ smbios_entries_len += sizeof(*field) + len;
|
||||
+ (*(uint16_t *)smbios_entries) =
|
||||
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
+}
|
||||
+
|
||||
+static void smbios_maybe_add_str(int type, int offset, const char *data)
|
||||
+{
|
||||
+ if (data) {
|
||||
+ smbios_add_field(type, offset, data, strlen(data) + 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void smbios_build_type_0_fields(void)
|
||||
+{
|
||||
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
|
||||
+ smbios_type0.vendor);
|
||||
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
|
||||
+ smbios_type0.version);
|
||||
+ smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
|
||||
+ bios_release_date_str),
|
||||
+ smbios_type0.date);
|
||||
+ if (smbios_type0.have_major_minor) {
|
||||
+ smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
+ system_bios_major_release),
|
||||
+ &smbios_type0.major, 1);
|
||||
+ smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
+ system_bios_minor_release),
|
||||
+ &smbios_type0.minor, 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void smbios_build_type_1_fields(void)
|
||||
+{
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
|
||||
+ smbios_type1.manufacturer);
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
|
||||
+ smbios_type1.product);
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
|
||||
+ smbios_type1.version);
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
|
||||
+ smbios_type1.serial);
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
|
||||
+ smbios_type1.sku);
|
||||
+ smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
|
||||
+ smbios_type1.family);
|
||||
+ if (qemu_uuid_set) {
|
||||
+ /*
|
||||
+ * We don't encode the UUID in the "wire format" here because this
|
||||
+ * function is for legacy mode and needs to keep the guest ABI, and
|
||||
+ * because we don't know what's the SMBIOS version advertised by the
|
||||
+ * BIOS.
|
||||
+ */
|
||||
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid),
|
||||
+ &qemu_uuid, 16);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
+{
|
||||
+ int i;
|
||||
+ size_t usr_offset;
|
||||
+
|
||||
+ /* complain if fields were given for types > 1 */
|
||||
+ if (find_next_bit(smbios_have_fields_bitmap,
|
||||
+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
|
||||
+ error_report("can't process fields for smbios "
|
||||
+ "types > 1 on machine versions < 2.1!");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (test_bit(4, smbios_have_binfile_bitmap)) {
|
||||
+ error_report("can't process table for smbios "
|
||||
+ "type 4 on machine versions < 2.1!");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ g_free(smbios_entries);
|
||||
+ smbios_entries_len = sizeof(uint16_t);
|
||||
+ smbios_entries = g_malloc0(smbios_entries_len);
|
||||
+
|
||||
+ for (i = 0, usr_offset = 0; usr_blobs_sizes && i < usr_blobs_sizes->len;
|
||||
+ i++)
|
||||
+ {
|
||||
+ struct smbios_table *table;
|
||||
+ struct smbios_structure_header *header;
|
||||
+ size_t size = g_array_index(usr_blobs_sizes, size_t, i);
|
||||
+
|
||||
+ header = (struct smbios_structure_header *)(usr_blobs + usr_offset);
|
||||
+ smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
|
||||
+ size + sizeof(*table));
|
||||
+ table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
|
||||
+ table->header.type = SMBIOS_TABLE_ENTRY;
|
||||
+ table->header.length = cpu_to_le16(sizeof(*table) + size);
|
||||
+ memcpy(table->data, header, size);
|
||||
+ smbios_entries_len += sizeof(*table) + size;
|
||||
+ (*(uint16_t *)smbios_entries) =
|
||||
+ cpu_to_le16(le16_to_cpu(*(uint16_t *)smbios_entries) + 1);
|
||||
+ usr_offset += size;
|
||||
+ }
|
||||
+
|
||||
+ smbios_build_type_0_fields();
|
||||
+ smbios_build_type_1_fields();
|
||||
+ smbios_validate_table();
|
||||
+ *length = smbios_entries_len;
|
||||
+ return smbios_entries;
|
||||
+}
|
||||
diff --git a/hw/smbios/smbios_legacy_stub.c b/hw/smbios/smbios_legacy_stub.c
|
||||
new file mode 100644
|
||||
index 0000000000..f29b15316c
|
||||
--- /dev/null
|
||||
+++ b/hw/smbios/smbios_legacy_stub.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/*
|
||||
+ * IPMI SMBIOS firmware handling
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Igor Mammedov, Red Hat, Inc.
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/firmware/smbios.h"
|
||||
+
|
||||
+void smbios_add_usr_blob_size(size_t size)
|
||||
+{
|
||||
+}
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 333de0d5fc..92e9aba415 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -17,6 +17,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+extern uint8_t *usr_blobs;
|
||||
+extern GArray *usr_blobs_sizes;
|
||||
+
|
||||
typedef struct {
|
||||
const char *vendor, *version, *date;
|
||||
bool have_major_minor, uefi;
|
||||
@@ -323,6 +326,8 @@ struct smbios_type_127 {
|
||||
struct smbios_structure_header header;
|
||||
} QEMU_PACKED;
|
||||
|
||||
+void smbios_validate_table(void);
|
||||
+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,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,65 +0,0 @@
|
||||
From 07f6ef2d032cda3e746ac2477c0a9bc1ac636f45 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Fri, 29 Dec 2023 14:08:13 +0100
|
||||
Subject: [PATCH 06/20] smbios: cleanup smbios_get_tables() from legacy
|
||||
handling
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [4/18] a5e09ce1df72293fecad863edd146a8c4b1a734f
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
smbios_get_tables() bails out right away if leagacy mode is enabled
|
||||
and won't generate any SMBIOS tables. At the same time x86 specific
|
||||
fw_cfg_build_smbios() will genarate legacy tables and then proceed
|
||||
to preparing temporary mem_array for useless call to
|
||||
smbios_get_tables() and then discard it.
|
||||
|
||||
Drop legacy related check in smbios_get_tables() and return from
|
||||
fw_cfg_build_smbios() early if legacy tables where built without
|
||||
proceeding to non legacy part of the function.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 1 +
|
||||
hw/smbios/smbios.c | 6 ------
|
||||
2 files changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 6a5466faf0..ed72b1442d 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -76,6 +76,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
if (smbios_tables) {
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
|
||||
smbios_tables, smbios_tables_len);
|
||||
+ return;
|
||||
}
|
||||
|
||||
/* build the array of physical mem area from e820 table */
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 074705fa4c..b13e40bae2 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -1244,12 +1244,6 @@ void smbios_get_tables(MachineState *ms,
|
||||
{
|
||||
unsigned i, dimm_cnt, offset;
|
||||
|
||||
- if (smbios_legacy) {
|
||||
- *tables = *anchor = NULL;
|
||||
- *tables_len = *anchor_len = 0;
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (!smbios_immutable) {
|
||||
smbios_build_type_0_table();
|
||||
smbios_build_type_1_table();
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,38 +0,0 @@
|
||||
From c0282a842a912aacac28a6ae229de5854c3fb5df Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Mon, 26 Feb 2024 13:20:22 +0100
|
||||
Subject: [PATCH 16/20] smbios: clear smbios_type4_count before building tables
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [14/18] f809595d2934ae975c0b7d17a4a79645e062ba42
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
it will help to keep type 4 tables accounting correct in case
|
||||
SMBIOS tables are built multiple times.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 7e32430b85..4521ea386c 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -1111,6 +1111,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
|
||||
g_free(smbios_tables);
|
||||
+ smbios_type4_count = 0;
|
||||
smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
|
||||
smbios_tables_len = usr_blobs_len;
|
||||
smbios_table_max = usr_table_max;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,133 +0,0 @@
|
||||
From 2b76d95ec07aba6d96070ee90c5015c1676be091 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 13 Feb 2024 16:25:54 +0100
|
||||
Subject: [PATCH 10/20] smbios: don't check type4 structures in legacy mode
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [8/18] c1f8409ea0d916f333c9373535bf21b521c62855
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
legacy mode doesn't support structures of type 2 and more,
|
||||
and CLI has a check for '-smbios type' option, however it's
|
||||
still possible to sneak in type4 as a blob with '-smbios file'
|
||||
option. However doing the later makes SMBIOS tables broken
|
||||
since SeaBIOS doesn't expect that.
|
||||
|
||||
Rather than trying to add support for type4 to legacy code
|
||||
(both QEMU and SeaBIOS), simplify smbios_get_table_legacy()
|
||||
by dropping not relevant check in legacy code and error out
|
||||
on type4 blob.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
|
||||
Conflicts: include/hw/firmware/smbios.h
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
|
||||
Please enter the commit message for your changes. Lines starting
|
||||
---
|
||||
hw/i386/fw_cfg.c | 3 +--
|
||||
hw/smbios/smbios.c | 18 ++++++++++++++----
|
||||
include/hw/firmware/smbios.h | 2 +-
|
||||
3 files changed, 16 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index bb7149c4c3..a25793a68f 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -73,8 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||
|
||||
if (pcmc->smbios_legacy_mode) {
|
||||
- smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
|
||||
- &smbios_tables_len);
|
||||
+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
|
||||
smbios_tables, smbios_tables_len);
|
||||
return;
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index d8d68716d4..441517cf24 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -530,14 +530,17 @@ opts_init(smbios_register_config);
|
||||
*/
|
||||
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
|
||||
|
||||
-static void smbios_validate_table(uint32_t expected_t4_count)
|
||||
+static void smbios_check_type4_count(uint32_t expected_t4_count)
|
||||
{
|
||||
if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
|
||||
error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
|
||||
expected_t4_count, smbios_type4_count);
|
||||
exit(1);
|
||||
}
|
||||
+}
|
||||
|
||||
+static void smbios_validate_table(void)
|
||||
+{
|
||||
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
|
||||
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
|
||||
error_report("SMBIOS 2.1 table length %zu exceeds %d",
|
||||
@@ -622,7 +625,7 @@ static void smbios_build_type_1_fields(void)
|
||||
}
|
||||
}
|
||||
|
||||
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
+uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
{
|
||||
int i;
|
||||
size_t usr_offset;
|
||||
@@ -635,6 +638,12 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+ if (test_bit(4, have_binfile_bitmap)) {
|
||||
+ error_report("can't process table for smbios "
|
||||
+ "type 4 on machine versions < 2.1!");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
g_free(smbios_entries);
|
||||
smbios_entries_len = sizeof(uint16_t);
|
||||
smbios_entries = g_malloc0(smbios_entries_len);
|
||||
@@ -661,7 +670,7 @@ uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
|
||||
smbios_build_type_0_fields();
|
||||
smbios_build_type_1_fields();
|
||||
- smbios_validate_table(expected_t4_count);
|
||||
+ smbios_validate_table();
|
||||
*length = smbios_entries_len;
|
||||
return smbios_entries;
|
||||
}
|
||||
@@ -1319,7 +1328,8 @@ void smbios_get_tables(MachineState *ms,
|
||||
smbios_build_type_41_table(errp);
|
||||
smbios_build_type_127_table();
|
||||
|
||||
- smbios_validate_table(ms->smp.sockets);
|
||||
+ smbios_check_type4_count(ms->smp.sockets);
|
||||
+ smbios_validate_table();
|
||||
smbios_entry_point_setup();
|
||||
|
||||
/* return tables blob and entry point (anchor), and their sizes */
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index b9fc9a0f42..d55018e5e3 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -315,7 +315,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
const char *stream_version);
|
||||
-uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
|
||||
+uint8_t *smbios_get_table_legacy(size_t *length);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,72 +0,0 @@
|
||||
From bbb2d260e6f33380b9df28c74421055bd8dccda5 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Mon, 26 Feb 2024 12:59:33 +0100
|
||||
Subject: [PATCH 19/20] smbios: error out when building type 4 table is not
|
||||
possible
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [17/18] 86b1c67bfbe9c0c14a190cd1204b6ccd1de1630f
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
If SMBIOS v2 version is requested but number of cores/threads
|
||||
are more than it's possible to describe with v2, error out
|
||||
instead of silently ignoring the fact and filling core/thread
|
||||
count with bogus values.
|
||||
|
||||
This will help caller to decide if it should fallback to
|
||||
SMBIOSv3 when smbios-entry-point-type='auto'
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 3d9dcb0d31..637aa952f5 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -655,7 +655,8 @@ static void smbios_build_type_3_table(void)
|
||||
}
|
||||
|
||||
static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
|
||||
- SmbiosEntryPointType ep_type)
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
+ Error **errp)
|
||||
{
|
||||
char sock_str[128];
|
||||
size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
|
||||
@@ -709,6 +710,12 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
|
||||
if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
|
||||
t->core_count2 = t->core_enabled2 = cpu_to_le16(cores_per_socket);
|
||||
t->thread_count2 = cpu_to_le16(threads_per_socket);
|
||||
+ } else if (t->core_count == 0xFF || t->thread_count == 0xFF) {
|
||||
+ error_setg(errp, "SMBIOS 2.0 doesn't support number of processor "
|
||||
+ "cores/threads more than 255, use "
|
||||
+ "-machine smbios-entry-point-type=64 option to enable "
|
||||
+ "SMBIOS 3.0 support");
|
||||
+ return;
|
||||
}
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
@@ -1126,7 +1133,10 @@ static bool smbios_get_tables_ep(MachineState *ms,
|
||||
assert(ms->smp.sockets >= 1);
|
||||
|
||||
for (i = 0; i < ms->smp.sockets; i++) {
|
||||
- smbios_build_type_4_table(ms, i, ep_type);
|
||||
+ smbios_build_type_4_table(ms, i, ep_type, errp);
|
||||
+ if (*errp) {
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
}
|
||||
|
||||
smbios_build_type_8_table();
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,48 +0,0 @@
|
||||
From c083959c963fde33f4769fd4c6e122dd16ce6d3c Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Wed, 21 Feb 2024 16:04:36 +0100
|
||||
Subject: [PATCH 17/20] smbios: extend smbios-entry-point-type with 'auto'
|
||||
value
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [15/18] 202563dcf77e062a238aa2a10ec14c25d3f5a7d0
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
later patches will use it to pick SMBIOS version at runtime
|
||||
depending on configuration.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Acked-by: Markus Armbruster <armbru@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
qapi/machine.json | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qapi/machine.json b/qapi/machine.json
|
||||
index b6d634b30d..99f6368fa6 100644
|
||||
--- a/qapi/machine.json
|
||||
+++ b/qapi/machine.json
|
||||
@@ -1788,10 +1788,13 @@
|
||||
#
|
||||
# @64: SMBIOS version 3.0 (64-bit) Entry Point
|
||||
#
|
||||
+# @auto: Either 2.x or 3.x SMBIOS version, 2.x if configuration can be
|
||||
+# described by it and 3.x otherwise (since: 9.0)
|
||||
+#
|
||||
# Since: 7.0
|
||||
##
|
||||
{ 'enum': 'SmbiosEntryPointType',
|
||||
- 'data': [ '32', '64' ] }
|
||||
+ 'data': [ '32', '64', 'auto' ] }
|
||||
|
||||
##
|
||||
# @MemorySizeConfiguration:
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,281 +0,0 @@
|
||||
From be0abbf3f7845847b46486704c46c5de5a2b2323 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Mon, 26 Feb 2024 13:49:14 +0100
|
||||
Subject: [PATCH 15/20] smbios: get rid of global smbios_ep_type
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [13/18] 2e838ed0d03989e2e4ee08041b5ba64d5d7f5820
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
Conflicts: hw/arm/virt.c, hw/i386/fw_cfg.c, hw/riscv/virt.c, hw/smbios/smbios.c,
|
||||
include/hw/firmware/smbios.h
|
||||
due to downstream specific smbios_set_defaults()
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 4 ++--
|
||||
hw/i386/fw_cfg.c | 6 +++---
|
||||
hw/i386/fw_cfg.h | 3 ++-
|
||||
hw/i386/pc.c | 2 +-
|
||||
hw/loongarch/virt.c | 7 ++++---
|
||||
hw/smbios/smbios.c | 26 ++++++++++++++------------
|
||||
hw/smbios/smbios_legacy.c | 2 +-
|
||||
include/hw/firmware/smbios.h | 4 ++--
|
||||
8 files changed, 29 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index e5cfc19c08..e4a66affcb 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1695,14 +1695,14 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
|
||||
smbios_set_defaults("QEMU", product,
|
||||
vmc->smbios_old_sys_ver ? "1.0" : mc->name,
|
||||
- true, SMBIOS_ENTRY_POINT_TYPE_64,
|
||||
+ true,
|
||||
NULL, NULL);
|
||||
|
||||
/* build the array of physical mem area from base_memmap */
|
||||
mem_array.address = vms->memmap[VIRT_MEM].base;
|
||||
mem_array.length = ms->ram_size;
|
||||
|
||||
- smbios_get_tables(ms, &mem_array, 1,
|
||||
+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, &mem_array, 1,
|
||||
&smbios_tables, &smbios_tables_len,
|
||||
&smbios_anchor, &smbios_anchor_len,
|
||||
&error_fatal);
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index bdc3cc4556..58429bb78d 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -48,7 +48,8 @@ const char *fw_cfg_arch_key_name(uint16_t key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
+ SmbiosEntryPointType ep_type)
|
||||
{
|
||||
#ifdef CONFIG_SMBIOS
|
||||
uint8_t *smbios_tables, *smbios_anchor;
|
||||
@@ -64,7 +65,6 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
/* These values are guest ABI, do not change */
|
||||
smbios_set_defaults("QEMU", mc->desc, mc->name,
|
||||
pcmc->smbios_uuid_encoded,
|
||||
- pcms->smbios_entry_point_type,
|
||||
pcmc->smbios_stream_product,
|
||||
pcmc->smbios_stream_version);
|
||||
}
|
||||
@@ -91,7 +91,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
array_count++;
|
||||
}
|
||||
}
|
||||
- smbios_get_tables(ms, mem_array, array_count,
|
||||
+ smbios_get_tables(ms, ep_type, mem_array, array_count,
|
||||
&smbios_tables, &smbios_tables_len,
|
||||
&smbios_anchor, &smbios_anchor_len,
|
||||
&error_fatal);
|
||||
diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h
|
||||
index 1e1de6b4a3..92e310f5fd 100644
|
||||
--- a/hw/i386/fw_cfg.h
|
||||
+++ b/hw/i386/fw_cfg.h
|
||||
@@ -23,7 +23,8 @@
|
||||
FWCfgState *fw_cfg_arch_create(MachineState *ms,
|
||||
uint16_t boot_cpus,
|
||||
uint16_t apic_id_limit);
|
||||
-void fw_cfg_build_smbios(PCMachineState *ms, FWCfgState *fw_cfg);
|
||||
+void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg,
|
||||
+ SmbiosEntryPointType ep_type);
|
||||
void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg);
|
||||
void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg);
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 16de2a59e8..ae6777fc1a 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -847,7 +847,7 @@ void pc_machine_done(Notifier *notifier, void *data)
|
||||
|
||||
acpi_setup();
|
||||
if (x86ms->fw_cfg) {
|
||||
- fw_cfg_build_smbios(pcms, x86ms->fw_cfg);
|
||||
+ fw_cfg_build_smbios(pcms, x86ms->fw_cfg, pcms->smbios_entry_point_type);
|
||||
fw_cfg_build_feature_control(MACHINE(pcms), x86ms->fw_cfg);
|
||||
/* update FW_CFG_NB_CPUS to account for -device added CPUs */
|
||||
fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 7358a023d3..77956b5ada 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -320,10 +320,11 @@ static void virt_build_smbios(LoongArchMachineState *lams)
|
||||
return;
|
||||
}
|
||||
|
||||
- smbios_set_defaults("QEMU", product, mc->name,
|
||||
- true, SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
+ smbios_set_defaults("QEMU", product, mc->name, true);
|
||||
|
||||
- smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
|
||||
+ smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
|
||||
+ NULL, 0,
|
||||
+ &smbios_tables, &smbios_tables_len,
|
||||
&smbios_anchor, &smbios_anchor_len, &error_fatal);
|
||||
|
||||
if (smbios_anchor) {
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index b5745c6c2d..7e32430b85 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -47,7 +47,6 @@ uint8_t *smbios_tables;
|
||||
size_t smbios_tables_len;
|
||||
unsigned smbios_table_max;
|
||||
unsigned smbios_table_cnt;
|
||||
-static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_32;
|
||||
|
||||
static SmbiosEntryPoint ep;
|
||||
|
||||
@@ -506,9 +505,9 @@ static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp)
|
||||
return true;
|
||||
}
|
||||
|
||||
-bool smbios_validate_table(Error **errp)
|
||||
+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp)
|
||||
{
|
||||
- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
|
||||
+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
|
||||
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
|
||||
error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d",
|
||||
smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
|
||||
@@ -655,14 +654,15 @@ static void smbios_build_type_3_table(void)
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
}
|
||||
|
||||
-static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
|
||||
+static void smbios_build_type_4_table(MachineState *ms, unsigned instance,
|
||||
+ SmbiosEntryPointType ep_type)
|
||||
{
|
||||
char sock_str[128];
|
||||
size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
|
||||
unsigned threads_per_socket;
|
||||
unsigned cores_per_socket;
|
||||
|
||||
- if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
|
||||
+ if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
|
||||
tbl_len = SMBIOS_TYPE_4_LEN_V30;
|
||||
}
|
||||
|
||||
@@ -991,13 +991,11 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
const char *version,
|
||||
bool uuid_encoded,
|
||||
- SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
const char *stream_version)
|
||||
{
|
||||
smbios_have_defaults = true;
|
||||
smbios_uuid_encoded = uuid_encoded;
|
||||
- smbios_ep_type = ep_type;
|
||||
|
||||
/*
|
||||
* If @stream_product & @stream_version are non-NULL, then
|
||||
@@ -1048,9 +1046,9 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
SMBIOS_SET_DEFAULT(type17.manufacturer, manufacturer);
|
||||
}
|
||||
|
||||
-static void smbios_entry_point_setup(void)
|
||||
+static void smbios_entry_point_setup(SmbiosEntryPointType ep_type)
|
||||
{
|
||||
- switch (smbios_ep_type) {
|
||||
+ switch (ep_type) {
|
||||
case SMBIOS_ENTRY_POINT_TYPE_32:
|
||||
memcpy(ep.ep21.anchor_string, "_SM_", 4);
|
||||
memcpy(ep.ep21.intermediate_anchor_string, "_DMI_", 5);
|
||||
@@ -1100,6 +1098,7 @@ static void smbios_entry_point_setup(void)
|
||||
}
|
||||
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
uint8_t **tables, size_t *tables_len,
|
||||
@@ -1108,6 +1107,9 @@ void smbios_get_tables(MachineState *ms,
|
||||
{
|
||||
unsigned i, dimm_cnt, offset;
|
||||
|
||||
+ assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ||
|
||||
+ ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
+
|
||||
g_free(smbios_tables);
|
||||
smbios_tables = g_memdup2(usr_blobs, usr_blobs_len);
|
||||
smbios_tables_len = usr_blobs_len;
|
||||
@@ -1122,7 +1124,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
assert(ms->smp.sockets >= 1);
|
||||
|
||||
for (i = 0; i < ms->smp.sockets; i++) {
|
||||
- smbios_build_type_4_table(ms, i);
|
||||
+ smbios_build_type_4_table(ms, i, ep_type);
|
||||
}
|
||||
|
||||
smbios_build_type_8_table();
|
||||
@@ -1171,10 +1173,10 @@ void smbios_get_tables(MachineState *ms,
|
||||
if (!smbios_check_type4_count(ms->smp.sockets, errp)) {
|
||||
goto err_exit;
|
||||
}
|
||||
- if (!smbios_validate_table(errp)) {
|
||||
+ if (!smbios_validate_table(ep_type, errp)) {
|
||||
goto err_exit;
|
||||
}
|
||||
- smbios_entry_point_setup();
|
||||
+ smbios_entry_point_setup(ep_type);
|
||||
|
||||
/* return tables blob and entry point (anchor), and their sizes */
|
||||
*tables = smbios_tables;
|
||||
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
|
||||
index a6544bf55a..06907cd16c 100644
|
||||
--- a/hw/smbios/smbios_legacy.c
|
||||
+++ b/hw/smbios/smbios_legacy.c
|
||||
@@ -173,7 +173,7 @@ uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
|
||||
|
||||
smbios_build_type_0_fields();
|
||||
smbios_build_type_1_fields();
|
||||
- if (!smbios_validate_table(errp)) {
|
||||
+ if (!smbios_validate_table(SMBIOS_ENTRY_POINT_TYPE_32, errp)) {
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 44af3a0d82..781298f594 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -326,18 +326,18 @@ struct smbios_type_127 {
|
||||
struct smbios_structure_header header;
|
||||
} QEMU_PACKED;
|
||||
|
||||
-bool smbios_validate_table(Error **errp);
|
||||
+bool smbios_validate_table(SmbiosEntryPointType ep_type, Error **errp);
|
||||
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,
|
||||
bool uuid_encoded,
|
||||
- SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
const char *stream_version);
|
||||
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
uint8_t **tables, size_t *tables_len,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,198 +0,0 @@
|
||||
From 0802fa7199c8085d018fc38dd4beaa5062d383d1 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Fri, 29 Dec 2023 15:37:29 +0100
|
||||
Subject: [PATCH 08/20] smbios: get rid of smbios_legacy global
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [6/18] 684dd1dca8d611c6de97b26ef8c1cda6ca509d54
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
clean up smbios_set_defaults() which is reused by legacy
|
||||
and non legacy machines from being aware of 'legacy' notion
|
||||
and need to turn it off. And push legacy handling up to
|
||||
PC machine code where it's relevant.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Acked-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
|
||||
Conflicts: hw/arm/virt.c, hw/i386/fw_cfg.c, hw/loongarch/virt.c,
|
||||
hw/smbios/smbios.c, include/hw/firmware/smbios.h
|
||||
due to downstream specifc signature of smbios_set_defaults()
|
||||
PS:
|
||||
while fixing conflicts move RHEL specific
|
||||
smbios_stream_product/smbios_stream_version
|
||||
at the end of arguments list
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/arm/virt.c | 5 +++--
|
||||
hw/i386/fw_cfg.c | 11 +++++-----
|
||||
hw/loongarch/virt.c | 2 +-
|
||||
hw/smbios/smbios.c | 39 ++++++++++++++++--------------------
|
||||
include/hw/firmware/smbios.h | 6 +++---
|
||||
5 files changed, 30 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||||
index 943c563391..e5cfc19c08 100644
|
||||
--- a/hw/arm/virt.c
|
||||
+++ b/hw/arm/virt.c
|
||||
@@ -1694,8 +1694,9 @@ static void virt_build_smbios(VirtMachineState *vms)
|
||||
}
|
||||
|
||||
smbios_set_defaults("QEMU", product,
|
||||
- vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
|
||||
- true, NULL, NULL, SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
+ vmc->smbios_old_sys_ver ? "1.0" : mc->name,
|
||||
+ true, SMBIOS_ENTRY_POINT_TYPE_64,
|
||||
+ NULL, NULL);
|
||||
|
||||
/* build the array of physical mem area from base_memmap */
|
||||
mem_array.address = vms->memmap[VIRT_MEM].base;
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index 79ff7f7225..bb7149c4c3 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -63,17 +63,18 @@ 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,
|
||||
- pcmc->smbios_legacy_mode, pcmc->smbios_uuid_encoded,
|
||||
+ pcmc->smbios_uuid_encoded,
|
||||
+ pcms->smbios_entry_point_type,
|
||||
pcmc->smbios_stream_product,
|
||||
- pcmc->smbios_stream_version,
|
||||
- pcms->smbios_entry_point_type);
|
||||
+ pcmc->smbios_stream_version);
|
||||
}
|
||||
|
||||
/* tell smbios about cpuid version and features */
|
||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||
|
||||
- smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
|
||||
- if (smbios_tables) {
|
||||
+ if (pcmc->smbios_legacy_mode) {
|
||||
+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus,
|
||||
+ &smbios_tables_len);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
|
||||
smbios_tables, smbios_tables_len);
|
||||
return;
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 4b7dc67a2d..7358a023d3 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -320,7 +320,7 @@ static void virt_build_smbios(LoongArchMachineState *lams)
|
||||
return;
|
||||
}
|
||||
|
||||
- smbios_set_defaults("QEMU", product, mc->name, false,
|
||||
+ smbios_set_defaults("QEMU", product, mc->name,
|
||||
true, SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
|
||||
smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 8129d396d1..0c8c439859 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -54,7 +54,6 @@ struct smbios_table {
|
||||
|
||||
static uint8_t *smbios_entries;
|
||||
static size_t smbios_entries_len;
|
||||
-static bool smbios_legacy = true;
|
||||
static bool smbios_uuid_encoded = true;
|
||||
/* end: legacy structures & constants for <= 2.0 machines */
|
||||
|
||||
@@ -618,9 +617,16 @@ static void smbios_build_type_1_fields(void)
|
||||
|
||||
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
{
|
||||
- if (!smbios_legacy) {
|
||||
- *length = 0;
|
||||
- return NULL;
|
||||
+ /* drop unwanted version of command-line file blob(s) */
|
||||
+ g_free(smbios_tables);
|
||||
+ smbios_tables = NULL;
|
||||
+
|
||||
+ /* also complain if fields were given for types > 1 */
|
||||
+ if (find_next_bit(have_fields_bitmap,
|
||||
+ SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
|
||||
+ error_report("can't process fields for smbios "
|
||||
+ "types > 1 on machine versions < 2.1!");
|
||||
+ exit(1);
|
||||
}
|
||||
|
||||
if (!smbios_immutable) {
|
||||
@@ -1107,31 +1113,16 @@ void smbios_set_cpuid(uint32_t version, uint32_t features)
|
||||
}
|
||||
|
||||
void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
- const char *version, bool legacy_mode,
|
||||
+ const char *version,
|
||||
bool uuid_encoded,
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
- const char *stream_version,
|
||||
- SmbiosEntryPointType ep_type)
|
||||
+ const char *stream_version)
|
||||
{
|
||||
smbios_have_defaults = true;
|
||||
- smbios_legacy = legacy_mode;
|
||||
smbios_uuid_encoded = uuid_encoded;
|
||||
smbios_ep_type = ep_type;
|
||||
|
||||
- /* drop unwanted version of command-line file blob(s) */
|
||||
- if (smbios_legacy) {
|
||||
- g_free(smbios_tables);
|
||||
- /* in legacy mode, also complain if fields were given for types > 1 */
|
||||
- if (find_next_bit(have_fields_bitmap,
|
||||
- SMBIOS_MAX_TYPE+1, 2) < SMBIOS_MAX_TYPE+1) {
|
||||
- error_report("can't process fields for smbios "
|
||||
- "types > 1 on machine versions < 2.1!");
|
||||
- exit(1);
|
||||
- }
|
||||
- } else {
|
||||
- g_free(smbios_entries);
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* If @stream_product & @stream_version are non-NULL, then
|
||||
* we're following rules for new Windows driver support.
|
||||
@@ -1241,6 +1232,10 @@ void smbios_get_tables(MachineState *ms,
|
||||
{
|
||||
unsigned i, dimm_cnt, offset;
|
||||
|
||||
+ /* drop unwanted (legacy) version of command-line file blob(s) */
|
||||
+ g_free(smbios_entries);
|
||||
+ smbios_entries = NULL;
|
||||
+
|
||||
if (!smbios_immutable) {
|
||||
smbios_build_type_0_table();
|
||||
smbios_build_type_1_table();
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 95ec64ce2c..b9fc9a0f42 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -310,11 +310,11 @@ struct smbios_type_127 {
|
||||
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, bool legacy_mode,
|
||||
+ const char *version,
|
||||
bool uuid_encoded,
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
- const char *stream_version,
|
||||
- SmbiosEntryPointType ep_type);
|
||||
+ const char *stream_version);
|
||||
uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,134 +0,0 @@
|
||||
From 1536f1ec00ddc1729854b381cc0d54814bb6c19f Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Fri, 29 Dec 2023 15:04:55 +0100
|
||||
Subject: [PATCH 07/20] smbios: get rid of smbios_smp_sockets global
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [5/18] f59bfeb547b7febcf1de2b6179af006e7fa0bccd
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
it makes smbios_validate_table() independent from
|
||||
smbios_smp_sockets global, which in turn lets
|
||||
smbios_get_tables() avoid using not related legacy code.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
|
||||
Conflicts:
|
||||
include/hw/firmware/smbios.h due to down-stream
|
||||
(d9ff466c980d Machine type related general changes)
|
||||
adding custom stream_product/stream_version
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 2 +-
|
||||
hw/smbios/smbios.c | 22 +++++++++-------------
|
||||
include/hw/firmware/smbios.h | 2 +-
|
||||
3 files changed, 11 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index ed72b1442d..79ff7f7225 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -72,7 +72,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
/* tell smbios about cpuid version and features */
|
||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||
|
||||
- smbios_tables = smbios_get_table_legacy(ms, &smbios_tables_len);
|
||||
+ smbios_tables = smbios_get_table_legacy(ms->smp.cpus, &smbios_tables_len);
|
||||
if (smbios_tables) {
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
|
||||
smbios_tables, smbios_tables_len);
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index b13e40bae2..8129d396d1 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -73,7 +73,7 @@ static SmbiosEntryPoint ep;
|
||||
static int smbios_type4_count = 0;
|
||||
static bool smbios_immutable;
|
||||
static bool smbios_have_defaults;
|
||||
-static uint32_t smbios_cpuid_version, smbios_cpuid_features, smbios_smp_sockets;
|
||||
+static uint32_t smbios_cpuid_version, smbios_cpuid_features;
|
||||
|
||||
static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
|
||||
static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
|
||||
@@ -524,14 +524,11 @@ opts_init(smbios_register_config);
|
||||
*/
|
||||
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
|
||||
|
||||
-static void smbios_validate_table(MachineState *ms)
|
||||
+static void smbios_validate_table(uint32_t expected_t4_count)
|
||||
{
|
||||
- uint32_t expect_t4_count = smbios_legacy ?
|
||||
- ms->smp.cpus : smbios_smp_sockets;
|
||||
-
|
||||
- if (smbios_type4_count && smbios_type4_count != expect_t4_count) {
|
||||
+ if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
|
||||
error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
|
||||
- expect_t4_count, smbios_type4_count);
|
||||
+ expected_t4_count, smbios_type4_count);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -619,7 +616,7 @@ static void smbios_build_type_1_fields(void)
|
||||
}
|
||||
}
|
||||
|
||||
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
|
||||
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length)
|
||||
{
|
||||
if (!smbios_legacy) {
|
||||
*length = 0;
|
||||
@@ -629,7 +626,7 @@ uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length)
|
||||
if (!smbios_immutable) {
|
||||
smbios_build_type_0_fields();
|
||||
smbios_build_type_1_fields();
|
||||
- smbios_validate_table(ms);
|
||||
+ smbios_validate_table(expected_t4_count);
|
||||
smbios_immutable = true;
|
||||
}
|
||||
*length = smbios_entries_len;
|
||||
@@ -1250,10 +1247,9 @@ void smbios_get_tables(MachineState *ms,
|
||||
smbios_build_type_2_table();
|
||||
smbios_build_type_3_table();
|
||||
|
||||
- smbios_smp_sockets = ms->smp.sockets;
|
||||
- assert(smbios_smp_sockets >= 1);
|
||||
+ assert(ms->smp.sockets >= 1);
|
||||
|
||||
- for (i = 0; i < smbios_smp_sockets; i++) {
|
||||
+ for (i = 0; i < ms->smp.sockets; i++) {
|
||||
smbios_build_type_4_table(ms, i);
|
||||
}
|
||||
|
||||
@@ -1299,7 +1295,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
smbios_build_type_41_table(errp);
|
||||
smbios_build_type_127_table();
|
||||
|
||||
- smbios_validate_table(ms);
|
||||
+ smbios_validate_table(ms->smp.sockets);
|
||||
smbios_entry_point_setup();
|
||||
smbios_immutable = true;
|
||||
}
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index f8dd07fe4c..95ec64ce2c 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -315,7 +315,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
const char *stream_product,
|
||||
const char *stream_version,
|
||||
SmbiosEntryPointType ep_type);
|
||||
-uint8_t *smbios_get_table_legacy(MachineState *ms, size_t *length);
|
||||
+uint8_t *smbios_get_table_legacy(uint32_t expected_t4_count, size_t *length);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,217 +0,0 @@
|
||||
From 7271c4424c6d90f0bb34f8090eb4e192eb2b2537 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 20 Feb 2024 10:30:28 +0100
|
||||
Subject: [PATCH 14/20] smbios: handle errors consistently
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [12/18] d8a5a70602ae0665ce35e5bf87b2d8420f9189bc
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
Current code uses mix of error_report()+exit(1)
|
||||
and error_setg() to handle errors.
|
||||
Use newer error_setg() everywhere, beside consistency
|
||||
it will allow to detect error condition without killing
|
||||
QEMU and attempt switch-over to SMBIOS3.x tables/entrypoint
|
||||
in follow up patch.
|
||||
|
||||
while at it, clear smbios_tables pointer after freeing.
|
||||
that will avoid double free if smbios_get_tables() is called
|
||||
multiple times.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Conflicts: include/hw/firmware/smbios.h
|
||||
due to downstream specific smbios_set_defaults()
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/i386/fw_cfg.c | 3 ++-
|
||||
hw/smbios/smbios.c | 34 ++++++++++++++++++++++------------
|
||||
hw/smbios/smbios_legacy.c | 22 ++++++++++++++--------
|
||||
include/hw/firmware/smbios.h | 4 ++--
|
||||
4 files changed, 40 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
|
||||
index a25793a68f..bdc3cc4556 100644
|
||||
--- a/hw/i386/fw_cfg.c
|
||||
+++ b/hw/i386/fw_cfg.c
|
||||
@@ -73,7 +73,8 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg)
|
||||
smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
|
||||
|
||||
if (pcmc->smbios_legacy_mode) {
|
||||
- smbios_tables = smbios_get_table_legacy(&smbios_tables_len);
|
||||
+ smbios_tables = smbios_get_table_legacy(&smbios_tables_len,
|
||||
+ &error_fatal);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
|
||||
smbios_tables, smbios_tables_len);
|
||||
return;
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index e40204550e..b5745c6c2d 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "qemu/units.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/config-file.h"
|
||||
-#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
@@ -497,23 +496,25 @@ opts_init(smbios_register_config);
|
||||
*/
|
||||
#define SMBIOS_21_MAX_TABLES_LEN 0xffff
|
||||
|
||||
-static void smbios_check_type4_count(uint32_t expected_t4_count)
|
||||
+static bool smbios_check_type4_count(uint32_t expected_t4_count, Error **errp)
|
||||
{
|
||||
if (smbios_type4_count && smbios_type4_count != expected_t4_count) {
|
||||
- error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
|
||||
- expected_t4_count, smbios_type4_count);
|
||||
- exit(1);
|
||||
+ error_setg(errp, "Expected %d SMBIOS Type 4 tables, got %d instead",
|
||||
+ expected_t4_count, smbios_type4_count);
|
||||
+ return false;
|
||||
}
|
||||
+ return true;
|
||||
}
|
||||
|
||||
-void smbios_validate_table(void)
|
||||
+bool smbios_validate_table(Error **errp)
|
||||
{
|
||||
if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_32 &&
|
||||
smbios_tables_len > SMBIOS_21_MAX_TABLES_LEN) {
|
||||
- error_report("SMBIOS 2.1 table length %zu exceeds %d",
|
||||
- smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
|
||||
- exit(1);
|
||||
+ error_setg(errp, "SMBIOS 2.1 table length %zu exceeds %d",
|
||||
+ smbios_tables_len, SMBIOS_21_MAX_TABLES_LEN);
|
||||
+ return false;
|
||||
}
|
||||
+ return true;
|
||||
}
|
||||
|
||||
bool smbios_skip_table(uint8_t type, bool required_table)
|
||||
@@ -1167,15 +1168,18 @@ void smbios_get_tables(MachineState *ms,
|
||||
smbios_build_type_41_table(errp);
|
||||
smbios_build_type_127_table();
|
||||
|
||||
- smbios_check_type4_count(ms->smp.sockets);
|
||||
- smbios_validate_table();
|
||||
+ if (!smbios_check_type4_count(ms->smp.sockets, errp)) {
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+ if (!smbios_validate_table(errp)) {
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
smbios_entry_point_setup();
|
||||
|
||||
/* return tables blob and entry point (anchor), and their sizes */
|
||||
*tables = smbios_tables;
|
||||
*tables_len = smbios_tables_len;
|
||||
*anchor = (uint8_t *)&ep;
|
||||
-
|
||||
/* calculate length based on anchor string */
|
||||
if (!strncmp((char *)&ep, "_SM_", 4)) {
|
||||
*anchor_len = sizeof(struct smbios_21_entry_point);
|
||||
@@ -1184,6 +1188,12 @@ void smbios_get_tables(MachineState *ms,
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
+
|
||||
+ return;
|
||||
+err_exit:
|
||||
+ g_free(smbios_tables);
|
||||
+ smbios_tables = NULL;
|
||||
+ return;
|
||||
}
|
||||
|
||||
static void save_opt(const char **dest, QemuOpts *opts, const char *name)
|
||||
diff --git a/hw/smbios/smbios_legacy.c b/hw/smbios/smbios_legacy.c
|
||||
index 21f143e738..a6544bf55a 100644
|
||||
--- a/hw/smbios/smbios_legacy.c
|
||||
+++ b/hw/smbios/smbios_legacy.c
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "qemu/bswap.h"
|
||||
#include "hw/firmware/smbios.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
-#include "qemu/error-report.h"
|
||||
+#include "qapi/error.h"
|
||||
|
||||
struct smbios_header {
|
||||
uint16_t length;
|
||||
@@ -128,7 +128,7 @@ static void smbios_build_type_1_fields(void)
|
||||
}
|
||||
}
|
||||
|
||||
-uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
|
||||
{
|
||||
int i;
|
||||
size_t usr_offset;
|
||||
@@ -136,15 +136,15 @@ uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
/* complain if fields were given for types > 1 */
|
||||
if (find_next_bit(smbios_have_fields_bitmap,
|
||||
SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
|
||||
- error_report("can't process fields for smbios "
|
||||
+ error_setg(errp, "can't process fields for smbios "
|
||||
"types > 1 on machine versions < 2.1!");
|
||||
- exit(1);
|
||||
+ goto err_exit;
|
||||
}
|
||||
|
||||
if (test_bit(4, smbios_have_binfile_bitmap)) {
|
||||
- error_report("can't process table for smbios "
|
||||
- "type 4 on machine versions < 2.1!");
|
||||
- exit(1);
|
||||
+ error_setg(errp, "can't process table for smbios "
|
||||
+ "type 4 on machine versions < 2.1!");
|
||||
+ goto err_exit;
|
||||
}
|
||||
|
||||
g_free(smbios_entries);
|
||||
@@ -173,7 +173,13 @@ uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
|
||||
smbios_build_type_0_fields();
|
||||
smbios_build_type_1_fields();
|
||||
- smbios_validate_table();
|
||||
+ if (!smbios_validate_table(errp)) {
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+
|
||||
*length = smbios_entries_len;
|
||||
return smbios_entries;
|
||||
+err_exit:
|
||||
+ g_free(smbios_entries);
|
||||
+ return NULL;
|
||||
}
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index 92e9aba415..44af3a0d82 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -326,7 +326,7 @@ struct smbios_type_127 {
|
||||
struct smbios_structure_header header;
|
||||
} QEMU_PACKED;
|
||||
|
||||
-void smbios_validate_table(void);
|
||||
+bool smbios_validate_table(Error **errp);
|
||||
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);
|
||||
@@ -336,7 +336,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
SmbiosEntryPointType ep_type,
|
||||
const char *stream_product,
|
||||
const char *stream_version);
|
||||
-uint8_t *smbios_get_table_legacy(size_t *length);
|
||||
+uint8_t *smbios_get_table_legacy(size_t *length, Error **errp);
|
||||
void smbios_get_tables(MachineState *ms,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,131 +0,0 @@
|
||||
From 38220bc61bdb1614f34a53481f7604720c9e9e5a Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Tue, 20 Feb 2024 10:41:06 +0100
|
||||
Subject: [PATCH 18/20] smbios: in case of entry point is 'auto' try to build
|
||||
v2 tables 1st
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [16/18] becbcb3d8dad4842e5939bb75e21f4e737a4a325
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
QEMU for some time now uses SMBIOS 3.0 for PC/Q35 machines by
|
||||
default, however Windows has a bug in locating SMBIOS 3.0
|
||||
entrypoint and fails to find tables when booted on SeaBIOS
|
||||
(on UEFI SMBIOS 3.0 tables work fine since firmware hands
|
||||
over tables in another way)
|
||||
|
||||
Missing SMBIOS tables may lead to some issues for guest
|
||||
though (worst are: possible reactiveation, inability to
|
||||
get virtio drivers from 'Windows Update')
|
||||
|
||||
It's unclear at this point if MS will fix the issue on their
|
||||
side. So instead of it (or rather in addition) this patch
|
||||
will try to workaround the issue.
|
||||
|
||||
aka, use smbios-entry-point-type=auto to make QEMU try
|
||||
generating conservative SMBIOS 2.0 tables and if that
|
||||
fails (due to limits/requested configuration) fallback
|
||||
to SMBIOS 3.0 tables.
|
||||
|
||||
With this in place majority of users will use SMBIOS 2.0
|
||||
tables which work fine with (Windows + legacy BIOS).
|
||||
The configurations that is not to possible to describe
|
||||
with SMBIOS 2.0 will switch automatically to SMBIOS 3.0
|
||||
(which will trigger Windows bug but there is nothing
|
||||
QEMU can do here, so go and aks Microsoft to real fix).
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 52 +++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 49 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index 4521ea386c..3d9dcb0d31 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -1097,7 +1097,7 @@ static void smbios_entry_point_setup(SmbiosEntryPointType ep_type)
|
||||
}
|
||||
}
|
||||
|
||||
-void smbios_get_tables(MachineState *ms,
|
||||
+static bool smbios_get_tables_ep(MachineState *ms,
|
||||
SmbiosEntryPointType ep_type,
|
||||
const struct smbios_phys_mem_area *mem_array,
|
||||
const unsigned int mem_array_size,
|
||||
@@ -1106,6 +1106,7 @@ void smbios_get_tables(MachineState *ms,
|
||||
Error **errp)
|
||||
{
|
||||
unsigned i, dimm_cnt, offset;
|
||||
+ ERRP_GUARD();
|
||||
|
||||
assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ||
|
||||
ep_type == SMBIOS_ENTRY_POINT_TYPE_64);
|
||||
@@ -1192,11 +1193,56 @@ void smbios_get_tables(MachineState *ms,
|
||||
abort();
|
||||
}
|
||||
|
||||
- return;
|
||||
+ return true;
|
||||
err_exit:
|
||||
g_free(smbios_tables);
|
||||
smbios_tables = NULL;
|
||||
- return;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void smbios_get_tables(MachineState *ms,
|
||||
+ SmbiosEntryPointType ep_type,
|
||||
+ const struct smbios_phys_mem_area *mem_array,
|
||||
+ const unsigned int mem_array_size,
|
||||
+ uint8_t **tables, size_t *tables_len,
|
||||
+ uint8_t **anchor, size_t *anchor_len,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ Error *local_err = NULL;
|
||||
+ bool is_valid;
|
||||
+ ERRP_GUARD();
|
||||
+
|
||||
+ switch (ep_type) {
|
||||
+ case SMBIOS_ENTRY_POINT_TYPE_AUTO:
|
||||
+ case SMBIOS_ENTRY_POINT_TYPE_32:
|
||||
+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_32,
|
||||
+ mem_array, mem_array_size,
|
||||
+ tables, tables_len,
|
||||
+ anchor, anchor_len,
|
||||
+ &local_err);
|
||||
+ if (is_valid || ep_type != SMBIOS_ENTRY_POINT_TYPE_AUTO) {
|
||||
+ break;
|
||||
+ }
|
||||
+ /*
|
||||
+ * fall through in case AUTO endpoint is selected and
|
||||
+ * SMBIOS 2.x tables can't be generated, to try if SMBIOS 3.x
|
||||
+ * tables would work
|
||||
+ */
|
||||
+ case SMBIOS_ENTRY_POINT_TYPE_64:
|
||||
+ error_free(local_err);
|
||||
+ local_err = NULL;
|
||||
+ is_valid = smbios_get_tables_ep(ms, SMBIOS_ENTRY_POINT_TYPE_64,
|
||||
+ mem_array, mem_array_size,
|
||||
+ tables, tables_len,
|
||||
+ anchor, anchor_len,
|
||||
+ &local_err);
|
||||
+ break;
|
||||
+ default:
|
||||
+ abort();
|
||||
+ }
|
||||
+ if (!is_valid) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void save_opt(const char **dest, QemuOpts *opts, const char *name)
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,330 +0,0 @@
|
||||
From 36b0256e27f9d5268c5413891b4a7322819ae9db Mon Sep 17 00:00:00 2001
|
||||
From: Igor Mammedov <imammedo@redhat.com>
|
||||
Date: Mon, 4 Mar 2024 15:56:19 +0100
|
||||
Subject: [PATCH 12/20] smbios: rename/expose structures/bitmaps used by both
|
||||
legacy and modern code
|
||||
|
||||
RH-Author: Igor Mammedov <imammedo@redhat.com>
|
||||
RH-MergeRequest: 230: Workaround Windows failing to find 64bit SMBIOS entry point with SeaBIOS
|
||||
RH-Jira: RHEL-21705
|
||||
RH-Acked-by: MST <mst@redhat.com>
|
||||
RH-Acked-by: Ani Sinha <None>
|
||||
RH-Commit: [10/18] 59fe438d5b7f6e584a6bb02597e4d4724fe2cece
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-21705
|
||||
|
||||
As a preparation to move legacy handling into a separate file,
|
||||
add prefix 'smbios_' to type0/type1/have_binfile_bitmap/have_fields_bitmap
|
||||
and expose them in smbios.h so that they can be reused in
|
||||
legacy and modern code.
|
||||
|
||||
Doing it as a separate patch to avoid rename cluttering follow-up
|
||||
patch which will move legacy code into a separate file.
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Reviewed-by: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
Conflicts: hw/smbios/smbios.c
|
||||
due to setting downstream type1.family/type1.sku defaults
|
||||
|
||||
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
|
||||
---
|
||||
hw/smbios/smbios.c | 117 ++++++++++++++++-------------------
|
||||
include/hw/firmware/smbios.h | 16 +++++
|
||||
2 files changed, 71 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
|
||||
index c48a290478..eb9927335d 100644
|
||||
--- a/hw/smbios/smbios.c
|
||||
+++ b/hw/smbios/smbios.c
|
||||
@@ -81,19 +81,11 @@ static int smbios_type4_count = 0;
|
||||
static bool smbios_have_defaults;
|
||||
static uint32_t smbios_cpuid_version, smbios_cpuid_features;
|
||||
|
||||
-static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1);
|
||||
-static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1);
|
||||
+DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
|
||||
+DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
|
||||
|
||||
-static struct {
|
||||
- const char *vendor, *version, *date;
|
||||
- bool have_major_minor, uefi;
|
||||
- uint8_t major, minor;
|
||||
-} type0;
|
||||
-
|
||||
-static struct {
|
||||
- const char *manufacturer, *product, *version, *serial, *sku, *family;
|
||||
- /* uuid is in qemu_uuid */
|
||||
-} type1;
|
||||
+smbios_type0_t smbios_type0;
|
||||
+smbios_type1_t smbios_type1;
|
||||
|
||||
static struct {
|
||||
const char *manufacturer, *product, *version, *serial, *asset, *location;
|
||||
@@ -584,36 +576,36 @@ static void smbios_maybe_add_str(int type, int offset, const char *data)
|
||||
static void smbios_build_type_0_fields(void)
|
||||
{
|
||||
smbios_maybe_add_str(0, offsetof(struct smbios_type_0, vendor_str),
|
||||
- type0.vendor);
|
||||
+ smbios_type0.vendor);
|
||||
smbios_maybe_add_str(0, offsetof(struct smbios_type_0, bios_version_str),
|
||||
- type0.version);
|
||||
+ smbios_type0.version);
|
||||
smbios_maybe_add_str(0, offsetof(struct smbios_type_0,
|
||||
bios_release_date_str),
|
||||
- type0.date);
|
||||
- if (type0.have_major_minor) {
|
||||
+ smbios_type0.date);
|
||||
+ if (smbios_type0.have_major_minor) {
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
system_bios_major_release),
|
||||
- &type0.major, 1);
|
||||
+ &smbios_type0.major, 1);
|
||||
smbios_add_field(0, offsetof(struct smbios_type_0,
|
||||
system_bios_minor_release),
|
||||
- &type0.minor, 1);
|
||||
+ &smbios_type0.minor, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void smbios_build_type_1_fields(void)
|
||||
{
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),
|
||||
- type1.manufacturer);
|
||||
+ smbios_type1.manufacturer);
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),
|
||||
- type1.product);
|
||||
+ smbios_type1.product);
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),
|
||||
- type1.version);
|
||||
+ smbios_type1.version);
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),
|
||||
- type1.serial);
|
||||
+ smbios_type1.serial);
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),
|
||||
- type1.sku);
|
||||
+ smbios_type1.sku);
|
||||
smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),
|
||||
- type1.family);
|
||||
+ smbios_type1.family);
|
||||
if (qemu_uuid_set) {
|
||||
/* We don't encode the UUID in the "wire format" here because this
|
||||
* function is for legacy mode and needs to keep the guest ABI, and
|
||||
@@ -631,14 +623,14 @@ uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
size_t usr_offset;
|
||||
|
||||
/* also complain if fields were given for types > 1 */
|
||||
- if (find_next_bit(have_fields_bitmap,
|
||||
+ if (find_next_bit(smbios_have_fields_bitmap,
|
||||
SMBIOS_MAX_TYPE + 1, 2) < SMBIOS_MAX_TYPE + 1) {
|
||||
error_report("can't process fields for smbios "
|
||||
"types > 1 on machine versions < 2.1!");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- if (test_bit(4, have_binfile_bitmap)) {
|
||||
+ if (test_bit(4, smbios_have_binfile_bitmap)) {
|
||||
error_report("can't process table for smbios "
|
||||
"type 4 on machine versions < 2.1!");
|
||||
exit(1);
|
||||
@@ -679,10 +671,10 @@ uint8_t *smbios_get_table_legacy(size_t *length)
|
||||
|
||||
bool smbios_skip_table(uint8_t type, bool required_table)
|
||||
{
|
||||
- if (test_bit(type, have_binfile_bitmap)) {
|
||||
+ if (test_bit(type, smbios_have_binfile_bitmap)) {
|
||||
return true; /* user provided their own binary blob(s) */
|
||||
}
|
||||
- if (test_bit(type, have_fields_bitmap)) {
|
||||
+ if (test_bit(type, smbios_have_fields_bitmap)) {
|
||||
return false; /* user provided fields via command line */
|
||||
}
|
||||
if (smbios_have_defaults && required_table) {
|
||||
@@ -710,25 +702,25 @@ static void smbios_build_type_0_table(void)
|
||||
{
|
||||
SMBIOS_BUILD_TABLE_PRE(0, T0_BASE, false); /* optional, leave up to BIOS */
|
||||
|
||||
- SMBIOS_TABLE_SET_STR(0, vendor_str, type0.vendor);
|
||||
- SMBIOS_TABLE_SET_STR(0, bios_version_str, type0.version);
|
||||
+ SMBIOS_TABLE_SET_STR(0, vendor_str, smbios_type0.vendor);
|
||||
+ SMBIOS_TABLE_SET_STR(0, bios_version_str, smbios_type0.version);
|
||||
|
||||
t->bios_starting_address_segment = cpu_to_le16(0xE800); /* from SeaBIOS */
|
||||
|
||||
- SMBIOS_TABLE_SET_STR(0, bios_release_date_str, type0.date);
|
||||
+ SMBIOS_TABLE_SET_STR(0, bios_release_date_str, smbios_type0.date);
|
||||
|
||||
t->bios_rom_size = 0; /* hardcoded in SeaBIOS with FIXME comment */
|
||||
|
||||
t->bios_characteristics = cpu_to_le64(0x08); /* Not supported */
|
||||
t->bios_characteristics_extension_bytes[0] = 0;
|
||||
t->bios_characteristics_extension_bytes[1] = 0x14; /* TCD/SVVP | VM */
|
||||
- if (type0.uefi) {
|
||||
+ if (smbios_type0.uefi) {
|
||||
t->bios_characteristics_extension_bytes[1] |= 0x08; /* |= UEFI */
|
||||
}
|
||||
|
||||
- if (type0.have_major_minor) {
|
||||
- t->system_bios_major_release = type0.major;
|
||||
- t->system_bios_minor_release = type0.minor;
|
||||
+ if (smbios_type0.have_major_minor) {
|
||||
+ t->system_bios_major_release = smbios_type0.major;
|
||||
+ t->system_bios_minor_release = smbios_type0.minor;
|
||||
} else {
|
||||
t->system_bios_major_release = 0;
|
||||
t->system_bios_minor_release = 0;
|
||||
@@ -758,18 +750,18 @@ static void smbios_build_type_1_table(void)
|
||||
{
|
||||
SMBIOS_BUILD_TABLE_PRE(1, T1_BASE, true); /* required */
|
||||
|
||||
- SMBIOS_TABLE_SET_STR(1, manufacturer_str, type1.manufacturer);
|
||||
- SMBIOS_TABLE_SET_STR(1, product_name_str, type1.product);
|
||||
- SMBIOS_TABLE_SET_STR(1, version_str, type1.version);
|
||||
- SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial);
|
||||
+ SMBIOS_TABLE_SET_STR(1, manufacturer_str, smbios_type1.manufacturer);
|
||||
+ SMBIOS_TABLE_SET_STR(1, product_name_str, smbios_type1.product);
|
||||
+ SMBIOS_TABLE_SET_STR(1, version_str, smbios_type1.version);
|
||||
+ SMBIOS_TABLE_SET_STR(1, serial_number_str, smbios_type1.serial);
|
||||
if (qemu_uuid_set) {
|
||||
smbios_encode_uuid(&t->uuid, &qemu_uuid);
|
||||
} else {
|
||||
memset(&t->uuid, 0, 16);
|
||||
}
|
||||
t->wake_up_type = 0x06; /* power switch */
|
||||
- SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku);
|
||||
- SMBIOS_TABLE_SET_STR(1, family_str, type1.family);
|
||||
+ SMBIOS_TABLE_SET_STR(1, sku_number_str, smbios_type1.sku);
|
||||
+ SMBIOS_TABLE_SET_STR(1, family_str, smbios_type1.family);
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
}
|
||||
@@ -1184,12 +1176,12 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
|
||||
*
|
||||
* We get 'System Manufacturer' and 'Baseboard Manufacturer'
|
||||
*/
|
||||
- SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer);
|
||||
- SMBIOS_SET_DEFAULT(type1.product, product);
|
||||
- SMBIOS_SET_DEFAULT(type1.version, version);
|
||||
- SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux");
|
||||
+ 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(type1.sku, stream_version);
|
||||
+ SMBIOS_SET_DEFAULT(smbios_type1.sku, stream_version);
|
||||
}
|
||||
SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer);
|
||||
if (stream_product != NULL) {
|
||||
@@ -1468,13 +1460,13 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
}
|
||||
|
||||
if (header->type <= SMBIOS_MAX_TYPE) {
|
||||
- if (test_bit(header->type, have_fields_bitmap)) {
|
||||
+ if (test_bit(header->type, smbios_have_fields_bitmap)) {
|
||||
error_setg(errp,
|
||||
"can't load type %d struct, fields already specified!",
|
||||
header->type);
|
||||
return;
|
||||
}
|
||||
- set_bit(header->type, have_binfile_bitmap);
|
||||
+ set_bit(header->type, smbios_have_binfile_bitmap);
|
||||
}
|
||||
|
||||
if (header->type == 4) {
|
||||
@@ -1505,41 +1497,42 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (test_bit(type, have_binfile_bitmap)) {
|
||||
+ if (test_bit(type, smbios_have_binfile_bitmap)) {
|
||||
error_setg(errp, "can't add fields, binary file already loaded!");
|
||||
return;
|
||||
}
|
||||
- set_bit(type, have_fields_bitmap);
|
||||
+ set_bit(type, smbios_have_fields_bitmap);
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
if (!qemu_opts_validate(opts, qemu_smbios_type0_opts, errp)) {
|
||||
return;
|
||||
}
|
||||
- save_opt(&type0.vendor, opts, "vendor");
|
||||
- save_opt(&type0.version, opts, "version");
|
||||
- save_opt(&type0.date, opts, "date");
|
||||
- type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
|
||||
+ save_opt(&smbios_type0.vendor, opts, "vendor");
|
||||
+ save_opt(&smbios_type0.version, opts, "version");
|
||||
+ save_opt(&smbios_type0.date, opts, "date");
|
||||
+ smbios_type0.uefi = qemu_opt_get_bool(opts, "uefi", false);
|
||||
|
||||
val = qemu_opt_get(opts, "release");
|
||||
if (val) {
|
||||
- if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
|
||||
+ if (sscanf(val, "%hhu.%hhu", &smbios_type0.major,
|
||||
+ &smbios_type0.minor) != 2) {
|
||||
error_setg(errp, "Invalid release");
|
||||
return;
|
||||
}
|
||||
- type0.have_major_minor = true;
|
||||
+ smbios_type0.have_major_minor = true;
|
||||
}
|
||||
return;
|
||||
case 1:
|
||||
if (!qemu_opts_validate(opts, qemu_smbios_type1_opts, errp)) {
|
||||
return;
|
||||
}
|
||||
- save_opt(&type1.manufacturer, opts, "manufacturer");
|
||||
- save_opt(&type1.product, opts, "product");
|
||||
- save_opt(&type1.version, opts, "version");
|
||||
- save_opt(&type1.serial, opts, "serial");
|
||||
- save_opt(&type1.sku, opts, "sku");
|
||||
- save_opt(&type1.family, opts, "family");
|
||||
+ save_opt(&smbios_type1.manufacturer, opts, "manufacturer");
|
||||
+ save_opt(&smbios_type1.product, opts, "product");
|
||||
+ save_opt(&smbios_type1.version, opts, "version");
|
||||
+ save_opt(&smbios_type1.serial, opts, "serial");
|
||||
+ save_opt(&smbios_type1.sku, opts, "sku");
|
||||
+ save_opt(&smbios_type1.family, opts, "family");
|
||||
|
||||
val = qemu_opt_get(opts, "uuid");
|
||||
if (val) {
|
||||
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
|
||||
index d55018e5e3..333de0d5fc 100644
|
||||
--- a/include/hw/firmware/smbios.h
|
||||
+++ b/include/hw/firmware/smbios.h
|
||||
@@ -2,6 +2,7 @@
|
||||
#define QEMU_SMBIOS_H
|
||||
|
||||
#include "qapi/qapi-types-machine.h"
|
||||
+#include "qemu/bitmap.h"
|
||||
|
||||
/*
|
||||
* SMBIOS Support
|
||||
@@ -16,8 +17,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+typedef struct {
|
||||
+ const char *vendor, *version, *date;
|
||||
+ bool have_major_minor, uefi;
|
||||
+ uint8_t major, minor;
|
||||
+} smbios_type0_t;
|
||||
+extern smbios_type0_t smbios_type0;
|
||||
+
|
||||
+typedef struct {
|
||||
+ const char *manufacturer, *product, *version, *serial, *sku, *family;
|
||||
+ /* uuid is in qemu_uuid */
|
||||
+} smbios_type1_t;
|
||||
+extern smbios_type1_t smbios_type1;
|
||||
|
||||
#define SMBIOS_MAX_TYPE 127
|
||||
+extern DECLARE_BITMAP(smbios_have_binfile_bitmap, SMBIOS_MAX_TYPE + 1);
|
||||
+extern DECLARE_BITMAP(smbios_have_fields_bitmap, SMBIOS_MAX_TYPE + 1);
|
||||
+
|
||||
#define offsetofend(TYPE, MEMBER) \
|
||||
(offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
|
||||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,190 +0,0 @@
|
||||
From c5f9e92cd49a2171a5b0223cafd7fab3f45edb82 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Tue, 9 Jan 2024 19:17:17 +0100
|
||||
Subject: [PATCH 06/22] string-output-visitor: Fix (pseudo) struct handling
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [2/17] 84e226f161680dd61b6635e213203d062c1aa556 (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
Commit ff32bb53 tried to get minimal struct support into the string
|
||||
output visitor by just making it return "<omitted>". Unfortunately, it
|
||||
forgot that the caller will still make more visitor calls for the
|
||||
content of the struct.
|
||||
|
||||
If the struct is contained in a list, such as IOThreadVirtQueueMapping,
|
||||
in the better case its fields show up as separate list entries. In the
|
||||
worse case, it contains another list, and the string output visitor
|
||||
doesn't support nested lists and asserts that this doesn't happen. So as
|
||||
soon as the optional "vqs" field in IOThreadVirtQueueMapping is
|
||||
specified, we get a crash.
|
||||
|
||||
This can be reproduced with the following command line:
|
||||
|
||||
echo "info qtree" | ./qemu-system-x86_64 \
|
||||
-object iothread,id=t0 \
|
||||
-blockdev null-co,node-name=disk \
|
||||
-device '{"driver": "virtio-blk-pci", "drive": "disk",
|
||||
"iothread-vq-mapping": [{"iothread": "t0", "vqs": [0]}]}' \
|
||||
-monitor stdio
|
||||
|
||||
Fix the problem by counting the nesting level of structs and ignoring
|
||||
any visitor calls for values (apart from start/end_struct) while we're
|
||||
not on the top level.
|
||||
|
||||
Lists nested directly within lists remain unimplemented, as we don't
|
||||
currently have a use case for them.
|
||||
|
||||
Fixes: ff32bb53476539d352653f4ed56372dced73a388
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2069
|
||||
Reported-by: Aihua Liang <aliang@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240109181717.42493-1-kwolf@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 014b99a8e41c8cd1e895137654b44dec5430122c)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
qapi/string-output-visitor.c | 46 ++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 46 insertions(+)
|
||||
|
||||
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
|
||||
index f0c1dea89e..5115536b15 100644
|
||||
--- a/qapi/string-output-visitor.c
|
||||
+++ b/qapi/string-output-visitor.c
|
||||
@@ -65,6 +65,7 @@ struct StringOutputVisitor
|
||||
} range_start, range_end;
|
||||
GList *ranges;
|
||||
void *list; /* Only needed for sanity checking the caller */
|
||||
+ unsigned int struct_nesting;
|
||||
};
|
||||
|
||||
static StringOutputVisitor *to_sov(Visitor *v)
|
||||
@@ -144,6 +145,10 @@ static bool print_type_int64(Visitor *v, const char *name, int64_t *obj,
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
GList *l;
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
switch (sov->list_mode) {
|
||||
case LM_NONE:
|
||||
string_output_append(sov, *obj);
|
||||
@@ -231,6 +236,10 @@ static bool print_type_size(Visitor *v, const char *name, uint64_t *obj,
|
||||
uint64_t val;
|
||||
char *out, *psize;
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
if (!sov->human) {
|
||||
out = g_strdup_printf("%"PRIu64, *obj);
|
||||
string_output_set(sov, out);
|
||||
@@ -250,6 +259,11 @@ static bool print_type_bool(Visitor *v, const char *name, bool *obj,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
+
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
string_output_set(sov, g_strdup(*obj ? "true" : "false"));
|
||||
return true;
|
||||
}
|
||||
@@ -260,6 +274,10 @@ static bool print_type_str(Visitor *v, const char *name, char **obj,
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
char *out;
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
if (sov->human) {
|
||||
out = *obj ? g_strdup_printf("\"%s\"", *obj) : g_strdup("<null>");
|
||||
} else {
|
||||
@@ -273,6 +291,11 @@ static bool print_type_number(Visitor *v, const char *name, double *obj,
|
||||
Error **errp)
|
||||
{
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
+
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
string_output_set(sov, g_strdup_printf("%.17g", *obj));
|
||||
return true;
|
||||
}
|
||||
@@ -283,6 +306,10 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj,
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
char *out;
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
if (sov->human) {
|
||||
out = g_strdup("<null>");
|
||||
} else {
|
||||
@@ -295,6 +322,9 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj,
|
||||
static bool start_struct(Visitor *v, const char *name, void **obj,
|
||||
size_t size, Error **errp)
|
||||
{
|
||||
+ StringOutputVisitor *sov = to_sov(v);
|
||||
+
|
||||
+ sov->struct_nesting++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -302,6 +332,10 @@ static void end_struct(Visitor *v, void **obj)
|
||||
{
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
|
||||
+ if (--sov->struct_nesting) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* TODO actually print struct fields */
|
||||
string_output_set(sov, g_strdup("<omitted>"));
|
||||
}
|
||||
@@ -312,6 +346,10 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
|
||||
{
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
/* we can't traverse a list in a list */
|
||||
assert(sov->list_mode == LM_NONE);
|
||||
/* We don't support visits without a list */
|
||||
@@ -329,6 +367,10 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
GenericList *ret = tail->next;
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (ret && !ret->next) {
|
||||
sov->list_mode = LM_END;
|
||||
}
|
||||
@@ -339,6 +381,10 @@ static void end_list(Visitor *v, void **obj)
|
||||
{
|
||||
StringOutputVisitor *sov = to_sov(v);
|
||||
|
||||
+ if (sov->struct_nesting) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
assert(sov->list == obj);
|
||||
assert(sov->list_mode == LM_STARTED ||
|
||||
sov->list_mode == LM_END ||
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,90 +0,0 @@
|
||||
From fb2069be402ec1322834c555714f0e993778cc9d Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 12 Dec 2023 08:49:34 -0500
|
||||
Subject: [PATCH 05/22] string-output-visitor: show structs as "<omitted>"
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [1/17] 0c08e8237d28fbdbdbc7576d4c17d2eeeb413c2a (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
StringOutputVisitor crashes when it visits a struct because
|
||||
->start_struct() is NULL.
|
||||
|
||||
Show "<omitted>" instead of crashing. This is necessary because the
|
||||
virtio-blk-pci iothread-vq-mapping parameter that I'd like to introduce
|
||||
soon is a list of IOThreadMapping structs.
|
||||
|
||||
This patch is a quick fix to solve the crash, but the long-term solution
|
||||
is replacing StringOutputVisitor with something that can handle the full
|
||||
gamut of values in QEMU.
|
||||
|
||||
Cc: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Message-ID: <20231212134934.500289-1-stefanha@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit ff32bb53476539d352653f4ed56372dced73a388)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
include/qapi/string-output-visitor.h | 6 +++---
|
||||
qapi/string-output-visitor.c | 16 ++++++++++++++++
|
||||
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
|
||||
index 268dfe9986..b1ee473b30 100644
|
||||
--- a/include/qapi/string-output-visitor.h
|
||||
+++ b/include/qapi/string-output-visitor.h
|
||||
@@ -26,9 +26,9 @@ typedef struct StringOutputVisitor StringOutputVisitor;
|
||||
* If everything else succeeds, pass @result to visit_complete() to
|
||||
* collect the result of the visit.
|
||||
*
|
||||
- * The string output visitor does not implement support for visiting
|
||||
- * QAPI structs, alternates, null, or arbitrary QTypes. It also
|
||||
- * requires a non-null list argument to visit_start_list().
|
||||
+ * The string output visitor does not implement support for alternates, null,
|
||||
+ * or arbitrary QTypes. Struct fields are not shown. It also requires a
|
||||
+ * non-null list argument to visit_start_list().
|
||||
*/
|
||||
Visitor *string_output_visitor_new(bool human, char **result);
|
||||
|
||||
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
|
||||
index c0cb72dbe4..f0c1dea89e 100644
|
||||
--- a/qapi/string-output-visitor.c
|
||||
+++ b/qapi/string-output-visitor.c
|
||||
@@ -292,6 +292,20 @@ static bool print_type_null(Visitor *v, const char *name, QNull **obj,
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool start_struct(Visitor *v, const char *name, void **obj,
|
||||
+ size_t size, Error **errp)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void end_struct(Visitor *v, void **obj)
|
||||
+{
|
||||
+ StringOutputVisitor *sov = to_sov(v);
|
||||
+
|
||||
+ /* TODO actually print struct fields */
|
||||
+ string_output_set(sov, g_strdup("<omitted>"));
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
start_list(Visitor *v, const char *name, GenericList **list, size_t size,
|
||||
Error **errp)
|
||||
@@ -379,6 +393,8 @@ Visitor *string_output_visitor_new(bool human, char **result)
|
||||
v->visitor.type_str = print_type_str;
|
||||
v->visitor.type_number = print_type_number;
|
||||
v->visitor.type_null = print_type_null;
|
||||
+ v->visitor.start_struct = start_struct;
|
||||
+ v->visitor.end_struct = end_struct;
|
||||
v->visitor.start_list = start_list;
|
||||
v->visitor.next_list = next_list;
|
||||
v->visitor.end_list = end_list;
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,205 +0,0 @@
|
||||
From cc8d794932e26df7c7f3c8cc0c1f42da8d52f12b Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Mon, 15 Jan 2024 10:26:52 +0100
|
||||
Subject: [PATCH 069/101] target/s390x/kvm/pv: Provide some more useful
|
||||
information if decryption fails
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 213: s390x: Provide some more useful information if decryption of a PV image fails
|
||||
RH-Jira: RHEL-18212
|
||||
RH-Acked-by: Cédric Le Goater <clg@redhat.com>
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||
RH-Commit: [1/1] 4ffb61869f7df33e23d3e0ebf8c29e386e3f6cbc (thuth/qemu-kvm-cs9)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-18212
|
||||
|
||||
commit 7af51621b16ae86646cc2dc9dee30de8176ff761
|
||||
Author: Thomas Huth <thuth@redhat.com>
|
||||
Date: Wed Jan 10 15:29:16 2024 +0100
|
||||
|
||||
target/s390x/kvm/pv: Provide some more useful information if decryption fails
|
||||
|
||||
It's a common scenario to copy guest images from one host to another
|
||||
to run the guest on the other machine. This (of course) does not work
|
||||
with "secure execution" guests since they are encrypted with one certain
|
||||
host key. However, if you still (accidentally) do it, you only get a
|
||||
very user-unfriendly error message that looks like this:
|
||||
|
||||
qemu-system-s390x: KVM PV command 2 (KVM_PV_SET_SEC_PARMS) failed:
|
||||
header rc 108 rrc 5 IOCTL rc: -22
|
||||
|
||||
Let's provide at least a somewhat nicer hint to the users so that they
|
||||
are able to figure out what might have gone wrong.
|
||||
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-18212
|
||||
Message-ID: <20240110142916.850605-1-thuth@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/ipl.c | 5 ++---
|
||||
hw/s390x/ipl.h | 2 +-
|
||||
hw/s390x/s390-virtio-ccw.c | 5 ++++-
|
||||
target/s390x/kvm/pv.c | 25 ++++++++++++++++++++-----
|
||||
target/s390x/kvm/pv.h | 5 +++--
|
||||
5 files changed, 30 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
|
||||
index 515dcf51b5..b23a6a0ef3 100644
|
||||
--- a/hw/s390x/ipl.c
|
||||
+++ b/hw/s390x/ipl.c
|
||||
@@ -703,7 +703,7 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu)
|
||||
cpu_physical_memory_unmap(addr, len, 1, len);
|
||||
}
|
||||
|
||||
-int s390_ipl_prepare_pv_header(void)
|
||||
+int s390_ipl_prepare_pv_header(Error **errp)
|
||||
{
|
||||
IplParameterBlock *ipib = s390_ipl_get_iplb_pv();
|
||||
IPLBlockPV *ipib_pv = &ipib->pv;
|
||||
@@ -712,8 +712,7 @@ int s390_ipl_prepare_pv_header(void)
|
||||
|
||||
cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr,
|
||||
ipib_pv->pv_header_len);
|
||||
- rc = s390_pv_set_sec_parms((uintptr_t)hdr,
|
||||
- ipib_pv->pv_header_len);
|
||||
+ rc = s390_pv_set_sec_parms((uintptr_t)hdr, ipib_pv->pv_header_len, errp);
|
||||
g_free(hdr);
|
||||
return rc;
|
||||
}
|
||||
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
|
||||
index 7fc86e7905..57cd125769 100644
|
||||
--- a/hw/s390x/ipl.h
|
||||
+++ b/hw/s390x/ipl.h
|
||||
@@ -107,7 +107,7 @@ typedef union IplParameterBlock IplParameterBlock;
|
||||
|
||||
int s390_ipl_set_loadparm(uint8_t *loadparm);
|
||||
void s390_ipl_update_diag308(IplParameterBlock *iplb);
|
||||
-int s390_ipl_prepare_pv_header(void);
|
||||
+int s390_ipl_prepare_pv_header(Error **errp);
|
||||
int s390_ipl_pv_unpack(void);
|
||||
void s390_ipl_prepare_cpu(S390CPU *cpu);
|
||||
IplParameterBlock *s390_ipl_get_iplb(void);
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 984891b82a..e26ce26f5a 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -391,7 +391,7 @@ static int s390_machine_protect(S390CcwMachineState *ms)
|
||||
}
|
||||
|
||||
/* Set SE header and unpack */
|
||||
- rc = s390_ipl_prepare_pv_header();
|
||||
+ rc = s390_ipl_prepare_pv_header(&local_err);
|
||||
if (rc) {
|
||||
goto out_err;
|
||||
}
|
||||
@@ -410,6 +410,9 @@ static int s390_machine_protect(S390CcwMachineState *ms)
|
||||
return rc;
|
||||
|
||||
out_err:
|
||||
+ if (local_err) {
|
||||
+ error_report_err(local_err);
|
||||
+ }
|
||||
s390_machine_unprotect(ms);
|
||||
return rc;
|
||||
}
|
||||
diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c
|
||||
index 6a69be7e5c..7ca7faec73 100644
|
||||
--- a/target/s390x/kvm/pv.c
|
||||
+++ b/target/s390x/kvm/pv.c
|
||||
@@ -29,7 +29,8 @@ static bool info_valid;
|
||||
static struct kvm_s390_pv_info_vm info_vm;
|
||||
static struct kvm_s390_pv_info_dump info_dump;
|
||||
|
||||
-static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
|
||||
+static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data,
|
||||
+ int *pvrc)
|
||||
{
|
||||
struct kvm_pv_cmd pv_cmd = {
|
||||
.cmd = cmd,
|
||||
@@ -46,6 +47,9 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
|
||||
"IOCTL rc: %d", cmd, cmdname, pv_cmd.rc, pv_cmd.rrc,
|
||||
rc);
|
||||
}
|
||||
+ if (pvrc) {
|
||||
+ *pvrc = pv_cmd.rc;
|
||||
+ }
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -53,12 +57,13 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
|
||||
* This macro lets us pass the command as a string to the function so
|
||||
* we can print it on an error.
|
||||
*/
|
||||
-#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data)
|
||||
+#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data, NULL)
|
||||
+#define s390_pv_cmd_pvrc(cmd, data, pvrc) __s390_pv_cmd(cmd, #cmd, data, pvrc)
|
||||
#define s390_pv_cmd_exit(cmd, data) \
|
||||
{ \
|
||||
int rc; \
|
||||
\
|
||||
- rc = __s390_pv_cmd(cmd, #cmd, data);\
|
||||
+ rc = __s390_pv_cmd(cmd, #cmd, data, NULL); \
|
||||
if (rc) { \
|
||||
exit(1); \
|
||||
} \
|
||||
@@ -142,14 +147,24 @@ bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms)
|
||||
return true;
|
||||
}
|
||||
|
||||
-int s390_pv_set_sec_parms(uint64_t origin, uint64_t length)
|
||||
+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length, Error **errp)
|
||||
{
|
||||
+ int ret, pvrc;
|
||||
struct kvm_s390_pv_sec_parm args = {
|
||||
.origin = origin,
|
||||
.length = length,
|
||||
};
|
||||
|
||||
- return s390_pv_cmd(KVM_PV_SET_SEC_PARMS, &args);
|
||||
+ ret = s390_pv_cmd_pvrc(KVM_PV_SET_SEC_PARMS, &args, &pvrc);
|
||||
+ if (ret) {
|
||||
+ error_setg(errp, "Failed to set secure execution parameters");
|
||||
+ if (pvrc == 0x108) {
|
||||
+ error_append_hint(errp, "Please check whether the image is "
|
||||
+ "correctly encrypted for this host\n");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/target/s390x/kvm/pv.h b/target/s390x/kvm/pv.h
|
||||
index 7b935e2246..5877d28ff1 100644
|
||||
--- a/target/s390x/kvm/pv.h
|
||||
+++ b/target/s390x/kvm/pv.h
|
||||
@@ -42,7 +42,7 @@ int s390_pv_query_info(void);
|
||||
int s390_pv_vm_enable(void);
|
||||
void s390_pv_vm_disable(void);
|
||||
bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms);
|
||||
-int s390_pv_set_sec_parms(uint64_t origin, uint64_t length);
|
||||
+int s390_pv_set_sec_parms(uint64_t origin, uint64_t length, Error **errp);
|
||||
int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak);
|
||||
void s390_pv_prep_reset(void);
|
||||
int s390_pv_verify(void);
|
||||
@@ -62,7 +62,8 @@ static inline int s390_pv_query_info(void) { return 0; }
|
||||
static inline int s390_pv_vm_enable(void) { return 0; }
|
||||
static inline void s390_pv_vm_disable(void) {}
|
||||
static inline bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms) { return false; }
|
||||
-static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; }
|
||||
+static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length,
|
||||
+ Error **errp) { return 0; }
|
||||
static inline int s390_pv_unpack(uint64_t addr, uint64_t size, uint64_t tweak) { return 0; }
|
||||
static inline void s390_pv_prep_reset(void) {}
|
||||
static inline int s390_pv_verify(void) { return 0; }
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 420bf75353286324822c3bbca3b52a7a56ed668c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Date: Tue, 5 Dec 2023 13:20:00 -0500
|
||||
Subject: [PATCH 083/101] tests: remove aio_context_acquire() tests
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 214: Remove AioContext lock
|
||||
RH-Jira: RHEL-15965
|
||||
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [14/26] f6421037c1523bc957f3be0f4ad05571ae012dba (kmwolf/centos-qemu-kvm)
|
||||
|
||||
The aio_context_acquire() API is being removed. Drop the test case that
|
||||
calls the API.
|
||||
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20231205182011.1976568-4-stefanha@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
tests/unit/test-aio.c | 67 +------------------------------------------
|
||||
1 file changed, 1 insertion(+), 66 deletions(-)
|
||||
|
||||
diff --git a/tests/unit/test-aio.c b/tests/unit/test-aio.c
|
||||
index 337b6e4ea7..e77d86be87 100644
|
||||
--- a/tests/unit/test-aio.c
|
||||
+++ b/tests/unit/test-aio.c
|
||||
@@ -100,76 +100,12 @@ static void event_ready_cb(EventNotifier *e)
|
||||
|
||||
/* Tests using aio_*. */
|
||||
|
||||
-typedef struct {
|
||||
- QemuMutex start_lock;
|
||||
- EventNotifier notifier;
|
||||
- bool thread_acquired;
|
||||
-} AcquireTestData;
|
||||
-
|
||||
-static void *test_acquire_thread(void *opaque)
|
||||
-{
|
||||
- AcquireTestData *data = opaque;
|
||||
-
|
||||
- /* Wait for other thread to let us start */
|
||||
- qemu_mutex_lock(&data->start_lock);
|
||||
- qemu_mutex_unlock(&data->start_lock);
|
||||
-
|
||||
- /* event_notifier_set might be called either before or after
|
||||
- * the main thread's call to poll(). The test case's outcome
|
||||
- * should be the same in either case.
|
||||
- */
|
||||
- event_notifier_set(&data->notifier);
|
||||
- aio_context_acquire(ctx);
|
||||
- aio_context_release(ctx);
|
||||
-
|
||||
- data->thread_acquired = true; /* success, we got here */
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
static void set_event_notifier(AioContext *nctx, EventNotifier *notifier,
|
||||
EventNotifierHandler *handler)
|
||||
{
|
||||
aio_set_event_notifier(nctx, notifier, handler, NULL, NULL);
|
||||
}
|
||||
|
||||
-static void dummy_notifier_read(EventNotifier *n)
|
||||
-{
|
||||
- event_notifier_test_and_clear(n);
|
||||
-}
|
||||
-
|
||||
-static void test_acquire(void)
|
||||
-{
|
||||
- QemuThread thread;
|
||||
- AcquireTestData data;
|
||||
-
|
||||
- /* Dummy event notifier ensures aio_poll() will block */
|
||||
- event_notifier_init(&data.notifier, false);
|
||||
- set_event_notifier(ctx, &data.notifier, dummy_notifier_read);
|
||||
- g_assert(!aio_poll(ctx, false)); /* consume aio_notify() */
|
||||
-
|
||||
- qemu_mutex_init(&data.start_lock);
|
||||
- qemu_mutex_lock(&data.start_lock);
|
||||
- data.thread_acquired = false;
|
||||
-
|
||||
- qemu_thread_create(&thread, "test_acquire_thread",
|
||||
- test_acquire_thread,
|
||||
- &data, QEMU_THREAD_JOINABLE);
|
||||
-
|
||||
- /* Block in aio_poll(), let other thread kick us and acquire context */
|
||||
- aio_context_acquire(ctx);
|
||||
- qemu_mutex_unlock(&data.start_lock); /* let the thread run */
|
||||
- g_assert(aio_poll(ctx, true));
|
||||
- g_assert(!data.thread_acquired);
|
||||
- aio_context_release(ctx);
|
||||
-
|
||||
- qemu_thread_join(&thread);
|
||||
- set_event_notifier(ctx, &data.notifier, NULL);
|
||||
- event_notifier_cleanup(&data.notifier);
|
||||
-
|
||||
- g_assert(data.thread_acquired);
|
||||
-}
|
||||
-
|
||||
static void test_bh_schedule(void)
|
||||
{
|
||||
BHTestData data = { .n = 0 };
|
||||
@@ -879,7 +815,7 @@ static void test_worker_thread_co_enter(void)
|
||||
qemu_thread_get_self(&this_thread);
|
||||
co = qemu_coroutine_create(co_check_current_thread, &this_thread);
|
||||
|
||||
- qemu_thread_create(&worker_thread, "test_acquire_thread",
|
||||
+ qemu_thread_create(&worker_thread, "test_aio_co_enter",
|
||||
test_aio_co_enter,
|
||||
co, QEMU_THREAD_JOINABLE);
|
||||
|
||||
@@ -899,7 +835,6 @@ int main(int argc, char **argv)
|
||||
while (g_main_context_iteration(NULL, false));
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
- g_test_add_func("/aio/acquire", test_acquire);
|
||||
g_test_add_func("/aio/bh/schedule", test_bh_schedule);
|
||||
g_test_add_func("/aio/bh/schedule10", test_bh_schedule10);
|
||||
g_test_add_func("/aio/bh/cancel", test_bh_cancel);
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,46 +0,0 @@
|
||||
From bbe64d706b3cb8b10ecd22bd71cf76b21eea257f Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 25 Jan 2024 17:58:03 +0100
|
||||
Subject: [PATCH 20/22] tests/unit: Bump test-replication timeout to 60 seconds
|
||||
|
||||
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-MergeRequest: 219: virtio-blk: add iothread-vq-mapping parameter
|
||||
RH-Jira: RHEL-17369 RHEL-20764 RHEL-7356
|
||||
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Commit: [16/17] 200768aedee44d10aa8d199b92a9c17a9002fc3f (stefanha/centos-stream-qemu-kvm)
|
||||
|
||||
We're seeing timeouts for this test on CI runs (specifically for
|
||||
ubuntu-20.04-s390x-all). It doesn't fail consistently, but even the
|
||||
successful runs take about 27 or 28 seconds, which is not very far from
|
||||
the 30 seconds timeout.
|
||||
|
||||
Bump the timeout a bit to make failure less likely even on this CI host.
|
||||
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240125165803.48373-1-kwolf@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 63b18312d14ac984acaf13c7c55d9baa2d61496e)
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
tests/unit/meson.build | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
|
||||
index a05d471090..28db6adea8 100644
|
||||
--- a/tests/unit/meson.build
|
||||
+++ b/tests/unit/meson.build
|
||||
@@ -173,7 +173,8 @@ test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
|
||||
|
||||
slow_tests = {
|
||||
'test-crypto-tlscredsx509': 45,
|
||||
- 'test-crypto-tlssession': 45
|
||||
+ 'test-crypto-tlssession': 45,
|
||||
+ 'test-replication': 60,
|
||||
}
|
||||
|
||||
foreach test_name, extra: tests
|
||||
--
|
||||
2.39.3
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 6e4f68e9ba3fe75ca6f200f189f96bb402f0ee8e Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Wed, 24 Jan 2024 11:57:49 +0100
|
||||
Subject: [PATCH 02/20] ui/clipboard: add asserts for update and request
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
||||
RH-MergeRequest: 228: ui/clipboard: mark type as not available when there is no data
|
||||
RH-Jira: RHEL-19629
|
||||
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
RH-Acked-by: Gerd Hoffmann <None>
|
||||
RH-Commit: [2/2] 176b4b835fd8aa226f2fa93fd334b9384080cf21 (jmaloy/jmaloy-qemu-kvm-2)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-19629
|
||||
CVE: CVE-2023-6683
|
||||
Upstream: Merged
|
||||
|
||||
ui/clipboard: add asserts for update and request
|
||||
|
||||
commit 9c416582611b7495bdddb4c5456c7acb64b78938
|
||||
Author: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Wed Jan 24 11:57:49 2024 +0100
|
||||
|
||||
ui/clipboard: add asserts for update and request
|
||||
|
||||
Should an issue like CVE-2023-6683 ever appear again in the future,
|
||||
it will be more obvious which assumption was violated.
|
||||
|
||||
Suggested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Message-ID: <20240124105749.204610-2-f.ebner@proxmox.com>
|
||||
|
||||
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
||||
---
|
||||
ui/clipboard.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/ui/clipboard.c b/ui/clipboard.c
|
||||
index b3f6fa3c9e..4264884a6c 100644
|
||||
--- a/ui/clipboard.c
|
||||
+++ b/ui/clipboard.c
|
||||
@@ -65,12 +65,24 @@ bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client)
|
||||
|
||||
void qemu_clipboard_update(QemuClipboardInfo *info)
|
||||
{
|
||||
+ uint32_t type;
|
||||
QemuClipboardNotify notify = {
|
||||
.type = QEMU_CLIPBOARD_UPDATE_INFO,
|
||||
.info = info,
|
||||
};
|
||||
assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
|
||||
|
||||
+ for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
|
||||
+ /*
|
||||
+ * If data is missing, the clipboard owner's 'request' callback needs to
|
||||
+ * be set. Otherwise, there is no way to get the clipboard data and
|
||||
+ * qemu_clipboard_request() cannot be called.
|
||||
+ */
|
||||
+ if (info->types[type].available && !info->types[type].data) {
|
||||
+ assert(info->owner && info->owner->request);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
notifier_list_notify(&clipboard_notifiers, ¬ify);
|
||||
|
||||
if (cbinfo[info->selection] != info) {
|
||||
@@ -132,6 +144,8 @@ void qemu_clipboard_request(QemuClipboardInfo *info,
|
||||
!info->owner)
|
||||
return;
|
||||
|
||||
+ assert(info->owner->request);
|
||||
+
|
||||
info->types[type].requested = true;
|
||||
info->owner->request(info, type);
|
||||
}
|
||||
--
|
||||
2.39.3
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user