diff --git a/.gitignore b/.gitignore index 49421e7..74aea26 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/qemu-9.0.0.tar.xz +SOURCES/qemu-9.1.0.tar.xz diff --git a/.qemu-kvm.metadata b/.qemu-kvm.metadata index 437fb86..e075286 100644 --- a/.qemu-kvm.metadata +++ b/.qemu-kvm.metadata @@ -1 +1 @@ -6699bb03d6da21159b89668bca01c6c958b95d07 SOURCES/qemu-9.0.0.tar.xz +d5bcdca53341c29470ef323191a3388fdb0571ed SOURCES/qemu-9.1.0.tar.xz diff --git a/SOURCES/0004-Initial-redhat-build.patch b/SOURCES/0004-Initial-redhat-build.patch index 49991a2..6fae1c6 100644 --- a/SOURCES/0004-Initial-redhat-build.patch +++ b/SOURCES/0004-Initial-redhat-build.patch @@ -1,4 +1,4 @@ -From ea7dff3dbf979d7d8a85a16cf5187235143e1048 Mon Sep 17 00:00:00 2001 +From cbd36e2ba7f3e96ce441c7cfbf92017a7ba3bfe8 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina 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.2.0-11.el9 +This rebase is based on qemu-kvm-9.0.0-10.el9 Signed-off-by: Miroslav Rezanina -- @@ -89,6 +89,10 @@ Rebase notes (9.0.0): - Package stp files for utilities - Download subprojects on local build +Rebase notes (9.1.0 rc0): +- Explicit BuildRequires for python3-tomli +- Removed --disable-avx512f configure option + Merged patches (6.0.0): - 605758c902 Limit build on Power to qemu-img and qemu-ga only @@ -209,18 +213,18 @@ Signed-off-by: Miroslav Rezanina .distro/README.tests | 39 + .distro/modules-load.conf | 4 + .distro/qemu-guest-agent.service | 1 - - .distro/qemu-kvm.spec.template | 5170 +++++++++++++++++++++++ + .distro/qemu-kvm.spec.template | 5351 +++++++++++++++++++++++ .distro/rpminspect.yaml | 6 +- .distro/scripts/extract_build_cmd.py | 12 + .distro/scripts/frh.py | 4 +- - .distro/scripts/process-patches.sh | 4 + + .distro/scripts/process-patches.sh | 6 +- .gitignore | 1 + README.systemtap | 43 + scripts/qemu-guest-agent/fsfreeze-hook | 2 +- 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, 5430 insertions(+), 6 deletions(-) + 16 files changed, 5612 insertions(+), 7 deletions(-) create mode 100644 .distro/Makefile create mode 100644 .distro/Makefile.common create mode 100644 .distro/README.tests diff --git a/SOURCES/0005-Enable-disable-devices-for-RHEL.patch b/SOURCES/0005-Enable-disable-devices-for-RHEL.patch index 61e84a1..0fdb361 100644 --- a/SOURCES/0005-Enable-disable-devices-for-RHEL.patch +++ b/SOURCES/0005-Enable-disable-devices-for-RHEL.patch @@ -1,4 +1,4 @@ -From 780c39975b059deaee106775b6e3a240155acea3 Mon Sep 17 00:00:00 2001 +From f9c7b0f1176bc2a0ddd97de6e0fbc1055eab7b57 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 7 Dec 2022 03:05:48 -0500 Subject: Enable/disable devices for RHEL @@ -53,6 +53,13 @@ Rebase notes (9.0.0 rc0): Rebase notes (9.0.0 rc1): - Do not compile armv7 cpu types +Rebase notes (9.1.0 rc0): +- Return value added for kvm_s390_apply_cpu_model +- Added new USB_HID and USB_HUB options + +Rebase notes (9.1.0 rc1): +- Fix disabling cpus in valid_cpy_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 @@ -87,14 +94,13 @@ Merged patches (9.0.0 rc0): - 2b4b13f70d Compile IOMMUFD object on aarch64 --- .distro/qemu-kvm.spec.template | 18 +-- - .../aarch64-softmmu/aarch64-rh-devices.mak | 42 +++++++ + .../aarch64-softmmu/aarch64-rh-devices.mak | 44 +++++++ .../ppc64-softmmu/ppc64-rh-devices.mak | 37 ++++++ configs/devices/rh-virtio.mak | 10 ++ .../s390x-softmmu/s390x-rh-devices.mak | 19 +++ - .../x86_64-softmmu/x86_64-rh-devices.mak | 112 ++++++++++++++++++ - hw/arm/virt.c | 2 + + .../x86_64-softmmu/x86_64-rh-devices.mak | 114 ++++++++++++++++++ + hw/arm/virt.c | 4 + 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 +- @@ -114,7 +120,7 @@ Merged patches (9.0.0 rc0): target/s390x/cpu_models_sysemu.c | 3 + target/s390x/kvm/kvm.c | 8 ++ tests/qtest/arm-cpu-features.c | 4 + - 28 files changed, 321 insertions(+), 17 deletions(-) + 27 files changed, 325 insertions(+), 16 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 @@ -123,10 +129,10 @@ Merged patches (9.0.0 rc0): 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..b0191d3c69 +index 0000000000..c7e4fdc25a --- /dev/null +++ b/configs/devices/aarch64-softmmu/aarch64-rh-devices.mak -@@ -0,0 +1,42 @@ +@@ -0,0 +1,44 @@ +include ../rh-virtio.mak + +CONFIG_ARM_GIC_KVM=y @@ -149,6 +155,8 @@ index 0000000000..b0191d3c69 +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_STORAGE_CORE=y +CONFIG_USB_STORAGE_CLASSIC=y ++CONFIG_USB_HUB=y ++CONFIG_USB_HID=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO_MMIO=y @@ -255,10 +263,10 @@ index 0000000000..24cf6dbd03 +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..d60ff1bcfc +index 0000000000..3e5f693b62 --- /dev/null +++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak -@@ -0,0 +1,112 @@ +@@ -0,0 +1,114 @@ +include ../rh-virtio.mak + +CONFIG_ACPI=y @@ -345,6 +353,8 @@ index 0000000000..d60ff1bcfc +CONFIG_USB_XHCI=y +CONFIG_USB_XHCI_NEC=y +CONFIG_USB_XHCI_PCI=y ++CONFIG_USB_HUB=y ++CONFIG_USB_HID=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VGA=y @@ -372,10 +382,10 @@ index 0000000000..d60ff1bcfc +CONFIG_VHOST_USER_FS=y +CONFIG_IOMMUFD=y diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index a9a913aead..6c6d155002 100644 +index 687fe0bb8b..eea7d2d038 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c -@@ -2954,6 +2954,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) +@@ -3032,6 +3032,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); static const char * const valid_cpu_types[] = { @@ -383,9 +393,13 @@ index a9a913aead..6c6d155002 100644 #ifdef CONFIG_TCG 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) +@@ -3047,8 +3048,11 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + ARM_CPU_TYPE_NAME("neoverse-n2"), + #endif /* TARGET_AARCH64 */ #endif /* CONFIG_TCG */ ++#endif /* disabled for RHEL */ #ifdef TARGET_AARCH64 ++#if 0 /* Disabled for Red Hat Enterprise Linux */ ARM_CPU_TYPE_NAME("cortex-a53"), +#endif /* disabled for RHEL */ ARM_CPU_TYPE_NAME("cortex-a57"), @@ -419,17 +433,6 @@ index 6dd94e98bc..a05757fc9a 100644 if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) { error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'"); return; -diff --git a/hw/cpu/meson.build b/hw/cpu/meson.build -index 38cdcfbe57..e588ecfd42 100644 ---- a/hw/cpu/meson.build -+++ b/hw/cpu/meson.build -@@ -1,4 +1,5 @@ --system_ss.add(files('core.c', 'cluster.c')) -+#system_ss.add(files('core.c', 'cluster.c')) -+system_ss.add(files('core.c')) - - system_ss.add(when: 'CONFIG_ARM11MPCORE', if_true: files('arm11mpcore.c')) - system_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_mpcore.c')) diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index 3e375f61a9..613adb3ebb 100644 --- a/hw/cxl/meson.build @@ -503,7 +506,7 @@ index 74f10b640f..2e85ecf476 100644 static const TypeInfo i8042_info = { diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index 43f3a4a701..267f182883 100644 +index 5012b96464..b435e54228 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -1746,6 +1746,7 @@ static const E1000Info e1000_devices[] = { @@ -523,10 +526,10 @@ index 43f3a4a701..267f182883 100644 static void e1000_register_types(void) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index e7c9edd033..3b0a47a28c 100644 +index 56090abcd1..0bf7c52077 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c -@@ -389,10 +389,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { +@@ -399,10 +399,12 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { .instance_size = sizeof(SpaprCpuCore), .class_size = sizeof(SpaprCpuCoreClass), }, @@ -540,7 +543,7 @@ index e7c9edd033..3b0a47a28c 100644 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 aac3bb35f2..5411ff35df 100644 +index d7de1003e3..1cdc0a1ba0 100644 --- a/hw/usb/meson.build +++ b/hw/usb/meson.build @@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_USB_SMARTCARD', if_true: files('dev-smartcard-reader @@ -553,7 +556,7 @@ index aac3bb35f2..5411ff35df 100644 endif diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index d7f18c96e6..aaabbb8b0b 100644 +index 621fc65454..c38bdd6fa4 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -20,7 +20,8 @@ if have_vhost @@ -597,10 +600,10 @@ index 3cc8cc738b..6f21fea1f5 100644 QAPI_LIST_PREPEND(*cpu_list, info); } diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index ab8d007a86..e5dce20f19 100644 +index 19191c2391..465f423d25 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c -@@ -2546,6 +2546,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) +@@ -2726,6 +2726,10 @@ static void cpu_register_class_init(ObjectClass *oc, void *data) acc->info = data; cc->gdb_core_xml_file = "arm-core.xml"; @@ -612,10 +615,10 @@ index ab8d007a86..e5dce20f19 100644 void arm_cpu_register(const ARMCPUInfo *info) diff --git a/target/arm/cpu.h b/target/arm/cpu.h -index bc0c84873f..e9472c8bb8 100644 +index 9a3fd59562..1261eae94d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h -@@ -37,6 +37,8 @@ +@@ -35,6 +35,8 @@ #define KVM_HAVE_MCE_INJECTION 1 #endif @@ -624,7 +627,7 @@ index bc0c84873f..e9472c8bb8 100644 #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ #define EXCP_PREFETCH_ABORT 3 -@@ -1092,6 +1094,7 @@ typedef struct ARMCPUInfo { +@@ -1110,6 +1112,7 @@ typedef struct ARMCPUInfo { const char *name; void (*initfn)(Object *obj); void (*class_init)(ObjectClass *oc, void *data); @@ -633,10 +636,10 @@ index bc0c84873f..e9472c8bb8 100644 /** diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 985b1efe16..46a4e80171 100644 +index 262a1d6c0b..800514d3fc 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c -@@ -648,6 +648,7 @@ static void aarch64_a57_initfn(Object *obj) +@@ -653,6 +653,7 @@ static void aarch64_a57_initfn(Object *obj) define_cortex_a72_a57_a53_cp_reginfo(cpu); } @@ -644,7 +647,7 @@ index 985b1efe16..46a4e80171 100644 static void aarch64_a53_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); -@@ -704,6 +705,7 @@ static void aarch64_a53_initfn(Object *obj) +@@ -710,6 +711,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->gic_pribits = 5; define_cortex_a72_a57_a53_cp_reginfo(cpu); } @@ -652,7 +655,7 @@ index 985b1efe16..46a4e80171 100644 static void aarch64_host_initfn(Object *obj) { -@@ -742,8 +744,11 @@ static void aarch64_max_initfn(Object *obj) +@@ -748,8 +750,11 @@ static void aarch64_max_initfn(Object *obj) } static const ARMCPUInfo aarch64_cpus[] = { @@ -665,7 +668,7 @@ index 985b1efe16..46a4e80171 100644 { .name = "max", .initfn = aarch64_max_initfn }, #if defined(CONFIG_KVM) || defined(CONFIG_HVF) { .name = "host", .initfn = aarch64_host_initfn }, -@@ -814,8 +819,13 @@ static void aarch64_cpu_instance_init(Object *obj) +@@ -820,8 +825,13 @@ static void aarch64_cpu_instance_init(Object *obj) static void cpu_register_class_init(ObjectClass *oc, void *data) { ARMCPUClass *acc = ARM_CPU_CLASS(oc); @@ -680,10 +683,10 @@ index 985b1efe16..46a4e80171 100644 void aarch64_cpu_register(const ARMCPUInfo *info) diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c -index de8f2be941..8896295ae3 100644 +index 20c2737f17..7e66fb6f14 100644 --- a/target/arm/tcg/cpu32.c +++ b/target/arm/tcg/cpu32.c -@@ -92,6 +92,7 @@ void aa32_max_features(ARMCPU *cpu) +@@ -120,6 +120,7 @@ void aa32_max_features(ARMCPU *cpu) cpu->isar.id_dfr1 = t; } @@ -691,13 +694,13 @@ index de8f2be941..8896295ae3 100644 /* CPU models. These are not needed for the AArch64 linux-user build. */ #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -@@ -1037,3 +1038,4 @@ static void arm_tcg_cpu_register_types(void) +@@ -1066,3 +1067,4 @@ static void arm_tcg_cpu_register_types(void) type_init(arm_tcg_cpu_register_types) #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 9f7a9f3d2c..7ec6851c9c 100644 +index fe232eb306..2678047488 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -29,6 +29,7 @@ @@ -708,7 +711,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644 static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize, unsigned cachesize) { -@@ -134,6 +135,7 @@ static void aarch64_a35_initfn(Object *obj) +@@ -135,6 +136,7 @@ static void aarch64_a35_initfn(Object *obj) /* These values are the same with A53/A57/A72. */ define_cortex_a72_a57_a53_cp_reginfo(cpu); } @@ -716,7 +719,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644 static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) -@@ -223,6 +225,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name, +@@ -224,6 +226,7 @@ static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name, static Property arm_cpu_lpa2_property = DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true); @@ -724,7 +727,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644 static void aarch64_a55_initfn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); -@@ -1065,6 +1068,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) +@@ -1074,6 +1077,7 @@ static void aarch64_neoverse_n2_initfn(Object *obj) aarch64_add_pauth_properties(obj); aarch64_add_sve_properties(obj); } @@ -732,7 +735,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644 /* * -cpu max: a CPU with as many features enabled as our emulation supports. -@@ -1271,6 +1275,7 @@ void aarch64_max_tcg_initfn(Object *obj) +@@ -1295,6 +1299,7 @@ void aarch64_max_tcg_initfn(Object *obj) qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property); } @@ -740,7 +743,7 @@ index 9f7a9f3d2c..7ec6851c9c 100644 static const ARMCPUInfo aarch64_cpus[] = { { .name = "cortex-a35", .initfn = aarch64_a35_initfn }, { .name = "cortex-a55", .initfn = aarch64_a55_initfn }, -@@ -1282,14 +1287,17 @@ static const ARMCPUInfo aarch64_cpus[] = { +@@ -1306,14 +1311,17 @@ static const ARMCPUInfo aarch64_cpus[] = { { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn }, { .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn }, }; @@ -759,10 +762,10 @@ index 9f7a9f3d2c..7ec6851c9c 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 +index 508932a249..7a12d7bfba 100644 --- a/target/arm/tcg/meson.build +++ b/target/arm/tcg/meson.build -@@ -56,5 +56,5 @@ arm_system_ss.add(files( +@@ -58,5 +58,5 @@ arm_system_ss.add(files( 'psci.c', )) @@ -834,7 +837,7 @@ index f2301b43f7..f77ebfcc81 100644 { NULL, NULL } }; diff --git a/target/s390x/cpu_models_sysemu.c b/target/s390x/cpu_models_sysemu.c -index 2d99218069..0728bfcc20 100644 +index f6df691b66..72572726b8 100644 --- a/target/s390x/cpu_models_sysemu.c +++ b/target/s390x/cpu_models_sysemu.c @@ -34,6 +34,9 @@ static void check_unavailable_features(const S390CPUModel *max_model, @@ -848,26 +851,26 @@ index 2d99218069..0728bfcc20 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 4ce809c5d4..55fb4855b1 100644 +index 94181d9281..45c23758e7 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c -@@ -2565,6 +2565,14 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) +@@ -2566,6 +2566,14 @@ bool kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) error_setg(errp, "KVM doesn't support CPU models"); - return; + return false; } + + /* Older CPU models are not supported on Red Hat Enterprise Linux */ + if (model->def->gen < 11) { + error_setg(errp, "KVM: Unsupported CPU type specified: %s", + MACHINE(qdev_get_machine())->cpu_type); -+ return; ++ return false; + } + prop.cpuid = s390_cpuid_from_cpu_model(model); prop.ibc = s390_ibc_from_cpu_model(model); /* configure cpu features indicated via STFL(e) */ diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c -index 9d6e6190d5..f822526acb 100644 +index cfd6f77353..3016e6233c 100644 --- a/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c @@ -452,8 +452,10 @@ static void test_query_cpu_model_expansion(const void *data) diff --git a/SOURCES/0006-Machine-type-related-general-changes.patch b/SOURCES/0006-Machine-type-related-general-changes.patch index e0c3795..2d6ee37 100644 --- a/SOURCES/0006-Machine-type-related-general-changes.patch +++ b/SOURCES/0006-Machine-type-related-general-changes.patch @@ -1,4 +1,4 @@ -From 8e6a30073f9c1a5d6294b2d16556522453e227e7 Mon Sep 17 00:00:00 2001 +From dc310c3f76c0d986ec4dc5a548a8ff37a85d61cf Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 11 Jan 2019 09:54:45 +0100 Subject: Machine type related general changes @@ -70,10 +70,14 @@ Merged patches (8.2.0): Merged patches (9.0.0 rc0): - 4b8fe42abc virtio-mem: default-enable "dynamic-memslots" + +Merged patches (9.1.0 rc0): +- 043ad5ce97 Add upstream compatibility bits (partial) +- 770eeed61e rhel 9.4.0 machine type compat for virtio-gpu migration --- hw/acpi/piix4.c | 2 +- - hw/arm/virt.c | 2 +- - hw/core/machine.c | 269 +++++++++++++++++++++++++++++++++++ + hw/arm/virt.c | 3 +- + hw/core/machine.c | 281 +++++++++++++++++++++++++++++++++++ hw/i386/fw_cfg.c | 3 +- hw/net/rtl8139.c | 4 +- hw/smbios/smbios.c | 46 +++++- @@ -81,10 +85,10 @@ Merged patches (9.0.0 rc0): 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/boards.h | 43 ++++++ include/hw/firmware/smbios.h | 4 +- include/hw/i386/pc.h | 3 + - 13 files changed, 414 insertions(+), 24 deletions(-) + 13 files changed, 430 insertions(+), 24 deletions(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index debe1adb84..e8ddcd716e 100644 @@ -100,23 +104,24 @@ index debe1adb84..e8ddcd716e 100644 .fields = (const VMStateField[]) { VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 6c6d155002..36e9b4b4e9 100644 +index eea7d2d038..b2aa3f1355 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c -@@ -1651,7 +1651,7 @@ static void virt_build_smbios(VirtMachineState *vms) +@@ -1699,7 +1699,8 @@ static void virt_build_smbios(VirtMachineState *vms) + } smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name, -- true); -+ true, NULL, NULL); +- vmc->smbios_old_sys_ver ? "1.0" : mc->name); ++ vmc->smbios_old_sys_ver ? "1.0" : mc->name, ++ NULL, NULL); /* build the array of physical mem area from base_memmap */ mem_array.address = vms->memmap[VIRT_MEM].base; diff --git a/hw/core/machine.c b/hw/core/machine.c -index 37ede0e7d4..695cb89a46 100644 +index 27dcda0248..f7fed78e4b 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c -@@ -296,6 +296,275 @@ GlobalProperty hw_compat_2_1[] = { +@@ -305,6 +305,287 @@ GlobalProperty hw_compat_2_1[] = { }; const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1); @@ -126,6 +131,18 @@ index 37ede0e7d4..695cb89a46 100644 +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" }, ++ /* hw_compat_rhel_9_5 from hw_compat_8_2 */ ++ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, ++}; ++const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5); ++ +GlobalProperty hw_compat_rhel_9_4[] = { + /* hw_compat_rhel_9_4 from hw_compat_8_0 */ + { TYPE_VIRTIO_NET, "host_uso", "off"}, @@ -393,24 +410,24 @@ index 37ede0e7d4..695cb89a46 100644 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 +index 0e4494627c..33ef280420 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, +@@ -73,7 +73,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, +- smbios_set_defaults("QEMU", mc->desc, mc->name); ++ smbios_set_defaults("QEMU", mc->desc, mc->name, + pcmc->smbios_stream_product, pcmc->smbios_stream_version); } /* tell smbios about cpuid version and features */ diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 897c86ec41..2d0db43f49 100644 +index 03a204ef8a..f2fe057535 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c -@@ -3169,7 +3169,7 @@ static int rtl8139_pre_save(void *opaque) +@@ -3173,7 +3173,7 @@ static int rtl8139_pre_save(void *opaque) static const VMStateDescription vmstate_rtl8139 = { .name = "rtl8139", @@ -419,7 +436,7 @@ index 897c86ec41..2d0db43f49 100644 .minimum_version_id = 3, .post_load = rtl8139_post_load, .pre_save = rtl8139_pre_save, -@@ -3250,7 +3250,9 @@ static const VMStateDescription vmstate_rtl8139 = { +@@ -3254,7 +3254,9 @@ static const VMStateDescription vmstate_rtl8139 = { VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State), VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State), VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State), @@ -430,10 +447,10 @@ index 897c86ec41..2d0db43f49 100644 VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index eed5787b15..68608a3403 100644 +index a394514264..88642ccce0 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c -@@ -39,6 +39,10 @@ size_t usr_blobs_len; +@@ -38,6 +38,10 @@ size_t usr_blobs_len; static unsigned usr_table_max; static unsigned usr_table_cnt; @@ -444,7 +461,7 @@ index eed5787b15..68608a3403 100644 uint8_t *smbios_tables; size_t smbios_tables_len; unsigned smbios_table_max; -@@ -629,7 +633,7 @@ static void smbios_build_type_1_table(void) +@@ -626,7 +630,7 @@ static void smbios_build_type_1_table(void) static void smbios_build_type_2_table(void) { @@ -453,17 +470,16 @@ index eed5787b15..68608a3403 100644 SMBIOS_TABLE_SET_STR(2, manufacturer_str, type2.manufacturer); SMBIOS_TABLE_SET_STR(2, product_str, type2.product); -@@ -1018,16 +1022,52 @@ void smbios_set_default_processor_family(uint16_t processor_family) +@@ -1014,15 +1018,51 @@ void smbios_set_default_processor_family(uint16_t processor_family) + } void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, -- bool uuid_encoded) -+ bool uuid_encoded, +- const char *version) ++ const char *version, + const char *stream_product, + const char *stream_version) { smbios_have_defaults = true; - smbios_uuid_encoded = uuid_encoded; + /* + * If @stream_product & @stream_version are non-NULL, then @@ -522,7 +538,7 @@ index 28fdabc321..bad13ec224 100644 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 4423983308..43b4b71fdf 100644 +index 264d7ebb77..2b9a3e06d4 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) @@ -586,7 +602,7 @@ index 4423983308..43b4b71fdf 100644 } pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | -@@ -154,6 +170,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) +@@ -153,6 +169,14 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp) assert(ret > 0); } @@ -601,7 +617,7 @@ index 4423983308..43b4b71fdf 100644 if (s->msix != ON_OFF_AUTO_OFF) { /* TODO check for errors, and should fail when msix=on */ msix_init(dev, s->xhci.numintrs, -@@ -198,11 +222,18 @@ static void xhci_instance_init(Object *obj) +@@ -197,11 +221,18 @@ static void xhci_instance_init(Object *obj) qdev_alias_all_properties(DEVICE(&s->xhci), obj); } @@ -633,7 +649,7 @@ index 08f70ce97c..1be7527c1b 100644 #endif diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c -index ffd119ebac..0e2be2219c 100644 +index ef64bf1b4a..ba11aa4646 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -1694,8 +1694,9 @@ static Property virtio_mem_properties[] = { @@ -648,13 +664,16 @@ index ffd119ebac..0e2be2219c 100644 }; diff --git a/include/hw/boards.h b/include/hw/boards.h -index 8b8f6d5c00..0466f9d0f3 100644 +index 48ff6d8b93..ccfc3e10eb 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h -@@ -512,4 +512,44 @@ extern const size_t hw_compat_2_2_len; +@@ -822,4 +822,47 @@ extern const size_t hw_compat_2_2_len; extern GlobalProperty hw_compat_2_1[]; extern 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; + @@ -697,27 +716,27 @@ index 8b8f6d5c00..0466f9d0f3 100644 +extern const char *rhel_old_machine_deprecation; #endif diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 8d3fb2fb3b..d9d6d7a169 100644 +index f066ab7262..e805d25fbe 100644 --- a/include/hw/firmware/smbios.h +++ b/include/hw/firmware/smbios.h -@@ -332,7 +332,9 @@ void smbios_entry_add(QemuOpts *opts, Error **errp); +@@ -331,7 +331,9 @@ void smbios_add_usr_blob_size(size_t size); + void smbios_entry_add(QemuOpts *opts, Error **errp); void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, -- bool uuid_encoded); -+ bool uuid_encoded, +- const char *version); ++ const char *version, + const char *stream_product, + const char *stream_version); void smbios_set_default_processor_family(uint16_t processor_family); uint8_t *smbios_get_table_legacy(size_t *length, Error **errp); void smbios_get_tables(MachineState *ms, diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 27a68071d7..ebd8f973f2 100644 +index 4e55d7ef6e..8776a3c937 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h -@@ -112,6 +112,9 @@ struct PCMachineClass { +@@ -103,6 +103,9 @@ struct PCMachineClass { + bool smbios_defaults; bool smbios_legacy_mode; - bool smbios_uuid_encoded; SmbiosEntryPointType default_smbios_ep_type; + /* New fields needed for Windows HardwareID-6 matching */ + const char *smbios_stream_product; diff --git a/SOURCES/0007-Add-aarch64-machine-types.patch b/SOURCES/0007-Add-aarch64-machine-types.patch deleted file mode 100644 index a556bb2..0000000 --- a/SOURCES/0007-Add-aarch64-machine-types.patch +++ /dev/null @@ -1,496 +0,0 @@ -From cf398296f3fcee185a00f23de5deae57c97d648e Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 12:53:31 +0200 -Subject: Add aarch64 machine types - -Adding changes to add RHEL machine types for aarch64 architecture. - -Signed-off-by: Miroslav Rezanina ---- -Rebase notes (6.1.0): -- Use CONFIG_TPM check when using TPM structures -- Add support for default_bus_bypass_iommu -- ea4c0b32d9 arm/virt: Register highmem and gic-version as class properties -- 895e1fa86a hw/arm/virt: Add 8.5 and 9.0 machine types and remove older ones - -Rebase notes (7.0.0): -- Added dtb-kaslr-seed option -- Set no_tcg_lpa2 to true - -Rebase notes (7.1.0): -- replace dtb_kaslr_seed by dtb_randomness -- Updated dtb_randomness comment - -Rebase notes (7.2.0): -- Disabled cortex-a35 - -Rebase notes (8.0.0): -- Moved changed code from target/arm/helper.c to target/arm/arm-qmp-cmds.c - -Rebase notes (8.1.0): -- Added setting default_nic - -Rebase notes (9.0.0 rc0): -- call arm_virt_compat_set on rhel type class_init - -Merged patches (6.2.0): -- 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type -- f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type - -Merged patches (7.0.0): -- 3b82be3dd3 redhat: virt-rhel8.5.0: Update machine type compatibility for QEMU 6.2.0 update -- c354a86c9b hw/arm/virt: Register "iommu" as a class property -- c1a2630dc9 hw/arm/virt: Register "its" as a class property -- 9d8c61dc93 hw/arm/virt: Rename default_bus_bypass_iommu -- a1d1b6eeb6 hw/arm/virt: Expose the 'RAS' option -- 47f8fe1b82 hw/arm/virt: Add 9.0 machine type and remove 8.5 one -- ed2346788f hw/arm/virt: Check no_tcg_its and minor style changes - -Merged patches (7.0.0): -- f79b31bdef hw/arm/virt: Remove the dtb-kaslr-seed machine option -- b6fca85f4a hw/arm/virt: Fix missing initialization in instance/class_init() - -Merged patches (7.1.0): -- ac97dd4f9f RHEL-only: AArch64: Drop unsupported CPU types -- e9c0a70664 target/arm: deprecate named CPU models - -Merged patches (7.2.0): -- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts) - -Merged patches (8.0.0): -- c1a21266d8 redhat: aarch64: add rhel9.2.0 virt machine type -- d97cd7c513 redhat: fix virt-rhel9.2.0 compat props - -Merged patches (8.1.0): -- bd5d81d286 Add RHEL 9.2.0 compat structure (arm part) -- c07f666086 hw/arm/virt: Validate cluster and NUMA node boundary for RHEL machines - -Merged patches (8.2.0): -- 4ee284aca9 Add machine types compat bits. (partial) - -Merged patches (9.0.0 rc0): -- 117068376a hw/arm/virt: Fix compats -- 8bcccfabc4 hw/arm/virt: Add properties to disable high memory regions -- 0005a8b93a hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types ---- - hw/arm/virt.c | 299 +++++++++++++++++++++++++++++++++++++++++- - include/hw/arm/virt.h | 8 ++ - 2 files changed, 306 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 36e9b4b4e9..22bc345137 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -101,6 +101,7 @@ static void arm_virt_compat_set(MachineClass *mc) - arm_virt_compat_len); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ - static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ - void *data) \ -@@ -128,7 +129,63 @@ static void arm_virt_compat_set(MachineClass *mc) - DEFINE_VIRT_MACHINE_LATEST(major, minor, true) - #define DEFINE_VIRT_MACHINE(major, minor) \ - DEFINE_VIRT_MACHINE_LATEST(major, minor, false) -+#endif /* disabled for RHEL */ -+ -+/* -+ * This variable is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. They may be overriden by older machine compats. -+ * -+ * virtio-net-pci variant romfiles are not needed because edk2 does -+ * fully support the pxe boot. Besides virtio romfiles are not shipped -+ * on rhel/aarch64. -+ */ -+GlobalProperty arm_rhel_compat[] = { -+ {"virtio-net-pci", "romfile", "" }, -+ {"virtio-net-pci-transitional", "romfile", "" }, -+ {"virtio-net-pci-non-transitional", "romfile", "" }, -+}; -+const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); - -+/* -+ * This cannot be called from the rhel_virt_class_init() because -+ * TYPE_RHEL_MACHINE is abstract and mc->compat_props g_ptr_array_new() -+ * only is called on virt-rhelm.n.s non abstract class init. -+ */ -+static void arm_rhel_compat_set(MachineClass *mc) -+{ -+ compat_props_add(mc->compat_props, arm_rhel_compat, -+ arm_rhel_compat_len); -+} -+ -+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ -+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ -+ void *data) \ -+ { \ -+ MachineClass *mc = MACHINE_CLASS(oc); \ -+ arm_rhel_compat_set(mc); \ -+ rhel##m##n##s##_virt_options(mc); \ -+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ -+ if (latest) { \ -+ mc->alias = "virt"; \ -+ mc->is_default = 1; \ -+ } \ -+ } \ -+ static const TypeInfo rhel##m##n##s##_machvirt_info = { \ -+ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \ -+ .parent = TYPE_RHEL_MACHINE, \ -+ .class_init = rhel##m##n##s##_virt_class_init, \ -+ }; \ -+ static void rhel##m##n##s##_machvirt_init(void) \ -+ { \ -+ type_register_static(&rhel##m##n##s##_machvirt_info); \ -+ } \ -+ type_init(rhel##m##n##s##_machvirt_init); -+ -+#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) -+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) - - /* Number of external interrupt lines to configure the GIC with */ - #define NUM_IRQS 256 -@@ -2355,6 +2412,7 @@ static void machvirt_init(MachineState *machine) - qemu_add_machine_init_done_notifier(&vms->machine_done); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_secure(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2382,6 +2440,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) - - vms->virt = value; - } -+#endif /* disabled for RHEL */ - - static bool virt_get_highmem(Object *obj, Error **errp) - { -@@ -2397,6 +2456,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) - vms->highmem = value; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_compact_highmem(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2410,6 +2470,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) - - vms->highmem_compact = value; - } -+#endif /* disabled for RHEL */ - - static bool virt_get_highmem_redists(Object *obj, Error **errp) - { -@@ -2453,7 +2514,6 @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) - vms->highmem_mmio = value; - } - -- - static bool virt_get_its(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2468,6 +2528,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp) - vms->its = value; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_dtb_randomness(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2481,6 +2542,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) - - vms->dtb_randomness = value; - } -+#endif /* disabled for RHEL */ - - static char *virt_get_oem_id(Object *obj, Error **errp) - { -@@ -2564,6 +2626,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) - vms->ras = value; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static bool virt_get_mte(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -2577,6 +2640,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) - - vms->mte = value; - } -+#endif /* disabled for RHEL */ - - static char *virt_get_gic_version(Object *obj, Error **errp) - { -@@ -2949,6 +3013,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) - return fixed_ipa ? 0 : requested_pa_size; - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void virt_machine_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); -@@ -3463,3 +3528,235 @@ static void virt_machine_2_6_options(MachineClass *mc) - vmc->no_pmu = true; - } - DEFINE_VIRT_MACHINE(2, 6) -+#endif /* disabled for RHEL */ -+ -+static void rhel_machine_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); -+ arm_virt_compat_set(mc); -+ -+ mc->family = "virt-rhel-Z"; -+ mc->init = machvirt_init; -+ /* Maximum supported VCPU count for all virt-rhel* machines */ -+ mc->max_cpus = 384; -+#ifdef CONFIG_TPM -+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); -+#endif -+ mc->block_default_type = IF_VIRTIO; -+ mc->no_cdrom = 1; -+ mc->pci_allow_0_address = true; -+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */ -+ mc->minimum_page_bits = 12; -+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; -+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props; -+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); -+ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; -+ mc->kvm_type = virt_kvm_type; -+ assert(!mc->get_hotplug_handler); -+ mc->get_hotplug_handler = virt_machine_get_hotplug_handler; -+ hc->pre_plug = virt_machine_device_pre_plug_cb; -+ hc->plug = virt_machine_device_plug_cb; -+ hc->unplug_request = virt_machine_device_unplug_request_cb; -+ hc->unplug = virt_machine_device_unplug_cb; -+ mc->nvdimm_supported = true; -+ mc->smp_props.clusters_supported = true; -+ mc->auto_enable_numa_with_memhp = true; -+ mc->auto_enable_numa_with_memdev = true; -+ /* platform instead of architectural choice */ -+ mc->cpu_cluster_has_numa_boundary = true; -+ mc->default_ram_id = "mach-virt.ram"; -+ mc->default_nic = "virtio-net-pci"; -+ -+ object_class_property_add(oc, "acpi", "OnOffAuto", -+ virt_get_acpi, virt_set_acpi, -+ NULL, NULL); -+ object_class_property_set_description(oc, "acpi", -+ "Enable ACPI"); -+ -+ object_class_property_add_bool(oc, "highmem", virt_get_highmem, -+ virt_set_highmem); -+ object_class_property_set_description(oc, "highmem", -+ "Set on/off to enable/disable using " -+ "physical address space above 32 bits"); -+ -+ object_class_property_add_bool(oc, "highmem-redists", -+ virt_get_highmem_redists, -+ virt_set_highmem_redists); -+ object_class_property_set_description(oc, "highmem-redists", -+ "Set on/off to enable/disable high " -+ "memory region for GICv3 or GICv4 " -+ "redistributor"); -+ -+ object_class_property_add_bool(oc, "highmem-ecam", -+ virt_get_highmem_ecam, -+ virt_set_highmem_ecam); -+ object_class_property_set_description(oc, "highmem-ecam", -+ "Set on/off to enable/disable high " -+ "memory region for PCI ECAM"); -+ -+ object_class_property_add_bool(oc, "highmem-mmio", -+ virt_get_highmem_mmio, -+ virt_set_highmem_mmio); -+ object_class_property_set_description(oc, "highmem-mmio", -+ "Set on/off to enable/disable high " -+ "memory region for PCI MMIO"); -+ -+ object_class_property_add_str(oc, "gic-version", virt_get_gic_version, -+ virt_set_gic_version); -+ object_class_property_set_description(oc, "gic-version", -+ "Set GIC version. " -+ "Valid values are 2, 3, host and max"); -+ -+ object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu); -+ object_class_property_set_description(oc, "iommu", -+ "Set the IOMMU type. " -+ "Valid values are none and smmuv3"); -+ -+ object_class_property_add_bool(oc, "default-bus-bypass-iommu", -+ virt_get_default_bus_bypass_iommu, -+ virt_set_default_bus_bypass_iommu); -+ object_class_property_set_description(oc, "default-bus-bypass-iommu", -+ "Set on/off to enable/disable " -+ "bypass_iommu for default root bus"); -+ -+ object_class_property_add_bool(oc, "ras", virt_get_ras, -+ virt_set_ras); -+ object_class_property_set_description(oc, "ras", -+ "Set on/off to enable/disable reporting host memory errors " -+ "to a KVM guest using ACPI and guest external abort exceptions"); -+ -+ object_class_property_add_bool(oc, "its", virt_get_its, -+ virt_set_its); -+ object_class_property_set_description(oc, "its", -+ "Set on/off to enable/disable " -+ "ITS instantiation"); -+ -+ object_class_property_add_str(oc, "x-oem-id", -+ virt_get_oem_id, -+ virt_set_oem_id); -+ object_class_property_set_description(oc, "x-oem-id", -+ "Override the default value of field OEMID " -+ "in ACPI table header." -+ "The string may be up to 6 bytes in size"); -+ -+ -+ object_class_property_add_str(oc, "x-oem-table-id", -+ virt_get_oem_table_id, -+ virt_set_oem_table_id); -+ object_class_property_set_description(oc, "x-oem-table-id", -+ "Override the default value of field OEM Table ID " -+ "in ACPI table header." -+ "The string may be up to 8 bytes in size"); -+} -+ -+static void rhel_virt_instance_init(Object *obj) -+{ -+ VirtMachineState *vms = VIRT_MACHINE(obj); -+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); -+ -+ /* EL3 is disabled by default and non-configurable for RHEL */ -+ vms->secure = false; -+ -+ /* EL2 is disabled by default and non-configurable for RHEL */ -+ vms->virt = false; -+ -+ /* High memory is enabled by default */ -+ vms->highmem = true; -+ vms->highmem_compact = !vmc->no_highmem_compact; -+ vms->gic_version = VIRT_GIC_VERSION_NOSEL; -+ -+ vms->highmem_ecam = !vmc->no_highmem_ecam; -+ vms->highmem_mmio = true; -+ vms->highmem_redists = true; -+ -+ if (vmc->no_its) { -+ vms->its = false; -+ } else { -+ /* Default allows ITS instantiation */ -+ vms->its = true; -+ -+ if (vmc->no_tcg_its) { -+ vms->tcg_its = false; -+ } else { -+ vms->tcg_its = true; -+ } -+ } -+ -+ /* Default disallows iommu instantiation */ -+ vms->iommu = VIRT_IOMMU_NONE; -+ -+ /* The default root bus is attached to iommu by default */ -+ vms->default_bus_bypass_iommu = false; -+ -+ /* Default disallows RAS instantiation and is non-configurable for RHEL */ -+ vms->ras = false; -+ -+ /* MTE is disabled by default and non-configurable for RHEL */ -+ vms->mte = false; -+ -+ /* Supply kaslr-seed and rng-seed by default, non-configurable for RHEL */ -+ vms->dtb_randomness = true; -+ -+ vms->irqmap = a15irqmap; -+ -+ virt_flash_create(vms); -+ -+ vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); -+ vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); -+} -+ -+static const TypeInfo rhel_machine_info = { -+ .name = TYPE_RHEL_MACHINE, -+ .parent = TYPE_MACHINE, -+ .abstract = true, -+ .instance_size = sizeof(VirtMachineState), -+ .class_size = sizeof(VirtMachineClass), -+ .class_init = rhel_machine_class_init, -+ .instance_init = rhel_virt_instance_init, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_HOTPLUG_HANDLER }, -+ { } -+ }, -+}; -+ -+static void rhel_machine_init(void) -+{ -+ type_register_static(&rhel_machine_info); -+} -+type_init(rhel_machine_init); -+ -+static void rhel940_virt_options(MachineClass *mc) -+{ -+} -+DEFINE_RHEL_MACHINE_AS_LATEST(9, 4, 0) -+ -+static void rhel920_virt_options(MachineClass *mc) -+{ -+ rhel940_virt_options(mc); -+ -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); -+ -+ /* RHEL 9.4 is the first supported release */ -+ mc->deprecation_reason = -+ "machine types for versions prior to 9.4 are deprecated"; -+} -+DEFINE_RHEL_MACHINE(9, 2, 0) -+ -+static void rhel900_virt_options(MachineClass *mc) -+{ -+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); -+ -+ rhel920_virt_options(mc); -+ -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); -+ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); -+ -+ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ -+ vmc->no_tcg_lpa2 = true; -+ /* Compact layout for high memory regions was introduced with 9.2.0 */ -+ vmc->no_highmem_compact = true; -+} -+DEFINE_RHEL_MACHINE(9, 0, 0) -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index bb486d36b1..237fc77bda 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -179,9 +179,17 @@ struct VirtMachineState { - - #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) - -+#if 0 /* disabled for Red Hat Enterprise Linux */ - #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") - OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) - -+#else -+#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel") -+typedef struct VirtMachineClass VirtMachineClass; -+typedef struct VirtMachineState VirtMachineState; -+DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_RHEL_MACHINE) -+#endif -+ - void virt_acpi_setup(VirtMachineState *vms); - bool virt_is_acpi_enabled(VirtMachineState *vms); - --- -2.39.3 - diff --git a/SOURCES/0007-meson-temporarily-disable-Wunused-function.patch b/SOURCES/0007-meson-temporarily-disable-Wunused-function.patch new file mode 100644 index 0000000..0716188 --- /dev/null +++ b/SOURCES/0007-meson-temporarily-disable-Wunused-function.patch @@ -0,0 +1,36 @@ +From 8781d75adf542ea09e62a0cafd0c79875015a272 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:32:32 +0100 +Subject: meson: temporarily disable -Wunused-function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Deleting the upstream versioned machine types will leave some functions +unused until RHEL machine types are added once again. Temporarily +disable the -Wunused-function warning to preserve bisectability with +fine grained patch splits. + +Signed-off-by: Daniel P. Berrangé + +Rebase notes (9.1.0 rc0) +- New patch +--- + meson.build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/meson.build b/meson.build +index fbda17c987..161d496d55 100644 +--- a/meson.build ++++ b/meson.build +@@ -651,6 +651,7 @@ warn_flags = [ + '-Wno-string-plus-int', + '-Wno-tautological-type-limit-compare', + '-Wno-typedef-redefinition', ++ '-Wno-unused-function', + ] + + if host_os != 'darwin' +-- +2.39.3 + diff --git a/SOURCES/0008-Remove-upstream-machine-type-versions-for-aarch64-s3.patch b/SOURCES/0008-Remove-upstream-machine-type-versions-for-aarch64-s3.patch new file mode 100644 index 0000000..2590cc4 --- /dev/null +++ b/SOURCES/0008-Remove-upstream-machine-type-versions-for-aarch64-s3.patch @@ -0,0 +1,139 @@ +From c5e6c533f498a698ef6797f58f3f8aced62476fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:25:13 +0100 +Subject: Remove upstream machine type versions for aarch64, s390x and x86_64 + architectures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The upstream versions will later be replaced by RHEL machine type +definitions. + +Signed-off-by: Daniel P. Berrangé +Signed-off-by: Mirslav Rezanina + +Rebase notes (9.1.0 rc0) + - Split off from downstream machine type addition patch +--- + hw/arm/virt.c | 2 ++ + hw/i386/pc_piix.c | 2 ++ + hw/i386/pc_q35.c | 2 ++ + hw/ppc/spapr.c | 5 +++++ + hw/s390x/s390-virtio-ccw.c | 2 ++ + 5 files changed, 13 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index b2aa3f1355..5396e7cb24 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -3306,6 +3306,7 @@ static void machvirt_machine_init(void) + } + type_init(machvirt_machine_init); + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void virt_machine_9_1_options(MachineClass *mc) + { + } +@@ -3552,3 +3553,4 @@ static void virt_machine_2_6_options(MachineClass *mc) + vmc->no_pmu = true; + } + DEFINE_VIRT_MACHINE(2, 6) ++#endif /* disabled for RHEL */ +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 347afa4c37..67107b174a 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -448,6 +448,7 @@ static void pc_i440fx_init(MachineState *machine) + #define DEFINE_I440FX_MACHINE(major, minor) \ + DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor); + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void pc_i440fx_machine_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); +@@ -775,6 +776,7 @@ static void pc_i440fx_machine_2_4_options(MachineClass *m) + } + + DEFINE_I440FX_MACHINE(2, 4); ++#endif /* Disabled for Red Hat Enterprise Linux */ + + #ifdef CONFIG_ISAPC + static void isapc_machine_options(MachineClass *m) +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index f2d8edfa84..5fb283f2df 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -356,6 +356,7 @@ static void pc_q35_machine_options(MachineClass *m) + pc_q35_compat_defaults, pc_q35_compat_defaults_len); + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void pc_q35_machine_9_1_options(MachineClass *m) + { + pc_q35_machine_options(m); +@@ -668,3 +669,4 @@ static void pc_q35_machine_2_4_options(MachineClass *m) + } + + DEFINE_Q35_MACHINE(2, 4); ++#endif /* Disabled for Red Hat Enterprise Linux */ +diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c +index 370d7c35d3..b48a2afc38 100644 +--- a/hw/ppc/spapr.c ++++ b/hw/ppc/spapr.c +@@ -4837,6 +4837,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) + #define DEFINE_SPAPR_MACHINE_TAGGED(major, minor, tag) \ + DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, _, tag) + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + /* + * pseries-9.1 + */ +@@ -5041,6 +5042,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) + } + + DEFINE_SPAPR_MACHINE(4, 1); ++#endif /* disabled for RHEL */ + + /* + * pseries-4.0 +@@ -5056,6 +5058,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, + } + return true; + } ++ ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void spapr_machine_4_0_class_options(MachineClass *mc) + { + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); +@@ -5380,6 +5384,7 @@ 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); ++#endif /* disabled for RHEL */ + + static void spapr_machine_register_types(void) + { +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index c483ff8064..86bfc9d2eb 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -871,6 +871,7 @@ static const TypeInfo ccw_machine_info = { + DEFINE_CCW_MACHINE_IMPL(false, major, minor) + + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void ccw_machine_9_1_instance_options(MachineState *machine) + { + } +@@ -1305,6 +1306,7 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) + DEFINE_CCW_MACHINE(2, 4); + + #endif ++#endif /* disabled for RHEL */ + + static void ccw_machine_register_types(void) + { +-- +2.39.3 + diff --git a/SOURCES/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch b/SOURCES/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch new file mode 100644 index 0000000..e5b4b10 --- /dev/null +++ b/SOURCES/0009-Adapt-versioned-machine-type-macros-for-RHEL.patch @@ -0,0 +1,195 @@ +From 3cb90f2fec9096ddde4038e037e82a9c44614791 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 15:27:03 +0100 +Subject: Adapt versioned machine type macros for RHEL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The versioned machine type macros are changed thus: + + * All symbol names get 'rhel' inserted eg 'virt_rhel_macine_9_4_0_' + * All machine type names get 'rhel' inserted eg 'virt-rhel9.4.0-machine' + * Lifecycle is changed to deprecate after 1 major RHEL release, + force non-registration (effectively deletion) after 2 major releases + * Custom message to explain RHEL deprecation/deletion policy + * Remove upstream logic that temporarily disabled deletion since + the upstream constraints in this area don't apply to RHEL + * For automatic deprecation/deletion, RHEL_VERSION is defined + +Signed-off-by: Daniel P. Berrangé +Signed-off-by: Miroslav Rezanina +--- + .distro/Makefile.common | 1 + + .distro/qemu-kvm.spec.template | 1 + + include/hw/boards.h | 60 +++++++++++----------------------- + meson.build | 1 + + meson_options.txt | 2 ++ + scripts/meson-buildoptions.sh | 2 ++ + 6 files changed, 26 insertions(+), 41 deletions(-) + +diff --git a/include/hw/boards.h b/include/hw/boards.h +index ccfc3e10eb..7f7eb4ec40 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -548,16 +548,16 @@ struct MachineState { + * "{prefix}-{major}.{minor}.{micro}-{tag}" + */ + #define _MACHINE_VER_TYPE_NAME2(prefix, major, minor) \ +- prefix "-" #major "." #minor TYPE_MACHINE_SUFFIX ++ prefix "-rhel" #major "." #minor TYPE_MACHINE_SUFFIX + + #define _MACHINE_VER_TYPE_NAME3(prefix, major, minor, micro) \ +- prefix "-" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX ++ prefix "-rhel" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX + + #define _MACHINE_VER_TYPE_NAME4(prefix, major, minor, _unused_, tag) \ +- prefix "-" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX ++ prefix "-rhel" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX + + #define _MACHINE_VER_TYPE_NAME5(prefix, major, minor, micro, _unused_, tag) \ +- prefix "-" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX ++ prefix "-rhel" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX + + #define MACHINE_VER_TYPE_NAME(prefix, ...) \ + _MACHINE_VER_PICK(__VA_ARGS__, \ +@@ -585,16 +585,16 @@ struct MachineState { + * {prefix}_machine_{major}_{minor}_{micro}_{tag}_{sym} + */ + #define _MACHINE_VER_SYM2(sym, prefix, major, minor) \ +- prefix ## _machine_ ## major ## _ ## minor ## _ ## sym ++ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## sym + + #define _MACHINE_VER_SYM3(sym, prefix, major, minor, micro) \ +- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym ++ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym + + #define _MACHINE_VER_SYM4(sym, prefix, major, minor, _unused_, tag) \ +- prefix ## _machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym ++ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym + + #define _MACHINE_VER_SYM5(sym, prefix, major, minor, micro, _unused_, tag) \ +- prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym ++ prefix ## _rhel_machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym + + #define MACHINE_VER_SYM(sym, prefix, ...) \ + _MACHINE_VER_PICK(__VA_ARGS__, \ +@@ -605,26 +605,22 @@ struct MachineState { + + + /* +- * How many years/major releases for each phase +- * of the life cycle. Assumes use of versioning +- * scheme where major is bumped each year ++ * How many RHEL major releases for each phase ++ * of the life cycle. + */ +-#define MACHINE_VER_DELETION_MAJOR 6 +-#define MACHINE_VER_DEPRECATION_MAJOR 3 ++#define MACHINE_VER_DELETION_MAJOR 2 ++#define MACHINE_VER_DEPRECATION_MAJOR 1 + + /* + * Expands to a static string containing a deprecation + * message for a versioned machine type + */ + #define MACHINE_VER_DEPRECATION_MSG \ +- "machines more than " stringify(MACHINE_VER_DEPRECATION_MAJOR) \ +- " years old are subject to deletion after " \ +- stringify(MACHINE_VER_DELETION_MAJOR) " years" ++ "machines from the previous RHEL major release are " \ ++ "subject to deletion in the next RHEL major release" + + #define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \ +- (((QEMU_VERSION_MAJOR - major) > cutoff) || \ +- (((QEMU_VERSION_MAJOR - major) == cutoff) && \ +- (QEMU_VERSION_MINOR - minor) >= 0)) ++ ((RHEL_VERSION - major) >= cutoff) + + #define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \ + _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) +@@ -686,32 +682,14 @@ struct MachineState { + * This must be unconditionally used in the register + * method for all machine types which support versioning. + * +- * Inijtially it will effectively be a no-op, but after a +- * suitable period of time has passed, it will cause +- * execution of the method to return, avoiding registration +- * of the machine +- * +- * The new deprecation and deletion policy for versioned +- * machine types was introduced in QEMU 9.1.0. +- * +- * Under the new policy a number of old machine types (any +- * prior to 2.12) would be liable for immediate deletion +- * which would be a violation of our historical deprecation +- * and removal policy +- * +- * Thus deletions are temporarily gated on existance of +- * the env variable "QEMU_DELETE_MACHINES" / QEMU version +- * number >= 10.1.0. This gate can be deleted in the 10.1.0 +- * dev cycle ++ * It will automatically avoid registration of machines ++ * that should have been deleted at the start of this ++ * RHEL release + */ + #define MACHINE_VER_DELETION(...) \ + do { \ + if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \ +- if (getenv("QEMU_DELETE_MACHINES") || \ +- QEMU_VERSION_MAJOR > 10 || (QEMU_VERSION_MAJOR == 10 && \ +- QEMU_VERSION_MINOR >= 1)) { \ +- return; \ +- } \ ++ return; \ + } \ + } while (0) + +diff --git a/meson.build b/meson.build +index 161d496d55..2de5ab024f 100644 +--- a/meson.build ++++ b/meson.build +@@ -2440,6 +2440,7 @@ config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) + config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) + config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) + config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) ++config_host_data.set('RHEL_VERSION', get_option('rhel_version').split('.')[0]) + + config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) + config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) +diff --git a/meson_options.txt b/meson_options.txt +index 0269fa0f16..aa2ba0baef 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -2,6 +2,8 @@ + # on the configure script command line. If you add more, list them in + # scripts/meson-buildoptions.py's SKIP_OPTIONS constant too. + ++option('rhel_version', type: 'string', value: '0.0', ++ description: 'RHEL major/minor version') + option('qemu_suffix', type : 'string', value: 'qemu', + description: 'Suffix for QEMU data/modules/config directories (can be empty)') + option('docdir', type : 'string', value : 'share/doc', +diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh +index c97079a38c..5f0cbfc725 100644 +--- a/scripts/meson-buildoptions.sh ++++ b/scripts/meson-buildoptions.sh +@@ -71,6 +71,7 @@ meson_options_help() { + printf "%s\n" ' "manufacturer" name for qemu-ga registry entries' + printf "%s\n" ' [QEMU]' + printf "%s\n" ' --qemu-ga-version=VALUE version number for qemu-ga installer' ++ printf "%s\n" ' --rhel-version=VALUE RHEL major/minor version [0.0]' + printf "%s\n" ' --smbd=VALUE Path to smbd for slirp networking' + printf "%s\n" ' --sysconfdir=VALUE Sysconf data directory [etc]' + printf "%s\n" ' --tls-priority=VALUE Default TLS protocol/cipher priority string' +@@ -450,6 +451,7 @@ _meson_option_parse() { + --disable-relocatable) printf "%s" -Drelocatable=false ;; + --enable-replication) printf "%s" -Dreplication=enabled ;; + --disable-replication) printf "%s" -Dreplication=disabled ;; ++ --rhel-version=*) quote_sh "-Drhel_version=$2" ;; + --enable-rng-none) printf "%s" -Drng_none=true ;; + --disable-rng-none) printf "%s" -Drng_none=false ;; + --enable-rutabaga-gfx) printf "%s" -Drutabaga_gfx=enabled ;; +-- +2.39.3 + diff --git a/SOURCES/0010-Increase-deletion-schedule-to-3-releases.patch b/SOURCES/0010-Increase-deletion-schedule-to-3-releases.patch new file mode 100644 index 0000000..09bebec --- /dev/null +++ b/SOURCES/0010-Increase-deletion-schedule-to-3-releases.patch @@ -0,0 +1,33 @@ +From f25d2c0298d8d6328cb0071926d477f647a512fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 18:45:58 +0100 +Subject: Increase deletion schedule to 3 releases +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The RHEL-9 series still keeps the rhel 7.6.0 machine types as a +special exception to our normal rule of deleting machine types +after 2 releases. The exception will go away in RHEL-10. + +Signed-off-by: Daniel P. Berrangé +--- + include/hw/boards.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/hw/boards.h b/include/hw/boards.h +index 7f7eb4ec40..32c4642f5a 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -608,7 +608,7 @@ struct MachineState { + * How many RHEL major releases for each phase + * of the life cycle. + */ +-#define MACHINE_VER_DELETION_MAJOR 2 ++#define MACHINE_VER_DELETION_MAJOR 3 + #define MACHINE_VER_DEPRECATION_MAJOR 1 + + /* +-- +2.39.3 + diff --git a/SOURCES/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch b/SOURCES/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch new file mode 100644 index 0000000..df71e68 --- /dev/null +++ b/SOURCES/0011-Add-downstream-aarch64-versioned-virt-machine-types.patch @@ -0,0 +1,368 @@ +From a2e5218bbe2e39712e06c5d8a51f836807c1cae9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:25:47 +0100 +Subject: Add downstream aarch64 versioned 'virt' machine types + +Adding changes to add RHEL machine types for aarch64 architecture. + +Signed-off-by: Miroslav Rezanina +--- +Rebase notes (6.1.0): +- Use CONFIG_TPM check when using TPM structures +- Add support for default_bus_bypass_iommu +- ea4c0b32d9 arm/virt: Register highmem and gic-version as class properties +- 895e1fa86a hw/arm/virt: Add 8.5 and 9.0 machine types and remove older ones + +Rebase notes (7.0.0): +- Added dtb-kaslr-seed option +- Set no_tcg_lpa2 to true + +Rebase notes (7.1.0): +- replace dtb_kaslr_seed by dtb_randomness +- Updated dtb_randomness comment + +Rebase notes (7.2.0): +- Disabled cortex-a35 + +Rebase notes (8.0.0): +- Moved changed code from target/arm/helper.c to target/arm/arm-qmp-cmds.c + +Rebase notes (8.1.0): +- Added setting default_nic + +Rebase notes (9.0.0 rc0): +- call arm_virt_compat_set on rhel type class_init + +Rebase notes (9.1.0 rc0): +- Merge copy+pasted base machine definition back with upstream + base machine definition to reduce RHEL delta, as is done with + other targets +- Convert to new DEFINE_VIRT_MACHINE macros + +Rebase notes (9.1.0 rc1): +- do not remove cpu_valid_types + +Rebase notes (9.1.0 rc2): +- Use preprocessing to remove unwanted code instead of removal + +Merged patches (6.2.0): +- 9a3d4fde0e hw/arm/virt: Remove 9.0 machine type +- f7d04d6695 hw: arm: virt: Add hw_compat_rhel_8_5 to 8.5 machine type + +Merged patches (7.0.0): +- 3b82be3dd3 redhat: virt-rhel8.5.0: Update machine type compatibility for QEMU 6.2.0 update +- c354a86c9b hw/arm/virt: Register "iommu" as a class property +- c1a2630dc9 hw/arm/virt: Register "its" as a class property +- 9d8c61dc93 hw/arm/virt: Rename default_bus_bypass_iommu +- a1d1b6eeb6 hw/arm/virt: Expose the 'RAS' option +- 47f8fe1b82 hw/arm/virt: Add 9.0 machine type and remove 8.5 one +- ed2346788f hw/arm/virt: Check no_tcg_its and minor style changes + +Merged patches (7.0.0): +- f79b31bdef hw/arm/virt: Remove the dtb-kaslr-seed machine option +- b6fca85f4a hw/arm/virt: Fix missing initialization in instance/class_init() + +Merged patches (7.1.0): +- ac97dd4f9f RHEL-only: AArch64: Drop unsupported CPU types +- e9c0a70664 target/arm: deprecate named CPU models + +Merged patches (7.2.0): +- 0be2889fa2 Introduce upstream 7.0 compat changes (only applicable parts) + +Merged patches (8.0.0): +- c1a21266d8 redhat: aarch64: add rhel9.2.0 virt machine type +- d97cd7c513 redhat: fix virt-rhel9.2.0 compat props + +Merged patches (8.1.0): +- bd5d81d286 Add RHEL 9.2.0 compat structure (arm part) +- c07f666086 hw/arm/virt: Validate cluster and NUMA node boundary for RHEL machines + +Merged patches (8.2.0): +- 4ee284aca9 Add machine types compat bits. (partial) + +Merged patches (9.0.0 rc0): +- 117068376a hw/arm/virt: Fix compats +- 8bcccfabc4 hw/arm/virt: Add properties to disable high memory regions + 0005a8b93a hw/arm/virt: deprecate virt-rhel9.{0,2}.0 machine types + +Merged patches (9.1.0 rc0): +- 043ad5ce97 Add upstream compatibility bits (partial) +- 092cb319ea hw/arm/virt: Fix spurious call to arm_virt_compat_set() +--- + hw/arm/virt.c | 101 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 81 insertions(+), 20 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 5396e7cb24..903c0f2e9f 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -90,6 +90,22 @@ static GlobalProperty arm_virt_compat[] = { + }; + static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat); + ++/* ++ * This variable is for changes to properties that are RHEL specific, ++ * different to the current upstream and to be applied to the latest ++ * machine type. They may be overriden by older machine compats. ++ * ++ * virtio-net-pci variant romfiles are not needed because edk2 does ++ * fully support the pxe boot. Besides virtio romfiles are not shipped ++ * on rhel/aarch64. ++ */ ++GlobalProperty arm_rhel_compat[] = { ++ {"virtio-net-pci", "romfile", "" }, ++ {"virtio-net-pci-transitional", "romfile", "" }, ++ {"virtio-net-pci-non-transitional", "romfile", "" }, ++}; ++const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); ++ + /* + * This cannot be called from the virt_machine_class_init() because + * TYPE_VIRT_MACHINE is abstract and mc->compat_props g_ptr_array_new() +@@ -99,6 +115,8 @@ static void arm_virt_compat_set(MachineClass *mc) + { + compat_props_add(mc->compat_props, arm_virt_compat, + arm_virt_compat_len); ++ compat_props_add(mc->compat_props, arm_rhel_compat, ++ arm_rhel_compat_len); + } + + #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \ +@@ -109,10 +127,11 @@ static void arm_virt_compat_set(MachineClass *mc) + MachineClass *mc = MACHINE_CLASS(oc); \ + arm_virt_compat_set(mc); \ + MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \ +- mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \ ++ mc->desc = "RHEL " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \ + MACHINE_VER_DEPRECATION(__VA_ARGS__); \ + if (latest) { \ + mc->alias = "virt"; \ ++ mc->is_default = 1; \ + } \ + } \ + static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \ +@@ -128,10 +147,10 @@ static void arm_virt_compat_set(MachineClass *mc) + } \ + type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__)); + +-#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \ +- DEFINE_VIRT_MACHINE_IMPL(true, major, minor) +-#define DEFINE_VIRT_MACHINE(major, minor) \ +- DEFINE_VIRT_MACHINE_IMPL(false, major, minor) ++#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor, micro) \ ++ DEFINE_VIRT_MACHINE_IMPL(true, major, minor, micro) ++#define DEFINE_VIRT_MACHINE(major, minor, micro) \ ++ DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro) + + + /* Number of external interrupt lines to configure the GIC with */ +@@ -2434,6 +2453,7 @@ static void machvirt_init(MachineState *machine) + qemu_add_machine_init_done_notifier(&vms->machine_done); + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static bool virt_get_secure(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -2461,6 +2481,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) + + vms->virt = value; + } ++#endif /* disabled for RHEL */ + + static bool virt_get_highmem(Object *obj, Error **errp) + { +@@ -2476,6 +2497,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) + vms->highmem = value; + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static bool virt_get_compact_highmem(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -2489,6 +2511,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) + + vms->highmem_compact = value; + } ++#endif /* disabled for RHEL */ + + static bool virt_get_highmem_redists(Object *obj, Error **errp) + { +@@ -2547,6 +2570,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp) + vms->its = value; + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static bool virt_get_dtb_randomness(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -2560,6 +2584,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) + + vms->dtb_randomness = value; + } ++#endif /* disabled for RHEL */ + + static char *virt_get_oem_id(Object *obj, Error **errp) + { +@@ -2643,6 +2668,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) + vms->ras = value; + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static bool virt_get_mte(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -2656,6 +2682,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) + + vms->mte = value; + } ++#endif /* disabled for RHEL */ + + static char *virt_get_gic_version(Object *obj, Error **errp) + { +@@ -3063,16 +3090,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + NULL + }; + ++ mc->family = "virt-rhel-Z"; + mc->init = machvirt_init; +- /* Start with max_cpus set to 512, which is the maximum supported by KVM. +- * The value may be reduced later when we have more information about the +- * configuration of the particular instance. +- */ +- mc->max_cpus = 512; +- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC); +- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE); +- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); +- machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM); ++ /* Maximum supported VCPU count for all virt-rhel* machines */ ++ mc->max_cpus = 384; + #ifdef CONFIG_TPM + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); + #endif +@@ -3083,11 +3104,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + mc->minimum_page_bits = 12; + mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; + mc->cpu_index_to_instance_props = virt_cpu_index_to_props; +-#ifdef CONFIG_TCG +- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); +-#else +- mc->default_cpu_type = ARM_CPU_TYPE_NAME("max"); +-#endif ++ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); + mc->valid_cpu_types = valid_cpu_types; + mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; + mc->kvm_type = virt_kvm_type; +@@ -3111,6 +3128,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + NULL, NULL); + object_class_property_set_description(oc, "acpi", + "Enable ACPI"); ++#if 0 /* disabled for RHEL */ + object_class_property_add_bool(oc, "secure", virt_get_secure, + virt_set_secure); + object_class_property_set_description(oc, "secure", +@@ -3123,6 +3141,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + "Set on/off to enable/disable emulating a " + "guest CPU which implements the ARM " + "Virtualization Extensions"); ++#endif /* disabled for RHEL */ + + object_class_property_add_bool(oc, "highmem", virt_get_highmem, + virt_set_highmem); +@@ -3130,12 +3149,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + "Set on/off to enable/disable using " + "physical address space above 32 bits"); + ++#if 0 /* disabled for RHEL */ + object_class_property_add_bool(oc, "compact-highmem", + virt_get_compact_highmem, + virt_set_compact_highmem); + object_class_property_set_description(oc, "compact-highmem", + "Set on/off to enable/disable compact " + "layout for high memory regions"); ++#endif /* disabled for RHEL */ + + object_class_property_add_bool(oc, "highmem-redists", + virt_get_highmem_redists, +@@ -3163,7 +3184,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + virt_set_gic_version); + object_class_property_set_description(oc, "gic-version", + "Set GIC version. " +- "Valid values are 2, 3, 4, host and max"); ++ "Valid values are 2, 3, host and max"); + + object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu); + object_class_property_set_description(oc, "iommu", +@@ -3183,11 +3204,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + "Set on/off to enable/disable reporting host memory errors " + "to a KVM guest using ACPI and guest external abort exceptions"); + ++#if 0 /* disabled for RHEL */ + object_class_property_add_bool(oc, "mte", virt_get_mte, virt_set_mte); + object_class_property_set_description(oc, "mte", + "Set on/off to enable/disable emulating a " + "guest CPU which implements the ARM " + "Memory Tagging Extension"); ++#endif /* disabled for RHEL */ + + object_class_property_add_bool(oc, "its", virt_get_its, + virt_set_its); +@@ -3195,6 +3218,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + "Set on/off to enable/disable " + "ITS instantiation"); + ++#if 0 /* disabled for RHEL */ + object_class_property_add_bool(oc, "dtb-randomness", + virt_get_dtb_randomness, + virt_set_dtb_randomness); +@@ -3207,6 +3231,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + virt_set_dtb_randomness); + object_class_property_set_description(oc, "dtb-kaslr-seed", + "Deprecated synonym of dtb-randomness"); ++#endif /* disabled for RHEL */ + + object_class_property_add_str(oc, "x-oem-id", + virt_get_oem_id, +@@ -3554,3 +3579,39 @@ static void virt_machine_2_6_options(MachineClass *mc) + } + DEFINE_VIRT_MACHINE(2, 6) + #endif /* disabled for RHEL */ ++ ++static void virt_rhel_machine_9_4_0_options(MachineClass *mc) ++{ ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); ++} ++DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0) ++ ++static void virt_rhel_machine_9_2_0_options(MachineClass *mc) ++{ ++ virt_rhel_machine_9_4_0_options(mc); ++ ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); ++ ++ /* RHEL 9.4 is the first supported release */ ++ mc->deprecation_reason = ++ "machine types for versions prior to 9.4 are deprecated"; ++} ++DEFINE_VIRT_MACHINE(9, 2, 0) ++ ++static void virt_rhel_machine_9_0_0_options(MachineClass *mc) ++{ ++ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); ++ ++ virt_rhel_machine_9_2_0_options(mc); ++ ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); ++ ++ /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ ++ vmc->no_tcg_lpa2 = true; ++ /* Compact layout for high memory regions was introduced with 9.2.0 */ ++ vmc->no_highmem_compact = true; ++} ++DEFINE_VIRT_MACHINE(9, 0, 0) +-- +2.39.3 + diff --git a/SOURCES/0008-Add-ppc64-machine-types.patch b/SOURCES/0012-Add-downstream-ppc64-versioned-spapr-machine-types.patch similarity index 75% rename from SOURCES/0008-Add-ppc64-machine-types.patch rename to SOURCES/0012-Add-downstream-ppc64-versioned-spapr-machine-types.patch index 87fcb3a..fb56514 100644 --- a/SOURCES/0008-Add-ppc64-machine-types.patch +++ b/SOURCES/0012-Add-downstream-ppc64-versioned-spapr-machine-types.patch @@ -1,7 +1,7 @@ -From fb905dbe5b51ed899062ef99a2dd7f238d3e3384 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:27:13 +0200 -Subject: Add ppc64 machine types +From 676f3da2fc29ae71ed4189483b86e3c6496b8905 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:44:31 +0100 +Subject: Add downstream ppc64 versioned 'spapr' machine types Adding changes to add RHEL machine types for ppc64 architecture. @@ -11,6 +11,10 @@ Rebase notes (6.2.0): - Fixed rebase conflict relicts - Update machine type compat for 6.2 (from MR 66) +Rebase notes (9.1.0 rc0) +- Don't call kvmppc_svm_allow() when !CONFIG_KVM +- Convert to new DEFINE_SPAPR_MACHINE macros + Merged patches (6.1.0): - c438c25ac3 redhat: Define pseries-rhel8.5.0 machine type - a3995e2eff Remove RHEL 7.0.0 machine type (only ppc64 changes) @@ -23,31 +27,34 @@ Merged patches (6.1.0): Merged patches (7.1.0): - baa6790171 target/ppc/cpu-models: Fix ppc_cpu_aliases list for RHEL --- - hw/ppc/spapr.c | 243 ++++++++++++++++++++++++++++++++++++++++ - hw/ppc/spapr_cpu_core.c | 13 +++ + hw/ppc/spapr.c | 254 +++++++++++++++++++++++++++++++++++++++- + hw/ppc/spapr_cpu_core.c | 13 ++ include/hw/ppc/spapr.h | 4 + - target/ppc/compat.c | 13 ++- - target/ppc/cpu-models.c | 1 + + target/ppc/compat.c | 11 ++ target/ppc/cpu.h | 1 + target/ppc/kvm.c | 27 +++++ - target/ppc/kvm_ppc.h | 13 +++ - 8 files changed, 314 insertions(+), 1 deletion(-) + target/ppc/kvm_ppc.h | 13 ++ + 7 files changed, 317 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index e9bc97fee0..a258d81846 100644 +index b48a2afc38..29e66f1b3f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c -@@ -1718,6 +1718,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) - pef_kvm_reset(machine->cgs, &error_fatal); +@@ -1746,6 +1746,13 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) + } spapr_caps_apply(spapr); spapr_nested_reset(spapr); + if (spapr->svm_allowed) { ++#ifdef CONFIG_KVM + kvmppc_svm_allow(&error_fatal); ++#else ++ error_setg(&error_fatal, "No PEF support in tcg, try x-svm-allowed=off"); ++#endif + } first_ppc_cpu = POWERPC_CPU(first_cpu); if (kvm_enabled() && kvmppc_has_cap_mmu_radix() && -@@ -3421,6 +3424,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp) +@@ -3452,6 +3459,20 @@ static void spapr_set_host_serial(Object *obj, const char *value, Error **errp) spapr->host_serial = g_strdup(value); } @@ -68,7 +75,7 @@ index e9bc97fee0..a258d81846 100644 static void spapr_instance_init(Object *obj) { SpaprMachineState *spapr = SPAPR_MACHINE(obj); -@@ -3499,6 +3516,12 @@ static void spapr_instance_init(Object *obj) +@@ -3530,6 +3551,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 +88,7 @@ index e9bc97fee0..a258d81846 100644 } static void spapr_machine_finalizefn(Object *obj) -@@ -4754,6 +4777,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) +@@ -4775,6 +4802,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,38 +96,30 @@ index e9bc97fee0..a258d81846 100644 } static const TypeInfo spapr_machine_info = { -@@ -4805,6 +4829,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) +@@ -4830,12 +4858,12 @@ static void spapr_machine_latest_class_options(MachineClass *mc) } \ - type_init(spapr_machine_register_##suffix) + type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__)) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ +-#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \ +- DEFINE_SPAPR_MACHINE_IMPL(true, major, minor) +-#define DEFINE_SPAPR_MACHINE(major, minor) \ +- DEFINE_SPAPR_MACHINE_IMPL(false, major, minor) +-#define DEFINE_SPAPR_MACHINE_TAGGED(major, minor, tag) \ +- DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, _, tag) ++#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor, micro) \ ++ DEFINE_SPAPR_MACHINE_IMPL(true, major, minor, micro) ++#define DEFINE_SPAPR_MACHINE(major, minor, micro) \ ++ DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, micro) ++#define DEFINE_SPAPR_MACHINE_TAGGED(major, minor, micro, tag) \ ++ DEFINE_SPAPR_MACHINE_IMPL(false, major, minor, micro, _, tag) + + #if 0 /* Disabled for Red Hat Enterprise Linux */ /* - * pseries-9.0 - */ -@@ -4998,6 +5023,7 @@ static void spapr_machine_4_1_class_options(MachineClass *mc) - } +@@ -5386,6 +5414,220 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) + DEFINE_SPAPR_MACHINE(2, 1); + #endif /* disabled for RHEL */ - DEFINE_SPAPR_MACHINE(4_1, "4.1", false); -+#endif - - /* - * pseries-4.0 -@@ -5013,6 +5039,8 @@ static bool phb_placement_4_0(SpaprMachineState *spapr, uint32_t index, - } - return true; - } -+ -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void spapr_machine_4_0_class_options(MachineClass *mc) - { - SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -@@ -5338,6 +5366,221 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) - compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len); - } - DEFINE_SPAPR_MACHINE(2_1, "2.1", false); -+#endif -+ -+static void spapr_machine_rhel_default_class_options(MachineClass *mc) ++static void spapr_rhel_machine_default_class_options(MachineClass *mc) +{ + /* + * Defaults for the latest behaviour inherited from the base class @@ -136,44 +135,44 @@ index e9bc97fee0..a258d81846 100644 + * like pseries-6.0 + */ + -+static void spapr_machine_rhel850_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_5_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + + /* The default machine type must apply the RHEL specific defaults */ -+ spapr_machine_rhel_default_class_options(mc); ++ spapr_rhel_machine_default_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_5, + hw_compat_rhel_8_5_len); + smc->pre_6_2_numa_affinity = true; + mc->smp_props.prefer_sockets = true; +} + -+DEFINE_SPAPR_MACHINE(rhel850, "rhel8.5.0", true); ++DEFINE_SPAPR_MACHINE_AS_LATEST(8, 5, 0); + +/* + * pseries-rhel8.4.0 + * like pseries-5.2 + */ + -+static void spapr_machine_rhel840_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_4_0_class_options(MachineClass *mc) +{ -+ spapr_machine_rhel850_class_options(mc); ++ spapr_rhel_machine_8_5_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_4, + hw_compat_rhel_8_4_len); +} + -+DEFINE_SPAPR_MACHINE(rhel840, "rhel8.4.0", false); ++DEFINE_SPAPR_MACHINE(8, 4, 0); + +/* + * pseries-rhel8.3.0 + * like pseries-5.1 + */ + -+static void spapr_machine_rhel830_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_3_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + -+ spapr_machine_rhel840_class_options(mc); ++ spapr_rhel_machine_8_4_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_3, + hw_compat_rhel_8_3_len); + @@ -181,7 +180,7 @@ index e9bc97fee0..a258d81846 100644 + smc->pre_5_2_numa_associativity = true; +} + -+DEFINE_SPAPR_MACHINE(rhel830, "rhel8.3.0", false); ++DEFINE_SPAPR_MACHINE(8, 3, 0); + +/* + * pseries-rhel8.2.0 @@ -189,7 +188,7 @@ index e9bc97fee0..a258d81846 100644 + * except SPAPR_CAP_CCF_ASSIST that has been backported to pseries-rhel8.1.0 + */ + -+static void spapr_machine_rhel820_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_2_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + /* from pseries-5.0 */ @@ -197,7 +196,7 @@ index e9bc97fee0..a258d81846 100644 + { TYPE_SPAPR_PCI_HOST_BRIDGE, "pre-5.1-associativity", "on" }, + }; + -+ spapr_machine_rhel830_class_options(mc); ++ spapr_rhel_machine_8_3_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_2, + hw_compat_rhel_8_2_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); @@ -212,14 +211,14 @@ index e9bc97fee0..a258d81846 100644 + smc->pre_5_1_assoc_refpoints = true; +} + -+DEFINE_SPAPR_MACHINE(rhel820, "rhel8.2.0", false); ++DEFINE_SPAPR_MACHINE(8, 2, 0); + +/* + * pseries-rhel8.1.0 + * like pseries-4.1 + */ + -+static void spapr_machine_rhel810_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_1_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + static GlobalProperty compat[] = { @@ -227,7 +226,7 @@ index e9bc97fee0..a258d81846 100644 + { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" }, + }; + -+ spapr_machine_rhel820_class_options(mc); ++ spapr_rhel_machine_8_2_0_class_options(mc); + + /* from pseries-4.1 */ + smc->linux_pci_probe = false; @@ -240,7 +239,7 @@ index e9bc97fee0..a258d81846 100644 + smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_OFF; +} + -+DEFINE_SPAPR_MACHINE(rhel810, "rhel8.1.0", false); ++DEFINE_SPAPR_MACHINE(8, 1, 0); + +/* + * pseries-rhel8.0.0 @@ -249,11 +248,11 @@ index e9bc97fee0..a258d81846 100644 + * that have been backported to pseries-rhel8.0.0 + */ + -+static void spapr_machine_rhel800_class_options(MachineClass *mc) ++static void spapr_rhel_machine_8_0_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + -+ spapr_machine_rhel810_class_options(mc); ++ spapr_rhel_machine_8_1_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_0, + hw_compat_rhel_8_0_len); + @@ -270,7 +269,7 @@ index e9bc97fee0..a258d81846 100644 + smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF; +} + -+DEFINE_SPAPR_MACHINE(rhel800, "rhel8.0.0", false); ++DEFINE_SPAPR_MACHINE(8, 0, 0); + +/* + * pseries-rhel7.6.0 @@ -284,11 +283,11 @@ index e9bc97fee0..a258d81846 100644 +const size_t spapr_compat_rhel7_6_len = G_N_ELEMENTS(spapr_compat_rhel7_6); + + -+static void spapr_machine_rhel760_class_options(MachineClass *mc) ++static void spapr_rhel_machine_7_6_0_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + -+ spapr_machine_rhel800_class_options(mc); ++ spapr_rhel_machine_8_0_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); + compat_props_add(mc->compat_props, spapr_compat_rhel7_6, spapr_compat_rhel7_6_len); + @@ -314,7 +313,7 @@ index e9bc97fee0..a258d81846 100644 + smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; +} + -+DEFINE_SPAPR_MACHINE(rhel760, "rhel7.6.0", false); ++DEFINE_SPAPR_MACHINE(7, 6, 0); + +/* + * pseries-rhel7.6.0-sxxm @@ -322,22 +321,23 @@ index e9bc97fee0..a258d81846 100644 + * pseries-rhel7.6.0 with speculative execution exploit mitigations enabled by default + */ + -+static void spapr_machine_rhel760sxxm_class_options(MachineClass *mc) ++static void spapr_rhel_machine_7_6_0_sxxm_class_options(MachineClass *mc) +{ + SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + -+ spapr_machine_rhel760_class_options(mc); ++ spapr_rhel_machine_7_6_0_class_options(mc); + smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; + smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; + smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; +} + -+DEFINE_SPAPR_MACHINE(rhel760sxxm, "rhel7.6.0-sxxm", false); - ++DEFINE_SPAPR_MACHINE_TAGGED(7, 6, 0, sxxm); ++ static void spapr_machine_register_types(void) { + type_register_static(&spapr_machine_info); diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index 3b0a47a28c..375e0c8e45 100644 +index 0bf7c52077..c845f4acef 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -25,6 +25,7 @@ @@ -375,7 +375,7 @@ index 3b0a47a28c..375e0c8e45 100644 qdev_unrealize(DEVICE(cpu)); return false; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h -index 4aaf23d28f..3233c54d11 100644 +index f6de3e9972..fc48348747 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -157,6 +157,7 @@ struct SpaprMachineClass { @@ -397,10 +397,10 @@ index 4aaf23d28f..3233c54d11 100644 char *kvm_type; char *host_model; diff --git a/target/ppc/compat.c b/target/ppc/compat.c -index ebef2cccec..ff2c00c60e 100644 +index ebef2cccec..ab7ed76806 100644 --- a/target/ppc/compat.c +++ b/target/ppc/compat.c -@@ -114,8 +114,19 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) +@@ -114,6 +114,17 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) return NULL; } @@ -416,28 +416,13 @@ index ebef2cccec..ff2c00c60e 100644 +} + static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr, -- uint32_t min_compat_pvr, uint32_t max_compat_pvr) -+ uint32_t min_compat_pvr, uint32_t max_compat_pvr) + uint32_t min_compat_pvr, uint32_t max_compat_pvr) { - const CompatInfo *compat = compat_by_pvr(compat_pvr); - const CompatInfo *min = compat_by_pvr(min_compat_pvr); -diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c -index f77ebfcc81..18e9422006 100644 ---- a/target/ppc/cpu-models.c -+++ b/target/ppc/cpu-models.c -@@ -744,6 +744,7 @@ - /* PowerPC CPU aliases */ - - PowerPCCPUAlias ppc_cpu_aliases[] = { -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { "405", "405d4" }, - { "405cr", "405crc" }, - { "405gp", "405gpd" }, diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h -index 67e6b2effd..11187aeb93 100644 +index 321ed2da75..e35a997628 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h -@@ -1655,6 +1655,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch) +@@ -1673,6 +1673,7 @@ static inline int ppc_env_mmu_index(CPUPPCState *env, bool ifetch) /* Compatibility modes */ #if defined(TARGET_PPC64) @@ -446,18 +431,18 @@ index 67e6b2effd..11187aeb93 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 8231feb2d4..59f640cf7b 100644 +index 907dba60d1..c942ff55b2 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c -@@ -89,6 +89,7 @@ static int cap_large_decr; +@@ -92,6 +92,7 @@ static int cap_large_decr; static int cap_fwnmi; static int cap_rpt_invalidate; static int cap_ail_mode_3; +static int cap_ppc_secure_guest; - static uint32_t debug_inst_opcode; - -@@ -141,6 +142,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + #ifdef CONFIG_PSERIES + static int cap_papr; +@@ -150,6 +151,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT); kvmppc_get_cpu_characteristics(s); cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); @@ -465,7 +450,7 @@ index 8231feb2d4..59f640cf7b 100644 cap_large_decr = kvmppc_get_dec_bits(); cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); /* -@@ -2564,6 +2566,16 @@ bool kvmppc_supports_ail_3(void) +@@ -2597,6 +2599,16 @@ bool kvmppc_supports_ail_3(void) return cap_ail_mode_3; } @@ -482,10 +467,10 @@ index 8231feb2d4..59f640cf7b 100644 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) { uint32_t host_pvr = mfpvr(); -@@ -2964,3 +2976,18 @@ bool kvm_arch_cpu_check_are_resettable(void) - void kvm_arch_accel_class_init(ObjectClass *oc) - { +@@ -3012,3 +3024,18 @@ static void kvm_cpu_accel_register_types(void) + type_register_static(&kvm_cpu_accel_type_info); } + type_init(kvm_cpu_accel_register_types); + +void kvmppc_svm_allow(Error **errp) +{ diff --git a/SOURCES/0009-Add-s390x-machine-types.patch b/SOURCES/0013-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch similarity index 64% rename from SOURCES/0009-Add-s390x-machine-types.patch rename to SOURCES/0013-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch index b9709f1..adad3c7 100644 --- a/SOURCES/0009-Add-s390x-machine-types.patch +++ b/SOURCES/0013-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch @@ -1,7 +1,7 @@ -From 04178c77cfe188b4eed9c08a0bf66842e61fe5dc Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:47:32 +0200 -Subject: Add s390x machine types +From 450ae6631771593689f7f9c3eb2081e93d3e75c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:44:36 +0100 +Subject: Add downstream s390x versioned 's390-ccw-virtio' machine types Adding changes to add RHEL machine types for s390x architecture. @@ -11,6 +11,9 @@ Signed-off-by: Miroslav Rezanina Rebase changes (7.1.0): - Moved adding rhel_old_machine_deprecation variable to general machine types commit +Rebase notes (9.1.0 rc0) +- Convert to new DEFINE_CCW_MACHINE macros + Merged patches (6.1.0): - 64a9a5c971 hw/s390x: Remove the RHEL7-only machine type - 395516d62b redhat: s390x: add rhel-8.5.0 compat machine @@ -41,68 +44,86 @@ Merged patches (8.1.0): Merged patches (8.2.0): - 4ee284aca9 Add machine types compat bits. (partial) + +Merged patches (9.1.0 rc0): +- 043ad5ce97 Add upstream compatibility bits (partial) --- - hw/s390x/s390-virtio-ccw.c | 159 +++++++++++++++++++++++++++++++ + hw/s390x/s390-virtio-ccw.c | 164 ++++++++++++++++++++++++++++++- target/s390x/cpu_models.c | 11 +++ target/s390x/cpu_models.h | 2 + target/s390x/cpu_models_sysemu.c | 2 + - 4 files changed, 174 insertions(+) + 4 files changed, 174 insertions(+), 5 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index b1dcb3857f..ff753a29e0 100644 +index 86bfc9d2eb..72e1279db9 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c -@@ -859,6 +859,7 @@ bool css_migration_enabled(void) +@@ -837,7 +837,7 @@ static const TypeInfo ccw_machine_info = { + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc); \ +- mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \ ++ mc->desc = "Virtual s390x machine (version rhel" MACHINE_VER_STR(__VA_ARGS__) ")"; \ + MACHINE_VER_DEPRECATION(__VA_ARGS__); \ + if (latest) { \ + mc->alias = "s390-ccw-virtio"; \ +@@ -864,11 +864,11 @@ static const TypeInfo ccw_machine_info = { } \ - type_init(ccw_machine_register_##suffix) + type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__)) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void ccw_machine_9_0_instance_options(MachineState *machine) - { - } -@@ -1272,6 +1273,164 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) - compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); - } - DEFINE_CCW_MACHINE(2_4, "2.4", false); -+#endif -+ -+ -+static void ccw_machine_rhel940_instance_options(MachineState *machine) +-#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \ +- DEFINE_CCW_MACHINE_IMPL(true, major, minor) ++#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor, micro) \ ++ DEFINE_CCW_MACHINE_IMPL(true, major, minor, micro) + +-#define DEFINE_CCW_MACHINE(major, minor) \ +- DEFINE_CCW_MACHINE_IMPL(false, major, minor) ++#define DEFINE_CCW_MACHINE(major, minor, micro) \ ++ DEFINE_CCW_MACHINE_IMPL(false, major, minor, micro) + + + #if 0 /* Disabled for Red Hat Enterprise Linux */ +@@ -1308,6 +1308,160 @@ DEFINE_CCW_MACHINE(2, 4); + #endif + #endif /* disabled for RHEL */ + ++static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine) +{ +} + -+static void ccw_machine_rhel940_class_options(MachineClass *mc) ++static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc) +{ ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); +} -+DEFINE_CCW_MACHINE(rhel940, "rhel9.4.0", true); ++DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0); + -+static void ccw_machine_rhel920_instance_options(MachineState *machine) ++static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine) +{ -+ ccw_machine_rhel940_instance_options(machine); ++ ccw_rhel_machine_9_4_0_instance_options(machine); +} + -+static void ccw_machine_rhel920_class_options(MachineClass *mc) ++static void ccw_rhel_machine_9_2_0_class_options(MachineClass *mc) +{ -+ ccw_machine_rhel940_class_options(mc); ++ ccw_rhel_machine_9_4_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); + mc->smp_props.drawers_supported = false; /* from ccw_machine_8_1 */ + mc->smp_props.books_supported = false; /* from ccw_machine_8_1 */ +} -+DEFINE_CCW_MACHINE(rhel920, "rhel9.2.0", false); ++DEFINE_CCW_MACHINE(9, 2, 0); + -+static void ccw_machine_rhel900_instance_options(MachineState *machine) ++static void ccw_rhel_machine_9_0_0_instance_options(MachineState *machine) +{ + static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_2 }; + -+ ccw_machine_rhel920_instance_options(machine); ++ ccw_rhel_machine_9_2_0_instance_options(machine); + + s390_set_qemu_cpu_model(0x3906, 14, 2, qemu_cpu_feat); + s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE); +} + -+static void ccw_machine_rhel900_class_options(MachineClass *mc) ++static void ccw_rhel_machine_9_0_0_class_options(MachineClass *mc) +{ + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); + static GlobalProperty compat[] = { @@ -110,42 +131,39 @@ index b1dcb3857f..ff753a29e0 100644 + { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", }, + }; + -+ ccw_machine_rhel920_class_options(mc); ++ ccw_rhel_machine_9_2_0_class_options(mc); + + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); + compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); + s390mc->max_threads = S390_MAX_CPUS; +} -+DEFINE_CCW_MACHINE(rhel900, "rhel9.0.0", false); ++DEFINE_CCW_MACHINE(9, 0, 0); + -+static void ccw_machine_rhel860_instance_options(MachineState *machine) ++static void ccw_rhel_machine_8_6_0_instance_options(MachineState *machine) +{ + /* Note: The -rhel8.6.0 and -rhel9.0.0 machines are technically identical */ -+ ccw_machine_rhel900_instance_options(machine); ++ ccw_rhel_machine_9_0_0_instance_options(machine); +} + -+static void ccw_machine_rhel860_class_options(MachineClass *mc) ++static void ccw_rhel_machine_8_6_0_class_options(MachineClass *mc) +{ + static GlobalProperty compat[] = { + { TYPE_S390_PCI_DEVICE, "interpret", "on", }, + { TYPE_S390_PCI_DEVICE, "forwarding-assist", "on", }, + }; + -+ ccw_machine_rhel900_class_options(mc); ++ ccw_rhel_machine_9_0_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_6, hw_compat_rhel_8_6_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); -+ -+ /* All RHEL machines for prior major releases are deprecated */ -+ mc->deprecation_reason = rhel_old_machine_deprecation; +} -+DEFINE_CCW_MACHINE(rhel860, "rhel8.6.0", false); ++DEFINE_CCW_MACHINE(8, 6, 0); + -+static void ccw_machine_rhel850_instance_options(MachineState *machine) ++static void ccw_rhel_machine_8_5_0_instance_options(MachineState *machine) +{ + static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 }; + -+ ccw_machine_rhel860_instance_options(machine); ++ ccw_rhel_machine_8_6_0_instance_options(machine); + + s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat); + @@ -156,52 +174,52 @@ index b1dcb3857f..ff753a29e0 100644 + s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAI); +} + -+static void ccw_machine_rhel850_class_options(MachineClass *mc) ++static void ccw_rhel_machine_8_5_0_class_options(MachineClass *mc) +{ + static GlobalProperty compat[] = { + { TYPE_S390_PCI_DEVICE, "interpret", "off", }, + { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", }, + }; + -+ ccw_machine_rhel860_class_options(mc); ++ ccw_rhel_machine_8_6_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_5, hw_compat_rhel_8_5_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); + mc->smp_props.prefer_sockets = true; +} -+DEFINE_CCW_MACHINE(rhel850, "rhel8.5.0", false); ++DEFINE_CCW_MACHINE(8, 5, 0); + -+static void ccw_machine_rhel840_instance_options(MachineState *machine) ++static void ccw_rhel_machine_8_4_0_instance_options(MachineState *machine) +{ -+ ccw_machine_rhel850_instance_options(machine); ++ ccw_rhel_machine_8_5_0_instance_options(machine); +} + -+static void ccw_machine_rhel840_class_options(MachineClass *mc) ++static void ccw_rhel_machine_8_4_0_class_options(MachineClass *mc) +{ -+ ccw_machine_rhel850_class_options(mc); ++ ccw_rhel_machine_8_5_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_4, hw_compat_rhel_8_4_len); +} -+DEFINE_CCW_MACHINE(rhel840, "rhel8.4.0", false); ++DEFINE_CCW_MACHINE(8, 4, 0); + -+static void ccw_machine_rhel820_instance_options(MachineState *machine) ++static void ccw_rhel_machine_8_2_0_instance_options(MachineState *machine) +{ -+ ccw_machine_rhel840_instance_options(machine); ++ ccw_rhel_machine_8_4_0_instance_options(machine); +} + -+static void ccw_machine_rhel820_class_options(MachineClass *mc) ++static void ccw_rhel_machine_8_2_0_class_options(MachineClass *mc) +{ -+ ccw_machine_rhel840_class_options(mc); ++ ccw_rhel_machine_8_4_0_class_options(mc); + mc->fixup_ram_size = s390_fixup_ram_size; + /* we did not publish a rhel8.3.0 machine */ + compat_props_add(mc->compat_props, hw_compat_rhel_8_3, hw_compat_rhel_8_3_len); + compat_props_add(mc->compat_props, hw_compat_rhel_8_2, hw_compat_rhel_8_2_len); +} -+DEFINE_CCW_MACHINE(rhel820, "rhel8.2.0", false); ++DEFINE_CCW_MACHINE(8, 2, 0); + -+static void ccw_machine_rhel760_instance_options(MachineState *machine) ++static void ccw_rhel_machine_7_6_0_instance_options(MachineState *machine) +{ + static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 }; + -+ ccw_machine_rhel820_instance_options(machine); ++ ccw_rhel_machine_8_2_0_instance_options(machine); + + s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat); + @@ -213,23 +231,24 @@ index b1dcb3857f..ff753a29e0 100644 + s390_cpudef_featoff(14, 1, S390_FEAT_PTFF_STOUE); +} + -+static void ccw_machine_rhel760_class_options(MachineClass *mc) ++static void ccw_rhel_machine_7_6_0_class_options(MachineClass *mc) +{ -+ ccw_machine_rhel820_class_options(mc); ++ ccw_rhel_machine_8_2_0_class_options(mc); + /* We never published the s390x version of RHEL-AV 8.0 and 8.1, so add this here */ + compat_props_add(mc->compat_props, hw_compat_rhel_8_1, hw_compat_rhel_8_1_len); + compat_props_add(mc->compat_props, hw_compat_rhel_8_0, hw_compat_rhel_8_0_len); + compat_props_add(mc->compat_props, hw_compat_rhel_7_6, hw_compat_rhel_7_6_len); +} -+DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", false); - ++DEFINE_CCW_MACHINE(7, 6, 0); ++ static void ccw_machine_register_types(void) { + type_register_static(&ccw_machine_info); diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c -index 8ed3bb6a27..370b3b3065 100644 +index a27f4b6f79..9ee30310c6 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c -@@ -46,6 +46,9 @@ +@@ -47,6 +47,9 @@ * of a following release have been a superset of the previous release. With * generation 15 one base feature and one optional feature have been deprecated. */ @@ -237,9 +256,9 @@ index 8ed3bb6a27..370b3b3065 100644 +#define RHEL_CPU_DEPRECATION "use at least 'z14', or 'host' / 'qemu' / 'max'" + static S390CPUDef s390_cpu_defs[] = { - CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"), - CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"), -@@ -866,22 +869,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) + /* + * Linux requires at least z10 nowadays, and IBM only supports recent CPUs +@@ -871,22 +874,30 @@ static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) { S390CPUClass *xcc = S390_CPU_CLASS(oc); @@ -271,7 +290,7 @@ index 8ed3bb6a27..370b3b3065 100644 static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data) diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h -index d7b8912989..1a806a97c4 100644 +index 71d4bc2dd4..d6c7c2cb50 100644 --- a/target/s390x/cpu_models.h +++ b/target/s390x/cpu_models.h @@ -38,6 +38,8 @@ typedef struct S390CPUDef { @@ -284,7 +303,7 @@ 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 0728bfcc20..ca2e5d91e2 100644 +index 72572726b8..707d546ca1 100644 --- a/target/s390x/cpu_models_sysemu.c +++ b/target/s390x/cpu_models_sysemu.c @@ -59,6 +59,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque) diff --git a/SOURCES/0010-Add-x86_64-machine-types.patch b/SOURCES/0014-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch similarity index 76% rename from SOURCES/0010-Add-x86_64-machine-types.patch rename to SOURCES/0014-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch index 83ee4a3..7959d6d 100644 --- a/SOURCES/0010-Add-x86_64-machine-types.patch +++ b/SOURCES/0014-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch @@ -1,7 +1,7 @@ -From 3c88acb005806ad2386ab6c94a8831151f624738 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Fri, 19 Oct 2018 13:10:31 +0200 -Subject: Add x86_64 machine types +From a7d5687a80eca95a1c39b73bebb9d478f3adfb0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:44:41 +0100 +Subject: Add downstream x86_64 versioned 'pc' & 'q35' machine types Adding changes to add RHEL machine types for x86_64 architecture. @@ -19,6 +19,11 @@ Rebase notes (8.0.0): Rebase notes (8.1.0): - default_nic_model to default_nic +Rebase notes (9.1.0 rc0) +- Merged pc_q35_machine_rhel_options back into + pc_q35_machine_options to reduce delta to upstream +- Convert to new DEFINE_(I440FX|Q35)_MACHINE macros + Merged patches (6.1.0): - 59c284ad3b x86: Add x86 rhel8.5 machine types - a8868b42fe redhat: x86: Enable 'kvm-asyncpf-int' by default @@ -60,39 +65,49 @@ Merged patches (8.2.0): Merged patches (9.0.0 rc0): - 9149e2bc8f x86: rhel 9.2.0 machine type compat fix + +Merged patches (9.1.0 rc0): +- 043ad5ce97 Add upstream compatibility bits (partial) + +Merged patches (9.1.0 rc2): +- 06ee79be2b introduce pc_rhel_9_5_compat +- 5cfd133600 target/i386: add guest-phys-bits cpu property (partial) +- 46206b821b hw/i386/sev: Use legacy SEV VM types for older machine types (partial) +- 414fe1d14f hw/i386/pc_sysfw: Alias rather than copy isa-bios region (partial) +- 0b6825631a i386/sev: Don't allow automatic fallback to legacy KVM_SEV*_INIT (partial) --- hw/i386/fw_cfg.c | 2 +- - hw/i386/pc.c | 159 ++++++++++++++++++++- - hw/i386/pc_piix.c | 109 ++++++++++++++ - hw/i386/pc_q35.c | 285 +++++++++++++++++++++++++++++++++++++ + hw/i386/pc.c | 167 +++++++++++++++++++++++++++++- + hw/i386/pc_piix.c | 105 ++++++++++++++++++- + hw/i386/pc_q35.c | 207 +++++++++++++++++++++++++++++++++++-- include/hw/boards.h | 2 + - include/hw/i386/pc.h | 33 +++++ - target/i386/cpu.c | 21 +++ + include/hw/i386/pc.h | 36 +++++++ + target/i386/cpu.c | 21 ++++ target/i386/kvm/kvm-cpu.c | 1 + target/i386/kvm/kvm.c | 4 + tests/qtest/pvpanic-test.c | 5 +- - 10 files changed, 617 insertions(+), 4 deletions(-) + 10 files changed, 537 insertions(+), 13 deletions(-) diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index c7aa39a13e..283c3f4c16 100644 +index 33ef280420..a322709ffa 100644 --- a/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c -@@ -63,7 +63,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, +@@ -73,7 +73,7 @@ void fw_cfg_build_smbios(PCMachineState *pcms, FWCfgState *fw_cfg, if (pcmc->smbios_defaults) { /* 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 5c21b0c4db..4a154c1a9a 100644 +index 7779c88a91..fa0e42d072 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c -@@ -326,6 +326,161 @@ GlobalProperty pc_compat_2_0[] = { - }; - const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0); +@@ -276,6 +276,169 @@ const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4); + */ + #define PC_FW_DATA (0x20000 + 0x8000) +/* This macro is for changes to properties that are RHEL specific, + * different to the current upstream and to be applied to the latest @@ -116,6 +131,14 @@ index 5c21b0c4db..4a154c1a9a 100644 +}; +const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); + ++GlobalProperty pc_rhel_9_5_compat[] = { ++ /* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */ ++ { TYPE_X86_CPU, "guest-phys-bits", "0" }, ++ /* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */ ++ { "sev-guest", "legacy-vm-type", "on" }, ++}; ++const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat); ++ +GlobalProperty pc_rhel_9_3_compat[] = { + /* pc_rhel_9_3_compat from pc_compat_8_0 */ + { "virtio-mem", "unplugged-inaccessible", "auto" }, @@ -252,15 +275,15 @@ index 5c21b0c4db..4a154c1a9a 100644 GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled) { GSIState *s; -@@ -1813,6 +1968,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - pcmc->resizable_acpi_blob = true; +@@ -1767,6 +1930,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) + pcmc->kvmclock_create_always = true; x86mc->apic_xrupt_override = true; assert(!mc->get_hotplug_handler); + mc->async_pf_vmexit_disable = false; mc->get_hotplug_handler = pc_get_hotplug_handler; mc->hotplug_allowed = pc_hotplug_allowed; - mc->cpu_index_to_instance_props = x86_cpu_index_to_props; -@@ -1823,7 +1979,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) + mc->auto_enable_numa_with_memhp = true; +@@ -1774,7 +1938,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; @@ -271,7 +294,7 @@ index 5c21b0c4db..4a154c1a9a 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 18ba076609..a647262d63 100644 +index 67107b174a..c93e78e896 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -52,6 +52,7 @@ @@ -282,19 +305,21 @@ index 18ba076609..a647262d63 100644 #ifdef CONFIG_XEN #include #include "hw/xen/xen_pt.h" -@@ -422,6 +423,7 @@ static void pc_set_south_bridge(Object *obj, int value, Error **errp) - * hw_compat_*, pc_compat_*, or * pc_*_machine_options(). - */ +@@ -445,8 +446,8 @@ static void pc_i440fx_init(MachineState *machine) + pc_init1(machine, TYPE_I440FX_PCI_DEVICE); + } -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_compat_2_3_fn(MachineState *machine) - { - X86MachineState *x86ms = X86_MACHINE(machine); -@@ -951,3 +953,110 @@ static void xenfv_3_1_machine_options(MachineClass *m) +-#define DEFINE_I440FX_MACHINE(major, minor) \ +- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor); ++#define DEFINE_I440FX_MACHINE(major, minor, micro) \ ++ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor, micro); + + #if 0 /* Disabled for Red Hat Enterprise Linux */ + static void pc_i440fx_machine_options(MachineClass *m) +@@ -826,3 +827,103 @@ static void xenfv_machine_3_1_options(MachineClass *m) DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, - xenfv_3_1_machine_options); + xenfv_machine_3_1_options); #endif -+#endif /* Disabled for Red Hat Enterprise Linux */ + +/* Red Hat Enterprise Linux machine types */ + @@ -305,7 +330,6 @@ index 18ba076609..a647262d63 100644 + m->family = "pc_piix_Y"; + m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; + pcmc->pci_root_uid = 0; -+ pcmc->resizable_acpi_blob = true; + m->default_nic = "e1000"; + m->default_display = "std"; + m->no_parallel = 1; @@ -316,14 +340,10 @@ index 18ba076609..a647262d63 100644 + m->alias = "pc"; + m->is_default = 1; + m->smp_props.prefer_sockets = true; ++ pcmc->isa_bios_alias = false; +} + -+static void pc_init_rhel760(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel760_options(MachineClass *m) ++static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + ObjectClass *oc = OBJECT_CLASS(m); @@ -332,9 +352,6 @@ index 18ba076609..a647262d63 100644 + m->async_pf_vmexit_disable = true; + m->smbus_no_migration_support = true; + -+ /* All RHEL machines for prior major releases are deprecated */ -+ m->deprecation_reason = rhel_old_machine_deprecation; -+ + pcmc->pvh_enabled = false; + pcmc->default_cpu_version = CPU_VERSION_LEGACY; + pcmc->kvmclock_create_always = false; @@ -356,7 +373,10 @@ index 18ba076609..a647262d63 100644 + object_class_property_set_description(oc, "x-south-bridge", + "Use a different south bridge than PIIX3"); + -+ ++ compat_props_add(m->compat_props, pc_rhel_9_5_compat, ++ pc_rhel_9_5_compat_len); ++ compat_props_add(m->compat_props, hw_compat_rhel_9_5, ++ hw_compat_rhel_9_5_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_4, + hw_compat_rhel_9_4_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_3, @@ -399,78 +419,66 @@ index 18ba076609..a647262d63 100644 + compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); +} + -+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, -+ pc_machine_rhel760_options); ++DEFINE_I440FX_MACHINE(7, 6, 0); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index c7bc8a2041..e872dc7e46 100644 +index 5fb283f2df..76f0ac1acd 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c -@@ -341,6 +341,7 @@ static void pc_q35_init(MachineState *machine) - DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) +@@ -338,20 +338,19 @@ static void pc_q35_machine_options(MachineClass *m) + pcmc->pci_root_uid = 0; + pcmc->default_cpu_version = 1; +- m->family = "pc_q35"; +- m->desc = "Standard PC (Q35 + ICH9, 2009)"; ++ m->family = "pc_q35_Z"; + m->units_per_default_bus = 1; +- m->default_machine_opts = "firmware=bios-256k.bin"; ++ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; + m->default_display = "std"; + m->default_nic = "e1000e"; +- m->default_kernel_irqchip_split = false; + m->no_floppy = 1; +- m->max_cpus = 4096; +- m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL); ++ m->max_cpus = 710; ++ m->no_parallel = 1; + machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); + machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); + machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); +- machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE); ++ m->alias = "q35"; ++ 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); + } +@@ -670,3 +669,197 @@ static void pc_q35_machine_2_4_options(MachineClass *m) -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_q35_machine_options(MachineClass *m) - { - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -@@ -693,3 +694,287 @@ static void pc_q35_2_4_machine_options(MachineClass *m) - - DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, - pc_q35_2_4_machine_options); -+#endif /* Disabled for Red Hat Enterprise Linux */ + DEFINE_Q35_MACHINE(2, 4); + #endif /* Disabled for Red Hat Enterprise Linux */ + +/* Red Hat Enterprise Linux machine types */ + -+/* Options for the latest rhel q35 machine type */ -+static void pc_q35_machine_rhel_options(MachineClass *m) ++static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pcmc->pci_root_uid = 0; -+ m->default_nic = "e1000e"; -+ m->family = "pc_q35_Z"; -+ m->units_per_default_bus = 1; -+ m->default_machine_opts = "firmware=bios-256k.bin,hpet=off"; -+ m->default_display = "std"; -+ m->no_floppy = 1; -+ m->no_parallel = 1; -+ pcmc->default_cpu_version = 1; -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); -+ 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) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel940_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel_options(m); ++ pc_q35_machine_options(m); + m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; + pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_version = "9.4.0"; ++ pcmc->isa_bios_alias = false; ++ ++ compat_props_add(m->compat_props, pc_rhel_9_5_compat, ++ pc_rhel_9_5_compat_len); ++ 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, -+ pc_q35_machine_rhel940_options); ++DEFINE_Q35_MACHINE_BUGFIX(9, 4, 0); + -+ -+static void pc_q35_init_rhel920(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel920_options(MachineClass *m) ++static void pc_q35_rhel_machine_9_2_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel940_options(m); ++ pc_q35_rhel_machine_9_4_0_options(m); + m->desc = "RHEL-9.2.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL"; @@ -493,18 +501,12 @@ index c7bc8a2041..e872dc7e46 100644 + pc_rhel_9_2_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel920, "pc-q35-rhel9.2.0", pc_q35_init_rhel920, -+ pc_q35_machine_rhel920_options); ++DEFINE_Q35_MACHINE_BUGFIX(9, 2, 0); + -+static void pc_q35_init_rhel900(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel900_options(MachineClass *m) ++static void pc_q35_rhel_machine_9_0_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel920_options(m); ++ pc_q35_rhel_machine_9_2_0_options(m); + m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL"; @@ -518,43 +520,27 @@ index c7bc8a2041..e872dc7e46 100644 + pc_rhel_9_0_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900, -+ pc_q35_machine_rhel900_options); ++DEFINE_Q35_MACHINE_BUGFIX(9, 0, 0); + -+static void pc_q35_init_rhel860(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel860_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_6_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel900_options(m); ++ pc_q35_rhel_machine_9_0_0_options(m); + m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + -+ /* All RHEL machines for prior major releases are deprecated */ -+ m->deprecation_reason = rhel_old_machine_deprecation; -+ + pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_version = "8.6.0"; + compat_props_add(m->compat_props, hw_compat_rhel_8_6, + hw_compat_rhel_8_6_len); +} + -+DEFINE_PC_MACHINE(q35_rhel860, "pc-q35-rhel8.6.0", pc_q35_init_rhel860, -+ pc_q35_machine_rhel860_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 6, 0); + -+ -+static void pc_q35_init_rhel850(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel850_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_5_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel860_options(m); ++ pc_q35_rhel_machine_8_6_0_options(m); + m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; @@ -566,19 +552,12 @@ index c7bc8a2041..e872dc7e46 100644 + m->smp_props.prefer_sockets = true; +} + -+DEFINE_PC_MACHINE(q35_rhel850, "pc-q35-rhel8.5.0", pc_q35_init_rhel850, -+ pc_q35_machine_rhel850_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 5, 0); + -+ -+static void pc_q35_init_rhel840(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel840_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_4_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel850_options(m); ++ pc_q35_rhel_machine_8_5_0_options(m); + m->desc = "RHEL-8.4.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; @@ -589,19 +568,12 @@ index c7bc8a2041..e872dc7e46 100644 + pc_rhel_8_4_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel840, "pc-q35-rhel8.4.0", pc_q35_init_rhel840, -+ pc_q35_machine_rhel840_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 4, 0); + -+ -+static void pc_q35_init_rhel830(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel830_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_3_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel840_options(m); ++ pc_q35_rhel_machine_8_4_0_options(m); + m->desc = "RHEL-8.3.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; @@ -616,18 +588,12 @@ index c7bc8a2041..e872dc7e46 100644 + pcmc->pci_root_uid = 1; +} + -+DEFINE_PC_MACHINE(q35_rhel830, "pc-q35-rhel8.3.0", pc_q35_init_rhel830, -+ pc_q35_machine_rhel830_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 3, 0); + -+static void pc_q35_init_rhel820(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel820_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_2_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel830_options(m); ++ pc_q35_rhel_machine_8_3_0_options(m); + m->desc = "RHEL-8.2.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + m->numa_mem_supported = true; @@ -640,18 +606,12 @@ index c7bc8a2041..e872dc7e46 100644 + pc_rhel_8_2_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel820, "pc-q35-rhel8.2.0", pc_q35_init_rhel820, -+ pc_q35_machine_rhel820_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 2, 0); + -+static void pc_q35_init_rhel810(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel810_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_1_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel820_options(m); ++ pc_q35_rhel_machine_8_2_0_options(m); + m->desc = "RHEL-8.1.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = NULL; @@ -660,18 +620,12 @@ index c7bc8a2041..e872dc7e46 100644 + compat_props_add(m->compat_props, pc_rhel_8_1_compat, pc_rhel_8_1_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel810, "pc-q35-rhel8.1.0", pc_q35_init_rhel810, -+ pc_q35_machine_rhel810_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 1, 0); + -+static void pc_q35_init_rhel800(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel800_options(MachineClass *m) ++static void pc_q35_rhel_machine_8_0_0_options(MachineClass *m) +{ + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel810_options(m); ++ pc_q35_rhel_machine_8_1_0_options(m); + m->desc = "RHEL-8.0.0 PC (Q35 + ICH9, 2009)"; + m->smbus_no_migration_support = true; + m->alias = NULL; @@ -681,17 +635,11 @@ index c7bc8a2041..e872dc7e46 100644 + compat_props_add(m->compat_props, pc_rhel_8_0_compat, pc_rhel_8_0_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel800, "pc-q35-rhel8.0.0", pc_q35_init_rhel800, -+ pc_q35_machine_rhel800_options); ++DEFINE_Q35_MACHINE_BUGFIX(8, 0, 0); + -+static void pc_q35_init_rhel760(MachineState *machine) ++static void pc_q35_rhel_machine_7_6_0_options(MachineClass *m) +{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel760_options(MachineClass *m) -+{ -+ pc_q35_machine_rhel800_options(m); ++ pc_q35_rhel_machine_8_0_0_options(m); + m->alias = NULL; + m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)"; + m->async_pf_vmexit_disable = true; @@ -699,13 +647,13 @@ index c7bc8a2041..e872dc7e46 100644 + compat_props_add(m->compat_props, pc_rhel_7_6_compat, pc_rhel_7_6_compat_len); +} + -+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, -+ pc_q35_machine_rhel760_options); ++DEFINE_Q35_MACHINE_BUGFIX(7, 6, 0); ++ diff --git a/include/hw/boards.h b/include/hw/boards.h -index 0466f9d0f3..46b8725c41 100644 +index 32c4642f5a..85b43e3d0d 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h -@@ -283,6 +283,8 @@ struct MachineClass { +@@ -289,6 +289,8 @@ struct MachineClass { strList *allowed_dynamic_sysbus_devices; bool auto_enable_numa_with_memhp; bool auto_enable_numa_with_memdev; @@ -715,16 +663,19 @@ index 0466f9d0f3..46b8725c41 100644 bool smbus_no_migration_support; bool nvdimm_supported; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index ebd8f973f2..a984c951ad 100644 +index 8776a3c937..75c9271cdd 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h -@@ -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; +@@ -302,6 +302,42 @@ extern const size_t pc_compat_2_4_len; + extern GlobalProperty pc_compat_2_3[]; + extern const size_t pc_compat_2_3_len; +extern GlobalProperty pc_rhel_compat[]; +extern const size_t pc_rhel_compat_len; + ++extern GlobalProperty pc_rhel_9_5_compat[]; ++extern const size_t pc_rhel_9_5_compat_len; ++ +extern GlobalProperty pc_rhel_9_3_compat[]; +extern const size_t pc_rhel_9_3_compat_len; + @@ -759,10 +710,10 @@ index ebd8f973f2..a984c951ad 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 33760a2ee1..be7b0663cd 100644 +index 85ef7452c0..ed278dd4a1 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c -@@ -2190,9 +2190,13 @@ static const CPUCaches epyc_genoa_cache_info = { +@@ -2411,9 +2411,13 @@ static const CPUCaches epyc_genoa_cache_info = { * PT in VMX operation */ @@ -776,7 +727,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 0xd, .vendor = CPUID_VENDOR_AMD, .family = 15, -@@ -2213,6 +2217,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2434,6 +2438,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "phenom", @@ -784,7 +735,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 5, .vendor = CPUID_VENDOR_AMD, .family = 16, -@@ -2245,6 +2250,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2466,6 +2471,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "core2duo", @@ -792,7 +743,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2287,6 +2293,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2508,6 +2514,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "kvm64", @@ -800,7 +751,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 0xd, .vendor = CPUID_VENDOR_INTEL, .family = 15, -@@ -2328,6 +2335,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2549,6 +2556,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "qemu32", @@ -808,7 +759,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 4, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2342,6 +2350,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2563,6 +2571,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "kvm32", @@ -816,7 +767,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 5, .vendor = CPUID_VENDOR_INTEL, .family = 15, -@@ -2372,6 +2381,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2593,6 +2602,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "coreduo", @@ -824,7 +775,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2405,6 +2415,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2626,6 +2636,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "486", @@ -832,7 +783,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 1, .vendor = CPUID_VENDOR_INTEL, .family = 4, -@@ -2417,6 +2428,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2638,6 +2649,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "pentium", @@ -840,7 +791,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 1, .vendor = CPUID_VENDOR_INTEL, .family = 5, -@@ -2429,6 +2441,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2650,6 +2662,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "pentium2", @@ -848,7 +799,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 2, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2441,6 +2454,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2662,6 +2675,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "pentium3", @@ -856,7 +807,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 3, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2453,6 +2467,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2674,6 +2688,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "athlon", @@ -864,7 +815,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 2, .vendor = CPUID_VENDOR_AMD, .family = 6, -@@ -2468,6 +2483,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2689,6 +2704,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "n270", @@ -872,7 +823,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2493,6 +2509,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2714,6 +2730,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "Conroe", @@ -880,7 +831,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -2533,6 +2550,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -2754,6 +2771,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "Penryn", @@ -888,7 +839,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 10, .vendor = CPUID_VENDOR_INTEL, .family = 6, -@@ -4394,6 +4412,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -4762,6 +4780,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "Opteron_G1", @@ -896,7 +847,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 5, .vendor = CPUID_VENDOR_AMD, .family = 15, -@@ -4414,6 +4433,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -4782,6 +4801,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "Opteron_G2", @@ -904,7 +855,7 @@ index 33760a2ee1..be7b0663cd 100644 .level = 5, .vendor = CPUID_VENDOR_AMD, .family = 15, -@@ -4436,6 +4456,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { +@@ -4804,6 +4824,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { }, { .name = "Opteron_G3", @@ -913,10 +864,10 @@ index 33760a2ee1..be7b0663cd 100644 .vendor = CPUID_VENDOR_AMD, .family = 16, diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index 9c791b7b05..b91af5051f 100644 +index 6bf8dcfc60..684e731cbc 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c -@@ -138,6 +138,7 @@ static PropValue kvm_default_props[] = { +@@ -178,6 +178,7 @@ static PropValue kvm_default_props[] = { { "acpi", "off" }, { "monitor", "off" }, { "svm", "off" }, @@ -925,10 +876,10 @@ index 9c791b7b05..b91af5051f 100644 }; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e68cbe9293..739f33db47 100644 +index 2fa88ef1e3..2b28c18693 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c -@@ -3715,6 +3715,7 @@ static int kvm_get_msrs(X86CPU *cpu) +@@ -4244,6 +4244,7 @@ static int kvm_get_msrs(X86CPU *cpu) struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; int ret, i; uint64_t mtrr_top_bits; @@ -936,7 +887,7 @@ index e68cbe9293..739f33db47 100644 kvm_msr_buf_reset(cpu); -@@ -4069,6 +4070,9 @@ static int kvm_get_msrs(X86CPU *cpu) +@@ -4636,6 +4637,9 @@ static int kvm_get_msrs(X86CPU *cpu) break; case MSR_KVM_ASYNC_PF_EN: env->async_pf_en_msr = msrs[i].data; @@ -947,10 +898,10 @@ index e68cbe9293..739f33db47 100644 case MSR_KVM_ASYNC_PF_INT: env->async_pf_int_msr = msrs[i].data; diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c -index 78f1cf8186..ac954c9b06 100644 +index d49d2ba931..c18f63e255 100644 --- a/tests/qtest/pvpanic-test.c +++ b/tests/qtest/pvpanic-test.c -@@ -17,7 +17,7 @@ static void test_panic_nopause(void) +@@ -18,7 +18,7 @@ static void test_panic_nopause(void) QDict *response, *data; QTestState *qts; @@ -958,8 +909,8 @@ index 78f1cf8186..ac954c9b06 100644 + qts = qtest_init("-M q35 -device pvpanic -action panic=none"); val = qtest_inb(qts, 0x505); - g_assert_cmpuint(val, ==, 3); -@@ -40,7 +40,8 @@ static void test_panic(void) + g_assert_cmpuint(val, ==, PVPANIC_EVENTS); +@@ -41,7 +41,8 @@ static void test_panic(void) QDict *response, *data; QTestState *qts; @@ -968,7 +919,7 @@ index 78f1cf8186..ac954c9b06 100644 + qts = qtest_init("-M q35 -device pvpanic -action panic=pause"); val = qtest_inb(qts, 0x505); - g_assert_cmpuint(val, ==, 3); + g_assert_cmpuint(val, ==, PVPANIC_EVENTS); -- 2.39.3 diff --git a/SOURCES/0015-Revert-meson-temporarily-disable-Wunused-function.patch b/SOURCES/0015-Revert-meson-temporarily-disable-Wunused-function.patch new file mode 100644 index 0000000..e528ecf --- /dev/null +++ b/SOURCES/0015-Revert-meson-temporarily-disable-Wunused-function.patch @@ -0,0 +1,32 @@ +From 2698c3de00b8736553112a037c7ffb5f5d9086b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 3 Jul 2024 13:47:04 +0100 +Subject: Revert "meson: temporarily disable -Wunused-function" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit c682111eaa73d9b985187b8be330338f50b78a7a. + +No longer needed after introduction of downstream machines. + +Signed-off-by: Daniel P. Berrangé +--- + meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 2de5ab024f..b3529aa0e1 100644 +--- a/meson.build ++++ b/meson.build +@@ -651,7 +651,6 @@ warn_flags = [ + '-Wno-string-plus-int', + '-Wno-tautological-type-limit-compare', + '-Wno-typedef-redefinition', +- '-Wno-unused-function', + ] + + if host_os != 'darwin' +-- +2.39.3 + diff --git a/SOURCES/0016-Add-upstream-compatibility-bits.patch b/SOURCES/0016-Add-upstream-compatibility-bits.patch deleted file mode 100644 index 3efa22c..0000000 --- a/SOURCES/0016-Add-upstream-compatibility-bits.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 59470e8ab849f22b407f55292e540e16a8cad01a Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -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 - ---- - -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 - diff --git a/SOURCES/0011-Enable-make-check.patch b/SOURCES/0016-Enable-make-check.patch similarity index 88% rename from SOURCES/0011-Enable-make-check.patch rename to SOURCES/0016-Enable-make-check.patch index 502bc67..0afff4e 100644 --- a/SOURCES/0011-Enable-make-check.patch +++ b/SOURCES/0016-Enable-make-check.patch @@ -1,4 +1,4 @@ -From 5768cf6811842e5c59da3b752f60659a9d6b5ba1 Mon Sep 17 00:00:00 2001 +From b877c7926d84e264bcfa57e6797f997d400fb19d Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 2 Sep 2020 09:39:41 +0200 Subject: Enable make check @@ -38,6 +38,9 @@ Rebase changes (8.1.0): Rebase changes (8.2.0 rc1): - Remove unneeded hack in qtest/usb-hcd-xhci-test.c +Rebase changes (9.1.0 rc0): +- use q35 for new pvpanic test + Merged patches (6.1.0): - 2f129df7d3 redhat: Enable the 'test-block-iothread' test again @@ -47,10 +50,12 @@ Merged patches (7.1.0): Merged patches (8.1.0): - f468163234 iotests: Use alternative CPU type that is not deprecated in RHEL --- + .distro/Makefile | 2 +- .distro/qemu-kvm.spec.template | 4 ++-- + .distro/scripts/process-patches.sh | 3 +++ tests/avocado/replay_kernel.py | 2 +- tests/avocado/reverse_debugging.py | 2 +- - tests/avocado/tcg_plugins.py | 6 ++--- + tests/avocado/tcg_plugins.py | 4 ++-- tests/qemu-iotests/meson.build | 34 ++++++++++++++--------------- tests/qemu-iotests/testenv.py | 3 +++ tests/qtest/fuzz-e1000e-test.c | 2 +- @@ -59,14 +64,15 @@ Merged patches (8.1.0): tests/qtest/libqos/meson.build | 2 +- tests/qtest/lpc-ich9-test.c | 2 +- tests/qtest/meson.build | 1 - + tests/qtest/pvpanic-test.c | 2 +- tests/qtest/virtio-net-failover.c | 1 + - 13 files changed, 33 insertions(+), 30 deletions(-) + 16 files changed, 37 insertions(+), 31 deletions(-) diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py -index 10d99403a4..c3422ea1e4 100644 +index e22c200a36..cb7ca19b1b 100644 --- a/tests/avocado/replay_kernel.py +++ b/tests/avocado/replay_kernel.py -@@ -166,7 +166,7 @@ def test_aarch64_virt(self): +@@ -193,7 +193,7 @@ def test_aarch64_virt(self): """ :avocado: tags=arch:aarch64 :avocado: tags=machine:virt @@ -76,10 +82,10 @@ index 10d99403a4..c3422ea1e4 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 92855a02a5..87822074b6 100644 +index f24287cd0a..3880b81df6 100644 --- a/tests/avocado/reverse_debugging.py +++ b/tests/avocado/reverse_debugging.py -@@ -230,7 +230,7 @@ def test_aarch64_virt(self): +@@ -228,7 +228,7 @@ def test_aarch64_virt(self): """ :avocado: tags=arch:aarch64 :avocado: tags=machine:virt @@ -89,7 +95,7 @@ index 92855a02a5..87822074b6 100644 kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' '/linux/releases/29/Everything/aarch64/os/images/pxeboot' diff --git a/tests/avocado/tcg_plugins.py b/tests/avocado/tcg_plugins.py -index 15fd87b2c1..f0d9d89c93 100644 +index a6ff457e27..5172ee9b9e 100644 --- a/tests/avocado/tcg_plugins.py +++ b/tests/avocado/tcg_plugins.py @@ -66,7 +66,7 @@ def test_aarch64_virt_insn(self): @@ -106,15 +112,6 @@ index 15fd87b2c1..f0d9d89c93 100644 :avocado: tags=arch:aarch64 :avocado: tags=machine:virt - :avocado: tags=cpu:cortex-a53 -+ :avocado: tags=cpu:cortex-a57 - """ - kernel_path = self._grab_aarch64_kernel() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + -@@ -126,7 +126,7 @@ def test_aarch64_virt_mem_icount(self): - :avocado: tags=accel:tcg - :avocado: tags=arch:aarch64 - :avocado: tags=machine:virt -- :avocado: tags=cpu:cortex-a53 + :avocado: tags=cpu:cortex-a57 """ kernel_path = self._grab_aarch64_kernel() @@ -163,10 +160,10 @@ index fad340ad59..3c0d5241f6 100644 +# endforeach endforeach diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py -index 588f30a4f1..3929a3634f 100644 +index c8848f2ec2..d515e5b8b0 100644 --- a/tests/qemu-iotests/testenv.py +++ b/tests/qemu-iotests/testenv.py -@@ -244,6 +244,9 @@ def __init__(self, source_dir: str, build_dir: str, +@@ -249,6 +249,9 @@ def __init__(self, source_dir: str, build_dir: str, if self.qemu_prog.endswith(f'qemu-system-{suffix}'): self.qemu_options += f' -machine {machine}' @@ -216,7 +213,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 3aed6efcb8..119613237e 100644 +index 1b2b2dbb22..86afbddb58 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -44,7 +44,7 @@ libqos_srcs = files( @@ -242,10 +239,10 @@ index 8ac95b89f7..cd2102555c 100644 qtest_outl(s, 0xcf8, 0x8000f840); /* PMBASE */ diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build -index 36c5c13a7b..a2887d6057 100644 +index 2f0d3ef080..44ee791508 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build -@@ -101,7 +101,6 @@ qtests_i386 = \ +@@ -102,7 +102,6 @@ qtests_i386 = \ 'drive_del-test', 'tco-test', 'cpu-plug-test', @@ -253,6 +250,19 @@ index 36c5c13a7b..a2887d6057 100644 'vmgenid-test', 'migration-test', 'test-x86-cpuid-compat', +diff --git a/tests/qtest/pvpanic-test.c b/tests/qtest/pvpanic-test.c +index c18f63e255..57fb129ae4 100644 +--- a/tests/qtest/pvpanic-test.c ++++ b/tests/qtest/pvpanic-test.c +@@ -65,7 +65,7 @@ static void test_pvshutdown(void) + QDict *response, *data; + QTestState *qts; + +- qts = qtest_init("-device pvpanic"); ++ qts = qtest_init("-M q35 -device pvpanic"); + + val = qtest_inb(qts, 0x505); + g_assert_cmpuint(val, ==, PVPANIC_EVENTS); diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c index 73dfabc272..a9dd304781 100644 --- a/tests/qtest/virtio-net-failover.c diff --git a/SOURCES/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch b/SOURCES/0017-vfio-cap-number-of-devices-that-can-be-assigned.patch similarity index 91% rename from SOURCES/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch rename to SOURCES/0017-vfio-cap-number-of-devices-that-can-be-assigned.patch index e8bf13a..b18c2bd 100644 --- a/SOURCES/0012-vfio-cap-number-of-devices-that-can-be-assigned.patch +++ b/SOURCES/0017-vfio-cap-number-of-devices-that-can-be-assigned.patch @@ -1,4 +1,4 @@ -From e06a905d726fc20ea6bd95dff1bd0ffe97ebb202 Mon Sep 17 00:00:00 2001 +From a30996377bd8b1316cd79ac482b4f9ae9a50c31d Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Tue, 3 Dec 2013 20:05:13 +0100 Subject: vfio: cap number of devices that can be assigned @@ -35,7 +35,7 @@ Rebase changes (8.2.0): 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 64780d1b79..57ac63c10c 100644 +index 2407720c35..82a47edc89 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -50,6 +50,9 @@ @@ -48,19 +48,16 @@ index 64780d1b79..57ac63c10c 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); -@@ -2946,13 +2949,36 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) +@@ -2963,10 +2966,33 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) ERRP_GUARD(); VFIOPCIDevice *vdev = VFIO_PCI(pdev); VFIODevice *vbasedev = &vdev->vbasedev; -+ VFIODevice *vbasedev_iter; -+ VFIOGroup *group; - char *tmp, *subsys; - Error *err = NULL; - int i, ret; + int ret, i = 0; - bool is_mdev; ++ VFIODevice *vbasedev_iter; ++ VFIOGroup *group; char uuid[UUID_STR_LEN]; - char *name; + g_autofree char *name = NULL; + if (device_limit && device_limit != vdev->assigned_device_limit) { + error_setg(errp, "Assigned device limit has been redefined. " @@ -86,7 +83,7 @@ index 64780d1b79..57ac63c10c 100644 if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { if (!(~vdev->host.domain || ~vdev->host.bus || ~vdev->host.slot || ~vdev->host.function)) { -@@ -3370,6 +3396,9 @@ static Property vfio_pci_dev_properties[] = { +@@ -3388,6 +3414,9 @@ static Property vfio_pci_dev_properties[] = { DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false), DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice, no_geforce_quirks, false), @@ -97,7 +94,7 @@ index 64780d1b79..57ac63c10c 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 6e64a2654e..b7de39c010 100644 +index bf67df2fbc..0d3c93fb2e 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -142,6 +142,7 @@ struct VFIOPCIDevice { diff --git a/SOURCES/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch b/SOURCES/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch deleted file mode 100644 index 5befe68..0000000 --- a/SOURCES/0017-x86-rhel-9.4.0-machine-type-compat-fix.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ba574acacf679850e337ec2d5e7836b8277cf393 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -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 ---- - 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 - diff --git a/SOURCES/0013-Add-support-statement-to-help-output.patch b/SOURCES/0018-Add-support-statement-to-help-output.patch similarity index 88% rename from SOURCES/0013-Add-support-statement-to-help-output.patch rename to SOURCES/0018-Add-support-statement-to-help-output.patch index 0644440..a3ef6f6 100644 --- a/SOURCES/0013-Add-support-statement-to-help-output.patch +++ b/SOURCES/0018-Add-support-statement-to-help-output.patch @@ -1,4 +1,4 @@ -From b467dc6a24ef41fa574260429807711f6802a54d Mon Sep 17 00:00:00 2001 +From d2a73465e69118a37a2bbc487b6faa30c9b5a81f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost 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 1 file changed, 9 insertions(+) diff --git a/system/vl.c b/system/vl.c -index c644222982..03c3b0aa94 100644 +index 01b8b8e77a..5359231bf5 100644 --- a/system/vl.c +++ b/system/vl.c -@@ -869,9 +869,17 @@ static void version(void) +@@ -877,9 +877,17 @@ static void version(void) QEMU_COPYRIGHT "\n"); } @@ -42,7 +42,7 @@ index c644222982..03c3b0aa94 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()); -@@ -897,6 +905,7 @@ static void help(int exitcode) +@@ -905,6 +913,7 @@ static void help(int exitcode) "\n" QEMU_HELP_BOTTOM "\n"); diff --git a/SOURCES/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/SOURCES/0019-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch similarity index 94% rename from SOURCES/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch rename to SOURCES/0019-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch index 04adb4a..4eb7d29 100644 --- a/SOURCES/0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +++ b/SOURCES/0019-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch @@ -1,4 +1,4 @@ -From 20cc3a6d9bce3e40d165f865b5e398c300cae7bf Mon Sep 17 00:00:00 2001 +From ca0507cfda11a73cb4311fc0b3a934ce8b40c5e9 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 8 Jul 2020 08:35:50 +0200 Subject: Use qemu-kvm in documentation instead of qemu-system- @@ -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 8ce85d4559..4fc27ee2e2 100644 +index d94e2cbbae..a7444abc7f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx -@@ -3493,11 +3493,11 @@ SRST +@@ -3688,11 +3688,11 @@ SRST :: diff --git a/SOURCES/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch b/SOURCES/0020-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch similarity index 95% rename from SOURCES/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch rename to SOURCES/0020-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch index 8518918..f1414a2 100644 --- a/SOURCES/0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch +++ b/SOURCES/0020-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch @@ -1,4 +1,4 @@ -From 2f9fdd21ecf2810d0d83a8125ce0cc1e75dbb13a Mon Sep 17 00:00:00 2001 +From 3fbdf1e92fe0dbabb59b611dfb3ad906edf80979 Mon Sep 17 00:00:00 2001 From: Kevin Wolf 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 956128b409..0e8b2f7518 100644 +index 70b19730a3..a4cffb628c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1358,6 +1358,12 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, @@ -61,7 +61,7 @@ index 956128b409..0e8b2f7518 100644 s->qcow_version = header.version; diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter -index 2846c83808..83472953a2 100644 +index fc3c64bcb8..4b238954d5 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -83,6 +83,7 @@ _filter_qemu() diff --git a/SOURCES/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch b/SOURCES/0021-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch similarity index 84% rename from SOURCES/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch rename to SOURCES/0021-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch index 967adc1..9657842 100644 --- a/SOURCES/kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch +++ b/SOURCES/0021-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch @@ -1,8 +1,7 @@ -From 97e10c2ccc8dc29019d6d22de1d23c55fea0f6c4 Mon Sep 17 00:00:00 2001 +From 8c62f120efeedfcdc43fece9f65b4c1b5b0a06e6 Mon Sep 17 00:00:00 2001 From: Dehan Meng Date: Wed, 21 Aug 2024 14:55:01 +0800 -Subject: [PATCH] qemu-guest-agent: Update the logfile path of - qga-fsfreeze-hook.log +Subject: qemu-guest-agent: Update the logfile path of qga-fsfreeze-hook.log RH-Author: 6-dehan RH-MergeRequest: 265: qemu-guest-agent: Update the logfile path of qga-fsfreeze-hook.log @@ -18,6 +17,10 @@ existing SELinux boolean and policy. Jira: https://issues.redhat.com/browse/RHEL-52250 Signed-off-by: Dehan Meng + +Patch-name: kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch +Patch-id: 137 +Patch-present-in-specfile: True --- scripts/qemu-guest-agent/fsfreeze-hook | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SOURCES/0023-Add-upstream-compatibility-bits.patch b/SOURCES/0023-Add-upstream-compatibility-bits.patch new file mode 100644 index 0000000..8d75874 --- /dev/null +++ b/SOURCES/0023-Add-upstream-compatibility-bits.patch @@ -0,0 +1,109 @@ +From 2b6f52a948d4ee1bbaadec56151a6c30782693a2 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Wed, 15 May 2024 01:41:13 -0400 +Subject: Add upstream compatibility bits + +--- + hw/arm/virt.c | 1 + + hw/core/machine.c | 17 +++++++++++++++++ + hw/i386/pc_piix.c | 2 ++ + hw/i386/pc_q35.c | 2 ++ + hw/s390x/s390-virtio-ccw.c | 1 + + include/hw/boards.h | 3 +++ + 6 files changed, 26 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 903c0f2e9f..3c776b5011 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -3582,6 +3582,7 @@ DEFINE_VIRT_MACHINE(2, 6) + + static void virt_rhel_machine_9_4_0_options(MachineClass *mc) + { ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } + DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0) +diff --git a/hw/core/machine.c b/hw/core/machine.c +index f7fed78e4b..add42660f8 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -311,6 +311,23 @@ const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1); + const char *rhel_old_machine_deprecation = + "machine types for previous major releases are deprecated"; + ++GlobalProperty hw_compat_rhel_9_6[] = { ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ {"arm-cpu", "backcompat-cntfrq", "true" }, ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ { "scsi-hd", "migrate-emulated-scsi-request", "false" }, ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ { "scsi-cd", "migrate-emulated-scsi-request", "false" }, ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ {"vfio-pci", "skip-vsc-check", "false" }, ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ { "virtio-pci", "x-pcie-pm-no-soft-reset", "off" }, ++ /* hw_compat_rhel_9_6 from hw_compat_9_0 */ ++ {"sd-card", "spec_version", "2" }, ++}; ++const size_t hw_compat_rhel_9_6_len = G_N_ELEMENTS(hw_compat_rhel_9_6); ++ ++ + GlobalProperty hw_compat_rhel_9_5[] = { + /* hw_compat_rhel_9_5 from hw_compat_8_2 */ + { "migration", "zero-page-detection", "legacy"}, +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index c93e78e896..80323cc08c 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -880,6 +880,8 @@ static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m) + object_class_property_set_description(oc, "x-south-bridge", + "Use a different south bridge than PIIX3"); + ++ compat_props_add(m->compat_props, hw_compat_rhel_9_6, ++ hw_compat_rhel_9_6_len); + compat_props_add(m->compat_props, pc_rhel_9_5_compat, + pc_rhel_9_5_compat_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_5, +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 76f0ac1acd..4580b2266e 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -681,6 +681,8 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) + pcmc->smbios_stream_version = "9.4.0"; + pcmc->isa_bios_alias = false; + ++ compat_props_add(m->compat_props, hw_compat_rhel_9_6, ++ hw_compat_rhel_9_6_len); + compat_props_add(m->compat_props, pc_rhel_9_5_compat, + pc_rhel_9_5_compat_len); + compat_props_add(m->compat_props, hw_compat_rhel_9_5, +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 72e1279db9..f884528639 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -1314,6 +1314,7 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine) + + static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc) + { ++ compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } + DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0); +diff --git a/include/hw/boards.h b/include/hw/boards.h +index 85b43e3d0d..ffefc0a625 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -802,6 +802,9 @@ extern const size_t hw_compat_2_2_len; + extern GlobalProperty hw_compat_2_1[]; + extern const size_t hw_compat_2_1_len; + ++extern GlobalProperty hw_compat_rhel_9_6[]; ++extern const size_t hw_compat_rhel_9_6_len; ++ + extern GlobalProperty hw_compat_rhel_9_5[]; + extern const size_t hw_compat_rhel_9_5_len; + +-- +2.39.3 + diff --git a/SOURCES/0024-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch b/SOURCES/0024-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch new file mode 100644 index 0000000..1f2c796 --- /dev/null +++ b/SOURCES/0024-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch @@ -0,0 +1,37 @@ +From 492900c0b6a99f157249c2706c2f2ef5f67d20df Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 26 Aug 2024 14:27:49 +0200 +Subject: redhat: Add QEMU 9.1 compat handling to the s390x machine types + +JIRA: https://issues.redhat.com/browse/RHEL-52323 + +Upstream changed the amount of information that is migrated for +the S390 interrupt controller (FLIC), so we have to switch on +a compatibility property for older machine types. + +Signed-off-by: Thomas Huth +--- + hw/s390x/s390-virtio-ccw.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index f884528639..4b7290f7a8 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -1314,8 +1314,13 @@ static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine) + + static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc) + { ++ static GlobalProperty compat[] = { ++ { TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", }, ++ }; ++ + compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); ++ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); + } + DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0); + +-- +2.39.3 + diff --git a/SOURCES/0025-redhat-Add-rhel9.6.0-machine-type.patch b/SOURCES/0025-redhat-Add-rhel9.6.0-machine-type.patch new file mode 100644 index 0000000..abaa414 --- /dev/null +++ b/SOURCES/0025-redhat-Add-rhel9.6.0-machine-type.patch @@ -0,0 +1,55 @@ +From 1ceaf6413ec7cb19ea2b6147ec91c776c7c5df40 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 26 Aug 2024 14:42:24 +0200 +Subject: redhat: Add rhel9.6.0 machine type + +JIRA: https://issues.redhat.com/browse/RHEL-52323 + +Add a new machine type to enable the latest features by default. + +Signed-off-by: Thomas Huth +--- + hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 4b7290f7a8..a4a6ffa053 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -1308,8 +1308,18 @@ DEFINE_CCW_MACHINE(2, 4); + #endif + #endif /* disabled for RHEL */ + ++static void ccw_rhel_machine_9_6_0_instance_options(MachineState *machine) ++{ ++} ++ ++static void ccw_rhel_machine_9_6_0_class_options(MachineClass *mc) ++{ ++} ++DEFINE_CCW_MACHINE_AS_LATEST(9, 6, 0); ++ + static void ccw_rhel_machine_9_4_0_instance_options(MachineState *machine) + { ++ ccw_rhel_machine_9_6_0_instance_options(machine); + } + + static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc) +@@ -1318,11 +1328,13 @@ static void ccw_rhel_machine_9_4_0_class_options(MachineClass *mc) + { TYPE_QEMU_S390_FLIC, "migrate-all-state", "off", }, + }; + ++ ccw_rhel_machine_9_6_0_class_options(mc); ++ + compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); + } +-DEFINE_CCW_MACHINE_AS_LATEST(9, 4, 0); ++DEFINE_CCW_MACHINE(9, 4, 0); + + static void ccw_rhel_machine_9_2_0_instance_options(MachineState *machine) + { +-- +2.39.3 + diff --git a/SOURCES/0026-x86-ensure-compatibility-of-pc-q35-rhel9-and-pc-i440.patch b/SOURCES/0026-x86-ensure-compatibility-of-pc-q35-rhel9-and-pc-i440.patch new file mode 100644 index 0000000..e6f14b8 --- /dev/null +++ b/SOURCES/0026-x86-ensure-compatibility-of-pc-q35-rhel9-and-pc-i440.patch @@ -0,0 +1,43 @@ +From f35f400c9255be5fbb0158c6885a96ef23e7fb86 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 5 Sep 2024 12:54:34 +0200 +Subject: x86: ensure compatibility of pc-q35-rhel9* and pc-i440fx-rhel7.6.0 + +Signed-off-by: Sebastian Ott +--- + hw/i386/pc_piix.c | 3 +++ + hw/i386/pc_q35.c | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 80323cc08c..656abb5d39 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -872,6 +872,9 @@ static void pc_i440fx_rhel_machine_7_6_0_options(MachineClass *m) + pcmc->broken_32bit_mem_addr_check = true; + /* Introduced in QEMU 8.2 */ + pcmc->default_south_bridge = TYPE_PIIX3_DEVICE; ++ /* From pc_i440fx_machine_9_0_options() */ ++ m->smbios_memory_device_size = 16 * GiB; ++ pcmc->isa_bios_alias = false; + + object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption", + &PCSouthBridgeOption_lookup, +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 4580b2266e..5cfed8b62f 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -679,7 +679,10 @@ static void pc_q35_rhel_machine_9_4_0_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"; ++ ++ /* From pc_q35_machine_9_0_options() */ + pcmc->isa_bios_alias = false; ++ m->smbios_memory_device_size = 16 * GiB; + + compat_props_add(m->compat_props, hw_compat_rhel_9_6, + hw_compat_rhel_9_6_len); +-- +2.39.3 + diff --git a/SOURCES/0027-arm-ensure-compatibility-of-virt-rhel9.patch b/SOURCES/0027-arm-ensure-compatibility-of-virt-rhel9.patch new file mode 100644 index 0000000..2e09fa2 --- /dev/null +++ b/SOURCES/0027-arm-ensure-compatibility-of-virt-rhel9.patch @@ -0,0 +1,27 @@ +From 9c65a3e2e15c96b3b74d7c7846dbd60b13474370 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 5 Sep 2024 13:02:32 +0200 +Subject: arm: ensure compatibility of virt-rhel9* + +Signed-off-by: Sebastian Ott +--- + hw/arm/virt.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 3c776b5011..1af1c9e170 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -3582,6 +3582,9 @@ DEFINE_VIRT_MACHINE(2, 6) + + static void virt_rhel_machine_9_4_0_options(MachineClass *mc) + { ++ /* From virt_machine_9_0_options() */ ++ mc->smbios_memory_device_size = 16 * GiB; ++ + compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } +-- +2.39.3 + diff --git a/SOURCES/0028-arm-create-new-virt-machine-type-for-rhel-9.6.patch b/SOURCES/0028-arm-create-new-virt-machine-type-for-rhel-9.6.patch new file mode 100644 index 0000000..ff63e0a --- /dev/null +++ b/SOURCES/0028-arm-create-new-virt-machine-type-for-rhel-9.6.patch @@ -0,0 +1,41 @@ +From 005be8f390c038ab9674103e1644dc1549c434a9 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 5 Sep 2024 13:11:23 +0200 +Subject: arm: create new virt machine type for rhel 9.6 + +Signed-off-by: Sebastian Ott +--- + 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 1af1c9e170..bf05499a12 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -3580,15 +3580,22 @@ static void virt_machine_2_6_options(MachineClass *mc) + DEFINE_VIRT_MACHINE(2, 6) + #endif /* disabled for RHEL */ + ++static void virt_rhel_machine_9_6_0_options(MachineClass *mc) ++{ ++} ++DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0) ++ + static void virt_rhel_machine_9_4_0_options(MachineClass *mc) + { ++ virt_rhel_machine_9_6_0_options(mc); ++ + /* From virt_machine_9_0_options() */ + mc->smbios_memory_device_size = 16 * GiB; + + compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + } +-DEFINE_VIRT_MACHINE_AS_LATEST(9, 4, 0) ++DEFINE_VIRT_MACHINE(9, 4, 0) + + static void virt_rhel_machine_9_2_0_options(MachineClass *mc) + { +-- +2.39.3 + diff --git a/SOURCES/0029-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch b/SOURCES/0029-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch new file mode 100644 index 0000000..e118d8e --- /dev/null +++ b/SOURCES/0029-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch @@ -0,0 +1,42 @@ +From 826f14b90a0ad2427e4e80232c0fbaea80600650 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 5 Sep 2024 13:31:12 +0200 +Subject: x86: create new pc-q35 machine type for rhel 9.6 + +Signed-off-by: Sebastian Ott +--- + hw/i386/pc_q35.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 5cfed8b62f..7606007bda 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -672,11 +672,23 @@ DEFINE_Q35_MACHINE(2, 4); + + /* Red Hat Enterprise Linux machine types */ + +-static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) ++static void pc_q35_rhel_machine_9_6_0_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + pc_q35_machine_options(m); ++ m->desc = "RHEL-9.6.0 PC (Q35 + ICH9, 2009)"; ++ pcmc->smbios_stream_product = "RHEL"; ++ pcmc->smbios_stream_version = "9.6.0"; ++} ++ ++DEFINE_Q35_MACHINE_BUGFIX(9, 6, 0); ++ ++static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_rhel_machine_9_6_0_options(m); + m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; ++ m->alias = NULL; + pcmc->smbios_stream_product = "RHEL"; + pcmc->smbios_stream_version = "9.4.0"; + +-- +2.39.3 + diff --git a/SOURCES/0030-hw-arm-virt-Fix-Manufacturer-and-Product-Name-in-emu.patch b/SOURCES/0030-hw-arm-virt-Fix-Manufacturer-and-Product-Name-in-emu.patch new file mode 100644 index 0000000..1419445 --- /dev/null +++ b/SOURCES/0030-hw-arm-virt-Fix-Manufacturer-and-Product-Name-in-emu.patch @@ -0,0 +1,90 @@ +From d6a415e7a62ca1bc21f1833f4251f512b2072a93 Mon Sep 17 00:00:00 2001 +From: Shaoqin Huang +Date: Wed, 22 May 2024 03:23:28 -0400 +Subject: hw/arm/virt: Fix Manufacturer and Product Name in emulated SMBIOS + mode + +Status: RHEL-only + +In vm, when run 'dmidecode -t system', it outputs different Manufacturer +and Product Name on x86_64 and aarch64 system. For example: + +For aarch64 vm: + Manufacturer: QEMU + Product Name: KVM Virtual Machine + +For x86_64 vm: + Manufacturer: Red Hat + Product Name: KVM + +Fixing this issue by changing Manufacturer to 'Red Hat' and Product +Name to 'KVM' on aarch64 platform. Thus the output is aligned on both +x86_64 and aarch64 platform. + +To keep the compatability, this only apply for the RHEL9.6 machine +type. For RHEL9.4 machine type, it still keep the old Manufacturer and +Product Name. + +Signed-off-by: Shaoqin Huang +--- + hw/arm/virt.c | 14 ++++++++++++-- + include/hw/arm/virt.h | 1 + + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index bf05499a12..c50bff2a6c 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1711,14 +1711,21 @@ static void virt_build_smbios(VirtMachineState *vms) + uint8_t *smbios_tables, *smbios_anchor; + size_t smbios_tables_len, smbios_anchor_len; + struct smbios_phys_mem_area mem_array; ++ const char *manufacturer = "QEMU"; + const char *product = "QEMU Virtual Machine"; ++ const char *version = vmc->smbios_old_sys_ver ? "1.0" : mc->name; + + if (kvm_enabled()) { + product = "KVM Virtual Machine"; + } + +- smbios_set_defaults("QEMU", product, +- vmc->smbios_old_sys_ver ? "1.0" : mc->name, ++ if (!vmc->manufacturer_product_compat) { ++ manufacturer = "Red Hat"; ++ product = "KVM"; ++ version = mc->desc; ++ } ++ ++ smbios_set_defaults(manufacturer, product, version, + NULL, NULL); + + /* build the array of physical mem area from base_memmap */ +@@ -3587,10 +3594,13 @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0) + + static void virt_rhel_machine_9_4_0_options(MachineClass *mc) + { ++ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); ++ + virt_rhel_machine_9_6_0_options(mc); + + /* From virt_machine_9_0_options() */ + mc->smbios_memory_device_size = 16 * GiB; ++ vmc->manufacturer_product_compat = true; + + compat_props_add(mc->compat_props, hw_compat_rhel_9_6, hw_compat_rhel_9_6_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); +diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h +index a4d937ed45..2fc30a7626 100644 +--- a/include/hw/arm/virt.h ++++ b/include/hw/arm/virt.h +@@ -134,6 +134,7 @@ struct VirtMachineClass { + bool no_cpu_topology; + bool no_tcg_lpa2; + bool no_ns_el2_virt_timer_irq; ++ bool manufacturer_product_compat; + }; + + struct VirtMachineState { +-- +2.39.3 + diff --git a/SOURCES/kvm-HostMem-Add-mechanism-to-opt-in-kvm-guest-memfd-via-.patch b/SOURCES/kvm-HostMem-Add-mechanism-to-opt-in-kvm-guest-memfd-via-.patch deleted file mode 100644 index 65da2cc..0000000 --- a/SOURCES/kvm-HostMem-Add-mechanism-to-opt-in-kvm-guest-memfd-via-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 93ea86ac8849ad9ca365b1646313dde9a34ba59c Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 20 Mar 2024 03:39:03 -0500 -Subject: [PATCH 031/100] HostMem: Add mechanism to opt in kvm guest memfd via - MachineState - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [31/91] 43ce32aef954479cdb736301d1adcb919602c321 (bonzini/rhel-qemu-kvm) - -Add a new member "guest_memfd" to memory backends. When it's set -to true, it enables RAM_GUEST_MEMFD in ram_flags, thus private kvm -guest_memfd will be allocated during RAMBlock allocation. - -Memory backend's @guest_memfd is wired with @require_guest_memfd -field of MachineState. It avoid looking up the machine in phymem.c. - -MachineState::require_guest_memfd is supposed to be set by any VMs -that requires KVM guest memfd as private memory, e.g., TDX VM. - -Signed-off-by: Xiaoyao Li -Reviewed-by: David Hildenbrand -Message-ID: <20240320083945.991426-8-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 37662d85b0b7dded0ebdf6747bef6c3bb7ed6a0c) -Signed-off-by: Paolo Bonzini ---- - backends/hostmem-file.c | 1 + - backends/hostmem-memfd.c | 1 + - backends/hostmem-ram.c | 1 + - backends/hostmem.c | 1 + - hw/core/machine.c | 5 +++++ - include/hw/boards.h | 2 ++ - include/sysemu/hostmem.h | 1 + - 7 files changed, 12 insertions(+) - -diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c -index ac3e433cbd..3c69db7946 100644 ---- a/backends/hostmem-file.c -+++ b/backends/hostmem-file.c -@@ -85,6 +85,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) - ram_flags |= fb->readonly ? RAM_READONLY_FD : 0; - ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0; - ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; -+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0; - ram_flags |= fb->is_pmem ? RAM_PMEM : 0; - ram_flags |= RAM_NAMED_FILE; - return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name, -diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c -index 3923ea9364..745ead0034 100644 ---- a/backends/hostmem-memfd.c -+++ b/backends/hostmem-memfd.c -@@ -55,6 +55,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) - name = host_memory_backend_get_name(backend); - ram_flags = backend->share ? RAM_SHARED : 0; - ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; -+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0; - return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name, - backend->size, ram_flags, fd, 0, errp); - } -diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c -index d121249f0f..f7d81af783 100644 ---- a/backends/hostmem-ram.c -+++ b/backends/hostmem-ram.c -@@ -30,6 +30,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) - name = host_memory_backend_get_name(backend); - ram_flags = backend->share ? RAM_SHARED : 0; - ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; -+ ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0; - return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend), - name, backend->size, - ram_flags, errp); -diff --git a/backends/hostmem.c b/backends/hostmem.c -index 81a72ce40b..eb9682b4a8 100644 ---- a/backends/hostmem.c -+++ b/backends/hostmem.c -@@ -277,6 +277,7 @@ static void host_memory_backend_init(Object *obj) - /* TODO: convert access to globals to compat properties */ - backend->merge = machine_mem_merge(machine); - backend->dump = machine_dump_guest_core(machine); -+ backend->guest_memfd = machine_require_guest_memfd(machine); - backend->reserve = true; - backend->prealloc_threads = machine->smp.cpus; - } -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 92609aae27..07b994e136 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -1480,6 +1480,11 @@ bool machine_mem_merge(MachineState *machine) - return machine->mem_merge; - } - -+bool machine_require_guest_memfd(MachineState *machine) -+{ -+ return machine->require_guest_memfd; -+} -+ - static char *cpu_slot_to_string(const CPUArchId *cpu) - { - GString *s = g_string_new(NULL); -diff --git a/include/hw/boards.h b/include/hw/boards.h -index cca62f906b..815a1c4b26 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -36,6 +36,7 @@ bool machine_usb(MachineState *machine); - int machine_phandle_start(MachineState *machine); - bool machine_dump_guest_core(MachineState *machine); - bool machine_mem_merge(MachineState *machine); -+bool machine_require_guest_memfd(MachineState *machine); - HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine); - void machine_set_cpu_numa_node(MachineState *machine, - const CpuInstanceProperties *props, -@@ -372,6 +373,7 @@ struct MachineState { - char *dt_compatible; - bool dump_guest_core; - bool mem_merge; -+ bool require_guest_memfd; - bool usb; - bool usb_disabled; - char *firmware; -diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h -index 0e411aaa29..04b884bf42 100644 ---- a/include/sysemu/hostmem.h -+++ b/include/sysemu/hostmem.h -@@ -74,6 +74,7 @@ struct HostMemoryBackend { - uint64_t size; - bool merge, dump, use_canonical_path; - bool prealloc, is_mapped, share, reserve; -+ bool guest_memfd; - uint32_t prealloc_threads; - ThreadContext *prealloc_context; - DECLARE_BITMAP(host_nodes, MAX_NODES + 1); --- -2.39.3 - diff --git a/SOURCES/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch b/SOURCES/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch new file mode 100644 index 0000000..2670a23 --- /dev/null +++ b/SOURCES/kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch @@ -0,0 +1,49 @@ +From f9dfed0e5fd03ee6fa7364801db7d101bf085a79 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 17 Sep 2024 12:38:33 -0400 +Subject: [PATCH 6/9] KVM: Define KVM_MEMSLOTS_NUM_MAX_DEFAULT + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [5/7] c95bdaa406e76b943882fd75c4d345ca5fc397d4 (peterx/qemu-kvm) + +Make the default max nr_slots a macro, it's only used when KVM reports +nothing. + +Reviewed-by: David Hildenbrand +Signed-off-by: Peter Xu +Link: https://lore.kernel.org/r/20240917163835.194664-3-peterx@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b34a908c8f24eedb0a8e5ff486b059b58fd793f4) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 44bf4180fa..3900de8883 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -71,6 +71,8 @@ + + /* Default num of memslots to be allocated when VM starts */ + #define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16 ++/* Default max allowed memslots if kernel reported nothing */ ++#define KVM_MEMSLOTS_NR_MAX_DEFAULT 32 + + struct KVMParkedVcpu { + unsigned long vcpu_id; +@@ -2617,7 +2619,7 @@ static int kvm_init(MachineState *ms) + + /* If unspecified, use the default value */ + if (!s->nr_slots) { +- s->nr_slots = 32; ++ s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT; + } + + s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE); +-- +2.39.3 + diff --git a/SOURCES/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch b/SOURCES/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch new file mode 100644 index 0000000..f3f0522 --- /dev/null +++ b/SOURCES/kvm-KVM-Dynamic-sized-kvm-memslots-array.patch @@ -0,0 +1,250 @@ +From 9813dc1d19a6afedbab382b79e72691190e42fcf Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 17 Sep 2024 12:38:32 -0400 +Subject: [PATCH 5/9] KVM: Dynamic sized kvm memslots array + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [4/7] 04d74707873b28a50b1e1bc08e4788c79455518c (peterx/qemu-kvm) + +Zhiyi reported an infinite loop issue in VFIO use case. The cause of that +was a separate discussion, however during that I found a regression of +dirty sync slowness when profiling. + +Each KVMMemoryListerner maintains an array of kvm memslots. Currently it's +statically allocated to be the max supported by the kernel. However after +Linux commit 4fc096a99e ("KVM: Raise the maximum number of user memslots"), +the max supported memslots reported now grows to some number large enough +so that it may not be wise to always statically allocate with the max +reported. + +What's worse, QEMU kvm code still walks all the allocated memslots entries +to do any form of lookups. It can drastically slow down all memslot +operations because each of such loop can run over 32K times on the new +kernels. + +Fix this issue by making the memslots to be allocated dynamically. + +Here the initial size was set to 16 because it should cover the basic VM +usages, so that the hope is the majority VM use case may not even need to +grow at all (e.g. if one starts a VM with ./qemu-system-x86_64 by default +it'll consume 9 memslots), however not too large to waste memory. + +There can also be even better way to address this, but so far this is the +simplest and should be already better even than before we grow the max +supported memslots. For example, in the case of above issue when VFIO was +attached on a 32GB system, there are only ~10 memslots used. So it could +be good enough as of now. + +In the above VFIO context, measurement shows that the precopy dirty sync +shrinked from ~86ms to ~3ms after this patch applied. It should also apply +to any KVM enabled VM even without VFIO. + +NOTE: we don't have a FIXES tag for this patch because there's no real +commit that regressed this in QEMU. Such behavior existed for a long time, +but only start to be a problem when the kernel reports very large +nr_slots_max value. However that's pretty common now (the kernel change +was merged in 2021) so we attached cc:stable because we'll want this change +to be backported to stable branches. + +Cc: qemu-stable +Reported-by: Zhiyi Guo +Tested-by: Zhiyi Guo +Signed-off-by: Peter Xu +Acked-by: David Hildenbrand +Reviewed-by: Fabiano Rosas +Link: https://lore.kernel.org/r/20240917163835.194664-2-peterx@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 5504a8126115d173687b37e657312a8ffe29fc0c) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 87 +++++++++++++++++++++++++++++++++------- + accel/kvm/trace-events | 1 + + include/sysemu/kvm_int.h | 1 + + 3 files changed, 74 insertions(+), 15 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index de709fbc43..44bf4180fa 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -69,6 +69,9 @@ + #define KVM_GUESTDBG_BLOCKIRQ 0 + #endif + ++/* Default num of memslots to be allocated when VM starts */ ++#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16 ++ + struct KVMParkedVcpu { + unsigned long vcpu_id; + int kvm_fd; +@@ -165,6 +168,57 @@ void kvm_resample_fd_notify(int gsi) + } + } + ++/** ++ * kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener ++ * ++ * @kml: The KVMMemoryListener* to grow the slots[] array ++ * @nr_slots_new: The new size of slots[] array ++ * ++ * Returns: True if the array grows larger, false otherwise. ++ */ ++static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new) ++{ ++ unsigned int i, cur = kml->nr_slots_allocated; ++ KVMSlot *slots; ++ ++ if (nr_slots_new > kvm_state->nr_slots) { ++ nr_slots_new = kvm_state->nr_slots; ++ } ++ ++ if (cur >= nr_slots_new) { ++ /* Big enough, no need to grow, or we reached max */ ++ return false; ++ } ++ ++ if (cur == 0) { ++ slots = g_new0(KVMSlot, nr_slots_new); ++ } else { ++ assert(kml->slots); ++ slots = g_renew(KVMSlot, kml->slots, nr_slots_new); ++ /* ++ * g_renew() doesn't initialize extended buffers, however kvm ++ * memslots require fields to be zero-initialized. E.g. pointers, ++ * memory_size field, etc. ++ */ ++ memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur)); ++ } ++ ++ for (i = cur; i < nr_slots_new; i++) { ++ slots[i].slot = i; ++ } ++ ++ kml->slots = slots; ++ kml->nr_slots_allocated = nr_slots_new; ++ trace_kvm_slots_grow(cur, nr_slots_new); ++ ++ return true; ++} ++ ++static bool kvm_slots_double(KVMMemoryListener *kml) ++{ ++ return kvm_slots_grow(kml, kml->nr_slots_allocated * 2); ++} ++ + unsigned int kvm_get_max_memslots(void) + { + KVMState *s = KVM_STATE(current_accel()); +@@ -193,15 +247,26 @@ unsigned int kvm_get_free_memslots(void) + /* Called with KVMMemoryListener.slots_lock held */ + static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml) + { +- KVMState *s = kvm_state; ++ unsigned int n; + int i; + +- for (i = 0; i < s->nr_slots; i++) { ++ for (i = 0; i < kml->nr_slots_allocated; i++) { + if (kml->slots[i].memory_size == 0) { + return &kml->slots[i]; + } + } + ++ /* ++ * If no free slots, try to grow first by doubling. Cache the old size ++ * here to avoid another round of search: if the grow succeeded, it ++ * means slots[] now must have the existing "n" slots occupied, ++ * followed by one or more free slots starting from slots[n]. ++ */ ++ n = kml->nr_slots_allocated; ++ if (kvm_slots_double(kml)) { ++ return &kml->slots[n]; ++ } ++ + return NULL; + } + +@@ -222,10 +287,9 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml, + hwaddr start_addr, + hwaddr size) + { +- KVMState *s = kvm_state; + int i; + +- for (i = 0; i < s->nr_slots; i++) { ++ for (i = 0; i < kml->nr_slots_allocated; i++) { + KVMSlot *mem = &kml->slots[i]; + + if (start_addr == mem->start_addr && size == mem->memory_size) { +@@ -267,7 +331,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram, + int i, ret = 0; + + kvm_slots_lock(); +- for (i = 0; i < s->nr_slots; i++) { ++ for (i = 0; i < kml->nr_slots_allocated; i++) { + KVMSlot *mem = &kml->slots[i]; + + if (ram >= mem->ram && ram < mem->ram + mem->memory_size) { +@@ -1071,7 +1135,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml, + + kvm_slots_lock(); + +- for (i = 0; i < s->nr_slots; i++) { ++ for (i = 0; i < kml->nr_slots_allocated; i++) { + mem = &kml->slots[i]; + /* Discard slots that are empty or do not overlap the section */ + if (!mem->memory_size || +@@ -1719,12 +1783,8 @@ static void kvm_log_sync_global(MemoryListener *l, bool last_stage) + /* Flush all kernel dirty addresses into KVMSlot dirty bitmap */ + kvm_dirty_ring_flush(); + +- /* +- * TODO: make this faster when nr_slots is big while there are +- * only a few used slots (small VMs). +- */ + kvm_slots_lock(); +- for (i = 0; i < s->nr_slots; i++) { ++ for (i = 0; i < kml->nr_slots_allocated; i++) { + mem = &kml->slots[i]; + if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) { + kvm_slot_sync_dirty_pages(mem); +@@ -1839,12 +1899,9 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, + { + int i; + +- kml->slots = g_new0(KVMSlot, s->nr_slots); + kml->as_id = as_id; + +- for (i = 0; i < s->nr_slots; i++) { +- kml->slots[i].slot = i; +- } ++ kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT); + + QSIMPLEQ_INIT(&kml->transaction_add); + QSIMPLEQ_INIT(&kml->transaction_del); +diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events +index 37626c1ac5..ad2ae6fca5 100644 +--- a/accel/kvm/trace-events ++++ b/accel/kvm/trace-events +@@ -36,3 +36,4 @@ kvm_io_window_exit(void) "" + kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32 + kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s" + kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64 ++kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u" +diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h +index 1d8fb1473b..48e496b3d4 100644 +--- a/include/sysemu/kvm_int.h ++++ b/include/sysemu/kvm_int.h +@@ -46,6 +46,7 @@ typedef struct KVMMemoryListener { + MemoryListener listener; + KVMSlot *slots; + unsigned int nr_used_slots; ++ unsigned int nr_slots_allocated; + int as_id; + QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add; + QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del; +-- +2.39.3 + diff --git a/SOURCES/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch b/SOURCES/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch new file mode 100644 index 0000000..2998318 --- /dev/null +++ b/SOURCES/kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch @@ -0,0 +1,72 @@ +From 6c0a0d9734c507af2c84aa33eb1624f35e1f51fb Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 17 Sep 2024 12:38:34 -0400 +Subject: [PATCH 7/9] KVM: Rename KVMMemoryListener.nr_used_slots to + nr_slots_used + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [6/7] 74e9576751e0adeb8113a5e8e495b4b1285b0d76 (peterx/qemu-kvm) + +This will make all nr_slots counters to be named in the same manner. + +Reviewed-by: David Hildenbrand +Signed-off-by: Peter Xu +Link: https://lore.kernel.org/r/20240917163835.194664-4-peterx@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit dbdc00ba5b136bba80d850f61cc79a9cafaae1cd) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 6 +++--- + include/sysemu/kvm_int.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 3900de8883..e414d015c9 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -239,7 +239,7 @@ unsigned int kvm_get_free_memslots(void) + if (!s->as[i].ml) { + continue; + } +- used_slots = MAX(used_slots, s->as[i].ml->nr_used_slots); ++ used_slots = MAX(used_slots, s->as[i].ml->nr_slots_used); + } + kvm_slots_unlock(); + +@@ -1516,7 +1516,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, + } + start_addr += slot_size; + size -= slot_size; +- kml->nr_used_slots--; ++ kml->nr_slots_used--; + } while (size); + return; + } +@@ -1555,7 +1555,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, + ram_start_offset += slot_size; + ram += slot_size; + size -= slot_size; +- kml->nr_used_slots++; ++ kml->nr_slots_used++; + } while (size); + } + +diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h +index 48e496b3d4..b705dfc9b4 100644 +--- a/include/sysemu/kvm_int.h ++++ b/include/sysemu/kvm_int.h +@@ -45,7 +45,7 @@ typedef struct KVMMemoryUpdate { + typedef struct KVMMemoryListener { + MemoryListener listener; + KVMSlot *slots; +- unsigned int nr_used_slots; ++ unsigned int nr_slots_used; + unsigned int nr_slots_allocated; + int as_id; + QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add; +-- +2.39.3 + diff --git a/SOURCES/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch b/SOURCES/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch new file mode 100644 index 0000000..1787c16 --- /dev/null +++ b/SOURCES/kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch @@ -0,0 +1,89 @@ +From 5b731abd3a932fe9a21f83f3849a3b3769906e19 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Tue, 17 Sep 2024 12:38:35 -0400 +Subject: [PATCH 8/9] KVM: Rename KVMState->nr_slots to nr_slots_max + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [7/7] 43471483e7380119ba6415bff6d8ee6c69aa9cd7 (peterx/qemu-kvm) + +This value used to reflect the maximum supported memslots from KVM kernel. +Rename it to be clearer. + +Reviewed-by: David Hildenbrand +Signed-off-by: Peter Xu +Link: https://lore.kernel.org/r/20240917163835.194664-5-peterx@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 943c742868c739c0b14fd996bad3adf744156fec) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 12 ++++++------ + include/sysemu/kvm_int.h | 4 ++-- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index e414d015c9..49dedda47e 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -183,8 +183,8 @@ static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new) + unsigned int i, cur = kml->nr_slots_allocated; + KVMSlot *slots; + +- if (nr_slots_new > kvm_state->nr_slots) { +- nr_slots_new = kvm_state->nr_slots; ++ if (nr_slots_new > kvm_state->nr_slots_max) { ++ nr_slots_new = kvm_state->nr_slots_max; + } + + if (cur >= nr_slots_new) { +@@ -225,7 +225,7 @@ unsigned int kvm_get_max_memslots(void) + { + KVMState *s = KVM_STATE(current_accel()); + +- return s->nr_slots; ++ return s->nr_slots_max; + } + + unsigned int kvm_get_free_memslots(void) +@@ -243,7 +243,7 @@ unsigned int kvm_get_free_memslots(void) + } + kvm_slots_unlock(); + +- return s->nr_slots - used_slots; ++ return s->nr_slots_max - used_slots; + } + + /* Called with KVMMemoryListener.slots_lock held */ +@@ -2615,10 +2615,10 @@ static int kvm_init(MachineState *ms) + (kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE); + + kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT); +- s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); ++ s->nr_slots_max = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); + + /* If unspecified, use the default value */ +- if (!s->nr_slots) { ++ if (!s->nr_slots_max) { + s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT; + } + +diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h +index b705dfc9b4..2c57194b6b 100644 +--- a/include/sysemu/kvm_int.h ++++ b/include/sysemu/kvm_int.h +@@ -103,8 +103,8 @@ struct KVMDirtyRingReaper { + struct KVMState + { + AccelState parent_obj; +- +- int nr_slots; ++ /* Max number of KVM slots supported */ ++ int nr_slots_max; + int fd; + int vmfd; + int coalesced_mmio; +-- +2.39.3 + diff --git a/SOURCES/kvm-KVM-remove-kvm_arch_cpu_check_are_resettable.patch b/SOURCES/kvm-KVM-remove-kvm_arch_cpu_check_are_resettable.patch deleted file mode 100644 index aaedcf4..0000000 --- a/SOURCES/kvm-KVM-remove-kvm_arch_cpu_check_are_resettable.patch +++ /dev/null @@ -1,203 +0,0 @@ -From c46ac3db0a4db60e667edeabc9ed451c6e8e0ccf Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 18 Mar 2024 14:41:33 -0400 -Subject: [PATCH 020/100] KVM: remove kvm_arch_cpu_check_are_resettable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [20/91] d7745bd1a0ed1b215847f150f4a1bb2e912beabc (bonzini/rhel-qemu-kvm) - -Board reset requires writing a fresh CPU state. As far as KVM is -concerned, the only thing that blocks reset is that CPU state is -encrypted; therefore, kvm_cpus_are_resettable() can simply check -if that is the case. - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Paolo Bonzini -(cherry picked from commit a99c0c66ebe7d8db3af6f16689ade9375247e43e) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-accel-ops.c | 2 +- - accel/kvm/kvm-all.c | 5 ----- - include/sysemu/kvm.h | 10 ---------- - target/arm/kvm.c | 5 ----- - target/i386/kvm/kvm.c | 5 ----- - target/loongarch/kvm/kvm.c | 5 ----- - target/mips/kvm.c | 5 ----- - target/ppc/kvm.c | 5 ----- - target/riscv/kvm/kvm-cpu.c | 5 ----- - target/s390x/kvm/kvm.c | 5 ----- - 10 files changed, 1 insertion(+), 51 deletions(-) - -diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c -index b3c946dc4b..74e3c5785b 100644 ---- a/accel/kvm/kvm-accel-ops.c -+++ b/accel/kvm/kvm-accel-ops.c -@@ -82,7 +82,7 @@ static bool kvm_vcpu_thread_is_idle(CPUState *cpu) - - static bool kvm_cpus_are_resettable(void) - { -- return !kvm_enabled() || kvm_cpu_check_are_resettable(); -+ return !kvm_enabled() || !kvm_state->guest_state_protected; - } - - #ifdef KVM_CAP_SET_GUEST_DEBUG -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index ec0f6df7c5..b51e09a583 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2696,11 +2696,6 @@ void kvm_flush_coalesced_mmio_buffer(void) - s->coalesced_flush_in_progress = false; - } - --bool kvm_cpu_check_are_resettable(void) --{ -- return kvm_arch_cpu_check_are_resettable(); --} -- - static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) - { - if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) { -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 302e8f6f1e..54f4d83a37 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -525,16 +525,6 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target); - /* Notify resamplefd for EOI of specific interrupts. */ - void kvm_resample_fd_notify(int gsi); - --/** -- * kvm_cpu_check_are_resettable - return whether CPUs can be reset -- * -- * Returns: true: CPUs are resettable -- * false: CPUs are not resettable -- */ --bool kvm_cpu_check_are_resettable(void); -- --bool kvm_arch_cpu_check_are_resettable(void); -- - bool kvm_dirty_ring_enabled(void); - - uint32_t kvm_dirty_ring_size(void); -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index ab85d628a8..21ebbf3b8f 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -1598,11 +1598,6 @@ int kvm_arch_msi_data_to_gsi(uint32_t data) - return (data - 32) & 0xffff; - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - static void kvm_arch_get_eager_split_size(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e271652620..a12207a8ee 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5623,11 +5623,6 @@ bool kvm_has_waitpkg(void) - return has_msr_umwait; - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return !sev_es_enabled(); --} -- - #define ARCH_REQ_XCOMP_GUEST_PERM 0x1025 - - void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index d630cc39cb..8224d94333 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -733,11 +733,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) - return true; - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - { - int ret = 0; -diff --git a/target/mips/kvm.c b/target/mips/kvm.c -index 6c52e59f55..a631ab544f 100644 ---- a/target/mips/kvm.c -+++ b/target/mips/kvm.c -@@ -1273,11 +1273,6 @@ int kvm_arch_get_default_type(MachineState *machine) - return -1; - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - void kvm_arch_accel_class_init(ObjectClass *oc) - { - } -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index 59f640cf7b..9d9d9f0d79 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -2968,11 +2968,6 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset) - } - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - void kvm_arch_accel_class_init(ObjectClass *oc) - { - } -diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c -index 6a6c6cae80..49d2f3ad58 100644 ---- a/target/riscv/kvm/kvm-cpu.c -+++ b/target/riscv/kvm/kvm-cpu.c -@@ -1475,11 +1475,6 @@ void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level) - } - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - static int aia_mode; - - static const char *kvm_aia_mode_str(uint64_t mode) -diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 55fb4855b1..4db59658e1 100644 ---- a/target/s390x/kvm/kvm.c -+++ b/target/s390x/kvm/kvm.c -@@ -2630,11 +2630,6 @@ void kvm_s390_stop_interrupt(S390CPU *cpu) - kvm_s390_vcpu_interrupt(cpu, &irq); - } - --bool kvm_arch_cpu_check_are_resettable(void) --{ -- return true; --} -- - int kvm_s390_get_zpci_op(void) - { - return cap_zpci_op; --- -2.39.3 - diff --git a/SOURCES/kvm-KVM-track-whether-guest-state-is-encrypted.patch b/SOURCES/kvm-KVM-track-whether-guest-state-is-encrypted.patch deleted file mode 100644 index 7cdab60..0000000 --- a/SOURCES/kvm-KVM-track-whether-guest-state-is-encrypted.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 50399796da938c4ea7c69058fde84695bce9d794 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 18 Mar 2024 14:41:10 -0400 -Subject: [PATCH 019/100] KVM: track whether guest state is encrypted -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [19/91] 685b9c54d43d0043d15c33d13afc3a420cbe139b (bonzini/rhel-qemu-kvm) - -So far, KVM has allowed KVM_GET/SET_* ioctls to execute even if the -guest state is encrypted, in which case they do nothing. For the new -API using VM types, instead, the ioctls will fail which is a safer and -more robust approach. - -The new API will be the only one available for SEV-SNP and TDX, but it -is also usable for SEV and SEV-ES. In preparation for that, require -architecture-specific KVM code to communicate the point at which guest -state is protected (which must be after kvm_cpu_synchronize_post_init(), -though that might change in the future in order to suppor migration). -From that point, skip reading registers so that cpu->vcpu_dirty is -never true: if it ever becomes true, kvm_arch_put_registers() will -fail miserably. - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Paolo Bonzini -(cherry picked from commit 5c3131c392f84c660033d511ec39872d8beb4b1e) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 17 ++++++++++++++--- - include/sysemu/kvm.h | 2 ++ - include/sysemu/kvm_int.h | 1 + - target/i386/sev.c | 1 + - 4 files changed, 18 insertions(+), 3 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 931f74256e..ec0f6df7c5 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2703,7 +2703,7 @@ bool kvm_cpu_check_are_resettable(void) - - static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) - { -- if (!cpu->vcpu_dirty) { -+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) { - int ret = kvm_arch_get_registers(cpu); - if (ret) { - error_report("Failed to get registers: %s", strerror(-ret)); -@@ -2717,7 +2717,7 @@ static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) - - void kvm_cpu_synchronize_state(CPUState *cpu) - { -- if (!cpu->vcpu_dirty) { -+ if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) { - run_on_cpu(cpu, do_kvm_cpu_synchronize_state, RUN_ON_CPU_NULL); - } - } -@@ -2752,7 +2752,13 @@ static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) - - void kvm_cpu_synchronize_post_init(CPUState *cpu) - { -- run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL); -+ if (!kvm_state->guest_state_protected) { -+ /* -+ * This runs before the machine_init_done notifiers, and is the last -+ * opportunity to synchronize the state of confidential guests. -+ */ -+ run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL); -+ } - } - - static void do_kvm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg) -@@ -4099,3 +4105,8 @@ void query_stats_schemas_cb(StatsSchemaList **result, Error **errp) - query_stats_schema_vcpu(first_cpu, &stats_args); - } - } -+ -+void kvm_mark_guest_state_protected(void) -+{ -+ kvm_state->guest_state_protected = true; -+} -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index fad9a7e8ff..302e8f6f1e 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -539,6 +539,8 @@ bool kvm_dirty_ring_enabled(void); - - uint32_t kvm_dirty_ring_size(void); - -+void kvm_mark_guest_state_protected(void); -+ - /** - * kvm_hwpoisoned_mem - indicate if there is any hwpoisoned page - * reported for the VM. -diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h -index 882e37e12c..3496be7997 100644 ---- a/include/sysemu/kvm_int.h -+++ b/include/sysemu/kvm_int.h -@@ -87,6 +87,7 @@ struct KVMState - bool kernel_irqchip_required; - OnOffAuto kernel_irqchip_split; - bool sync_mmu; -+ bool guest_state_protected; - uint64_t manual_dirty_log_protect; - /* The man page (and posix) say ioctl numbers are signed int, but - * they're not. Linux, glibc and *BSD all treat ioctl numbers as -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b8f79d34d1..c49a8fd55e 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -755,6 +755,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - if (ret) { - exit(1); - } -+ kvm_mark_guest_state_protected(); - } - - /* query the measurement blob length */ --- -2.39.3 - diff --git a/SOURCES/kvm-RAMBlock-Add-support-of-KVM-private-guest-memfd.patch b/SOURCES/kvm-RAMBlock-Add-support-of-KVM-private-guest-memfd.patch deleted file mode 100644 index 8e47872..0000000 --- a/SOURCES/kvm-RAMBlock-Add-support-of-KVM-private-guest-memfd.patch +++ /dev/null @@ -1,329 +0,0 @@ -From f4b01d645926faab2cab86fadb7398c26d6b8285 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 20 Mar 2024 03:39:02 -0500 -Subject: [PATCH 028/100] RAMBlock: Add support of KVM private guest memfd - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [28/91] 95fdf196afcb67113834c20fa354ee1397411bfd (bonzini/rhel-qemu-kvm) - -Add KVM guest_memfd support to RAMBlock so both normal hva based memory -and kvm guest memfd based private memory can be associated in one RAMBlock. - -Introduce new flag RAM_GUEST_MEMFD. When it's set, it calls KVM ioctl to -create private guest_memfd during RAMBlock setup. - -Allocating a new RAM_GUEST_MEMFD flag to instruct the setup of guest memfd -is more flexible and extensible than simply relying on the VM type because -in the future we may have the case that not all the memory of a VM need -guest memfd. As a benefit, it also avoid getting MachineState in memory -subsystem. - -Note, RAM_GUEST_MEMFD is supposed to be set for memory backends of -confidential guests, such as TDX VM. How and when to set it for memory -backends will be implemented in the following patches. - -Introduce memory_region_has_guest_memfd() to query if the MemoryRegion has -KVM guest_memfd allocated. - -Signed-off-by: Xiaoyao Li -Reviewed-by: David Hildenbrand -Message-ID: <20240320083945.991426-7-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 15f7a80c49cb3637f62fa37fa4a17da913bd91ff) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 28 ++++++++++++++++++++++++++++ - accel/stubs/kvm-stub.c | 5 +++++ - include/exec/memory.h | 20 +++++++++++++++++--- - include/exec/ram_addr.h | 2 +- - include/exec/ramblock.h | 1 + - include/sysemu/kvm.h | 2 ++ - system/memory.c | 5 +++++ - system/physmem.c | 34 +++++++++++++++++++++++++++++++--- - 8 files changed, 90 insertions(+), 7 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 272e945f52..a7b9a127dd 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -92,6 +92,7 @@ static bool kvm_has_guest_debug; - static int kvm_sstep_flags; - static bool kvm_immediate_exit; - static uint64_t kvm_supported_memory_attributes; -+static bool kvm_guest_memfd_supported; - static hwaddr kvm_max_slot_size = ~0; - - static const KVMCapabilityInfo kvm_required_capabilites[] = { -@@ -2419,6 +2420,11 @@ static int kvm_init(MachineState *ms) - } - - kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES); -+ kvm_guest_memfd_supported = -+ kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) && -+ kvm_check_extension(s, KVM_CAP_USER_MEMORY2) && -+ (kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE); -+ - kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT); - s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); - -@@ -4138,3 +4144,25 @@ void kvm_mark_guest_state_protected(void) - { - kvm_state->guest_state_protected = true; - } -+ -+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp) -+{ -+ int fd; -+ struct kvm_create_guest_memfd guest_memfd = { -+ .size = size, -+ .flags = flags, -+ }; -+ -+ if (!kvm_guest_memfd_supported) { -+ error_setg(errp, "KVM does not support guest_memfd"); -+ return -1; -+ } -+ -+ fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_GUEST_MEMFD, &guest_memfd); -+ if (fd < 0) { -+ error_setg_errno(errp, errno, "Error creating KVM guest_memfd"); -+ return -1; -+ } -+ -+ return fd; -+} -diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c -index ca38172884..8e0eb22e61 100644 ---- a/accel/stubs/kvm-stub.c -+++ b/accel/stubs/kvm-stub.c -@@ -129,3 +129,8 @@ bool kvm_hwpoisoned_mem(void) - { - return false; - } -+ -+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp) -+{ -+ return -ENOSYS; -+} -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 8626a355b3..679a847685 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -243,6 +243,9 @@ typedef struct IOMMUTLBEvent { - /* RAM FD is opened read-only */ - #define RAM_READONLY_FD (1 << 11) - -+/* RAM can be private that has kvm guest memfd backend */ -+#define RAM_GUEST_MEMFD (1 << 12) -+ - static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn, - IOMMUNotifierFlag flags, - hwaddr start, hwaddr end, -@@ -1307,7 +1310,8 @@ bool memory_region_init_ram_nomigrate(MemoryRegion *mr, - * @name: Region name, becomes part of RAMBlock name used in migration stream - * must be unique within any device - * @size: size of the region. -- * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE. -+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE, -+ * RAM_GUEST_MEMFD. - * @errp: pointer to Error*, to store an error if it happens. - * - * Note that this function does not do anything to cause the data in the -@@ -1369,7 +1373,7 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr, - * (getpagesize()) will be used. - * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM, - * RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY, -- * RAM_READONLY_FD -+ * RAM_READONLY_FD, RAM_GUEST_MEMFD - * @path: the path in which to allocate the RAM. - * @offset: offset within the file referenced by path - * @errp: pointer to Error*, to store an error if it happens. -@@ -1399,7 +1403,7 @@ bool memory_region_init_ram_from_file(MemoryRegion *mr, - * @size: size of the region. - * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM, - * RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY, -- * RAM_READONLY_FD -+ * RAM_READONLY_FD, RAM_GUEST_MEMFD - * @fd: the fd to mmap. - * @offset: offset within the file referenced by fd - * @errp: pointer to Error*, to store an error if it happens. -@@ -1722,6 +1726,16 @@ static inline bool memory_region_is_romd(MemoryRegion *mr) - */ - bool memory_region_is_protected(MemoryRegion *mr); - -+/** -+ * memory_region_has_guest_memfd: check whether a memory region has guest_memfd -+ * associated -+ * -+ * Returns %true if a memory region's ram_block has valid guest_memfd assigned. -+ * -+ * @mr: the memory region being queried -+ */ -+bool memory_region_has_guest_memfd(MemoryRegion *mr); -+ - /** - * memory_region_get_iommu: check whether a memory region is an iommu - * -diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h -index de45ba7bc9..07c8f86375 100644 ---- a/include/exec/ram_addr.h -+++ b/include/exec/ram_addr.h -@@ -110,7 +110,7 @@ long qemu_maxrampagesize(void); - * @mr: the memory region where the ram block is - * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM, - * RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY, -- * RAM_READONLY_FD -+ * RAM_READONLY_FD, RAM_GUEST_MEMFD - * @mem_path or @fd: specify the backing file or device - * @offset: Offset into target file - * @errp: pointer to Error*, to store an error if it happens -diff --git a/include/exec/ramblock.h b/include/exec/ramblock.h -index 848915ea5b..459c8917de 100644 ---- a/include/exec/ramblock.h -+++ b/include/exec/ramblock.h -@@ -41,6 +41,7 @@ struct RAMBlock { - QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers; - int fd; - uint64_t fd_offset; -+ int guest_memfd; - size_t page_size; - /* dirty bitmap used during migration */ - unsigned long *bmap; -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index f114ff6986..9e4ab7ae89 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -537,6 +537,8 @@ void kvm_mark_guest_state_protected(void); - */ - bool kvm_hwpoisoned_mem(void); - -+int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp); -+ - int kvm_set_memory_attributes_private(hwaddr start, uint64_t size); - int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size); - -diff --git a/system/memory.c b/system/memory.c -index a229a79988..c756950c0c 100644 ---- a/system/memory.c -+++ b/system/memory.c -@@ -1850,6 +1850,11 @@ bool memory_region_is_protected(MemoryRegion *mr) - return mr->ram && (mr->ram_block->flags & RAM_PROTECTED); - } - -+bool memory_region_has_guest_memfd(MemoryRegion *mr) -+{ -+ return mr->ram_block && mr->ram_block->guest_memfd >= 0; -+} -+ - uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr) - { - uint8_t mask = mr->dirty_log_mask; -diff --git a/system/physmem.c b/system/physmem.c -index a4fe3d2bf8..f5dfa20e57 100644 ---- a/system/physmem.c -+++ b/system/physmem.c -@@ -1808,6 +1808,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) - const bool shared = qemu_ram_is_shared(new_block); - RAMBlock *block; - RAMBlock *last_block = NULL; -+ bool free_on_error = false; - ram_addr_t old_ram_size, new_ram_size; - Error *err = NULL; - -@@ -1837,6 +1838,19 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) - return; - } - memory_try_enable_merging(new_block->host, new_block->max_length); -+ free_on_error = true; -+ } -+ } -+ -+ if (new_block->flags & RAM_GUEST_MEMFD) { -+ assert(kvm_enabled()); -+ assert(new_block->guest_memfd < 0); -+ -+ new_block->guest_memfd = kvm_create_guest_memfd(new_block->max_length, -+ 0, errp); -+ if (new_block->guest_memfd < 0) { -+ qemu_mutex_unlock_ramlist(); -+ goto out_free; - } - } - -@@ -1888,6 +1902,13 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) - ram_block_notify_add(new_block->host, new_block->used_length, - new_block->max_length); - } -+ return; -+ -+out_free: -+ if (free_on_error) { -+ qemu_anon_ram_free(new_block->host, new_block->max_length); -+ new_block->host = NULL; -+ } - } - - #ifdef CONFIG_POSIX -@@ -1902,7 +1923,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, - /* Just support these ram flags by now. */ - assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_NORESERVE | - RAM_PROTECTED | RAM_NAMED_FILE | RAM_READONLY | -- RAM_READONLY_FD)) == 0); -+ RAM_READONLY_FD | RAM_GUEST_MEMFD)) == 0); - - if (xen_enabled()) { - error_setg(errp, "-mem-path not supported with Xen"); -@@ -1939,6 +1960,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, - new_block->used_length = size; - new_block->max_length = size; - new_block->flags = ram_flags; -+ new_block->guest_memfd = -1; - new_block->host = file_ram_alloc(new_block, size, fd, !file_size, offset, - errp); - if (!new_block->host) { -@@ -2018,7 +2040,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, - int align; - - assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC | -- RAM_NORESERVE)) == 0); -+ RAM_NORESERVE | RAM_GUEST_MEMFD)) == 0); - assert(!host ^ (ram_flags & RAM_PREALLOC)); - - align = qemu_real_host_page_size(); -@@ -2033,6 +2055,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size, - new_block->max_length = max_size; - assert(max_size >= size); - new_block->fd = -1; -+ new_block->guest_memfd = -1; - new_block->page_size = qemu_real_host_page_size(); - new_block->host = host; - new_block->flags = ram_flags; -@@ -2055,7 +2078,7 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, - RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags, - MemoryRegion *mr, Error **errp) - { -- assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE)) == 0); -+ assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE | RAM_GUEST_MEMFD)) == 0); - return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, errp); - } - -@@ -2083,6 +2106,11 @@ static void reclaim_ramblock(RAMBlock *block) - } else { - qemu_anon_ram_free(block->host, block->max_length); - } -+ -+ if (block->guest_memfd >= 0) { -+ close(block->guest_memfd); -+ } -+ - g_free(block); - } - --- -2.39.3 - diff --git a/SOURCES/kvm-RAMBlock-make-guest_memfd-require-uncoordinated-disc.patch b/SOURCES/kvm-RAMBlock-make-guest_memfd-require-uncoordinated-disc.patch deleted file mode 100644 index 04a5fbf..0000000 --- a/SOURCES/kvm-RAMBlock-make-guest_memfd-require-uncoordinated-disc.patch +++ /dev/null @@ -1,82 +0,0 @@ -From bd289293604d6f33e9fb89196f0b19117ce81f89 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Wed, 20 Mar 2024 17:45:29 +0100 -Subject: [PATCH 032/100] RAMBlock: make guest_memfd require uncoordinated - discard - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [32/91] 0c005849026c334737b88cbd20a0ac237dfca37e (bonzini/rhel-qemu-kvm) - -Some subsystems like VFIO might disable ram block discard, but guest_memfd -uses discard operations to implement conversions between private and -shared memory. Because of this, sequences like the following can result -in stale IOMMU mappings: - -1. allocate shared page -2. convert page shared->private -3. discard shared page -4. convert page private->shared -5. allocate shared page -6. issue DMA operations against that shared page - -This is not a use-after-free, because after step 3 VFIO is still pinning -the page. However, DMA operations in step 6 will hit the old mapping -that was allocated in step 1. - -Address this by taking ram_block_discard_is_enabled() into account when -deciding whether or not to discard pages. - -Since kvm_convert_memory()/guest_memfd doesn't implement a -RamDiscardManager handler to convey and replay discard operations, -this is a case of uncoordinated discard, which is blocked/released -by ram_block_discard_require(). Interestingly, this function had -no use so far. - -Alternative approaches would be to block discard of shared pages, but -this would cause guests to consume twice the memory if they use VFIO; -or to implement a RamDiscardManager and only block uncoordinated -discard, i.e. use ram_block_coordinated_discard_require(). - -[Commit message mostly by Michael Roth ] - -Signed-off-by: Paolo Bonzini -(cherry picked from commit 852f0048f3ea9f14de18eb279a99fccb6d250e8f) -Signed-off-by: Paolo Bonzini ---- - system/physmem.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/system/physmem.c b/system/physmem.c -index f5dfa20e57..5ebcf5be11 100644 ---- a/system/physmem.c -+++ b/system/physmem.c -@@ -1846,6 +1846,13 @@ static void ram_block_add(RAMBlock *new_block, Error **errp) - assert(kvm_enabled()); - assert(new_block->guest_memfd < 0); - -+ if (ram_block_discard_require(true) < 0) { -+ error_setg_errno(errp, errno, -+ "cannot set up private guest memory: discard currently blocked"); -+ error_append_hint(errp, "Are you using assigned devices?\n"); -+ goto out_free; -+ } -+ - new_block->guest_memfd = kvm_create_guest_memfd(new_block->max_length, - 0, errp); - if (new_block->guest_memfd < 0) { -@@ -2109,6 +2116,7 @@ static void reclaim_ramblock(RAMBlock *block) - - if (block->guest_memfd >= 0) { - close(block->guest_memfd); -+ ram_block_discard_require(false); - } - - g_free(block); --- -2.39.3 - diff --git a/SOURCES/kvm-Revert-monitor-use-aio_co_reschedule_self.patch b/SOURCES/kvm-Revert-monitor-use-aio_co_reschedule_self.patch deleted file mode 100644 index 32e792e..0000000 --- a/SOURCES/kvm-Revert-monitor-use-aio_co_reschedule_self.patch +++ /dev/null @@ -1,67 +0,0 @@ -From d4e6f7105b00ba2536d5d733b7c03116f28ce116 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 6 May 2024 15:06:21 -0400 -Subject: [PATCH 2/5] Revert "monitor: use aio_co_reschedule_self()" - -RH-Author: Kevin Wolf -RH-MergeRequest: 248: Revert "monitor: use aio_co_reschedule_self()" -RH-Jira: RHEL-34618 RHEL-38697 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/2] b6a2ebd4a69dbcd2bd56c61e7c747f8f8f42337e (kmwolf/centos-qemu-kvm) - -Commit 1f25c172f837 ("monitor: use aio_co_reschedule_self()") was a code -cleanup that uses aio_co_reschedule_self() instead of open coding -coroutine rescheduling. - -Bug RHEL-34618 was reported and Kevin Wolf identified -the root cause. I missed that aio_co_reschedule_self() -> -qemu_get_current_aio_context() only knows about -qemu_aio_context/IOThread AioContexts and not about iohandler_ctx. It -does not function correctly when going back from the iohandler_ctx to -qemu_aio_context. - -Go back to open coding the AioContext transitions to avoid this bug. - -This reverts commit 1f25c172f83704e350c0829438d832384084a74d. - -Cc: qemu-stable@nongnu.org -Buglink: https://issues.redhat.com/browse/RHEL-34618 -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240506190622.56095-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 719c6819ed9a9838520fa732f9861918dc693bda) -Signed-off-by: Kevin Wolf ---- - qapi/qmp-dispatch.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c -index f3488afeef..176b549473 100644 ---- a/qapi/qmp-dispatch.c -+++ b/qapi/qmp-dispatch.c -@@ -212,7 +212,8 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ - * executing the command handler so that it can make progress if it - * involves an AIO_WAIT_WHILE(). - */ -- aio_co_reschedule_self(qemu_get_aio_context()); -+ aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self()); -+ qemu_coroutine_yield(); - } - - monitor_set_cur(qemu_coroutine_self(), cur_mon); -@@ -226,7 +227,9 @@ QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *requ - * Move back to iohandler_ctx so that nested event loops for - * qemu_aio_context don't start new monitor commands. - */ -- aio_co_reschedule_self(iohandler_get_aio_context()); -+ aio_co_schedule(iohandler_get_aio_context(), -+ qemu_coroutine_self()); -+ qemu_coroutine_yield(); - } - } else { - /* --- -2.39.3 - diff --git a/SOURCES/kvm-Revert-x86-rhel-9.4.0-machine-type-compat-fix.patch b/SOURCES/kvm-Revert-x86-rhel-9.4.0-machine-type-compat-fix.patch deleted file mode 100644 index 96756df..0000000 --- a/SOURCES/kvm-Revert-x86-rhel-9.4.0-machine-type-compat-fix.patch +++ /dev/null @@ -1,38 +0,0 @@ -From bcbc897cb19b3a6523de611f48f6bac6cea16c97 Mon Sep 17 00:00:00 2001 -From: Sebastian Ott -Date: Thu, 2 May 2024 13:17:03 +0200 -Subject: [PATCH 2/2] Revert "x86: rhel 9.4.0 machine type compat fix" - -RH-Author: Sebastian Ott -RH-MergeRequest: 237: Revert "x86: rhel 9.4.0 machine type compat fix" -RH-Jira: RHEL-30362 -RH-Acked-by: Ani Sinha -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] 858ec153e65e96c39ca4db17ed93fd58c77dc2eb (seott1/cos-qemu-kvm) - -This reverts commit c46e44f0f4e861fe412ce679b0b0204881c1c2f5. - -pc-q35-rhel9.4.0 and newer should stay with SMBIOS_ENTRY_POINT_TYPE_AUTO. - -Signed-off-by: Sebastian Ott ---- - hw/i386/pc_q35.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 2f11f9af7d..2b54944c0f 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -734,9 +734,6 @@ static void pc_q35_machine_rhel940_options(MachineClass *m) - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.4.0"; - -- /* From pc_q35_8_2_machine_options() - use SMBIOS 3.X by default */ -- pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_64; -- - compat_props_add(m->compat_props, hw_compat_rhel_9_5, - hw_compat_rhel_9_5_len); - } --- -2.39.3 - diff --git a/SOURCES/kvm-accel-kvm-refactor-dirty-ring-setup.patch b/SOURCES/kvm-accel-kvm-refactor-dirty-ring-setup.patch new file mode 100644 index 0000000..ec064f5 --- /dev/null +++ b/SOURCES/kvm-accel-kvm-refactor-dirty-ring-setup.patch @@ -0,0 +1,143 @@ +From e27a9d1e5194243084efe4405fe50463442f0fe3 Mon Sep 17 00:00:00 2001 +From: Ani Sinha +Date: Thu, 12 Sep 2024 11:48:38 +0530 +Subject: [PATCH 4/9] accel/kvm: refactor dirty ring setup + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [3/7] 226ae9826237887fc55f75b9175524f12b4fa4a9 (peterx/qemu-kvm) + +Refactor setting up of dirty ring code in kvm_init() so that is can be +reused in the future patchsets. + +Signed-off-by: Ani Sinha +Link: https://lore.kernel.org/r/20240912061838.4501-1-anisinha@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 28ed7f9761eb273e7dedcfdc0507d158106d0451) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 88 +++++++++++++++++++++++++-------------------- + 1 file changed, 50 insertions(+), 38 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 4f96d8b45e..de709fbc43 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2439,6 +2439,55 @@ static int find_kvm_machine_type(MachineState *ms) + return type; + } + ++static int kvm_setup_dirty_ring(KVMState *s) ++{ ++ uint64_t dirty_log_manual_caps; ++ int ret; ++ ++ /* ++ * Enable KVM dirty ring if supported, otherwise fall back to ++ * dirty logging mode ++ */ ++ ret = kvm_dirty_ring_init(s); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* ++ * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is ++ * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no ++ * page is wr-protected initially, which is against how kvm dirty ring is ++ * usage - kvm dirty ring requires all pages are wr-protected at the very ++ * beginning. Enabling this feature for dirty ring causes data corruption. ++ * ++ * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log, ++ * we may expect a higher stall time when starting the migration. In the ++ * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too: ++ * instead of clearing dirty bit, it can be a way to explicitly wr-protect ++ * guest pages. ++ */ ++ if (!s->kvm_dirty_ring_size) { ++ dirty_log_manual_caps = ++ kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2); ++ dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | ++ KVM_DIRTY_LOG_INITIALLY_SET); ++ s->manual_dirty_log_protect = dirty_log_manual_caps; ++ if (dirty_log_manual_caps) { ++ ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, ++ dirty_log_manual_caps); ++ if (ret) { ++ warn_report("Trying to enable capability %"PRIu64" of " ++ "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. " ++ "Falling back to the legacy mode. ", ++ dirty_log_manual_caps); ++ s->manual_dirty_log_protect = 0; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + static int kvm_init(MachineState *ms) + { + MachineClass *mc = MACHINE_GET_CLASS(ms); +@@ -2458,7 +2507,6 @@ static int kvm_init(MachineState *ms) + const KVMCapabilityInfo *missing_cap; + int ret; + int type; +- uint64_t dirty_log_manual_caps; + + qemu_mutex_init(&kml_slots_lock); + +@@ -2570,47 +2618,11 @@ static int kvm_init(MachineState *ms) + s->coalesced_pio = s->coalesced_mmio && + kvm_check_extension(s, KVM_CAP_COALESCED_PIO); + +- /* +- * Enable KVM dirty ring if supported, otherwise fall back to +- * dirty logging mode +- */ +- ret = kvm_dirty_ring_init(s); ++ ret = kvm_setup_dirty_ring(s); + if (ret < 0) { + goto err; + } + +- /* +- * KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is +- * enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no +- * page is wr-protected initially, which is against how kvm dirty ring is +- * usage - kvm dirty ring requires all pages are wr-protected at the very +- * beginning. Enabling this feature for dirty ring causes data corruption. +- * +- * TODO: Without KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 and kvm clear dirty log, +- * we may expect a higher stall time when starting the migration. In the +- * future we can enable KVM_CLEAR_DIRTY_LOG to work with dirty ring too: +- * instead of clearing dirty bit, it can be a way to explicitly wr-protect +- * guest pages. +- */ +- if (!s->kvm_dirty_ring_size) { +- dirty_log_manual_caps = +- kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2); +- dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | +- KVM_DIRTY_LOG_INITIALLY_SET); +- s->manual_dirty_log_protect = dirty_log_manual_caps; +- if (dirty_log_manual_caps) { +- ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, +- dirty_log_manual_caps); +- if (ret) { +- warn_report("Trying to enable capability %"PRIu64" of " +- "KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. " +- "Falling back to the legacy mode. ", +- dirty_log_manual_caps); +- s->manual_dirty_log_protect = 0; +- } +- } +- } +- + #ifdef KVM_CAP_VCPU_EVENTS + s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS); + #endif +-- +2.39.3 + diff --git a/SOURCES/kvm-aio-warn-about-iohandler_ctx-special-casing.patch b/SOURCES/kvm-aio-warn-about-iohandler_ctx-special-casing.patch deleted file mode 100644 index a0d9d31..0000000 --- a/SOURCES/kvm-aio-warn-about-iohandler_ctx-special-casing.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0e3934e89ad1dda21681f64ff38da69b07d1b531 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 6 May 2024 15:06:22 -0400 -Subject: [PATCH 3/5] aio: warn about iohandler_ctx special casing - -RH-Author: Kevin Wolf -RH-MergeRequest: 248: Revert "monitor: use aio_co_reschedule_self()" -RH-Jira: RHEL-34618 RHEL-38697 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/2] cc316d70b2c187ee0412d6560ca1a03e381a69c1 (kmwolf/centos-qemu-kvm) - -The main loop has two AioContexts: qemu_aio_context and iohandler_ctx. -The main loop runs them both, but nested aio_poll() calls on -qemu_aio_context exclude iohandler_ctx. - -Which one should qemu_get_current_aio_context() return when called from -the main loop? Document that it's always qemu_aio_context. - -This has subtle effects on functions that use -qemu_get_current_aio_context(). For example, aio_co_reschedule_self() -does not work when moving from iohandler_ctx to qemu_aio_context because -qemu_get_current_aio_context() does not differentiate these two -AioContexts. - -Document this in order to reduce the chance of future bugs. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240506190622.56095-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit e669e800fc9ef8806af5c5578249ab758a4f8a5a) -Signed-off-by: Kevin Wolf ---- - include/block/aio.h | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/include/block/aio.h b/include/block/aio.h -index 8378553eb9..4ee81936ed 100644 ---- a/include/block/aio.h -+++ b/include/block/aio.h -@@ -629,6 +629,9 @@ void aio_co_schedule(AioContext *ctx, Coroutine *co); - * - * Move the currently running coroutine to new_ctx. If the coroutine is already - * running in new_ctx, do nothing. -+ * -+ * Note that this function cannot reschedule from iohandler_ctx to -+ * qemu_aio_context. - */ - void coroutine_fn aio_co_reschedule_self(AioContext *new_ctx); - -@@ -661,6 +664,9 @@ void aio_co_enter(AioContext *ctx, Coroutine *co); - * If called from an IOThread this will be the IOThread's AioContext. If - * called from the main thread or with the "big QEMU lock" taken it - * will be the main loop AioContext. -+ * -+ * Note that the return value is never the main loop's iohandler_ctx and the -+ * return value is the main loop AioContext instead. - */ - AioContext *qemu_get_current_aio_context(void); - --- -2.39.3 - diff --git a/SOURCES/kvm-arm-disable-pauth-for-virt-rhel9.patch b/SOURCES/kvm-arm-disable-pauth-for-virt-rhel9.patch new file mode 100644 index 0000000..dd121ff --- /dev/null +++ b/SOURCES/kvm-arm-disable-pauth-for-virt-rhel9.patch @@ -0,0 +1,60 @@ +From 664e672182e39516f26e5f6b10784e42c9dd9864 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Wed, 22 Jan 2025 06:01:21 -0500 +Subject: [PATCH 10/11] arm: disable pauth for virt-rhel9* + +RH-Author: Sebastian Ott +RH-MergeRequest: 330: arm: disable pauth for virt-rhel9* +RH-Jira: RHEL-75782 +RH-Acked-by: Eric Auger +RH-Acked-by: Kashyap Chamarthy +RH-Acked-by: Gavin Shan +RH-Commit: [1/2] 6b30d9a755f06d6823b8a874babf12a1b5fc3295 (seott1/cos-qemu-kvm) + +RHEL9 kernels have pauth disabled while RHEL10 has it enabled, +since qemu will setup the VM/VCPU with pauth when KVM supports it +the guest visible ID registers will change when a RHEL9 qemu is +used on a RHEL10 kernel (e.g. in a container on a host with pauth +support). + +Make sure that virt-rhel9* machine types in RHEL9 stay the same +independent of the kernel. + +Signed-off-by: Sebastian Ott +JIRA: https://issues.redhat.com/browse/RHEL-75782 +--- + hw/arm/virt.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index c50bff2a6c..c5270a5abc 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -90,6 +90,16 @@ static GlobalProperty arm_virt_compat[] = { + }; + static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat); + ++/* ++ * RHEL9 kernels have pauth disabled while RHEL10 has it enabled, ++ * since qemu will setup the VM with pauth when KVM supports it we ++ * have to disable it for virt-rhel9* to support upgrades / migration. ++ */ ++GlobalProperty arm_rhel9_compat[] = { ++ {TYPE_ARM_CPU, "pauth", "off", .optional = true}, ++}; ++const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_compat); ++ + /* + * This variable is for changes to properties that are RHEL specific, + * different to the current upstream and to be applied to the latest +@@ -3589,6 +3599,7 @@ DEFINE_VIRT_MACHINE(2, 6) + + static void virt_rhel_machine_9_6_0_options(MachineClass *mc) + { ++ compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len); + } + DEFINE_VIRT_MACHINE_AS_LATEST(9, 6, 0) + +-- +2.48.0 + diff --git a/SOURCES/kvm-block-Add-active-field-to-BlockDeviceInfo.patch b/SOURCES/kvm-block-Add-active-field-to-BlockDeviceInfo.patch new file mode 100644 index 0000000..42ce35b --- /dev/null +++ b/SOURCES/kvm-block-Add-active-field-to-BlockDeviceInfo.patch @@ -0,0 +1,317 @@ +From 454a498569318365a16ed65bd2110daef5bb3fc3 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:52 +0100 +Subject: [PATCH 08/23] block: Add 'active' field to BlockDeviceInfo + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [7/22] 6309d1a9ac2a7a21013cfe71dc40474cbdc89464 (kmwolf/centos-qemu-kvm) + +This allows querying from QMP (and also HMP) whether an image is +currently active or inactive (in the sense of BDRV_O_INACTIVE). + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-2-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit aec81049c2daa8a97b89e59f03733b21ae0f8c2d) +Signed-off-by: Kevin Wolf +--- + block.c | 4 ++++ + block/monitor/block-hmp-cmds.c | 5 +++-- + block/qapi.c | 1 + + include/block/block-global-state.h | 3 +++ + qapi/block-core.json | 6 +++++- + tests/qemu-iotests/184.out | 2 ++ + tests/qemu-iotests/191.out | 16 ++++++++++++++++ + tests/qemu-iotests/273.out | 5 +++++ + 8 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/block.c b/block.c +index c317de9eaa..c94d78eefd 100644 +--- a/block.c ++++ b/block.c +@@ -6824,6 +6824,10 @@ void bdrv_init_with_whitelist(void) + bdrv_init(); + } + ++bool bdrv_is_inactive(BlockDriverState *bs) { ++ return bs->open_flags & BDRV_O_INACTIVE; ++} ++ + int bdrv_activate(BlockDriverState *bs, Error **errp) + { + BdrvChild *child, *parent; +diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c +index bdf2eb50b6..cc832549e1 100644 +--- a/block/monitor/block-hmp-cmds.c ++++ b/block/monitor/block-hmp-cmds.c +@@ -630,11 +630,12 @@ static void print_block_info(Monitor *mon, BlockInfo *info, + } + + if (inserted) { +- monitor_printf(mon, ": %s (%s%s%s)\n", ++ monitor_printf(mon, ": %s (%s%s%s%s)\n", + inserted->file, + inserted->drv, + inserted->ro ? ", read-only" : "", +- inserted->encrypted ? ", encrypted" : ""); ++ inserted->encrypted ? ", encrypted" : "", ++ inserted->active ? "" : ", inactive"); + } else { + monitor_printf(mon, ": [not inserted]\n"); + } +diff --git a/block/qapi.c b/block/qapi.c +index 2b5793f1d9..709170e63d 100644 +--- a/block/qapi.c ++++ b/block/qapi.c +@@ -63,6 +63,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, + info->file = g_strdup(bs->filename); + info->ro = bdrv_is_read_only(bs); + info->drv = g_strdup(bs->drv->format_name); ++ info->active = !bdrv_is_inactive(bs); + info->encrypted = bs->encrypted; + + info->cache = g_new(BlockdevCacheInfo, 1); +diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h +index bd7cecd1cf..a826bf5f78 100644 +--- a/include/block/block-global-state.h ++++ b/include/block/block-global-state.h +@@ -175,6 +175,9 @@ BlockDriverState * GRAPH_RDLOCK + check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, + Error **errp); + ++ ++bool GRAPH_RDLOCK bdrv_is_inactive(BlockDriverState *bs); ++ + int no_coroutine_fn GRAPH_RDLOCK + bdrv_activate(BlockDriverState *bs, Error **errp); + +diff --git a/qapi/block-core.json b/qapi/block-core.json +index aa40d44f1d..92af032744 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -486,6 +486,10 @@ + # @backing_file_depth: number of files in the backing file chain + # (since: 1.2) + # ++# @active: true if the backend is active; typical cases for inactive backends ++# are on the migration source instance after migration completes and on the ++# destination before it completes. (since: 10.0) ++# + # @encrypted: true if the backing device is encrypted + # + # @detect_zeroes: detect and optimize zero writes (Since 2.1) +@@ -556,7 +560,7 @@ + { 'struct': 'BlockDeviceInfo', + 'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str', + '*backing_file': 'str', 'backing_file_depth': 'int', +- 'encrypted': 'bool', ++ 'active': 'bool', 'encrypted': 'bool', + 'detect_zeroes': 'BlockdevDetectZeroesOptions', + 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int', + 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int', +diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out +index e8f631f853..52692b6b3b 100644 +--- a/tests/qemu-iotests/184.out ++++ b/tests/qemu-iotests/184.out +@@ -26,6 +26,7 @@ Testing: + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 1073741824, +@@ -59,6 +60,7 @@ Testing: + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 1073741824, + "filename": "null-co://", +diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out +index c3309e4bc6..2a72ca7106 100644 +--- a/tests/qemu-iotests/191.out ++++ b/tests/qemu-iotests/191.out +@@ -114,6 +114,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 67108864, +@@ -155,6 +156,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.ovl2", +@@ -183,6 +185,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 67108864, +@@ -224,6 +227,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT", +@@ -252,6 +256,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 67108864, +@@ -293,6 +298,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 393216, + "filename": "TEST_DIR/t.IMGFMT.mid", +@@ -321,6 +327,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 67108864, + "filename": "TEST_DIR/t.IMGFMT.base", +@@ -350,6 +357,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 393216, + "filename": "TEST_DIR/t.IMGFMT.base", +@@ -521,6 +529,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 67108864, +@@ -562,6 +571,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.ovl2", +@@ -590,6 +600,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "backing-image": { +@@ -642,6 +653,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.ovl3", +@@ -670,6 +682,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 67108864, + "filename": "TEST_DIR/t.IMGFMT.base", +@@ -699,6 +712,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 393216, + "filename": "TEST_DIR/t.IMGFMT.base", +@@ -727,6 +741,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 67108864, +@@ -768,6 +783,7 @@ wrote 65536/65536 bytes at offset 1048576 + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT", +diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out +index 71843f02de..c19753c685 100644 +--- a/tests/qemu-iotests/273.out ++++ b/tests/qemu-iotests/273.out +@@ -23,6 +23,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "backing-image": { +@@ -74,6 +75,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT", +@@ -102,6 +104,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "backing-image": { + "virtual-size": 197120, +@@ -142,6 +145,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.mid", +@@ -170,6 +174,7 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev + { + "iops_rd": 0, + "detect_zeroes": "off", ++ "active": true, + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.base", +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Add-blockdev-set-active-QMP-command.patch b/SOURCES/kvm-block-Add-blockdev-set-active-QMP-command.patch new file mode 100644 index 0000000..1c0b59a --- /dev/null +++ b/SOURCES/kvm-block-Add-blockdev-set-active-QMP-command.patch @@ -0,0 +1,187 @@ +From c6c40cc92fbb91d704d3739bb78bfd936f111625 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:59 +0100 +Subject: [PATCH 15/23] block: Add blockdev-set-active QMP command + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [14/22] e494fb6df6c363b6266e5fb7d09c31b3e7694f04 (kmwolf/centos-qemu-kvm) + +The system emulator tries to automatically activate and inactivate block +nodes at the right point during migration. However, there are still +cases where it's necessary that the user can do this manually. + +Images are only activated on the destination VM of a migration when the +VM is actually resumed. If the VM was paused, this doesn't happen +automatically. The user may want to perform some operation on a block +device (e.g. taking a snapshot or starting a block job) without also +resuming the VM yet. This is an example where a manual command is +necessary. + +Another example is VM migration when the image files are opened by an +external qemu-storage-daemon instance on each side. In this case, the +process that needs to hand over the images isn't even part of the +migration and can't know when the migration completes. Management tools +need a way to explicitly inactivate images on the source and activate +them on the destination. + +This adds a new blockdev-set-active QMP command that lets the user +change the status of individual nodes (this is necessary in +qemu-storage-daemon because it could be serving multiple VMs and only +one of them migrates at a time). For convenience, operating on all +devices (like QEMU does automatically during migration) is offered as an +option, too, and can be used in the context of single VM. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-9-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 8cd37207f8a90c5f995283ecf95f1cb5f7518a77) +Signed-off-by: Kevin Wolf +--- + block.c | 21 ++++++++++++++++++++ + blockdev.c | 32 ++++++++++++++++++++++++++++++ + include/block/block-global-state.h | 3 +++ + qapi/block-core.json | 32 ++++++++++++++++++++++++++++++ + 4 files changed, 88 insertions(+) + +diff --git a/block.c b/block.c +index fd2ac177ef..2140a5d3b7 100644 +--- a/block.c ++++ b/block.c +@@ -7052,6 +7052,27 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level) + return 0; + } + ++int bdrv_inactivate(BlockDriverState *bs, Error **errp) ++{ ++ int ret; ++ ++ GLOBAL_STATE_CODE(); ++ GRAPH_RDLOCK_GUARD_MAINLOOP(); ++ ++ if (bdrv_has_bds_parent(bs, true)) { ++ error_setg(errp, "Node has active parent node"); ++ return -EPERM; ++ } ++ ++ ret = bdrv_inactivate_recurse(bs, true); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to inactivate node"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + int bdrv_inactivate_all(void) + { + BlockDriverState *bs = NULL; +diff --git a/blockdev.c b/blockdev.c +index 81430122df..70046b6690 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -3468,6 +3468,38 @@ void qmp_blockdev_del(const char *node_name, Error **errp) + bdrv_unref(bs); + } + ++void qmp_blockdev_set_active(const char *node_name, bool active, Error **errp) ++{ ++ int ret; ++ ++ GLOBAL_STATE_CODE(); ++ GRAPH_RDLOCK_GUARD_MAINLOOP(); ++ ++ if (!node_name) { ++ if (active) { ++ bdrv_activate_all(errp); ++ } else { ++ ret = bdrv_inactivate_all(); ++ if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to inactivate all nodes"); ++ } ++ } ++ } else { ++ BlockDriverState *bs = bdrv_find_node(node_name); ++ if (!bs) { ++ error_setg(errp, "Failed to find node with node-name='%s'", ++ node_name); ++ return; ++ } ++ ++ if (active) { ++ bdrv_activate(bs, errp); ++ } else { ++ bdrv_inactivate(bs, errp); ++ } ++ } ++} ++ + static BdrvChild * GRAPH_RDLOCK + bdrv_find_child(BlockDriverState *parent_bs, const char *child_name) + { +diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h +index a826bf5f78..9be34b3c99 100644 +--- a/include/block/block-global-state.h ++++ b/include/block/block-global-state.h +@@ -184,6 +184,9 @@ bdrv_activate(BlockDriverState *bs, Error **errp); + int coroutine_fn no_co_wrapper_bdrv_rdlock + bdrv_co_activate(BlockDriverState *bs, Error **errp); + ++int no_coroutine_fn ++bdrv_inactivate(BlockDriverState *bs, Error **errp); ++ + void bdrv_activate_all(Error **errp); + int bdrv_inactivate_all(void); + +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 6ec603aa6f..c1af3d1f7d 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -4930,6 +4930,38 @@ + { 'command': 'blockdev-del', 'data': { 'node-name': 'str' }, + 'allow-preconfig': true } + ++## ++# @blockdev-set-active: ++# ++# Activate or inactivate a block device. Use this to manage the handover of ++# block devices on migration with qemu-storage-daemon. ++# ++# Activating a node automatically activates all of its child nodes first. ++# Inactivating a node automatically inactivates any of its child nodes that are ++# not in use by a still active node. ++# ++# @node-name: Name of the graph node to activate or inactivate. By default, all ++# nodes are affected by the operation. ++# ++# @active: true if the nodes should be active when the command returns success, ++# false if they should be inactive. ++# ++# Since: 10.0 ++# ++# .. qmp-example:: ++# ++# -> { "execute": "blockdev-set-active", ++# "arguments": { ++# "node-name": "node0", ++# "active": false ++# } ++# } ++# <- { "return": {} } ++## ++{ 'command': 'blockdev-set-active', ++ 'data': { '*node-name': 'str', 'active': 'bool' }, ++ 'allow-preconfig': true } ++ + ## + # @BlockdevCreateOptionsFile: + # +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Add-option-to-create-inactive-nodes.patch b/SOURCES/kvm-block-Add-option-to-create-inactive-nodes.patch new file mode 100644 index 0000000..8502b88 --- /dev/null +++ b/SOURCES/kvm-block-Add-option-to-create-inactive-nodes.patch @@ -0,0 +1,102 @@ +From d44250363b08e627e06a9afe288d02a3d995afc0 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:58 +0100 +Subject: [PATCH 14/23] block: Add option to create inactive nodes + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [13/22] 45b01b9c09d5f12715e4977cab6140d2cac90714 (kmwolf/centos-qemu-kvm) + +In QEMU, nodes are automatically created inactive while expecting an +incoming migration (i.e. RUN_STATE_INMIGRATE). In qemu-storage-daemon, +the notion of runstates doesn't exist. It also wouldn't necessarily make +sense to introduce it because a single daemon can serve multiple VMs +that can be in different states. + +Therefore, allow the user to explicitly open images as inactive with a +new option. The default is as before: Nodes are usually active, except +when created during RUN_STATE_INMIGRATE. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-8-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit faecd16fe5c65a25b5b55b5edbe4322cec5a9d96) +Signed-off-by: Kevin Wolf +--- + block.c | 9 +++++++++ + include/block/block-common.h | 1 + + qapi/block-core.json | 6 ++++++ + 3 files changed, 16 insertions(+) + +diff --git a/block.c b/block.c +index bedd54deaa..fd2ac177ef 100644 +--- a/block.c ++++ b/block.c +@@ -1573,6 +1573,10 @@ static void update_flags_from_options(int *flags, QemuOpts *opts) + if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) { + *flags |= BDRV_O_AUTO_RDONLY; + } ++ ++ if (!qemu_opt_get_bool_del(opts, BDRV_OPT_ACTIVE, true)) { ++ *flags |= BDRV_O_INACTIVE; ++ } + } + + static void update_options_from_flags(QDict *options, int flags) +@@ -1799,6 +1803,11 @@ QemuOptsList bdrv_runtime_opts = { + .type = QEMU_OPT_BOOL, + .help = "Ignore flush requests", + }, ++ { ++ .name = BDRV_OPT_ACTIVE, ++ .type = QEMU_OPT_BOOL, ++ .help = "Node is activated", ++ }, + { + .name = BDRV_OPT_READ_ONLY, + .type = QEMU_OPT_BOOL, +diff --git a/include/block/block-common.h b/include/block/block-common.h +index 338fe5ff7a..7030669f04 100644 +--- a/include/block/block-common.h ++++ b/include/block/block-common.h +@@ -257,6 +257,7 @@ typedef enum { + #define BDRV_OPT_AUTO_READ_ONLY "auto-read-only" + #define BDRV_OPT_DISCARD "discard" + #define BDRV_OPT_FORCE_SHARE "force-share" ++#define BDRV_OPT_ACTIVE "active" + + + #define BDRV_SECTOR_BITS 9 +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 92af032744..6ec603aa6f 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -4668,6 +4668,11 @@ + # + # @cache: cache-related options + # ++# @active: whether the block node should be activated (default: true). ++# Having inactive block nodes is useful primarily for migration because it ++# allows opening an image on the destination while the source is still ++# holding locks for it. (Since 10.0) ++# + # @read-only: whether the block device should be read-only (default: + # false). Note that some block drivers support only read-only + # access, either generally or in certain configurations. In this +@@ -4694,6 +4699,7 @@ + '*node-name': 'str', + '*discard': 'BlockdevDiscardOptions', + '*cache': 'BlockdevCacheOptions', ++ '*active': 'bool', + '*read-only': 'bool', + '*auto-read-only': 'bool', + '*force-share': 'bool', +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Allow-inactivating-already-inactive-nodes.patch b/SOURCES/kvm-block-Allow-inactivating-already-inactive-nodes.patch new file mode 100644 index 0000000..7001529 --- /dev/null +++ b/SOURCES/kvm-block-Allow-inactivating-already-inactive-nodes.patch @@ -0,0 +1,80 @@ +From f7f73025679c5d001256d87bc47566d1db4e98c7 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:53 +0100 +Subject: [PATCH 09/23] block: Allow inactivating already inactive nodes + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [8/22] 781a749ae61e038b5b562407b01d53a1bfba598c (kmwolf/centos-qemu-kvm) + +What we wanted to catch with the assertion is cases where the recursion +finds that a child was inactive before its parent. This should never +happen. But if the user tries to inactivate an image that is already +inactive, that's harmless and we don't want to fail the assertion. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-3-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit a6490ec9d56b9e95a13918813585a3a9891710bc) +Signed-off-by: Kevin Wolf +--- + block.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/block.c b/block.c +index c94d78eefd..a2aa454312 100644 +--- a/block.c ++++ b/block.c +@@ -6959,7 +6959,8 @@ bdrv_has_bds_parent(BlockDriverState *bs, bool only_active) + return false; + } + +-static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) ++static int GRAPH_RDLOCK ++bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level) + { + BdrvChild *child, *parent; + int ret; +@@ -6977,7 +6978,14 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) + return 0; + } + +- assert(!(bs->open_flags & BDRV_O_INACTIVE)); ++ /* ++ * Inactivating an already inactive node on user request is harmless, but if ++ * a child is already inactive before its parent, that's bad. ++ */ ++ if (bs->open_flags & BDRV_O_INACTIVE) { ++ assert(top_level); ++ return 0; ++ } + + /* Inactivate this node */ + if (bs->drv->bdrv_inactivate) { +@@ -7014,7 +7022,7 @@ static int GRAPH_RDLOCK bdrv_inactivate_recurse(BlockDriverState *bs) + + /* Recursively inactivate children */ + QLIST_FOREACH(child, &bs->children, next) { +- ret = bdrv_inactivate_recurse(child->bs); ++ ret = bdrv_inactivate_recurse(child->bs, false); + if (ret < 0) { + return ret; + } +@@ -7039,7 +7047,7 @@ int bdrv_inactivate_all(void) + if (bdrv_has_bds_parent(bs, false)) { + continue; + } +- ret = bdrv_inactivate_recurse(bs); ++ ret = bdrv_inactivate_recurse(bs, true); + if (ret < 0) { + bdrv_next_cleanup(&it); + break; +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Don-t-attach-inactive-child-to-active-node.patch b/SOURCES/kvm-block-Don-t-attach-inactive-child-to-active-node.patch new file mode 100644 index 0000000..f2a9219 --- /dev/null +++ b/SOURCES/kvm-block-Don-t-attach-inactive-child-to-active-node.patch @@ -0,0 +1,46 @@ +From 0f0968badaa11f4ac56f8ee93cbe11f9a6d5fc95 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:56 +0100 +Subject: [PATCH 12/23] block: Don't attach inactive child to active node + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [11/22] 1ca560728b97bd1d5f7498a7e5d23e2d8bb0808d (kmwolf/centos-qemu-kvm) + +An active node makes unrestricted use of its children and would possibly +run into assertion failures when it operates on an inactive child node. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-6-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 9b81361aedcc47905de5e91f68221de89c6f5467) +Signed-off-by: Kevin Wolf +--- + block.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/block.c b/block.c +index a2aa454312..41e72e6965 100644 +--- a/block.c ++++ b/block.c +@@ -3183,6 +3183,11 @@ bdrv_attach_child_noperm(BlockDriverState *parent_bs, + child_bs->node_name, child_name, parent_bs->node_name); + return NULL; + } ++ if (bdrv_is_inactive(child_bs) && !bdrv_is_inactive(parent_bs)) { ++ error_setg(errp, "Inactive '%s' can't be a %s child of active '%s'", ++ child_bs->node_name, child_name, parent_bs->node_name); ++ return NULL; ++ } + + bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); + bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Drain-nodes-before-inactivating-them.patch b/SOURCES/kvm-block-Drain-nodes-before-inactivating-them.patch new file mode 100644 index 0000000..6514f25 --- /dev/null +++ b/SOURCES/kvm-block-Drain-nodes-before-inactivating-them.patch @@ -0,0 +1,52 @@ +From bc9b651ce0f36da5a5b6eb8631e7040e59ea2493 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:02 +0100 +Subject: [PATCH 18/23] block: Drain nodes before inactivating them + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [17/22] f0fec0f51ed033038b565297a7217cbf61ab70f7 (kmwolf/centos-qemu-kvm) + +So far the assumption has always been that if we try to inactivate a +node, it is already idle. This doesn't hold true any more if we allow +inactivating exported nodes because we can't know when new external +requests come in. + +Drain the node around setting BDRV_O_INACTIVE so that requests can't +start operating on an active node and then in the middle it suddenly +becomes inactive. With this change, it's enough for exports to check +for new requests that they operate on an active node (or, like reads, +are allowed even on an inactive node). + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Message-ID: <20250204211407.381505-12-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit 2849092a0024405e74c96f0a5ec41bb182ec8538) +Signed-off-by: Kevin Wolf +--- + block.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/block.c b/block.c +index 2140a5d3b7..38cb8481a8 100644 +--- a/block.c ++++ b/block.c +@@ -7032,7 +7032,9 @@ bdrv_inactivate_recurse(BlockDriverState *bs, bool top_level) + return -EPERM; + } + ++ bdrv_drained_begin(bs); + bs->open_flags |= BDRV_O_INACTIVE; ++ bdrv_drained_end(bs); + + /* + * Update permissions, they may differ for inactive nodes. +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch b/SOURCES/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch new file mode 100644 index 0000000..63d37e6 --- /dev/null +++ b/SOURCES/kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch @@ -0,0 +1,68 @@ +From eed2b4b40553cae162407b375f18c935f5025c53 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:57 +0100 +Subject: [PATCH 13/23] block: Fix crash on block_resize on inactive node + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [12/22] e352c665f68a865859cc62fe1ed6e4044407b8e3 (kmwolf/centos-qemu-kvm) + +In order for block_resize to fail gracefully on an inactive node instead +of crashing with an assertion failure in bdrv_co_write_req_prepare() +(called from bdrv_co_truncate()), we need to check for inactive nodes +also when they are attached as a root node and make sure that +BLK_PERM_RESIZE isn't among the permissions allowed for inactive nodes. +To this effect, don't enumerate the permissions that are incompatible +with inactive nodes any more, but allow only BLK_PERM_CONSISTENT_READ +for them. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-7-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 8c2c72a33581987af8d8c484d03af3cd69b9e10a) +Signed-off-by: Kevin Wolf +--- + block.c | 7 +++++++ + block/block-backend.c | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/block.c b/block.c +index 41e72e6965..bedd54deaa 100644 +--- a/block.c ++++ b/block.c +@@ -3077,6 +3077,13 @@ bdrv_attach_child_common(BlockDriverState *child_bs, + assert(child_class->get_parent_desc); + GLOBAL_STATE_CODE(); + ++ if (bdrv_is_inactive(child_bs) && (perm & ~BLK_PERM_CONSISTENT_READ)) { ++ g_autofree char *perm_names = bdrv_perm_names(perm); ++ error_setg(errp, "Permission '%s' unavailable on inactive node", ++ perm_names); ++ return NULL; ++ } ++ + new_child = g_new(BdrvChild, 1); + *new_child = (BdrvChild) { + .bs = NULL, +diff --git a/block/block-backend.c b/block/block-backend.c +index db6f9b92a3..356db1b703 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -253,7 +253,7 @@ static bool blk_can_inactivate(BlockBackend *blk) + * guest. For block job BBs that satisfy this, we can just allow + * it. This is the case for mirror job source, which is required + * by libvirt non-shared block migration. */ +- if (!(blk->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED))) { ++ if (!(blk->perm & ~BLK_PERM_CONSISTENT_READ)) { + return true; + } + +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch b/SOURCES/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch new file mode 100644 index 0000000..3c38d06 --- /dev/null +++ b/SOURCES/kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch @@ -0,0 +1,68 @@ +From 6f4a7e3489a104137f60e034157cf687e4c3158f Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:54 +0100 +Subject: [PATCH 10/23] block: Inactivate external snapshot overlays when + necessary + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [9/22] 59b39138f0da734d497f3a58d458992abc348978 (kmwolf/centos-qemu-kvm) + +Putting an active block node on top of an inactive one is strictly +speaking an invalid configuration and the next patch will turn it into a +hard error. + +However, taking a snapshot while disk images are inactive after +completing migration has an important use case: After migrating to a +file, taking an external snapshot is what is needed to take a full VM +snapshot. + +In order for this to keep working after the later patches, change +creating a snapshot such that it automatically inactivates an overlay +that is added on top of an already inactive node. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-4-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit e80210ffb24c4e47650344ba77ce3ed354af596c) +Signed-off-by: Kevin Wolf +--- + blockdev.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/blockdev.c b/blockdev.c +index 835064ed03..81430122df 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -1497,6 +1497,22 @@ static void external_snapshot_action(TransactionAction *action, + return; + } + ++ /* ++ * Older QEMU versions have allowed adding an active parent node to an ++ * inactive child node. This is unsafe in the general case, but there is an ++ * important use case, which is taking a VM snapshot with migration to file ++ * and then adding an external snapshot while the VM is still stopped and ++ * images are inactive. Requiring the user to explicitly create the overlay ++ * as inactive would break compatibility, so just do it automatically here ++ * to keep this working. ++ */ ++ if (bdrv_is_inactive(state->old_bs) && !bdrv_is_inactive(state->new_bs)) { ++ ret = bdrv_inactivate(state->new_bs, errp); ++ if (ret < 0) { ++ return; ++ } ++ } ++ + ret = bdrv_append(state->new_bs, state->old_bs, errp); + if (ret < 0) { + return; +-- +2.48.1 + diff --git a/SOURCES/kvm-block-Parse-filenames-only-when-explicitly-requested.patch b/SOURCES/kvm-block-Parse-filenames-only-when-explicitly-requested.patch deleted file mode 100644 index 8db6199..0000000 --- a/SOURCES/kvm-block-Parse-filenames-only-when-explicitly-requested.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 2ee645a339e9ef9cd92620a8b784d18d512326be Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 25 Apr 2024 14:56:02 +0200 -Subject: [PATCH 4/4] block: Parse filenames only when explicitly requested - -RH-Author: Hana Czenczek -RH-MergeRequest: 1: CVE 2024-4467 (PRDSC) -RH-Jira: RHEL-35611 -RH-CVE: CVE-2024-4467 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Eric Blake -RH-Commit: [4/4] f44c2941d4419e60f16dea3e9adca164e75aa78d - -When handling image filenames from legacy options such as -drive or from -tools, these filenames are parsed for protocol prefixes, including for -the json:{} pseudo-protocol. - -This behaviour is intended for filenames that come directly from the -command line and for backing files, which may come from the image file -itself. Higher level management tools generally take care to verify that -untrusted images don't contain a bad (or any) backing file reference; -'qemu-img info' is a suitable tool for this. - -However, for other files that can be referenced in images, such as -qcow2 data files or VMDK extents, the string from the image file is -usually not verified by management tools - and 'qemu-img info' wouldn't -be suitable because in contrast to backing files, it already opens these -other referenced files. So here the string should be interpreted as a -literal local filename. More complex configurations need to be specified -explicitly on the command line or in QMP. - -This patch changes bdrv_open_inherit() so that it only parses filenames -if a new parameter parse_filename is true. It is set for the top level -in bdrv_open(), for the file child and for the backing file child. All -other callers pass false and disable filename parsing this way. - -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Hanna Czenczek -Upstream: N/A, embargoed -Signed-off-by: Hanna Czenczek ---- - block.c | 90 ++++++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 57 insertions(+), 33 deletions(-) - -diff --git a/block.c b/block.c -index 468cf5e67d..50bdd197b7 100644 ---- a/block.c -+++ b/block.c -@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, - BlockDriverState *parent, - const BdrvChildClass *child_class, - BdrvChildRole child_role, -+ bool parse_filename, - Error **errp); - - static bool bdrv_recurse_has_child(BlockDriverState *bs, -@@ -2058,7 +2059,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename, - * block driver has been specified explicitly. - */ - static int bdrv_fill_options(QDict **options, const char *filename, -- int *flags, Error **errp) -+ int *flags, bool allow_parse_filename, -+ Error **errp) - { - const char *drvname; - bool protocol = *flags & BDRV_O_PROTOCOL; -@@ -2100,7 +2102,7 @@ static int bdrv_fill_options(QDict **options, const char *filename, - if (protocol && filename) { - if (!qdict_haskey(*options, "filename")) { - qdict_put_str(*options, "filename", filename); -- parse_filename = true; -+ parse_filename = allow_parse_filename; - } else { - error_setg(errp, "Can't specify 'file' and 'filename' options at " - "the same time"); -@@ -3663,7 +3665,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, - } - - backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs, -- &child_of_bds, bdrv_backing_role(bs), errp); -+ &child_of_bds, bdrv_backing_role(bs), true, -+ errp); - if (!backing_hd) { - bs->open_flags |= BDRV_O_NO_BACKING; - error_prepend(errp, "Could not open backing file: "); -@@ -3697,7 +3700,8 @@ free_exit: - static BlockDriverState * - bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, - BlockDriverState *parent, const BdrvChildClass *child_class, -- BdrvChildRole child_role, bool allow_none, Error **errp) -+ BdrvChildRole child_role, bool allow_none, -+ bool parse_filename, Error **errp) - { - BlockDriverState *bs = NULL; - QDict *image_options; -@@ -3728,7 +3732,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, - } - - bs = bdrv_open_inherit(filename, reference, image_options, 0, -- parent, child_class, child_role, errp); -+ parent, child_class, child_role, parse_filename, -+ errp); - if (!bs) { - goto done; - } -@@ -3738,6 +3743,33 @@ done: - return bs; - } - -+static BdrvChild *bdrv_open_child_common(const char *filename, -+ QDict *options, const char *bdref_key, -+ BlockDriverState *parent, -+ const BdrvChildClass *child_class, -+ BdrvChildRole child_role, -+ bool allow_none, bool parse_filename, -+ Error **errp) -+{ -+ BlockDriverState *bs; -+ BdrvChild *child; -+ -+ GLOBAL_STATE_CODE(); -+ -+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, -+ child_role, allow_none, parse_filename, errp); -+ if (bs == NULL) { -+ return NULL; -+ } -+ -+ bdrv_graph_wrlock(); -+ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, -+ errp); -+ bdrv_graph_wrunlock(); -+ -+ return child; -+} -+ - /* - * Opens a disk image whose options are given as BlockdevRef in another block - * device's options. -@@ -3761,27 +3793,15 @@ BdrvChild *bdrv_open_child(const char *filename, - BdrvChildRole child_role, - bool allow_none, Error **errp) - { -- BlockDriverState *bs; -- BdrvChild *child; -- -- GLOBAL_STATE_CODE(); -- -- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, -- child_role, allow_none, errp); -- if (bs == NULL) { -- return NULL; -- } -- -- bdrv_graph_wrlock(); -- child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, -- errp); -- bdrv_graph_wrunlock(); -- -- return child; -+ return bdrv_open_child_common(filename, options, bdref_key, parent, -+ child_class, child_role, allow_none, false, -+ errp); - } - - /* -- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. -+ * This does mostly the same as bdrv_open_child(), but for opening the primary -+ * child of a node. A notable difference from bdrv_open_child() is that it -+ * enables filename parsing for protocol names (including json:). - * - * @parent can move to a different AioContext in this function. - */ -@@ -3796,8 +3816,8 @@ int bdrv_open_file_child(const char *filename, - role = parent->drv->is_filter ? - (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; - -- if (!bdrv_open_child(filename, options, bdref_key, parent, -- &child_of_bds, role, false, errp)) -+ if (!bdrv_open_child_common(filename, options, bdref_key, parent, -+ &child_of_bds, role, false, true, errp)) - { - return -EINVAL; - } -@@ -3842,7 +3862,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) - - } - -- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp); -+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false, -+ errp); - obj = NULL; - qobject_unref(obj); - visit_free(v); -@@ -3932,7 +3953,7 @@ static BlockDriverState * no_coroutine_fn - bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - int flags, BlockDriverState *parent, - const BdrvChildClass *child_class, BdrvChildRole child_role, -- Error **errp) -+ bool parse_filename, Error **errp) - { - int ret; - BlockBackend *file = NULL; -@@ -3980,9 +4001,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - } - - /* json: syntax counts as explicit options, as if in the QDict */ -- parse_json_protocol(options, &filename, &local_err); -- if (local_err) { -- goto fail; -+ if (parse_filename) { -+ parse_json_protocol(options, &filename, &local_err); -+ if (local_err) { -+ goto fail; -+ } - } - - bs->explicit_options = qdict_clone_shallow(options); -@@ -4007,7 +4030,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - parent->open_flags, parent->options); - } - -- ret = bdrv_fill_options(&options, filename, &flags, &local_err); -+ ret = bdrv_fill_options(&options, filename, &flags, parse_filename, -+ &local_err); - if (ret < 0) { - goto fail; - } -@@ -4076,7 +4100,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, - - file_bs = bdrv_open_child_bs(filename, options, "file", bs, - &child_of_bds, BDRV_CHILD_IMAGE, -- true, &local_err); -+ true, true, &local_err); - if (local_err) { - goto fail; - } -@@ -4225,7 +4249,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference, - GLOBAL_STATE_CODE(); - - return bdrv_open_inherit(filename, reference, options, flags, NULL, -- NULL, 0, errp); -+ NULL, 0, true, errp); - } - - /* Return true if the NULL-terminated @list contains @str */ --- -2.39.3 - diff --git a/SOURCES/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch b/SOURCES/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch new file mode 100644 index 0000000..fbe6fda --- /dev/null +++ b/SOURCES/kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch @@ -0,0 +1,66 @@ +From 9ab8c39284c0fc2d9d685706b2d788ab02930a08 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:00 +0100 +Subject: [PATCH 16/23] block: Support inactive nodes in blk_insert_bs() + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [15/22] 17405266afeddc47f73828816d0b8c1ab5ece462 (kmwolf/centos-qemu-kvm) + +Device models have a relatively complex way to set up their block +backends, in which blk_attach_dev() sets blk->disable_perm = true. +We want to support inactive images in exports, too, so that +qemu-storage-daemon can be used with migration. Because they don't use +blk_attach_dev(), they need another way to set this flag. The most +convenient is to do this automatically when an inactive node is attached +to a BlockBackend that can be inactivated. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-10-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit c1c5c7cc4ef6c45ca769c640566fd40d2cb7d5c1) +Signed-off-by: Kevin Wolf +--- + block/block-backend.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 356db1b703..4a5a1c1f6a 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -909,14 +909,24 @@ void blk_remove_bs(BlockBackend *blk) + int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp) + { + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; ++ uint64_t perm, shared_perm; + + GLOBAL_STATE_CODE(); + bdrv_ref(bs); + bdrv_graph_wrlock(); ++ ++ if ((bs->open_flags & BDRV_O_INACTIVE) && blk_can_inactivate(blk)) { ++ blk->disable_perm = true; ++ perm = 0; ++ shared_perm = BLK_PERM_ALL; ++ } else { ++ perm = blk->perm; ++ shared_perm = blk->shared_perm; ++ } ++ + blk->root = bdrv_root_attach_child(bs, "root", &child_root, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, +- blk->perm, blk->shared_perm, +- blk, errp); ++ perm, shared_perm, blk, errp); + bdrv_graph_wrunlock(); + if (blk->root == NULL) { + return -EPERM; +-- +2.48.1 + diff --git a/SOURCES/kvm-block-crypto-create-ciphers-on-demand.patch b/SOURCES/kvm-block-crypto-create-ciphers-on-demand.patch deleted file mode 100644 index c2b9c47..0000000 --- a/SOURCES/kvm-block-crypto-create-ciphers-on-demand.patch +++ /dev/null @@ -1,330 +0,0 @@ -From a67edfb4b591acdffc5b4987601a30224376996f Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 27 May 2024 11:58:50 -0400 -Subject: [PATCH 4/5] block/crypto: create ciphers on demand -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 251: block/crypto: create ciphers on demand -RH-Jira: RHEL-36159 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/2] 22a4c87fef774cad98a6f5a79f27df50a208013d (stefanha/centos-stream-qemu-kvm) - -Ciphers are pre-allocated by qcrypto_block_init_cipher() depending on -the given number of threads. The -device -virtio-blk-pci,iothread-vq-mapping= feature allows users to assign -multiple IOThreads to a virtio-blk device, but the association between -the virtio-blk device and the block driver happens after the block -driver is already open. - -When the number of threads given to qcrypto_block_init_cipher() is -smaller than the actual number of threads at runtime, the -block->n_free_ciphers > 0 assertion in qcrypto_block_pop_cipher() can -fail. - -Get rid of qcrypto_block_init_cipher() n_thread's argument and allocate -ciphers on demand. - -Reported-by: Qing Wang -Buglink: https://issues.redhat.com/browse/RHEL-36159 -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240527155851.892885-2-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Acked-by: Daniel P. Berrangé -Signed-off-by: Kevin Wolf -(cherry picked from commit af206c284e4c1b17cdfb0f17e898b288c0fc1751) -Signed-off-by: Stefan Hajnoczi ---- - crypto/block-luks.c | 3 +- - crypto/block-qcow.c | 2 +- - crypto/block.c | 111 ++++++++++++++++++++++++++------------------ - crypto/blockpriv.h | 12 +++-- - 4 files changed, 78 insertions(+), 50 deletions(-) - -diff --git a/crypto/block-luks.c b/crypto/block-luks.c -index 3ee928fb5a..3357852c0a 100644 ---- a/crypto/block-luks.c -+++ b/crypto/block-luks.c -@@ -1262,7 +1262,6 @@ qcrypto_block_luks_open(QCryptoBlock *block, - luks->cipher_mode, - masterkey, - luks->header.master_key_len, -- n_threads, - errp) < 0) { - goto fail; - } -@@ -1456,7 +1455,7 @@ qcrypto_block_luks_create(QCryptoBlock *block, - /* Setup the block device payload encryption objects */ - if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg, - luks_opts.cipher_mode, masterkey, -- luks->header.master_key_len, 1, errp) < 0) { -+ luks->header.master_key_len, errp) < 0) { - goto error; - } - -diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c -index 4d7cf36a8f..02305058e3 100644 ---- a/crypto/block-qcow.c -+++ b/crypto/block-qcow.c -@@ -75,7 +75,7 @@ qcrypto_block_qcow_init(QCryptoBlock *block, - ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC, - keybuf, G_N_ELEMENTS(keybuf), -- n_threads, errp); -+ errp); - if (ret < 0) { - ret = -ENOTSUP; - goto fail; -diff --git a/crypto/block.c b/crypto/block.c -index 506ea1d1a3..ba6d1cebc7 100644 ---- a/crypto/block.c -+++ b/crypto/block.c -@@ -20,6 +20,7 @@ - - #include "qemu/osdep.h" - #include "qapi/error.h" -+#include "qemu/lockable.h" - #include "blockpriv.h" - #include "block-qcow.h" - #include "block-luks.h" -@@ -57,6 +58,8 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - { - QCryptoBlock *block = g_new0(QCryptoBlock, 1); - -+ qemu_mutex_init(&block->mutex); -+ - block->format = options->format; - - if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || -@@ -76,8 +79,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - return NULL; - } - -- qemu_mutex_init(&block->mutex); -- - return block; - } - -@@ -92,6 +93,8 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, - { - QCryptoBlock *block = g_new0(QCryptoBlock, 1); - -+ qemu_mutex_init(&block->mutex); -+ - block->format = options->format; - - if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || -@@ -111,8 +114,6 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, - return NULL; - } - -- qemu_mutex_init(&block->mutex); -- - return block; - } - -@@ -227,37 +228,42 @@ QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) - * This function is used only in test with one thread (it's safe to skip - * pop/push interface), so it's enough to assert it here: - */ -- assert(block->n_ciphers <= 1); -- return block->ciphers ? block->ciphers[0] : NULL; -+ assert(block->max_free_ciphers <= 1); -+ return block->free_ciphers ? block->free_ciphers[0] : NULL; - } - - --static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block) -+static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block, -+ Error **errp) - { -- QCryptoCipher *cipher; -- -- qemu_mutex_lock(&block->mutex); -- -- assert(block->n_free_ciphers > 0); -- block->n_free_ciphers--; -- cipher = block->ciphers[block->n_free_ciphers]; -- -- qemu_mutex_unlock(&block->mutex); -+ /* Usually there is a free cipher available */ -+ WITH_QEMU_LOCK_GUARD(&block->mutex) { -+ if (block->n_free_ciphers > 0) { -+ block->n_free_ciphers--; -+ return block->free_ciphers[block->n_free_ciphers]; -+ } -+ } - -- return cipher; -+ /* Otherwise allocate a new cipher */ -+ return qcrypto_cipher_new(block->alg, block->mode, block->key, -+ block->nkey, errp); - } - - - static void qcrypto_block_push_cipher(QCryptoBlock *block, - QCryptoCipher *cipher) - { -- qemu_mutex_lock(&block->mutex); -+ QEMU_LOCK_GUARD(&block->mutex); - -- assert(block->n_free_ciphers < block->n_ciphers); -- block->ciphers[block->n_free_ciphers] = cipher; -- block->n_free_ciphers++; -+ if (block->n_free_ciphers == block->max_free_ciphers) { -+ block->max_free_ciphers++; -+ block->free_ciphers = g_renew(QCryptoCipher *, -+ block->free_ciphers, -+ block->max_free_ciphers); -+ } - -- qemu_mutex_unlock(&block->mutex); -+ block->free_ciphers[block->n_free_ciphers] = cipher; -+ block->n_free_ciphers++; - } - - -@@ -265,24 +271,31 @@ int qcrypto_block_init_cipher(QCryptoBlock *block, - QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, size_t nkey, -- size_t n_threads, Error **errp) -+ Error **errp) - { -- size_t i; -+ QCryptoCipher *cipher; - -- assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers); -+ assert(!block->free_ciphers && !block->max_free_ciphers && -+ !block->n_free_ciphers); - -- block->ciphers = g_new0(QCryptoCipher *, n_threads); -+ /* Stash away cipher parameters for qcrypto_block_pop_cipher() */ -+ block->alg = alg; -+ block->mode = mode; -+ block->key = g_memdup2(key, nkey); -+ block->nkey = nkey; - -- for (i = 0; i < n_threads; i++) { -- block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp); -- if (!block->ciphers[i]) { -- qcrypto_block_free_cipher(block); -- return -1; -- } -- block->n_ciphers++; -- block->n_free_ciphers++; -+ /* -+ * Create a new cipher to validate the parameters now. This reduces the -+ * chance of cipher creation failing at I/O time. -+ */ -+ cipher = qcrypto_block_pop_cipher(block, errp); -+ if (!cipher) { -+ g_free(block->key); -+ block->key = NULL; -+ return -1; - } - -+ qcrypto_block_push_cipher(block, cipher); - return 0; - } - -@@ -291,19 +304,23 @@ void qcrypto_block_free_cipher(QCryptoBlock *block) - { - size_t i; - -- if (!block->ciphers) { -+ g_free(block->key); -+ block->key = NULL; -+ -+ if (!block->free_ciphers) { - return; - } - -- assert(block->n_ciphers == block->n_free_ciphers); -+ /* All popped ciphers were eventually pushed back */ -+ assert(block->n_free_ciphers == block->max_free_ciphers); - -- for (i = 0; i < block->n_ciphers; i++) { -- qcrypto_cipher_free(block->ciphers[i]); -+ for (i = 0; i < block->max_free_ciphers; i++) { -+ qcrypto_cipher_free(block->free_ciphers[i]); - } - -- g_free(block->ciphers); -- block->ciphers = NULL; -- block->n_ciphers = block->n_free_ciphers = 0; -+ g_free(block->free_ciphers); -+ block->free_ciphers = NULL; -+ block->max_free_ciphers = block->n_free_ciphers = 0; - } - - QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) -@@ -311,7 +328,7 @@ QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) - /* ivgen should be accessed under mutex. However, this function is used only - * in test with one thread, so it's enough to assert it here: - */ -- assert(block->n_ciphers <= 1); -+ assert(block->max_free_ciphers <= 1); - return block->ivgen; - } - -@@ -446,7 +463,10 @@ int qcrypto_block_decrypt_helper(QCryptoBlock *block, - Error **errp) - { - int ret; -- QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); -+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block, errp); -+ if (!cipher) { -+ return -1; -+ } - - ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, - &block->mutex, sectorsize, offset, buf, -@@ -465,7 +485,10 @@ int qcrypto_block_encrypt_helper(QCryptoBlock *block, - Error **errp) - { - int ret; -- QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); -+ QCryptoCipher *cipher = qcrypto_block_pop_cipher(block, errp); -+ if (!cipher) { -+ return -1; -+ } - - ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, - &block->mutex, sectorsize, offset, buf, -diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h -index 836f3b4726..4bf6043d5d 100644 ---- a/crypto/blockpriv.h -+++ b/crypto/blockpriv.h -@@ -32,8 +32,14 @@ struct QCryptoBlock { - const QCryptoBlockDriver *driver; - void *opaque; - -- QCryptoCipher **ciphers; -- size_t n_ciphers; -+ /* Cipher parameters */ -+ QCryptoCipherAlgorithm alg; -+ QCryptoCipherMode mode; -+ uint8_t *key; -+ size_t nkey; -+ -+ QCryptoCipher **free_ciphers; -+ size_t max_free_ciphers; - size_t n_free_ciphers; - QCryptoIVGen *ivgen; - QemuMutex mutex; -@@ -130,7 +136,7 @@ int qcrypto_block_init_cipher(QCryptoBlock *block, - QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, size_t nkey, -- size_t n_threads, Error **errp); -+ Error **errp); - - void qcrypto_block_free_cipher(QCryptoBlock *block); - --- -2.39.3 - diff --git a/SOURCES/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch b/SOURCES/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch new file mode 100644 index 0000000..e3db67a --- /dev/null +++ b/SOURCES/kvm-block-export-Add-option-to-allow-export-of-inactive-.patch @@ -0,0 +1,135 @@ +From 22de4ba6cec94a38cd56156d9114f06dc4d2a5a5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:03 +0100 +Subject: [PATCH 19/23] block/export: Add option to allow export of inactive + nodes + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [18/22] 985eadb03f27d046b89ffeef1fb36ef2e4579552 (kmwolf/centos-qemu-kvm) + +Add an option in BlockExportOptions to allow creating an export on an +inactive node without activating the node. This mode needs to be +explicitly supported by the export type (so that it doesn't perform any +operations that are forbidden for inactive nodes), so this patch alone +doesn't allow this option to be successfully used yet. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-13-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 1600ef01ab1296ca8230daa6bc41ba983751f646) +Signed-off-by: Kevin Wolf +--- + block/export/export.c | 31 +++++++++++++++++++++---------- + include/block/export.h | 3 +++ + qapi/block-export.json | 10 +++++++++- + 3 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/block/export/export.c b/block/export/export.c +index 23a86efcdb..71af65b3e5 100644 +--- a/block/export/export.c ++++ b/block/export/export.c +@@ -75,6 +75,7 @@ static const BlockExportDriver *blk_exp_find_driver(BlockExportType type) + BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) + { + bool fixed_iothread = export->has_fixed_iothread && export->fixed_iothread; ++ bool allow_inactive = export->has_allow_inactive && export->allow_inactive; + const BlockExportDriver *drv; + BlockExport *exp = NULL; + BlockDriverState *bs; +@@ -138,17 +139,24 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) + } + } + +- /* +- * Block exports are used for non-shared storage migration. Make sure +- * that BDRV_O_INACTIVE is cleared and the image is ready for write +- * access since the export could be available before migration handover. +- * ctx was acquired in the caller. +- */ + bdrv_graph_rdlock_main_loop(); +- ret = bdrv_activate(bs, errp); +- if (ret < 0) { +- bdrv_graph_rdunlock_main_loop(); +- goto fail; ++ if (allow_inactive) { ++ if (!drv->supports_inactive) { ++ error_setg(errp, "Export type does not support inactive exports"); ++ bdrv_graph_rdunlock_main_loop(); ++ goto fail; ++ } ++ } else { ++ /* ++ * Block exports are used for non-shared storage migration. Make sure ++ * that BDRV_O_INACTIVE is cleared and the image is ready for write ++ * access since the export could be available before migration handover. ++ */ ++ ret = bdrv_activate(bs, errp); ++ if (ret < 0) { ++ bdrv_graph_rdunlock_main_loop(); ++ goto fail; ++ } + } + bdrv_graph_rdunlock_main_loop(); + +@@ -162,6 +170,9 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) + if (!fixed_iothread) { + blk_set_allow_aio_context_change(blk, true); + } ++ if (allow_inactive) { ++ blk_set_force_allow_inactivate(blk); ++ } + + ret = blk_insert_bs(blk, bs, errp); + if (ret < 0) { +diff --git a/include/block/export.h b/include/block/export.h +index f2fe0f8078..4bd9531d4d 100644 +--- a/include/block/export.h ++++ b/include/block/export.h +@@ -29,6 +29,9 @@ typedef struct BlockExportDriver { + */ + size_t instance_size; + ++ /* True if the export type supports running on an inactive node */ ++ bool supports_inactive; ++ + /* Creates and starts a new block export */ + int (*create)(BlockExport *, BlockExportOptions *, Error **); + +diff --git a/qapi/block-export.json b/qapi/block-export.json +index ce33fe378d..117b05d13c 100644 +--- a/qapi/block-export.json ++++ b/qapi/block-export.json +@@ -372,6 +372,13 @@ + # cannot be moved to the iothread. The default is false. + # (since: 5.2) + # ++# @allow-inactive: If true, the export allows the exported node to be inactive. ++# If it is created for an inactive block node, the node remains inactive. If ++# the export type doesn't support running on an inactive node, an error is ++# returned. If false, inactive block nodes are automatically activated before ++# creating the export and trying to inactivate them later fails. ++# (since: 10.0; default: false) ++# + # Since: 4.2 + ## + { 'union': 'BlockExportOptions', +@@ -381,7 +388,8 @@ + '*iothread': 'str', + 'node-name': 'str', + '*writable': 'bool', +- '*writethrough': 'bool' }, ++ '*writethrough': 'bool', ++ '*allow-inactive': 'bool' }, + 'discriminator': 'type', + 'data': { + 'nbd': 'BlockExportOptionsNbd', +-- +2.48.1 + diff --git a/SOURCES/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch b/SOURCES/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch new file mode 100644 index 0000000..217851f --- /dev/null +++ b/SOURCES/kvm-block-export-Don-t-ignore-image-activation-error-in-.patch @@ -0,0 +1,50 @@ +From 0cced76da63a886e6aaaa96a2c40620db27cb8cc Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:01 +0100 +Subject: [PATCH 17/23] block/export: Don't ignore image activation error in + blk_exp_add() + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [16/22] 86e791a19948c88a3512bb7ba3bd3ed0f03a2a18 (kmwolf/centos-qemu-kvm) + +Currently, block exports can't handle inactive images correctly. +Incoming write requests would run into assertion failures. Make sure +that we return an error when creating an export can't activate the +image. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-11-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 69f28176ca0af850db23a1c6364f0c8525b20801) +Signed-off-by: Kevin Wolf +--- + block/export/export.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/block/export/export.c b/block/export/export.c +index 6d51ae8ed7..23a86efcdb 100644 +--- a/block/export/export.c ++++ b/block/export/export.c +@@ -145,7 +145,11 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) + * ctx was acquired in the caller. + */ + bdrv_graph_rdlock_main_loop(); +- bdrv_activate(bs, NULL); ++ ret = bdrv_activate(bs, errp); ++ if (ret < 0) { ++ bdrv_graph_rdunlock_main_loop(); ++ goto fail; ++ } + bdrv_graph_rdunlock_main_loop(); + + perm = BLK_PERM_CONSISTENT_READ; +-- +2.48.1 + diff --git a/SOURCES/kvm-confidential-guest-support-Add-kvm_init-and-kvm_rese.patch b/SOURCES/kvm-confidential-guest-support-Add-kvm_init-and-kvm_rese.patch deleted file mode 100644 index 785b437..0000000 --- a/SOURCES/kvm-confidential-guest-support-Add-kvm_init-and-kvm_rese.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0f0a3a860a07addea21a0282556a5022b9cb8b2c Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 29 Feb 2024 01:00:35 -0500 -Subject: [PATCH 011/100] confidential guest support: Add kvm_init() and - kvm_reset() in class - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [11/91] 21d2178178bf181a8e4d0b051f64bd983f0d0cf1 (bonzini/rhel-qemu-kvm) - -Different confidential VMs in different architectures all have the same -needs to do their specific initialization (and maybe resetting) stuffs -with KVM. Currently each of them exposes individual *_kvm_init() -functions and let machine code or kvm code to call it. - -To facilitate the introduction of confidential guest technology from -different x86 vendors, add two virtual functions, kvm_init() and kvm_reset() -in ConfidentialGuestSupportClass, and expose two helpers functions for -invodking them. - -Signed-off-by: Xiaoyao Li -Message-Id: <20240229060038.606591-1-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 41a605944e3fecae43ca18ded95ec31f28e0c7fe) -Signed-off-by: Paolo Bonzini ---- - include/exec/confidential-guest-support.h | 34 ++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index ba2dd4b5df..e5b188cffb 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -23,7 +23,10 @@ - #include "qom/object.h" - - #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support" --OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT) -+OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, -+ ConfidentialGuestSupportClass, -+ CONFIDENTIAL_GUEST_SUPPORT) -+ - - struct ConfidentialGuestSupport { - Object parent; -@@ -55,8 +58,37 @@ struct ConfidentialGuestSupport { - - typedef struct ConfidentialGuestSupportClass { - ObjectClass parent; -+ -+ int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp); -+ int (*kvm_reset)(ConfidentialGuestSupport *cgs, Error **errp); - } ConfidentialGuestSupportClass; - -+static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs, -+ Error **errp) -+{ -+ ConfidentialGuestSupportClass *klass; -+ -+ klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs); -+ if (klass->kvm_init) { -+ return klass->kvm_init(cgs, errp); -+ } -+ -+ return 0; -+} -+ -+static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs, -+ Error **errp) -+{ -+ ConfidentialGuestSupportClass *klass; -+ -+ klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs); -+ if (klass->kvm_reset) { -+ return klass->kvm_reset(cgs, errp); -+ } -+ -+ return 0; -+} -+ - #endif /* !CONFIG_USER_ONLY */ - - #endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */ --- -2.39.3 - diff --git a/SOURCES/kvm-crypto-block-drop-qcrypto_block_open-n_threads-argum.patch b/SOURCES/kvm-crypto-block-drop-qcrypto_block_open-n_threads-argum.patch deleted file mode 100644 index b5fcef5..0000000 --- a/SOURCES/kvm-crypto-block-drop-qcrypto_block_open-n_threads-argum.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 117486e0820f135f191e19f8ebb8838a98b121c6 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Mon, 27 May 2024 11:58:51 -0400 -Subject: [PATCH 5/5] crypto/block: drop qcrypto_block_open() n_threads - argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Stefan Hajnoczi -RH-MergeRequest: 251: block/crypto: create ciphers on demand -RH-Jira: RHEL-36159 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/2] 68290935b174b1f2b76aa857a926da9011e54abe (stefanha/centos-stream-qemu-kvm) - -The n_threads argument is no longer used since the previous commit. -Remove it. - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20240527155851.892885-3-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Acked-by: Daniel P. Berrangé -Signed-off-by: Kevin Wolf -(cherry picked from commit 3ab0f063e58ed9224237d69c4211ca83335164c4) -Signed-off-by: Stefan Hajnoczi ---- - block/crypto.c | 1 - - block/qcow.c | 2 +- - block/qcow2.c | 5 ++--- - crypto/block-luks.c | 1 - - crypto/block-qcow.c | 6 ++---- - crypto/block.c | 3 +-- - crypto/blockpriv.h | 1 - - include/crypto/block.h | 2 -- - tests/unit/test-crypto-block.c | 4 ---- - 9 files changed, 6 insertions(+), 19 deletions(-) - -diff --git a/block/crypto.c b/block/crypto.c -index 21eed909c1..4eed3ffa6a 100644 ---- a/block/crypto.c -+++ b/block/crypto.c -@@ -363,7 +363,6 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, - block_crypto_read_func, - bs, - cflags, -- 1, - errp); - - if (!crypto->block) { -diff --git a/block/qcow.c b/block/qcow.c -index ca8e1d5ec8..c2f89db055 100644 ---- a/block/qcow.c -+++ b/block/qcow.c -@@ -211,7 +211,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, - cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; - } - s->crypto = qcrypto_block_open(crypto_opts, "encrypt.", -- NULL, NULL, cflags, 1, errp); -+ NULL, NULL, cflags, errp); - if (!s->crypto) { - ret = -EINVAL; - goto fail; -diff --git a/block/qcow2.c b/block/qcow2.c -index 0e8b2f7518..0ebd455dc8 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -321,7 +321,7 @@ qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, - } - s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", - qcow2_crypto_hdr_read_func, -- bs, cflags, QCOW2_MAX_THREADS, errp); -+ bs, cflags, errp); - if (!s->crypto) { - return -EINVAL; - } -@@ -1707,8 +1707,7 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, - cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; - } - s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", -- NULL, NULL, cflags, -- QCOW2_MAX_THREADS, errp); -+ NULL, NULL, cflags, errp); - if (!s->crypto) { - ret = -EINVAL; - goto fail; -diff --git a/crypto/block-luks.c b/crypto/block-luks.c -index 3357852c0a..5b777c15d3 100644 ---- a/crypto/block-luks.c -+++ b/crypto/block-luks.c -@@ -1189,7 +1189,6 @@ qcrypto_block_luks_open(QCryptoBlock *block, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, -- size_t n_threads, - Error **errp) - { - QCryptoBlockLUKS *luks = NULL; -diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c -index 02305058e3..42e9556e42 100644 ---- a/crypto/block-qcow.c -+++ b/crypto/block-qcow.c -@@ -44,7 +44,6 @@ qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED, - static int - qcrypto_block_qcow_init(QCryptoBlock *block, - const char *keysecret, -- size_t n_threads, - Error **errp) - { - char *password; -@@ -100,7 +99,6 @@ qcrypto_block_qcow_open(QCryptoBlock *block, - QCryptoBlockReadFunc readfunc G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED, - unsigned int flags, -- size_t n_threads, - Error **errp) - { - if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) { -@@ -115,7 +113,7 @@ qcrypto_block_qcow_open(QCryptoBlock *block, - return -1; - } - return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, -- n_threads, errp); -+ errp); - } - } - -@@ -135,7 +133,7 @@ qcrypto_block_qcow_create(QCryptoBlock *block, - return -1; - } - /* QCow2 has no special header, since everything is hardwired */ -- return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, errp); -+ return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp); - } - - -diff --git a/crypto/block.c b/crypto/block.c -index ba6d1cebc7..3bcc4270c3 100644 ---- a/crypto/block.c -+++ b/crypto/block.c -@@ -53,7 +53,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, -- size_t n_threads, - Error **errp) - { - QCryptoBlock *block = g_new0(QCryptoBlock, 1); -@@ -73,7 +72,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - block->driver = qcrypto_block_drivers[options->format]; - - if (block->driver->open(block, options, optprefix, -- readfunc, opaque, flags, n_threads, errp) < 0) -+ readfunc, opaque, flags, errp) < 0) - { - g_free(block); - return NULL; -diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h -index 4bf6043d5d..b8f77cb5eb 100644 ---- a/crypto/blockpriv.h -+++ b/crypto/blockpriv.h -@@ -59,7 +59,6 @@ struct QCryptoBlockDriver { - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, -- size_t n_threads, - Error **errp); - - int (*create)(QCryptoBlock *block, -diff --git a/include/crypto/block.h b/include/crypto/block.h -index 92e823c9f2..5b5d039800 100644 ---- a/include/crypto/block.h -+++ b/include/crypto/block.h -@@ -76,7 +76,6 @@ typedef enum { - * @readfunc: callback for reading data from the volume - * @opaque: data to pass to @readfunc - * @flags: bitmask of QCryptoBlockOpenFlags values -- * @n_threads: allow concurrent I/O from up to @n_threads threads - * @errp: pointer to a NULL-initialized error object - * - * Create a new block encryption object for an existing -@@ -113,7 +112,6 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, -- size_t n_threads, - Error **errp); - - typedef enum { -diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c -index 6cfc817a92..42cfab6067 100644 ---- a/tests/unit/test-crypto-block.c -+++ b/tests/unit/test-crypto-block.c -@@ -303,7 +303,6 @@ static void test_block(gconstpointer opaque) - test_block_read_func, - &header, - 0, -- 1, - NULL); - g_assert(blk == NULL); - -@@ -312,7 +311,6 @@ static void test_block(gconstpointer opaque) - test_block_read_func, - &header, - QCRYPTO_BLOCK_OPEN_NO_IO, -- 1, - &error_abort); - - g_assert(qcrypto_block_get_cipher(blk) == NULL); -@@ -327,7 +325,6 @@ static void test_block(gconstpointer opaque) - test_block_read_func, - &header, - 0, -- 1, - &error_abort); - g_assert(blk); - -@@ -384,7 +381,6 @@ test_luks_bad_header(gconstpointer data) - test_block_read_func, - &buf, - 0, -- 1, - &err); - g_assert(!blk); - g_assert(err); --- -2.39.3 - diff --git a/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch b/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch new file mode 100644 index 0000000..2b707e6 --- /dev/null +++ b/SOURCES/kvm-docs-system-Update-documentation-for-s390x-IPL.patch @@ -0,0 +1,76 @@ +From 38df1fff536527bf47e190d000d8c05679f0f220 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:52 -0400 +Subject: [PATCH 19/27] docs/system: Update documentation for s390x IPL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [19/23] feefab248336e1744eeb6bdf86e9033fe8184b3a (thuth/qemu-kvm-cs9) + +Update docs to show that s390x PC BIOS can support more than one boot device. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-19-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 0bd107138ff0b171e3cd314dbc200950bcab2b05) +--- + docs/system/bootindex.rst | 7 ++++--- + docs/system/s390x/bootdevices.rst | 9 ++++++--- + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst +index 8b057f812f..988f7b3beb 100644 +--- a/docs/system/bootindex.rst ++++ b/docs/system/bootindex.rst +@@ -49,10 +49,11 @@ Limitations + ----------- + + Some firmware has limitations on which devices can be considered for +-booting. For instance, the PC BIOS boot specification allows only one +-disk to be bootable. If boot from disk fails for some reason, the BIOS ++booting. For instance, the x86 PC BIOS boot specification allows only one ++disk to be bootable. If boot from disk fails for some reason, the x86 BIOS + won't retry booting from other disk. It can still try to boot from +-floppy or net, though. ++floppy or net, though. In the case of s390x BIOS, the BIOS will try up to ++8 total devices, any number of which may be disks. + + Sometimes, firmware cannot map the device path QEMU wants firmware to + boot from to a boot method. It doesn't happen for devices the firmware +diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst +index c97efb8fc0..1a1a764c1c 100644 +--- a/docs/system/s390x/bootdevices.rst ++++ b/docs/system/s390x/bootdevices.rst +@@ -6,9 +6,7 @@ Booting with bootindex parameter + + For classical mainframe guests (i.e. LPAR or z/VM installations), you always + have to explicitly specify the disk where you want to boot from (or "IPL" from, +-in s390x-speak -- IPL means "Initial Program Load"). In particular, there can +-also be only one boot device according to the architecture specification, thus +-specifying multiple boot devices is not possible (yet). ++in s390x-speak -- IPL means "Initial Program Load"). + + So for booting an s390x guest in QEMU, you should always mark the + device where you want to boot from with the ``bootindex`` property, for +@@ -17,6 +15,11 @@ example:: + qemu-system-s390x -drive if=none,id=dr1,file=guest.qcow2 \ + -device virtio-blk,drive=dr1,bootindex=1 + ++Multiple devices may have a bootindex. The lowest bootindex is assigned to the ++device to IPL first. If the IPL fails for the first, the device with the second ++lowest bootindex will be tried and so on until IPL is successful or there are no ++remaining boot devices to try. ++ + For booting from a CD-ROM ISO image (which needs to include El-Torito boot + information in order to be bootable), it is recommended to specify a ``scsi-cd`` + device, for example like this:: +-- +2.39.3 + diff --git a/SOURCES/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch b/SOURCES/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch new file mode 100644 index 0000000..0956149 --- /dev/null +++ b/SOURCES/kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch @@ -0,0 +1,45 @@ +From 5a0451f82a143dbaa0f75543a75c8e4560ac477f Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 11 Nov 2024 11:55:06 +0100 +Subject: [PATCH 03/10] docs/system/bootindex: Make it clear that s390x can + also boot from virtio-net +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/8] 2921f4532ad7b0891dea251a4d768776170c6271 (thuth/qemu-kvm-cs9) + +Let's make it clear that s390x can also boot from virtio-net, to avoid +that people think that s390x can only boot from disk devices. + +Reported-by: Boris Fiuczynski +Message-ID: <20241111105506.264640-1-thuth@redhat.com> +Reviewed-by: Prasad Pandit +Reviewed-by: Boris Fiuczynski +Signed-off-by: Thomas Huth +(cherry picked from commit b8c5fdc6588f82d95807be0eb2215d215a3ba16e) +--- + docs/system/bootindex.rst | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/system/bootindex.rst b/docs/system/bootindex.rst +index 988f7b3beb..5e1b33ee22 100644 +--- a/docs/system/bootindex.rst ++++ b/docs/system/bootindex.rst +@@ -53,7 +53,7 @@ booting. For instance, the x86 PC BIOS boot specification allows only one + disk to be bootable. If boot from disk fails for some reason, the x86 BIOS + won't retry booting from other disk. It can still try to boot from + floppy or net, though. In the case of s390x BIOS, the BIOS will try up to +-8 total devices, any number of which may be disks. ++8 total devices, any number of which may be disks or virtio-net devices. + + Sometimes, firmware cannot map the device path QEMU wants firmware to + boot from to a boot method. It doesn't happen for devices the firmware +-- +2.39.3 + diff --git a/SOURCES/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch new file mode 100644 index 0000000..900b9ab --- /dev/null +++ b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch @@ -0,0 +1,65 @@ +From 255d789ab8fbc5a79236e0943a222371ceded164 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Thu, 14 Nov 2024 19:27:42 -0500 +Subject: [PATCH 02/10] docs/system/s390x/bootdevices: Update loadparm + documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/8] df997bcf56bad83b5d4832dbf6c3298abd15b249 (thuth/qemu-kvm-cs9) + +Update documentation to include per-device loadparm support. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241115002742.3576842-1-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 0271fdc650b212533b8aeaecbedfe8ccf6bbbef3) +--- + docs/system/s390x/bootdevices.rst | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst +index 1a1a764c1c..97b3914785 100644 +--- a/docs/system/s390x/bootdevices.rst ++++ b/docs/system/s390x/bootdevices.rst +@@ -79,7 +79,29 @@ The second way to use this parameter is to use a number in the range from 0 + to 31. The numbers that can be used here correspond to the numbers that are + shown when using the ``PROMPT`` option, and the s390-ccw bios will then try + to automatically boot the kernel that is associated with the given number. +-Note that ``0`` can be used to boot the default entry. ++Note that ``0`` can be used to boot the default entry. If the machine ++``loadparm`` is not assigned a value, then the default entry is used. ++ ++By default, the machine ``loadparm`` applies to all boot devices. If multiple ++devices are assigned a ``bootindex`` and the ``loadparm`` is to be different ++between them, an independent ``loadparm`` may be assigned on a per-device basis. ++ ++An example guest using per-device ``loadparm``:: ++ ++ qemu-system-s390x -drive if=none,id=dr1,file=primary.qcow2 \ ++ -device virtio-blk,drive=dr1,bootindex=1 \ ++ -drive if=none,id=dr2,file=secondary.qcow2 \ ++ -device virtio-blk,drive=dr2,bootindex=2,loadparm=3 ++ ++In this case, the primary boot device will attempt to IPL using the default ++entry (because no ``loadparm`` is specified for this device or for the ++machine). If that device fails to boot, the secondary device will attempt to ++IPL using entry number 3. ++ ++If a ``loadparm`` is specified on both the machine and a device, the per-device ++value will superseded the machine value. Per-device ``loadparm`` values are ++only used for devices with an assigned ``bootindex``. The machine ``loadparm`` ++is used when attempting to boot without a ``bootindex``. + + + Booting from a network device +-- +2.39.3 + diff --git a/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch new file mode 100644 index 0000000..fdc7d4b --- /dev/null +++ b/SOURCES/kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch @@ -0,0 +1,66 @@ +From 63c705bdd8d8f17860988d22aa29a238e9fae631 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:40 -0400 +Subject: [PATCH 07/27] docs/system/s390x/bootdevices: Update the documentation + about network booting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/23] 31b1f484e98304c385adbefb6eb50b501d179268 (thuth/qemu-kvm-cs9) + +Remove the information about the separate s390-netboot.img from +the documentation. + +Co-authored by: Thomas Huth +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-7-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit ab2691b6c7ff360875e0af86ff463278f17786f5) +--- + docs/system/s390x/bootdevices.rst | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +diff --git a/docs/system/s390x/bootdevices.rst b/docs/system/s390x/bootdevices.rst +index 1a7a18b43b..c97efb8fc0 100644 +--- a/docs/system/s390x/bootdevices.rst ++++ b/docs/system/s390x/bootdevices.rst +@@ -82,23 +82,17 @@ Note that ``0`` can be used to boot the default entry. + Booting from a network device + ----------------------------- + +-Beside the normal guest firmware (which is loaded from the file ``s390-ccw.img`` +-in the data directory of QEMU, or via the ``-bios`` option), QEMU ships with +-a small TFTP network bootloader firmware for virtio-net-ccw devices, too. This +-firmware is loaded from a file called ``s390-netboot.img`` in the QEMU data +-directory. In case you want to load it from a different filename instead, +-you can specify it via the ``-global s390-ipl.netboot_fw=filename`` +-command line option. +- +-The ``bootindex`` property is especially important for booting via the network. +-If you don't specify the ``bootindex`` property here, the network bootloader +-firmware code won't get loaded into the guest memory so that the network boot +-will fail. For a successful network boot, try something like this:: ++The firmware that ships with QEMU includes a small TFTP network bootloader ++for virtio-net-ccw devices. The ``bootindex`` property is especially ++important for booting via the network. If you don't specify the ``bootindex`` ++property here, the network bootloader won't be taken into consideration and ++the network boot will fail. For a successful network boot, try something ++like this:: + + qemu-system-s390x -netdev user,id=n1,tftp=...,bootfile=... \ + -device virtio-net-ccw,netdev=n1,bootindex=1 + +-The network bootloader firmware also has basic support for pxelinux.cfg-style ++The network bootloader also has basic support for pxelinux.cfg-style + configuration files. See the `PXELINUX Configuration page + `__ + for details how to set up the configuration file on your TFTP server. +-- +2.39.3 + diff --git a/SOURCES/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch b/SOURCES/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch new file mode 100644 index 0000000..70e6bcc --- /dev/null +++ b/SOURCES/kvm-hostmem-Apply-merge-property-after-the-memory-region.patch @@ -0,0 +1,61 @@ +From 34266f76ec5c96aceee89d1dd25c338af81f99dc Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 20 Nov 2024 17:13:44 +1000 +Subject: [PATCH 2/2] hostmem: Apply merge property after the memory region is + initialized + +RH-Author: Gavin Shan +RH-MergeRequest: 296: hostmem: Apply merge property after the memory region is initialized +RH-Jira: RHEL-68289 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Eric Auger +RH-Acked-by: Sebastian Ott +RH-Commit: [1/1] fc01302c3299a15fd523247e5a3df0957becba6a (gwshan/qemu-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-68289 + +The semantic change has been introduced by commit 5becdc0ab0 ("hostmem: +simplify the code for merge and dump properties") even it clarifies that +no senmatic change has been introduced. After the commit, the merge +property can be applied even the corresponding memory region isn't +initialized yet. This leads to crash dump by the following command +lines. + + # /home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \ + -accel kvm -machine virt -cpu host \ + -object memory-backend-ram,id=mem-memN0,size=4096M,merge=off + : + qemu-system-aarch64: ../system/memory.c:2419: memory_region_get_ram_ptr: \ + Assertion `mr->ram_block' failed. + +Fix it by applying the merge property only when the memory region is +initialized. + +Message-ID: <20240915233117.478169-1-gshan@redhat.com> +Fixes: 5becdc0ab083 ("hostmem: simplify the code for merge and dump properties") +Reported-by: Zhenyu Zhang +Tested-by: Zhenyu Zhang +Signed-off-by: Gavin Shan +Signed-off-by: David Hildenbrand +(cherry picked from commit 78c8f780d3f0d6d17aa93d6f99ff72960080fdd7) +Signed-off-by: Gavin Shan +--- + backends/hostmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/backends/hostmem.c b/backends/hostmem.c +index 4e5576a4ad..181446626a 100644 +--- a/backends/hostmem.c ++++ b/backends/hostmem.c +@@ -178,7 +178,7 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp) + return; + } + +- if (!host_memory_backend_mr_inited(backend) && ++ if (host_memory_backend_mr_inited(backend) && + value != backend->merge) { + void *ptr = memory_region_get_ram_ptr(&backend->mr); + uint64_t sz = memory_region_size(&backend->mr); +-- +2.45.1 + diff --git a/SOURCES/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch b/SOURCES/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch new file mode 100644 index 0000000..14fe2f0 --- /dev/null +++ b/SOURCES/kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch @@ -0,0 +1,221 @@ +From 7aa02e169dde52b4a7f6ec832a3fe55027fbd5e2 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Fri, 15 Nov 2024 15:12:02 +0100 +Subject: [PATCH 05/10] hw: Add "loadparm" property to scsi disk devices for + booting on s390x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/8] 7e3444e1fda776ca3b6de246b2dd696edf4980dd (thuth/qemu-kvm-cs9) + +While adding the new flexible boot order feature on s390x recently, +we missed to add the "loadparm" property to the scsi-hd and scsi-cd +devices. This property is required on s390x to pass the information +to the boot loader about which kernel should be started or whether +the boot menu should be shown. But even more serious: The missing +property is now causing trouble with the corresponding libvirt patches +that assume that the "loadparm" property is either settable for all +bootable devices (when the "boot order" feature is implemented in +QEMU), or none (meaning the behaviour of older QEMUs that only allowed +one "loadparm" at the machine level). To fix this broken situation, +let's implement the "loadparm" property in for the SCSI devices, too. + +Message-ID: <20241115141202.1877294-1-thuth@redhat.com> +Acked-by: Eric Farman +Signed-off-by: Thomas Huth +(cherry picked from commit 429442e52d94f890fa194a151e8cd649b04e9e63) +--- + hw/core/qdev-properties-system.c | 26 +++++++++++++++++ + hw/s390x/ipl.c | 19 ++++--------- + hw/scsi/scsi-disk.c | 43 +++++++++++++++++++++++++++++ + include/hw/qdev-properties-system.h | 3 ++ + 4 files changed, 78 insertions(+), 13 deletions(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index f13350b4fb..5cd527cdba 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -58,6 +58,32 @@ static bool check_prop_still_unset(Object *obj, const char *name, + return false; + } + ++bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str, ++ Error **errp) ++{ ++ int i, len; ++ ++ len = strlen(str); ++ if (len > 8) { ++ error_setg(errp, "'loadparm' can only contain up to 8 characters"); ++ return false; ++ } ++ ++ for (i = 0; i < len; i++) { ++ uint8_t c = qemu_toupper(str[i]); /* mimic HMC */ ++ ++ if (qemu_isalnum(c) || c == '.' || c == ' ') { ++ loadparm[i] = c; ++ } else { ++ error_setg(errp, ++ "invalid character in 'loadparm': '%c' (ASCII 0x%02x)", ++ c, c); ++ return false; ++ } ++ } ++ ++ return true; ++} + + /* --- drive --- */ + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index 5fbd43c346..8101825dfe 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -418,21 +418,9 @@ static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain) + + void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp) + { +- int i; +- + /* Initialize the loadparm with spaces */ + memset(loadparm, ' ', LOADPARM_LEN); +- for (i = 0; i < LOADPARM_LEN && str[i]; i++) { +- uint8_t c = qemu_toupper(str[i]); /* mimic HMC */ +- +- if (qemu_isalnum(c) || c == '.' || c == ' ') { +- loadparm[i] = c; +- } else { +- error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)", +- c, c); +- return; +- } +- } ++ qdev_prop_sanitize_s390x_loadparm(loadparm, str, errp); + } + + void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) +@@ -452,6 +440,7 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + SCSIDevice *sd; + int devtype; + uint8_t *lp; ++ g_autofree void *scsi_lp = NULL; + + /* + * Currently allow IPL only from CCW devices. +@@ -463,6 +452,10 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + switch (devtype) { + case CCW_DEVTYPE_SCSI: + sd = SCSI_DEVICE(dev_st); ++ scsi_lp = object_property_get_str(OBJECT(sd), "loadparm", NULL); ++ if (scsi_lp && strlen(scsi_lp) > 0) { ++ lp = scsi_lp; ++ } + iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); + iplb->blk0_len = + cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 4d94b2b816..7566a5f531 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -32,6 +32,7 @@ + #include "migration/vmstate.h" + #include "hw/scsi/emulation.h" + #include "scsi/constants.h" ++#include "sysemu/arch_init.h" + #include "sysemu/block-backend.h" + #include "sysemu/blockdev.h" + #include "hw/block/block.h" +@@ -111,6 +112,7 @@ struct SCSIDiskState { + char *vendor; + char *product; + char *device_id; ++ char *loadparm; /* only for s390x */ + bool tray_open; + bool tray_locked; + /* +@@ -3135,6 +3137,43 @@ BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov, + return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque); + } + ++static char *scsi_property_get_loadparm(Object *obj, Error **errp) ++{ ++ return g_strdup(SCSI_DISK_BASE(obj)->loadparm); ++} ++ ++static void scsi_property_set_loadparm(Object *obj, const char *value, ++ Error **errp) ++{ ++ void *lp_str; ++ ++ if (object_property_get_int(obj, "bootindex", NULL) < 0) { ++ error_setg(errp, "'loadparm' is only valid for boot devices"); ++ return; ++ } ++ ++ lp_str = g_malloc0(strlen(value)); ++ if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) { ++ g_free(lp_str); ++ return; ++ } ++ SCSI_DISK_BASE(obj)->loadparm = lp_str; ++} ++ ++static void scsi_property_add_specifics(DeviceClass *dc) ++{ ++ ObjectClass *oc = OBJECT_CLASS(dc); ++ ++ /* The loadparm property is only supported on s390x */ ++ if (arch_type & QEMU_ARCH_S390X) { ++ object_class_property_add_str(oc, "loadparm", ++ scsi_property_get_loadparm, ++ scsi_property_set_loadparm); ++ object_class_property_set_description(oc, "loadparm", ++ "load parameter (s390x only)"); ++ } ++} ++ + static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); +@@ -3218,6 +3257,8 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data) + dc->desc = "virtual SCSI disk"; + device_class_set_props(dc, scsi_hd_properties); + dc->vmsd = &vmstate_scsi_disk_state; ++ ++ scsi_property_add_specifics(dc); + } + + static const TypeInfo scsi_hd_info = { +@@ -3258,6 +3299,8 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data) + dc->desc = "virtual SCSI CD-ROM"; + device_class_set_props(dc, scsi_cd_properties); + dc->vmsd = &vmstate_scsi_disk_state; ++ ++ scsi_property_add_specifics(dc); + } + + static const TypeInfo scsi_cd_info = { +diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h +index 438f65389f..88e4257ad0 100644 +--- a/include/hw/qdev-properties-system.h ++++ b/include/hw/qdev-properties-system.h +@@ -3,6 +3,9 @@ + + #include "hw/qdev-properties.h" + ++bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str, ++ Error **errp); ++ + extern const PropertyInfo qdev_prop_chr; + extern const PropertyInfo qdev_prop_macaddr; + extern const PropertyInfo qdev_prop_reserved_region; +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-arm-virt-Avoid-unexpected-warning-from-Linux-gues.patch b/SOURCES/kvm-hw-arm-virt-Avoid-unexpected-warning-from-Linux-gues.patch deleted file mode 100644 index 29991d5..0000000 --- a/SOURCES/kvm-hw-arm-virt-Avoid-unexpected-warning-from-Linux-gues.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 41c4083269ec772b406c6c57b496ca2011f928c7 Mon Sep 17 00:00:00 2001 -From: Zhenyu Zhang -Date: Tue, 9 Jul 2024 23:08:59 -0400 -Subject: [PATCH 2/2] hw/arm/virt: Avoid unexpected warning from Linux guest on - host with Fujitsu CPUs - -RH-Author: zhenyzha -RH-MergeRequest: 256: hw/arm/virt: Avoid unexpected warning from Linux guest on host with Fujitsu CPUs -RH-Jira: RHEL-39936 -RH-Acked-by: Gavin Shan -RH-Acked-by: Sebastian Ott -RH-Acked-by: Cornelia Huck -RH-Commit: [1/1] fdf156fd05b219a06e2e2ca409fff0f728c1e2cf (zhenyzha/qemu-kvm) - -JIRA: https://issues.redhat.com/browse/RHEL-39936 - -Multiple warning messages and corresponding backtraces are observed when Linux -guest is booted on the host with Fujitsu CPUs. One of them is shown as below. - -[ 0.032443] ------------[ cut here ]------------ -[ 0.032446] uart-pl011 9000000.pl011: ARCH_DMA_MINALIGN smaller than -CTR_EL0.CWG (128 < 256) -[ 0.032454] WARNING: CPU: 0 PID: 1 at arch/arm64/mm/dma-mapping.c:54 -arch_setup_dma_ops+0xbc/0xcc -[ 0.032470] Modules linked in: -[ 0.032475] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-452.el9.aarch64 -[ 0.032481] Hardware name: linux,dummy-virt (DT) -[ 0.032484] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 0.032490] pc : arch_setup_dma_ops+0xbc/0xcc -[ 0.032496] lr : arch_setup_dma_ops+0xbc/0xcc -[ 0.032501] sp : ffff80008003b860 -[ 0.032503] x29: ffff80008003b860 x28: 0000000000000000 x27: ffffaae4b949049c -[ 0.032510] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 -[ 0.032517] x23: 0000000000000100 x22: 0000000000000000 x21: 0000000000000000 -[ 0.032523] x20: 0000000100000000 x19: ffff2f06c02ea400 x18: ffffffffffffffff -[ 0.032529] x17: 00000000208a5f76 x16: 000000006589dbcb x15: ffffaae4ba071c89 -[ 0.032535] x14: 0000000000000000 x13: ffffaae4ba071c84 x12: 455f525443206e61 -[ 0.032541] x11: 68742072656c6c61 x10: 0000000000000029 x9 : ffffaae4b7d21da4 -[ 0.032547] x8 : 0000000000000029 x7 : 4c414e494d5f414d x6 : 0000000000000029 -[ 0.032553] x5 : 000000000000000f x4 : ffffaae4b9617a00 x3 : 0000000000000001 -[ 0.032558] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff2f06c029be40 -[ 0.032564] Call trace: -[ 0.032566] arch_setup_dma_ops+0xbc/0xcc -[ 0.032572] of_dma_configure_id+0x138/0x300 -[ 0.032591] amba_dma_configure+0x34/0xc0 -[ 0.032600] really_probe+0x78/0x3dc -[ 0.032614] __driver_probe_device+0x108/0x160 -[ 0.032619] driver_probe_device+0x44/0x114 -[ 0.032624] __device_attach_driver+0xb8/0x14c -[ 0.032629] bus_for_each_drv+0x88/0xe4 -[ 0.032634] __device_attach+0xb0/0x1e0 -[ 0.032638] device_initial_probe+0x18/0x20 -[ 0.032643] bus_probe_device+0xa8/0xb0 -[ 0.032648] device_add+0x4b4/0x6c0 -[ 0.032652] amba_device_try_add.part.0+0x48/0x360 -[ 0.032657] amba_device_add+0x104/0x144 -[ 0.032662] of_amba_device_create.isra.0+0x100/0x1c4 -[ 0.032666] of_platform_bus_create+0x294/0x35c -[ 0.032669] of_platform_populate+0x5c/0x150 -[ 0.032672] of_platform_default_populate_init+0xd0/0xec -[ 0.032697] do_one_initcall+0x4c/0x2e0 -[ 0.032701] do_initcalls+0x100/0x13c -[ 0.032707] kernel_init_freeable+0x1c8/0x21c -[ 0.032712] kernel_init+0x28/0x140 -[ 0.032731] ret_from_fork+0x10/0x20 -[ 0.032735] ---[ end trace 0000000000000000 ]--- - -In Linux, a check is applied to every device which is exposed through -device-tree node. The warning message is raised when the device isn't -DMA coherent and the cache line size is larger than ARCH_DMA_MINALIGN -(128 bytes). The cache line is sorted from CTR_EL0[CWG], which corresponds -to 256 bytes on the guest CPUs. The DMA coherent capability is claimed -through 'dma-coherent' in their device-tree nodes or parent nodes. -This happens even when the device doesn't implement or use DMA at all, -for legacy reasons. - -Fix the issue by adding 'dma-coherent' property to the device-tree root -node, meaning all devices are capable of DMA coherent by default. -This both suppresses the spurious kernel warnings and also guards -against possible future QEMU bugs where we add a DMA-capable device -and forget to mark it as dma-coherent. - -Signed-off-by: Zhenyu Zhang -Reviewed-by: Gavin Shan -Reviewed-by: Donald Dutile -Message-id: 20240612020506.307793-1-zhenyzha@redhat.com -[PMM: tweaked commit message] -Signed-off-by: Peter Maydell -(cherry picked from commit dda533087ad5559674ff486e7031c88dc01e0abd) -Signed-off-by: Zhenyu Zhang ---- - hw/arm/virt.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 3f0496cdb9..6ece67f11d 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -330,6 +330,17 @@ static void create_fdt(VirtMachineState *vms) - qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); - qemu_fdt_setprop_string(fdt, "/", "model", "linux,dummy-virt"); - -+ /* -+ * For QEMU, all DMA is coherent. Advertising this in the root node -+ * has two benefits: -+ * -+ * - It avoids potential bugs where we forget to mark a DMA -+ * capable device as being dma-coherent -+ * - It avoids spurious warnings from the Linux kernel about -+ * devices which can't do DMA at all -+ */ -+ qemu_fdt_setprop(fdt, "/", "dma-coherent", NULL, 0); -+ - /* /chosen must exist for load_dtb to fill in necessary properties later */ - qemu_fdt_add_subnode(fdt, "/chosen"); - if (vms->dtb_randomness) { --- -2.39.3 - diff --git a/SOURCES/kvm-hw-arm-virt-Fix-spurious-call-to-arm_virt_compat_set.patch b/SOURCES/kvm-hw-arm-virt-Fix-spurious-call-to-arm_virt_compat_set.patch deleted file mode 100644 index 8128a4e..0000000 --- a/SOURCES/kvm-hw-arm-virt-Fix-spurious-call-to-arm_virt_compat_set.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e3360c415f7de923d27c3167260a93cb679afabe Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Mon, 6 May 2024 15:09:43 +0200 -Subject: [PATCH 1/2] hw/arm/virt: Fix spurious call to arm_virt_compat_set() - -RH-Author: Eric Auger -RH-MergeRequest: 238: hw/arm/virt: Fix spurious call to arm_virt_compat_set() -RH-Jira: RHEL-34945 -RH-Acked-by: Miroslav Rezanina -RH-Acked-by: Cornelia Huck -RH-Acked-by: Gavin Shan -RH-Commit: [1/1] a858a3e1dff12b28e14f7e4bd2b896a9f06eacbb (eauger1/centos-qemu-kvm) - -JIRA: https://issues.redhat.com/browse/RHEL-34945 -Status: RHEL-only - -Downstream, we apply arm_rhel_compat in place of arm_virt_compat. -This is done though arm_rhel_compat_set() transparently called in -DEFINE_RHEL_MACHINE_LATEST(). So there is no need to call -arm_virt_compat_set() in rhel_machine_class_init(). Besides -this triggers a "GLib: g_ptr_array_add: assertion 'rarray' failed" -warning. - -Signed-off-by: Eric Auger ---- - hw/arm/virt.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index f1af9495c6..3f0496cdb9 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -85,6 +85,7 @@ - #include "hw/char/pl011.h" - #include "qemu/guest-random.h" - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static GlobalProperty arm_virt_compat[] = { - { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" }, - }; -@@ -101,7 +102,6 @@ static void arm_virt_compat_set(MachineClass *mc) - arm_virt_compat_len); - } - --#if 0 /* Disabled for Red Hat Enterprise Linux */ - #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ - static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ - void *data) \ -@@ -3536,7 +3536,6 @@ static void rhel_machine_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); -- arm_virt_compat_set(mc); - - mc->family = "virt-rhel-Z"; - mc->init = machvirt_init; --- -2.39.3 - diff --git a/SOURCES/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch b/SOURCES/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch new file mode 100644 index 0000000..0ab609d --- /dev/null +++ b/SOURCES/kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch @@ -0,0 +1,69 @@ +From 6aa786b145f484ed6e2e8a1a5089ad6e150306a8 Mon Sep 17 00:00:00 2001 +From: Sana Sharm +Date: Fri, 3 Jan 2025 13:27:20 -0500 +Subject: [PATCH 19/19] hw/char/pl011: Use correct masks for IBRD and FBRD +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: sansshar +RH-MergeRequest: 310: hw/char/pl011: Use correct masks for IBRD and FBRD +RH-Jira: RHEL-67107 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 4c7174da1dff8de3d7e2d88d84973eb69d6fc28a (sansshar/qemu-kvm-centos) + +Brew build id: 5098441 + +In commit b88cfee90268cad we defined masks for the IBRD and FBRD +integer and fractional baud rate divider registers, to prevent the +guest from writing invalid values which could cause division-by-zero. +Unfortunately we got the mask values the wrong way around: the FBRD +register is six bits and the IBRD register is 16 bits, not +vice-versa. + +You would only run into this bug if you programmed the UART to a baud +rate of less than 9600, because for 9600 baud and above the IBRD +value will fit into 6 bits, as per the table in + https://developer.arm.com/documentation/ddi0183/g/programmers-model/register-descriptions/fractional-baud-rate-register--uartfbrd + +The only visible effects would be that the value read back from +the register by the guest would be truncated, and we would +print an incorrect baud rate in the debug logs. + +Cc: qemu-stable@nongnu.org +Fixes: b88cfee90268 ("hw/char/pl011: Avoid division-by-zero in pl011_get_baudrate()") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2610 +Signed-off-by: Peter Maydell +Reviewed-by: Alex Bennée +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Gavin Shan +Message-id: 20241007144732.2491331-1-peter.maydell@linaro.org +(cherry picked from commit cd247eae16ab1b9ce97fd34c000c1b883feeda45) +Signed-off-by: Sana Sharma + + Changes to be committed: + modified: hw/char/pl011.c +--- + hw/char/pl011.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/char/pl011.c b/hw/char/pl011.c +index f8078aa216..949e9d0e0d 100644 +--- a/hw/char/pl011.c ++++ b/hw/char/pl011.c +@@ -88,10 +88,10 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr) + #define CR_LBE (1 << 7) + + /* Integer Baud Rate Divider, UARTIBRD */ +-#define IBRD_MASK 0x3f ++#define IBRD_MASK 0xffff + + /* Fractional Baud Rate Divider, UARTFBRD */ +-#define FBRD_MASK 0xffff ++#define FBRD_MASK 0x3f + + static const unsigned char pl011_id_arm[8] = + { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-i386-Add-support-for-loading-BIOS-using-guest_mem.patch b/SOURCES/kvm-hw-i386-Add-support-for-loading-BIOS-using-guest_mem.patch deleted file mode 100644 index ee2f88e..0000000 --- a/SOURCES/kvm-hw-i386-Add-support-for-loading-BIOS-using-guest_mem.patch +++ /dev/null @@ -1,73 +0,0 @@ -From e74980be81d641736ea9d44d0fe9af02af63a220 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:40 -0500 -Subject: [PATCH 083/100] hw/i386: Add support for loading BIOS using - guest_memfd - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [83/91] 7b77d212ef7d83b66ad9d8348179ee84e64fb911 (bonzini/rhel-qemu-kvm) - -When guest_memfd is enabled, the BIOS is generally part of the initial -encrypted guest image and will be accessed as private guest memory. Add -the necessary changes to set up the associated RAM region with a -guest_memfd backend to allow for this. - -Current support centers around using -bios to load the BIOS data. -Support for loading the BIOS via pflash requires additional enablement -since those interfaces rely on the use of ROM memory regions which make -use of the KVM_MEM_READONLY memslot flag, which is not supported for -guest_memfd-backed memslots. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-29-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit fc7a69e177e4ba26d11fcf47b853f85115b35a11) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86-common.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - -diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c -index 35fe6eabea..6cbb76c25c 100644 ---- a/hw/i386/x86-common.c -+++ b/hw/i386/x86-common.c -@@ -969,8 +969,13 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - (bios_size % 65536) != 0) { - goto bios_error; - } -- memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, -- &error_fatal); -+ if (machine_require_guest_memfd(MACHINE(x86ms))) { -+ memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios", -+ bios_size, &error_fatal); -+ } else { -+ memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", -+ bios_size, &error_fatal); -+ } - if (sev_enabled()) { - /* - * The concept of a "reset" simply doesn't exist for -@@ -991,9 +996,11 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - } - g_free(filename); - -- /* map the last 128KB of the BIOS in ISA space */ -- x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, -- !isapc_ram_fw); -+ if (!machine_require_guest_memfd(MACHINE(x86ms))) { -+ /* map the last 128KB of the BIOS in ISA space */ -+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, -+ !isapc_ram_fw); -+ } - - /* map all the bios at the top of memory */ - memory_region_add_subregion(rom_memory, --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-Have-x86_bios_rom_init-take-X86MachineState-.patch b/SOURCES/kvm-hw-i386-Have-x86_bios_rom_init-take-X86MachineState-.patch deleted file mode 100644 index 1fafe03..0000000 --- a/SOURCES/kvm-hw-i386-Have-x86_bios_rom_init-take-X86MachineState-.patch +++ /dev/null @@ -1,106 +0,0 @@ -From c1e615d6b8f609b72a94ffe6d31a9848a41744ef Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Tue, 30 Apr 2024 17:06:39 +0200 -Subject: [PATCH 038/100] hw/i386: Have x86_bios_rom_init() take - X86MachineState rather than MachineState -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [38/91] 59f388b1dffc5d0aa2f0fff768194d755bc3efbb (bonzini/rhel-qemu-kvm) - -The function creates and leaks two MemoryRegion objects regarding the BIOS which -will be moved into X86MachineState in the next steps to avoid the leakage. - -Signed-off-by: Bernhard Beschow -Reviewed-by: Philippe Mathieu-Daudé -Message-ID: <20240430150643.111976-3-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit 848351840148f8c3b53ddf6210194506547d3ffd) -Signed-off-by: Paolo Bonzini ---- - hw/i386/microvm.c | 2 +- - hw/i386/pc_sysfw.c | 4 ++-- - hw/i386/x86.c | 4 ++-- - include/hw/i386/x86.h | 2 +- - 4 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c -index 61a772dfe6..fec63cacfa 100644 ---- a/hw/i386/microvm.c -+++ b/hw/i386/microvm.c -@@ -278,7 +278,7 @@ static void microvm_devices_init(MicrovmMachineState *mms) - default_firmware = x86_machine_is_acpi_enabled(x86ms) - ? MICROVM_BIOS_FILENAME - : MICROVM_QBOOT_FILENAME; -- x86_bios_rom_init(MACHINE(mms), default_firmware, get_system_memory(), true); -+ x86_bios_rom_init(x86ms, default_firmware, get_system_memory(), true); - } - - static void microvm_memory_init(MicrovmMachineState *mms) -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index 3efabbbab2..ef7dea9798 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -206,7 +206,7 @@ void pc_system_firmware_init(PCMachineState *pcms, - BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)]; - - if (!pcmc->pci_enabled) { -- x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, true); -+ x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, true); - return; - } - -@@ -227,7 +227,7 @@ void pc_system_firmware_init(PCMachineState *pcms, - - if (!pflash_blk[0]) { - /* Machine property pflash0 not set, use ROM mode */ -- x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, false); -+ x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, false); - } else { - if (kvm_enabled() && !kvm_readonly_mem_enabled()) { - /* -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 2a4f3ee285..6d3c72f124 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1128,7 +1128,7 @@ void x86_load_linux(X86MachineState *x86ms, - nb_option_roms++; - } - --void x86_bios_rom_init(MachineState *ms, const char *default_firmware, -+void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - MemoryRegion *rom_memory, bool isapc_ram_fw) - { - const char *bios_name; -@@ -1138,7 +1138,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, - ssize_t ret; - - /* BIOS load */ -- bios_name = ms->firmware ?: default_firmware; -+ bios_name = MACHINE(x86ms)->firmware ?: default_firmware; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - if (filename) { - bios_size = get_image_size(filename); -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index 4dc30dcb4d..cb07618d19 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -116,7 +116,7 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, - void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp); - --void x86_bios_rom_init(MachineState *ms, const char *default_firmware, -+void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - MemoryRegion *rom_memory, bool isapc_ram_fw); - - void x86_load_linux(X86MachineState *x86ms, --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-acpi-Set-PCAT_COMPAT-bit-only-when-pic-is-no.patch b/SOURCES/kvm-hw-i386-acpi-Set-PCAT_COMPAT-bit-only-when-pic-is-no.patch deleted file mode 100644 index a789fb7..0000000 --- a/SOURCES/kvm-hw-i386-acpi-Set-PCAT_COMPAT-bit-only-when-pic-is-no.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 7bb1f124413891bc5d2187f12cd19da6e794904b Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 3 Apr 2024 10:59:53 -0400 -Subject: [PATCH 010/100] hw/i386/acpi: Set PCAT_COMPAT bit only when pic is - not disabled - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [10/91] 62110e4bf52cb3e106c8d2a902bbd31548beba00 (bonzini/rhel-qemu-kvm) - -A value 1 of PCAT_COMPAT (bit 0) of MADT.Flags indicates that the system -also has a PC-AT-compatible dual-8259 setup, i.e., the PIC. When PIC -is not enabled (pic=off) for x86 machine, the PCAT_COMPAT bit needs to -be cleared. The PIC probe should then print: - - [ 0.155970] Using NULL legacy PIC - -However, no such log printed in guest kernel unless PCAT_COMPAT is -cleared. - -Signed-off-by: Xiaoyao Li -Message-ID: <20240403145953.3082491-1-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 292dd287e78e0cbafde9d1522c729349d132d844) -Signed-off-by: Paolo Bonzini ---- - hw/i386/acpi-common.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c -index 20f19269da..0cc2919bb8 100644 ---- a/hw/i386/acpi-common.c -+++ b/hw/i386/acpi-common.c -@@ -107,7 +107,9 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker, - acpi_table_begin(&table, table_data); - /* Local APIC Address */ - build_append_int_noprefix(table_data, APIC_DEFAULT_ADDRESS, 4); -- build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ -+ /* Flags. bit 0: PCAT_COMPAT */ -+ build_append_int_noprefix(table_data, -+ x86ms->pic != ON_OFF_AUTO_OFF ? 1 : 0 , 4); - - for (i = 0; i < apic_ids->len; i++) { - pc_madt_cpu_entry(i, apic_ids, table_data, false); --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-pc_sysfw-Alias-rather-than-copy-isa-bios-reg.patch b/SOURCES/kvm-hw-i386-pc_sysfw-Alias-rather-than-copy-isa-bios-reg.patch deleted file mode 100644 index 021db3d..0000000 --- a/SOURCES/kvm-hw-i386-pc_sysfw-Alias-rather-than-copy-isa-bios-reg.patch +++ /dev/null @@ -1,164 +0,0 @@ -From fd6de3c5e97bdf13a39342fc71815a20c66867ae Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Wed, 8 May 2024 19:55:07 +0200 -Subject: [PATCH 043/100] hw/i386/pc_sysfw: Alias rather than copy isa-bios - region - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [43/91] f64dab2a091838a10a9b94e3d09ea11432b0809f (bonzini/rhel-qemu-kvm) - -In the -bios case the "isa-bios" memory region is an alias to the BIOS mapped -to the top of the 4G memory boundary. Do the same in the -pflash case, but only -for new machine versions for migration compatibility. This establishes common -behavior and makes pflash commands work in the "isa-bios" region which some -real-world legacy bioses rely on. - -Note that in the sev_enabled() case, the "isa-bios" memory region in the -pflash -case will now also point to encrypted memory, just like it already does in the --bios case. - -When running `info mtree` before and after this commit with -`qemu-system-x86_64 -S -drive \ -if=pflash,format=raw,readonly=on,file=/usr/share/qemu/bios-256k.bin` and running -`diff -u before.mtree after.mtree` results in the following changes in the -memory tree: - -| --- before.mtree -| +++ after.mtree -| @@ -71,7 +71,7 @@ -| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci -| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem -| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom -| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios -| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff -| 00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff -| 00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff -| 00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff -| @@ -108,7 +108,7 @@ -| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci -| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem -| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom -| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios -| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff -| 00000000000a0000-00000000000bffff (prio 1, i/o): alias smram-region @pci 00000000000a0000-00000000000bffff -| 00000000000c0000-00000000000c3fff (prio 1, i/o): alias pam-pci @pci 00000000000c0000-00000000000c3fff -| 00000000000c4000-00000000000c7fff (prio 1, i/o): alias pam-pci @pci 00000000000c4000-00000000000c7fff -| @@ -131,11 +131,14 @@ -| memory-region: pc.ram -| 0000000000000000-0000000007ffffff (prio 0, ram): pc.ram -| -| +memory-region: system.flash0 -| + 00000000fffc0000-00000000ffffffff (prio 0, romd): system.flash0 -| + -| memory-region: pci -| 0000000000000000-ffffffffffffffff (prio -1, i/o): pci -| 00000000000a0000-00000000000bffff (prio 1, i/o): vga-lowmem -| 00000000000c0000-00000000000dffff (prio 1, rom): pc.rom -| - 00000000000e0000-00000000000fffff (prio 1, rom): isa-bios -| + 00000000000e0000-00000000000fffff (prio 1, romd): alias isa-bios @system.flash0 0000000000020000-000000000003ffff -| -| memory-region: smram -| 00000000000a0000-00000000000bffff (prio 0, ram): alias smram-low @pc.ram 00000000000a0000-00000000000bffff - -Note that in both cases the "system" memory region contains the entry - - 00000000fffc0000-00000000ffffffff (prio 0, romd): system.flash0 - -but the "system.flash0" memory region only appears standalone when "isa-bios" is -an alias. - -Signed-off-by: Bernhard Beschow -Message-ID: <20240508175507.22270-7-shentey@gmail.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit a44ea3fa7f2aa1d809fdca1b84a52695b53d8ad0) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 1 + - hw/i386/pc_piix.c | 1 + - hw/i386/pc_q35.c | 1 + - hw/i386/pc_sysfw.c | 8 +++++++- - include/hw/i386/pc.h | 1 + - 5 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 1a34bc4522..660a59c63b 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -1967,6 +1967,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - pcmc->has_reserved_memory = true; - pcmc->enforce_aligned_dimm = true; - pcmc->enforce_amd_1tb_hole = true; -+ pcmc->isa_bios_alias = true; - /* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported - * to be used at the moment, 32K should be enough for a while. */ - pcmc->acpi_data_size = 0x20000 + 0x8000; -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index bef3e8b73e..dbb7f2ed17 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -975,6 +975,7 @@ static void pc_machine_rhel7_options(MachineClass *m) - m->alias = "pc"; - m->is_default = 1; - m->smp_props.prefer_sockets = true; -+ pcmc->isa_bios_alias = false; - } - - static void pc_init_rhel760(MachineState *machine) -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index dedc86eec9..f9900ad798 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -735,6 +735,7 @@ static void pc_q35_machine_rhel940_options(MachineClass *m) - m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.4.0"; -+ pcmc->isa_bios_alias = false; - - compat_props_add(m->compat_props, pc_rhel_9_5_compat, - pc_rhel_9_5_compat_len); -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index 82d37cb376..ac88ad4eb9 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -135,6 +135,7 @@ static void pc_system_flash_map(PCMachineState *pcms, - MemoryRegion *rom_memory) - { - X86MachineState *x86ms = X86_MACHINE(pcms); -+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); - hwaddr total_size = 0; - int i; - BlockBackend *blk; -@@ -184,7 +185,12 @@ static void pc_system_flash_map(PCMachineState *pcms, - - if (i == 0) { - flash_mem = pflash_cfi01_get_memory(system_flash); -- pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem); -+ if (pcmc->isa_bios_alias) { -+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem, -+ true); -+ } else { -+ pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem); -+ } - - /* Encrypt the pflash boot ROM */ - if (sev_enabled()) { -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 467e7fb52f..3f53ec73ac 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -122,6 +122,7 @@ struct PCMachineClass { - bool enforce_aligned_dimm; - bool broken_reserved_end; - bool enforce_amd_1tb_hole; -+ bool isa_bios_alias; - - /* generate legacy CPU hotplug AML */ - bool legacy_cpu_hotplug; --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-pc_sysfw-Remove-unused-parameter-from-pc_isa.patch b/SOURCES/kvm-hw-i386-pc_sysfw-Remove-unused-parameter-from-pc_isa.patch deleted file mode 100644 index 4188fd3..0000000 --- a/SOURCES/kvm-hw-i386-pc_sysfw-Remove-unused-parameter-from-pc_isa.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 9bf1d368c4b53139db39649833d475e097fc98d1 Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Mon, 22 Apr 2024 22:06:22 +0200 -Subject: [PATCH 039/100] hw/i386/pc_sysfw: Remove unused parameter from - pc_isa_bios_init() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [39/91] c0019dc2706a8e3f40486fd4a4c0dd1fbe23237b (bonzini/rhel-qemu-kvm) - -Signed-off-by: Bernhard Beschow -Reviewed-by: Philippe Mathieu-Daudé -Message-ID: <20240422200625.2768-2-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit f4b63768b91811cdcf1fb7b270587123251dfea5) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc_sysfw.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index ef7dea9798..59c7a81692 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -41,8 +41,7 @@ - #define FLASH_SECTOR_SIZE 4096 - - static void pc_isa_bios_init(MemoryRegion *rom_memory, -- MemoryRegion *flash_mem, -- int ram_size) -+ MemoryRegion *flash_mem) - { - int isa_bios_size; - MemoryRegion *isa_bios; -@@ -186,7 +185,7 @@ static void pc_system_flash_map(PCMachineState *pcms, - - if (i == 0) { - flash_mem = pflash_cfi01_get_memory(system_flash); -- pc_isa_bios_init(rom_memory, flash_mem, size); -+ pc_isa_bios_init(rom_memory, flash_mem); - - /* Encrypt the pflash boot ROM */ - if (sev_enabled()) { --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-sev-Add-function-to-get-SEV-metadata-from-OV.patch b/SOURCES/kvm-hw-i386-sev-Add-function-to-get-SEV-metadata-from-OV.patch deleted file mode 100644 index a543c79..0000000 --- a/SOURCES/kvm-hw-i386-sev-Add-function-to-get-SEV-metadata-from-OV.patch +++ /dev/null @@ -1,158 +0,0 @@ -From e6472ff46cbed97c2a238a8ef7d321351931333a Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:30 -0500 -Subject: [PATCH 070/100] hw/i386/sev: Add function to get SEV metadata from - OVMF header - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [70/91] ba818dade96119c8a51ca1fb222f4f69e2752396 (bonzini/rhel-qemu-kvm) - -A recent version of OVMF expanded the reset vector GUID list to add -SEV-specific metadata GUID. The SEV metadata describes the reserved -memory regions such as the secrets and CPUID page used during the SEV-SNP -guest launch. - -The pc_system_get_ovmf_sev_metadata_ptr() is used to retieve the SEV -metadata pointer from the OVMF GUID list. - -Signed-off-by: Brijesh Singh -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-19-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit f3c30c575d34122573b7370a7da5ca3a27dde481) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc_sysfw.c | 4 ++++ - include/hw/i386/pc.h | 26 ++++++++++++++++++++++++++ - target/i386/sev-sysemu-stub.c | 4 ++++ - target/i386/sev.c | 32 ++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 ++ - 5 files changed, 68 insertions(+) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index ac88ad4eb9..9b8671c441 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -260,6 +260,10 @@ void x86_firmware_configure(void *ptr, int size) - pc_system_parse_ovmf_flash(ptr, size); - - if (sev_enabled()) { -+ -+ /* Copy the SEV metadata table (if it exists) */ -+ pc_system_parse_sev_metadata(ptr, size); -+ - ret = sev_es_save_reset_vector(ptr, size); - if (ret) { - error_report("failed to locate and/or save reset vector"); -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 3f53ec73ac..94b49310f5 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -167,6 +167,32 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level); - #define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size" - #define PCI_HOST_PROP_SMM_RANGES "smm-ranges" - -+typedef enum { -+ SEV_DESC_TYPE_UNDEF, -+ /* The section contains the region that must be validated by the VMM. */ -+ SEV_DESC_TYPE_SNP_SEC_MEM, -+ /* The section contains the SNP secrets page */ -+ SEV_DESC_TYPE_SNP_SECRETS, -+ /* The section contains address that can be used as a CPUID page */ -+ SEV_DESC_TYPE_CPUID, -+ -+} ovmf_sev_metadata_desc_type; -+ -+typedef struct __attribute__((__packed__)) OvmfSevMetadataDesc { -+ uint32_t base; -+ uint32_t len; -+ ovmf_sev_metadata_desc_type type; -+} OvmfSevMetadataDesc; -+ -+typedef struct __attribute__((__packed__)) OvmfSevMetadata { -+ uint8_t signature[4]; -+ uint32_t len; -+ uint32_t version; -+ uint32_t num_desc; -+ OvmfSevMetadataDesc descs[]; -+} OvmfSevMetadata; -+ -+OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void); - - void pc_pci_as_mapping_init(MemoryRegion *system_memory, - MemoryRegion *pci_address_space); -diff --git a/target/i386/sev-sysemu-stub.c b/target/i386/sev-sysemu-stub.c -index 96e1c15cc3..fc1c57c411 100644 ---- a/target/i386/sev-sysemu-stub.c -+++ b/target/i386/sev-sysemu-stub.c -@@ -67,3 +67,7 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict) - { - monitor_printf(mon, "SEV is not available in this QEMU\n"); - } -+ -+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size) -+{ -+} -diff --git a/target/i386/sev.c b/target/i386/sev.c -index e84e4395a5..17281bb2c7 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -597,6 +597,38 @@ SevCapability *qmp_query_sev_capabilities(Error **errp) - return sev_get_capabilities(errp); - } - -+static OvmfSevMetadata *ovmf_sev_metadata_table; -+ -+#define OVMF_SEV_META_DATA_GUID "dc886566-984a-4798-A75e-5585a7bf67cc" -+typedef struct __attribute__((__packed__)) OvmfSevMetadataOffset { -+ uint32_t offset; -+} OvmfSevMetadataOffset; -+ -+OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void) -+{ -+ return ovmf_sev_metadata_table; -+} -+ -+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size) -+{ -+ OvmfSevMetadata *metadata; -+ OvmfSevMetadataOffset *data; -+ -+ if (!pc_system_ovmf_table_find(OVMF_SEV_META_DATA_GUID, (uint8_t **)&data, -+ NULL)) { -+ return; -+ } -+ -+ metadata = (OvmfSevMetadata *)(flash_ptr + flash_size - data->offset); -+ if (memcmp(metadata->signature, "ASEV", 4) != 0 || -+ metadata->len < sizeof(OvmfSevMetadata) || -+ metadata->len > flash_size - data->offset) { -+ return; -+ } -+ -+ ovmf_sev_metadata_table = g_memdup2(metadata, metadata->len); -+} -+ - static SevAttestationReport *sev_get_attestation_report(const char *mnonce, - Error **errp) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 5dc4767b1e..cc12824dd6 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -66,4 +66,6 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, - int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size); - void sev_es_set_reset_vector(CPUState *cpu); - -+void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size); -+ - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-sev-Add-support-to-encrypt-BIOS-when-SEV-SNP.patch b/SOURCES/kvm-hw-i386-sev-Add-support-to-encrypt-BIOS-when-SEV-SNP.patch deleted file mode 100644 index c5a7a28..0000000 --- a/SOURCES/kvm-hw-i386-sev-Add-support-to-encrypt-BIOS-when-SEV-SNP.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 226cf6c3d3e2fd1a35422043dbe0b73d1216df83 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:36 -0500 -Subject: [PATCH 073/100] hw/i386/sev: Add support to encrypt BIOS when SEV-SNP - is enabled - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [73/91] 844afd322c12c3e8992cf6ec692c94e70747bd0c (bonzini/rhel-qemu-kvm) - -As with SEV, an SNP guest requires that the BIOS be part of the initial -encrypted/measured guest payload. Extend sev_encrypt_flash() to handle -the SNP case and plumb through the GPA of the BIOS location since this -is needed for SNP. - -Signed-off-by: Brijesh Singh -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-25-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 77d1abd91e5352ad30ae2f83790f95fa6a3c0b6b) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc_sysfw.c | 12 +++++++----- - hw/i386/x86-common.c | 2 +- - include/hw/i386/x86.h | 2 +- - target/i386/sev-sysemu-stub.c | 2 +- - target/i386/sev.c | 5 +++-- - target/i386/sev.h | 2 +- - 6 files changed, 14 insertions(+), 11 deletions(-) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index 9b8671c441..7cdbafc8d2 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -148,6 +148,8 @@ static void pc_system_flash_map(PCMachineState *pcms, - assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled); - - for (i = 0; i < ARRAY_SIZE(pcms->flash); i++) { -+ hwaddr gpa; -+ - system_flash = pcms->flash[i]; - blk = pflash_cfi01_get_blk(system_flash); - if (!blk) { -@@ -177,11 +179,11 @@ static void pc_system_flash_map(PCMachineState *pcms, - } - - total_size += size; -+ gpa = 0x100000000ULL - total_size; /* where the flash is mapped */ - qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks", - size / FLASH_SECTOR_SIZE); - sysbus_realize_and_unref(SYS_BUS_DEVICE(system_flash), &error_fatal); -- sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, -- 0x100000000ULL - total_size); -+ sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0, gpa); - - if (i == 0) { - flash_mem = pflash_cfi01_get_memory(system_flash); -@@ -196,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms, - if (sev_enabled()) { - flash_ptr = memory_region_get_ram_ptr(flash_mem); - flash_size = memory_region_size(flash_mem); -- x86_firmware_configure(flash_ptr, flash_size); -+ x86_firmware_configure(gpa, flash_ptr, flash_size); - } - } - } -@@ -249,7 +251,7 @@ void pc_system_firmware_init(PCMachineState *pcms, - pc_system_flash_cleanup_unused(pcms); - } - --void x86_firmware_configure(void *ptr, int size) -+void x86_firmware_configure(hwaddr gpa, void *ptr, int size) - { - int ret; - -@@ -270,6 +272,6 @@ void x86_firmware_configure(void *ptr, int size) - exit(1); - } - -- sev_encrypt_flash(ptr, size, &error_fatal); -+ sev_encrypt_flash(gpa, ptr, size, &error_fatal); - } - } -diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c -index 67b03c913a..35fe6eabea 100644 ---- a/hw/i386/x86-common.c -+++ b/hw/i386/x86-common.c -@@ -981,7 +981,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - */ - void *ptr = memory_region_get_ram_ptr(&x86ms->bios); - load_image_size(filename, ptr, bios_size); -- x86_firmware_configure(ptr, bios_size); -+ x86_firmware_configure(0x100000000ULL - bios_size, ptr, bios_size); - } else { - memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw); - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index b006f16b8d..d43cb3908e 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -154,6 +154,6 @@ void ioapic_init_gsi(GSIState *gsi_state, Object *parent); - DeviceState *ioapic_init_secondary(GSIState *gsi_state); - - /* pc_sysfw.c */ --void x86_firmware_configure(void *ptr, int size); -+void x86_firmware_configure(hwaddr gpa, void *ptr, int size); - - #endif -diff --git a/target/i386/sev-sysemu-stub.c b/target/i386/sev-sysemu-stub.c -index fc1c57c411..d5bf886e79 100644 ---- a/target/i386/sev-sysemu-stub.c -+++ b/target/i386/sev-sysemu-stub.c -@@ -42,7 +42,7 @@ void qmp_sev_inject_launch_secret(const char *packet_header, const char *secret, - error_setg(errp, "SEV is not available in this QEMU"); - } - --int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) -+int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - g_assert_not_reached(); - } -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 06401f0526..7b5c4b4874 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1484,7 +1484,7 @@ static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - int --sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) -+sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - -@@ -1841,7 +1841,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - /* zero the excess data so the measurement can be reliably calculated */ - memset(padded_ht->padding, 0, sizeof(padded_ht->padding)); - -- if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { -+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht, -+ sizeof(*padded_ht), errp) < 0) { - ret = false; - } - -diff --git a/target/i386/sev.h b/target/i386/sev.h -index cc12824dd6..858005a119 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -59,7 +59,7 @@ uint32_t sev_get_cbit_position(void); - uint32_t sev_get_reduced_phys_bits(void); - bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); - --int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); -+int sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-sev-Use-guest_memfd-for-legacy-ROMs.patch b/SOURCES/kvm-hw-i386-sev-Use-guest_memfd-for-legacy-ROMs.patch deleted file mode 100644 index 050a522..0000000 --- a/SOURCES/kvm-hw-i386-sev-Use-guest_memfd-for-legacy-ROMs.patch +++ /dev/null @@ -1,123 +0,0 @@ -From a20b2e3e52b9589ac1abc8b9b818d526c86368cf Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:39 -0500 -Subject: [PATCH 082/100] hw/i386/sev: Use guest_memfd for legacy ROMs - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [82/91] a591e85e00c353009803b143c80852b8c9b1f15e (bonzini/rhel-qemu-kvm) - -Current SNP guest kernels will attempt to access these regions with -with C-bit set, so guest_memfd is needed to handle that. Otherwise, -kvm_convert_memory() will fail when the guest kernel tries to access it -and QEMU attempts to call KVM_SET_MEMORY_ATTRIBUTES to set these ranges -to private. - -Whether guests should actually try to access ROM regions in this way (or -need to deal with legacy ROM regions at all), is a separate issue to be -addressed on kernel side, but current SNP guest kernels will exhibit -this behavior and so this handling is needed to allow QEMU to continue -running existing SNP guest kernels. - -Signed-off-by: Michael Roth -[pankaj: Added sev_snp_enabled() check] -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-28-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 413a67450750e0459efeffc3db3ba9759c3e381c) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 14 ++++++++++---- - hw/i386/pc_sysfw.c | 19 +++++++++++++------ - 2 files changed, 23 insertions(+), 10 deletions(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 0aca0cc79e..b25d075b59 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -62,6 +62,7 @@ - #include "hw/mem/memory-device.h" - #include "e820_memory_layout.h" - #include "trace.h" -+#include "sev.h" - #include CONFIG_DEVICES - - #ifdef CONFIG_XEN_EMU -@@ -1173,10 +1174,15 @@ void pc_memory_init(PCMachineState *pcms, - pc_system_firmware_init(pcms, rom_memory); - - option_rom_mr = g_malloc(sizeof(*option_rom_mr)); -- memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, -- &error_fatal); -- if (pcmc->pci_enabled) { -- memory_region_set_readonly(option_rom_mr, true); -+ if (machine_require_guest_memfd(machine)) { -+ memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom", -+ PC_ROM_SIZE, &error_fatal); -+ } else { -+ memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, -+ &error_fatal); -+ if (pcmc->pci_enabled) { -+ memory_region_set_readonly(option_rom_mr, true); -+ } - } - memory_region_add_subregion_overlap(rom_memory, - PC_ROM_MIN_VGA, -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index 7cdbafc8d2..ef80281d28 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -40,8 +40,8 @@ - - #define FLASH_SECTOR_SIZE 4096 - --static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory, -- MemoryRegion *flash_mem) -+static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios, -+ MemoryRegion *rom_memory, MemoryRegion *flash_mem) - { - int isa_bios_size; - uint64_t flash_size; -@@ -51,8 +51,13 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory, - - /* map the last 128KB of the BIOS in ISA space */ - isa_bios_size = MIN(flash_size, 128 * KiB); -- memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size, -- &error_fatal); -+ if (machine_require_guest_memfd(MACHINE(pcms))) { -+ memory_region_init_ram_guest_memfd(isa_bios, NULL, "isa-bios", -+ isa_bios_size, &error_fatal); -+ } else { -+ memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size, -+ &error_fatal); -+ } - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, - isa_bios, -@@ -65,7 +70,9 @@ static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory, - ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size), - isa_bios_size); - -- memory_region_set_readonly(isa_bios, true); -+ if (!machine_require_guest_memfd(current_machine)) { -+ memory_region_set_readonly(isa_bios, true); -+ } - } - - static PFlashCFI01 *pc_pflash_create(PCMachineState *pcms, -@@ -191,7 +198,7 @@ static void pc_system_flash_map(PCMachineState *pcms, - x86_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem, - true); - } else { -- pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem); -+ pc_isa_bios_init(pcms, &x86ms->isa_bios, rom_memory, flash_mem); - } - - /* Encrypt the pflash boot ROM */ --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-sev-Use-legacy-SEV-VM-types-for-older-machin.patch b/SOURCES/kvm-hw-i386-sev-Use-legacy-SEV-VM-types-for-older-machin.patch deleted file mode 100644 index 7b03cb4..0000000 --- a/SOURCES/kvm-hw-i386-sev-Use-legacy-SEV-VM-types-for-older-machin.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 4331180aa09e44550ff8de781c618bae5e99bb70 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Tue, 9 Apr 2024 18:07:43 -0500 -Subject: [PATCH 025/100] hw/i386/sev: Use legacy SEV VM types for older - machine types - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [25/91] 8c73cd312736ccb0818b4d3216fd13712f21f3c9 (bonzini/rhel-qemu-kvm) - -Newer 9.1 machine types will default to using the KVM_SEV_INIT2 API for -creating SEV/SEV-ES going forward. However, this API results in guest -measurement changes which are generally not expected for users of these -older guest types and can cause disruption if they switch to a newer -QEMU/kernel version. Avoid this by continuing to use the older -KVM_SEV_INIT/KVM_SEV_ES_INIT APIs for older machine types. - -Signed-off-by: Michael Roth -Message-ID: <20240409230743.962513-4-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit ea7fbd37537b3a598335c21ccb2ea674630fc810) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 1 + - target/i386/sev.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index b9fde3cec1..1a34bc4522 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -351,6 +351,7 @@ const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); - GlobalProperty pc_rhel_9_5_compat[] = { - /* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */ - { TYPE_X86_CPU, "guest-phys-bits", "0" }, -+ { "sev-guest", "legacy-vm-type", "true" }, - }; - const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat); - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index f4ee317cb0..d30b68c11e 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1417,6 +1417,7 @@ sev_guest_instance_init(Object *obj) - object_property_add_uint32_ptr(obj, "reduced-phys-bits", - &sev->reduced_phys_bits, - OBJ_PROP_FLAG_READWRITE); -+ object_apply_compat_props(obj); - } - - /* sev guest info */ --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-split-x86.c-in-multiple-parts.patch b/SOURCES/kvm-hw-i386-split-x86.c-in-multiple-parts.patch deleted file mode 100644 index 40ca52b..0000000 --- a/SOURCES/kvm-hw-i386-split-x86.c-in-multiple-parts.patch +++ /dev/null @@ -1,2301 +0,0 @@ -From bf2206fae2e640da9de7fc0648b4b90ad3ddfbe3 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 9 May 2024 19:00:41 +0200 -Subject: [PATCH 046/100] hw/i386: split x86.c in multiple parts - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [46/91] 3d6e8364aa9b691c25bdcf54a30b116da5d33874 (bonzini/rhel-qemu-kvm) - -Keep the basic X86MachineState definition in x86.c. Move out functions that -are only needed by other files: x86-common.c for the pc and microvm machines, -x86-cpu.c for those used by accelerator code. - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Message-ID: <20240509170044.190795-11-pbonzini@redhat.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit b061f0598b9231f7992aff4fcdf3f336f9747d11) -Signed-off-by: Paolo Bonzini ---- - hw/i386/meson.build | 4 +- - hw/i386/x86-common.c | 1007 +++++++++++++++++++++++++++++++++++++++ - hw/i386/x86-cpu.c | 97 ++++ - hw/i386/x86.c | 1052 +---------------------------------------- - include/hw/i386/x86.h | 6 +- - 5 files changed, 1113 insertions(+), 1053 deletions(-) - create mode 100644 hw/i386/x86-common.c - create mode 100644 hw/i386/x86-cpu.c - -diff --git a/hw/i386/meson.build b/hw/i386/meson.build -index d9da676038..3437da0aad 100644 ---- a/hw/i386/meson.build -+++ b/hw/i386/meson.build -@@ -4,6 +4,7 @@ i386_ss.add(files( - 'e820_memory_layout.c', - 'multiboot.c', - 'x86.c', -+ 'x86-cpu.c', - )) - - i386_ss.add(when: 'CONFIG_APIC', if_true: files('vapic.c')) -@@ -12,7 +13,7 @@ i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'), - i386_ss.add(when: 'CONFIG_AMD_IOMMU', if_true: files('amd_iommu.c'), - if_false: files('amd_iommu-stub.c')) - i386_ss.add(when: 'CONFIG_I440FX', if_true: files('pc_piix.c')) --i386_ss.add(when: 'CONFIG_MICROVM', if_true: files('microvm.c', 'acpi-microvm.c', 'microvm-dt.c')) -+i386_ss.add(when: 'CONFIG_MICROVM', if_true: files('x86-common.c', 'microvm.c', 'acpi-microvm.c', 'microvm-dt.c')) - i386_ss.add(when: 'CONFIG_Q35', if_true: files('pc_q35.c')) - i386_ss.add(when: 'CONFIG_VMMOUSE', if_true: files('vmmouse.c')) - i386_ss.add(when: 'CONFIG_VMPORT', if_true: files('vmport.c')) -@@ -22,6 +23,7 @@ i386_ss.add(when: 'CONFIG_SGX', if_true: files('sgx-epc.c','sgx.c'), - - i386_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-common.c')) - i386_ss.add(when: 'CONFIG_PC', if_true: files( -+ 'x86-common.c', - 'pc.c', - 'pc_sysfw.c', - 'acpi-build.c', -diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c -new file mode 100644 -index 0000000000..67b03c913a ---- /dev/null -+++ b/hw/i386/x86-common.c -@@ -0,0 +1,1007 @@ -+/* -+ * Copyright (c) 2003-2004 Fabrice Bellard -+ * Copyright (c) 2019, 2024 Red Hat, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+#include "qemu/osdep.h" -+#include "qemu/error-report.h" -+#include "qemu/cutils.h" -+#include "qemu/units.h" -+#include "qemu/datadir.h" -+#include "qapi/error.h" -+#include "sysemu/numa.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/xen.h" -+#include "trace.h" -+ -+#include "hw/i386/x86.h" -+#include "target/i386/cpu.h" -+#include "hw/rtc/mc146818rtc.h" -+#include "target/i386/sev.h" -+ -+#include "hw/acpi/cpu_hotplug.h" -+#include "hw/irq.h" -+#include "hw/loader.h" -+#include "multiboot.h" -+#include "elf.h" -+#include "standard-headers/asm-x86/bootparam.h" -+#include CONFIG_DEVICES -+#include "kvm/kvm_i386.h" -+ -+#ifdef CONFIG_XEN_EMU -+#include "hw/xen/xen.h" -+#include "hw/i386/kvm/xen_evtchn.h" -+#endif -+ -+/* Physical Address of PVH entry point read from kernel ELF NOTE */ -+static size_t pvh_start_addr; -+ -+static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp) -+{ -+ Object *cpu = object_new(MACHINE(x86ms)->cpu_type); -+ -+ if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) { -+ goto out; -+ } -+ qdev_realize(DEVICE(cpu), NULL, errp); -+ -+out: -+ object_unref(cpu); -+} -+ -+void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) -+{ -+ int i; -+ const CPUArchIdList *possible_cpus; -+ MachineState *ms = MACHINE(x86ms); -+ MachineClass *mc = MACHINE_GET_CLASS(x86ms); -+ -+ x86_cpu_set_default_version(default_cpu_version); -+ -+ /* -+ * Calculates the limit to CPU APIC ID values -+ * -+ * Limit for the APIC ID value, so that all -+ * CPU APIC IDs are < x86ms->apic_id_limit. -+ * -+ * This is used for FW_CFG_MAX_CPUS. See comments on fw_cfg_arch_create(). -+ */ -+ x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms, -+ ms->smp.max_cpus - 1) + 1; -+ -+ /* -+ * Can we support APIC ID 255 or higher? With KVM, that requires -+ * both in-kernel lapic and X2APIC userspace API. -+ * -+ * kvm_enabled() must go first to ensure that kvm_* references are -+ * not emitted for the linker to consume (kvm_enabled() is -+ * a literal `0` in configurations where kvm_* aren't defined) -+ */ -+ if (kvm_enabled() && x86ms->apic_id_limit > 255 && -+ kvm_irqchip_in_kernel() && !kvm_enable_x2apic()) { -+ error_report("current -smp configuration requires kernel " -+ "irqchip and X2APIC API support."); -+ exit(EXIT_FAILURE); -+ } -+ -+ if (kvm_enabled()) { -+ kvm_set_max_apic_id(x86ms->apic_id_limit); -+ } -+ -+ if (!kvm_irqchip_in_kernel()) { -+ apic_set_max_apic_id(x86ms->apic_id_limit); -+ } -+ -+ possible_cpus = mc->possible_cpu_arch_ids(ms); -+ for (i = 0; i < ms->smp.cpus; i++) { -+ x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); -+ } -+} -+ -+void x86_rtc_set_cpus_count(ISADevice *s, uint16_t cpus_count) -+{ -+ MC146818RtcState *rtc = MC146818_RTC(s); -+ -+ if (cpus_count > 0xff) { -+ /* -+ * If the number of CPUs can't be represented in 8 bits, the -+ * BIOS must use "FW_CFG_NB_CPUS". Set RTC field to 0 just -+ * to make old BIOSes fail more predictably. -+ */ -+ mc146818rtc_set_cmos_data(rtc, 0x5f, 0); -+ } else { -+ mc146818rtc_set_cmos_data(rtc, 0x5f, cpus_count - 1); -+ } -+} -+ -+static int x86_apic_cmp(const void *a, const void *b) -+{ -+ CPUArchId *apic_a = (CPUArchId *)a; -+ CPUArchId *apic_b = (CPUArchId *)b; -+ -+ return apic_a->arch_id - apic_b->arch_id; -+} -+ -+/* -+ * returns pointer to CPUArchId descriptor that matches CPU's apic_id -+ * in ms->possible_cpus->cpus, if ms->possible_cpus->cpus has no -+ * entry corresponding to CPU's apic_id returns NULL. -+ */ -+static CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx) -+{ -+ CPUArchId apic_id, *found_cpu; -+ -+ apic_id.arch_id = id; -+ found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, -+ ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), -+ x86_apic_cmp); -+ if (found_cpu && idx) { -+ *idx = found_cpu - ms->possible_cpus->cpus; -+ } -+ return found_cpu; -+} -+ -+void x86_cpu_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ CPUArchId *found_cpu; -+ Error *local_err = NULL; -+ X86CPU *cpu = X86_CPU(dev); -+ X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -+ -+ if (x86ms->acpi_dev) { -+ hotplug_handler_plug(x86ms->acpi_dev, dev, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ } -+ -+ /* increment the number of CPUs */ -+ x86ms->boot_cpus++; -+ if (x86ms->rtc) { -+ x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); -+ } -+ if (x86ms->fw_cfg) { -+ fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -+ } -+ -+ found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL); -+ found_cpu->cpu = CPU(dev); -+out: -+ error_propagate(errp, local_err); -+} -+ -+void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ int idx = -1; -+ X86CPU *cpu = X86_CPU(dev); -+ X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -+ -+ if (!x86ms->acpi_dev) { -+ error_setg(errp, "CPU hot unplug not supported without ACPI"); -+ return; -+ } -+ -+ x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx); -+ assert(idx != -1); -+ if (idx == 0) { -+ error_setg(errp, "Boot CPU is unpluggable"); -+ return; -+ } -+ -+ hotplug_handler_unplug_request(x86ms->acpi_dev, dev, -+ errp); -+} -+ -+void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ CPUArchId *found_cpu; -+ Error *local_err = NULL; -+ X86CPU *cpu = X86_CPU(dev); -+ X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -+ -+ hotplug_handler_unplug(x86ms->acpi_dev, dev, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ -+ found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL); -+ found_cpu->cpu = NULL; -+ qdev_unrealize(dev); -+ -+ /* decrement the number of CPUs */ -+ x86ms->boot_cpus--; -+ /* Update the number of CPUs in CMOS */ -+ x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); -+ fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -+ out: -+ error_propagate(errp, local_err); -+} -+ -+void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ int idx; -+ CPUState *cs; -+ CPUArchId *cpu_slot; -+ X86CPUTopoIDs topo_ids; -+ X86CPU *cpu = X86_CPU(dev); -+ CPUX86State *env = &cpu->env; -+ MachineState *ms = MACHINE(hotplug_dev); -+ X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -+ unsigned int smp_cores = ms->smp.cores; -+ unsigned int smp_threads = ms->smp.threads; -+ X86CPUTopoInfo topo_info; -+ -+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { -+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", -+ ms->cpu_type); -+ return; -+ } -+ -+ if (x86ms->acpi_dev) { -+ Error *local_err = NULL; -+ -+ hotplug_handler_pre_plug(HOTPLUG_HANDLER(x86ms->acpi_dev), dev, -+ &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ } -+ -+ init_topo_info(&topo_info, x86ms); -+ -+ env->nr_dies = ms->smp.dies; -+ -+ /* -+ * If APIC ID is not set, -+ * set it based on socket/die/core/thread properties. -+ */ -+ if (cpu->apic_id == UNASSIGNED_APIC_ID) { -+ int max_socket = (ms->smp.max_cpus - 1) / -+ smp_threads / smp_cores / ms->smp.dies; -+ -+ /* -+ * die-id was optional in QEMU 4.0 and older, so keep it optional -+ * if there's only one die per socket. -+ */ -+ if (cpu->die_id < 0 && ms->smp.dies == 1) { -+ cpu->die_id = 0; -+ } -+ -+ if (cpu->socket_id < 0) { -+ error_setg(errp, "CPU socket-id is not set"); -+ return; -+ } else if (cpu->socket_id > max_socket) { -+ error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", -+ cpu->socket_id, max_socket); -+ return; -+ } -+ if (cpu->die_id < 0) { -+ error_setg(errp, "CPU die-id is not set"); -+ return; -+ } else if (cpu->die_id > ms->smp.dies - 1) { -+ error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", -+ cpu->die_id, ms->smp.dies - 1); -+ return; -+ } -+ if (cpu->core_id < 0) { -+ error_setg(errp, "CPU core-id is not set"); -+ return; -+ } else if (cpu->core_id > (smp_cores - 1)) { -+ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", -+ cpu->core_id, smp_cores - 1); -+ return; -+ } -+ if (cpu->thread_id < 0) { -+ error_setg(errp, "CPU thread-id is not set"); -+ return; -+ } else if (cpu->thread_id > (smp_threads - 1)) { -+ error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u", -+ cpu->thread_id, smp_threads - 1); -+ return; -+ } -+ -+ topo_ids.pkg_id = cpu->socket_id; -+ topo_ids.die_id = cpu->die_id; -+ topo_ids.core_id = cpu->core_id; -+ topo_ids.smt_id = cpu->thread_id; -+ cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); -+ } -+ -+ cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx); -+ if (!cpu_slot) { -+ x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); -+ error_setg(errp, -+ "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" -+ " APIC ID %" PRIu32 ", valid index range 0:%d", -+ topo_ids.pkg_id, topo_ids.die_id, topo_ids.core_id, topo_ids.smt_id, -+ cpu->apic_id, ms->possible_cpus->len - 1); -+ return; -+ } -+ -+ if (cpu_slot->cpu) { -+ error_setg(errp, "CPU[%d] with APIC ID %" PRIu32 " exists", -+ idx, cpu->apic_id); -+ return; -+ } -+ -+ /* if 'address' properties socket-id/core-id/thread-id are not set, set them -+ * so that machine_query_hotpluggable_cpus would show correct values -+ */ -+ /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn() -+ * once -smp refactoring is complete and there will be CPU private -+ * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */ -+ x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); -+ if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) { -+ error_setg(errp, "property socket-id: %u doesn't match set apic-id:" -+ " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, -+ topo_ids.pkg_id); -+ return; -+ } -+ cpu->socket_id = topo_ids.pkg_id; -+ -+ if (cpu->die_id != -1 && cpu->die_id != topo_ids.die_id) { -+ error_setg(errp, "property die-id: %u doesn't match set apic-id:" -+ " 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo_ids.die_id); -+ return; -+ } -+ cpu->die_id = topo_ids.die_id; -+ -+ if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) { -+ error_setg(errp, "property core-id: %u doesn't match set apic-id:" -+ " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, -+ topo_ids.core_id); -+ return; -+ } -+ cpu->core_id = topo_ids.core_id; -+ -+ if (cpu->thread_id != -1 && cpu->thread_id != topo_ids.smt_id) { -+ error_setg(errp, "property thread-id: %u doesn't match set apic-id:" -+ " 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, -+ topo_ids.smt_id); -+ return; -+ } -+ cpu->thread_id = topo_ids.smt_id; -+ -+ /* -+ * kvm_enabled() must go first to ensure that kvm_* references are -+ * not emitted for the linker to consume (kvm_enabled() is -+ * a literal `0` in configurations where kvm_* aren't defined) -+ */ -+ if (kvm_enabled() && hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) && -+ !kvm_hv_vpindex_settable()) { -+ error_setg(errp, "kernel doesn't allow setting HyperV VP_INDEX"); -+ return; -+ } -+ -+ cs = CPU(cpu); -+ cs->cpu_index = idx; -+ -+ numa_cpu_pre_plug(cpu_slot, dev, errp); -+} -+ -+static long get_file_size(FILE *f) -+{ -+ long where, size; -+ -+ /* XXX: on Unix systems, using fstat() probably makes more sense */ -+ -+ where = ftell(f); -+ fseek(f, 0, SEEK_END); -+ size = ftell(f); -+ fseek(f, where, SEEK_SET); -+ -+ return size; -+} -+ -+void gsi_handler(void *opaque, int n, int level) -+{ -+ GSIState *s = opaque; -+ -+ trace_x86_gsi_interrupt(n, level); -+ switch (n) { -+ case 0 ... ISA_NUM_IRQS - 1: -+ if (s->i8259_irq[n]) { -+ /* Under KVM, Kernel will forward to both PIC and IOAPIC */ -+ qemu_set_irq(s->i8259_irq[n], level); -+ } -+ /* fall through */ -+ case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1: -+#ifdef CONFIG_XEN_EMU -+ /* -+ * Xen delivers the GSI to the Legacy PIC (not that Legacy PIC -+ * routing actually works properly under Xen). And then to -+ * *either* the PIRQ handling or the I/OAPIC depending on -+ * whether the former wants it. -+ */ -+ if (xen_mode == XEN_EMULATE && xen_evtchn_set_gsi(n, level)) { -+ break; -+ } -+#endif -+ qemu_set_irq(s->ioapic_irq[n], level); -+ break; -+ case IO_APIC_SECONDARY_IRQBASE -+ ... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1: -+ qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level); -+ break; -+ } -+} -+ -+void ioapic_init_gsi(GSIState *gsi_state, Object *parent) -+{ -+ DeviceState *dev; -+ SysBusDevice *d; -+ unsigned int i; -+ -+ assert(parent); -+ if (kvm_ioapic_in_kernel()) { -+ dev = qdev_new(TYPE_KVM_IOAPIC); -+ } else { -+ dev = qdev_new(TYPE_IOAPIC); -+ } -+ object_property_add_child(parent, "ioapic", OBJECT(dev)); -+ d = SYS_BUS_DEVICE(dev); -+ sysbus_realize_and_unref(d, &error_fatal); -+ sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS); -+ -+ for (i = 0; i < IOAPIC_NUM_PINS; i++) { -+ gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); -+ } -+} -+ -+DeviceState *ioapic_init_secondary(GSIState *gsi_state) -+{ -+ DeviceState *dev; -+ SysBusDevice *d; -+ unsigned int i; -+ -+ dev = qdev_new(TYPE_IOAPIC); -+ d = SYS_BUS_DEVICE(dev); -+ sysbus_realize_and_unref(d, &error_fatal); -+ sysbus_mmio_map(d, 0, IO_APIC_SECONDARY_ADDRESS); -+ -+ for (i = 0; i < IOAPIC_NUM_PINS; i++) { -+ gsi_state->ioapic2_irq[i] = qdev_get_gpio_in(dev, i); -+ } -+ return dev; -+} -+ -+/* -+ * The entry point into the kernel for PVH boot is different from -+ * the native entry point. The PVH entry is defined by the x86/HVM -+ * direct boot ABI and is available in an ELFNOTE in the kernel binary. -+ * -+ * This function is passed to load_elf() when it is called from -+ * load_elfboot() which then additionally checks for an ELF Note of -+ * type XEN_ELFNOTE_PHYS32_ENTRY and passes it to this function to -+ * parse the PVH entry address from the ELF Note. -+ * -+ * Due to trickery in elf_opts.h, load_elf() is actually available as -+ * load_elf32() or load_elf64() and this routine needs to be able -+ * to deal with being called as 32 or 64 bit. -+ * -+ * The address of the PVH entry point is saved to the 'pvh_start_addr' -+ * global variable. (although the entry point is 32-bit, the kernel -+ * binary can be either 32-bit or 64-bit). -+ */ -+static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64) -+{ -+ size_t *elf_note_data_addr; -+ -+ /* Check if ELF Note header passed in is valid */ -+ if (arg1 == NULL) { -+ return 0; -+ } -+ -+ if (is64) { -+ struct elf64_note *nhdr64 = (struct elf64_note *)arg1; -+ uint64_t nhdr_size64 = sizeof(struct elf64_note); -+ uint64_t phdr_align = *(uint64_t *)arg2; -+ uint64_t nhdr_namesz = nhdr64->n_namesz; -+ -+ elf_note_data_addr = -+ ((void *)nhdr64) + nhdr_size64 + -+ QEMU_ALIGN_UP(nhdr_namesz, phdr_align); -+ -+ pvh_start_addr = *elf_note_data_addr; -+ } else { -+ struct elf32_note *nhdr32 = (struct elf32_note *)arg1; -+ uint32_t nhdr_size32 = sizeof(struct elf32_note); -+ uint32_t phdr_align = *(uint32_t *)arg2; -+ uint32_t nhdr_namesz = nhdr32->n_namesz; -+ -+ elf_note_data_addr = -+ ((void *)nhdr32) + nhdr_size32 + -+ QEMU_ALIGN_UP(nhdr_namesz, phdr_align); -+ -+ pvh_start_addr = *(uint32_t *)elf_note_data_addr; -+ } -+ -+ return pvh_start_addr; -+} -+ -+static bool load_elfboot(const char *kernel_filename, -+ int kernel_file_size, -+ uint8_t *header, -+ size_t pvh_xen_start_addr, -+ FWCfgState *fw_cfg) -+{ -+ uint32_t flags = 0; -+ uint32_t mh_load_addr = 0; -+ uint32_t elf_kernel_size = 0; -+ uint64_t elf_entry; -+ uint64_t elf_low, elf_high; -+ int kernel_size; -+ -+ if (ldl_p(header) != 0x464c457f) { -+ return false; /* no elfboot */ -+ } -+ -+ bool elf_is64 = header[EI_CLASS] == ELFCLASS64; -+ flags = elf_is64 ? -+ ((Elf64_Ehdr *)header)->e_flags : ((Elf32_Ehdr *)header)->e_flags; -+ -+ if (flags & 0x00010004) { /* LOAD_ELF_HEADER_HAS_ADDR */ -+ error_report("elfboot unsupported flags = %x", flags); -+ exit(1); -+ } -+ -+ uint64_t elf_note_type = XEN_ELFNOTE_PHYS32_ENTRY; -+ kernel_size = load_elf(kernel_filename, read_pvh_start_addr, -+ NULL, &elf_note_type, &elf_entry, -+ &elf_low, &elf_high, NULL, 0, I386_ELF_MACHINE, -+ 0, 0); -+ -+ if (kernel_size < 0) { -+ error_report("Error while loading elf kernel"); -+ exit(1); -+ } -+ mh_load_addr = elf_low; -+ elf_kernel_size = elf_high - elf_low; -+ -+ if (pvh_start_addr == 0) { -+ error_report("Error loading uncompressed kernel without PVH ELF Note"); -+ exit(1); -+ } -+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, pvh_start_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_load_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, elf_kernel_size); -+ -+ return true; -+} -+ -+void x86_load_linux(X86MachineState *x86ms, -+ FWCfgState *fw_cfg, -+ int acpi_data_size, -+ bool pvh_enabled) -+{ -+ bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled; -+ uint16_t protocol; -+ int setup_size, kernel_size, cmdline_size; -+ int dtb_size, setup_data_offset; -+ uint32_t initrd_max; -+ uint8_t header[8192], *setup, *kernel; -+ hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0; -+ FILE *f; -+ char *vmode; -+ MachineState *machine = MACHINE(x86ms); -+ struct setup_data *setup_data; -+ const char *kernel_filename = machine->kernel_filename; -+ const char *initrd_filename = machine->initrd_filename; -+ const char *dtb_filename = machine->dtb; -+ const char *kernel_cmdline = machine->kernel_cmdline; -+ SevKernelLoaderContext sev_load_ctx = {}; -+ -+ /* Align to 16 bytes as a paranoia measure */ -+ cmdline_size = (strlen(kernel_cmdline) + 16) & ~15; -+ -+ /* load the kernel header */ -+ f = fopen(kernel_filename, "rb"); -+ if (!f) { -+ fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", -+ kernel_filename, strerror(errno)); -+ exit(1); -+ } -+ -+ kernel_size = get_file_size(f); -+ if (!kernel_size || -+ fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) != -+ MIN(ARRAY_SIZE(header), kernel_size)) { -+ fprintf(stderr, "qemu: could not load kernel '%s': %s\n", -+ kernel_filename, strerror(errno)); -+ exit(1); -+ } -+ -+ /* kernel protocol version */ -+ if (ldl_p(header + 0x202) == 0x53726448) { -+ protocol = lduw_p(header + 0x206); -+ } else { -+ /* -+ * This could be a multiboot kernel. If it is, let's stop treating it -+ * like a Linux kernel. -+ * Note: some multiboot images could be in the ELF format (the same of -+ * PVH), so we try multiboot first since we check the multiboot magic -+ * header before to load it. -+ */ -+ if (load_multiboot(x86ms, fw_cfg, f, kernel_filename, initrd_filename, -+ kernel_cmdline, kernel_size, header)) { -+ return; -+ } -+ /* -+ * Check if the file is an uncompressed kernel file (ELF) and load it, -+ * saving the PVH entry point used by the x86/HVM direct boot ABI. -+ * If load_elfboot() is successful, populate the fw_cfg info. -+ */ -+ if (pvh_enabled && -+ load_elfboot(kernel_filename, kernel_size, -+ header, pvh_start_addr, fw_cfg)) { -+ fclose(f); -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, -+ strlen(kernel_cmdline) + 1); -+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, -+ header, sizeof(header)); -+ -+ /* load initrd */ -+ if (initrd_filename) { -+ GMappedFile *mapped_file; -+ gsize initrd_size; -+ gchar *initrd_data; -+ GError *gerr = NULL; -+ -+ mapped_file = g_mapped_file_new(initrd_filename, false, &gerr); -+ if (!mapped_file) { -+ fprintf(stderr, "qemu: error reading initrd %s: %s\n", -+ initrd_filename, gerr->message); -+ exit(1); -+ } -+ x86ms->initrd_mapped_file = mapped_file; -+ -+ initrd_data = g_mapped_file_get_contents(mapped_file); -+ initrd_size = g_mapped_file_get_length(mapped_file); -+ initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; -+ if (initrd_size >= initrd_max) { -+ fprintf(stderr, "qemu: initrd is too large, cannot support." -+ "(max: %"PRIu32", need %"PRId64")\n", -+ initrd_max, (uint64_t)initrd_size); -+ exit(1); -+ } -+ -+ initrd_addr = (initrd_max - initrd_size) & ~4095; -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, -+ initrd_size); -+ } -+ -+ option_rom[nb_option_roms].bootindex = 0; -+ option_rom[nb_option_roms].name = "pvh.bin"; -+ nb_option_roms++; -+ -+ return; -+ } -+ protocol = 0; -+ } -+ -+ if (protocol < 0x200 || !(header[0x211] & 0x01)) { -+ /* Low kernel */ -+ real_addr = 0x90000; -+ cmdline_addr = 0x9a000 - cmdline_size; -+ prot_addr = 0x10000; -+ } else if (protocol < 0x202) { -+ /* High but ancient kernel */ -+ real_addr = 0x90000; -+ cmdline_addr = 0x9a000 - cmdline_size; -+ prot_addr = 0x100000; -+ } else { -+ /* High and recent kernel */ -+ real_addr = 0x10000; -+ cmdline_addr = 0x20000; -+ prot_addr = 0x100000; -+ } -+ -+ /* highest address for loading the initrd */ -+ if (protocol >= 0x20c && -+ lduw_p(header + 0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) { -+ /* -+ * Linux has supported initrd up to 4 GB for a very long time (2007, -+ * long before XLF_CAN_BE_LOADED_ABOVE_4G which was added in 2013), -+ * though it only sets initrd_max to 2 GB to "work around bootloader -+ * bugs". Luckily, QEMU firmware(which does something like bootloader) -+ * has supported this. -+ * -+ * It's believed that if XLF_CAN_BE_LOADED_ABOVE_4G is set, initrd can -+ * be loaded into any address. -+ * -+ * In addition, initrd_max is uint32_t simply because QEMU doesn't -+ * support the 64-bit boot protocol (specifically the ext_ramdisk_image -+ * field). -+ * -+ * Therefore here just limit initrd_max to UINT32_MAX simply as well. -+ */ -+ initrd_max = UINT32_MAX; -+ } else if (protocol >= 0x203) { -+ initrd_max = ldl_p(header + 0x22c); -+ } else { -+ initrd_max = 0x37ffffff; -+ } -+ -+ if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { -+ initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; -+ } -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); -+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); -+ sev_load_ctx.cmdline_data = (char *)kernel_cmdline; -+ sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1; -+ -+ if (protocol >= 0x202) { -+ stl_p(header + 0x228, cmdline_addr); -+ } else { -+ stw_p(header + 0x20, 0xA33F); -+ stw_p(header + 0x22, cmdline_addr - real_addr); -+ } -+ -+ /* handle vga= parameter */ -+ vmode = strstr(kernel_cmdline, "vga="); -+ if (vmode) { -+ unsigned int video_mode; -+ const char *end; -+ int ret; -+ /* skip "vga=" */ -+ vmode += 4; -+ if (!strncmp(vmode, "normal", 6)) { -+ video_mode = 0xffff; -+ } else if (!strncmp(vmode, "ext", 3)) { -+ video_mode = 0xfffe; -+ } else if (!strncmp(vmode, "ask", 3)) { -+ video_mode = 0xfffd; -+ } else { -+ ret = qemu_strtoui(vmode, &end, 0, &video_mode); -+ if (ret != 0 || (*end && *end != ' ')) { -+ fprintf(stderr, "qemu: invalid 'vga=' kernel parameter.\n"); -+ exit(1); -+ } -+ } -+ stw_p(header + 0x1fa, video_mode); -+ } -+ -+ /* loader type */ -+ /* -+ * High nybble = B reserved for QEMU; low nybble is revision number. -+ * If this code is substantially changed, you may want to consider -+ * incrementing the revision. -+ */ -+ if (protocol >= 0x200) { -+ header[0x210] = 0xB0; -+ } -+ /* heap */ -+ if (protocol >= 0x201) { -+ header[0x211] |= 0x80; /* CAN_USE_HEAP */ -+ stw_p(header + 0x224, cmdline_addr - real_addr - 0x200); -+ } -+ -+ /* load initrd */ -+ if (initrd_filename) { -+ GMappedFile *mapped_file; -+ gsize initrd_size; -+ gchar *initrd_data; -+ GError *gerr = NULL; -+ -+ if (protocol < 0x200) { -+ fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n"); -+ exit(1); -+ } -+ -+ mapped_file = g_mapped_file_new(initrd_filename, false, &gerr); -+ if (!mapped_file) { -+ fprintf(stderr, "qemu: error reading initrd %s: %s\n", -+ initrd_filename, gerr->message); -+ exit(1); -+ } -+ x86ms->initrd_mapped_file = mapped_file; -+ -+ initrd_data = g_mapped_file_get_contents(mapped_file); -+ initrd_size = g_mapped_file_get_length(mapped_file); -+ if (initrd_size >= initrd_max) { -+ fprintf(stderr, "qemu: initrd is too large, cannot support." -+ "(max: %"PRIu32", need %"PRId64")\n", -+ initrd_max, (uint64_t)initrd_size); -+ exit(1); -+ } -+ -+ initrd_addr = (initrd_max - initrd_size) & ~4095; -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size); -+ sev_load_ctx.initrd_data = initrd_data; -+ sev_load_ctx.initrd_size = initrd_size; -+ -+ stl_p(header + 0x218, initrd_addr); -+ stl_p(header + 0x21c, initrd_size); -+ } -+ -+ /* load kernel and setup */ -+ setup_size = header[0x1f1]; -+ if (setup_size == 0) { -+ setup_size = 4; -+ } -+ setup_size = (setup_size + 1) * 512; -+ if (setup_size > kernel_size) { -+ fprintf(stderr, "qemu: invalid kernel header\n"); -+ exit(1); -+ } -+ kernel_size -= setup_size; -+ -+ setup = g_malloc(setup_size); -+ kernel = g_malloc(kernel_size); -+ fseek(f, 0, SEEK_SET); -+ if (fread(setup, 1, setup_size, f) != setup_size) { -+ fprintf(stderr, "fread() failed\n"); -+ exit(1); -+ } -+ if (fread(kernel, 1, kernel_size, f) != kernel_size) { -+ fprintf(stderr, "fread() failed\n"); -+ exit(1); -+ } -+ fclose(f); -+ -+ /* append dtb to kernel */ -+ if (dtb_filename) { -+ if (protocol < 0x209) { -+ fprintf(stderr, "qemu: Linux kernel too old to load a dtb\n"); -+ exit(1); -+ } -+ -+ dtb_size = get_image_size(dtb_filename); -+ if (dtb_size <= 0) { -+ fprintf(stderr, "qemu: error reading dtb %s: %s\n", -+ dtb_filename, strerror(errno)); -+ exit(1); -+ } -+ -+ setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); -+ kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size; -+ kernel = g_realloc(kernel, kernel_size); -+ -+ stq_p(header + 0x250, prot_addr + setup_data_offset); -+ -+ setup_data = (struct setup_data *)(kernel + setup_data_offset); -+ setup_data->next = 0; -+ setup_data->type = cpu_to_le32(SETUP_DTB); -+ setup_data->len = cpu_to_le32(dtb_size); -+ -+ load_image_size(dtb_filename, setup_data->data, dtb_size); -+ } -+ -+ /* -+ * If we're starting an encrypted VM, it will be OVMF based, which uses the -+ * efi stub for booting and doesn't require any values to be placed in the -+ * kernel header. We therefore don't update the header so the hash of the -+ * kernel on the other side of the fw_cfg interface matches the hash of the -+ * file the user passed in. -+ */ -+ if (!sev_enabled()) { -+ memcpy(setup, header, MIN(sizeof(header), setup_size)); -+ } -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); -+ sev_load_ctx.kernel_data = (char *)kernel; -+ sev_load_ctx.kernel_size = kernel_size; -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr); -+ fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); -+ sev_load_ctx.setup_data = (char *)setup; -+ sev_load_ctx.setup_size = setup_size; -+ -+ if (sev_enabled()) { -+ sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal); -+ } -+ -+ option_rom[nb_option_roms].bootindex = 0; -+ option_rom[nb_option_roms].name = "linuxboot.bin"; -+ if (linuxboot_dma_enabled && fw_cfg_dma_enabled(fw_cfg)) { -+ option_rom[nb_option_roms].name = "linuxboot_dma.bin"; -+ } -+ nb_option_roms++; -+} -+ -+void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, -+ MemoryRegion *bios, bool read_only) -+{ -+ uint64_t bios_size = memory_region_size(bios); -+ uint64_t isa_bios_size = MIN(bios_size, 128 * KiB); -+ -+ memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, -+ bios_size - isa_bios_size, isa_bios_size); -+ memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size, -+ isa_bios, 1); -+ memory_region_set_readonly(isa_bios, read_only); -+} -+ -+void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, -+ MemoryRegion *rom_memory, bool isapc_ram_fw) -+{ -+ const char *bios_name; -+ char *filename; -+ int bios_size; -+ ssize_t ret; -+ -+ /* BIOS load */ -+ bios_name = MACHINE(x86ms)->firmware ?: default_firmware; -+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); -+ if (filename) { -+ bios_size = get_image_size(filename); -+ } else { -+ bios_size = -1; -+ } -+ if (bios_size <= 0 || -+ (bios_size % 65536) != 0) { -+ goto bios_error; -+ } -+ memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, -+ &error_fatal); -+ if (sev_enabled()) { -+ /* -+ * The concept of a "reset" simply doesn't exist for -+ * confidential computing guests, we have to destroy and -+ * re-launch them instead. So there is no need to register -+ * the firmware as rom to properly re-initialize on reset. -+ * Just go for a straight file load instead. -+ */ -+ void *ptr = memory_region_get_ram_ptr(&x86ms->bios); -+ load_image_size(filename, ptr, bios_size); -+ x86_firmware_configure(ptr, bios_size); -+ } else { -+ memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw); -+ ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); -+ if (ret != 0) { -+ goto bios_error; -+ } -+ } -+ g_free(filename); -+ -+ /* map the last 128KB of the BIOS in ISA space */ -+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, -+ !isapc_ram_fw); -+ -+ /* map all the bios at the top of memory */ -+ memory_region_add_subregion(rom_memory, -+ (uint32_t)(-bios_size), -+ &x86ms->bios); -+ return; -+ -+bios_error: -+ fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); -+ exit(1); -+} -diff --git a/hw/i386/x86-cpu.c b/hw/i386/x86-cpu.c -new file mode 100644 -index 0000000000..ab2920522d ---- /dev/null -+++ b/hw/i386/x86-cpu.c -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (c) 2003-2004 Fabrice Bellard -+ * Copyright (c) 2019, 2024 Red Hat, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+#include "qemu/osdep.h" -+#include "sysemu/whpx.h" -+#include "sysemu/cpu-timers.h" -+#include "trace.h" -+ -+#include "hw/i386/x86.h" -+#include "target/i386/cpu.h" -+#include "hw/intc/i8259.h" -+#include "hw/irq.h" -+#include "sysemu/kvm.h" -+ -+/* TSC handling */ -+uint64_t cpu_get_tsc(CPUX86State *env) -+{ -+ return cpus_get_elapsed_ticks(); -+} -+ -+/* IRQ handling */ -+static void pic_irq_request(void *opaque, int irq, int level) -+{ -+ CPUState *cs = first_cpu; -+ X86CPU *cpu = X86_CPU(cs); -+ -+ trace_x86_pic_interrupt(irq, level); -+ if (cpu_is_apic_enabled(cpu->apic_state) && !kvm_irqchip_in_kernel() && -+ !whpx_apic_in_platform()) { -+ CPU_FOREACH(cs) { -+ cpu = X86_CPU(cs); -+ if (apic_accept_pic_intr(cpu->apic_state)) { -+ apic_deliver_pic_intr(cpu->apic_state, level); -+ } -+ } -+ } else { -+ if (level) { -+ cpu_interrupt(cs, CPU_INTERRUPT_HARD); -+ } else { -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ } -+ } -+} -+ -+qemu_irq x86_allocate_cpu_irq(void) -+{ -+ return qemu_allocate_irq(pic_irq_request, NULL, 0); -+} -+ -+int cpu_get_pic_interrupt(CPUX86State *env) -+{ -+ X86CPU *cpu = env_archcpu(env); -+ int intno; -+ -+ if (!kvm_irqchip_in_kernel() && !whpx_apic_in_platform()) { -+ intno = apic_get_interrupt(cpu->apic_state); -+ if (intno >= 0) { -+ return intno; -+ } -+ /* read the irq from the PIC */ -+ if (!apic_accept_pic_intr(cpu->apic_state)) { -+ return -1; -+ } -+ } -+ -+ intno = pic_read_irq(isa_pic); -+ return intno; -+} -+ -+DeviceState *cpu_get_current_apic(void) -+{ -+ if (current_cpu) { -+ X86CPU *cpu = X86_CPU(current_cpu); -+ return cpu->apic_state; -+ } else { -+ return NULL; -+ } -+} -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index fcef652c1e..0b5cc59956 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -22,52 +22,25 @@ - */ - #include "qemu/osdep.h" - #include "qemu/error-report.h" --#include "qemu/option.h" --#include "qemu/cutils.h" - #include "qemu/units.h" --#include "qemu/datadir.h" - #include "qapi/error.h" - #include "qapi/qapi-visit-common.h" --#include "qapi/clone-visitor.h" - #include "qapi/qapi-visit-machine.h" - #include "qapi/visitor.h" - #include "sysemu/qtest.h" --#include "sysemu/whpx.h" - #include "sysemu/numa.h" --#include "sysemu/replay.h" --#include "sysemu/sysemu.h" --#include "sysemu/cpu-timers.h" --#include "sysemu/xen.h" - #include "trace.h" - -+#include "hw/acpi/aml-build.h" - #include "hw/i386/x86.h" --#include "target/i386/cpu.h" - #include "hw/i386/topology.h" --#include "hw/i386/fw_cfg.h" --#include "hw/intc/i8259.h" --#include "hw/rtc/mc146818rtc.h" --#include "target/i386/sev.h" - --#include "hw/acpi/cpu_hotplug.h" --#include "hw/irq.h" - #include "hw/nmi.h" --#include "hw/loader.h" --#include "multiboot.h" --#include "elf.h" --#include "standard-headers/asm-x86/bootparam.h" --#include CONFIG_DEVICES - #include "kvm/kvm_i386.h" - --#ifdef CONFIG_XEN_EMU --#include "hw/xen/xen.h" --#include "hw/i386/kvm/xen_evtchn.h" --#endif - --/* Physical Address of PVH entry point read from kernel ELF NOTE */ --static size_t pvh_start_addr; -- --static void init_topo_info(X86CPUTopoInfo *topo_info, -- const X86MachineState *x86ms) -+void init_topo_info(X86CPUTopoInfo *topo_info, -+ const X86MachineState *x86ms) - { - MachineState *ms = MACHINE(x86ms); - -@@ -94,355 +67,6 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, - return x86_apicid_from_cpu_idx(&topo_info, cpu_index); - } - -- --void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp) --{ -- Object *cpu = object_new(MACHINE(x86ms)->cpu_type); -- -- if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) { -- goto out; -- } -- qdev_realize(DEVICE(cpu), NULL, errp); -- --out: -- object_unref(cpu); --} -- --void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) --{ -- int i; -- const CPUArchIdList *possible_cpus; -- MachineState *ms = MACHINE(x86ms); -- MachineClass *mc = MACHINE_GET_CLASS(x86ms); -- -- x86_cpu_set_default_version(default_cpu_version); -- -- /* -- * Calculates the limit to CPU APIC ID values -- * -- * Limit for the APIC ID value, so that all -- * CPU APIC IDs are < x86ms->apic_id_limit. -- * -- * This is used for FW_CFG_MAX_CPUS. See comments on fw_cfg_arch_create(). -- */ -- x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms, -- ms->smp.max_cpus - 1) + 1; -- -- /* -- * Can we support APIC ID 255 or higher? With KVM, that requires -- * both in-kernel lapic and X2APIC userspace API. -- * -- * kvm_enabled() must go first to ensure that kvm_* references are -- * not emitted for the linker to consume (kvm_enabled() is -- * a literal `0` in configurations where kvm_* aren't defined) -- */ -- if (kvm_enabled() && x86ms->apic_id_limit > 255 && -- kvm_irqchip_in_kernel() && !kvm_enable_x2apic()) { -- error_report("current -smp configuration requires kernel " -- "irqchip and X2APIC API support."); -- exit(EXIT_FAILURE); -- } -- -- if (kvm_enabled()) { -- kvm_set_max_apic_id(x86ms->apic_id_limit); -- } -- -- if (!kvm_irqchip_in_kernel()) { -- apic_set_max_apic_id(x86ms->apic_id_limit); -- } -- -- possible_cpus = mc->possible_cpu_arch_ids(ms); -- for (i = 0; i < ms->smp.cpus; i++) { -- x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); -- } --} -- --void x86_rtc_set_cpus_count(ISADevice *s, uint16_t cpus_count) --{ -- MC146818RtcState *rtc = MC146818_RTC(s); -- -- if (cpus_count > 0xff) { -- /* -- * If the number of CPUs can't be represented in 8 bits, the -- * BIOS must use "FW_CFG_NB_CPUS". Set RTC field to 0 just -- * to make old BIOSes fail more predictably. -- */ -- mc146818rtc_set_cmos_data(rtc, 0x5f, 0); -- } else { -- mc146818rtc_set_cmos_data(rtc, 0x5f, cpus_count - 1); -- } --} -- --static int x86_apic_cmp(const void *a, const void *b) --{ -- CPUArchId *apic_a = (CPUArchId *)a; -- CPUArchId *apic_b = (CPUArchId *)b; -- -- return apic_a->arch_id - apic_b->arch_id; --} -- --/* -- * returns pointer to CPUArchId descriptor that matches CPU's apic_id -- * in ms->possible_cpus->cpus, if ms->possible_cpus->cpus has no -- * entry corresponding to CPU's apic_id returns NULL. -- */ --CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx) --{ -- CPUArchId apic_id, *found_cpu; -- -- apic_id.arch_id = id; -- found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, -- ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), -- x86_apic_cmp); -- if (found_cpu && idx) { -- *idx = found_cpu - ms->possible_cpus->cpus; -- } -- return found_cpu; --} -- --void x86_cpu_plug(HotplugHandler *hotplug_dev, -- DeviceState *dev, Error **errp) --{ -- CPUArchId *found_cpu; -- Error *local_err = NULL; -- X86CPU *cpu = X86_CPU(dev); -- X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -- -- if (x86ms->acpi_dev) { -- hotplug_handler_plug(x86ms->acpi_dev, dev, &local_err); -- if (local_err) { -- goto out; -- } -- } -- -- /* increment the number of CPUs */ -- x86ms->boot_cpus++; -- if (x86ms->rtc) { -- x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); -- } -- if (x86ms->fw_cfg) { -- fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -- } -- -- found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL); -- found_cpu->cpu = CPU(dev); --out: -- error_propagate(errp, local_err); --} -- --void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, -- DeviceState *dev, Error **errp) --{ -- int idx = -1; -- X86CPU *cpu = X86_CPU(dev); -- X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -- -- if (!x86ms->acpi_dev) { -- error_setg(errp, "CPU hot unplug not supported without ACPI"); -- return; -- } -- -- x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx); -- assert(idx != -1); -- if (idx == 0) { -- error_setg(errp, "Boot CPU is unpluggable"); -- return; -- } -- -- hotplug_handler_unplug_request(x86ms->acpi_dev, dev, -- errp); --} -- --void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, -- DeviceState *dev, Error **errp) --{ -- CPUArchId *found_cpu; -- Error *local_err = NULL; -- X86CPU *cpu = X86_CPU(dev); -- X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -- -- hotplug_handler_unplug(x86ms->acpi_dev, dev, &local_err); -- if (local_err) { -- goto out; -- } -- -- found_cpu = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, NULL); -- found_cpu->cpu = NULL; -- qdev_unrealize(dev); -- -- /* decrement the number of CPUs */ -- x86ms->boot_cpus--; -- /* Update the number of CPUs in CMOS */ -- x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus); -- fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); -- out: -- error_propagate(errp, local_err); --} -- --void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, -- DeviceState *dev, Error **errp) --{ -- int idx; -- CPUState *cs; -- CPUArchId *cpu_slot; -- X86CPUTopoIDs topo_ids; -- X86CPU *cpu = X86_CPU(dev); -- CPUX86State *env = &cpu->env; -- MachineState *ms = MACHINE(hotplug_dev); -- X86MachineState *x86ms = X86_MACHINE(hotplug_dev); -- unsigned int smp_cores = ms->smp.cores; -- unsigned int smp_threads = ms->smp.threads; -- X86CPUTopoInfo topo_info; -- -- if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { -- error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", -- ms->cpu_type); -- return; -- } -- -- if (x86ms->acpi_dev) { -- Error *local_err = NULL; -- -- hotplug_handler_pre_plug(HOTPLUG_HANDLER(x86ms->acpi_dev), dev, -- &local_err); -- if (local_err) { -- error_propagate(errp, local_err); -- return; -- } -- } -- -- init_topo_info(&topo_info, x86ms); -- -- env->nr_dies = ms->smp.dies; -- -- /* -- * If APIC ID is not set, -- * set it based on socket/die/core/thread properties. -- */ -- if (cpu->apic_id == UNASSIGNED_APIC_ID) { -- int max_socket = (ms->smp.max_cpus - 1) / -- smp_threads / smp_cores / ms->smp.dies; -- -- /* -- * die-id was optional in QEMU 4.0 and older, so keep it optional -- * if there's only one die per socket. -- */ -- if (cpu->die_id < 0 && ms->smp.dies == 1) { -- cpu->die_id = 0; -- } -- -- if (cpu->socket_id < 0) { -- error_setg(errp, "CPU socket-id is not set"); -- return; -- } else if (cpu->socket_id > max_socket) { -- error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", -- cpu->socket_id, max_socket); -- return; -- } -- if (cpu->die_id < 0) { -- error_setg(errp, "CPU die-id is not set"); -- return; -- } else if (cpu->die_id > ms->smp.dies - 1) { -- error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u", -- cpu->die_id, ms->smp.dies - 1); -- return; -- } -- if (cpu->core_id < 0) { -- error_setg(errp, "CPU core-id is not set"); -- return; -- } else if (cpu->core_id > (smp_cores - 1)) { -- error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", -- cpu->core_id, smp_cores - 1); -- return; -- } -- if (cpu->thread_id < 0) { -- error_setg(errp, "CPU thread-id is not set"); -- return; -- } else if (cpu->thread_id > (smp_threads - 1)) { -- error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u", -- cpu->thread_id, smp_threads - 1); -- return; -- } -- -- topo_ids.pkg_id = cpu->socket_id; -- topo_ids.die_id = cpu->die_id; -- topo_ids.core_id = cpu->core_id; -- topo_ids.smt_id = cpu->thread_id; -- cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids); -- } -- -- cpu_slot = x86_find_cpu_slot(MACHINE(x86ms), cpu->apic_id, &idx); -- if (!cpu_slot) { -- x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); -- error_setg(errp, -- "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with" -- " APIC ID %" PRIu32 ", valid index range 0:%d", -- topo_ids.pkg_id, topo_ids.die_id, topo_ids.core_id, topo_ids.smt_id, -- cpu->apic_id, ms->possible_cpus->len - 1); -- return; -- } -- -- if (cpu_slot->cpu) { -- error_setg(errp, "CPU[%d] with APIC ID %" PRIu32 " exists", -- idx, cpu->apic_id); -- return; -- } -- -- /* if 'address' properties socket-id/core-id/thread-id are not set, set them -- * so that machine_query_hotpluggable_cpus would show correct values -- */ -- /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn() -- * once -smp refactoring is complete and there will be CPU private -- * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */ -- x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids); -- if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) { -- error_setg(errp, "property socket-id: %u doesn't match set apic-id:" -- " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, -- topo_ids.pkg_id); -- return; -- } -- cpu->socket_id = topo_ids.pkg_id; -- -- if (cpu->die_id != -1 && cpu->die_id != topo_ids.die_id) { -- error_setg(errp, "property die-id: %u doesn't match set apic-id:" -- " 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo_ids.die_id); -- return; -- } -- cpu->die_id = topo_ids.die_id; -- -- if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) { -- error_setg(errp, "property core-id: %u doesn't match set apic-id:" -- " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, -- topo_ids.core_id); -- return; -- } -- cpu->core_id = topo_ids.core_id; -- -- if (cpu->thread_id != -1 && cpu->thread_id != topo_ids.smt_id) { -- error_setg(errp, "property thread-id: %u doesn't match set apic-id:" -- " 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, -- topo_ids.smt_id); -- return; -- } -- cpu->thread_id = topo_ids.smt_id; -- -- /* -- * kvm_enabled() must go first to ensure that kvm_* references are -- * not emitted for the linker to consume (kvm_enabled() is -- * a literal `0` in configurations where kvm_* aren't defined) -- */ -- if (kvm_enabled() && hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) && -- !kvm_hv_vpindex_settable()) { -- error_setg(errp, "kernel doesn't allow setting HyperV VP_INDEX"); -- return; -- } -- -- cs = CPU(cpu); -- cs->cpu_index = idx; -- -- numa_cpu_pre_plug(cpu_slot, dev, errp); --} -- - static CpuInstanceProperties - x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) - { -@@ -528,676 +152,6 @@ static void x86_nmi(NMIState *n, int cpu_index, Error **errp) - } - } - --static long get_file_size(FILE *f) --{ -- long where, size; -- -- /* XXX: on Unix systems, using fstat() probably makes more sense */ -- -- where = ftell(f); -- fseek(f, 0, SEEK_END); -- size = ftell(f); -- fseek(f, where, SEEK_SET); -- -- return size; --} -- --/* TSC handling */ --uint64_t cpu_get_tsc(CPUX86State *env) --{ -- return cpus_get_elapsed_ticks(); --} -- --/* IRQ handling */ --static void pic_irq_request(void *opaque, int irq, int level) --{ -- CPUState *cs = first_cpu; -- X86CPU *cpu = X86_CPU(cs); -- -- trace_x86_pic_interrupt(irq, level); -- if (cpu_is_apic_enabled(cpu->apic_state) && !kvm_irqchip_in_kernel() && -- !whpx_apic_in_platform()) { -- CPU_FOREACH(cs) { -- cpu = X86_CPU(cs); -- if (apic_accept_pic_intr(cpu->apic_state)) { -- apic_deliver_pic_intr(cpu->apic_state, level); -- } -- } -- } else { -- if (level) { -- cpu_interrupt(cs, CPU_INTERRUPT_HARD); -- } else { -- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -- } -- } --} -- --qemu_irq x86_allocate_cpu_irq(void) --{ -- return qemu_allocate_irq(pic_irq_request, NULL, 0); --} -- --int cpu_get_pic_interrupt(CPUX86State *env) --{ -- X86CPU *cpu = env_archcpu(env); -- int intno; -- -- if (!kvm_irqchip_in_kernel() && !whpx_apic_in_platform()) { -- intno = apic_get_interrupt(cpu->apic_state); -- if (intno >= 0) { -- return intno; -- } -- /* read the irq from the PIC */ -- if (!apic_accept_pic_intr(cpu->apic_state)) { -- return -1; -- } -- } -- -- intno = pic_read_irq(isa_pic); -- return intno; --} -- --DeviceState *cpu_get_current_apic(void) --{ -- if (current_cpu) { -- X86CPU *cpu = X86_CPU(current_cpu); -- return cpu->apic_state; -- } else { -- return NULL; -- } --} -- --void gsi_handler(void *opaque, int n, int level) --{ -- GSIState *s = opaque; -- -- trace_x86_gsi_interrupt(n, level); -- switch (n) { -- case 0 ... ISA_NUM_IRQS - 1: -- if (s->i8259_irq[n]) { -- /* Under KVM, Kernel will forward to both PIC and IOAPIC */ -- qemu_set_irq(s->i8259_irq[n], level); -- } -- /* fall through */ -- case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1: --#ifdef CONFIG_XEN_EMU -- /* -- * Xen delivers the GSI to the Legacy PIC (not that Legacy PIC -- * routing actually works properly under Xen). And then to -- * *either* the PIRQ handling or the I/OAPIC depending on -- * whether the former wants it. -- */ -- if (xen_mode == XEN_EMULATE && xen_evtchn_set_gsi(n, level)) { -- break; -- } --#endif -- qemu_set_irq(s->ioapic_irq[n], level); -- break; -- case IO_APIC_SECONDARY_IRQBASE -- ... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1: -- qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level); -- break; -- } --} -- --void ioapic_init_gsi(GSIState *gsi_state, Object *parent) --{ -- DeviceState *dev; -- SysBusDevice *d; -- unsigned int i; -- -- assert(parent); -- if (kvm_ioapic_in_kernel()) { -- dev = qdev_new(TYPE_KVM_IOAPIC); -- } else { -- dev = qdev_new(TYPE_IOAPIC); -- } -- object_property_add_child(parent, "ioapic", OBJECT(dev)); -- d = SYS_BUS_DEVICE(dev); -- sysbus_realize_and_unref(d, &error_fatal); -- sysbus_mmio_map(d, 0, IO_APIC_DEFAULT_ADDRESS); -- -- for (i = 0; i < IOAPIC_NUM_PINS; i++) { -- gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); -- } --} -- --DeviceState *ioapic_init_secondary(GSIState *gsi_state) --{ -- DeviceState *dev; -- SysBusDevice *d; -- unsigned int i; -- -- dev = qdev_new(TYPE_IOAPIC); -- d = SYS_BUS_DEVICE(dev); -- sysbus_realize_and_unref(d, &error_fatal); -- sysbus_mmio_map(d, 0, IO_APIC_SECONDARY_ADDRESS); -- -- for (i = 0; i < IOAPIC_NUM_PINS; i++) { -- gsi_state->ioapic2_irq[i] = qdev_get_gpio_in(dev, i); -- } -- return dev; --} -- --/* -- * The entry point into the kernel for PVH boot is different from -- * the native entry point. The PVH entry is defined by the x86/HVM -- * direct boot ABI and is available in an ELFNOTE in the kernel binary. -- * -- * This function is passed to load_elf() when it is called from -- * load_elfboot() which then additionally checks for an ELF Note of -- * type XEN_ELFNOTE_PHYS32_ENTRY and passes it to this function to -- * parse the PVH entry address from the ELF Note. -- * -- * Due to trickery in elf_opts.h, load_elf() is actually available as -- * load_elf32() or load_elf64() and this routine needs to be able -- * to deal with being called as 32 or 64 bit. -- * -- * The address of the PVH entry point is saved to the 'pvh_start_addr' -- * global variable. (although the entry point is 32-bit, the kernel -- * binary can be either 32-bit or 64-bit). -- */ --static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64) --{ -- size_t *elf_note_data_addr; -- -- /* Check if ELF Note header passed in is valid */ -- if (arg1 == NULL) { -- return 0; -- } -- -- if (is64) { -- struct elf64_note *nhdr64 = (struct elf64_note *)arg1; -- uint64_t nhdr_size64 = sizeof(struct elf64_note); -- uint64_t phdr_align = *(uint64_t *)arg2; -- uint64_t nhdr_namesz = nhdr64->n_namesz; -- -- elf_note_data_addr = -- ((void *)nhdr64) + nhdr_size64 + -- QEMU_ALIGN_UP(nhdr_namesz, phdr_align); -- -- pvh_start_addr = *elf_note_data_addr; -- } else { -- struct elf32_note *nhdr32 = (struct elf32_note *)arg1; -- uint32_t nhdr_size32 = sizeof(struct elf32_note); -- uint32_t phdr_align = *(uint32_t *)arg2; -- uint32_t nhdr_namesz = nhdr32->n_namesz; -- -- elf_note_data_addr = -- ((void *)nhdr32) + nhdr_size32 + -- QEMU_ALIGN_UP(nhdr_namesz, phdr_align); -- -- pvh_start_addr = *(uint32_t *)elf_note_data_addr; -- } -- -- return pvh_start_addr; --} -- --static bool load_elfboot(const char *kernel_filename, -- int kernel_file_size, -- uint8_t *header, -- size_t pvh_xen_start_addr, -- FWCfgState *fw_cfg) --{ -- uint32_t flags = 0; -- uint32_t mh_load_addr = 0; -- uint32_t elf_kernel_size = 0; -- uint64_t elf_entry; -- uint64_t elf_low, elf_high; -- int kernel_size; -- -- if (ldl_p(header) != 0x464c457f) { -- return false; /* no elfboot */ -- } -- -- bool elf_is64 = header[EI_CLASS] == ELFCLASS64; -- flags = elf_is64 ? -- ((Elf64_Ehdr *)header)->e_flags : ((Elf32_Ehdr *)header)->e_flags; -- -- if (flags & 0x00010004) { /* LOAD_ELF_HEADER_HAS_ADDR */ -- error_report("elfboot unsupported flags = %x", flags); -- exit(1); -- } -- -- uint64_t elf_note_type = XEN_ELFNOTE_PHYS32_ENTRY; -- kernel_size = load_elf(kernel_filename, read_pvh_start_addr, -- NULL, &elf_note_type, &elf_entry, -- &elf_low, &elf_high, NULL, 0, I386_ELF_MACHINE, -- 0, 0); -- -- if (kernel_size < 0) { -- error_report("Error while loading elf kernel"); -- exit(1); -- } -- mh_load_addr = elf_low; -- elf_kernel_size = elf_high - elf_low; -- -- if (pvh_start_addr == 0) { -- error_report("Error loading uncompressed kernel without PVH ELF Note"); -- exit(1); -- } -- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, pvh_start_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_load_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, elf_kernel_size); -- -- return true; --} -- --void x86_load_linux(X86MachineState *x86ms, -- FWCfgState *fw_cfg, -- int acpi_data_size, -- bool pvh_enabled) --{ -- bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled; -- uint16_t protocol; -- int setup_size, kernel_size, cmdline_size; -- int dtb_size, setup_data_offset; -- uint32_t initrd_max; -- uint8_t header[8192], *setup, *kernel; -- hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0; -- FILE *f; -- char *vmode; -- MachineState *machine = MACHINE(x86ms); -- struct setup_data *setup_data; -- const char *kernel_filename = machine->kernel_filename; -- const char *initrd_filename = machine->initrd_filename; -- const char *dtb_filename = machine->dtb; -- const char *kernel_cmdline = machine->kernel_cmdline; -- SevKernelLoaderContext sev_load_ctx = {}; -- -- /* Align to 16 bytes as a paranoia measure */ -- cmdline_size = (strlen(kernel_cmdline) + 16) & ~15; -- -- /* load the kernel header */ -- f = fopen(kernel_filename, "rb"); -- if (!f) { -- fprintf(stderr, "qemu: could not open kernel file '%s': %s\n", -- kernel_filename, strerror(errno)); -- exit(1); -- } -- -- kernel_size = get_file_size(f); -- if (!kernel_size || -- fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) != -- MIN(ARRAY_SIZE(header), kernel_size)) { -- fprintf(stderr, "qemu: could not load kernel '%s': %s\n", -- kernel_filename, strerror(errno)); -- exit(1); -- } -- -- /* kernel protocol version */ -- if (ldl_p(header + 0x202) == 0x53726448) { -- protocol = lduw_p(header + 0x206); -- } else { -- /* -- * This could be a multiboot kernel. If it is, let's stop treating it -- * like a Linux kernel. -- * Note: some multiboot images could be in the ELF format (the same of -- * PVH), so we try multiboot first since we check the multiboot magic -- * header before to load it. -- */ -- if (load_multiboot(x86ms, fw_cfg, f, kernel_filename, initrd_filename, -- kernel_cmdline, kernel_size, header)) { -- return; -- } -- /* -- * Check if the file is an uncompressed kernel file (ELF) and load it, -- * saving the PVH entry point used by the x86/HVM direct boot ABI. -- * If load_elfboot() is successful, populate the fw_cfg info. -- */ -- if (pvh_enabled && -- load_elfboot(kernel_filename, kernel_size, -- header, pvh_start_addr, fw_cfg)) { -- fclose(f); -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, -- strlen(kernel_cmdline) + 1); -- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); -- fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, -- header, sizeof(header)); -- -- /* load initrd */ -- if (initrd_filename) { -- GMappedFile *mapped_file; -- gsize initrd_size; -- gchar *initrd_data; -- GError *gerr = NULL; -- -- mapped_file = g_mapped_file_new(initrd_filename, false, &gerr); -- if (!mapped_file) { -- fprintf(stderr, "qemu: error reading initrd %s: %s\n", -- initrd_filename, gerr->message); -- exit(1); -- } -- x86ms->initrd_mapped_file = mapped_file; -- -- initrd_data = g_mapped_file_get_contents(mapped_file); -- initrd_size = g_mapped_file_get_length(mapped_file); -- initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; -- if (initrd_size >= initrd_max) { -- fprintf(stderr, "qemu: initrd is too large, cannot support." -- "(max: %"PRIu32", need %"PRId64")\n", -- initrd_max, (uint64_t)initrd_size); -- exit(1); -- } -- -- initrd_addr = (initrd_max - initrd_size) & ~4095; -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -- fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, -- initrd_size); -- } -- -- option_rom[nb_option_roms].bootindex = 0; -- option_rom[nb_option_roms].name = "pvh.bin"; -- nb_option_roms++; -- -- return; -- } -- protocol = 0; -- } -- -- if (protocol < 0x200 || !(header[0x211] & 0x01)) { -- /* Low kernel */ -- real_addr = 0x90000; -- cmdline_addr = 0x9a000 - cmdline_size; -- prot_addr = 0x10000; -- } else if (protocol < 0x202) { -- /* High but ancient kernel */ -- real_addr = 0x90000; -- cmdline_addr = 0x9a000 - cmdline_size; -- prot_addr = 0x100000; -- } else { -- /* High and recent kernel */ -- real_addr = 0x10000; -- cmdline_addr = 0x20000; -- prot_addr = 0x100000; -- } -- -- /* highest address for loading the initrd */ -- if (protocol >= 0x20c && -- lduw_p(header + 0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) { -- /* -- * Linux has supported initrd up to 4 GB for a very long time (2007, -- * long before XLF_CAN_BE_LOADED_ABOVE_4G which was added in 2013), -- * though it only sets initrd_max to 2 GB to "work around bootloader -- * bugs". Luckily, QEMU firmware(which does something like bootloader) -- * has supported this. -- * -- * It's believed that if XLF_CAN_BE_LOADED_ABOVE_4G is set, initrd can -- * be loaded into any address. -- * -- * In addition, initrd_max is uint32_t simply because QEMU doesn't -- * support the 64-bit boot protocol (specifically the ext_ramdisk_image -- * field). -- * -- * Therefore here just limit initrd_max to UINT32_MAX simply as well. -- */ -- initrd_max = UINT32_MAX; -- } else if (protocol >= 0x203) { -- initrd_max = ldl_p(header + 0x22c); -- } else { -- initrd_max = 0x37ffffff; -- } -- -- if (initrd_max >= x86ms->below_4g_mem_size - acpi_data_size) { -- initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1; -- } -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); -- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); -- sev_load_ctx.cmdline_data = (char *)kernel_cmdline; -- sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1; -- -- if (protocol >= 0x202) { -- stl_p(header + 0x228, cmdline_addr); -- } else { -- stw_p(header + 0x20, 0xA33F); -- stw_p(header + 0x22, cmdline_addr - real_addr); -- } -- -- /* handle vga= parameter */ -- vmode = strstr(kernel_cmdline, "vga="); -- if (vmode) { -- unsigned int video_mode; -- const char *end; -- int ret; -- /* skip "vga=" */ -- vmode += 4; -- if (!strncmp(vmode, "normal", 6)) { -- video_mode = 0xffff; -- } else if (!strncmp(vmode, "ext", 3)) { -- video_mode = 0xfffe; -- } else if (!strncmp(vmode, "ask", 3)) { -- video_mode = 0xfffd; -- } else { -- ret = qemu_strtoui(vmode, &end, 0, &video_mode); -- if (ret != 0 || (*end && *end != ' ')) { -- fprintf(stderr, "qemu: invalid 'vga=' kernel parameter.\n"); -- exit(1); -- } -- } -- stw_p(header + 0x1fa, video_mode); -- } -- -- /* loader type */ -- /* -- * High nybble = B reserved for QEMU; low nybble is revision number. -- * If this code is substantially changed, you may want to consider -- * incrementing the revision. -- */ -- if (protocol >= 0x200) { -- header[0x210] = 0xB0; -- } -- /* heap */ -- if (protocol >= 0x201) { -- header[0x211] |= 0x80; /* CAN_USE_HEAP */ -- stw_p(header + 0x224, cmdline_addr - real_addr - 0x200); -- } -- -- /* load initrd */ -- if (initrd_filename) { -- GMappedFile *mapped_file; -- gsize initrd_size; -- gchar *initrd_data; -- GError *gerr = NULL; -- -- if (protocol < 0x200) { -- fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n"); -- exit(1); -- } -- -- mapped_file = g_mapped_file_new(initrd_filename, false, &gerr); -- if (!mapped_file) { -- fprintf(stderr, "qemu: error reading initrd %s: %s\n", -- initrd_filename, gerr->message); -- exit(1); -- } -- x86ms->initrd_mapped_file = mapped_file; -- -- initrd_data = g_mapped_file_get_contents(mapped_file); -- initrd_size = g_mapped_file_get_length(mapped_file); -- if (initrd_size >= initrd_max) { -- fprintf(stderr, "qemu: initrd is too large, cannot support." -- "(max: %"PRIu32", need %"PRId64")\n", -- initrd_max, (uint64_t)initrd_size); -- exit(1); -- } -- -- initrd_addr = (initrd_max - initrd_size) & ~4095; -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -- fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size); -- sev_load_ctx.initrd_data = initrd_data; -- sev_load_ctx.initrd_size = initrd_size; -- -- stl_p(header + 0x218, initrd_addr); -- stl_p(header + 0x21c, initrd_size); -- } -- -- /* load kernel and setup */ -- setup_size = header[0x1f1]; -- if (setup_size == 0) { -- setup_size = 4; -- } -- setup_size = (setup_size + 1) * 512; -- if (setup_size > kernel_size) { -- fprintf(stderr, "qemu: invalid kernel header\n"); -- exit(1); -- } -- kernel_size -= setup_size; -- -- setup = g_malloc(setup_size); -- kernel = g_malloc(kernel_size); -- fseek(f, 0, SEEK_SET); -- if (fread(setup, 1, setup_size, f) != setup_size) { -- fprintf(stderr, "fread() failed\n"); -- exit(1); -- } -- if (fread(kernel, 1, kernel_size, f) != kernel_size) { -- fprintf(stderr, "fread() failed\n"); -- exit(1); -- } -- fclose(f); -- -- /* append dtb to kernel */ -- if (dtb_filename) { -- if (protocol < 0x209) { -- fprintf(stderr, "qemu: Linux kernel too old to load a dtb\n"); -- exit(1); -- } -- -- dtb_size = get_image_size(dtb_filename); -- if (dtb_size <= 0) { -- fprintf(stderr, "qemu: error reading dtb %s: %s\n", -- dtb_filename, strerror(errno)); -- exit(1); -- } -- -- setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16); -- kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size; -- kernel = g_realloc(kernel, kernel_size); -- -- stq_p(header + 0x250, prot_addr + setup_data_offset); -- -- setup_data = (struct setup_data *)(kernel + setup_data_offset); -- setup_data->next = 0; -- setup_data->type = cpu_to_le32(SETUP_DTB); -- setup_data->len = cpu_to_le32(dtb_size); -- -- load_image_size(dtb_filename, setup_data->data, dtb_size); -- } -- -- /* -- * If we're starting an encrypted VM, it will be OVMF based, which uses the -- * efi stub for booting and doesn't require any values to be placed in the -- * kernel header. We therefore don't update the header so the hash of the -- * kernel on the other side of the fw_cfg interface matches the hash of the -- * file the user passed in. -- */ -- if (!sev_enabled()) { -- memcpy(setup, header, MIN(sizeof(header), setup_size)); -- } -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); -- fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); -- sev_load_ctx.kernel_data = (char *)kernel; -- sev_load_ctx.kernel_size = kernel_size; -- -- fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr); -- fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); -- fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); -- sev_load_ctx.setup_data = (char *)setup; -- sev_load_ctx.setup_size = setup_size; -- -- if (sev_enabled()) { -- sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal); -- } -- -- option_rom[nb_option_roms].bootindex = 0; -- option_rom[nb_option_roms].name = "linuxboot.bin"; -- if (linuxboot_dma_enabled && fw_cfg_dma_enabled(fw_cfg)) { -- option_rom[nb_option_roms].name = "linuxboot_dma.bin"; -- } -- nb_option_roms++; --} -- --void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, -- MemoryRegion *bios, bool read_only) --{ -- uint64_t bios_size = memory_region_size(bios); -- uint64_t isa_bios_size = MIN(bios_size, 128 * KiB); -- -- memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, -- bios_size - isa_bios_size, isa_bios_size); -- memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size, -- isa_bios, 1); -- memory_region_set_readonly(isa_bios, read_only); --} -- --void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, -- MemoryRegion *rom_memory, bool isapc_ram_fw) --{ -- const char *bios_name; -- char *filename; -- int bios_size; -- ssize_t ret; -- -- /* BIOS load */ -- bios_name = MACHINE(x86ms)->firmware ?: default_firmware; -- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); -- if (filename) { -- bios_size = get_image_size(filename); -- } else { -- bios_size = -1; -- } -- if (bios_size <= 0 || -- (bios_size % 65536) != 0) { -- goto bios_error; -- } -- memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, -- &error_fatal); -- if (sev_enabled()) { -- /* -- * The concept of a "reset" simply doesn't exist for -- * confidential computing guests, we have to destroy and -- * re-launch them instead. So there is no need to register -- * the firmware as rom to properly re-initialize on reset. -- * Just go for a straight file load instead. -- */ -- void *ptr = memory_region_get_ram_ptr(&x86ms->bios); -- load_image_size(filename, ptr, bios_size); -- x86_firmware_configure(ptr, bios_size); -- } else { -- memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw); -- ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); -- if (ret != 0) { -- goto bios_error; -- } -- } -- g_free(filename); -- -- /* map the last 128KB of the BIOS in ISA space */ -- x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, -- !isapc_ram_fw); -- -- /* map all the bios at the top of memory */ -- memory_region_add_subregion(rom_memory, -- (uint32_t)(-bios_size), -- &x86ms->bios); -- return; -- --bios_error: -- fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); -- exit(1); --} -- - bool x86_machine_is_smm_enabled(const X86MachineState *x86ms) - { - bool smm_available = false; -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index c2062db13f..b006f16b8d 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -21,6 +21,7 @@ - #include "exec/memory.h" - - #include "hw/boards.h" -+#include "hw/i386/topology.h" - #include "hw/intc/ioapic.h" - #include "hw/isa/isa.h" - #include "qom/object.h" -@@ -109,12 +110,11 @@ struct X86MachineState { - #define TYPE_X86_MACHINE MACHINE_TYPE_NAME("x86") - OBJECT_DECLARE_TYPE(X86MachineState, X86MachineClass, X86_MACHINE) - --uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms, -+void init_topo_info(X86CPUTopoInfo *topo_info, const X86MachineState *x86ms); -+uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, - unsigned int cpu_index); - --void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, Error **errp); - void x86_cpus_init(X86MachineState *pcms, int default_cpu_version); --CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx); - void x86_rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count); - void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp); --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-x86-Don-t-leak-isa-bios-memory-regions.patch b/SOURCES/kvm-hw-i386-x86-Don-t-leak-isa-bios-memory-regions.patch deleted file mode 100644 index 38fd870..0000000 --- a/SOURCES/kvm-hw-i386-x86-Don-t-leak-isa-bios-memory-regions.patch +++ /dev/null @@ -1,133 +0,0 @@ -From ebf08d2a822576acfa60fbd5f552d26de1e4c4be Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Wed, 8 May 2024 19:55:04 +0200 -Subject: [PATCH 040/100] hw/i386/x86: Don't leak "isa-bios" memory regions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [40/91] bb595357c6cc2d5a80bf3873853c69553c5feee5 (bonzini/rhel-qemu-kvm) - -Fix the leaking in x86_bios_rom_init() and pc_isa_bios_init() by adding an -"isa_bios" attribute to X86MachineState. - -Suggested-by: Philippe Mathieu-Daudé -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Bernhard Beschow -Message-ID: <20240508175507.22270-4-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit 32d3ee87a17fc91e981a23dba94855bff89f5920) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc_sysfw.c | 7 +++---- - hw/i386/x86.c | 9 ++++----- - include/hw/i386/x86.h | 7 +++++++ - 3 files changed, 14 insertions(+), 9 deletions(-) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index 59c7a81692..82d37cb376 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -40,11 +40,10 @@ - - #define FLASH_SECTOR_SIZE 4096 - --static void pc_isa_bios_init(MemoryRegion *rom_memory, -+static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory, - MemoryRegion *flash_mem) - { - int isa_bios_size; -- MemoryRegion *isa_bios; - uint64_t flash_size; - void *flash_ptr, *isa_bios_ptr; - -@@ -52,7 +51,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory, - - /* map the last 128KB of the BIOS in ISA space */ - isa_bios_size = MIN(flash_size, 128 * KiB); -- isa_bios = g_malloc(sizeof(*isa_bios)); - memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size, - &error_fatal); - memory_region_add_subregion_overlap(rom_memory, -@@ -136,6 +134,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms) - static void pc_system_flash_map(PCMachineState *pcms, - MemoryRegion *rom_memory) - { -+ X86MachineState *x86ms = X86_MACHINE(pcms); - hwaddr total_size = 0; - int i; - BlockBackend *blk; -@@ -185,7 +184,7 @@ static void pc_system_flash_map(PCMachineState *pcms, - - if (i == 0) { - flash_mem = pflash_cfi01_get_memory(system_flash); -- pc_isa_bios_init(rom_memory, flash_mem); -+ pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem); - - /* Encrypt the pflash boot ROM */ - if (sev_enabled()) { -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 6d3c72f124..457e8a34a5 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1133,7 +1133,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - { - const char *bios_name; - char *filename; -- MemoryRegion *bios, *isa_bios; -+ MemoryRegion *bios; - int bios_size, isa_bios_size; - ssize_t ret; - -@@ -1173,14 +1173,13 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - - /* map the last 128KB of the BIOS in ISA space */ - isa_bios_size = MIN(bios_size, 128 * KiB); -- isa_bios = g_malloc(sizeof(*isa_bios)); -- memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, -+ memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios, - bios_size - isa_bios_size, isa_bios_size); - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, -- isa_bios, -+ &x86ms->isa_bios, - 1); -- memory_region_set_readonly(isa_bios, !isapc_ram_fw); -+ memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw); - - /* map all the bios at the top of memory */ - memory_region_add_subregion(rom_memory, -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index cb07618d19..a07de79167 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -18,6 +18,7 @@ - #define HW_I386_X86_H - - #include "exec/hwaddr.h" -+#include "exec/memory.h" - - #include "hw/boards.h" - #include "hw/intc/ioapic.h" -@@ -52,6 +53,12 @@ struct X86MachineState { - GMappedFile *initrd_mapped_file; - HotplugHandler *acpi_dev; - -+ /* -+ * Map the upper 128 KiB of the BIOS just underneath the 1 MiB address -+ * boundary. -+ */ -+ MemoryRegion isa_bios; -+ - /* RAM information (sizes, addresses, configuration): */ - ram_addr_t below_4g_mem_size, above_4g_mem_size; - --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-x86-Don-t-leak-pc.bios-memory-region.patch b/SOURCES/kvm-hw-i386-x86-Don-t-leak-pc.bios-memory-region.patch deleted file mode 100644 index 7a61f95..0000000 --- a/SOURCES/kvm-hw-i386-x86-Don-t-leak-pc.bios-memory-region.patch +++ /dev/null @@ -1,105 +0,0 @@ -From e1f2265b5f6bf5b63bf3808bb540888f3cf8badb Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Wed, 8 May 2024 19:55:05 +0200 -Subject: [PATCH 041/100] hw/i386/x86: Don't leak "pc.bios" memory region -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [41/91] a9cd61d8d240134c09c46e244efb89217cadf60c (bonzini/rhel-qemu-kvm) - -Fix the leaking in x86_bios_rom_init() by adding a "bios" attribute to -X86MachineState. Note that it is only used in the -bios case. - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Bernhard Beschow -Message-ID: <20240508175507.22270-5-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit 865d95321ffc8d9941e33000b10140550f094556) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86.c | 13 ++++++------- - include/hw/i386/x86.h | 6 ++++++ - 2 files changed, 12 insertions(+), 7 deletions(-) - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 457e8a34a5..29167de97d 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1133,7 +1133,6 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - { - const char *bios_name; - char *filename; -- MemoryRegion *bios; - int bios_size, isa_bios_size; - ssize_t ret; - -@@ -1149,8 +1148,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - (bios_size % 65536) != 0) { - goto bios_error; - } -- bios = g_malloc(sizeof(*bios)); -- memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); -+ memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, -+ &error_fatal); - if (sev_enabled()) { - /* - * The concept of a "reset" simply doesn't exist for -@@ -1159,11 +1158,11 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - * the firmware as rom to properly re-initialize on reset. - * Just go for a straight file load instead. - */ -- void *ptr = memory_region_get_ram_ptr(bios); -+ void *ptr = memory_region_get_ram_ptr(&x86ms->bios); - load_image_size(filename, ptr, bios_size); - x86_firmware_configure(ptr, bios_size); - } else { -- memory_region_set_readonly(bios, !isapc_ram_fw); -+ memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw); - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); - if (ret != 0) { - goto bios_error; -@@ -1173,7 +1172,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - - /* map the last 128KB of the BIOS in ISA space */ - isa_bios_size = MIN(bios_size, 128 * KiB); -- memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", bios, -+ memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios, - bios_size - isa_bios_size, isa_bios_size); - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, -@@ -1184,7 +1183,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - /* map all the bios at the top of memory */ - memory_region_add_subregion(rom_memory, - (uint32_t)(-bios_size), -- bios); -+ &x86ms->bios); - return; - - bios_error: -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index a07de79167..55c6809ae0 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -53,6 +53,12 @@ struct X86MachineState { - GMappedFile *initrd_mapped_file; - HotplugHandler *acpi_dev; - -+ /* -+ * Map the whole BIOS just underneath the 4 GiB address boundary. Only used -+ * in the ROM (-bios) case. -+ */ -+ MemoryRegion bios; -+ - /* - * Map the upper 128 KiB of the BIOS just underneath the 1 MiB address - * boundary. --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-x86-Eliminate-two-if-statements-in-x86_bios_.patch b/SOURCES/kvm-hw-i386-x86-Eliminate-two-if-statements-in-x86_bios_.patch deleted file mode 100644 index b9c18e7..0000000 --- a/SOURCES/kvm-hw-i386-x86-Eliminate-two-if-statements-in-x86_bios_.patch +++ /dev/null @@ -1,69 +0,0 @@ -From b9d0c78f04160fbc1eee6cfd94b17f1133a35d83 Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Tue, 30 Apr 2024 17:06:38 +0200 -Subject: [PATCH 037/100] hw/i386/x86: Eliminate two if statements in - x86_bios_rom_init() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [37/91] 1ef6a13214e85f6ef773f5c894c720f20330912b (bonzini/rhel-qemu-kvm) - -Given that memory_region_set_readonly() is a no-op when the readonlyness is -already as requested it is possible to simplify the pattern - - if (condition) { - foo(true); - } - -to - - foo(condition); - -which is shorter and allows to see the invariant of the code more easily. - -Signed-off-by: Bernhard Beschow -Reviewed-by: Philippe Mathieu-Daudé -Message-ID: <20240430150643.111976-2-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit 014dbdac8798799d081abc9dff3e4876ca54f49e) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 3d5b51e92d..2a4f3ee285 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1163,9 +1163,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, - load_image_size(filename, ptr, bios_size); - x86_firmware_configure(ptr, bios_size); - } else { -- if (!isapc_ram_fw) { -- memory_region_set_readonly(bios, true); -- } -+ memory_region_set_readonly(bios, !isapc_ram_fw); - ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); - if (ret != 0) { - goto bios_error; -@@ -1182,9 +1180,7 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware, - 0x100000 - isa_bios_size, - isa_bios, - 1); -- if (!isapc_ram_fw) { -- memory_region_set_readonly(isa_bios, true); -- } -+ memory_region_set_readonly(isa_bios, !isapc_ram_fw); - - /* map all the bios at the top of memory */ - memory_region_add_subregion(rom_memory, --- -2.39.3 - diff --git a/SOURCES/kvm-hw-i386-x86-Extract-x86_isa_bios_init-from-x86_bios_.patch b/SOURCES/kvm-hw-i386-x86-Extract-x86_isa_bios_init-from-x86_bios_.patch deleted file mode 100644 index 6ce9c72..0000000 --- a/SOURCES/kvm-hw-i386-x86-Extract-x86_isa_bios_init-from-x86_bios_.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 1baf67564d4227d6ba98923217a15814c438c32b Mon Sep 17 00:00:00 2001 -From: Bernhard Beschow -Date: Wed, 8 May 2024 19:55:06 +0200 -Subject: [PATCH 042/100] hw/i386/x86: Extract x86_isa_bios_init() from - x86_bios_rom_init() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [42/91] 1db417a5995480924f7fd0661a306f2d2bfa0a77 (bonzini/rhel-qemu-kvm) - -The function is inspired by pc_isa_bios_init() and should eventually replace it. -Using x86_isa_bios_init() rather than pc_isa_bios_init() fixes pflash commands -to work in the isa-bios region. - -While at it convert the magic number 0x100000 (== 1MiB) to increase readability. - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Bernhard Beschow -Message-ID: <20240508175507.22270-6-shentey@gmail.com> -Signed-off-by: Philippe Mathieu-Daudé -(cherry picked from commit 5c5ffec12c30d2017cbdee6798f54d8fad3f9656) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86.c | 25 ++++++++++++++++--------- - include/hw/i386/x86.h | 2 ++ - 2 files changed, 18 insertions(+), 9 deletions(-) - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 29167de97d..c61f4ebfa6 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1128,12 +1128,25 @@ void x86_load_linux(X86MachineState *x86ms, - nb_option_roms++; - } - -+void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, -+ MemoryRegion *bios, bool read_only) -+{ -+ uint64_t bios_size = memory_region_size(bios); -+ uint64_t isa_bios_size = MIN(bios_size, 128 * KiB); -+ -+ memory_region_init_alias(isa_bios, NULL, "isa-bios", bios, -+ bios_size - isa_bios_size, isa_bios_size); -+ memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size, -+ isa_bios, 1); -+ memory_region_set_readonly(isa_bios, read_only); -+} -+ - void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - MemoryRegion *rom_memory, bool isapc_ram_fw) - { - const char *bios_name; - char *filename; -- int bios_size, isa_bios_size; -+ int bios_size; - ssize_t ret; - - /* BIOS load */ -@@ -1171,14 +1184,8 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - g_free(filename); - - /* map the last 128KB of the BIOS in ISA space */ -- isa_bios_size = MIN(bios_size, 128 * KiB); -- memory_region_init_alias(&x86ms->isa_bios, NULL, "isa-bios", &x86ms->bios, -- bios_size - isa_bios_size, isa_bios_size); -- memory_region_add_subregion_overlap(rom_memory, -- 0x100000 - isa_bios_size, -- &x86ms->isa_bios, -- 1); -- memory_region_set_readonly(&x86ms->isa_bios, !isapc_ram_fw); -+ x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios, -+ !isapc_ram_fw); - - /* map all the bios at the top of memory */ - memory_region_add_subregion(rom_memory, -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index 55c6809ae0..d7b7d3f3ce 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -129,6 +129,8 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, - void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp); - -+void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory, -+ MemoryRegion *bios, bool read_only); - void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, - MemoryRegion *rom_memory, bool isapc_ram_fw); - --- -2.39.3 - diff --git a/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch b/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch new file mode 100644 index 0000000..2b89353 --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch @@ -0,0 +1,270 @@ +From ca648a6167953204a9ec55131e9aa836f63ab7e8 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:49 -0400 +Subject: [PATCH 16/27] hw/s390x: Build an IPLB for each boot device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [16/23] 4b87f66a28d9a34b0182e0a2c92af406d2e492a6 (thuth/qemu-kvm-cs9) + +Build an IPLB for any device with a bootindex (up to a maximum of 8 devices). + +The IPLB chain is placed immediately before the BIOS in memory. Because this +is not a fixed address, the location of the next IPLB and number of remaining +boot devices is stored in the QIPL global variable for possible later access by +the guest during IPL. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-16-jrossi@linux.ibm.com> +[thuth: Fix endianness problem when accessing the qipl structure] +Signed-off-by: Thomas Huth +(cherry picked from commit 0927875e704e93ace03bb7533c0877bf97e4bda9) +--- + hw/s390x/ipl.c | 129 ++++++++++++++++++++++++++++-------- + hw/s390x/ipl.h | 1 + + include/hw/s390x/ipl/qipl.h | 4 +- + 3 files changed, 105 insertions(+), 29 deletions(-) + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index d83832d975..f4576f8822 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -56,6 +56,13 @@ static bool iplb_extended_needed(void *opaque) + return ipl->iplbext_migration; + } + ++/* Place the IPLB chain immediately before the BIOS in memory */ ++static uint64_t find_iplb_chain_addr(uint64_t bios_addr, uint16_t count) ++{ ++ return (bios_addr & TARGET_PAGE_MASK) ++ - (count * sizeof(IplParameterBlock)); ++} ++ + static const VMStateDescription vmstate_iplb_extended = { + .name = "ipl/iplb_extended", + .version_id = 0, +@@ -398,6 +405,17 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype) + return ccw_dev; + } + ++static uint64_t s390_ipl_map_iplb_chain(IplParameterBlock *iplb_chain) ++{ ++ S390IPLState *ipl = get_ipl_device(); ++ uint16_t count = be16_to_cpu(ipl->qipl.chain_len); ++ uint64_t len = sizeof(IplParameterBlock) * count; ++ uint64_t chain_addr = find_iplb_chain_addr(ipl->bios_start_addr, count); ++ ++ cpu_physical_memory_write(chain_addr, iplb_chain, len); ++ return chain_addr; ++} ++ + void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp) + { + int i; +@@ -428,54 +446,51 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) + } + } + +-static bool s390_gen_initial_iplb(S390IPLState *ipl) ++static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + { +- DeviceState *dev_st; ++ S390IPLState *ipl = get_ipl_device(); + CcwDevice *ccw_dev = NULL; + SCSIDevice *sd; + int devtype; + uint8_t *lp; + +- dev_st = get_boot_device(0); +- if (dev_st) { +- ccw_dev = s390_get_ccw_device(dev_st, &devtype); +- } +- + /* + * Currently allow IPL only from CCW devices. + */ ++ ccw_dev = s390_get_ccw_device(dev_st, &devtype); + if (ccw_dev) { + lp = ccw_dev->loadparm; + + switch (devtype) { + case CCW_DEVTYPE_SCSI: + sd = SCSI_DEVICE(dev_st); +- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); +- ipl->iplb.blk0_len = ++ iplb->len = cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN); ++ iplb->blk0_len = + cpu_to_be32(S390_IPLB_MIN_QEMU_SCSI_LEN - S390_IPLB_HEADER_LEN); +- ipl->iplb.pbt = S390_IPL_TYPE_QEMU_SCSI; +- ipl->iplb.scsi.lun = cpu_to_be32(sd->lun); +- ipl->iplb.scsi.target = cpu_to_be16(sd->id); +- ipl->iplb.scsi.channel = cpu_to_be16(sd->channel); +- ipl->iplb.scsi.devno = cpu_to_be16(ccw_dev->sch->devno); +- ipl->iplb.scsi.ssid = ccw_dev->sch->ssid & 3; ++ iplb->pbt = S390_IPL_TYPE_QEMU_SCSI; ++ iplb->scsi.lun = cpu_to_be32(sd->lun); ++ iplb->scsi.target = cpu_to_be16(sd->id); ++ iplb->scsi.channel = cpu_to_be16(sd->channel); ++ iplb->scsi.devno = cpu_to_be16(ccw_dev->sch->devno); ++ iplb->scsi.ssid = ccw_dev->sch->ssid & 3; + break; + case CCW_DEVTYPE_VFIO: +- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); +- ipl->iplb.pbt = S390_IPL_TYPE_CCW; +- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); +- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; ++ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); ++ iplb->pbt = S390_IPL_TYPE_CCW; ++ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno); ++ iplb->ccw.ssid = ccw_dev->sch->ssid & 3; + break; + case CCW_DEVTYPE_VIRTIO_NET: ++ /* The S390IPLState netboot is true if ANY IPLB may use netboot */ + ipl->netboot = true; + /* Fall through to CCW_DEVTYPE_VIRTIO case */ + case CCW_DEVTYPE_VIRTIO: +- ipl->iplb.len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); +- ipl->iplb.blk0_len = ++ iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); ++ iplb->blk0_len = + cpu_to_be32(S390_IPLB_MIN_CCW_LEN - S390_IPLB_HEADER_LEN); +- ipl->iplb.pbt = S390_IPL_TYPE_CCW; +- ipl->iplb.ccw.devno = cpu_to_be16(ccw_dev->sch->devno); +- ipl->iplb.ccw.ssid = ccw_dev->sch->ssid & 3; ++ iplb->pbt = S390_IPL_TYPE_CCW; ++ iplb->ccw.devno = cpu_to_be16(ccw_dev->sch->devno); ++ iplb->ccw.ssid = ccw_dev->sch->ssid & 3; + break; + } + +@@ -484,8 +499,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) + lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm; + } + +- s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm); +- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; ++ s390_ipl_convert_loadparm((char *)lp, iplb->loadparm); ++ iplb->flags |= DIAG308_FLAGS_LP_VALID; + + return true; + } +@@ -493,6 +508,62 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) + return false; + } + ++static bool s390_init_all_iplbs(S390IPLState *ipl) ++{ ++ int iplb_num = 0; ++ IplParameterBlock iplb_chain[7]; ++ DeviceState *dev_st = get_boot_device(0); ++ Object *machine = qdev_get_machine(); ++ ++ /* ++ * Parse the boot devices. Generate an IPLB for only the first boot device ++ * which will later be set with DIAG308. ++ */ ++ if (!dev_st) { ++ ipl->qipl.chain_len = 0; ++ return false; ++ } ++ ++ /* If no machine loadparm was defined fill it with spaces */ ++ if (memcmp(S390_CCW_MACHINE(machine)->loadparm, NO_LOADPARM, 8) == 0) { ++ object_property_set_str(machine, "loadparm", " ", NULL); ++ } ++ ++ iplb_num = 1; ++ s390_build_iplb(dev_st, &ipl->iplb); ++ ++ /* Index any fallback boot devices */ ++ while (get_boot_device(iplb_num)) { ++ iplb_num++; ++ } ++ ++ if (iplb_num > MAX_BOOT_DEVS) { ++ warn_report("Excess boot devices defined! %d boot devices found, " ++ "but only the first %d will be considered.", ++ iplb_num, MAX_BOOT_DEVS); ++ ++ iplb_num = MAX_BOOT_DEVS; ++ } ++ ++ ipl->qipl.chain_len = cpu_to_be16(iplb_num - 1); ++ ++ /* ++ * Build fallback IPLBs for any boot devices above index 0, up to a ++ * maximum amount as defined in ipl.h ++ */ ++ if (iplb_num > 1) { ++ /* Start at 1 because the IPLB for boot index 0 is not chained */ ++ for (int i = 1; i < iplb_num; i++) { ++ dev_st = get_boot_device(i); ++ s390_build_iplb(dev_st, &iplb_chain[i - 1]); ++ } ++ ++ ipl->qipl.next_iplb = cpu_to_be64(s390_ipl_map_iplb_chain(iplb_chain)); ++ } ++ ++ return iplb_num; ++} ++ + static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, + int virtio_id) + { +@@ -620,7 +691,7 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) + * this is the original boot device's SCSI + * so restore IPL parameter info from it + */ +- ipl->iplb_valid = s390_gen_initial_iplb(ipl); ++ ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb); + } + } + if (reset_type == S390_RESET_MODIFIED_CLEAR || +@@ -714,7 +785,9 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) + if (!ipl->kernel || ipl->iplb_valid) { + cpu->env.psw.addr = ipl->bios_start_addr; + if (!ipl->iplb_valid) { +- ipl->iplb_valid = s390_gen_initial_iplb(ipl); ++ ipl->iplb_valid = s390_init_all_iplbs(ipl); ++ } else { ++ ipl->qipl.chain_len = 0; + } + } + s390_ipl_set_boot_menu(ipl); +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index b670bad551..54eb48fd6e 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -20,6 +20,7 @@ + #include "qom/object.h" + + #define DIAG308_FLAGS_LP_VALID 0x80 ++#define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */ + + void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); + void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); +diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h +index b67d2ae061..1da4f75aa8 100644 +--- a/include/hw/s390x/ipl/qipl.h ++++ b/include/hw/s390x/ipl/qipl.h +@@ -32,7 +32,9 @@ struct QemuIplParameters { + uint8_t reserved1[3]; + uint64_t reserved2; + uint32_t boot_menu_timeout; +- uint8_t reserved3[12]; ++ uint8_t reserved3[2]; ++ uint16_t chain_len; ++ uint64_t next_iplb; + } QEMU_PACKED; + typedef struct QemuIplParameters QemuIplParameters; + +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch b/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch new file mode 100644 index 0000000..b5b820d --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch @@ -0,0 +1,201 @@ +From 99d6e739324ff1be46ad89a2682978cc1fa3a56c Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Thu, 20 Jun 2024 16:59:28 +0200 +Subject: [PATCH 05/27] hw/s390x: Remove the possibility to load the + s390-netboot.img binary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/23] e4e037f24be08626c02f8e870992e8f0a5ed505e (thuth/qemu-kvm-cs9) + +Since the netboot code has now been merged into the main s390-ccw.img +binary, we don't need the separate s390-netboot.img anymore. Remove +it and the code that was responsible for loading it. + +Message-Id: <20240621082422.136217-6-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 188e255bf8ed68fa64bcb63577cb100eeb326254) +--- + hw/s390x/ipl.c | 55 -------------------------------------- + hw/s390x/ipl.h | 12 +++------ + hw/s390x/s390-virtio-ccw.c | 10 ++----- + pc-bios/meson.build | 1 - + 4 files changed, 6 insertions(+), 72 deletions(-) + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index 9362de0b6f..8a0a3e6961 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -288,7 +288,6 @@ static Property s390_ipl_properties[] = { + DEFINE_PROP_STRING("initrd", S390IPLState, initrd), + DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline), + DEFINE_PROP_STRING("firmware", S390IPLState, firmware), +- DEFINE_PROP_STRING("netboot_fw", S390IPLState, netboot_fw), + DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false), + DEFINE_PROP_BOOL("iplbext_migration", S390IPLState, iplbext_migration, + true), +@@ -480,56 +479,6 @@ int s390_ipl_set_loadparm(uint8_t *loadparm) + return -1; + } + +-static int load_netboot_image(Error **errp) +-{ +- MachineState *ms = MACHINE(qdev_get_machine()); +- S390IPLState *ipl = get_ipl_device(); +- char *netboot_filename; +- MemoryRegion *sysmem = get_system_memory(); +- MemoryRegion *mr = NULL; +- void *ram_ptr = NULL; +- int img_size = -1; +- +- mr = memory_region_find(sysmem, 0, 1).mr; +- if (!mr) { +- error_setg(errp, "Failed to find memory region at address 0"); +- return -1; +- } +- +- ram_ptr = memory_region_get_ram_ptr(mr); +- if (!ram_ptr) { +- error_setg(errp, "No RAM found"); +- goto unref_mr; +- } +- +- netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw); +- if (netboot_filename == NULL) { +- error_setg(errp, "Could not find network bootloader '%s'", +- ipl->netboot_fw); +- goto unref_mr; +- } +- +- img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL, +- &ipl->start_addr, +- NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL, +- false); +- +- if (img_size < 0) { +- img_size = load_image_size(netboot_filename, ram_ptr, ms->ram_size); +- ipl->start_addr = KERN_IMAGE_START; +- } +- +- if (img_size < 0) { +- error_setg(errp, "Failed to load network bootloader"); +- } +- +- g_free(netboot_filename); +- +-unref_mr: +- memory_region_unref(mr); +- return img_size; +-} +- + static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, + int virtio_id) + { +@@ -754,10 +703,6 @@ void s390_ipl_prepare_cpu(S390CPU *cpu) + ipl->iplb_valid = s390_gen_initial_iplb(ipl); + } + } +- if (ipl->netboot) { +- load_netboot_image(&error_fatal); +- ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr); +- } + s390_ipl_set_boot_menu(ipl); + s390_ipl_prepare_qipl(cpu); + } +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index 57cd125769..b2105b616a 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -134,11 +134,8 @@ void s390_ipl_clear_reset_request(void); + /* + * The QEMU IPL Parameters will be stored at absolute address + * 204 (0xcc) which means it is 32-bit word aligned but not +- * double-word aligned. +- * Placement of data fields in this area must account for +- * their alignment needs. E.g., netboot_start_address must +- * have an offset of 4 + n * 8 bytes within the struct in order +- * to keep it double-word aligned. ++ * double-word aligned. Placement of 64-bit data fields in this ++ * area must account for their alignment needs. + * The total size of the struct must never exceed 28 bytes. + * This definition must be kept in sync with the definition + * in pc-bios/s390-ccw/iplb.h. +@@ -146,9 +143,9 @@ void s390_ipl_clear_reset_request(void); + struct QemuIplParameters { + uint8_t qipl_flags; + uint8_t reserved1[3]; +- uint64_t netboot_start_addr; ++ uint64_t reserved2; + uint32_t boot_menu_timeout; +- uint8_t reserved2[12]; ++ uint8_t reserved3[12]; + } QEMU_PACKED; + typedef struct QemuIplParameters QemuIplParameters; + +@@ -178,7 +175,6 @@ struct S390IPLState { + char *initrd; + char *cmdline; + char *firmware; +- char *netboot_fw; + uint8_t cssid; + uint8_t ssid; + uint16_t devno; +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index a4a6ffa053..5113313aa8 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -197,11 +197,10 @@ static void s390_memory_init(MemoryRegion *ram) + static void s390_init_ipl_dev(const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, const char *firmware, +- const char *netboot_fw, bool enforce_bios) ++ bool enforce_bios) + { + Object *new = object_new(TYPE_S390_IPL); + DeviceState *dev = DEVICE(new); +- char *netboot_fw_prop; + + if (kernel_filename) { + qdev_prop_set_string(dev, "kernel", kernel_filename); +@@ -212,11 +211,6 @@ static void s390_init_ipl_dev(const char *kernel_filename, + qdev_prop_set_string(dev, "cmdline", kernel_cmdline); + qdev_prop_set_string(dev, "firmware", firmware); + qdev_prop_set_bit(dev, "enforce_bios", enforce_bios); +- netboot_fw_prop = object_property_get_str(new, "netboot_fw", &error_abort); +- if (!strlen(netboot_fw_prop)) { +- qdev_prop_set_string(dev, "netboot_fw", netboot_fw); +- } +- g_free(netboot_fw_prop); + object_property_add_child(qdev_get_machine(), TYPE_S390_IPL, + new); + object_unref(new); +@@ -284,7 +278,7 @@ static void ccw_init(MachineState *machine) + s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, + machine->initrd_filename, + machine->firmware ?: "s390-ccw.img", +- "s390-netboot.img", true); ++ true); + + dev = qdev_new(TYPE_S390_PCI_HOST_BRIDGE); + object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE, +diff --git a/pc-bios/meson.build b/pc-bios/meson.build +index 8602b45b9b..ea85c54c86 100644 +--- a/pc-bios/meson.build ++++ b/pc-bios/meson.build +@@ -66,7 +66,6 @@ blobs = [ + 'kvmvapic.bin', + 'pvh.bin', + 's390-ccw.img', +- 's390-netboot.img', + 'slof.bin', + 'skiboot.lid', + 'palcode-clipper', +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch b/SOURCES/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch new file mode 100644 index 0000000..3395dec --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch @@ -0,0 +1,113 @@ +From ffffba85b269096d25fef307b342b8f576610d34 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Wed, 13 Nov 2024 12:47:41 +0100 +Subject: [PATCH 04/10] hw/s390x: Restrict "loadparm" property to devices that + can be used for booting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/8] e381997b44f5b8c80a90ae99f5ae5d863f6d5aa5 (thuth/qemu-kvm-cs9) + +Commit bb185de423 ("s390x: Add individual loadparm assignment to +CCW device") added a "loadparm" property to all CCW devices. This +was a little bit unfortunate, since this property is only useful +for devices that can be used for booting, but certainly it is not +useful for devices like virtio-gpu or virtio-tablet. + +Thus let's restrict the property to CCW devices that we can boot from +(i.e. virtio-block, virtio-net and vfio-ccw devices). + +Message-ID: <20241113114741.681096-1-thuth@redhat.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Jared Rossi +Signed-off-by: Thomas Huth +(cherry picked from commit 6e7c96ae61e0542e97d385084f1f2281a0331054) +--- + hw/s390x/ccw-device.c | 4 +--- + hw/s390x/ccw-device.h | 5 +++++ + hw/s390x/virtio-ccw-blk.c | 1 + + hw/s390x/virtio-ccw-net.c | 1 + + hw/vfio/ccw.c | 1 + + 5 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c +index 4e54f34b1c..d7bb364579 100644 +--- a/hw/s390x/ccw-device.c ++++ b/hw/s390x/ccw-device.c +@@ -73,7 +73,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v, + s390_ipl_fmt_loadparm(dev->loadparm, val, errp); + } + +-static const PropertyInfo ccw_loadparm = { ++const PropertyInfo ccw_loadparm = { + .name = "ccw_loadparm", + .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass" + " to the guest loader/kernel", +@@ -85,8 +85,6 @@ static Property ccw_device_properties[] = { + DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno), + DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id), + DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id), +- DEFINE_PROP("loadparm", CcwDevice, loadparm, ccw_loadparm, +- typeof(uint8_t[8])), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h +index 1e1737c0f3..4439feb140 100644 +--- a/hw/s390x/ccw-device.h ++++ b/hw/s390x/ccw-device.h +@@ -51,4 +51,9 @@ static inline CcwDevice *to_ccw_dev_fast(DeviceState *d) + + OBJECT_DECLARE_TYPE(CcwDevice, CCWDeviceClass, CCW_DEVICE) + ++extern const PropertyInfo ccw_loadparm; ++ ++#define DEFINE_PROP_CCW_LOADPARM(_n, _s, _f) \ ++ DEFINE_PROP(_n, _s, _f, ccw_loadparm, typeof(uint8_t[8])) ++ + #endif +diff --git a/hw/s390x/virtio-ccw-blk.c b/hw/s390x/virtio-ccw-blk.c +index 8e0e58b77d..2364432c6e 100644 +--- a/hw/s390x/virtio-ccw-blk.c ++++ b/hw/s390x/virtio-ccw-blk.c +@@ -48,6 +48,7 @@ static Property virtio_ccw_blk_properties[] = { + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), ++ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/s390x/virtio-ccw-net.c b/hw/s390x/virtio-ccw-net.c +index 484e617659..a4a3f65c7e 100644 +--- a/hw/s390x/virtio-ccw-net.c ++++ b/hw/s390x/virtio-ccw-net.c +@@ -51,6 +51,7 @@ static Property virtio_ccw_net_properties[] = { + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), ++ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c +index 115862f430..99f16614ad 100644 +--- a/hw/vfio/ccw.c ++++ b/hw/vfio/ccw.c +@@ -662,6 +662,7 @@ static Property vfio_ccw_properties[] = { + DEFINE_PROP_LINK("iommufd", VFIOCCWDevice, vdev.iommufd, + TYPE_IOMMUFD_BACKEND, IOMMUFDBackend *), + #endif ++ DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), + DEFINE_PROP_END_OF_LIST(), + }; + +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch b/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch new file mode 100644 index 0000000..3e333d4 --- /dev/null +++ b/SOURCES/kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch @@ -0,0 +1,61 @@ +From 22693a98eca5872f87249006d873a95e71c448f2 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Fri, 21 Jun 2024 10:24:17 +0200 +Subject: [PATCH 01/27] hw/s390x/ipl: Provide more memory to the s390-ccw.img + firmware +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/23] b54cc7784876becb9fcec189811f505c22119b72 (thuth/qemu-kvm-cs9) + +We are going to link the SLOF libc into the s390-ccw.img, and this +libc needs more memory for providing space for malloc() and friends. +Thus bump the memory size that we reserve for the bios to 3 MiB +instead of only 2 MiB. While we're at it, add a proper check that +there is really enough memory assigned to the machine before blindly +using it. + +Message-ID: <20240621082422.136217-3-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit abaabb2e601adfe296a64471746a997eabcc607f) +--- + hw/s390x/ipl.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index e934bf89d1..9362de0b6f 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -45,6 +45,7 @@ + #define INITRD_PARM_START 0x010408UL + #define PARMFILE_START 0x001000UL + #define ZIPL_IMAGE_START 0x009000UL ++#define BIOS_MAX_SIZE 0x300000UL + #define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) + + static bool iplb_extended_needed(void *opaque) +@@ -144,7 +145,14 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) + * even if an external kernel has been defined. + */ + if (!ipl->kernel || ipl->enforce_bios) { +- uint64_t fwbase = (MIN(ms->ram_size, 0x80000000U) - 0x200000) & ~0xffffUL; ++ uint64_t fwbase; ++ ++ if (ms->ram_size < BIOS_MAX_SIZE) { ++ error_setg(errp, "not enough RAM to load the BIOS file"); ++ return; ++ } ++ ++ fwbase = (MIN(ms->ram_size, 0x80000000U) - BIOS_MAX_SIZE) & ~0xffffUL; + + bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->firmware); + if (bios_filename == NULL) { +-- +2.39.3 + diff --git a/SOURCES/kvm-hw-virtio-Fix-the-de-initialization-of-vhost-user-de.patch b/SOURCES/kvm-hw-virtio-Fix-the-de-initialization-of-vhost-user-de.patch deleted file mode 100644 index 7b2e1b6..0000000 --- a/SOURCES/kvm-hw-virtio-Fix-the-de-initialization-of-vhost-user-de.patch +++ /dev/null @@ -1,108 +0,0 @@ -From c554f8768a18ceba173aedbd582c1cae43a41e2c Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Tue, 18 Jun 2024 14:19:58 +0200 -Subject: [PATCH 1/2] hw/virtio: Fix the de-initialization of vhost-user - devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Thomas Huth -RH-MergeRequest: 255: hw/virtio: Fix the de-initialization of vhost-user devices -RH-Jira: RHEL-40708 -RH-Acked-by: Cédric Le Goater -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/1] c7815a249ec135993f45934cab1c1f2c038b80ea (thuth/qemu-kvm-cs9) - -JIRA: https://issues.redhat.com/browse/RHEL-40708 - -The unrealize functions of the various vhost-user devices are -calling the corresponding vhost_*_set_status() functions with a -status of 0 to shut down the device correctly. - -Now these vhost_*_set_status() functions all follow this scheme: - - bool should_start = virtio_device_should_start(vdev, status); - - if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) { - return; - } - - if (should_start) { - /* ... do the initialization stuff ... */ - } else { - /* ... do the cleanup stuff ... */ - } - -The problem here is virtio_device_should_start(vdev, 0) currently -always returns "true" since it internally only looks at vdev->started -instead of looking at the "status" parameter. Thus once the device -got started once, virtio_device_should_start() always returns true -and thus the vhost_*_set_status() functions return early, without -ever doing any clean-up when being called with status == 0. This -causes e.g. problems when trying to hot-plug and hot-unplug a vhost -user devices multiple times since the de-initialization step is -completely skipped during the unplug operation. - -This bug has been introduced in commit 9f6bcfd99f ("hw/virtio: move -vm_running check to virtio_device_started") which replaced - - should_start = status & VIRTIO_CONFIG_S_DRIVER_OK; - -with - - should_start = virtio_device_started(vdev, status); - -which later got replaced by virtio_device_should_start(). This blocked -the possibility to set should_start to false in case the status flag -VIRTIO_CONFIG_S_DRIVER_OK was not set. - -Fix it by adjusting the virtio_device_should_start() function to -only consider the status flag instead of vdev->started. Since this -function is only used in the various vhost_*_set_status() functions -for exactly the same purpose, it should be fine to fix it in this -central place there without any risk to change the behavior of other -code. - -Fixes: 9f6bcfd99f ("hw/virtio: move vm_running check to virtio_device_started") -Buglink: https://issues.redhat.com/browse/RHEL-40708 -Signed-off-by: Thomas Huth -Message-Id: <20240618121958.88673-1-thuth@redhat.com> -Reviewed-by: Manos Pitsidianakis -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit d72479b11797c28893e1e3fc565497a9cae5ca16) -Signed-off-by: Thomas Huth ---- - include/hw/virtio/virtio.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 7d5ffdc145..2eafad17b8 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -470,9 +470,9 @@ static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status) - * @vdev - the VirtIO device - * @status - the devices status bits - * -- * This is similar to virtio_device_started() but also encapsulates a -- * check on the VM status which would prevent a device starting -- * anyway. -+ * This is similar to virtio_device_started() but ignores vdev->started -+ * and also encapsulates a check on the VM status which would prevent a -+ * device from starting anyway. - */ - static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status) - { -@@ -480,7 +480,7 @@ static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status - return false; - } - -- return virtio_device_started(vdev, status); -+ return status & VIRTIO_CONFIG_S_DRIVER_OK; - } - - static inline void virtio_set_started(VirtIODevice *vdev, bool started) --- -2.39.3 - diff --git a/SOURCES/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch b/SOURCES/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch new file mode 100644 index 0000000..a88b622 --- /dev/null +++ b/SOURCES/kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch @@ -0,0 +1,103 @@ +From 714fff9a66f8894f5397d367182c550e3f1c1605 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 29 Nov 2024 13:55:05 +0000 +Subject: [PATCH 2/4] hw/virtio: fix crash in processing balloon stats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 321: hw/virtio: fix crash in processing balloon stats +RH-Jira: RHEL-73688 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: David Hildenbrand +RH-Acked-by: Daniel P. Berrangé +RH-Commit: [1/1] 590aaa6c243617dcc24ef4fcc3cffc51d10a4ba0 (thuth/qemu-kvm-cs9) + +balloon_stats_get_all will iterate over guest stats upto the max +VIRTIO_BALLOON_S_NR value, calling visit_type_uint64 to populate +the QObject dict. The dict keys are obtained from the static +array balloon_stat_names which is VIRTIO_BALLOON_S_NR in size. + +Unfortunately the way that array is declared results in any +unassigned stats getting a NULL name, which will then cause +visit_type_uint64 to trigger an assert in qobject_output_add_obj. + +The balloon_stat_names array was fortunately fully populated with +names until recently: + + commit 0d2eeef77a33315187df8519491a900bde4a3d83 + Author: Bibo Mao + Date: Mon Oct 28 10:38:09 2024 +0800 + + linux-headers: Update to Linux v6.12-rc5 + +pulled a change to include/standard-headers/linux/virtio_balloon.h +which increased VIRTIO_BALLOON_S_NR by 6, and failed to add the new +names to balloon_stat_names. + +This commit fills in the missing names, and uses a static assert to +guarantee that any future changes to VIRTIO_BALLOON_S_NR will cause +a build failure until balloon_stat_names is updated. + +This problem was detected by the Cockpit Project's automated +integration tests on QEMU 9.2.0-rc1. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2329448 +Fixes: 0d2eeef77a3 ("linux-headers: Update to Linux v6.12-rc5") +Reported-by: Martin Pitt +Reviewed-by: Richard W.M. Jones +Signed-off-by: Daniel P. Berrangé +Reviewed-by: David Hildenbrand +Reviewed-by: Michael Tokarev +Acked-by: Michael S. Tsirkin +Message-ID: <20241129135507.699030-2-berrange@redhat.com> +Signed-off-by: Philippe Mathieu-Daudé +(cherry picked from commit bff1050a5630ce5da6f43ed002725d52140bb9e6) +Signed-off-by: Thomas Huth +--- + hw/virtio/virtio-balloon.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c +index 609e39a821..afd2ad6dd6 100644 +--- a/hw/virtio/virtio-balloon.c ++++ b/hw/virtio/virtio-balloon.c +@@ -167,19 +167,33 @@ static void balloon_deflate_page(VirtIOBalloon *balloon, + } + } + ++/* ++ * All stats upto VIRTIO_BALLOON_S_NR /must/ have a ++ * non-NULL name declared here, since these are used ++ * as keys for populating the QDict with stats ++ */ + static const char *balloon_stat_names[] = { + [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in", + [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out", + [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults", + [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults", + [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory", ++ + [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory", + [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory", + [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches", + [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc", + [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail", +- [VIRTIO_BALLOON_S_NR] = NULL ++ ++ [VIRTIO_BALLOON_S_OOM_KILL] = "stat-oom-kills", ++ [VIRTIO_BALLOON_S_ALLOC_STALL] = "stat-alloc-stalls", ++ [VIRTIO_BALLOON_S_ASYNC_SCAN] = "stat-async-scans", ++ [VIRTIO_BALLOON_S_DIRECT_SCAN] = "stat-direct-scans", ++ [VIRTIO_BALLOON_S_ASYNC_RECLAIM] = "stat-async-reclaims", ++ ++ [VIRTIO_BALLOON_S_DIRECT_RECLAIM] = "stat-direct-reclaims", + }; ++G_STATIC_ASSERT(G_N_ELEMENTS(balloon_stat_names) == VIRTIO_BALLOON_S_NR); + + /* + * reset_stats - Mark all items in the stats array as unset +-- +2.39.3 + diff --git a/SOURCES/kvm-i386-correctly-select-code-in-hw-i386-that-depends-o.patch b/SOURCES/kvm-i386-correctly-select-code-in-hw-i386-that-depends-o.patch deleted file mode 100644 index 8f69f9e..0000000 --- a/SOURCES/kvm-i386-correctly-select-code-in-hw-i386-that-depends-o.patch +++ /dev/null @@ -1,68 +0,0 @@ -From f572a40924c7138072e387111d0f092185972477 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 9 May 2024 19:00:39 +0200 -Subject: [PATCH 044/100] i386: correctly select code in hw/i386 that depends - on other components - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [44/91] 1327a5eb2b91edacf56cc4e93255cad456abbbeb (bonzini/rhel-qemu-kvm) - -fw_cfg.c and vapic.c are currently included unconditionally but -depend on other components. vapic.c depends on the local APIC, -while fw_cfg.c includes a piece of AML builder code that depends -on CONFIG_ACPI. - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Message-ID: <20240509170044.190795-9-pbonzini@redhat.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 7974e51342775c87f6e759a8c525db1045ddfa24) -Signed-off-by: Paolo Bonzini ---- - hw/i386/fw_cfg.c | 2 ++ - hw/i386/meson.build | 2 +- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c -index 283c3f4c16..7f97d40616 100644 ---- a/hw/i386/fw_cfg.c -+++ b/hw/i386/fw_cfg.c -@@ -204,6 +204,7 @@ void fw_cfg_build_feature_control(MachineState *ms, FWCfgState *fw_cfg) - fw_cfg_add_file(fw_cfg, "etc/msr_feature_control", val, sizeof(*val)); - } - -+#ifdef CONFIG_ACPI - void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg) - { - /* -@@ -230,3 +231,4 @@ void fw_cfg_add_acpi_dsdt(Aml *scope, FWCfgState *fw_cfg) - aml_append(dev, aml_name_decl("_CRS", crs)); - aml_append(scope, dev); - } -+#endif -diff --git a/hw/i386/meson.build b/hw/i386/meson.build -index d8b70ef3e9..d9da676038 100644 ---- a/hw/i386/meson.build -+++ b/hw/i386/meson.build -@@ -1,12 +1,12 @@ - i386_ss = ss.source_set() - i386_ss.add(files( - 'fw_cfg.c', -- 'vapic.c', - 'e820_memory_layout.c', - 'multiboot.c', - 'x86.c', - )) - -+i386_ss.add(when: 'CONFIG_APIC', if_true: files('vapic.c')) - i386_ss.add(when: 'CONFIG_X86_IOMMU', if_true: files('x86-iommu.c'), - if_false: files('x86-iommu-stub.c')) - i386_ss.add(when: 'CONFIG_AMD_IOMMU', if_true: files('amd_iommu.c'), --- -2.39.3 - diff --git a/SOURCES/kvm-i386-cpu-Set-SEV-SNP-CPUID-bit-when-SNP-enabled.patch b/SOURCES/kvm-i386-cpu-Set-SEV-SNP-CPUID-bit-when-SNP-enabled.patch deleted file mode 100644 index 31a7e92..0000000 --- a/SOURCES/kvm-i386-cpu-Set-SEV-SNP-CPUID-bit-when-SNP-enabled.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 127f3c60668e1bd08ec00856a317cb841adf0440 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:23 -0500 -Subject: [PATCH 063/100] i386/cpu: Set SEV-SNP CPUID bit when SNP enabled - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [63/91] 0f834a6897c5cdc0e29a5b1862e621f8ce309657 (bonzini/rhel-qemu-kvm) - -SNP guests will rely on this bit to determine certain feature support. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-12-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 7831221941cccbde922412c1550ed8b4bce7c361) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 489c853b42..13737cd703 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6822,6 +6822,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - if (sev_enabled()) { - *eax = 0x2; - *eax |= sev_es_enabled() ? 0x8 : 0; -+ *eax |= sev_snp_enabled() ? 0x10 : 0; - *ebx = sev_get_cbit_position() & 0x3f; /* EBX[5:0] */ - *ebx |= (sev_get_reduced_phys_bits() & 0x3f) << 6; /* EBX[11:6] */ - } --- -2.39.3 - diff --git a/SOURCES/kvm-i386-kvm-Add-KVM_EXIT_HYPERCALL-handling-for-KVM_HC_.patch b/SOURCES/kvm-i386-kvm-Add-KVM_EXIT_HYPERCALL-handling-for-KVM_HC_.patch deleted file mode 100644 index fd604d2..0000000 --- a/SOURCES/kvm-i386-kvm-Add-KVM_EXIT_HYPERCALL-handling-for-KVM_HC_.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 14aa42bbacde75b2ce9a59d1267f73d613026461 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:42 -0500 -Subject: [PATCH 076/100] i386/kvm: Add KVM_EXIT_HYPERCALL handling for - KVM_HC_MAP_GPA_RANGE - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [76/91] 3e1201c330dc826af1ec4650974d47053270eb16 (bonzini/rhel-qemu-kvm) - -KVM_HC_MAP_GPA_RANGE will be used to send requests to userspace for -private/shared memory attribute updates requested by the guest. -Implement handling for that use-case along with some basic -infrastructure for enabling specific hypercall events. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-31-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 47e76d03b155e43beca550251a6eb7ea926c059f) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 55 ++++++++++++++++++++++++++++++++++++ - target/i386/kvm/kvm_i386.h | 1 + - target/i386/kvm/trace-events | 1 + - 3 files changed, 57 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 75e75d9772..2935e3931a 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -21,6 +21,7 @@ - #include - - #include -+#include - #include "standard-headers/asm-x86/kvm_para.h" - #include "hw/xen/interface/arch-x86/cpuid.h" - -@@ -208,6 +209,13 @@ int kvm_get_vm_type(MachineState *ms) - return kvm_type; - } - -+bool kvm_enable_hypercall(uint64_t enable_mask) -+{ -+ KVMState *s = KVM_STATE(current_accel()); -+ -+ return !kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, enable_mask); -+} -+ - bool kvm_has_smm(void) - { - return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM); -@@ -5325,6 +5333,50 @@ static bool host_supports_vmx(void) - return ecx & CPUID_EXT_VMX; - } - -+/* -+ * Currently the handling here only supports use of KVM_HC_MAP_GPA_RANGE -+ * to service guest-initiated memory attribute update requests so that -+ * KVM_SET_MEMORY_ATTRIBUTES can update whether or not a page should be -+ * backed by the private memory pool provided by guest_memfd, and as such -+ * is only applicable to guest_memfd-backed guests (e.g. SNP/TDX). -+ * -+ * Other other use-cases for KVM_HC_MAP_GPA_RANGE, such as for SEV live -+ * migration, are not implemented here currently. -+ * -+ * For the guest_memfd use-case, these exits will generally be synthesized -+ * by KVM based on platform-specific hypercalls, like GHCB requests in the -+ * case of SEV-SNP, and not issued directly within the guest though the -+ * KVM_HC_MAP_GPA_RANGE hypercall. So in this case, KVM_HC_MAP_GPA_RANGE is -+ * not actually advertised to guests via the KVM CPUID feature bit, as -+ * opposed to SEV live migration where it would be. Since it is unlikely the -+ * SEV live migration use-case would be useful for guest-memfd backed guests, -+ * because private/shared page tracking is already provided through other -+ * means, these 2 use-cases should be treated as being mutually-exclusive. -+ */ -+static int kvm_handle_hc_map_gpa_range(struct kvm_run *run) -+{ -+ uint64_t gpa, size, attributes; -+ -+ if (!machine_require_guest_memfd(current_machine)) -+ return -EINVAL; -+ -+ gpa = run->hypercall.args[0]; -+ size = run->hypercall.args[1] * TARGET_PAGE_SIZE; -+ attributes = run->hypercall.args[2]; -+ -+ trace_kvm_hc_map_gpa_range(gpa, size, attributes, run->hypercall.flags); -+ -+ return kvm_convert_memory(gpa, size, attributes & KVM_MAP_GPA_RANGE_ENCRYPTED); -+} -+ -+static int kvm_handle_hypercall(struct kvm_run *run) -+{ -+ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE) -+ return kvm_handle_hc_map_gpa_range(run); -+ -+ return -EINVAL; -+} -+ - #define VMX_INVALID_GUEST_STATE 0x80000021 - - int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) -@@ -5420,6 +5472,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - ret = kvm_xen_handle_exit(cpu, &run->xen); - break; - #endif -+ case KVM_EXIT_HYPERCALL: -+ ret = kvm_handle_hypercall(run); -+ break; - default: - fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); - ret = -1; -diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h -index 6b44844d95..34fc60774b 100644 ---- a/target/i386/kvm/kvm_i386.h -+++ b/target/i386/kvm/kvm_i386.h -@@ -33,6 +33,7 @@ - bool kvm_has_smm(void); - bool kvm_enable_x2apic(void); - bool kvm_hv_vpindex_settable(void); -+bool kvm_enable_hypercall(uint64_t enable_mask); - - bool kvm_enable_sgx_provisioning(KVMState *s); - bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); -diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events -index b365a8e8e2..74a6234ff7 100644 ---- a/target/i386/kvm/trace-events -+++ b/target/i386/kvm/trace-events -@@ -5,6 +5,7 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" - kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d" - kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d" - kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" -+kvm_hc_map_gpa_range(uint64_t gpa, uint64_t size, uint64_t attributes, uint64_t flags) "gpa 0x%" PRIx64 " size 0x%" PRIx64 " attributes 0x%" PRIx64 " flags 0x%" PRIx64 - - # xen-emu.c - kvm_xen_hypercall(int cpu, uint8_t cpl, uint64_t input, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t ret) "xen_hypercall: cpu %d cpl %d input %" PRIu64 " a0 0x%" PRIx64 " a1 0x%" PRIx64 " a2 0x%" PRIx64" ret 0x%" PRIx64 --- -2.39.3 - diff --git a/SOURCES/kvm-i386-kvm-Move-architectural-CPUID-leaf-generation-to.patch b/SOURCES/kvm-i386-kvm-Move-architectural-CPUID-leaf-generation-to.patch deleted file mode 100644 index 4b91e93..0000000 --- a/SOURCES/kvm-i386-kvm-Move-architectural-CPUID-leaf-generation-to.patch +++ /dev/null @@ -1,536 +0,0 @@ -From 5ead79f45e8e90b7a04586c89e70cb9d0b66b730 Mon Sep 17 00:00:00 2001 -From: Sean Christopherson -Date: Thu, 29 Feb 2024 01:36:43 -0500 -Subject: [PATCH 004/100] i386/kvm: Move architectural CPUID leaf generation to - separate helper - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [4/91] 06ecdbcf05ad3d658273980b114f02477d0b0475 (bonzini/rhel-qemu-kvm) - -Move the architectural (for lack of a better term) CPUID leaf generation -to a separate helper so that the generation code can be reused by TDX, -which needs to generate a canonical VM-scoped configuration. - -For now this is just a cleanup, so keep the function static. - -Signed-off-by: Sean Christopherson -Signed-off-by: Xiaoyao Li -Message-ID: <20240229063726.610065-23-xiaoyao.li@intel.com> -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -(cherry picked from commit a5acf4f26c208a05d05ef1bde65553ce2ab5e5d0) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 417 +++++++++++++++++++++--------------------- - 1 file changed, 211 insertions(+), 206 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 739f33db47..5f30b649a0 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -1706,195 +1706,22 @@ static void kvm_init_nested_state(CPUX86State *env) - } - } - --int kvm_arch_init_vcpu(CPUState *cs) -+static uint32_t kvm_x86_build_cpuid(CPUX86State *env, -+ struct kvm_cpuid_entry2 *entries, -+ uint32_t cpuid_i) - { -- struct { -- struct kvm_cpuid2 cpuid; -- struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; -- } cpuid_data; -- /* -- * The kernel defines these structs with padding fields so there -- * should be no extra padding in our cpuid_data struct. -- */ -- QEMU_BUILD_BUG_ON(sizeof(cpuid_data) != -- sizeof(struct kvm_cpuid2) + -- sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); -- -- X86CPU *cpu = X86_CPU(cs); -- CPUX86State *env = &cpu->env; -- uint32_t limit, i, j, cpuid_i; -+ uint32_t limit, i, j; - uint32_t unused; - struct kvm_cpuid_entry2 *c; -- uint32_t signature[3]; -- int kvm_base = KVM_CPUID_SIGNATURE; -- int max_nested_state_len; -- int r; -- Error *local_err = NULL; -- -- memset(&cpuid_data, 0, sizeof(cpuid_data)); -- -- cpuid_i = 0; -- -- has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2); -- -- r = kvm_arch_set_tsc_khz(cs); -- if (r < 0) { -- return r; -- } -- -- /* vcpu's TSC frequency is either specified by user, or following -- * the value used by KVM if the former is not present. In the -- * latter case, we query it from KVM and record in env->tsc_khz, -- * so that vcpu's TSC frequency can be migrated later via this field. -- */ -- if (!env->tsc_khz) { -- r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ? -- kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : -- -ENOTSUP; -- if (r > 0) { -- env->tsc_khz = r; -- } -- } -- -- env->apic_bus_freq = KVM_APIC_BUS_FREQUENCY; -- -- /* -- * kvm_hyperv_expand_features() is called here for the second time in case -- * KVM_CAP_SYS_HYPERV_CPUID is not supported. While we can't possibly handle -- * 'query-cpu-model-expansion' in this case as we don't have a KVM vCPU to -- * check which Hyper-V enlightenments are supported and which are not, we -- * can still proceed and check/expand Hyper-V enlightenments here so legacy -- * behavior is preserved. -- */ -- if (!kvm_hyperv_expand_features(cpu, &local_err)) { -- error_report_err(local_err); -- return -ENOSYS; -- } -- -- if (hyperv_enabled(cpu)) { -- r = hyperv_init_vcpu(cpu); -- if (r) { -- return r; -- } -- -- cpuid_i = hyperv_fill_cpuids(cs, cpuid_data.entries); -- kvm_base = KVM_CPUID_SIGNATURE_NEXT; -- has_msr_hv_hypercall = true; -- } -- -- if (cs->kvm_state->xen_version) { --#ifdef CONFIG_XEN_EMU -- struct kvm_cpuid_entry2 *xen_max_leaf; -- -- memcpy(signature, "XenVMMXenVMM", 12); -- -- xen_max_leaf = c = &cpuid_data.entries[cpuid_i++]; -- c->function = kvm_base + XEN_CPUID_SIGNATURE; -- c->eax = kvm_base + XEN_CPUID_TIME; -- c->ebx = signature[0]; -- c->ecx = signature[1]; -- c->edx = signature[2]; -- -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = kvm_base + XEN_CPUID_VENDOR; -- c->eax = cs->kvm_state->xen_version; -- c->ebx = 0; -- c->ecx = 0; -- c->edx = 0; -- -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = kvm_base + XEN_CPUID_HVM_MSR; -- /* Number of hypercall-transfer pages */ -- c->eax = 1; -- /* Hypercall MSR base address */ -- if (hyperv_enabled(cpu)) { -- c->ebx = XEN_HYPERCALL_MSR_HYPERV; -- kvm_xen_init(cs->kvm_state, c->ebx); -- } else { -- c->ebx = XEN_HYPERCALL_MSR; -- } -- c->ecx = 0; -- c->edx = 0; -- -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = kvm_base + XEN_CPUID_TIME; -- c->eax = ((!!tsc_is_stable_and_known(env) << 1) | -- (!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << 2)); -- /* default=0 (emulate if necessary) */ -- c->ebx = 0; -- /* guest tsc frequency */ -- c->ecx = env->user_tsc_khz; -- /* guest tsc incarnation (migration count) */ -- c->edx = 0; -- -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = kvm_base + XEN_CPUID_HVM; -- xen_max_leaf->eax = kvm_base + XEN_CPUID_HVM; -- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 5)) { -- c->function = kvm_base + XEN_CPUID_HVM; -- -- if (cpu->xen_vapic) { -- c->eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT; -- c->eax |= XEN_HVM_CPUID_X2APIC_VIRT; -- } -- -- c->eax |= XEN_HVM_CPUID_IOMMU_MAPPINGS; -- -- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 6)) { -- c->eax |= XEN_HVM_CPUID_VCPU_ID_PRESENT; -- c->ebx = cs->cpu_index; -- } -- -- if (cs->kvm_state->xen_version >= XEN_VERSION(4, 17)) { -- c->eax |= XEN_HVM_CPUID_UPCALL_VECTOR; -- } -- } -- -- r = kvm_xen_init_vcpu(cs); -- if (r) { -- return r; -- } -- -- kvm_base += 0x100; --#else /* CONFIG_XEN_EMU */ -- /* This should never happen as kvm_arch_init() would have died first. */ -- fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n"); -- abort(); --#endif -- } else if (cpu->expose_kvm) { -- memcpy(signature, "KVMKVMKVM\0\0\0", 12); -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = KVM_CPUID_SIGNATURE | kvm_base; -- c->eax = KVM_CPUID_FEATURES | kvm_base; -- c->ebx = signature[0]; -- c->ecx = signature[1]; -- c->edx = signature[2]; -- -- c = &cpuid_data.entries[cpuid_i++]; -- c->function = KVM_CPUID_FEATURES | kvm_base; -- c->eax = env->features[FEAT_KVM]; -- c->edx = env->features[FEAT_KVM_HINTS]; -- } - - cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); - -- if (cpu->kvm_pv_enforce_cpuid) { -- r = kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0, 1); -- if (r < 0) { -- fprintf(stderr, -- "failed to enable KVM_CAP_ENFORCE_PV_FEATURE_CPUID: %s", -- strerror(-r)); -- abort(); -- } -- } -- - for (i = 0; i <= limit; i++) { -+ j = 0; - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "unsupported level value: 0x%x\n", limit); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -- -+ c = &entries[cpuid_i++]; - switch (i) { - case 2: { - /* Keep reading function 2 till all the input is received */ -@@ -1908,11 +1735,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - - for (j = 1; j < times; ++j) { - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "cpuid_data is full, no space for " -- "cpuid(eax:2):eax & 0xf = 0x%x\n", times); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - c->function = i; - c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC; - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); -@@ -1951,11 +1776,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - continue; - } - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "cpuid_data is full, no space for " -- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - } - break; - case 0x12: -@@ -1970,11 +1793,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - } - - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "cpuid_data is full, no space for " -- "cpuid(eax:0x12,ecx:0x%x)\n", j); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - } - break; - case 0x7: -@@ -1991,11 +1812,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - - for (j = 1; j <= times; ++j) { - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "cpuid_data is full, no space for " -- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - c->function = i; - c->index = j; - c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX; -@@ -2048,11 +1867,11 @@ int kvm_arch_init_vcpu(CPUState *cs) - cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused); - - for (i = 0x80000000; i <= limit; i++) { -+ j = 0; - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - - switch (i) { - case 0x8000001d: -@@ -2067,11 +1886,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - break; - } - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "cpuid_data is full, no space for " -- "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - } - break; - default: -@@ -2094,11 +1911,11 @@ int kvm_arch_init_vcpu(CPUState *cs) - cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused); - - for (i = 0xC0000000; i <= limit; i++) { -+ j = 0; - if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { -- fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit); -- abort(); -+ goto full; - } -- c = &cpuid_data.entries[cpuid_i++]; -+ c = &entries[cpuid_i++]; - - c->function = i; - c->flags = 0; -@@ -2106,6 +1923,194 @@ int kvm_arch_init_vcpu(CPUState *cs) - } - } - -+ return cpuid_i; -+ -+full: -+ fprintf(stderr, "cpuid_data is full, no space for " -+ "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); -+ abort(); -+} -+ -+int kvm_arch_init_vcpu(CPUState *cs) -+{ -+ struct { -+ struct kvm_cpuid2 cpuid; -+ struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; -+ } cpuid_data; -+ /* -+ * The kernel defines these structs with padding fields so there -+ * should be no extra padding in our cpuid_data struct. -+ */ -+ QEMU_BUILD_BUG_ON(sizeof(cpuid_data) != -+ sizeof(struct kvm_cpuid2) + -+ sizeof(struct kvm_cpuid_entry2) * KVM_MAX_CPUID_ENTRIES); -+ -+ X86CPU *cpu = X86_CPU(cs); -+ CPUX86State *env = &cpu->env; -+ uint32_t cpuid_i; -+ struct kvm_cpuid_entry2 *c; -+ uint32_t signature[3]; -+ int kvm_base = KVM_CPUID_SIGNATURE; -+ int max_nested_state_len; -+ int r; -+ Error *local_err = NULL; -+ -+ memset(&cpuid_data, 0, sizeof(cpuid_data)); -+ -+ cpuid_i = 0; -+ -+ has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2); -+ -+ r = kvm_arch_set_tsc_khz(cs); -+ if (r < 0) { -+ return r; -+ } -+ -+ /* vcpu's TSC frequency is either specified by user, or following -+ * the value used by KVM if the former is not present. In the -+ * latter case, we query it from KVM and record in env->tsc_khz, -+ * so that vcpu's TSC frequency can be migrated later via this field. -+ */ -+ if (!env->tsc_khz) { -+ r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ? -+ kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : -+ -ENOTSUP; -+ if (r > 0) { -+ env->tsc_khz = r; -+ } -+ } -+ -+ env->apic_bus_freq = KVM_APIC_BUS_FREQUENCY; -+ -+ /* -+ * kvm_hyperv_expand_features() is called here for the second time in case -+ * KVM_CAP_SYS_HYPERV_CPUID is not supported. While we can't possibly handle -+ * 'query-cpu-model-expansion' in this case as we don't have a KVM vCPU to -+ * check which Hyper-V enlightenments are supported and which are not, we -+ * can still proceed and check/expand Hyper-V enlightenments here so legacy -+ * behavior is preserved. -+ */ -+ if (!kvm_hyperv_expand_features(cpu, &local_err)) { -+ error_report_err(local_err); -+ return -ENOSYS; -+ } -+ -+ if (hyperv_enabled(cpu)) { -+ r = hyperv_init_vcpu(cpu); -+ if (r) { -+ return r; -+ } -+ -+ cpuid_i = hyperv_fill_cpuids(cs, cpuid_data.entries); -+ kvm_base = KVM_CPUID_SIGNATURE_NEXT; -+ has_msr_hv_hypercall = true; -+ } -+ -+ if (cs->kvm_state->xen_version) { -+#ifdef CONFIG_XEN_EMU -+ struct kvm_cpuid_entry2 *xen_max_leaf; -+ -+ memcpy(signature, "XenVMMXenVMM", 12); -+ -+ xen_max_leaf = c = &cpuid_data.entries[cpuid_i++]; -+ c->function = kvm_base + XEN_CPUID_SIGNATURE; -+ c->eax = kvm_base + XEN_CPUID_TIME; -+ c->ebx = signature[0]; -+ c->ecx = signature[1]; -+ c->edx = signature[2]; -+ -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = kvm_base + XEN_CPUID_VENDOR; -+ c->eax = cs->kvm_state->xen_version; -+ c->ebx = 0; -+ c->ecx = 0; -+ c->edx = 0; -+ -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = kvm_base + XEN_CPUID_HVM_MSR; -+ /* Number of hypercall-transfer pages */ -+ c->eax = 1; -+ /* Hypercall MSR base address */ -+ if (hyperv_enabled(cpu)) { -+ c->ebx = XEN_HYPERCALL_MSR_HYPERV; -+ kvm_xen_init(cs->kvm_state, c->ebx); -+ } else { -+ c->ebx = XEN_HYPERCALL_MSR; -+ } -+ c->ecx = 0; -+ c->edx = 0; -+ -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = kvm_base + XEN_CPUID_TIME; -+ c->eax = ((!!tsc_is_stable_and_known(env) << 1) | -+ (!!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_RDTSCP) << 2)); -+ /* default=0 (emulate if necessary) */ -+ c->ebx = 0; -+ /* guest tsc frequency */ -+ c->ecx = env->user_tsc_khz; -+ /* guest tsc incarnation (migration count) */ -+ c->edx = 0; -+ -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = kvm_base + XEN_CPUID_HVM; -+ xen_max_leaf->eax = kvm_base + XEN_CPUID_HVM; -+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 5)) { -+ c->function = kvm_base + XEN_CPUID_HVM; -+ -+ if (cpu->xen_vapic) { -+ c->eax |= XEN_HVM_CPUID_APIC_ACCESS_VIRT; -+ c->eax |= XEN_HVM_CPUID_X2APIC_VIRT; -+ } -+ -+ c->eax |= XEN_HVM_CPUID_IOMMU_MAPPINGS; -+ -+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 6)) { -+ c->eax |= XEN_HVM_CPUID_VCPU_ID_PRESENT; -+ c->ebx = cs->cpu_index; -+ } -+ -+ if (cs->kvm_state->xen_version >= XEN_VERSION(4, 17)) { -+ c->eax |= XEN_HVM_CPUID_UPCALL_VECTOR; -+ } -+ } -+ -+ r = kvm_xen_init_vcpu(cs); -+ if (r) { -+ return r; -+ } -+ -+ kvm_base += 0x100; -+#else /* CONFIG_XEN_EMU */ -+ /* This should never happen as kvm_arch_init() would have died first. */ -+ fprintf(stderr, "Cannot enable Xen CPUID without Xen support\n"); -+ abort(); -+#endif -+ } else if (cpu->expose_kvm) { -+ memcpy(signature, "KVMKVMKVM\0\0\0", 12); -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = KVM_CPUID_SIGNATURE | kvm_base; -+ c->eax = KVM_CPUID_FEATURES | kvm_base; -+ c->ebx = signature[0]; -+ c->ecx = signature[1]; -+ c->edx = signature[2]; -+ -+ c = &cpuid_data.entries[cpuid_i++]; -+ c->function = KVM_CPUID_FEATURES | kvm_base; -+ c->eax = env->features[FEAT_KVM]; -+ c->edx = env->features[FEAT_KVM_HINTS]; -+ } -+ -+ if (cpu->kvm_pv_enforce_cpuid) { -+ r = kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0, 1); -+ if (r < 0) { -+ fprintf(stderr, -+ "failed to enable KVM_CAP_ENFORCE_PV_FEATURE_CPUID: %s", -+ strerror(-r)); -+ abort(); -+ } -+ } -+ -+ cpuid_i = kvm_x86_build_cpuid(env, cpuid_data.entries, cpuid_i); - cpuid_data.cpuid.nent = cpuid_i; - - if (((env->cpuid_version >> 8)&0xF) >= 6 --- -2.39.3 - diff --git a/SOURCES/kvm-i386-pc-remove-unnecessary-MachineClass-overrides.patch b/SOURCES/kvm-i386-pc-remove-unnecessary-MachineClass-overrides.patch deleted file mode 100644 index 65d09ab..0000000 --- a/SOURCES/kvm-i386-pc-remove-unnecessary-MachineClass-overrides.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 03e275023b482ac79b4f92ca4ceef6de3caa634f Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 9 May 2024 19:00:40 +0200 -Subject: [PATCH 045/100] i386: pc: remove unnecessary MachineClass overrides - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [45/91] c03d5b57014d0d02f6ce0cdfb19a34996d100dea (bonzini/rhel-qemu-kvm) - -There is no need to override these fields of MachineClass because they are -already set to the right value in the superclass. - -Signed-off-by: Paolo Bonzini -Reviewed-by: Zhao Liu -Message-ID: <20240509170044.190795-10-pbonzini@redhat.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit b348fdcdac9f9fc70be9ae56c54e41765e9aae24) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 3 --- - hw/i386/x86.c | 6 +++--- - include/hw/i386/x86.h | 4 ---- - 3 files changed, 3 insertions(+), 10 deletions(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 660a59c63b..0aca0cc79e 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -1979,9 +1979,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - mc->async_pf_vmexit_disable = false; - mc->get_hotplug_handler = pc_get_hotplug_handler; - mc->hotplug_allowed = pc_hotplug_allowed; -- mc->cpu_index_to_instance_props = x86_cpu_index_to_props; -- mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; -- mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; - mc->auto_enable_numa_with_memhp = true; - mc->auto_enable_numa_with_memdev = true; - mc->has_hotpluggable_cpus = true; -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index c61f4ebfa6..fcef652c1e 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -443,7 +443,7 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, - numa_cpu_pre_plug(cpu_slot, dev, errp); - } - --CpuInstanceProperties -+static CpuInstanceProperties - x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) - { - MachineClass *mc = MACHINE_GET_CLASS(ms); -@@ -453,7 +453,7 @@ x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) - return possible_cpus->cpus[cpu_index].props; - } - --int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) -+static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) - { - X86CPUTopoIDs topo_ids; - X86MachineState *x86ms = X86_MACHINE(ms); -@@ -467,7 +467,7 @@ int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) - return topo_ids.pkg_id % ms->numa_state->num_nodes; - } - --const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) -+static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) - { - X86MachineState *x86ms = X86_MACHINE(ms); - unsigned int max_cpus = ms->smp.max_cpus; -diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h -index d7b7d3f3ce..c2062db13f 100644 ---- a/include/hw/i386/x86.h -+++ b/include/hw/i386/x86.h -@@ -114,10 +114,6 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms, - - void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, Error **errp); - void x86_cpus_init(X86MachineState *pcms, int default_cpu_version); --CpuInstanceProperties x86_cpu_index_to_props(MachineState *ms, -- unsigned cpu_index); --int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx); --const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms); - CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx); - void x86_rtc_set_cpus_count(ISADevice *rtc, uint16_t cpus_count); - void x86_cpu_pre_plug(HotplugHandler *hotplug_dev, --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-a-class-method-to-determine-KVM-VM-type.patch b/SOURCES/kvm-i386-sev-Add-a-class-method-to-determine-KVM-VM-type.patch deleted file mode 100644 index fce51aa..0000000 --- a/SOURCES/kvm-i386-sev-Add-a-class-method-to-determine-KVM-VM-type.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 652793962000d6906e219ceae36348a476b78c28 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 31 May 2024 12:44:44 +0200 -Subject: [PATCH 065/100] i386/sev: Add a class method to determine KVM VM type - for SNP guests - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [65/91] c6cbeac0a6f691138df212b80efaa9b1143fdaa8 (bonzini/rhel-qemu-kvm) - -SEV guests can use either KVM_X86_DEFAULT_VM, KVM_X86_SEV_VM, -or KVM_X86_SEV_ES_VM depending on the configuration and what -the host kernel supports. SNP guests on the other hand can only -ever use KVM_X86_SNP_VM, so split determination of VM type out -into a separate class method that can be set accordingly for -sev-guest vs. sev-snp-guest objects and add handling for SNP. - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-14-pankaj.gupta@amd.com> -[Remove unnecessary function pointer declaration. - Paolo] -Signed-off-by: Paolo Bonzini -(cherry picked from commit a808132f6d8e855bd83a400570ec91d2e00bebe3) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 1 + - target/i386/sev.c | 15 ++++++++++++--- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 408568d053..75e75d9772 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -166,6 +166,7 @@ static const char *vm_type_name[] = { - [KVM_X86_DEFAULT_VM] = "default", - [KVM_X86_SEV_VM] = "SEV", - [KVM_X86_SEV_ES_VM] = "SEV-ES", -+ [KVM_X86_SNP_VM] = "SEV-SNP", - }; - - bool kvm_is_vm_type_supported(int type) -diff --git a/target/i386/sev.c b/target/i386/sev.c -index c3daaf1ad5..072cc4f853 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -885,6 +885,11 @@ out: - return sev_common->kvm_type; - } - -+static int sev_snp_kvm_type(X86ConfidentialGuest *cg) -+{ -+ return KVM_X86_SNP_VM; -+} -+ - static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - char *devname; -@@ -894,6 +899,8 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - struct sev_user_data_status status = {}; - SevCommonState *sev_common = SEV_COMMON(cgs); - SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs); -+ X86ConfidentialGuestClass *x86_klass = -+ X86_CONFIDENTIAL_GUEST_GET_CLASS(cgs); - - sev_common->state = SEV_STATE_UNINIT; - -@@ -964,7 +971,7 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - trace_kvm_sev_init(); -- if (sev_kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) { -+ if (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) { - cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT; - - ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error); -@@ -1441,10 +1448,8 @@ static void - sev_common_class_init(ObjectClass *oc, void *data) - { - ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); -- X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - - klass->kvm_init = sev_common_kvm_init; -- x86_klass->kvm_type = sev_kvm_type; - - object_class_property_add_str(oc, "sev-device", - sev_common_get_sev_device, -@@ -1529,10 +1534,12 @@ static void - sev_guest_class_init(ObjectClass *oc, void *data) - { - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); -+ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - - klass->launch_start = sev_launch_start; - klass->launch_finish = sev_launch_finish; - klass->kvm_init = sev_kvm_init; -+ x86_klass->kvm_type = sev_kvm_type; - - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, -@@ -1770,8 +1777,10 @@ static void - sev_snp_guest_class_init(ObjectClass *oc, void *data) - { - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); -+ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - - klass->kvm_init = sev_snp_kvm_init; -+ x86_klass->kvm_type = sev_snp_kvm_type; - - object_class_property_add(oc, "policy", "uint64", - sev_snp_guest_get_policy, --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-a-sev_snp_enabled-helper.patch b/SOURCES/kvm-i386-sev-Add-a-sev_snp_enabled-helper.patch deleted file mode 100644 index d194994..0000000 --- a/SOURCES/kvm-i386-sev-Add-a-sev_snp_enabled-helper.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 82a714b79851b5c2d1389d2fa7a01548c486a854 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:20 -0500 -Subject: [PATCH 060/100] i386/sev: Add a sev_snp_enabled() helper - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [60/91] c35ead095028ccfb1e1be0fe010ca4f7688530a0 (bonzini/rhel-qemu-kvm) - -Add a simple helper to check if the current guest type is SNP. Also have -SNP-enabled imply that SEV-ES is enabled as well, and fix up any places -where the sev_es_enabled() check is expecting a pure/non-SNP guest. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-9-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 99190f805dca9475fe244fbd8041961842657dc2) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 13 ++++++++++++- - target/i386/sev.h | 2 ++ - 2 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index a81b3228d4..4edfedc139 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -325,12 +325,21 @@ sev_enabled(void) - return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON); - } - -+bool -+sev_snp_enabled(void) -+{ -+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs; -+ -+ return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_SNP_GUEST); -+} -+ - bool - sev_es_enabled(void) - { - ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs; - -- return sev_enabled() && (SEV_GUEST(cgs)->policy & SEV_POLICY_ES); -+ return sev_snp_enabled() || -+ (sev_enabled() && SEV_GUEST(cgs)->policy & SEV_POLICY_ES); - } - - uint32_t -@@ -946,7 +955,9 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - "support", __func__); - goto err; - } -+ } - -+ if (sev_es_enabled() && !sev_snp_enabled()) { - if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) { - error_setg(errp, "%s: guest policy requires SEV-ES, but " - "host SEV-ES support unavailable", -diff --git a/target/i386/sev.h b/target/i386/sev.h -index bedc667eeb..94295ee74f 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -45,9 +45,11 @@ typedef struct SevKernelLoaderContext { - #ifdef CONFIG_SEV - bool sev_enabled(void); - bool sev_es_enabled(void); -+bool sev_snp_enabled(void); - #else - #define sev_enabled() 0 - #define sev_es_enabled() 0 -+#define sev_snp_enabled() 0 - #endif - - uint32_t sev_get_cbit_position(void); --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-handling-to-encrypt-finalize-guest-laun.patch b/SOURCES/kvm-i386-sev-Add-handling-to-encrypt-finalize-guest-laun.patch deleted file mode 100644 index 2bab2ac..0000000 --- a/SOURCES/kvm-i386-sev-Add-handling-to-encrypt-finalize-guest-laun.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 0e435819540b0d39da2c828aacc0f35ecaadbdf6 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:28 -0500 -Subject: [PATCH 068/100] i386/sev: Add handling to encrypt/finalize guest - launch data - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [68/91] fe77931d279aa8df061823da88a320fb5f72ffea (bonzini/rhel-qemu-kvm) - -Process any queued up launch data and encrypt/measure it into the SNP -guest instance prior to initial guest launch. - -This also updates the KVM_SEV_SNP_LAUNCH_UPDATE call to handle partial -update responses. - -Signed-off-by: Brijesh Singh -Co-developed-by: Michael Roth -Signed-off-by: Michael Roth -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-17-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 9f3a6999f9730a694d7db448a99f9c9cb6515992) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 112 ++++++++++++++++++++++++++++++++++++++- - target/i386/trace-events | 2 + - 2 files changed, 113 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index e89b87d2f5..ef2e592ca7 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -756,6 +756,76 @@ out: - return ret; - } - -+static const char * -+snp_page_type_to_str(int type) -+{ -+ switch (type) { -+ case KVM_SEV_SNP_PAGE_TYPE_NORMAL: return "Normal"; -+ case KVM_SEV_SNP_PAGE_TYPE_ZERO: return "Zero"; -+ case KVM_SEV_SNP_PAGE_TYPE_UNMEASURED: return "Unmeasured"; -+ case KVM_SEV_SNP_PAGE_TYPE_SECRETS: return "Secrets"; -+ case KVM_SEV_SNP_PAGE_TYPE_CPUID: return "Cpuid"; -+ default: return "unknown"; -+ } -+} -+ -+static int -+sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, -+ SevLaunchUpdateData *data) -+{ -+ int ret, fw_error; -+ struct kvm_sev_snp_launch_update update = {0}; -+ -+ if (!data->hva || !data->len) { -+ error_report("SNP_LAUNCH_UPDATE called with invalid address" -+ "/ length: %p / %lx", -+ data->hva, data->len); -+ return 1; -+ } -+ -+ update.uaddr = (__u64)(unsigned long)data->hva; -+ update.gfn_start = data->gpa >> TARGET_PAGE_BITS; -+ update.len = data->len; -+ update.type = data->type; -+ -+ /* -+ * KVM_SEV_SNP_LAUNCH_UPDATE requires that GPA ranges have the private -+ * memory attribute set in advance. -+ */ -+ ret = kvm_set_memory_attributes_private(data->gpa, data->len); -+ if (ret) { -+ error_report("SEV-SNP: failed to configure initial" -+ "private guest memory"); -+ goto out; -+ } -+ -+ while (update.len || ret == -EAGAIN) { -+ trace_kvm_sev_snp_launch_update(update.uaddr, update.gfn_start << -+ TARGET_PAGE_BITS, update.len, -+ snp_page_type_to_str(update.type)); -+ -+ ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd, -+ KVM_SEV_SNP_LAUNCH_UPDATE, -+ &update, &fw_error); -+ if (ret && ret != -EAGAIN) { -+ error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ break; -+ } -+ } -+ -+out: -+ if (!ret && update.gfn_start << TARGET_PAGE_BITS != data->gpa + data->len) { -+ error_report("SEV-SNP: expected update of GPA range %lx-%lx," -+ "got GPA range %lx-%llx", -+ data->gpa, data->gpa + data->len, data->gpa, -+ update.gfn_start << TARGET_PAGE_BITS); -+ ret = -EIO; -+ } -+ -+ return ret; -+} -+ - static int - sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len) - { -@@ -901,6 +971,46 @@ sev_launch_finish(SevCommonState *sev_common) - migrate_add_blocker(&sev_mig_blocker, &error_fatal); - } - -+static void -+sev_snp_launch_finish(SevCommonState *sev_common) -+{ -+ int ret, error; -+ Error *local_err = NULL; -+ SevLaunchUpdateData *data; -+ SevSnpGuestState *sev_snp = SEV_SNP_GUEST(sev_common); -+ struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf; -+ -+ QTAILQ_FOREACH(data, &launch_update, next) { -+ ret = sev_snp_launch_update(sev_snp, data); -+ if (ret) { -+ exit(1); -+ } -+ } -+ -+ trace_kvm_sev_snp_launch_finish(sev_snp->id_block, sev_snp->id_auth, -+ sev_snp->host_data); -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_FINISH, -+ finish, &error); -+ if (ret) { -+ error_report("SNP_LAUNCH_FINISH ret=%d fw_error=%d '%s'", -+ ret, error, fw_error_to_str(error)); -+ exit(1); -+ } -+ -+ sev_set_guest_state(sev_common, SEV_STATE_RUNNING); -+ -+ /* add migration blocker */ -+ error_setg(&sev_mig_blocker, -+ "SEV-SNP: Migration is not implemented"); -+ ret = migrate_add_blocker(&sev_mig_blocker, &local_err); -+ if (local_err) { -+ error_report_err(local_err); -+ error_free(sev_mig_blocker); -+ exit(1); -+ } -+} -+ -+ - static void - sev_vm_state_change(void *opaque, bool running, RunState state) - { -@@ -1832,10 +1942,10 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - - klass->launch_start = sev_snp_launch_start; -+ klass->launch_finish = sev_snp_launch_finish; - klass->kvm_init = sev_snp_kvm_init; - x86_klass->kvm_type = sev_snp_kvm_type; - -- - object_class_property_add(oc, "policy", "uint64", - sev_snp_guest_get_policy, - sev_snp_guest_set_policy, NULL, NULL); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index cb26d8a925..06b44ead2e 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -12,3 +12,5 @@ kvm_sev_launch_finish(void) "" - kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" - kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" - kvm_sev_snp_launch_start(uint64_t policy, char *gosvw) "policy 0x%" PRIx64 " gosvw %s" -+kvm_sev_snp_launch_update(uint64_t src, uint64_t gpa, uint64_t len, const char *type) "src 0x%" PRIx64 " gpa 0x%" PRIx64 " len 0x%" PRIx64 " (%s page)" -+kvm_sev_snp_launch_finish(char *id_block, char *id_auth, char *host_data) "id_block %s id_auth %s host_data %s" --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-legacy-vm-type-parameter-for-SEV-guest-.patch b/SOURCES/kvm-i386-sev-Add-legacy-vm-type-parameter-for-SEV-guest-.patch deleted file mode 100644 index 572dddc..0000000 --- a/SOURCES/kvm-i386-sev-Add-legacy-vm-type-parameter-for-SEV-guest-.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 2872c423fa44dcbf50b581a5c3feac064a0473a0 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Tue, 9 Apr 2024 18:07:41 -0500 -Subject: [PATCH 024/100] i386/sev: Add 'legacy-vm-type' parameter for SEV - guest objects - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [24/91] ce35d1b09fe8aa8772ff149543f7760455c1e6b5 (bonzini/rhel-qemu-kvm) - -QEMU will currently automatically make use of the KVM_SEV_INIT2 API for -initializing SEV and SEV-ES guests verses the older -KVM_SEV_INIT/KVM_SEV_ES_INIT interfaces. - -However, the older interfaces will silently avoid sync'ing FPU/XSAVE -state to the VMSA prior to encryption, thus relying on behavior and -measurements that assume the related fields to be allow zero. - -With KVM_SEV_INIT2, this state is now synced into the VMSA, resulting in -measurements changes and, theoretically, behaviorial changes, though the -latter are unlikely to be seen in practice. - -To allow a smooth transition to the newer interface, while still -providing a mechanism to maintain backward compatibility with VMs -created using the older interfaces, provide a new command-line -parameter: - - -object sev-guest,legacy-vm-type=true,... - -and have it default to false. - -Signed-off-by: Michael Roth -Message-ID: <20240409230743.962513-2-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 023267334da375226720e62963df9545aa8fc2fd) -Signed-off-by: Paolo Bonzini ---- - qapi/qom.json | 11 ++++++++++- - target/i386/sev.c | 18 +++++++++++++++++- - 2 files changed, 27 insertions(+), 2 deletions(-) - -diff --git a/qapi/qom.json b/qapi/qom.json -index 85e6b4f84a..38dde6d785 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -898,6 +898,14 @@ - # designated guest firmware page for measured boot with -kernel - # (default: false) (since 6.2) - # -+# @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM. -+# The newer KVM_SEV_INIT2 interface syncs additional vCPU -+# state when initializing the VMSA structures, which will -+# result in a different guest measurement. Set this to -+# maintain compatibility with older QEMU or kernel versions -+# that rely on legacy KVM_SEV_INIT behavior. -+# (default: false) (since 9.1) -+# - # Since: 2.12 - ## - { 'struct': 'SevGuestProperties', -@@ -908,7 +916,8 @@ - '*handle': 'uint32', - '*cbitpos': 'uint32', - 'reduced-phys-bits': 'uint32', -- '*kernel-hashes': 'bool' } } -+ '*kernel-hashes': 'bool', -+ '*legacy-vm-type': 'bool' } } - - ## - # @ThreadContextProperties: -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 9dab4060b8..f4ee317cb0 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -67,6 +67,7 @@ struct SevGuestState { - uint32_t cbitpos; - uint32_t reduced_phys_bits; - bool kernel_hashes; -+ bool legacy_vm_type; - - /* runtime state */ - uint32_t handle; -@@ -356,6 +357,16 @@ static void sev_guest_set_kernel_hashes(Object *obj, bool value, Error **errp) - sev->kernel_hashes = value; - } - -+static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp) -+{ -+ return SEV_GUEST(obj)->legacy_vm_type; -+} -+ -+static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp) -+{ -+ SEV_GUEST(obj)->legacy_vm_type = value; -+} -+ - bool - sev_enabled(void) - { -@@ -863,7 +874,7 @@ static int sev_kvm_type(X86ConfidentialGuest *cg) - } - - kvm_type = (sev->policy & SEV_POLICY_ES) ? KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM; -- if (kvm_is_vm_type_supported(kvm_type)) { -+ if (kvm_is_vm_type_supported(kvm_type) && !sev->legacy_vm_type) { - sev->kvm_type = kvm_type; - } else { - sev->kvm_type = KVM_X86_DEFAULT_VM; -@@ -1381,6 +1392,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) - sev_guest_set_kernel_hashes); - object_class_property_set_description(oc, "kernel-hashes", - "add kernel hashes to guest firmware for measured Linux boot"); -+ object_class_property_add_bool(oc, "legacy-vm-type", -+ sev_guest_get_legacy_vm_type, -+ sev_guest_set_legacy_vm_type); -+ object_class_property_set_description(oc, "legacy-vm-type", -+ "use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions."); - } - - static void --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-sev_kvm_init-override-for-SEV-class.patch b/SOURCES/kvm-i386-sev-Add-sev_kvm_init-override-for-SEV-class.patch deleted file mode 100644 index ca1338c..0000000 --- a/SOURCES/kvm-i386-sev-Add-sev_kvm_init-override-for-SEV-class.patch +++ /dev/null @@ -1,203 +0,0 @@ -From a236548a903aa8350fff9601d481b2f529c8d4a7 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:21 -0500 -Subject: [PATCH 061/100] i386/sev: Add sev_kvm_init() override for SEV class - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [61/91] b24fcbc8712e7394e029312229da023c63803969 (bonzini/rhel-qemu-kvm) - -Some aspects of the init routine SEV are specific to SEV and not -applicable for SNP guests, so move the SEV-specific bits into -separate class method and retain only the common functionality. - -Co-developed-by: Michael Roth -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-10-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 990da8d243a8c59dafcbed78b56a0e4ffb1605d9) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 72 +++++++++++++++++++++++++++++++++-------------- - 1 file changed, 51 insertions(+), 21 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 4edfedc139..5519de1c6b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -73,6 +73,7 @@ struct SevCommonStateClass { - /* public */ - int (*launch_start)(SevCommonState *sev_common); - void (*launch_finish)(SevCommonState *sev_common); -+ int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp); - }; - - /** -@@ -882,7 +883,7 @@ out: - return sev_common->kvm_type; - } - --static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevCommonState *sev_common = SEV_COMMON(cgs); - char *devname; -@@ -892,12 +893,6 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - struct sev_user_data_status status = {}; - SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs); - -- ret = ram_block_discard_disable(true); -- if (ret) { -- error_report("%s: cannot disable RAM discard", __func__); -- return -1; -- } -- - sev_common->state = SEV_STATE_UNINIT; - - host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); -@@ -911,7 +906,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - if (host_cbitpos != sev_common->cbitpos) { - error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'", - __func__, host_cbitpos, sev_common->cbitpos); -- goto err; -+ return -1; - } - - /* -@@ -924,7 +919,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - error_setg(errp, "%s: reduced_phys_bits check failed," - " it should be in the range of 1 to 63, requested '%d'", - __func__, sev_common->reduced_phys_bits); -- goto err; -+ return -1; - } - - devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL); -@@ -933,7 +928,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - error_setg(errp, "%s: Failed to open %s '%s'", __func__, - devname, strerror(errno)); - g_free(devname); -- goto err; -+ return -1; - } - g_free(devname); - -@@ -943,7 +938,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - error_setg(errp, "%s: failed to get platform status ret=%d " - "fw_error='%d: %s'", __func__, ret, fw_error, - fw_error_to_str(fw_error)); -- goto err; -+ return -1; - } - sev_common->build_id = status.build; - sev_common->api_major = status.api_major; -@@ -953,7 +948,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - if (!kvm_kernel_irqchip_allowed()) { - error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip" - "support", __func__); -- goto err; -+ return -1; - } - } - -@@ -962,7 +957,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - error_setg(errp, "%s: guest policy requires SEV-ES, but " - "host SEV-ES support unavailable", - __func__); -- goto err; -+ return -1; - } - } - -@@ -980,25 +975,59 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - if (ret) { - error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); -- goto err; -+ return -1; - } - - ret = klass->launch_start(sev_common); - if (ret) { - error_setg(errp, "%s: failed to create encryption context", __func__); -- goto err; -+ return -1; -+ } -+ -+ if (klass->kvm_init && klass->kvm_init(cgs, errp)) { -+ return -1; - } - -- ram_block_notifier_add(&sev_ram_notifier); -- qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common); - - cgs->ready = true; - - return 0; --err: -- ram_block_discard_disable(false); -- return -1; -+} -+ -+static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+{ -+ int ret; -+ -+ /* -+ * SEV/SEV-ES rely on pinned memory to back guest RAM so discarding -+ * isn't actually possible. With SNP, only guest_memfd pages are used -+ * for private guest memory, so discarding of shared memory is still -+ * possible.. -+ */ -+ ret = ram_block_discard_disable(true); -+ if (ret) { -+ error_setg(errp, "%s: cannot disable RAM discard", __func__); -+ return -1; -+ } -+ -+ /* -+ * SEV uses these notifiers to register/pin pages prior to guest use, -+ * but SNP relies on guest_memfd for private pages, which has its -+ * own internal mechanisms for registering/pinning private memory. -+ */ -+ ram_block_notifier_add(&sev_ram_notifier); -+ -+ /* -+ * The machine done notify event is used for SEV guests to get the -+ * measurement of the encrypted images. When SEV-SNP is enabled, the -+ * measurement is part of the guest attestation process where it can -+ * be collected without any reliance on the VMM. So skip registering -+ * the notifier for SNP in favor of using guest attestation instead. -+ */ -+ qemu_add_machine_init_done_notifier(&sev_machine_done_notify); -+ -+ return 0; - } - - int -@@ -1397,7 +1426,7 @@ sev_common_class_init(ObjectClass *oc, void *data) - ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - -- klass->kvm_init = sev_kvm_init; -+ klass->kvm_init = sev_common_kvm_init; - x86_klass->kvm_type = sev_kvm_type; - - object_class_property_add_str(oc, "sev-device", -@@ -1486,6 +1515,7 @@ sev_guest_class_init(ObjectClass *oc, void *data) - - klass->launch_start = sev_launch_start; - klass->launch_finish = sev_launch_finish; -+ klass->kvm_init = sev_kvm_init; - - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-snp_kvm_init-override-for-SNP-class.patch b/SOURCES/kvm-i386-sev-Add-snp_kvm_init-override-for-SNP-class.patch deleted file mode 100644 index 0db345c..0000000 --- a/SOURCES/kvm-i386-sev-Add-snp_kvm_init-override-for-SNP-class.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 35ceebdeccbf5dceb374c6f89a12e9981def570b Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:22 -0500 -Subject: [PATCH 062/100] i386/sev: Add snp_kvm_init() override for SNP class - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [62/91] 8fa537961c9262b99a4ffb99e1c25f080d76d1de (bonzini/rhel-qemu-kvm) - -SNP does not support SMM and requires guest_memfd for -private guest memory, so add SNP specific kvm_init() -functionality in snp_kvm_init() class method. - -Signed-off-by: Michael Roth -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-11-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 125b95a6d465a03ff30816eff0b1889aec01f0c3) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 24 +++++++++++++++++++++++- - 1 file changed, 23 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 5519de1c6b..6525b3c1a0 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -885,12 +885,12 @@ out: - - static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { -- SevCommonState *sev_common = SEV_COMMON(cgs); - char *devname; - int ret, fw_error, cmd; - uint32_t ebx; - uint32_t host_cbitpos; - struct sev_user_data_status status = {}; -+ SevCommonState *sev_common = SEV_COMMON(cgs); - SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs); - - sev_common->state = SEV_STATE_UNINIT; -@@ -1030,6 +1030,21 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - return 0; - } - -+static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ X86MachineState *x86ms = X86_MACHINE(ms); -+ -+ if (x86ms->smm == ON_OFF_AUTO_AUTO) { -+ x86ms->smm = ON_OFF_AUTO_OFF; -+ } else if (x86ms->smm == ON_OFF_AUTO_ON) { -+ error_setg(errp, "SEV-SNP does not support SMM."); -+ return -1; -+ } -+ -+ return 0; -+} -+ - int - sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) - { -@@ -1752,6 +1767,10 @@ sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp) - static void - sev_snp_guest_class_init(ObjectClass *oc, void *data) - { -+ SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); -+ -+ klass->kvm_init = sev_snp_kvm_init; -+ - object_class_property_add(oc, "policy", "uint64", - sev_snp_guest_get_policy, - sev_snp_guest_set_policy, NULL, NULL); -@@ -1778,8 +1797,11 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - static void - sev_snp_guest_instance_init(Object *obj) - { -+ ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj); - SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); - -+ cgs->require_guest_memfd = true; -+ - /* default init/start/finish params for kvm */ - sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY; - } --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-support-for-SNP-CPUID-validation.patch b/SOURCES/kvm-i386-sev-Add-support-for-SNP-CPUID-validation.patch deleted file mode 100644 index c10f75f..0000000 --- a/SOURCES/kvm-i386-sev-Add-support-for-SNP-CPUID-validation.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 4013364679757161d6b9754bfc33ae38be0a1b7f Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:32 -0500 -Subject: [PATCH 072/100] i386/sev: Add support for SNP CPUID validation - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [72/91] 080e2942552dc7de8966e69d0d0d3b8951392030 (bonzini/rhel-qemu-kvm) - -SEV-SNP firmware allows a special guest page to be populated with a -table of guest CPUID values so that they can be validated through -firmware before being loaded into encrypted guest memory where they can -be used in place of hypervisor-provided values[1]. - -As part of SEV-SNP guest initialization, use this interface to validate -the CPUID entries reported by KVM_GET_CPUID2 prior to initial guest -start and populate the CPUID page reserved by OVMF with the resulting -encrypted data. - -[1] SEV SNP Firmware ABI Specification, Rev. 0.8, 8.13.2.6 - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-21-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 70943ad8e4dfbe5f77006b880290219be9d03553) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 164 +++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 162 insertions(+), 2 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index c57534fca2..06401f0526 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -200,6 +200,36 @@ static const char *const sev_fw_errlist[] = { - - #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) - -+/* doesn't expose this, so re-use the max from kvm.c */ -+#define KVM_MAX_CPUID_ENTRIES 100 -+ -+typedef struct KvmCpuidInfo { -+ struct kvm_cpuid2 cpuid; -+ struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; -+} KvmCpuidInfo; -+ -+#define SNP_CPUID_FUNCTION_MAXCOUNT 64 -+#define SNP_CPUID_FUNCTION_UNKNOWN 0xFFFFFFFF -+ -+typedef struct { -+ uint32_t eax_in; -+ uint32_t ecx_in; -+ uint64_t xcr0_in; -+ uint64_t xss_in; -+ uint32_t eax; -+ uint32_t ebx; -+ uint32_t ecx; -+ uint32_t edx; -+ uint64_t reserved; -+} __attribute__((packed)) SnpCpuidFunc; -+ -+typedef struct { -+ uint32_t count; -+ uint32_t reserved1; -+ uint64_t reserved2; -+ SnpCpuidFunc entries[SNP_CPUID_FUNCTION_MAXCOUNT]; -+} __attribute__((packed)) SnpCpuidInfo; -+ - static int - sev_ioctl(int fd, int cmd, void *data, int *error) - { -@@ -788,6 +818,35 @@ out: - return ret; - } - -+static void -+sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old, -+ SnpCpuidInfo *new) -+{ -+ size_t i; -+ -+ if (old->count != new->count) { -+ error_report("SEV-SNP: CPUID validation failed due to count mismatch," -+ "provided: %d, expected: %d", old->count, new->count); -+ return; -+ } -+ -+ for (i = 0; i < old->count; i++) { -+ SnpCpuidFunc *old_func, *new_func; -+ -+ old_func = &old->entries[i]; -+ new_func = &new->entries[i]; -+ -+ if (memcmp(old_func, new_func, sizeof(SnpCpuidFunc))) { -+ error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x" -+ "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x" -+ "expected: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x", -+ old_func->eax_in, old_func->ecx_in, -+ old_func->eax, old_func->ebx, old_func->ecx, old_func->edx, -+ new_func->eax, new_func->ebx, new_func->ecx, new_func->edx); -+ } -+ } -+} -+ - static const char * - snp_page_type_to_str(int type) - { -@@ -806,6 +865,7 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, - SevLaunchUpdateData *data) - { - int ret, fw_error; -+ SnpCpuidInfo snp_cpuid_info; - struct kvm_sev_snp_launch_update update = {0}; - - if (!data->hva || !data->len) { -@@ -815,6 +875,11 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, - return 1; - } - -+ if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) { -+ /* Save a copy for comparison in case the LAUNCH_UPDATE fails */ -+ memcpy(&snp_cpuid_info, data->hva, sizeof(snp_cpuid_info)); -+ } -+ - update.uaddr = (__u64)(unsigned long)data->hva; - update.gfn_start = data->gpa >> TARGET_PAGE_BITS; - update.len = data->len; -@@ -842,6 +907,11 @@ sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, - if (ret && ret != -EAGAIN) { - error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'", - ret, fw_error, fw_error_to_str(fw_error)); -+ -+ if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) { -+ sev_snp_cpuid_report_mismatches(&snp_cpuid_info, data->hva); -+ error_report("SEV-SNP: failed update CPUID page"); -+ } - break; - } - } -@@ -1004,7 +1074,8 @@ sev_launch_finish(SevCommonState *sev_common) - } - - static int --snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type) -+snp_launch_update_data(uint64_t gpa, void *hva, -+ uint32_t len, int type) - { - SevLaunchUpdateData *data; - -@@ -1019,6 +1090,90 @@ snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type) - return 0; - } - -+static int -+sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info, -+ const KvmCpuidInfo *kvm_cpuid_info) -+{ -+ size_t i; -+ -+ if (kvm_cpuid_info->cpuid.nent > SNP_CPUID_FUNCTION_MAXCOUNT) { -+ error_report("SEV-SNP: CPUID entry count (%d) exceeds max (%d)", -+ kvm_cpuid_info->cpuid.nent, SNP_CPUID_FUNCTION_MAXCOUNT); -+ return -1; -+ } -+ -+ memset(snp_cpuid_info, 0, sizeof(*snp_cpuid_info)); -+ -+ for (i = 0; i < kvm_cpuid_info->cpuid.nent; i++) { -+ const struct kvm_cpuid_entry2 *kvm_cpuid_entry; -+ SnpCpuidFunc *snp_cpuid_entry; -+ -+ kvm_cpuid_entry = &kvm_cpuid_info->entries[i]; -+ snp_cpuid_entry = &snp_cpuid_info->entries[i]; -+ -+ snp_cpuid_entry->eax_in = kvm_cpuid_entry->function; -+ if (kvm_cpuid_entry->flags == KVM_CPUID_FLAG_SIGNIFCANT_INDEX) { -+ snp_cpuid_entry->ecx_in = kvm_cpuid_entry->index; -+ } -+ snp_cpuid_entry->eax = kvm_cpuid_entry->eax; -+ snp_cpuid_entry->ebx = kvm_cpuid_entry->ebx; -+ snp_cpuid_entry->ecx = kvm_cpuid_entry->ecx; -+ snp_cpuid_entry->edx = kvm_cpuid_entry->edx; -+ -+ /* -+ * Guest kernels will calculate EBX themselves using the 0xD -+ * subfunctions corresponding to the individual XSAVE areas, so only -+ * encode the base XSAVE size in the initial leaves, corresponding -+ * to the initial XCR0=1 state. -+ */ -+ if (snp_cpuid_entry->eax_in == 0xD && -+ (snp_cpuid_entry->ecx_in == 0x0 || snp_cpuid_entry->ecx_in == 0x1)) { -+ snp_cpuid_entry->ebx = 0x240; -+ snp_cpuid_entry->xcr0_in = 1; -+ snp_cpuid_entry->xss_in = 0; -+ } -+ } -+ -+ snp_cpuid_info->count = i; -+ -+ return 0; -+} -+ -+static int -+snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len) -+{ -+ KvmCpuidInfo kvm_cpuid_info = {0}; -+ SnpCpuidInfo snp_cpuid_info; -+ CPUState *cs = first_cpu; -+ int ret; -+ uint32_t i = 0; -+ -+ assert(sizeof(snp_cpuid_info) <= cpuid_len); -+ -+ /* get the cpuid list from KVM */ -+ do { -+ kvm_cpuid_info.cpuid.nent = ++i; -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_CPUID2, &kvm_cpuid_info); -+ } while (ret == -E2BIG); -+ -+ if (ret) { -+ error_report("SEV-SNP: unable to query CPUID values for CPU: '%s'", -+ strerror(-ret)); -+ return 1; -+ } -+ -+ ret = sev_snp_cpuid_info_fill(&snp_cpuid_info, &kvm_cpuid_info); -+ if (ret) { -+ error_report("SEV-SNP: failed to generate CPUID table information"); -+ return 1; -+ } -+ -+ memcpy(hva, &snp_cpuid_info, sizeof(snp_cpuid_info)); -+ -+ return snp_launch_update_data(cpuid_addr, hva, cpuid_len, -+ KVM_SEV_SNP_PAGE_TYPE_CPUID); -+} -+ - static int - snp_metadata_desc_to_page_type(int desc_type) - { -@@ -1053,7 +1208,12 @@ snp_populate_metadata_pages(SevSnpGuestState *sev_snp, - exit(1); - } - -- ret = snp_launch_update_data(desc->base, hva, desc->len, type); -+ if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) { -+ ret = snp_launch_update_cpuid(desc->base, hva, desc->len); -+ } else { -+ ret = snp_launch_update_data(desc->base, hva, desc->len, type); -+ } -+ - if (ret) { - error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d", - __func__, desc->base, desc->len, desc->type); --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-support-for-populating-OVMF-metadata-pa.patch b/SOURCES/kvm-i386-sev-Add-support-for-populating-OVMF-metadata-pa.patch deleted file mode 100644 index 4691679..0000000 --- a/SOURCES/kvm-i386-sev-Add-support-for-populating-OVMF-metadata-pa.patch +++ /dev/null @@ -1,127 +0,0 @@ -From b2cfd4d89026e76ba86ea7adea323f2c3a588790 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:31 -0500 -Subject: [PATCH 071/100] i386/sev: Add support for populating OVMF metadata - pages - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [71/91] b563442c0e2f6ea01937425d300b56d9e641fd57 (bonzini/rhel-qemu-kvm) - -OVMF reserves various pages so they can be pre-initialized/validated -prior to launching the guest. Add support for populating these pages -with the expected content. - -Signed-off-by: Brijesh Singh -Signed-off-by: Michael Roth -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-20-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 3d8c2a7f4806ff39423312e503737fd76c34dcae) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 74 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 17281bb2c7..c57534fca2 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1003,15 +1003,89 @@ sev_launch_finish(SevCommonState *sev_common) - migrate_add_blocker(&sev_mig_blocker, &error_fatal); - } - -+static int -+snp_launch_update_data(uint64_t gpa, void *hva, uint32_t len, int type) -+{ -+ SevLaunchUpdateData *data; -+ -+ data = g_new0(SevLaunchUpdateData, 1); -+ data->gpa = gpa; -+ data->hva = hva; -+ data->len = len; -+ data->type = type; -+ -+ QTAILQ_INSERT_TAIL(&launch_update, data, next); -+ -+ return 0; -+} -+ -+static int -+snp_metadata_desc_to_page_type(int desc_type) -+{ -+ switch (desc_type) { -+ /* Add the umeasured prevalidated pages as a zero page */ -+ case SEV_DESC_TYPE_SNP_SEC_MEM: return KVM_SEV_SNP_PAGE_TYPE_ZERO; -+ case SEV_DESC_TYPE_SNP_SECRETS: return KVM_SEV_SNP_PAGE_TYPE_SECRETS; -+ case SEV_DESC_TYPE_CPUID: return KVM_SEV_SNP_PAGE_TYPE_CPUID; -+ default: -+ return KVM_SEV_SNP_PAGE_TYPE_ZERO; -+ } -+} -+ -+static void -+snp_populate_metadata_pages(SevSnpGuestState *sev_snp, -+ OvmfSevMetadata *metadata) -+{ -+ OvmfSevMetadataDesc *desc; -+ int type, ret, i; -+ void *hva; -+ MemoryRegion *mr = NULL; -+ -+ for (i = 0; i < metadata->num_desc; i++) { -+ desc = &metadata->descs[i]; -+ -+ type = snp_metadata_desc_to_page_type(desc->type); -+ -+ hva = gpa2hva(&mr, desc->base, desc->len, NULL); -+ if (!hva) { -+ error_report("%s: Failed to get HVA for GPA 0x%x sz 0x%x", -+ __func__, desc->base, desc->len); -+ exit(1); -+ } -+ -+ ret = snp_launch_update_data(desc->base, hva, desc->len, type); -+ if (ret) { -+ error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d", -+ __func__, desc->base, desc->len, desc->type); -+ exit(1); -+ } -+ } -+} -+ - static void - sev_snp_launch_finish(SevCommonState *sev_common) - { - int ret, error; - Error *local_err = NULL; -+ OvmfSevMetadata *metadata; - SevLaunchUpdateData *data; - SevSnpGuestState *sev_snp = SEV_SNP_GUEST(sev_common); - struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf; - -+ /* -+ * To boot the SNP guest, the hypervisor is required to populate the CPUID -+ * and Secrets page before finalizing the launch flow. The location of -+ * the secrets and CPUID page is available through the OVMF metadata GUID. -+ */ -+ metadata = pc_system_get_ovmf_sev_metadata_ptr(); -+ if (metadata == NULL) { -+ error_report("%s: Failed to locate SEV metadata header", __func__); -+ exit(1); -+ } -+ -+ /* Populate all the metadata pages */ -+ snp_populate_metadata_pages(sev_snp, metadata); -+ - QTAILQ_FOREACH(data, &launch_update, next) { - ret = sev_snp_launch_update(sev_snp, data); - if (ret) { --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Add-the-SNP-launch-start-context.patch b/SOURCES/kvm-i386-sev-Add-the-SNP-launch-start-context.patch deleted file mode 100644 index 5da793f..0000000 --- a/SOURCES/kvm-i386-sev-Add-the-SNP-launch-start-context.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0f7432f2b968298b64fd243df793b176f67a538f Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:27 -0500 -Subject: [PATCH 067/100] i386/sev: Add the SNP launch start context - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [67/91] 63759a25a413a7a9a7274fb4c3b8bc2528634855 (bonzini/rhel-qemu-kvm) - -The SNP_LAUNCH_START is called first to create a cryptographic launch -context within the firmware. - -Signed-off-by: Brijesh Singh -Signed-off-by: Michael Roth -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-16-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit d3107f882ec22cfb211eab7efa0c4e95f5ce11bb) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 39 +++++++++++++++++++++++++++++++++++++++ - target/i386/trace-events | 1 + - 2 files changed, 40 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 43d1c48bd9..e89b87d2f5 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -39,6 +39,7 @@ - #include "confidential-guest.h" - #include "hw/i386/pc.h" - #include "exec/address-spaces.h" -+#include "qemu/queue.h" - - OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON) - OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST) -@@ -115,6 +116,16 @@ struct SevSnpGuestState { - #define DEFAULT_SEV_DEVICE "/dev/sev" - #define DEFAULT_SEV_SNP_POLICY 0x30000 - -+typedef struct SevLaunchUpdateData { -+ QTAILQ_ENTRY(SevLaunchUpdateData) next; -+ hwaddr gpa; -+ void *hva; -+ uint64_t len; -+ int type; -+} SevLaunchUpdateData; -+ -+static QTAILQ_HEAD(, SevLaunchUpdateData) launch_update; -+ - #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e" - typedef struct __attribute__((__packed__)) SevInfoBlock { - /* SEV-ES Reset Vector Address */ -@@ -674,6 +685,31 @@ sev_read_file_base64(const char *filename, guchar **data, gsize *len) - return 0; - } - -+static int -+sev_snp_launch_start(SevCommonState *sev_common) -+{ -+ int fw_error, rc; -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common); -+ struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf; -+ -+ trace_kvm_sev_snp_launch_start(start->policy, -+ sev_snp_guest->guest_visible_workarounds); -+ -+ rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START, -+ start, &fw_error); -+ if (rc < 0) { -+ error_report("%s: SNP_LAUNCH_START ret=%d fw_error=%d '%s'", -+ __func__, rc, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ QTAILQ_INIT(&launch_update); -+ -+ sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE); -+ -+ return 0; -+} -+ - static int - sev_launch_start(SevCommonState *sev_common) - { -@@ -1003,6 +1039,7 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - ret = klass->launch_start(sev_common); -+ - if (ret) { - error_setg(errp, "%s: failed to create encryption context", __func__); - return -1; -@@ -1794,9 +1831,11 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - -+ klass->launch_start = sev_snp_launch_start; - klass->kvm_init = sev_snp_kvm_init; - x86_klass->kvm_type = sev_snp_kvm_type; - -+ - object_class_property_add(oc, "policy", "uint64", - sev_snp_guest_get_policy, - sev_snp_guest_set_policy, NULL, NULL); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 2cd8726eeb..cb26d8a925 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -11,3 +11,4 @@ kvm_sev_launch_measurement(const char *value) "data %s" - kvm_sev_launch_finish(void) "" - kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" - kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" -+kvm_sev_snp_launch_start(uint64_t policy, char *gosvw) "policy 0x%" PRIx64 " gosvw %s" --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Allow-measured-direct-kernel-boot-on-SNP.patch b/SOURCES/kvm-i386-sev-Allow-measured-direct-kernel-boot-on-SNP.patch deleted file mode 100644 index f809242..0000000 --- a/SOURCES/kvm-i386-sev-Allow-measured-direct-kernel-boot-on-SNP.patch +++ /dev/null @@ -1,237 +0,0 @@ -From ec786a1ec0a76775e980862d77500f5196a937e3 Mon Sep 17 00:00:00 2001 -From: Dov Murik -Date: Thu, 30 May 2024 06:16:35 -0500 -Subject: [PATCH 080/100] i386/sev: Allow measured direct kernel boot on SNP - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [80/91] 11c629862519c1a279566febf5a537c63c5fcf61 (bonzini/rhel-qemu-kvm) - -In SNP, the hashes page designated with a specific metadata entry -published in AmdSev OVMF. - -Therefore, if the user enabled kernel hashes (for measured direct boot), -QEMU should prepare the content of hashes table, and during the -processing of the metadata entry it copy the content into the designated -page and encrypt it. - -Note that in SNP (unlike SEV and SEV-ES) the measurements is done in -whole 4KB pages. Therefore QEMU zeros the whole page that includes the -hashes table, and fills in the kernel hashes area in that page, and then -encrypts the whole page. The rest of the page is reserved for SEV -launch secrets which are not usable anyway on SNP. - -If the user disabled kernel hashes, QEMU pre-validates the kernel hashes -page as a zero page. - -Signed-off-by: Dov Murik -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-24-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit c1996992cc882b00139f78067d6a64e2ec9cb0d8) -Signed-off-by: Paolo Bonzini ---- - include/hw/i386/pc.h | 2 + - target/i386/sev.c | 111 ++++++++++++++++++++++++++++++++----------- - 2 files changed, 85 insertions(+), 28 deletions(-) - -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 94b49310f5..ee3bfb7be9 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -175,6 +175,8 @@ typedef enum { - SEV_DESC_TYPE_SNP_SECRETS, - /* The section contains address that can be used as a CPUID page */ - SEV_DESC_TYPE_CPUID, -+ /* The section contains the region for kernel hashes for measured direct boot */ -+ SEV_DESC_TYPE_SNP_KERNEL_HASHES = 0x10, - - } ovmf_sev_metadata_desc_type; - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 3fce4c08eb..004c667ac1 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -115,6 +115,10 @@ struct SevCommonStateClass { - X86ConfidentialGuestClass parent_class; - - /* public */ -+ bool (*build_kernel_loader_hashes)(SevCommonState *sev_common, -+ SevHashTableDescriptor *area, -+ SevKernelLoaderContext *ctx, -+ Error **errp); - int (*launch_start)(SevCommonState *sev_common); - void (*launch_finish)(SevCommonState *sev_common); - int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len); -@@ -154,6 +158,9 @@ struct SevSnpGuestState { - - struct kvm_sev_snp_launch_start kvm_start_conf; - struct kvm_sev_snp_launch_finish kvm_finish_conf; -+ -+ uint32_t kernel_hashes_offset; -+ PaddedSevHashTable *kernel_hashes_data; - }; - - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ -@@ -1189,6 +1196,23 @@ snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len) - KVM_SEV_SNP_PAGE_TYPE_CPUID); - } - -+static int -+snp_launch_update_kernel_hashes(SevSnpGuestState *sev_snp, uint32_t addr, -+ void *hva, uint32_t len) -+{ -+ int type = KVM_SEV_SNP_PAGE_TYPE_ZERO; -+ if (sev_snp->parent_obj.kernel_hashes) { -+ assert(sev_snp->kernel_hashes_data); -+ assert((sev_snp->kernel_hashes_offset + -+ sizeof(*sev_snp->kernel_hashes_data)) <= len); -+ memset(hva, 0, len); -+ memcpy(hva + sev_snp->kernel_hashes_offset, sev_snp->kernel_hashes_data, -+ sizeof(*sev_snp->kernel_hashes_data)); -+ type = KVM_SEV_SNP_PAGE_TYPE_NORMAL; -+ } -+ return snp_launch_update_data(addr, hva, len, type); -+} -+ - static int - snp_metadata_desc_to_page_type(int desc_type) - { -@@ -1225,6 +1249,9 @@ snp_populate_metadata_pages(SevSnpGuestState *sev_snp, - - if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) { - ret = snp_launch_update_cpuid(desc->base, hva, desc->len); -+ } else if (desc->type == SEV_DESC_TYPE_SNP_KERNEL_HASHES) { -+ ret = snp_launch_update_kernel_hashes(sev_snp, desc->base, hva, -+ desc->len); - } else { - ret = snp_launch_update_data(desc->base, hva, desc->len, type); - } -@@ -1823,6 +1850,58 @@ static bool build_kernel_loader_hashes(PaddedSevHashTable *padded_ht, - return true; - } - -+static bool sev_snp_build_kernel_loader_hashes(SevCommonState *sev_common, -+ SevHashTableDescriptor *area, -+ SevKernelLoaderContext *ctx, -+ Error **errp) -+{ -+ /* -+ * SNP: Populate the hashes table in an area that later in -+ * snp_launch_update_kernel_hashes() will be copied to the guest memory -+ * and encrypted. -+ */ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common); -+ sev_snp_guest->kernel_hashes_offset = area->base & ~TARGET_PAGE_MASK; -+ sev_snp_guest->kernel_hashes_data = g_new0(PaddedSevHashTable, 1); -+ return build_kernel_loader_hashes(sev_snp_guest->kernel_hashes_data, ctx, errp); -+} -+ -+static bool sev_build_kernel_loader_hashes(SevCommonState *sev_common, -+ SevHashTableDescriptor *area, -+ SevKernelLoaderContext *ctx, -+ Error **errp) -+{ -+ PaddedSevHashTable *padded_ht; -+ hwaddr mapped_len = sizeof(*padded_ht); -+ MemTxAttrs attrs = { 0 }; -+ bool ret = true; -+ -+ /* -+ * Populate the hashes table in the guest's memory at the OVMF-designated -+ * area for the SEV hashes table -+ */ -+ padded_ht = address_space_map(&address_space_memory, area->base, -+ &mapped_len, true, attrs); -+ if (!padded_ht || mapped_len != sizeof(*padded_ht)) { -+ error_setg(errp, "SEV: cannot map hashes table guest memory area"); -+ return false; -+ } -+ -+ if (build_kernel_loader_hashes(padded_ht, ctx, errp)) { -+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht, -+ sizeof(*padded_ht), errp) < 0) { -+ ret = false; -+ } -+ } else { -+ ret = false; -+ } -+ -+ address_space_unmap(&address_space_memory, padded_ht, -+ mapped_len, true, mapped_len); -+ -+ return ret; -+} -+ - /* - * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page - * which is included in SEV's initial memory measurement. -@@ -1831,11 +1910,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - { - uint8_t *data; - SevHashTableDescriptor *area; -- PaddedSevHashTable *padded_ht; -- hwaddr mapped_len = sizeof(*padded_ht); -- MemTxAttrs attrs = { 0 }; -- bool ret = true; - SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common); - - /* - * Only add the kernel hashes if the sev-guest configuration explicitly -@@ -1858,30 +1934,7 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return false; - } - -- /* -- * Populate the hashes table in the guest's memory at the OVMF-designated -- * area for the SEV hashes table -- */ -- padded_ht = address_space_map(&address_space_memory, area->base, -- &mapped_len, true, attrs); -- if (!padded_ht || mapped_len != sizeof(*padded_ht)) { -- error_setg(errp, "SEV: cannot map hashes table guest memory area"); -- return false; -- } -- -- if (build_kernel_loader_hashes(padded_ht, ctx, errp)) { -- if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht, -- sizeof(*padded_ht), errp) < 0) { -- ret = false; -- } -- } else { -- ret = false; -- } -- -- address_space_unmap(&address_space_memory, padded_ht, -- mapped_len, true, mapped_len); -- -- return ret; -+ return klass->build_kernel_loader_hashes(sev_common, area, ctx, errp); - } - - static char * -@@ -1998,6 +2051,7 @@ sev_guest_class_init(ObjectClass *oc, void *data) - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - -+ klass->build_kernel_loader_hashes = sev_build_kernel_loader_hashes; - klass->launch_start = sev_launch_start; - klass->launch_finish = sev_launch_finish; - klass->launch_update_data = sev_launch_update_data; -@@ -2242,6 +2296,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - -+ klass->build_kernel_loader_hashes = sev_snp_build_kernel_loader_hashes; - klass->launch_start = sev_snp_launch_start; - klass->launch_finish = sev_snp_launch_finish; - klass->launch_update_data = sev_snp_launch_update_data; --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Don-t-allow-automatic-fallback-to-legacy-KV.patch b/SOURCES/kvm-i386-sev-Don-t-allow-automatic-fallback-to-legacy-KV.patch deleted file mode 100644 index aacb0da..0000000 --- a/SOURCES/kvm-i386-sev-Don-t-allow-automatic-fallback-to-legacy-KV.patch +++ /dev/null @@ -1,268 +0,0 @@ -From ab6197309551bd6ddd9f8239191f68dfac23684b Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Tue, 9 Jul 2024 23:10:05 -0500 -Subject: [PATCH 090/100] i386/sev: Don't allow automatic fallback to legacy - KVM_SEV*_INIT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [90/91] 2b1345faa56f993bb6e13d63e11656c784e20412 (bonzini/rhel-qemu-kvm) - -Currently if the 'legacy-vm-type' property of the sev-guest object is -'on', QEMU will attempt to use the newer KVM_SEV_INIT2 kernel -interface in conjunction with the newer KVM_X86_SEV_VM and -KVM_X86_SEV_ES_VM KVM VM types. - -This can lead to measurement changes if, for instance, an SEV guest was -created on a host that originally had an older kernel that didn't -support KVM_SEV_INIT2, but is booted on the same host later on after the -host kernel was upgraded. - -Instead, if legacy-vm-type is 'off', QEMU should fail if the -KVM_SEV_INIT2 interface is not provided by the current host kernel. -Modify the fallback handling accordingly. - -In the future, VMSA features and other flags might be added to QEMU -which will require legacy-vm-type to be 'off' because they will rely -on the newer KVM_SEV_INIT2 interface. It may be difficult to convey to -users what values of legacy-vm-type are compatible with which -features/options, so as part of this rework, switch legacy-vm-type to a -tri-state OnOffAuto option. 'auto' in this case will automatically -switch to using the newer KVM_SEV_INIT2, but only if it is required to -make use of new VMSA features or other options only available via -KVM_SEV_INIT2. - -Defining 'auto' in this way would avoid inadvertantly breaking -compatibility with older kernels since it would only be used in cases -where users opt into newer features that are only available via -KVM_SEV_INIT2 and newer kernels, and provide better default behavior -than the legacy-vm-type=off behavior that was previously in place, so -make it the default for 9.1+ machine types. - -Cc: Daniel P. Berrangé -Cc: Paolo Bonzini -cc: kvm@vger.kernel.org -Signed-off-by: Michael Roth -Reviewed-by: Daniel P. Berrangé -Link: https://lore.kernel.org/r/20240710041005.83720-1-michael.roth@amd.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 9d38d9dca2a81aaf5752d45d221021ef96d496cd) - -RHEL: adjust compatiility setting, applying it to 9.4 machine type ---- - hw/i386/pc.c | 2 +- - qapi/qom.json | 18 ++++++---- - target/i386/sev.c | 85 +++++++++++++++++++++++++++++++++++++++-------- - 3 files changed, 83 insertions(+), 22 deletions(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index b25d075b59..e9c5ea5d8f 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -352,7 +352,7 @@ const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); - GlobalProperty pc_rhel_9_5_compat[] = { - /* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */ - { TYPE_X86_CPU, "guest-phys-bits", "0" }, -- { "sev-guest", "legacy-vm-type", "true" }, -+ { "sev-guest", "legacy-vm-type", "on" }, - }; - const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat); - -diff --git a/qapi/qom.json b/qapi/qom.json -index 8bd299265e..17bd5a0cf7 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -912,12 +912,16 @@ - # @handle: SEV firmware handle (default: 0) - # - # @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM. --# The newer KVM_SEV_INIT2 interface syncs additional vCPU --# state when initializing the VMSA structures, which will --# result in a different guest measurement. Set this to --# maintain compatibility with older QEMU or kernel versions --# that rely on legacy KVM_SEV_INIT behavior. --# (default: false) (since 9.1) -+# The newer KVM_SEV_INIT2 interface, from Linux >= 6.10, syncs -+# additional vCPU state when initializing the VMSA structures, -+# which will result in a different guest measurement. Set -+# this to 'on' to force compatibility with older QEMU or kernel -+# versions that rely on legacy KVM_SEV_INIT behavior. 'auto' -+# will behave identically to 'on', but will automatically -+# switch to using KVM_SEV_INIT2 if the user specifies any -+# additional options that require it. If set to 'off', QEMU -+# will require KVM_SEV_INIT2 unconditionally. -+# (default: off) (since 9.1) - # - # Since: 2.12 - ## -@@ -927,7 +931,7 @@ - '*session-file': 'str', - '*policy': 'uint32', - '*handle': 'uint32', -- '*legacy-vm-type': 'bool' } } -+ '*legacy-vm-type': 'OnOffAuto' } } - - ## - # @SevSnpGuestProperties: -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 491fab74fd..b921defb63 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -144,7 +144,7 @@ struct SevGuestState { - uint32_t policy; - char *dh_cert_file; - char *session_file; -- bool legacy_vm_type; -+ OnOffAuto legacy_vm_type; - }; - - struct SevSnpGuestState { -@@ -1334,6 +1334,17 @@ sev_vm_state_change(void *opaque, bool running, RunState state) - } - } - -+/* -+ * This helper is to examine sev-guest properties and determine if any options -+ * have been set which rely on the newer KVM_SEV_INIT2 interface and associated -+ * KVM VM types. -+ */ -+static bool sev_init2_required(SevGuestState *sev_guest) -+{ -+ /* Currently no KVM_SEV_INIT2-specific options are exposed via QEMU */ -+ return false; -+} -+ - static int sev_kvm_type(X86ConfidentialGuest *cg) - { - SevCommonState *sev_common = SEV_COMMON(cg); -@@ -1344,14 +1355,39 @@ static int sev_kvm_type(X86ConfidentialGuest *cg) - goto out; - } - -+ /* These are the only cases where legacy VM types can be used. */ -+ if (sev_guest->legacy_vm_type == ON_OFF_AUTO_ON || -+ (sev_guest->legacy_vm_type == ON_OFF_AUTO_AUTO && -+ !sev_init2_required(sev_guest))) { -+ sev_common->kvm_type = KVM_X86_DEFAULT_VM; -+ goto out; -+ } -+ -+ /* -+ * Newer VM types are required, either explicitly via legacy-vm-type=on, or -+ * implicitly via legacy-vm-type=auto along with additional sev-guest -+ * properties that require the newer VM types. -+ */ - kvm_type = (sev_guest->policy & SEV_POLICY_ES) ? - KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM; -- if (kvm_is_vm_type_supported(kvm_type) && !sev_guest->legacy_vm_type) { -- sev_common->kvm_type = kvm_type; -- } else { -- sev_common->kvm_type = KVM_X86_DEFAULT_VM; -+ if (!kvm_is_vm_type_supported(kvm_type)) { -+ if (sev_guest->legacy_vm_type == ON_OFF_AUTO_AUTO) { -+ error_report("SEV: host kernel does not support requested %s VM type, which is required " -+ "for the set of options specified. To allow use of the legacy " -+ "KVM_X86_DEFAULT_VM VM type, please disable any options that are not " -+ "compatible with the legacy VM type, or upgrade your kernel.", -+ kvm_type == KVM_X86_SEV_VM ? "KVM_X86_SEV_VM" : "KVM_X86_SEV_ES_VM"); -+ } else { -+ error_report("SEV: host kernel does not support requested %s VM type. To allow use of " -+ "the legacy KVM_X86_DEFAULT_VM VM type, the 'legacy-vm-type' argument " -+ "must be set to 'on' or 'auto' for the sev-guest object.", -+ kvm_type == KVM_X86_SEV_VM ? "KVM_X86_SEV_VM" : "KVM_X86_SEV_ES_VM"); -+ } -+ -+ return -1; - } - -+ sev_common->kvm_type = kvm_type; - out: - return sev_common->kvm_type; - } -@@ -1442,14 +1478,24 @@ static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - trace_kvm_sev_init(); -- if (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) { -+ switch (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common))) { -+ case KVM_X86_DEFAULT_VM: - cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT; - - ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error); -- } else { -+ break; -+ case KVM_X86_SEV_VM: -+ case KVM_X86_SEV_ES_VM: -+ case KVM_X86_SNP_VM: { - struct kvm_sev_init args = { 0 }; - - ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_INIT2, &args, &fw_error); -+ break; -+ } -+ default: -+ error_setg(errp, "%s: host kernel does not support the requested SEV configuration.", -+ __func__); -+ return -1; - } - - if (ret) { -@@ -2037,14 +2083,23 @@ sev_guest_set_session_file(Object *obj, const char *value, Error **errp) - SEV_GUEST(obj)->session_file = g_strdup(value); - } - --static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp) -+static void sev_guest_get_legacy_vm_type(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) - { -- return SEV_GUEST(obj)->legacy_vm_type; -+ SevGuestState *sev_guest = SEV_GUEST(obj); -+ OnOffAuto legacy_vm_type = sev_guest->legacy_vm_type; -+ -+ visit_type_OnOffAuto(v, name, &legacy_vm_type, errp); - } - --static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp) -+static void sev_guest_set_legacy_vm_type(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) - { -- SEV_GUEST(obj)->legacy_vm_type = value; -+ SevGuestState *sev_guest = SEV_GUEST(obj); -+ -+ visit_type_OnOffAuto(v, name, &sev_guest->legacy_vm_type, errp); - } - - static void -@@ -2070,9 +2125,9 @@ sev_guest_class_init(ObjectClass *oc, void *data) - sev_guest_set_session_file); - object_class_property_set_description(oc, "session-file", - "guest owners session parameters (encoded with base64)"); -- object_class_property_add_bool(oc, "legacy-vm-type", -- sev_guest_get_legacy_vm_type, -- sev_guest_set_legacy_vm_type); -+ object_class_property_add(oc, "legacy-vm-type", "OnOffAuto", -+ sev_guest_get_legacy_vm_type, -+ sev_guest_set_legacy_vm_type, NULL, NULL); - object_class_property_set_description(oc, "legacy-vm-type", - "use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions."); - } -@@ -2088,6 +2143,8 @@ sev_guest_instance_init(Object *obj) - object_property_add_uint32_ptr(obj, "policy", &sev_guest->policy, - OBJ_PROP_FLAG_READWRITE); - object_apply_compat_props(obj); -+ -+ sev_guest->legacy_vm_type = ON_OFF_AUTO_AUTO; - } - - /* guest info specific sev/sev-es */ --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Don-t-return-launch-measurements-for-SEV-SN.patch b/SOURCES/kvm-i386-sev-Don-t-return-launch-measurements-for-SEV-SN.patch deleted file mode 100644 index 739a145..0000000 --- a/SOURCES/kvm-i386-sev-Don-t-return-launch-measurements-for-SEV-SN.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ebb3c3536366c383fa09b0987a4efb68d018b7b8 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:24 -0500 -Subject: [PATCH 064/100] i386/sev: Don't return launch measurements for - SEV-SNP guests - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [64/91] 5a29bb2d8b5a07aec6fd271ec37345e665e9cce4 (bonzini/rhel-qemu-kvm) - -For SEV-SNP guests, launch measurement is queried from within the guest -during attestation, so don't attempt to return it as part of -query-sev-launch-measure. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-13-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 73ae63b162fc1fed520f53ad200712964d7d0264) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 6525b3c1a0..c3daaf1ad5 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -795,7 +795,9 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - - static char *sev_get_launch_measurement(void) - { -- SevGuestState *sev_guest = SEV_GUEST(MACHINE(qdev_get_machine())->cgs); -+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs; -+ SevGuestState *sev_guest = -+ (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST); - - if (sev_guest && - SEV_COMMON(sev_guest)->state >= SEV_STATE_LAUNCH_SECRET) { --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Enable-KVM_HC_MAP_GPA_RANGE-hcall-for-SNP-g.patch b/SOURCES/kvm-i386-sev-Enable-KVM_HC_MAP_GPA_RANGE-hcall-for-SNP-g.patch deleted file mode 100644 index e438cd3..0000000 --- a/SOURCES/kvm-i386-sev-Enable-KVM_HC_MAP_GPA_RANGE-hcall-for-SNP-g.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0612c7ed587422ec7e07c27c8ca11b89c7aa8b02 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:43 -0500 -Subject: [PATCH 077/100] i386/sev: Enable KVM_HC_MAP_GPA_RANGE hcall for SNP - guests - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [77/91] 3c494eb54499c24121cc2c47045626478b8bb41e (bonzini/rhel-qemu-kvm) - -KVM will forward GHCB page-state change requests to userspace in the -form of KVM_HC_MAP_GPA_RANGE, so make sure the hypercall handling is -enabled for SNP guests. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-32-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit e3cddff93c1f88fea3b26841e792dc0be6b6fae8) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index eaf5fc6c6b..abb63062ac 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -14,6 +14,7 @@ - #include "qemu/osdep.h" - - #include -+#include - #include - - #include -@@ -758,6 +759,10 @@ sev_snp_launch_start(SevCommonState *sev_common) - trace_kvm_sev_snp_launch_start(start->policy, - sev_snp_guest->guest_visible_workarounds); - -+ if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) { -+ return 1; -+ } -+ - rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START, - start, &fw_error); - if (rc < 0) { --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Extract-build_kernel_loader_hashes.patch b/SOURCES/kvm-i386-sev-Extract-build_kernel_loader_hashes.patch deleted file mode 100644 index a06301d..0000000 --- a/SOURCES/kvm-i386-sev-Extract-build_kernel_loader_hashes.patch +++ /dev/null @@ -1,167 +0,0 @@ -From eed17520567c202f53ab767bfd42cfe303838772 Mon Sep 17 00:00:00 2001 -From: Dov Murik -Date: Thu, 30 May 2024 06:16:33 -0500 -Subject: [PATCH 078/100] i386/sev: Extract build_kernel_loader_hashes - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [78/91] 291ea10e774178826d1afd38fc8292d67c5fd42d (bonzini/rhel-qemu-kvm) - -Extract the building of the kernel hashes table out from -sev_add_kernel_loader_hashes() to allow building it in -other memory areas (for SNP support). - -No functional change intended. - -Signed-off-by: Dov Murik -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-22-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 06cbd66cecaa3230cccb330facac241a677b29d5) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 102 ++++++++++++++++++++++++++-------------------- - 1 file changed, 58 insertions(+), 44 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index abb63062ac..73f9406715 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1754,45 +1754,16 @@ static const QemuUUID sev_cmdline_entry_guid = { - 0x4d, 0x36, 0xab, 0x2a) - }; - --/* -- * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page -- * which is included in SEV's initial memory measurement. -- */ --bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) -+static bool build_kernel_loader_hashes(PaddedSevHashTable *padded_ht, -+ SevKernelLoaderContext *ctx, -+ Error **errp) - { -- uint8_t *data; -- SevHashTableDescriptor *area; - SevHashTable *ht; -- PaddedSevHashTable *padded_ht; - uint8_t cmdline_hash[HASH_SIZE]; - uint8_t initrd_hash[HASH_SIZE]; - uint8_t kernel_hash[HASH_SIZE]; - uint8_t *hashp; - size_t hash_len = HASH_SIZE; -- hwaddr mapped_len = sizeof(*padded_ht); -- MemTxAttrs attrs = { 0 }; -- bool ret = true; -- SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -- -- /* -- * Only add the kernel hashes if the sev-guest configuration explicitly -- * stated kernel-hashes=on. -- */ -- if (!sev_common->kernel_hashes) { -- return false; -- } -- -- if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) { -- error_setg(errp, "SEV: kernel specified but guest firmware " -- "has no hashes table GUID"); -- return false; -- } -- area = (SevHashTableDescriptor *)data; -- if (!area->base || area->size < sizeof(PaddedSevHashTable)) { -- error_setg(errp, "SEV: guest firmware hashes table area is invalid " -- "(base=0x%x size=0x%x)", area->base, area->size); -- return false; -- } - - /* - * Calculate hash of kernel command-line with the terminating null byte. If -@@ -1829,16 +1800,6 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - } - assert(hash_len == HASH_SIZE); - -- /* -- * Populate the hashes table in the guest's memory at the OVMF-designated -- * area for the SEV hashes table -- */ -- padded_ht = address_space_map(&address_space_memory, area->base, -- &mapped_len, true, attrs); -- if (!padded_ht || mapped_len != sizeof(*padded_ht)) { -- error_setg(errp, "SEV: cannot map hashes table guest memory area"); -- return false; -- } - ht = &padded_ht->ht; - - ht->guid = sev_hash_table_header_guid; -@@ -1859,8 +1820,61 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - /* zero the excess data so the measurement can be reliably calculated */ - memset(padded_ht->padding, 0, sizeof(padded_ht->padding)); - -- if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht, -- sizeof(*padded_ht), errp) < 0) { -+ return true; -+} -+ -+/* -+ * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page -+ * which is included in SEV's initial memory measurement. -+ */ -+bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) -+{ -+ uint8_t *data; -+ SevHashTableDescriptor *area; -+ PaddedSevHashTable *padded_ht; -+ hwaddr mapped_len = sizeof(*padded_ht); -+ MemTxAttrs attrs = { 0 }; -+ bool ret = true; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ -+ /* -+ * Only add the kernel hashes if the sev-guest configuration explicitly -+ * stated kernel-hashes=on. -+ */ -+ if (!sev_common->kernel_hashes) { -+ return false; -+ } -+ -+ if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) { -+ error_setg(errp, "SEV: kernel specified but guest firmware " -+ "has no hashes table GUID"); -+ return false; -+ } -+ -+ area = (SevHashTableDescriptor *)data; -+ if (!area->base || area->size < sizeof(PaddedSevHashTable)) { -+ error_setg(errp, "SEV: guest firmware hashes table area is invalid " -+ "(base=0x%x size=0x%x)", area->base, area->size); -+ return false; -+ } -+ -+ /* -+ * Populate the hashes table in the guest's memory at the OVMF-designated -+ * area for the SEV hashes table -+ */ -+ padded_ht = address_space_map(&address_space_memory, area->base, -+ &mapped_len, true, attrs); -+ if (!padded_ht || mapped_len != sizeof(*padded_ht)) { -+ error_setg(errp, "SEV: cannot map hashes table guest memory area"); -+ return false; -+ } -+ -+ if (build_kernel_loader_hashes(padded_ht, ctx, errp)) { -+ if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht, -+ sizeof(*padded_ht), errp) < 0) { -+ ret = false; -+ } -+ } else { - ret = false; - } - --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Fallback-to-the-default-SEV-device-if-none-.patch b/SOURCES/kvm-i386-sev-Fallback-to-the-default-SEV-device-if-none-.patch deleted file mode 100644 index 1d30674..0000000 --- a/SOURCES/kvm-i386-sev-Fallback-to-the-default-SEV-device-if-none-.patch +++ /dev/null @@ -1,65 +0,0 @@ -From a9530c89225fce9e381929c4cd8e372068827acf Mon Sep 17 00:00:00 2001 -From: Michal Privoznik -Date: Mon, 24 Jun 2024 10:52:49 +0200 -Subject: [PATCH 089/100] i386/sev: Fallback to the default SEV device if none - provided in sev_get_capabilities() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [89/91] 22318c20d7102815f754cec0efaf383e05ef79c1 (bonzini/rhel-qemu-kvm) - -When management tools (e.g. libvirt) query QEMU capabilities, -they start QEMU with a minimalistic configuration and issue -various commands on monitor. One of the command issued is/might -be "query-sev-capabilities" to learn values like cbitpos or -reduced-phys-bits. But as of v9.0.0-1145-g16dcf200dc the monitor -command returns an error instead. - -This creates a chicken-egg problem because in order to query -those aforementioned values QEMU needs to be started with a -'sev-guest' object. But to start QEMU with the values must be -known. - -I think it's safe to assume that the default path ("/dev/sev") -provides the same data as user provided one. So fall back to it. - -Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0 -Signed-off-by: Michal Privoznik -Link: https://lore.kernel.org/r/157f93712c23818be193ce785f648f0060b33dee.1719218926.git.mprivozn@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit 3fb24530b2bb1346a44e17becefc9865b40a2257) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 53b7f7315b..491fab74fd 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -585,13 +585,13 @@ static SevCapability *sev_get_capabilities(Error **errp) - } - - sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -- if (!sev_common) { -- error_setg(errp, "SEV is not configured"); -- return NULL; -+ if (sev_common) { -+ sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", -+ &error_abort); -+ } else { -+ sev_device = g_strdup(DEFAULT_SEV_DEVICE); - } - -- sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", -- &error_abort); - fd = open(sev_device, O_RDWR); - if (fd < 0) { - error_setg_errno(errp, errno, "SEV: Failed to open %s", --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Fix-error-message-in-sev_get_capabilities.patch b/SOURCES/kvm-i386-sev-Fix-error-message-in-sev_get_capabilities.patch deleted file mode 100644 index b23e008..0000000 --- a/SOURCES/kvm-i386-sev-Fix-error-message-in-sev_get_capabilities.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b672cdf8c10a530b5bcf6dd4489632891eb2c731 Mon Sep 17 00:00:00 2001 -From: Michal Privoznik -Date: Mon, 24 Jun 2024 10:52:48 +0200 -Subject: [PATCH 088/100] i386/sev: Fix error message in sev_get_capabilities() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [88/91] ff8a8b27af02e565172ffe39d0571c234317713d (bonzini/rhel-qemu-kvm) - -When a custom path is provided to sev-guest object and opening -the path fails an error message is reported. But the error -message still mentions DEFAULT_SEV_DEVICE ("/dev/sev") instead of -the custom path. - -Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0 -Signed-off-by: Michal Privoznik -Reviewed-by: Philippe Mathieu-Daudé -Link: https://lore.kernel.org/r/b4648905d399780063dc70851d3d6a3cd28719a5.1719218926.git.mprivozn@redhat.com -Signed-off-by: Paolo Bonzini -(cherry picked from commit e306ae87e0ef04bc7a5dec6db693f6ea09d64d45) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 37de80adc7..53b7f7315b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -595,7 +595,7 @@ static SevCapability *sev_get_capabilities(Error **errp) - fd = open(sev_device, O_RDWR); - if (fd < 0) { - error_setg_errno(errp, errno, "SEV: Failed to open %s", -- DEFAULT_SEV_DEVICE); -+ sev_device); - g_free(sev_device); - return NULL; - } --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Introduce-sev-common-type-to-encapsulate-co.patch b/SOURCES/kvm-i386-sev-Introduce-sev-common-type-to-encapsulate-co.patch deleted file mode 100644 index 2d167af..0000000 --- a/SOURCES/kvm-i386-sev-Introduce-sev-common-type-to-encapsulate-co.patch +++ /dev/null @@ -1,1118 +0,0 @@ -From e6cf2115eb9db545821180b8a978cdccc6a2c2db Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:16 -0500 -Subject: [PATCH 056/100] i386/sev: Introduce "sev-common" type to encapsulate - common SEV state - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [56/91] b52d5c9c5e4997d2fd791fa36dd5d4c836dfc32f (bonzini/rhel-qemu-kvm) - -Currently all SEV/SEV-ES functionality is managed through a single -'sev-guest' QOM type. With upcoming support for SEV-SNP, taking this -same approach won't work well since some of the properties/state -managed by 'sev-guest' is not applicable to SEV-SNP, which will instead -rely on a new QOM type with its own set of properties/state. - -To prepare for this, this patch moves common state into an abstract -'sev-common' parent type to encapsulate properties/state that are -common to both SEV/SEV-ES and SEV-SNP, leaving only SEV/SEV-ES-specific -properties/state in the current 'sev-guest' type. This should not -affect current behavior or command-line options. - -As part of this patch, some related changes are also made: - - - a static 'sev_guest' variable is currently used to keep track of - the 'sev-guest' instance. SEV-SNP would similarly introduce an - 'sev_snp_guest' static variable. But these instances are now - available via qdev_get_machine()->cgs, so switch to using that - instead and drop the static variable. - - - 'sev_guest' is currently used as the name for the static variable - holding a pointer to the 'sev-guest' instance. Re-purpose the name - as a local variable referring the 'sev-guest' instance, and use - that consistently throughout the code so it can be easily - distinguished from sev-common/sev-snp-guest instances. - - - 'sev' is generally used as the name for local variables holding a - pointer to the 'sev-guest' instance. In cases where that now points - to common state, use the name 'sev_common'; in cases where that now - points to state specific to 'sev-guest' instance, use the name - 'sev_guest' - -In order to enable kernel-hashes for SNP, pull it from -SevGuestProperties to its parent SevCommonProperties so -it will be available for both SEV and SNP. - -Signed-off-by: Michael Roth -Co-developed-by: Dov Murik -Signed-off-by: Dov Murik -Acked-by: Markus Armbruster (QAPI schema) -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 16dcf200dc951c1cde3e5b442457db5f690b8cf0) -Signed-off-by: Paolo Bonzini ---- - qapi/qom.json | 40 ++-- - target/i386/sev.c | 489 ++++++++++++++++++++++++++-------------------- - target/i386/sev.h | 3 + - 3 files changed, 301 insertions(+), 231 deletions(-) - -diff --git a/qapi/qom.json b/qapi/qom.json -index 38dde6d785..056b38f491 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -875,20 +875,12 @@ - 'data': { '*filename': 'str' } } - - ## --# @SevGuestProperties: -+# @SevCommonProperties: - # --# Properties for sev-guest objects. -+# Properties common to objects that are derivatives of sev-common. - # - # @sev-device: SEV device to use (default: "/dev/sev") - # --# @dh-cert-file: guest owners DH certificate (encoded with base64) --# --# @session-file: guest owners session parameters (encoded with base64) --# --# @policy: SEV policy value (default: 0x1) --# --# @handle: SEV firmware handle (default: 0) --# - # @cbitpos: C-bit location in page table entry (default: 0) - # - # @reduced-phys-bits: number of bits in physical addresses that become -@@ -898,6 +890,27 @@ - # designated guest firmware page for measured boot with -kernel - # (default: false) (since 6.2) - # -+# Since: 9.1 -+## -+{ 'struct': 'SevCommonProperties', -+ 'data': { '*sev-device': 'str', -+ '*cbitpos': 'uint32', -+ 'reduced-phys-bits': 'uint32', -+ '*kernel-hashes': 'bool' } } -+ -+## -+# @SevGuestProperties: -+# -+# Properties for sev-guest objects. -+# -+# @dh-cert-file: guest owners DH certificate (encoded with base64) -+# -+# @session-file: guest owners session parameters (encoded with base64) -+# -+# @policy: SEV policy value (default: 0x1) -+# -+# @handle: SEV firmware handle (default: 0) -+# - # @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM. - # The newer KVM_SEV_INIT2 interface syncs additional vCPU - # state when initializing the VMSA structures, which will -@@ -909,14 +922,11 @@ - # Since: 2.12 - ## - { 'struct': 'SevGuestProperties', -- 'data': { '*sev-device': 'str', -- '*dh-cert-file': 'str', -+ 'base': 'SevCommonProperties', -+ 'data': { '*dh-cert-file': 'str', - '*session-file': 'str', - '*policy': 'uint32', - '*handle': 'uint32', -- '*cbitpos': 'uint32', -- 'reduced-phys-bits': 'uint32', -- '*kernel-hashes': 'bool', - '*legacy-vm-type': 'bool' } } - - ## -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 67ed32e5ea..33e606eea0 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -40,49 +40,59 @@ - #include "hw/i386/pc.h" - #include "exec/address-spaces.h" - --#define TYPE_SEV_GUEST "sev-guest" --OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) -+OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON) -+OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST) - -- --/** -- * SevGuestState: -- * -- * The SevGuestState object is used for creating and managing a SEV -- * guest. -- * -- * # $QEMU \ -- * -object sev-guest,id=sev0 \ -- * -machine ...,memory-encryption=sev0 -- */ --struct SevGuestState { -+struct SevCommonState { - X86ConfidentialGuest parent_obj; - - int kvm_type; - - /* configuration parameters */ - char *sev_device; -- uint32_t policy; -- char *dh_cert_file; -- char *session_file; - uint32_t cbitpos; - uint32_t reduced_phys_bits; - bool kernel_hashes; -- bool legacy_vm_type; - - /* runtime state */ -- uint32_t handle; - uint8_t api_major; - uint8_t api_minor; - uint8_t build_id; - int sev_fd; - SevState state; -- gchar *measurement; - - uint32_t reset_cs; - uint32_t reset_ip; - bool reset_data_valid; - }; - -+struct SevCommonStateClass { -+ X86ConfidentialGuestClass parent_class; -+ -+}; -+ -+/** -+ * SevGuestState: -+ * -+ * The SevGuestState object is used for creating and managing a SEV -+ * guest. -+ * -+ * # $QEMU \ -+ * -object sev-guest,id=sev0 \ -+ * -machine ...,memory-encryption=sev0 -+ */ -+struct SevGuestState { -+ SevCommonState parent_obj; -+ gchar *measurement; -+ -+ /* configuration parameters */ -+ uint32_t handle; -+ uint32_t policy; -+ char *dh_cert_file; -+ char *session_file; -+ bool legacy_vm_type; -+}; -+ - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ - #define DEFAULT_SEV_DEVICE "/dev/sev" - -@@ -128,7 +138,6 @@ typedef struct QEMU_PACKED PaddedSevHashTable { - - QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0); - --static SevGuestState *sev_guest; - static Error *sev_mig_blocker; - - static const char *const sev_fw_errlist[] = { -@@ -209,21 +218,21 @@ fw_error_to_str(int code) - } - - static bool --sev_check_state(const SevGuestState *sev, SevState state) -+sev_check_state(const SevCommonState *sev_common, SevState state) - { -- assert(sev); -- return sev->state == state ? true : false; -+ assert(sev_common); -+ return sev_common->state == state ? true : false; - } - - static void --sev_set_guest_state(SevGuestState *sev, SevState new_state) -+sev_set_guest_state(SevCommonState *sev_common, SevState new_state) - { - assert(new_state < SEV_STATE__MAX); -- assert(sev); -+ assert(sev_common); - -- trace_kvm_sev_change_state(SevState_str(sev->state), -+ trace_kvm_sev_change_state(SevState_str(sev_common->state), - SevState_str(new_state)); -- sev->state = new_state; -+ sev_common->state = new_state; - } - - static void -@@ -290,121 +299,61 @@ static struct RAMBlockNotifier sev_ram_notifier = { - .ram_block_removed = sev_ram_block_removed, - }; - --static void --sev_guest_finalize(Object *obj) --{ --} -- --static char * --sev_guest_get_session_file(Object *obj, Error **errp) --{ -- SevGuestState *s = SEV_GUEST(obj); -- -- return s->session_file ? g_strdup(s->session_file) : NULL; --} -- --static void --sev_guest_set_session_file(Object *obj, const char *value, Error **errp) --{ -- SevGuestState *s = SEV_GUEST(obj); -- -- s->session_file = g_strdup(value); --} -- --static char * --sev_guest_get_dh_cert_file(Object *obj, Error **errp) --{ -- SevGuestState *s = SEV_GUEST(obj); -- -- return g_strdup(s->dh_cert_file); --} -- --static void --sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp) --{ -- SevGuestState *s = SEV_GUEST(obj); -- -- s->dh_cert_file = g_strdup(value); --} -- --static char * --sev_guest_get_sev_device(Object *obj, Error **errp) --{ -- SevGuestState *sev = SEV_GUEST(obj); -- -- return g_strdup(sev->sev_device); --} -- --static void --sev_guest_set_sev_device(Object *obj, const char *value, Error **errp) --{ -- SevGuestState *sev = SEV_GUEST(obj); -- -- sev->sev_device = g_strdup(value); --} -- --static bool sev_guest_get_kernel_hashes(Object *obj, Error **errp) --{ -- SevGuestState *sev = SEV_GUEST(obj); -- -- return sev->kernel_hashes; --} -- --static void sev_guest_set_kernel_hashes(Object *obj, bool value, Error **errp) --{ -- SevGuestState *sev = SEV_GUEST(obj); -- -- sev->kernel_hashes = value; --} -- --static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp) --{ -- return SEV_GUEST(obj)->legacy_vm_type; --} -- --static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp) --{ -- SEV_GUEST(obj)->legacy_vm_type = value; --} -- - bool - sev_enabled(void) - { -- return !!sev_guest; -+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs; -+ -+ return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON); - } - - bool - sev_es_enabled(void) - { -- return sev_enabled() && (sev_guest->policy & SEV_POLICY_ES); -+ ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs; -+ -+ return sev_enabled() && (SEV_GUEST(cgs)->policy & SEV_POLICY_ES); - } - - uint32_t - sev_get_cbit_position(void) - { -- return sev_guest ? sev_guest->cbitpos : 0; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ -+ return sev_common ? sev_common->cbitpos : 0; - } - - uint32_t - sev_get_reduced_phys_bits(void) - { -- return sev_guest ? sev_guest->reduced_phys_bits : 0; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ -+ return sev_common ? sev_common->reduced_phys_bits : 0; - } - - static SevInfo *sev_get_info(void) - { - SevInfo *info; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ SevGuestState *sev_guest = -+ (SevGuestState *)object_dynamic_cast(OBJECT(sev_common), -+ TYPE_SEV_GUEST); - - info = g_new0(SevInfo, 1); - info->enabled = sev_enabled(); - - if (info->enabled) { -- info->api_major = sev_guest->api_major; -- info->api_minor = sev_guest->api_minor; -- info->build_id = sev_guest->build_id; -- info->policy = sev_guest->policy; -- info->state = sev_guest->state; -- info->handle = sev_guest->handle; -+ if (sev_guest) { -+ info->handle = sev_guest->handle; -+ } -+ info->api_major = sev_common->api_major; -+ info->api_minor = sev_common->api_minor; -+ info->build_id = sev_common->build_id; -+ info->state = sev_common->state; -+ /* we only report the lower 32-bits of policy for SNP, ok for now... */ -+ info->policy = -+ (uint32_t)object_property_get_uint(OBJECT(sev_common), -+ "policy", NULL); - } - - return info; -@@ -530,6 +479,8 @@ static SevCapability *sev_get_capabilities(Error **errp) - size_t pdh_len = 0, cert_chain_len = 0, cpu0_id_len = 0; - uint32_t ebx; - int fd; -+ SevCommonState *sev_common; -+ char *sev_device; - - if (!kvm_enabled()) { - error_setg(errp, "KVM not enabled"); -@@ -540,12 +491,21 @@ static SevCapability *sev_get_capabilities(Error **errp) - return NULL; - } - -- fd = open(DEFAULT_SEV_DEVICE, O_RDWR); -+ sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ if (!sev_common) { -+ error_setg(errp, "SEV is not configured"); -+ } -+ -+ sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", -+ &error_abort); -+ fd = open(sev_device, O_RDWR); - if (fd < 0) { - error_setg_errno(errp, errno, "SEV: Failed to open %s", - DEFAULT_SEV_DEVICE); -+ g_free(sev_device); - return NULL; - } -+ g_free(sev_device); - - if (sev_get_pdh_info(fd, &pdh_data, &pdh_len, - &cert_chain_data, &cert_chain_len, errp)) { -@@ -588,7 +548,7 @@ static SevAttestationReport *sev_get_attestation_report(const char *mnonce, - { - struct kvm_sev_attestation_report input = {}; - SevAttestationReport *report = NULL; -- SevGuestState *sev = sev_guest; -+ SevCommonState *sev_common; - g_autofree guchar *data = NULL; - g_autofree guchar *buf = NULL; - gsize len; -@@ -613,8 +573,10 @@ static SevAttestationReport *sev_get_attestation_report(const char *mnonce, - return NULL; - } - -+ sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ - /* Query the report length */ -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, - &input, &err); - if (ret < 0) { - if (err != SEV_RET_INVALID_LEN) { -@@ -630,7 +592,7 @@ static SevAttestationReport *sev_get_attestation_report(const char *mnonce, - memcpy(input.mnonce, buf, sizeof(input.mnonce)); - - /* Query the report */ -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT, - &input, &err); - if (ret) { - error_setg_errno(errp, errno, "SEV: Failed to get attestation report" -@@ -670,26 +632,27 @@ sev_read_file_base64(const char *filename, guchar **data, gsize *len) - } - - static int --sev_launch_start(SevGuestState *sev) -+sev_launch_start(SevGuestState *sev_guest) - { - gsize sz; - int ret = 1; - int fw_error, rc; - struct kvm_sev_launch_start start = { -- .handle = sev->handle, .policy = sev->policy -+ .handle = sev_guest->handle, .policy = sev_guest->policy - }; - guchar *session = NULL, *dh_cert = NULL; -+ SevCommonState *sev_common = SEV_COMMON(sev_guest); - -- if (sev->session_file) { -- if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { -+ if (sev_guest->session_file) { -+ if (sev_read_file_base64(sev_guest->session_file, &session, &sz) < 0) { - goto out; - } - start.session_uaddr = (unsigned long)session; - start.session_len = sz; - } - -- if (sev->dh_cert_file) { -- if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { -+ if (sev_guest->dh_cert_file) { -+ if (sev_read_file_base64(sev_guest->dh_cert_file, &dh_cert, &sz) < 0) { - goto out; - } - start.dh_uaddr = (unsigned long)dh_cert; -@@ -697,15 +660,15 @@ sev_launch_start(SevGuestState *sev) - } - - trace_kvm_sev_launch_start(start.policy, session, dh_cert); -- rc = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_START, &start, &fw_error); -+ rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_START, &start, &fw_error); - if (rc < 0) { - error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); - goto out; - } - -- sev_set_guest_state(sev, SEV_STATE_LAUNCH_UPDATE); -- sev->handle = start.handle; -+ sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE); -+ sev_guest->handle = start.handle; - ret = 0; - - out: -@@ -715,7 +678,7 @@ out: - } - - static int --sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len) -+sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len) - { - int ret, fw_error; - struct kvm_sev_launch_update_data update; -@@ -727,7 +690,7 @@ sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len) - update.uaddr = (uintptr_t)addr; - update.len = len; - trace_kvm_sev_launch_update_data(addr, len); -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, -+ ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, - &update, &fw_error); - if (ret) { - error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'", -@@ -738,11 +701,12 @@ sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len) - } - - static int --sev_launch_update_vmsa(SevGuestState *sev) -+sev_launch_update_vmsa(SevGuestState *sev_guest) - { - int ret, fw_error; - -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL, &fw_error); -+ ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA, -+ NULL, &fw_error); - if (ret) { - error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); -@@ -754,18 +718,19 @@ sev_launch_update_vmsa(SevGuestState *sev) - static void - sev_launch_get_measure(Notifier *notifier, void *unused) - { -- SevGuestState *sev = sev_guest; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ SevGuestState *sev_guest = SEV_GUEST(sev_common); - int ret, error; - g_autofree guchar *data = NULL; - struct kvm_sev_launch_measure measurement = {}; - -- if (!sev_check_state(sev, SEV_STATE_LAUNCH_UPDATE)) { -+ if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) { - return; - } - - if (sev_es_enabled()) { - /* measure all the VM save areas before getting launch_measure */ -- ret = sev_launch_update_vmsa(sev); -+ ret = sev_launch_update_vmsa(sev_guest); - if (ret) { - exit(1); - } -@@ -773,7 +738,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - } - - /* query the measurement blob length */ -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE, - &measurement, &error); - if (!measurement.len) { - error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", -@@ -785,7 +750,7 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - measurement.uaddr = (unsigned long)data; - - /* get the measurement blob */ -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE, - &measurement, &error); - if (ret) { - error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", -@@ -793,17 +758,19 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - return; - } - -- sev_set_guest_state(sev, SEV_STATE_LAUNCH_SECRET); -+ sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_SECRET); - - /* encode the measurement value and emit the event */ -- sev->measurement = g_base64_encode(data, measurement.len); -- trace_kvm_sev_launch_measurement(sev->measurement); -+ sev_guest->measurement = g_base64_encode(data, measurement.len); -+ trace_kvm_sev_launch_measurement(sev_guest->measurement); - } - - static char *sev_get_launch_measurement(void) - { -+ SevGuestState *sev_guest = SEV_GUEST(MACHINE(qdev_get_machine())->cgs); -+ - if (sev_guest && -- sev_guest->state >= SEV_STATE_LAUNCH_SECRET) { -+ SEV_COMMON(sev_guest)->state >= SEV_STATE_LAUNCH_SECRET) { - return g_strdup(sev_guest->measurement); - } - -@@ -832,19 +799,20 @@ static Notifier sev_machine_done_notify = { - }; - - static void --sev_launch_finish(SevGuestState *sev) -+sev_launch_finish(SevGuestState *sev_guest) - { - int ret, error; - - trace_kvm_sev_launch_finish(); -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error); -+ ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, -+ &error); - if (ret) { - error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'", - __func__, ret, error, fw_error_to_str(error)); - exit(1); - } - -- sev_set_guest_state(sev, SEV_STATE_RUNNING); -+ sev_set_guest_state(SEV_COMMON(sev_guest), SEV_STATE_RUNNING); - - /* add migration blocker */ - error_setg(&sev_mig_blocker, -@@ -855,38 +823,40 @@ sev_launch_finish(SevGuestState *sev) - static void - sev_vm_state_change(void *opaque, bool running, RunState state) - { -- SevGuestState *sev = opaque; -+ SevCommonState *sev_common = opaque; - - if (running) { -- if (!sev_check_state(sev, SEV_STATE_RUNNING)) { -- sev_launch_finish(sev); -+ if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) { -+ sev_launch_finish(SEV_GUEST(sev_common)); - } - } - } - - static int sev_kvm_type(X86ConfidentialGuest *cg) - { -- SevGuestState *sev = SEV_GUEST(cg); -+ SevCommonState *sev_common = SEV_COMMON(cg); -+ SevGuestState *sev_guest = SEV_GUEST(sev_common); - int kvm_type; - -- if (sev->kvm_type != -1) { -+ if (sev_common->kvm_type != -1) { - goto out; - } - -- kvm_type = (sev->policy & SEV_POLICY_ES) ? KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM; -- if (kvm_is_vm_type_supported(kvm_type) && !sev->legacy_vm_type) { -- sev->kvm_type = kvm_type; -+ kvm_type = (sev_guest->policy & SEV_POLICY_ES) ? -+ KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM; -+ if (kvm_is_vm_type_supported(kvm_type) && !sev_guest->legacy_vm_type) { -+ sev_common->kvm_type = kvm_type; - } else { -- sev->kvm_type = KVM_X86_DEFAULT_VM; -+ sev_common->kvm_type = KVM_X86_DEFAULT_VM; - } - - out: -- return sev->kvm_type; -+ return sev_common->kvm_type; - } - - static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { -- SevGuestState *sev = SEV_GUEST(cgs); -+ SevCommonState *sev_common = SEV_COMMON(cgs); - char *devname; - int ret, fw_error, cmd; - uint32_t ebx; -@@ -899,8 +869,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - return -1; - } - -- sev_guest = sev; -- sev->state = SEV_STATE_UNINIT; -+ sev_common->state = SEV_STATE_UNINIT; - - host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); - host_cbitpos = ebx & 0x3f; -@@ -910,9 +879,9 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - * register of CPUID 0x8000001F. No need to verify the range as the - * comparison against the host value accomplishes that. - */ -- if (host_cbitpos != sev->cbitpos) { -+ if (host_cbitpos != sev_common->cbitpos) { - error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'", -- __func__, host_cbitpos, sev->cbitpos); -+ __func__, host_cbitpos, sev_common->cbitpos); - goto err; - } - -@@ -921,16 +890,17 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - * the EBX register of CPUID 0x8000001F, so verify the supplied value - * is in the range of 1 to 63. - */ -- if (sev->reduced_phys_bits < 1 || sev->reduced_phys_bits > 63) { -+ if (sev_common->reduced_phys_bits < 1 || -+ sev_common->reduced_phys_bits > 63) { - error_setg(errp, "%s: reduced_phys_bits check failed," - " it should be in the range of 1 to 63, requested '%d'", -- __func__, sev->reduced_phys_bits); -+ __func__, sev_common->reduced_phys_bits); - goto err; - } - -- devname = object_property_get_str(OBJECT(sev), "sev-device", NULL); -- sev->sev_fd = open(devname, O_RDWR); -- if (sev->sev_fd < 0) { -+ devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL); -+ sev_common->sev_fd = open(devname, O_RDWR); -+ if (sev_common->sev_fd < 0) { - error_setg(errp, "%s: Failed to open %s '%s'", __func__, - devname, strerror(errno)); - g_free(devname); -@@ -938,7 +908,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - g_free(devname); - -- ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, &status, -+ ret = sev_platform_ioctl(sev_common->sev_fd, SEV_PLATFORM_STATUS, &status, - &fw_error); - if (ret) { - error_setg(errp, "%s: failed to get platform status ret=%d " -@@ -946,9 +916,9 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - fw_error_to_str(fw_error)); - goto err; - } -- sev->build_id = status.build; -- sev->api_major = status.api_major; -- sev->api_minor = status.api_minor; -+ sev_common->build_id = status.build; -+ sev_common->api_major = status.api_major; -+ sev_common->api_minor = status.api_minor; - - if (sev_es_enabled()) { - if (!kvm_kernel_irqchip_allowed()) { -@@ -966,14 +936,14 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - trace_kvm_sev_init(); -- if (sev_kvm_type(X86_CONFIDENTIAL_GUEST(sev)) == KVM_X86_DEFAULT_VM) { -+ if (sev_kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) { - cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT; - -- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error); - } else { - struct kvm_sev_init args = { 0 }; - -- ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT2, &args, &fw_error); -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_INIT2, &args, &fw_error); - } - - if (ret) { -@@ -982,7 +952,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -- ret = sev_launch_start(sev); -+ sev_launch_start(SEV_GUEST(sev_common)); - if (ret) { - error_setg(errp, "%s: failed to create encryption context", __func__); - goto err; -@@ -990,13 +960,12 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - - ram_block_notifier_add(&sev_ram_notifier); - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); -- qemu_add_vm_change_state_handler(sev_vm_state_change, sev); -+ qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common); - - cgs->ready = true; - - return 0; - err: -- sev_guest = NULL; - ram_block_discard_disable(false); - return -1; - } -@@ -1004,13 +973,15 @@ err: - int - sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) - { -- if (!sev_guest) { -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ -+ if (!sev_common) { - return 0; - } - - /* if SEV is in update state then encrypt the data else do nothing */ -- if (sev_check_state(sev_guest, SEV_STATE_LAUNCH_UPDATE)) { -- int ret = sev_launch_update_data(sev_guest, ptr, len); -+ if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) { -+ int ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len); - if (ret < 0) { - error_setg(errp, "SEV: Failed to encrypt pflash rom"); - return ret; -@@ -1030,16 +1001,17 @@ int sev_inject_launch_secret(const char *packet_hdr, const char *secret, - void *hva; - gsize hdr_sz = 0, data_sz = 0; - MemoryRegion *mr = NULL; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - -- if (!sev_guest) { -+ if (!sev_common) { - error_setg(errp, "SEV not enabled for guest"); - return 1; - } - - /* secret can be injected only in this state */ -- if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) { -+ if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_SECRET)) { - error_setg(errp, "SEV: Not in correct state. (LSECRET) %x", -- sev_guest->state); -+ sev_common->state); - return 1; - } - -@@ -1073,7 +1045,7 @@ int sev_inject_launch_secret(const char *packet_hdr, const char *secret, - trace_kvm_sev_launch_secret(gpa, input.guest_uaddr, - input.trans_uaddr, input.trans_len); - -- ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_LAUNCH_SECRET, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_SECRET, - &input, &error); - if (ret) { - error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'", -@@ -1180,9 +1152,10 @@ void sev_es_set_reset_vector(CPUState *cpu) - { - X86CPU *x86; - CPUX86State *env; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - - /* Only update if we have valid reset information */ -- if (!sev_guest || !sev_guest->reset_data_valid) { -+ if (!sev_common || !sev_common->reset_data_valid) { - return; - } - -@@ -1194,11 +1167,11 @@ void sev_es_set_reset_vector(CPUState *cpu) - x86 = X86_CPU(cpu); - env = &x86->env; - -- cpu_x86_load_seg_cache(env, R_CS, 0xf000, sev_guest->reset_cs, 0xffff, -+ cpu_x86_load_seg_cache(env, R_CS, 0xf000, sev_common->reset_cs, 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | - DESC_R_MASK | DESC_A_MASK); - -- env->eip = sev_guest->reset_ip; -+ env->eip = sev_common->reset_ip; - } - - int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) -@@ -1206,6 +1179,7 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) - CPUState *cpu; - uint32_t addr; - int ret; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - - if (!sev_es_enabled()) { - return 0; -@@ -1219,9 +1193,9 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) - } - - if (addr) { -- sev_guest->reset_cs = addr & 0xffff0000; -- sev_guest->reset_ip = addr & 0x0000ffff; -- sev_guest->reset_data_valid = true; -+ sev_common->reset_cs = addr & 0xffff0000; -+ sev_common->reset_ip = addr & 0x0000ffff; -+ sev_common->reset_data_valid = true; - - CPU_FOREACH(cpu) { - sev_es_set_reset_vector(cpu); -@@ -1267,12 +1241,13 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - hwaddr mapped_len = sizeof(*padded_ht); - MemTxAttrs attrs = { 0 }; - bool ret = true; -+ SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - - /* - * Only add the kernel hashes if the sev-guest configuration explicitly - * stated kernel-hashes=on. - */ -- if (!sev_guest->kernel_hashes) { -+ if (!sev_common->kernel_hashes) { - return false; - } - -@@ -1363,8 +1338,30 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+static char * -+sev_common_get_sev_device(Object *obj, Error **errp) -+{ -+ return g_strdup(SEV_COMMON(obj)->sev_device); -+} -+ - static void --sev_guest_class_init(ObjectClass *oc, void *data) -+sev_common_set_sev_device(Object *obj, const char *value, Error **errp) -+{ -+ SEV_COMMON(obj)->sev_device = g_strdup(value); -+} -+ -+static bool sev_common_get_kernel_hashes(Object *obj, Error **errp) -+{ -+ return SEV_COMMON(obj)->kernel_hashes; -+} -+ -+static void sev_common_set_kernel_hashes(Object *obj, bool value, Error **errp) -+{ -+ SEV_COMMON(obj)->kernel_hashes = value; -+} -+ -+static void -+sev_common_class_init(ObjectClass *oc, void *data) - { - ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); - X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); -@@ -1373,10 +1370,87 @@ sev_guest_class_init(ObjectClass *oc, void *data) - x86_klass->kvm_type = sev_kvm_type; - - object_class_property_add_str(oc, "sev-device", -- sev_guest_get_sev_device, -- sev_guest_set_sev_device); -+ sev_common_get_sev_device, -+ sev_common_set_sev_device); - object_class_property_set_description(oc, "sev-device", - "SEV device to use"); -+ object_class_property_add_bool(oc, "kernel-hashes", -+ sev_common_get_kernel_hashes, -+ sev_common_set_kernel_hashes); -+ object_class_property_set_description(oc, "kernel-hashes", -+ "add kernel hashes to guest firmware for measured Linux boot"); -+} -+ -+static void -+sev_common_instance_init(Object *obj) -+{ -+ SevCommonState *sev_common = SEV_COMMON(obj); -+ -+ sev_common->kvm_type = -1; -+ -+ sev_common->sev_device = g_strdup(DEFAULT_SEV_DEVICE); -+ -+ object_property_add_uint32_ptr(obj, "cbitpos", &sev_common->cbitpos, -+ OBJ_PROP_FLAG_READWRITE); -+ object_property_add_uint32_ptr(obj, "reduced-phys-bits", -+ &sev_common->reduced_phys_bits, -+ OBJ_PROP_FLAG_READWRITE); -+} -+ -+/* sev guest info common to sev/sev-es/sev-snp */ -+static const TypeInfo sev_common_info = { -+ .parent = TYPE_X86_CONFIDENTIAL_GUEST, -+ .name = TYPE_SEV_COMMON, -+ .instance_size = sizeof(SevCommonState), -+ .instance_init = sev_common_instance_init, -+ .class_size = sizeof(SevCommonStateClass), -+ .class_init = sev_common_class_init, -+ .abstract = true, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_USER_CREATABLE }, -+ { } -+ } -+}; -+ -+static char * -+sev_guest_get_dh_cert_file(Object *obj, Error **errp) -+{ -+ return g_strdup(SEV_GUEST(obj)->dh_cert_file); -+} -+ -+static void -+sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp) -+{ -+ SEV_GUEST(obj)->dh_cert_file = g_strdup(value); -+} -+ -+static char * -+sev_guest_get_session_file(Object *obj, Error **errp) -+{ -+ SevGuestState *sev_guest = SEV_GUEST(obj); -+ -+ return sev_guest->session_file ? g_strdup(sev_guest->session_file) : NULL; -+} -+ -+static void -+sev_guest_set_session_file(Object *obj, const char *value, Error **errp) -+{ -+ SEV_GUEST(obj)->session_file = g_strdup(value); -+} -+ -+static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp) -+{ -+ return SEV_GUEST(obj)->legacy_vm_type; -+} -+ -+static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp) -+{ -+ SEV_GUEST(obj)->legacy_vm_type = value; -+} -+ -+static void -+sev_guest_class_init(ObjectClass *oc, void *data) -+{ - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, - sev_guest_set_dh_cert_file); -@@ -1387,11 +1461,6 @@ sev_guest_class_init(ObjectClass *oc, void *data) - sev_guest_set_session_file); - object_class_property_set_description(oc, "session-file", - "guest owners session parameters (encoded with base64)"); -- object_class_property_add_bool(oc, "kernel-hashes", -- sev_guest_get_kernel_hashes, -- sev_guest_set_kernel_hashes); -- object_class_property_set_description(oc, "kernel-hashes", -- "add kernel hashes to guest firmware for measured Linux boot"); - object_class_property_add_bool(oc, "legacy-vm-type", - sev_guest_get_legacy_vm_type, - sev_guest_set_legacy_vm_type); -@@ -1402,41 +1471,29 @@ sev_guest_class_init(ObjectClass *oc, void *data) - static void - sev_guest_instance_init(Object *obj) - { -- SevGuestState *sev = SEV_GUEST(obj); -- -- sev->kvm_type = -1; -+ SevGuestState *sev_guest = SEV_GUEST(obj); - -- sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); -- sev->policy = DEFAULT_GUEST_POLICY; -- object_property_add_uint32_ptr(obj, "policy", &sev->policy, -- OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "handle", &sev->handle, -+ sev_guest->policy = DEFAULT_GUEST_POLICY; -+ object_property_add_uint32_ptr(obj, "handle", &sev_guest->handle, - OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos, -- OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "reduced-phys-bits", -- &sev->reduced_phys_bits, -+ object_property_add_uint32_ptr(obj, "policy", &sev_guest->policy, - OBJ_PROP_FLAG_READWRITE); - object_apply_compat_props(obj); - } - --/* sev guest info */ -+/* guest info specific sev/sev-es */ - static const TypeInfo sev_guest_info = { -- .parent = TYPE_X86_CONFIDENTIAL_GUEST, -+ .parent = TYPE_SEV_COMMON, - .name = TYPE_SEV_GUEST, - .instance_size = sizeof(SevGuestState), -- .instance_finalize = sev_guest_finalize, -- .class_init = sev_guest_class_init, - .instance_init = sev_guest_instance_init, -- .interfaces = (InterfaceInfo[]) { -- { TYPE_USER_CREATABLE }, -- { } -- } -+ .class_init = sev_guest_class_init, - }; - - static void - sev_register_types(void) - { -+ type_register_static(&sev_common_info); - type_register_static(&sev_guest_info); - } - -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 9e10d09539..668374eef3 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -20,6 +20,9 @@ - - #include "exec/confidential-guest-support.h" - -+#define TYPE_SEV_COMMON "sev-common" -+#define TYPE_SEV_GUEST "sev-guest" -+ - #define SEV_POLICY_NODBG 0x1 - #define SEV_POLICY_NOKS 0x2 - #define SEV_POLICY_ES 0x4 --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Introduce-sev-snp-guest-object.patch b/SOURCES/kvm-i386-sev-Introduce-sev-snp-guest-object.patch deleted file mode 100644 index b347bf6..0000000 --- a/SOURCES/kvm-i386-sev-Introduce-sev-snp-guest-object.patch +++ /dev/null @@ -1,530 +0,0 @@ -From 900859fd3445b9a71f1a9a8befda17f0c33f3923 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 30 May 2024 06:16:19 -0500 -Subject: [PATCH 059/100] i386/sev: Introduce 'sev-snp-guest' object - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [59/91] 3e585113d209176c2b97ad5e4fe943f19dfdcaeb (bonzini/rhel-qemu-kvm) - -SEV-SNP support relies on a different set of properties/state than the -existing 'sev-guest' object. This patch introduces the 'sev-snp-guest' -object, which can be used to configure an SEV-SNP guest. For example, -a default-configured SEV-SNP guest with no additional information -passed in for use with attestation: - - -object sev-snp-guest,id=sev0 - -or a fully-specified SEV-SNP guest where all spec-defined binary -blobs are passed in as base64-encoded strings: - - -object sev-snp-guest,id=sev0, \ - policy=0x30000, \ - init-flags=0, \ - id-block=YWFhYWFhYWFhYWFhYWFhCg==, \ - id-auth=CxHK/OKLkXGn/KpAC7Wl1FSiisWDbGTEKz..., \ - author-key-enabled=on, \ - host-data=LNkCWBRC5CcdGXirbNUV1OrsR28s..., \ - guest-visible-workarounds=AA==, \ - -See the QAPI schema updates included in this patch for more usage -details. - -In some cases these blobs may be up to 4096 characters, but this is -generally well below the default limit for linux hosts where -command-line sizes are defined by the sysconf-configurable ARG_MAX -value, which defaults to 2097152 characters for Ubuntu hosts, for -example. - -Signed-off-by: Brijesh Singh -Co-developed-by: Michael Roth -Acked-by: Markus Armbruster (for QAPI schema) -Signed-off-by: Michael Roth -Co-developed-by: Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 7b34df44260b391e33bc3acf1ced30019d9aadf1) -Signed-off-by: Paolo Bonzini ---- - docs/system/i386/amd-memory-encryption.rst | 70 +++++- - qapi/qom.json | 58 +++++ - target/i386/sev.c | 253 +++++++++++++++++++++ - target/i386/sev.h | 1 + - 4 files changed, 380 insertions(+), 2 deletions(-) - -diff --git a/docs/system/i386/amd-memory-encryption.rst b/docs/system/i386/amd-memory-encryption.rst -index e9bc142bc1..748f5094ba 100644 ---- a/docs/system/i386/amd-memory-encryption.rst -+++ b/docs/system/i386/amd-memory-encryption.rst -@@ -25,8 +25,8 @@ support for notifying a guest's operating system when certain types of VMEXITs - are about to occur. This allows the guest to selectively share information with - the hypervisor to satisfy the requested function. - --Launching ----------- -+Launching (SEV and SEV-ES) -+-------------------------- - - Boot images (such as bios) must be encrypted before a guest can be booted. The - ``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images: ``LAUNCH_START``, -@@ -161,6 +161,72 @@ The value of GCTX.LD is - If kernel hashes are not used, or SEV-ES is disabled, use empty blobs for - ``kernel_hashes_blob`` and ``vmsas_blob`` as needed. - -+Launching (SEV-SNP) -+------------------- -+Boot images (such as bios) must be encrypted before a guest can be booted. The -+``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images: -+``SNP_LAUNCH_START``, ``SNP_LAUNCH_UPDATE``, and ``SNP_LAUNCH_FINISH``. These -+three commands communicate with SEV-SNP firmware to generate a fresh memory -+encryption key for the VM, encrypt the boot images for a successful launch. For -+more details on the SEV-SNP firmware interfaces used by these commands please -+see the SEV-SNP Firmware ABI. -+ -+``SNP_LAUNCH_START`` is called first to create a cryptographic launch context -+within the firmware. To create this context, the guest owner must provide a -+guest policy and other parameters as described in the SEV-SNP firmware -+specification. The launch parameters should be specified as described in the -+QAPI schema for the sev-snp-guest object. -+ -+The ``SNP_LAUNCH_START`` uses the following parameters, which can be configured -+by the corresponding parameters documented in the QAPI schema for the -+'sev-snp-guest' object. -+ -++--------+-------+----------+-------------------------------------------------+ -+| key | type | default | meaning | -++---------------------------+-------------------------------------------------+ -+| policy | hex | 0x30000 | a 64-bit guest policy | -++---------------------------+-------------------------------------------------+ -+| guest-visible-workarounds | string| 0 | 16-byte base64 encoded string| -+| | | | for guest OS visible | -+| | | | workarounds. | -++---------------------------+-------------------------------------------------+ -+ -+``SNP_LAUNCH_UPDATE`` encrypts the memory region using the cryptographic context -+created via the ``SNP_LAUNCH_START`` command. If required, this command can be -+called multiple times to encrypt different memory regions. The command also -+calculates the measurement of the memory contents as it encrypts. -+ -+``SNP_LAUNCH_FINISH`` finalizes the guest launch flow. Optionally, while -+finalizing the launch the firmware can perform checks on the launch digest -+computing through the ``SNP_LAUNCH_UPDATE``. To perform the check the user must -+supply the id block, authentication blob and host data that should be included -+in the attestation report. See the SEV-SNP spec for further details. -+ -+The ``SNP_LAUNCH_FINISH`` uses the following parameters, which can be configured -+by the corresponding parameters documented in the QAPI schema for the -+'sev-snp-guest' object. -+ -++--------------------+-------+----------+-------------------------------------+ -+| key | type | default | meaning | -++--------------------+-------+----------+-------------------------------------+ -+| id-block | string| none | base64 encoded ID block | -++--------------------+-------+----------+-------------------------------------+ -+| id-auth | string| none | base64 encoded authentication | -+| | | | information | -++--------------------+-------+----------+-------------------------------------+ -+| author-key-enabled | bool | 0 | auth block contains author key | -++--------------------+-------+----------+-------------------------------------+ -+| host_data | string| none | host provided data | -++--------------------+-------+----------+-------------------------------------+ -+ -+To launch a SEV-SNP guest (additional parameters are documented in the QAPI -+schema for the 'sev-snp-guest' object):: -+ -+ # ${QEMU} \ -+ -machine ...,confidential-guest-support=sev0 \ -+ -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1 -+ -+ - Debugging - --------- - -diff --git a/qapi/qom.json b/qapi/qom.json -index 056b38f491..8bd299265e 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -929,6 +929,62 @@ - '*handle': 'uint32', - '*legacy-vm-type': 'bool' } } - -+## -+# @SevSnpGuestProperties: -+# -+# Properties for sev-snp-guest objects. Most of these are direct -+# arguments for the KVM_SNP_* interfaces documented in the Linux -+# kernel source under -+# Documentation/arch/x86/amd-memory-encryption.rst, which are in turn -+# closely coupled with the SNP_INIT/SNP_LAUNCH_* firmware commands -+# documented in the SEV-SNP Firmware ABI Specification (Rev 0.9). -+# -+# More usage information is also available in the QEMU source tree -+# under docs/amd-memory-encryption. -+# -+# @policy: the 'POLICY' parameter to the SNP_LAUNCH_START command, as -+# defined in the SEV-SNP firmware ABI (default: 0x30000) -+# -+# @guest-visible-workarounds: 16-byte, base64-encoded blob to report -+# hypervisor-defined workarounds, corresponding to the 'GOSVW' -+# parameter of the SNP_LAUNCH_START command defined in the SEV-SNP -+# firmware ABI (default: all-zero) -+# -+# @id-block: 96-byte, base64-encoded blob to provide the 'ID Block' -+# structure for the SNP_LAUNCH_FINISH command defined in the -+# SEV-SNP firmware ABI (default: all-zero) -+# -+# @id-auth: 4096-byte, base64-encoded blob to provide the 'ID -+# Authentication Information Structure' for the SNP_LAUNCH_FINISH -+# command defined in the SEV-SNP firmware ABI (default: all-zero) -+# -+# @author-key-enabled: true if 'id-auth' blob contains the 'AUTHOR_KEY' -+# field defined SEV-SNP firmware ABI (default: false) -+# -+# @host-data: 32-byte, base64-encoded, user-defined blob to provide to -+# the guest, as documented for the 'HOST_DATA' parameter of the -+# SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI (default: -+# all-zero) -+# -+# @vcek-disabled: Guests are by default allowed to choose between VLEK -+# (Versioned Loaded Endorsement Key) or VCEK (Versioned Chip -+# Endorsement Key) when requesting attestation reports from -+# firmware. Set this to true to disable the use of VCEK. -+# (default: false) (since: 9.1) -+# -+# Since: 9.1 -+## -+{ 'struct': 'SevSnpGuestProperties', -+ 'base': 'SevCommonProperties', -+ 'data': { -+ '*policy': 'uint64', -+ '*guest-visible-workarounds': 'str', -+ '*id-block': 'str', -+ '*id-auth': 'str', -+ '*author-key-enabled': 'bool', -+ '*host-data': 'str', -+ '*vcek-disabled': 'bool' } } -+ - ## - # @ThreadContextProperties: - # -@@ -1007,6 +1063,7 @@ - { 'name': 'secret_keyring', - 'if': 'CONFIG_SECRET_KEYRING' }, - 'sev-guest', -+ 'sev-snp-guest', - 'thread-context', - 's390-pv-guest', - 'throttle-group', -@@ -1077,6 +1134,7 @@ - 'secret_keyring': { 'type': 'SecretKeyringProperties', - 'if': 'CONFIG_SECRET_KEYRING' }, - 'sev-guest': 'SevGuestProperties', -+ 'sev-snp-guest': 'SevSnpGuestProperties', - 'thread-context': 'ThreadContextProperties', - 'throttle-group': 'ThrottleGroupProperties', - 'tls-creds-anon': 'TlsCredsAnonProperties', -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 28a018ed83..a81b3228d4 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -42,6 +42,7 @@ - - OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON) - OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST) -+OBJECT_DECLARE_TYPE(SevSnpGuestState, SevCommonStateClass, SEV_SNP_GUEST) - - struct SevCommonState { - X86ConfidentialGuest parent_obj; -@@ -96,8 +97,22 @@ struct SevGuestState { - bool legacy_vm_type; - }; - -+struct SevSnpGuestState { -+ SevCommonState parent_obj; -+ -+ /* configuration parameters */ -+ char *guest_visible_workarounds; -+ char *id_block; -+ char *id_auth; -+ char *host_data; -+ -+ struct kvm_sev_snp_launch_start kvm_start_conf; -+ struct kvm_sev_snp_launch_finish kvm_finish_conf; -+}; -+ - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ - #define DEFAULT_SEV_DEVICE "/dev/sev" -+#define DEFAULT_SEV_SNP_POLICY 0x30000 - - #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e" - typedef struct __attribute__((__packed__)) SevInfoBlock { -@@ -1500,11 +1515,249 @@ static const TypeInfo sev_guest_info = { - .class_init = sev_guest_class_init, - }; - -+static void -+sev_snp_guest_get_policy(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ visit_type_uint64(v, name, -+ (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy, -+ errp); -+} -+ -+static void -+sev_snp_guest_set_policy(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ visit_type_uint64(v, name, -+ (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy, -+ errp); -+} -+ -+static char * -+sev_snp_guest_get_guest_visible_workarounds(Object *obj, Error **errp) -+{ -+ return g_strdup(SEV_SNP_GUEST(obj)->guest_visible_workarounds); -+} -+ -+static void -+sev_snp_guest_set_guest_visible_workarounds(Object *obj, const char *value, -+ Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf; -+ g_autofree guchar *blob; -+ gsize len; -+ -+ g_free(sev_snp_guest->guest_visible_workarounds); -+ -+ /* store the base64 str so we don't need to re-encode in getter */ -+ sev_snp_guest->guest_visible_workarounds = g_strdup(value); -+ -+ blob = qbase64_decode(sev_snp_guest->guest_visible_workarounds, -+ -1, &len, errp); -+ if (!blob) { -+ return; -+ } -+ -+ if (len != sizeof(start->gosvw)) { -+ error_setg(errp, "parameter length of %lu exceeds max of %lu", -+ len, sizeof(start->gosvw)); -+ return; -+ } -+ -+ memcpy(start->gosvw, blob, len); -+} -+ -+static char * -+sev_snp_guest_get_id_block(Object *obj, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ return g_strdup(sev_snp_guest->id_block); -+} -+ -+static void -+sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf; -+ gsize len; -+ -+ g_free(sev_snp_guest->id_block); -+ g_free((guchar *)finish->id_block_uaddr); -+ -+ /* store the base64 str so we don't need to re-encode in getter */ -+ sev_snp_guest->id_block = g_strdup(value); -+ -+ finish->id_block_uaddr = -+ (uint64_t)qbase64_decode(sev_snp_guest->id_block, -1, &len, errp); -+ -+ if (!finish->id_block_uaddr) { -+ return; -+ } -+ -+ if (len != KVM_SEV_SNP_ID_BLOCK_SIZE) { -+ error_setg(errp, "parameter length of %lu not equal to %u", -+ len, KVM_SEV_SNP_ID_BLOCK_SIZE); -+ return; -+ } -+ -+ finish->id_block_en = (len) ? 1 : 0; -+} -+ -+static char * -+sev_snp_guest_get_id_auth(Object *obj, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ return g_strdup(sev_snp_guest->id_auth); -+} -+ -+static void -+sev_snp_guest_set_id_auth(Object *obj, const char *value, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf; -+ gsize len; -+ -+ g_free(sev_snp_guest->id_auth); -+ g_free((guchar *)finish->id_auth_uaddr); -+ -+ /* store the base64 str so we don't need to re-encode in getter */ -+ sev_snp_guest->id_auth = g_strdup(value); -+ -+ finish->id_auth_uaddr = -+ (uint64_t)qbase64_decode(sev_snp_guest->id_auth, -1, &len, errp); -+ -+ if (!finish->id_auth_uaddr) { -+ return; -+ } -+ -+ if (len > KVM_SEV_SNP_ID_AUTH_SIZE) { -+ error_setg(errp, "parameter length:ID_AUTH %lu exceeds max of %u", -+ len, KVM_SEV_SNP_ID_AUTH_SIZE); -+ return; -+ } -+} -+ -+static bool -+sev_snp_guest_get_author_key_enabled(Object *obj, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ return !!sev_snp_guest->kvm_finish_conf.auth_key_en; -+} -+ -+static void -+sev_snp_guest_set_author_key_enabled(Object *obj, bool value, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ sev_snp_guest->kvm_finish_conf.auth_key_en = value; -+} -+ -+static bool -+sev_snp_guest_get_vcek_disabled(Object *obj, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ return !!sev_snp_guest->kvm_finish_conf.vcek_disabled; -+} -+ -+static void -+sev_snp_guest_set_vcek_disabled(Object *obj, bool value, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ sev_snp_guest->kvm_finish_conf.vcek_disabled = value; -+} -+ -+static char * -+sev_snp_guest_get_host_data(Object *obj, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ return g_strdup(sev_snp_guest->host_data); -+} -+ -+static void -+sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf; -+ g_autofree guchar *blob; -+ gsize len; -+ -+ g_free(sev_snp_guest->host_data); -+ -+ /* store the base64 str so we don't need to re-encode in getter */ -+ sev_snp_guest->host_data = g_strdup(value); -+ -+ blob = qbase64_decode(sev_snp_guest->host_data, -1, &len, errp); -+ -+ if (!blob) { -+ return; -+ } -+ -+ if (len != sizeof(finish->host_data)) { -+ error_setg(errp, "parameter length of %lu not equal to %lu", -+ len, sizeof(finish->host_data)); -+ return; -+ } -+ -+ memcpy(finish->host_data, blob, len); -+} -+ -+static void -+sev_snp_guest_class_init(ObjectClass *oc, void *data) -+{ -+ object_class_property_add(oc, "policy", "uint64", -+ sev_snp_guest_get_policy, -+ sev_snp_guest_set_policy, NULL, NULL); -+ object_class_property_add_str(oc, "guest-visible-workarounds", -+ sev_snp_guest_get_guest_visible_workarounds, -+ sev_snp_guest_set_guest_visible_workarounds); -+ object_class_property_add_str(oc, "id-block", -+ sev_snp_guest_get_id_block, -+ sev_snp_guest_set_id_block); -+ object_class_property_add_str(oc, "id-auth", -+ sev_snp_guest_get_id_auth, -+ sev_snp_guest_set_id_auth); -+ object_class_property_add_bool(oc, "author-key-enabled", -+ sev_snp_guest_get_author_key_enabled, -+ sev_snp_guest_set_author_key_enabled); -+ object_class_property_add_bool(oc, "vcek-required", -+ sev_snp_guest_get_vcek_disabled, -+ sev_snp_guest_set_vcek_disabled); -+ object_class_property_add_str(oc, "host-data", -+ sev_snp_guest_get_host_data, -+ sev_snp_guest_set_host_data); -+} -+ -+static void -+sev_snp_guest_instance_init(Object *obj) -+{ -+ SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj); -+ -+ /* default init/start/finish params for kvm */ -+ sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY; -+} -+ -+/* guest info specific to sev-snp */ -+static const TypeInfo sev_snp_guest_info = { -+ .parent = TYPE_SEV_COMMON, -+ .name = TYPE_SEV_SNP_GUEST, -+ .instance_size = sizeof(SevSnpGuestState), -+ .class_init = sev_snp_guest_class_init, -+ .instance_init = sev_snp_guest_instance_init, -+}; -+ - static void - sev_register_types(void) - { - type_register_static(&sev_common_info); - type_register_static(&sev_guest_info); -+ type_register_static(&sev_snp_guest_info); - } - - type_init(sev_register_types); -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 668374eef3..bedc667eeb 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -22,6 +22,7 @@ - - #define TYPE_SEV_COMMON "sev-common" - #define TYPE_SEV_GUEST "sev-guest" -+#define TYPE_SEV_SNP_GUEST "sev-snp-guest" - - #define SEV_POLICY_NODBG 0x1 - #define SEV_POLICY_NOKS 0x2 --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SEV-class.patch b/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SEV-class.patch deleted file mode 100644 index 265da66..0000000 --- a/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SEV-class.patch +++ /dev/null @@ -1,85 +0,0 @@ -From be37914ae54c8aebc218cf41b37bc0ea1563daae Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 31 May 2024 12:51:44 +0200 -Subject: [PATCH 074/100] i386/sev: Invoke launch_updata_data() for SEV class - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [74/91] f1b588a9ffecd6944a78186d88a6be3849698710 (bonzini/rhel-qemu-kvm) - -Add launch_update_data() in SevCommonStateClass and -invoke as sev_launch_update_data() for SEV object. - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-26-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 9861405a8f845133b7984322c2df0c43a45553c3) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 7b5c4b4874..8834cf9441 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -74,6 +74,7 @@ struct SevCommonStateClass { - /* public */ - int (*launch_start)(SevCommonState *sev_common); - void (*launch_finish)(SevCommonState *sev_common); -+ int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len); - int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp); - }; - -@@ -929,7 +930,7 @@ out: - } - - static int --sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len) -+sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, uint8_t *addr, uint64_t len) - { - int ret, fw_error; - struct kvm_sev_launch_update_data update; -@@ -941,7 +942,7 @@ sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len) - update.uaddr = (uintptr_t)addr; - update.len = len; - trace_kvm_sev_launch_update_data(addr, len); -- ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, - &update, &fw_error); - if (ret) { - error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'", -@@ -1487,6 +1488,7 @@ int - sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common); - - if (!sev_common) { - return 0; -@@ -1494,7 +1496,9 @@ sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp) - - /* if SEV is in update state then encrypt the data else do nothing */ - if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) { -- int ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len); -+ int ret; -+ -+ ret = klass->launch_update_data(sev_common, gpa, ptr, len); - if (ret < 0) { - error_setg(errp, "SEV: Failed to encrypt pflash rom"); - return ret; -@@ -1968,6 +1972,7 @@ sev_guest_class_init(ObjectClass *oc, void *data) - - klass->launch_start = sev_launch_start; - klass->launch_finish = sev_launch_finish; -+ klass->launch_update_data = sev_launch_update_data; - klass->kvm_init = sev_kvm_init; - x86_klass->kvm_type = sev_kvm_type; - --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SNP-class.patch b/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SNP-class.patch deleted file mode 100644 index f28004d..0000000 --- a/SOURCES/kvm-i386-sev-Invoke-launch_updata_data-for-SNP-class.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 32899eb4fa5143b795b107de4857adce2cf1d434 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:38 -0500 -Subject: [PATCH 075/100] i386/sev: Invoke launch_updata_data() for SNP class - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [75/91] 3520af5847f8dddb6d7fe7ad5feb308230f387b9 (bonzini/rhel-qemu-kvm) - -Invoke as sev_snp_launch_update_data() for SNP object. - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-27-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 0765d136eba400ad1cb7cae18438bb10eace64dc) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 8834cf9441..eaf5fc6c6b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1091,6 +1091,15 @@ snp_launch_update_data(uint64_t gpa, void *hva, - return 0; - } - -+static int -+sev_snp_launch_update_data(SevCommonState *sev_common, hwaddr gpa, -+ uint8_t *ptr, uint64_t len) -+{ -+ int ret = snp_launch_update_data(gpa, ptr, len, -+ KVM_SEV_SNP_PAGE_TYPE_NORMAL); -+ return ret; -+} -+ - static int - sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info, - const KvmCpuidInfo *kvm_cpuid_info) -@@ -2216,6 +2225,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - - klass->launch_start = sev_snp_launch_start; - klass->launch_finish = sev_snp_launch_finish; -+ klass->launch_update_data = sev_snp_launch_update_data; - klass->kvm_init = sev_snp_kvm_init; - x86_klass->kvm_type = sev_snp_kvm_type; - --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Move-SEV_COMMON-null-check-before-dereferen.patch b/SOURCES/kvm-i386-sev-Move-SEV_COMMON-null-check-before-dereferen.patch deleted file mode 100644 index e38615b..0000000 --- a/SOURCES/kvm-i386-sev-Move-SEV_COMMON-null-check-before-dereferen.patch +++ /dev/null @@ -1,47 +0,0 @@ -From fa6076291eb45255bc2fe523399d7d0647fc5570 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Fri, 7 Jun 2024 13:36:10 -0500 -Subject: [PATCH 085/100] i386/sev: Move SEV_COMMON null check before - dereferencing - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [85/91] e8d2bfd077766a5e7777b9337d0e77146f883224 (bonzini/rhel-qemu-kvm) - -Fixes Coverity CID 1546886. - -Fixes: 9861405a8f ("i386/sev: Invoke launch_updata_data() for SEV class") -Signed-off-by: Pankaj Gupta -Message-ID: <20240607183611.1111100-3-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 48779faef3c8e2fe70bd8285bffa731bd76dc844) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 7c9df621de..f18432f58e 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1529,11 +1529,12 @@ int - sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -- SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common); -+ SevCommonStateClass *klass; - - if (!sev_common) { - return 0; - } -+ klass = SEV_COMMON_GET_CLASS(sev_common); - - /* if SEV is in update state then encrypt the data else do nothing */ - if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) { --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Move-sev_launch_finish-to-separate-class-me.patch b/SOURCES/kvm-i386-sev-Move-sev_launch_finish-to-separate-class-me.patch deleted file mode 100644 index 250a723..0000000 --- a/SOURCES/kvm-i386-sev-Move-sev_launch_finish-to-separate-class-me.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 4d96ca893126d4c17c9fe03c76973b1d4a414f21 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:18 -0500 -Subject: [PATCH 058/100] i386/sev: Move sev_launch_finish to separate class - method - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [58/91] 7865710d320a6df7038ef7016d350aa9cdcea326 (bonzini/rhel-qemu-kvm) - -When sev-snp-guest objects are introduced there will be a number of -differences in how the launch finish is handled compared to the existing -sev-guest object. Move sev_launch_finish() to a class method to make it -easier to implement SNP-specific launch update functionality later. - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-7-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit bce615a14aec07cab0488e5a242f6a91e641efcb) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b2aa0d6f99..28a018ed83 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -71,6 +71,7 @@ struct SevCommonStateClass { - - /* public */ - int (*launch_start)(SevCommonState *sev_common); -+ void (*launch_finish)(SevCommonState *sev_common); - }; - - /** -@@ -801,12 +802,12 @@ static Notifier sev_machine_done_notify = { - }; - - static void --sev_launch_finish(SevGuestState *sev_guest) -+sev_launch_finish(SevCommonState *sev_common) - { - int ret, error; - - trace_kvm_sev_launch_finish(); -- ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, -+ ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, - &error); - if (ret) { - error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'", -@@ -814,7 +815,7 @@ sev_launch_finish(SevGuestState *sev_guest) - exit(1); - } - -- sev_set_guest_state(SEV_COMMON(sev_guest), SEV_STATE_RUNNING); -+ sev_set_guest_state(sev_common, SEV_STATE_RUNNING); - - /* add migration blocker */ - error_setg(&sev_mig_blocker, -@@ -826,10 +827,11 @@ static void - sev_vm_state_change(void *opaque, bool running, RunState state) - { - SevCommonState *sev_common = opaque; -+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(opaque); - - if (running) { - if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) { -- sev_launch_finish(SEV_GUEST(sev_common)); -+ klass->launch_finish(sev_common); - } - } - } -@@ -1457,6 +1459,7 @@ sev_guest_class_init(ObjectClass *oc, void *data) - SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); - - klass->launch_start = sev_launch_start; -+ klass->launch_finish = sev_launch_finish; - - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Move-sev_launch_update-to-separate-class-me.patch b/SOURCES/kvm-i386-sev-Move-sev_launch_update-to-separate-class-me.patch deleted file mode 100644 index 12824ec..0000000 --- a/SOURCES/kvm-i386-sev-Move-sev_launch_update-to-separate-class-me.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a170ba2c7dbf2775eb9047779d3643a2a81bb372 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:17 -0500 -Subject: [PATCH 057/100] i386/sev: Move sev_launch_update to separate class - method - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [57/91] 4f31e7afaec6f2c2a7c06cda4d7d27d4037e53e0 (bonzini/rhel-qemu-kvm) - -When sev-snp-guest objects are introduced there will be a number of -differences in how the launch data is handled compared to the existing -sev-guest object. Move sev_launch_start() to a class method to make it -easier to implement SNP-specific launch update functionality later. - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-6-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 6600f1ac0c81cbe67faf048ea07f78542dea925f) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 33e606eea0..b2aa0d6f99 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -69,6 +69,8 @@ struct SevCommonState { - struct SevCommonStateClass { - X86ConfidentialGuestClass parent_class; - -+ /* public */ -+ int (*launch_start)(SevCommonState *sev_common); - }; - - /** -@@ -632,16 +634,16 @@ sev_read_file_base64(const char *filename, guchar **data, gsize *len) - } - - static int --sev_launch_start(SevGuestState *sev_guest) -+sev_launch_start(SevCommonState *sev_common) - { - gsize sz; - int ret = 1; - int fw_error, rc; -+ SevGuestState *sev_guest = SEV_GUEST(sev_common); - struct kvm_sev_launch_start start = { - .handle = sev_guest->handle, .policy = sev_guest->policy - }; - guchar *session = NULL, *dh_cert = NULL; -- SevCommonState *sev_common = SEV_COMMON(sev_guest); - - if (sev_guest->session_file) { - if (sev_read_file_base64(sev_guest->session_file, &session, &sz) < 0) { -@@ -862,6 +864,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - uint32_t ebx; - uint32_t host_cbitpos; - struct sev_user_data_status status = {}; -+ SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs); - - ret = ram_block_discard_disable(true); - if (ret) { -@@ -952,7 +955,7 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -- sev_launch_start(SEV_GUEST(sev_common)); -+ ret = klass->launch_start(sev_common); - if (ret) { - error_setg(errp, "%s: failed to create encryption context", __func__); - goto err; -@@ -1451,6 +1454,10 @@ static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp) - static void - sev_guest_class_init(ObjectClass *oc, void *data) - { -+ SevCommonStateClass *klass = SEV_COMMON_CLASS(oc); -+ -+ klass->launch_start = sev_launch_start; -+ - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, - sev_guest_set_dh_cert_file); --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Reorder-struct-declarations.patch b/SOURCES/kvm-i386-sev-Reorder-struct-declarations.patch deleted file mode 100644 index 746317d..0000000 --- a/SOURCES/kvm-i386-sev-Reorder-struct-declarations.patch +++ /dev/null @@ -1,134 +0,0 @@ -From d009fa2cebebd1da80f4f2f5d0c4fffb87e02afc Mon Sep 17 00:00:00 2001 -From: Dov Murik -Date: Thu, 30 May 2024 06:16:34 -0500 -Subject: [PATCH 079/100] i386/sev: Reorder struct declarations - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [79/91] 1274d4620e88dda99ec10173ca5e3cd4184c8fb6 (bonzini/rhel-qemu-kvm) - -Move the declaration of PaddedSevHashTable before SevSnpGuest so -we can add a new such field to the latter. - -No functional change intended. - -Signed-off-by: Dov Murik -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-23-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit cc483bf911931f405dea682c74a3d8b9b6c54369) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 84 +++++++++++++++++++++++------------------------ - 1 file changed, 42 insertions(+), 42 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 73f9406715..3fce4c08eb 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -46,6 +46,48 @@ OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON) - OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST) - OBJECT_DECLARE_TYPE(SevSnpGuestState, SevCommonStateClass, SEV_SNP_GUEST) - -+/* hard code sha256 digest size */ -+#define HASH_SIZE 32 -+ -+typedef struct QEMU_PACKED SevHashTableEntry { -+ QemuUUID guid; -+ uint16_t len; -+ uint8_t hash[HASH_SIZE]; -+} SevHashTableEntry; -+ -+typedef struct QEMU_PACKED SevHashTable { -+ QemuUUID guid; -+ uint16_t len; -+ SevHashTableEntry cmdline; -+ SevHashTableEntry initrd; -+ SevHashTableEntry kernel; -+} SevHashTable; -+ -+/* -+ * Data encrypted by sev_encrypt_flash() must be padded to a multiple of -+ * 16 bytes. -+ */ -+typedef struct QEMU_PACKED PaddedSevHashTable { -+ SevHashTable ht; -+ uint8_t padding[ROUND_UP(sizeof(SevHashTable), 16) - sizeof(SevHashTable)]; -+} PaddedSevHashTable; -+ -+QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0); -+ -+#define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e" -+typedef struct __attribute__((__packed__)) SevInfoBlock { -+ /* SEV-ES Reset Vector Address */ -+ uint32_t reset_addr; -+} SevInfoBlock; -+ -+#define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454" -+typedef struct QEMU_PACKED SevHashTableDescriptor { -+ /* SEV hash table area guest address */ -+ uint32_t base; -+ /* SEV hash table area size (in bytes) */ -+ uint32_t size; -+} SevHashTableDescriptor; -+ - struct SevCommonState { - X86ConfidentialGuest parent_obj; - -@@ -128,48 +170,6 @@ typedef struct SevLaunchUpdateData { - - static QTAILQ_HEAD(, SevLaunchUpdateData) launch_update; - --#define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e" --typedef struct __attribute__((__packed__)) SevInfoBlock { -- /* SEV-ES Reset Vector Address */ -- uint32_t reset_addr; --} SevInfoBlock; -- --#define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454" --typedef struct QEMU_PACKED SevHashTableDescriptor { -- /* SEV hash table area guest address */ -- uint32_t base; -- /* SEV hash table area size (in bytes) */ -- uint32_t size; --} SevHashTableDescriptor; -- --/* hard code sha256 digest size */ --#define HASH_SIZE 32 -- --typedef struct QEMU_PACKED SevHashTableEntry { -- QemuUUID guid; -- uint16_t len; -- uint8_t hash[HASH_SIZE]; --} SevHashTableEntry; -- --typedef struct QEMU_PACKED SevHashTable { -- QemuUUID guid; -- uint16_t len; -- SevHashTableEntry cmdline; -- SevHashTableEntry initrd; -- SevHashTableEntry kernel; --} SevHashTable; -- --/* -- * Data encrypted by sev_encrypt_flash() must be padded to a multiple of -- * 16 bytes. -- */ --typedef struct QEMU_PACKED PaddedSevHashTable { -- SevHashTable ht; -- uint8_t padding[ROUND_UP(sizeof(SevHashTable), 16) - sizeof(SevHashTable)]; --} PaddedSevHashTable; -- --QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0); -- - static Error *sev_mig_blocker; - - static const char *const sev_fw_errlist[] = { --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Replace-error_report-with-error_setg.patch b/SOURCES/kvm-i386-sev-Replace-error_report-with-error_setg.patch deleted file mode 100644 index ba66cde..0000000 --- a/SOURCES/kvm-i386-sev-Replace-error_report-with-error_setg.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 80c1d78e31b2567d1c610c8939b75d159ff6ea27 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:13 -0500 -Subject: [PATCH 055/100] i386/sev: Replace error_report with error_setg - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [55/91] 1e15fc2458687e564af9fa5022c29e79ddc8edfd (bonzini/rhel-qemu-kvm) - -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-2-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 18c453409a3a84cf7b2c764c5a03fb429a73bbeb) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index d30b68c11e..67ed32e5ea 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -952,13 +952,13 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - - if (sev_es_enabled()) { - if (!kvm_kernel_irqchip_allowed()) { -- error_report("%s: SEV-ES guests require in-kernel irqchip support", -- __func__); -+ error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip" -+ "support", __func__); - goto err; - } - - if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) { -- error_report("%s: guest policy requires SEV-ES, but " -+ error_setg(errp, "%s: guest policy requires SEV-ES, but " - "host SEV-ES support unavailable", - __func__); - goto err; --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Return-when-sev_common-is-null.patch b/SOURCES/kvm-i386-sev-Return-when-sev_common-is-null.patch deleted file mode 100644 index 6fc68aa..0000000 --- a/SOURCES/kvm-i386-sev-Return-when-sev_common-is-null.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 88da6d01b1de2b92adb5c47c6d482876a054705f Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Fri, 7 Jun 2024 13:36:11 -0500 -Subject: [PATCH 086/100] i386/sev: Return when sev_common is null - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [86/91] 02ce4a6a51ce9fd961f417c13db0a760673591ba (bonzini/rhel-qemu-kvm) - -Fixes Coverity CID 1546885. - -Fixes: 16dcf200dc ("i386/sev: Introduce "sev-common" type to encapsulate common SEV state") -Signed-off-by: Pankaj Gupta -Message-ID: <20240607183611.1111100-4-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit cd7093a7a168a823d07671348996f049d45e8f67) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index f18432f58e..c40562dce3 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -587,6 +587,7 @@ static SevCapability *sev_get_capabilities(Error **errp) - sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); - if (!sev_common) { - error_setg(errp, "SEV is not configured"); -+ return NULL; - } - - sev_device = object_property_get_str(OBJECT(sev_common), "sev-device", --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Set-CPU-state-to-protected-once-SNP-guest-p.patch b/SOURCES/kvm-i386-sev-Set-CPU-state-to-protected-once-SNP-guest-p.patch deleted file mode 100644 index 8548e22..0000000 --- a/SOURCES/kvm-i386-sev-Set-CPU-state-to-protected-once-SNP-guest-p.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c7649ac1b958dc48de50f32b1ad80d84b17945a8 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:29 -0500 -Subject: [PATCH 069/100] i386/sev: Set CPU state to protected once SNP guest - payload is finalized - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [69/91] 09280f987a186511ec7d62c3f340b2148e8556d7 (bonzini/rhel-qemu-kvm) - -Once KVM_SNP_LAUNCH_FINISH is called the vCPU state is copied into the -vCPU's VMSA page and measured/encrypted. Any attempt to read/write CPU -state afterward will only be acting on the initial data and so are -effectively no-ops. - -Set the vCPU state to protected at this point so that QEMU don't -continue trying to re-sync vCPU data during guest runtime. - -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-18-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 3d44fdff60ea66fbd7a33f5d32b50843cd80f48a) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index ef2e592ca7..e84e4395a5 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -997,6 +997,7 @@ sev_snp_launch_finish(SevCommonState *sev_common) - exit(1); - } - -+ kvm_mark_guest_state_protected(); - sev_set_guest_state(sev_common, SEV_STATE_RUNNING); - - /* add migration blocker */ --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Switch-to-use-confidential_guest_kvm_init.patch b/SOURCES/kvm-i386-sev-Switch-to-use-confidential_guest_kvm_init.patch deleted file mode 100644 index 05ccb0a..0000000 --- a/SOURCES/kvm-i386-sev-Switch-to-use-confidential_guest_kvm_init.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 5540bb5ca052531563df1ade68995e268ae65224 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 29 Feb 2024 01:00:36 -0500 -Subject: [PATCH 012/100] i386/sev: Switch to use confidential_guest_kvm_init() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [12/91] 6f5f8d1b818826f7ee4b6ae527963ef23c97f531 (bonzini/rhel-qemu-kvm) - -Use confidential_guest_kvm_init() instead of calling SEV -specific sev_kvm_init(). This allows the introduction of multiple -confidential-guest-support subclasses for different x86 vendors. - -As a bonus, stubs are not needed anymore since there is no -direct call from target/i386/kvm/kvm.c to SEV code. - -Signed-off-by: Xiaoyao Li -Message-Id: <20240229060038.606591-1-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 637c95b37b106c2eeba313e0abb38ec12e918a59) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 10 +-- - target/i386/kvm/meson.build | 2 - - target/i386/kvm/sev-stub.c | 21 ------ - target/i386/sev.c | 127 ++++++++++++++++++------------------ - target/i386/sev.h | 2 - - 5 files changed, 69 insertions(+), 93 deletions(-) - delete mode 100644 target/i386/kvm/sev-stub.c - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 5f30b649a0..e271652620 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -2543,10 +2543,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - * mechanisms are supported in future (e.g. TDX), they'll need - * their own initialization either here or elsewhere. - */ -- ret = sev_kvm_init(ms->cgs, &local_err); -- if (ret < 0) { -- error_report_err(local_err); -- return ret; -+ if (ms->cgs) { -+ ret = confidential_guest_kvm_init(ms->cgs, &local_err); -+ if (ret < 0) { -+ error_report_err(local_err); -+ return ret; -+ } - } - - has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS); -diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build -index 84d9143e60..e7850981e6 100644 ---- a/target/i386/kvm/meson.build -+++ b/target/i386/kvm/meson.build -@@ -7,8 +7,6 @@ i386_kvm_ss.add(files( - - i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) - --i386_kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c')) -- - i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) - - i386_system_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss) -diff --git a/target/i386/kvm/sev-stub.c b/target/i386/kvm/sev-stub.c -deleted file mode 100644 -index 1be5341e8a..0000000000 ---- a/target/i386/kvm/sev-stub.c -+++ /dev/null -@@ -1,21 +0,0 @@ --/* -- * QEMU SEV stub -- * -- * Copyright Advanced Micro Devices 2018 -- * -- * Authors: -- * Brijesh Singh -- * -- * 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 "sev.h" -- --int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) --{ -- /* If we get here, cgs must be some non-SEV thing */ -- return 0; --} -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 72930ff0dc..b8f79d34d1 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -353,63 +353,6 @@ static void sev_guest_set_kernel_hashes(Object *obj, bool value, Error **errp) - sev->kernel_hashes = value; - } - --static void --sev_guest_class_init(ObjectClass *oc, void *data) --{ -- object_class_property_add_str(oc, "sev-device", -- sev_guest_get_sev_device, -- sev_guest_set_sev_device); -- object_class_property_set_description(oc, "sev-device", -- "SEV device to use"); -- object_class_property_add_str(oc, "dh-cert-file", -- sev_guest_get_dh_cert_file, -- sev_guest_set_dh_cert_file); -- object_class_property_set_description(oc, "dh-cert-file", -- "guest owners DH certificate (encoded with base64)"); -- object_class_property_add_str(oc, "session-file", -- sev_guest_get_session_file, -- sev_guest_set_session_file); -- object_class_property_set_description(oc, "session-file", -- "guest owners session parameters (encoded with base64)"); -- object_class_property_add_bool(oc, "kernel-hashes", -- sev_guest_get_kernel_hashes, -- sev_guest_set_kernel_hashes); -- object_class_property_set_description(oc, "kernel-hashes", -- "add kernel hashes to guest firmware for measured Linux boot"); --} -- --static void --sev_guest_instance_init(Object *obj) --{ -- SevGuestState *sev = SEV_GUEST(obj); -- -- sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); -- sev->policy = DEFAULT_GUEST_POLICY; -- object_property_add_uint32_ptr(obj, "policy", &sev->policy, -- OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "handle", &sev->handle, -- OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos, -- OBJ_PROP_FLAG_READWRITE); -- object_property_add_uint32_ptr(obj, "reduced-phys-bits", -- &sev->reduced_phys_bits, -- OBJ_PROP_FLAG_READWRITE); --} -- --/* sev guest info */ --static const TypeInfo sev_guest_info = { -- .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT, -- .name = TYPE_SEV_GUEST, -- .instance_size = sizeof(SevGuestState), -- .instance_finalize = sev_guest_finalize, -- .class_init = sev_guest_class_init, -- .instance_init = sev_guest_instance_init, -- .interfaces = (InterfaceInfo[]) { -- { TYPE_USER_CREATABLE }, -- { } -- } --}; -- - bool - sev_enabled(void) - { -@@ -906,20 +849,15 @@ sev_vm_state_change(void *opaque, bool running, RunState state) - } - } - --int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { -- SevGuestState *sev -- = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST); -+ SevGuestState *sev = SEV_GUEST(cgs); - char *devname; - int ret, fw_error, cmd; - uint32_t ebx; - uint32_t host_cbitpos; - struct sev_user_data_status status = {}; - -- if (!sev) { -- return 0; -- } -- - ret = ram_block_discard_disable(true); - if (ret) { - error_report("%s: cannot disable RAM discard", __func__); -@@ -1384,6 +1322,67 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+static void -+sev_guest_class_init(ObjectClass *oc, void *data) -+{ -+ ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); -+ -+ klass->kvm_init = sev_kvm_init; -+ -+ object_class_property_add_str(oc, "sev-device", -+ sev_guest_get_sev_device, -+ sev_guest_set_sev_device); -+ object_class_property_set_description(oc, "sev-device", -+ "SEV device to use"); -+ object_class_property_add_str(oc, "dh-cert-file", -+ sev_guest_get_dh_cert_file, -+ sev_guest_set_dh_cert_file); -+ object_class_property_set_description(oc, "dh-cert-file", -+ "guest owners DH certificate (encoded with base64)"); -+ object_class_property_add_str(oc, "session-file", -+ sev_guest_get_session_file, -+ sev_guest_set_session_file); -+ object_class_property_set_description(oc, "session-file", -+ "guest owners session parameters (encoded with base64)"); -+ object_class_property_add_bool(oc, "kernel-hashes", -+ sev_guest_get_kernel_hashes, -+ sev_guest_set_kernel_hashes); -+ object_class_property_set_description(oc, "kernel-hashes", -+ "add kernel hashes to guest firmware for measured Linux boot"); -+} -+ -+static void -+sev_guest_instance_init(Object *obj) -+{ -+ SevGuestState *sev = SEV_GUEST(obj); -+ -+ sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); -+ sev->policy = DEFAULT_GUEST_POLICY; -+ object_property_add_uint32_ptr(obj, "policy", &sev->policy, -+ OBJ_PROP_FLAG_READWRITE); -+ object_property_add_uint32_ptr(obj, "handle", &sev->handle, -+ OBJ_PROP_FLAG_READWRITE); -+ object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos, -+ OBJ_PROP_FLAG_READWRITE); -+ object_property_add_uint32_ptr(obj, "reduced-phys-bits", -+ &sev->reduced_phys_bits, -+ OBJ_PROP_FLAG_READWRITE); -+} -+ -+/* sev guest info */ -+static const TypeInfo sev_guest_info = { -+ .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT, -+ .name = TYPE_SEV_GUEST, -+ .instance_size = sizeof(SevGuestState), -+ .instance_finalize = sev_guest_finalize, -+ .class_init = sev_guest_class_init, -+ .instance_init = sev_guest_instance_init, -+ .interfaces = (InterfaceInfo[]) { -+ { TYPE_USER_CREATABLE }, -+ { } -+ } -+}; -+ - static void - sev_register_types(void) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index e7499c95b1..9e10d09539 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -57,6 +57,4 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, - int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size); - void sev_es_set_reset_vector(CPUState *cpu); - --int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); -- - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-Update-query-sev-QAPI-format-to-handle-SEV-.patch b/SOURCES/kvm-i386-sev-Update-query-sev-QAPI-format-to-handle-SEV-.patch deleted file mode 100644 index 27852d5..0000000 --- a/SOURCES/kvm-i386-sev-Update-query-sev-QAPI-format-to-handle-SEV-.patch +++ /dev/null @@ -1,240 +0,0 @@ -From a870e7c31d9605baea4741d82521612b6164c99b Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Thu, 30 May 2024 06:16:26 -0500 -Subject: [PATCH 066/100] i386/sev: Update query-sev QAPI format to handle - SEV-SNP - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [66/91] a19b3e226e857f3995176e7d2ef1ce2e4329a885 (bonzini/rhel-qemu-kvm) - -Most of the current 'query-sev' command is relevant to both legacy -SEV/SEV-ES guests and SEV-SNP guests, with 2 exceptions: - - - 'policy' is a 64-bit field for SEV-SNP, not 32-bit, and - the meaning of the bit positions has changed - - 'handle' is not relevant to SEV-SNP - -To address this, this patch adds a new 'sev-type' field that can be -used as a discriminator to select between SEV and SEV-SNP-specific -fields/formats without breaking compatibility for existing management -tools (so long as management tools that add support for launching -SEV-SNP guest update their handling of query-sev appropriately). - -The corresponding HMP command has also been fixed up similarly. - -Signed-off-by: Michael Roth -Co-developed-by:Pankaj Gupta -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-15-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 59d3740cb4ac0f010ce35877572904f6297284b4) -Signed-off-by: Paolo Bonzini ---- - qapi/misc-target.json | 72 ++++++++++++++++++++++++++++++++++--------- - target/i386/sev.c | 55 +++++++++++++++++++++------------ - target/i386/sev.h | 3 ++ - 3 files changed, 96 insertions(+), 34 deletions(-) - -diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index 4e0a6492a9..2d7d4d89bd 100644 ---- a/qapi/misc-target.json -+++ b/qapi/misc-target.json -@@ -47,6 +47,50 @@ - 'send-update', 'receive-update' ], - 'if': 'TARGET_I386' } - -+## -+# @SevGuestType: -+# -+# An enumeration indicating the type of SEV guest being run. -+# -+# @sev: The guest is a legacy SEV or SEV-ES guest. -+# -+# @sev-snp: The guest is an SEV-SNP guest. -+# -+# Since: 6.2 -+## -+{ 'enum': 'SevGuestType', -+ 'data': [ 'sev', 'sev-snp' ], -+ 'if': 'TARGET_I386' } -+ -+## -+# @SevGuestInfo: -+# -+# Information specific to legacy SEV/SEV-ES guests. -+# -+# @policy: SEV policy value -+# -+# @handle: SEV firmware handle -+# -+# Since: 2.12 -+## -+{ 'struct': 'SevGuestInfo', -+ 'data': { 'policy': 'uint32', -+ 'handle': 'uint32' }, -+ 'if': 'TARGET_I386' } -+ -+## -+# @SevSnpGuestInfo: -+# -+# Information specific to SEV-SNP guests. -+# -+# @snp-policy: SEV-SNP policy value -+# -+# Since: 9.1 -+## -+{ 'struct': 'SevSnpGuestInfo', -+ 'data': { 'snp-policy': 'uint64' }, -+ 'if': 'TARGET_I386' } -+ - ## - # @SevInfo: - # -@@ -60,25 +104,25 @@ - # - # @build-id: SEV FW build id - # --# @policy: SEV policy value --# - # @state: SEV guest state - # --# @handle: SEV firmware handle -+# @sev-type: Type of SEV guest being run - # - # Since: 2.12 - ## --{ 'struct': 'SevInfo', -- 'data': { 'enabled': 'bool', -- 'api-major': 'uint8', -- 'api-minor' : 'uint8', -- 'build-id' : 'uint8', -- 'policy' : 'uint32', -- 'state' : 'SevState', -- 'handle' : 'uint32' -- }, -- 'if': 'TARGET_I386' --} -+{ 'union': 'SevInfo', -+ 'base': { 'enabled': 'bool', -+ 'api-major': 'uint8', -+ 'api-minor' : 'uint8', -+ 'build-id' : 'uint8', -+ 'state' : 'SevState', -+ 'sev-type' : 'SevGuestType' }, -+ 'discriminator': 'sev-type', -+ 'data': { -+ 'sev': 'SevGuestInfo', -+ 'sev-snp': 'SevSnpGuestInfo' }, -+ 'if': 'TARGET_I386' } -+ - - ## - # @query-sev: -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 072cc4f853..43d1c48bd9 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -363,25 +363,27 @@ static SevInfo *sev_get_info(void) - { - SevInfo *info; - SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs); -- SevGuestState *sev_guest = -- (SevGuestState *)object_dynamic_cast(OBJECT(sev_common), -- TYPE_SEV_GUEST); - - info = g_new0(SevInfo, 1); - info->enabled = sev_enabled(); - - if (info->enabled) { -- if (sev_guest) { -- info->handle = sev_guest->handle; -- } - info->api_major = sev_common->api_major; - info->api_minor = sev_common->api_minor; - info->build_id = sev_common->build_id; - info->state = sev_common->state; -- /* we only report the lower 32-bits of policy for SNP, ok for now... */ -- info->policy = -- (uint32_t)object_property_get_uint(OBJECT(sev_common), -- "policy", NULL); -+ -+ if (sev_snp_enabled()) { -+ info->sev_type = SEV_GUEST_TYPE_SEV_SNP; -+ info->u.sev_snp.snp_policy = -+ object_property_get_uint(OBJECT(sev_common), "policy", NULL); -+ } else { -+ info->sev_type = SEV_GUEST_TYPE_SEV; -+ info->u.sev.handle = SEV_GUEST(sev_common)->handle; -+ info->u.sev.policy = -+ (uint32_t)object_property_get_uint(OBJECT(sev_common), -+ "policy", NULL); -+ } - } - - return info; -@@ -404,20 +406,33 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict) - { - SevInfo *info = sev_get_info(); - -- if (info && info->enabled) { -- monitor_printf(mon, "handle: %d\n", info->handle); -- monitor_printf(mon, "state: %s\n", SevState_str(info->state)); -- monitor_printf(mon, "build: %d\n", info->build_id); -- monitor_printf(mon, "api version: %d.%d\n", -- info->api_major, info->api_minor); -+ if (!info || !info->enabled) { -+ monitor_printf(mon, "SEV is not enabled\n"); -+ goto out; -+ } -+ -+ monitor_printf(mon, "SEV type: %s\n", SevGuestType_str(info->sev_type)); -+ monitor_printf(mon, "state: %s\n", SevState_str(info->state)); -+ monitor_printf(mon, "build: %d\n", info->build_id); -+ monitor_printf(mon, "api version: %d.%d\n", info->api_major, -+ info->api_minor); -+ -+ if (sev_snp_enabled()) { - monitor_printf(mon, "debug: %s\n", -- info->policy & SEV_POLICY_NODBG ? "off" : "on"); -- monitor_printf(mon, "key-sharing: %s\n", -- info->policy & SEV_POLICY_NOKS ? "off" : "on"); -+ info->u.sev_snp.snp_policy & SEV_SNP_POLICY_DBG ? "on" -+ : "off"); -+ monitor_printf(mon, "SMT allowed: %s\n", -+ info->u.sev_snp.snp_policy & SEV_SNP_POLICY_SMT ? "on" -+ : "off"); - } else { -- monitor_printf(mon, "SEV is not enabled\n"); -+ monitor_printf(mon, "handle: %d\n", info->u.sev.handle); -+ monitor_printf(mon, "debug: %s\n", -+ info->u.sev.policy & SEV_POLICY_NODBG ? "off" : "on"); -+ monitor_printf(mon, "key-sharing: %s\n", -+ info->u.sev.policy & SEV_POLICY_NOKS ? "off" : "on"); - } - -+out: - qapi_free_SevInfo(info); - } - -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 94295ee74f..5dc4767b1e 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -31,6 +31,9 @@ - #define SEV_POLICY_DOMAIN 0x10 - #define SEV_POLICY_SEV 0x20 - -+#define SEV_SNP_POLICY_SMT 0x10000 -+#define SEV_SNP_POLICY_DBG 0x80000 -+ - typedef struct SevKernelLoaderContext { - char *setup_data; - size_t setup_size; --- -2.39.3 - diff --git a/SOURCES/kvm-i386-sev-fix-unreachable-code-coverity-issue.patch b/SOURCES/kvm-i386-sev-fix-unreachable-code-coverity-issue.patch deleted file mode 100644 index 56f9f6f..0000000 --- a/SOURCES/kvm-i386-sev-fix-unreachable-code-coverity-issue.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 98057e3adafa052b21a4fe5ef22835d30df3e644 Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Fri, 7 Jun 2024 13:36:09 -0500 -Subject: [PATCH 084/100] i386/sev: fix unreachable code coverity issue - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [84/91] dc7bf28f491bf675b22a98ea593fba72d8bc415a (bonzini/rhel-qemu-kvm) - -Set 'finish->id_block_en' early, so that it is properly reset. - -Fixes coverity CID 1546887. - -Fixes: 7b34df4426 ("i386/sev: Introduce 'sev-snp-guest' object") -Signed-off-by: Pankaj Gupta -Message-ID: <20240607183611.1111100-2-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit c94eb5db8e409c932da9eb187e68d4cdc14acc5b) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 004c667ac1..7c9df621de 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -2165,6 +2165,7 @@ sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp) - struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf; - gsize len; - -+ finish->id_block_en = 0; - g_free(sev_snp_guest->id_block); - g_free((guchar *)finish->id_block_uaddr); - -@@ -2184,7 +2185,7 @@ sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp) - return; - } - -- finish->id_block_en = (len) ? 1 : 0; -+ finish->id_block_en = 1; - } - - static char * --- -2.39.3 - diff --git a/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch b/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch new file mode 100644 index 0000000..944c549 --- /dev/null +++ b/SOURCES/kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch @@ -0,0 +1,402 @@ +From 40b5689f28e6fef2dfdd0269639c8556200458a3 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:47 -0400 +Subject: [PATCH 14/27] include/hw/s390x: Add include files for common IPL + structs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [14/23] 632d18ef238ded324c962855edb77e3d3f0b4eae (thuth/qemu-kvm-cs9) + +Currently, structures defined in both hw/s390x/ipl.h and pc-bios/s390-ccw/iplb.h +must be kept in sync, which is prone to error. Instead, create a new directory +at include/hw/s390x/ipl/ to contain the definitions that must be shared. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-14-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit ba3658adc80a9370257a9c4e114829ec691311e3) +--- + hw/s390x/ipl.h | 104 +----------------------------- + include/hw/s390x/ipl/qipl.h | 123 ++++++++++++++++++++++++++++++++++++ + pc-bios/s390-ccw/Makefile | 2 +- + pc-bios/s390-ccw/iplb.h | 84 ++---------------------- + 4 files changed, 130 insertions(+), 183 deletions(-) + create mode 100644 include/hw/s390x/ipl/qipl.h + +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index b2105b616a..fa394c339d 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -16,95 +16,11 @@ + #include "cpu.h" + #include "exec/address-spaces.h" + #include "hw/qdev-core.h" ++#include "hw/s390x/ipl/qipl.h" + #include "qom/object.h" + +-struct IPLBlockPVComp { +- uint64_t tweak_pref; +- uint64_t addr; +- uint64_t size; +-} QEMU_PACKED; +-typedef struct IPLBlockPVComp IPLBlockPVComp; +- +-struct IPLBlockPV { +- uint8_t reserved18[87]; /* 0x18 */ +- uint8_t version; /* 0x6f */ +- uint32_t reserved70; /* 0x70 */ +- uint32_t num_comp; /* 0x74 */ +- uint64_t pv_header_addr; /* 0x78 */ +- uint64_t pv_header_len; /* 0x80 */ +- struct IPLBlockPVComp components[0]; +-} QEMU_PACKED; +-typedef struct IPLBlockPV IPLBlockPV; +- +-struct IplBlockCcw { +- uint8_t reserved0[85]; +- uint8_t ssid; +- uint16_t devno; +- uint8_t vm_flags; +- uint8_t reserved3[3]; +- uint32_t vm_parm_len; +- uint8_t nss_name[8]; +- uint8_t vm_parm[64]; +- uint8_t reserved4[8]; +-} QEMU_PACKED; +-typedef struct IplBlockCcw IplBlockCcw; +- +-struct IplBlockFcp { +- uint8_t reserved1[305 - 1]; +- uint8_t opt; +- uint8_t reserved2[3]; +- uint16_t reserved3; +- uint16_t devno; +- uint8_t reserved4[4]; +- uint64_t wwpn; +- uint64_t lun; +- uint32_t bootprog; +- uint8_t reserved5[12]; +- uint64_t br_lba; +- uint32_t scp_data_len; +- uint8_t reserved6[260]; +- uint8_t scp_data[0]; +-} QEMU_PACKED; +-typedef struct IplBlockFcp IplBlockFcp; +- +-struct IplBlockQemuScsi { +- uint32_t lun; +- uint16_t target; +- uint16_t channel; +- uint8_t reserved0[77]; +- uint8_t ssid; +- uint16_t devno; +-} QEMU_PACKED; +-typedef struct IplBlockQemuScsi IplBlockQemuScsi; +- + #define DIAG308_FLAGS_LP_VALID 0x80 + +-union IplParameterBlock { +- struct { +- uint32_t len; +- uint8_t reserved0[3]; +- uint8_t version; +- uint32_t blk0_len; +- uint8_t pbt; +- uint8_t flags; +- uint16_t reserved01; +- uint8_t loadparm[8]; +- union { +- IplBlockCcw ccw; +- IplBlockFcp fcp; +- IPLBlockPV pv; +- IplBlockQemuScsi scsi; +- }; +- } QEMU_PACKED; +- struct { +- uint8_t reserved1[110]; +- uint16_t devno; +- uint8_t reserved2[88]; +- uint8_t reserved_ext[4096 - 200]; +- } QEMU_PACKED; +-} QEMU_PACKED; +-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(Error **errp); +@@ -131,24 +47,6 @@ void s390_ipl_clear_reset_request(void); + #define QIPL_FLAG_BM_OPTS_CMD 0x80 + #define QIPL_FLAG_BM_OPTS_ZIPL 0x40 + +-/* +- * The QEMU IPL Parameters will be stored at absolute address +- * 204 (0xcc) which means it is 32-bit word aligned but not +- * double-word aligned. Placement of 64-bit data fields in this +- * area must account for their alignment needs. +- * The total size of the struct must never exceed 28 bytes. +- * This definition must be kept in sync with the definition +- * in pc-bios/s390-ccw/iplb.h. +- */ +-struct QemuIplParameters { +- uint8_t qipl_flags; +- uint8_t reserved1[3]; +- uint64_t reserved2; +- uint32_t boot_menu_timeout; +- uint8_t reserved3[12]; +-} QEMU_PACKED; +-typedef struct QemuIplParameters QemuIplParameters; +- + #define TYPE_S390_IPL "s390-ipl" + OBJECT_DECLARE_SIMPLE_TYPE(S390IPLState, S390_IPL) + +diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h +new file mode 100644 +index 0000000000..0ef04af027 +--- /dev/null ++++ b/include/hw/s390x/ipl/qipl.h +@@ -0,0 +1,123 @@ ++/* ++ * S/390 boot structures ++ * ++ * Copyright 2024 IBM Corp. ++ * Author(s): Jared Rossi ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++ ++#ifndef S390X_QIPL_H ++#define S390X_QIPL_H ++ ++/* Boot Menu flags */ ++#define QIPL_FLAG_BM_OPTS_CMD 0x80 ++#define QIPL_FLAG_BM_OPTS_ZIPL 0x40 ++ ++#define QIPL_ADDRESS 0xcc ++#define LOADPARM_LEN 8 ++ ++/* ++ * The QEMU IPL Parameters will be stored at absolute address ++ * 204 (0xcc) which means it is 32-bit word aligned but not ++ * double-word aligned. Placement of 64-bit data fields in this ++ * area must account for their alignment needs. ++ * The total size of the struct must never exceed 28 bytes. ++ */ ++struct QemuIplParameters { ++ uint8_t qipl_flags; ++ uint8_t reserved1[3]; ++ uint64_t reserved2; ++ uint32_t boot_menu_timeout; ++ uint8_t reserved3[12]; ++} QEMU_PACKED; ++typedef struct QemuIplParameters QemuIplParameters; ++ ++struct IPLBlockPVComp { ++ uint64_t tweak_pref; ++ uint64_t addr; ++ uint64_t size; ++} QEMU_PACKED; ++typedef struct IPLBlockPVComp IPLBlockPVComp; ++ ++struct IPLBlockPV { ++ uint8_t reserved18[87]; /* 0x18 */ ++ uint8_t version; /* 0x6f */ ++ uint32_t reserved70; /* 0x70 */ ++ uint32_t num_comp; /* 0x74 */ ++ uint64_t pv_header_addr; /* 0x78 */ ++ uint64_t pv_header_len; /* 0x80 */ ++ struct IPLBlockPVComp components[0]; ++} QEMU_PACKED; ++typedef struct IPLBlockPV IPLBlockPV; ++ ++struct IplBlockCcw { ++ uint8_t reserved0[85]; ++ uint8_t ssid; ++ uint16_t devno; ++ uint8_t vm_flags; ++ uint8_t reserved3[3]; ++ uint32_t vm_parm_len; ++ uint8_t nss_name[8]; ++ uint8_t vm_parm[64]; ++ uint8_t reserved4[8]; ++} QEMU_PACKED; ++typedef struct IplBlockCcw IplBlockCcw; ++ ++struct IplBlockFcp { ++ uint8_t reserved1[305 - 1]; ++ uint8_t opt; ++ uint8_t reserved2[3]; ++ uint16_t reserved3; ++ uint16_t devno; ++ uint8_t reserved4[4]; ++ uint64_t wwpn; ++ uint64_t lun; ++ uint32_t bootprog; ++ uint8_t reserved5[12]; ++ uint64_t br_lba; ++ uint32_t scp_data_len; ++ uint8_t reserved6[260]; ++ uint8_t scp_data[0]; ++} QEMU_PACKED; ++typedef struct IplBlockFcp IplBlockFcp; ++ ++struct IplBlockQemuScsi { ++ uint32_t lun; ++ uint16_t target; ++ uint16_t channel; ++ uint8_t reserved0[77]; ++ uint8_t ssid; ++ uint16_t devno; ++} QEMU_PACKED; ++typedef struct IplBlockQemuScsi IplBlockQemuScsi; ++ ++union IplParameterBlock { ++ struct { ++ uint32_t len; ++ uint8_t reserved0[3]; ++ uint8_t version; ++ uint32_t blk0_len; ++ uint8_t pbt; ++ uint8_t flags; ++ uint16_t reserved01; ++ uint8_t loadparm[LOADPARM_LEN]; ++ union { ++ IplBlockCcw ccw; ++ IplBlockFcp fcp; ++ IPLBlockPV pv; ++ IplBlockQemuScsi scsi; ++ }; ++ } QEMU_PACKED; ++ struct { ++ uint8_t reserved1[110]; ++ uint16_t devno; ++ uint8_t reserved2[88]; ++ uint8_t reserved_ext[4096 - 200]; ++ } QEMU_PACKED; ++} QEMU_PACKED; ++typedef union IplParameterBlock IplParameterBlock; ++ ++#endif +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index 27cbb354af..db9e8f0892 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -3,7 +3,7 @@ all: build-all + @true + + include config-host.mak +-CFLAGS = -O2 -g ++CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl + MAKEFLAGS += -rR + + GIT_SUBMODULES = roms/SLOF +diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h +index 3758698468..16643f5879 100644 +--- a/pc-bios/s390-ccw/iplb.h ++++ b/pc-bios/s390-ccw/iplb.h +@@ -12,88 +12,14 @@ + #ifndef IPLB_H + #define IPLB_H + +-#define LOADPARM_LEN 8 ++#ifndef QEMU_PACKED ++#define QEMU_PACKED __attribute__((packed)) ++#endif + +-struct IplBlockCcw { +- uint8_t reserved0[85]; +- uint8_t ssid; +- uint16_t devno; +- uint8_t vm_flags; +- uint8_t reserved3[3]; +- uint32_t vm_parm_len; +- uint8_t nss_name[8]; +- uint8_t vm_parm[64]; +- uint8_t reserved4[8]; +-} __attribute__ ((packed)); +-typedef struct IplBlockCcw IplBlockCcw; +- +-struct IplBlockFcp { +- uint8_t reserved1[305 - 1]; +- uint8_t opt; +- uint8_t reserved2[3]; +- uint16_t reserved3; +- uint16_t devno; +- uint8_t reserved4[4]; +- uint64_t wwpn; +- uint64_t lun; +- uint32_t bootprog; +- uint8_t reserved5[12]; +- uint64_t br_lba; +- uint32_t scp_data_len; +- uint8_t reserved6[260]; +- uint8_t scp_data[]; +-} __attribute__ ((packed)); +-typedef struct IplBlockFcp IplBlockFcp; +- +-struct IplBlockQemuScsi { +- uint32_t lun; +- uint16_t target; +- uint16_t channel; +- uint8_t reserved0[77]; +- uint8_t ssid; +- uint16_t devno; +-} __attribute__ ((packed)); +-typedef struct IplBlockQemuScsi IplBlockQemuScsi; +- +-struct IplParameterBlock { +- uint32_t len; +- uint8_t reserved0[3]; +- uint8_t version; +- uint32_t blk0_len; +- uint8_t pbt; +- uint8_t flags; +- uint16_t reserved01; +- uint8_t loadparm[LOADPARM_LEN]; +- union { +- IplBlockCcw ccw; +- IplBlockFcp fcp; +- IplBlockQemuScsi scsi; +- }; +-} __attribute__ ((packed)); +-typedef struct IplParameterBlock IplParameterBlock; +- +-extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); +- +-#define QIPL_ADDRESS 0xcc +- +-/* Boot Menu flags */ +-#define QIPL_FLAG_BM_OPTS_CMD 0x80 +-#define QIPL_FLAG_BM_OPTS_ZIPL 0x40 +- +-/* +- * This definition must be kept in sync with the definition +- * in hw/s390x/ipl.h +- */ +-struct QemuIplParameters { +- uint8_t qipl_flags; +- uint8_t reserved1[3]; +- uint64_t reserved2; +- uint32_t boot_menu_timeout; +- uint8_t reserved3[12]; +-} __attribute__ ((packed)); +-typedef struct QemuIplParameters QemuIplParameters; ++#include + + extern QemuIplParameters qipl; ++extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); + + #define S390_IPL_TYPE_FCP 0x00 + #define S390_IPL_TYPE_CCW 0x02 +-- +2.39.3 + diff --git a/SOURCES/kvm-introduce-pc_rhel_9_5_compat.patch b/SOURCES/kvm-introduce-pc_rhel_9_5_compat.patch deleted file mode 100644 index 9a17dda..0000000 --- a/SOURCES/kvm-introduce-pc_rhel_9_5_compat.patch +++ /dev/null @@ -1,81 +0,0 @@ -From deae6c3b57c3919946a5ce1613e667a3240cf158 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 15 Apr 2024 12:45:09 +0200 -Subject: [PATCH 001/100] introduce pc_rhel_9_5_compat - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [1/91] cfd402fa5080eddba7c954e81ed79f9a1dd654cf (bonzini/rhel-qemu-kvm) - -Allow undoing backported changes that impact guest ABI. - -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 4 ++++ - hw/i386/pc_piix.c | 2 ++ - hw/i386/pc_q35.c | 2 ++ - include/hw/i386/pc.h | 3 +++ - 4 files changed, 11 insertions(+) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 4a154c1a9a..648762d908 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -348,6 +348,10 @@ GlobalProperty pc_rhel_compat[] = { - }; - const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); - -+GlobalProperty pc_rhel_9_5_compat[] = { -+}; -+const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat); -+ - GlobalProperty pc_rhel_9_3_compat[] = { - /* pc_rhel_9_3_compat from pc_compat_8_0 */ - { "virtio-mem", "unplugged-inaccessible", "auto" }, -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index 6b260682eb..bef3e8b73e 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -1015,6 +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, pc_rhel_9_5_compat, -+ pc_rhel_9_5_compat_len); - compat_props_add(m->compat_props, hw_compat_rhel_9_5, - hw_compat_rhel_9_5_len); - compat_props_add(m->compat_props, hw_compat_rhel_9_4, -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 2b54944c0f..9adcdadce8 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -734,6 +734,8 @@ static void pc_q35_machine_rhel940_options(MachineClass *m) - pcmc->smbios_stream_product = "RHEL"; - pcmc->smbios_stream_version = "9.4.0"; - -+ compat_props_add(m->compat_props, pc_rhel_9_5_compat, -+ pc_rhel_9_5_compat_len); - compat_props_add(m->compat_props, hw_compat_rhel_9_5, - hw_compat_rhel_9_5_len); - } -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index a984c951ad..87420783ab 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -294,6 +294,9 @@ extern const size_t pc_compat_2_0_len; - extern GlobalProperty pc_rhel_compat[]; - extern const size_t pc_rhel_compat_len; - -+extern GlobalProperty pc_rhel_9_5_compat[]; -+extern const size_t pc_rhel_9_5_compat_len; -+ - extern GlobalProperty pc_rhel_9_3_compat[]; - extern const size_t pc_rhel_9_3_compat_len; - --- -2.39.3 - diff --git a/SOURCES/kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch b/SOURCES/kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch deleted file mode 100644 index 137cb53..0000000 --- a/SOURCES/kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 16c2e9e339a4c83055fd39e032fa16a0e732ed17 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 25 Apr 2024 14:49:40 +0200 -Subject: [PATCH 2/4] iotests/244: Don't store data-file with protocol in image - -RH-Author: Hana Czenczek -RH-MergeRequest: 1: CVE 2024-4467 (PRDSC) -RH-Jira: RHEL-35611 -RH-CVE: CVE-2024-4467 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Eric Blake -RH-Commit: [2/4] 92e00dab8be1570b13172353d77d2af44cb4e22b - -We want to disable filename parsing for data files because it's too easy -to abuse in malicious image files. Make the test ready for the change by -passing the data file explicitly in command line options. - -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Hanna Czenczek -Upstream: N/A, embargoed -Signed-off-by: Hanna Czenczek ---- - tests/qemu-iotests/244 | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 -index 3e61fa25bb..bb9cc6512f 100755 ---- a/tests/qemu-iotests/244 -+++ b/tests/qemu-iotests/244 -@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" - $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" - - # blkdebug doesn't support copy offloading, so this tests the error path --$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG" --$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" --$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" -+test_img_with_blkdebug="json:{ -+ 'driver': 'qcow2', -+ 'file': { -+ 'driver': 'file', -+ 'filename': '$TEST_IMG' -+ }, -+ 'data-file': { -+ 'driver': 'blkdebug', -+ 'image': { -+ 'driver': 'file', -+ 'filename': '$TEST_IMG.data' -+ } -+ } -+}" -+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug" -+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug" - - echo - echo "=== Flushing should flush the data file ===" --- -2.39.3 - diff --git a/SOURCES/kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch b/SOURCES/kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch deleted file mode 100644 index 2c1d6ae..0000000 --- a/SOURCES/kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch +++ /dev/null @@ -1,64 +0,0 @@ -From d70daa2eb5b670513ccd36c0baa5b36ec8cef666 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 25 Apr 2024 14:49:40 +0200 -Subject: [PATCH 3/4] iotests/270: Don't store data-file with json: prefix in - image - -RH-Author: Hana Czenczek -RH-MergeRequest: 1: CVE 2024-4467 (PRDSC) -RH-Jira: RHEL-35611 -RH-CVE: CVE-2024-4467 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Eric Blake -RH-Commit: [3/4] 705bcc2819ce8e0f8b9d660a93bc48de26413aec - -We want to disable filename parsing for data files because it's too easy -to abuse in malicious image files. Make the test ready for the change by -passing the data file explicitly in command line options. - -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Hanna Czenczek -Upstream: N/A, embargoed -Signed-off-by: Hanna Czenczek ---- - tests/qemu-iotests/270 | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270 -index 74352342db..c37b674aa2 100755 ---- a/tests/qemu-iotests/270 -+++ b/tests/qemu-iotests/270 -@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \ - # "write" 2G of data without using any space. - # (qemu-img create does not like it, though, because null-co does not - # support image creation.) --$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ -- "$TEST_IMG" -+test_img_with_null_data="json:{ -+ 'driver': '$IMGFMT', -+ 'file': { -+ 'filename': '$TEST_IMG' -+ }, -+ 'data-file': { -+ 'driver': 'null-co', -+ 'size':'4294967296' -+ } -+}" - - # This gives us a range of: - # 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31 -@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ - # on L2 boundaries, we need large L2 tables; hence the cluster size of - # 2 MB. (Anything from 256 kB should work, though, because then one L2 - # table covers 8 GB.) --$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io -+$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io - - _check_test_img - --- -2.39.3 - diff --git a/SOURCES/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch b/SOURCES/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch new file mode 100644 index 0000000..0308722 --- /dev/null +++ b/SOURCES/kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch @@ -0,0 +1,609 @@ +From 9cf467603ed9b5f4a3a16fbd5da21eb02ec2e224 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:07 +0100 +Subject: [PATCH 23/23] iotests: Add (NBD-based) tests for inactive nodes + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [22/22] 60b324d221718b24a5d0f95e1a052607aa8b9338 (kmwolf/centos-qemu-kvm) + +This tests different types of operations on inactive block nodes +(including graph changes, block jobs and NBD exports) to make sure that +users manually activating and inactivating nodes doesn't break things. + +Support for inactive nodes in other export types will have to come with +separate test cases because they have different dependencies like blkio +or root permissions and we don't want to disable this basic test when +they are not fulfilled. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Message-ID: <20250204211407.381505-17-kwolf@redhat.com> +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit bbf105ef3cc48fff282789e9bf56b7a81e1407bd) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/iotests.py | 4 + + tests/qemu-iotests/tests/inactive-node-nbd | 303 ++++++++++++++++++ + .../qemu-iotests/tests/inactive-node-nbd.out | 239 ++++++++++++++ + 3 files changed, 546 insertions(+) + create mode 100755 tests/qemu-iotests/tests/inactive-node-nbd + create mode 100644 tests/qemu-iotests/tests/inactive-node-nbd.out + +diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py +index 1a42aa1416..c8cb028c2d 100644 +--- a/tests/qemu-iotests/iotests.py ++++ b/tests/qemu-iotests/iotests.py +@@ -913,6 +913,10 @@ def add_incoming(self, addr): + self._args.append(addr) + return self + ++ def add_paused(self): ++ self._args.append('-S') ++ return self ++ + def hmp(self, command_line: str, use_log: bool = False) -> QMPMessage: + cmd = 'human-monitor-command' + kwargs: Dict[str, Any] = {'command-line': command_line} +diff --git a/tests/qemu-iotests/tests/inactive-node-nbd b/tests/qemu-iotests/tests/inactive-node-nbd +new file mode 100755 +index 0000000000..a95b37e796 +--- /dev/null ++++ b/tests/qemu-iotests/tests/inactive-node-nbd +@@ -0,0 +1,303 @@ ++#!/usr/bin/env python3 ++# group: rw quick ++# ++# Copyright (C) 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 . ++# ++# Creator/Owner: Kevin Wolf ++ ++import iotests ++ ++from iotests import QemuIoInteractive ++from iotests import filter_qemu_io, filter_qtest, filter_qmp_testfiles ++ ++iotests.script_initialize(supported_fmts=['generic'], ++ supported_protocols=['file'], ++ supported_platforms=['linux']) ++ ++def get_export(node_name='disk-fmt', allow_inactive=None): ++ exp = { ++ 'id': 'exp0', ++ 'type': 'nbd', ++ 'node-name': node_name, ++ 'writable': True, ++ } ++ ++ if allow_inactive is not None: ++ exp['allow-inactive'] = allow_inactive ++ ++ return exp ++ ++def node_is_active(_vm, node_name): ++ nodes = _vm.cmd('query-named-block-nodes', flat=True) ++ node = next(n for n in nodes if n['node-name'] == node_name) ++ return node['active'] ++ ++with iotests.FilePath('disk.img') as path, \ ++ iotests.FilePath('snap.qcow2') as snap_path, \ ++ iotests.FilePath('snap2.qcow2') as snap2_path, \ ++ iotests.FilePath('target.img') as target_path, \ ++ iotests.FilePath('nbd.sock', base_dir=iotests.sock_dir) as nbd_sock, \ ++ iotests.VM() as vm: ++ ++ img_size = '10M' ++ ++ iotests.log('Preparing disk...') ++ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) ++ iotests.qemu_img_create('-f', iotests.imgfmt, target_path, img_size) ++ ++ iotests.qemu_img_create('-f', 'qcow2', '-b', path, '-F', iotests.imgfmt, ++ snap_path) ++ iotests.qemu_img_create('-f', 'qcow2', '-b', snap_path, '-F', 'qcow2', ++ snap2_path) ++ ++ iotests.log('Launching VM...') ++ vm.add_blockdev(f'file,node-name=disk-file,filename={path}') ++ vm.add_blockdev(f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' ++ 'active=off') ++ vm.add_blockdev(f'file,node-name=target-file,filename={target_path}') ++ vm.add_blockdev(f'{iotests.imgfmt},file=target-file,node-name=target-fmt') ++ vm.add_blockdev(f'file,node-name=snap-file,filename={snap_path}') ++ vm.add_blockdev(f'file,node-name=snap2-file,filename={snap2_path}') ++ ++ # Actually running the VM activates all images ++ vm.add_paused() ++ ++ vm.launch() ++ vm.qmp_log('nbd-server-start', ++ addr={'type': 'unix', 'data':{'path': nbd_sock}}, ++ filters=[filter_qmp_testfiles]) ++ ++ iotests.log('\n=== Creating export of inactive node ===') ++ ++ iotests.log('\nExports activate nodes without allow-inactive') ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('block-export-add', **get_export()) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\nExports activate nodes with allow-inactive=false') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('block-export-add', **get_export(allow_inactive=False)) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\nExport leaves nodes inactive with allow-inactive=true') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('block-export-add', **get_export(allow_inactive=True)) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\n=== Inactivating node with existing export ===') ++ ++ iotests.log('\nInactivating nodes with an export fails without ' ++ 'allow-inactive') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) ++ vm.qmp_log('block-export-add', **get_export(node_name='disk-fmt')) ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\nInactivating nodes with an export fails with ' ++ 'allow-inactive=false') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) ++ vm.qmp_log('block-export-add', ++ **get_export(node_name='disk-fmt', allow_inactive=False)) ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\nInactivating nodes with an export works with ' ++ 'allow-inactive=true') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) ++ vm.qmp_log('block-export-add', ++ **get_export(node_name='disk-fmt', allow_inactive=True)) ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ vm.qmp_log('query-block-exports') ++ vm.qmp_log('block-export-del', id='exp0') ++ vm.event_wait('BLOCK_EXPORT_DELETED') ++ vm.qmp_log('query-block-exports') ++ ++ iotests.log('\n=== Inactive nodes with parent ===') ++ ++ iotests.log('\nInactivating nodes with an active parent fails') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) ++ vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) ++ iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ ++ iotests.log('\nInactivating nodes with an inactive parent works') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=False) ++ vm.qmp_log('blockdev-set-active', node_name='disk-file', active=False) ++ iotests.log('disk-file active: %s' % node_is_active(vm, 'disk-file')) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ ++ iotests.log('\nCreating active parent node with an inactive child fails') ++ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', ++ node_name='disk-filter') ++ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', ++ node_name='disk-filter', active=True) ++ ++ iotests.log('\nCreating inactive parent node with an inactive child works') ++ vm.qmp_log('blockdev-add', driver='raw', file='disk-fmt', ++ node_name='disk-filter', active=False) ++ vm.qmp_log('blockdev-del', node_name='disk-filter') ++ ++ iotests.log('\n=== Resizing an inactive node ===') ++ vm.qmp_log('block_resize', node_name='disk-fmt', size=16*1024*1024) ++ ++ iotests.log('\n=== Taking a snapshot of an inactive node ===') ++ ++ iotests.log('\nActive overlay over inactive backing file automatically ' ++ 'makes both inactive for compatibility') ++ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', ++ file='snap-file', backing=None) ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ vm.qmp_log('blockdev-del', node_name='snap-fmt') ++ ++ iotests.log('\nInactive overlay over inactive backing file just works') ++ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap-fmt', ++ file='snap-file', backing=None, active=False) ++ vm.qmp_log('blockdev-snapshot', node='disk-fmt', overlay='snap-fmt') ++ ++ iotests.log('\n=== Block jobs with inactive nodes ===') ++ ++ iotests.log('\nStreaming into an inactive node') ++ vm.qmp_log('block-stream', device='snap-fmt', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nCommitting an inactive root node (active commit)') ++ vm.qmp_log('block-commit', job_id='job0', device='snap-fmt', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nCommitting an inactive intermediate node to inactive base') ++ vm.qmp_log('blockdev-add', driver='qcow2', node_name='snap2-fmt', ++ file='snap2-file', backing='snap-fmt', active=False) ++ ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) ++ ++ vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', ++ top_node='snap-fmt', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nCommitting an inactive intermediate node to active base') ++ vm.qmp_log('blockdev-set-active', node_name='disk-fmt', active=True) ++ vm.qmp_log('block-commit', job_id='job0', device='snap2-fmt', ++ top_node='snap-fmt', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nMirror from inactive source to active target') ++ vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', ++ target='target-fmt', sync='full', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nMirror from active source to inactive target') ++ ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) ++ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) ++ ++ # Activating snap2-fmt recursively activates the whole backing chain ++ vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=True) ++ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) ++ ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) ++ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) ++ ++ vm.qmp_log('blockdev-mirror', job_id='job0', device='snap2-fmt', ++ target='target-fmt', sync='full', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nBackup from active source to inactive target') ++ ++ vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', ++ target='target-fmt', sync='full', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\nBackup from inactive source to active target') ++ ++ # Inactivating snap2-fmt recursively inactivates the whole backing chain ++ vm.qmp_log('blockdev-set-active', node_name='snap2-fmt', active=False) ++ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=True) ++ ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) ++ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) ++ ++ vm.qmp_log('blockdev-backup', job_id='job0', device='snap2-fmt', ++ target='target-fmt', sync='full', ++ filters=[iotests.filter_qmp_generated_node_ids]) ++ ++ iotests.log('\n=== Accessing export on inactive node ===') ++ ++ # Use the target node because it has the right image format and isn't the ++ # (read-only) backing file of a qcow2 node ++ vm.qmp_log('blockdev-set-active', node_name='target-fmt', active=False) ++ vm.qmp_log('block-export-add', ++ **get_export(node_name='target-fmt', allow_inactive=True)) ++ ++ # The read should succeed, everything else should fail gracefully ++ qemu_io = QemuIoInteractive('-f', 'raw', ++ f'nbd+unix:///target-fmt?socket={nbd_sock}') ++ iotests.log(qemu_io.cmd('read 0 64k'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('write 0 64k'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('write -z 0 64k'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('write -zu 0 64k'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('discard 0 64k'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('flush'), filters=[filter_qemu_io]) ++ iotests.log(qemu_io.cmd('map'), filters=[filter_qemu_io]) ++ qemu_io.close() ++ ++ iotests.log('\n=== Resuming VM activates all images ===') ++ vm.qmp_log('cont') ++ ++ iotests.log('disk-fmt active: %s' % node_is_active(vm, 'disk-fmt')) ++ iotests.log('snap-fmt active: %s' % node_is_active(vm, 'snap-fmt')) ++ iotests.log('snap2-fmt active: %s' % node_is_active(vm, 'snap2-fmt')) ++ iotests.log('target-fmt active: %s' % node_is_active(vm, 'target-fmt')) ++ ++ iotests.log('\nShutting down...') ++ vm.shutdown() ++ log = vm.get_log() ++ if log: ++ iotests.log(log, [filter_qtest, filter_qemu_io]) +diff --git a/tests/qemu-iotests/tests/inactive-node-nbd.out b/tests/qemu-iotests/tests/inactive-node-nbd.out +new file mode 100644 +index 0000000000..a458b4fc05 +--- /dev/null ++++ b/tests/qemu-iotests/tests/inactive-node-nbd.out +@@ -0,0 +1,239 @@ ++Preparing disk... ++Launching VM... ++{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}} ++{"return": {}} ++ ++=== Creating export of inactive node === ++ ++Exports activate nodes without allow-inactive ++disk-fmt active: False ++{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++disk-fmt active: True ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++Exports activate nodes with allow-inactive=false ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"return": {}} ++disk-fmt active: False ++{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++disk-fmt active: True ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++Export leaves nodes inactive with allow-inactive=true ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"return": {}} ++disk-fmt active: False ++{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++disk-fmt active: False ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++=== Inactivating node with existing export === ++ ++Inactivating nodes with an export fails without allow-inactive ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} ++disk-fmt active: True ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++Inactivating nodes with an export fails with allow-inactive=false ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "block-export-add", "arguments": {"allow-inactive": false, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"error": {"class": "GenericError", "desc": "Failed to inactivate node: Operation not permitted"}} ++disk-fmt active: True ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++Inactivating nodes with an export works with allow-inactive=true ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "disk-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"return": {}} ++disk-fmt active: False ++{"execute": "query-block-exports", "arguments": {}} ++{"return": [{"id": "exp0", "node-name": "disk-fmt", "shutting-down": false, "type": "nbd"}]} ++{"execute": "block-export-del", "arguments": {"id": "exp0"}} ++{"return": {}} ++{"execute": "query-block-exports", "arguments": {}} ++{"return": []} ++ ++=== Inactive nodes with parent === ++ ++Inactivating nodes with an active parent fails ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} ++{"error": {"class": "GenericError", "desc": "Node has active parent node"}} ++disk-file active: True ++disk-fmt active: True ++ ++Inactivating nodes with an inactive parent works ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "disk-file"}} ++{"return": {}} ++disk-file active: False ++disk-fmt active: False ++ ++Creating active parent node with an inactive child fails ++{"execute": "blockdev-add", "arguments": {"driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} ++{"execute": "blockdev-add", "arguments": {"active": true, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'disk-fmt' can't be a file child of active 'disk-filter'"}} ++ ++Creating inactive parent node with an inactive child works ++{"execute": "blockdev-add", "arguments": {"active": false, "driver": "raw", "file": "disk-fmt", "node-name": "disk-filter"}} ++{"return": {}} ++{"execute": "blockdev-del", "arguments": {"node-name": "disk-filter"}} ++{"return": {}} ++ ++=== Resizing an inactive node === ++{"execute": "block_resize", "arguments": {"node-name": "disk-fmt", "size": 16777216}} ++{"error": {"class": "GenericError", "desc": "Permission 'resize' unavailable on inactive node"}} ++ ++=== Taking a snapshot of an inactive node === ++ ++Active overlay over inactive backing file automatically makes both inactive for compatibility ++{"execute": "blockdev-add", "arguments": {"backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} ++{"return": {}} ++disk-fmt active: False ++snap-fmt active: True ++{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} ++{"return": {}} ++disk-fmt active: False ++snap-fmt active: False ++{"execute": "blockdev-del", "arguments": {"node-name": "snap-fmt"}} ++{"return": {}} ++ ++Inactive overlay over inactive backing file just works ++{"execute": "blockdev-add", "arguments": {"active": false, "backing": null, "driver": "qcow2", "file": "snap-file", "node-name": "snap-fmt"}} ++{"return": {}} ++{"execute": "blockdev-snapshot", "arguments": {"node": "disk-fmt", "overlay": "snap-fmt"}} ++{"return": {}} ++ ++=== Block jobs with inactive nodes === ++ ++Streaming into an inactive node ++{"execute": "block-stream", "arguments": {"device": "snap-fmt"}} ++{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap-fmt' can't be a file child of active 'NODE_NAME'"}} ++ ++Committing an inactive root node (active commit) ++{"execute": "block-commit", "arguments": {"device": "snap-fmt", "job-id": "job0"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} ++ ++Committing an inactive intermediate node to inactive base ++{"execute": "blockdev-add", "arguments": {"active": false, "backing": "snap-fmt", "driver": "qcow2", "file": "snap2-file", "node-name": "snap2-fmt"}} ++{"return": {}} ++disk-fmt active: False ++snap-fmt active: False ++snap2-fmt active: False ++{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} ++ ++Committing an inactive intermediate node to active base ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "disk-fmt"}} ++{"return": {}} ++{"execute": "block-commit", "arguments": {"device": "snap2-fmt", "job-id": "job0", "top-node": "snap-fmt"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'snap-fmt' can't be a backing child of active 'NODE_NAME'"}} ++ ++Mirror from inactive source to active target ++{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} ++{"error": {"class": "GenericError", "desc": "Inactive 'snap2-fmt' can't be a backing child of active 'NODE_NAME'"}} ++ ++Mirror from active source to inactive target ++disk-fmt active: True ++snap-fmt active: False ++snap2-fmt active: False ++target-fmt active: True ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "snap2-fmt"}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} ++{"return": {}} ++disk-fmt active: True ++snap-fmt active: True ++snap2-fmt active: True ++target-fmt active: False ++{"execute": "blockdev-mirror", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} ++{"error": {"class": "GenericError", "desc": "Permission 'write' unavailable on inactive node"}} ++ ++Backup from active source to inactive target ++{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} ++{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'target-fmt' can't be a target child of active 'NODE_NAME'"}} ++ ++Backup from inactive source to active target ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "snap2-fmt"}} ++{"return": {}} ++{"execute": "blockdev-set-active", "arguments": {"active": true, "node-name": "target-fmt"}} ++{"return": {}} ++disk-fmt active: False ++snap-fmt active: False ++snap2-fmt active: False ++target-fmt active: True ++{"execute": "blockdev-backup", "arguments": {"device": "snap2-fmt", "job-id": "job0", "sync": "full", "target": "target-fmt"}} ++{"error": {"class": "GenericError", "desc": "Could not create node: Inactive 'snap2-fmt' can't be a file child of active 'NODE_NAME'"}} ++ ++=== Accessing export on inactive node === ++{"execute": "blockdev-set-active", "arguments": {"active": false, "node-name": "target-fmt"}} ++{"return": {}} ++{"execute": "block-export-add", "arguments": {"allow-inactive": true, "id": "exp0", "node-name": "target-fmt", "type": "nbd", "writable": true}} ++{"return": {}} ++read 65536/65536 bytes at offset 0 ++64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++ ++write failed: Operation not permitted ++ ++write failed: Operation not permitted ++ ++write failed: Operation not permitted ++ ++discard failed: Operation not permitted ++ ++ ++qemu-io: Failed to get allocation status: Operation not permitted ++ ++ ++=== Resuming VM activates all images === ++{"execute": "cont", "arguments": {}} ++{"return": {}} ++disk-fmt active: True ++snap-fmt active: True ++snap2-fmt active: True ++target-fmt active: True ++ ++Shutting down... ++ +-- +2.48.1 + diff --git a/SOURCES/kvm-iotests-Add-filter_qtest.patch b/SOURCES/kvm-iotests-Add-filter_qtest.patch new file mode 100644 index 0000000..7b8d69a --- /dev/null +++ b/SOURCES/kvm-iotests-Add-filter_qtest.patch @@ -0,0 +1,113 @@ +From 1597f6bec5764608fead44fccdf2822846a506ef Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:05 +0100 +Subject: [PATCH 21/23] iotests: Add filter_qtest() + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [20/22] 7b62d4e707582e94a2ca92f27fb217a721cdad0c (kmwolf/centos-qemu-kvm) + +The open-coded form of this filter has been copied into enough tests +that it's better to move it into iotests.py. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Message-ID: <20250204211407.381505-15-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit ed26db83673f4a190332d2a378e2f6e342b8904d) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/041 | 4 +--- + tests/qemu-iotests/165 | 4 +--- + tests/qemu-iotests/iotests.py | 4 ++++ + tests/qemu-iotests/tests/copy-before-write | 3 +-- + tests/qemu-iotests/tests/migrate-bitmaps-test | 7 +++---- + 5 files changed, 10 insertions(+), 12 deletions(-) + +diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 +index 98d17b1388..8452845f44 100755 +--- a/tests/qemu-iotests/041 ++++ b/tests/qemu-iotests/041 +@@ -1100,10 +1100,8 @@ class TestRepairQuorum(iotests.QMPTestCase): + + # Check the full error message now + self.vm.shutdown() +- log = self.vm.get_log() +- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) ++ log = iotests.filter_qtest(self.vm.get_log()) + log = re.sub(r'^Formatting.*\n', '', log) +- log = re.sub(r'\n\[I \+\d+\.\d+\] CLOSED\n?$', '', log) + log = re.sub(r'^%s: ' % os.path.basename(iotests.qemu_prog), '', log) + + self.assertEqual(log, +diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165 +index b24907a62f..b3b1709d71 100755 +--- a/tests/qemu-iotests/165 ++++ b/tests/qemu-iotests/165 +@@ -82,9 +82,7 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase): + self.vm.shutdown() + + #catch 'Persistent bitmaps are lost' possible error +- log = self.vm.get_log() +- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) +- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) ++ log = iotests.filter_qtest(self.vm.get_log()) + if log: + print(log) + +diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py +index ea48af4a7b..1a42aa1416 100644 +--- a/tests/qemu-iotests/iotests.py ++++ b/tests/qemu-iotests/iotests.py +@@ -701,6 +701,10 @@ def _filter(_key, value): + def filter_nbd_exports(output: str) -> str: + return re.sub(r'((min|opt|max) block): [0-9]+', r'\1: XXX', output) + ++def filter_qtest(output: str) -> str: ++ output = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', output) ++ output = re.sub(r'\n?\[I \+\d+\.\d+\] CLOSED\n?$', '', output) ++ return output + + Msg = TypeVar('Msg', Dict[str, Any], List[Any], str) + +diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write +index d33bea577d..498c558008 100755 +--- a/tests/qemu-iotests/tests/copy-before-write ++++ b/tests/qemu-iotests/tests/copy-before-write +@@ -95,8 +95,7 @@ class TestCbwError(iotests.QMPTestCase): + + self.vm.shutdown() + log = self.vm.get_log() +- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) +- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) ++ log = iotests.filter_qtest(log) + log = iotests.filter_qemu_io(log) + return log + +diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test +index f98e721e97..8fb4099201 100755 +--- a/tests/qemu-iotests/tests/migrate-bitmaps-test ++++ b/tests/qemu-iotests/tests/migrate-bitmaps-test +@@ -122,11 +122,10 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase): + + # catch 'Could not reopen qcow2 layer: Bitmap already exists' + # possible error +- log = self.vm_a.get_log() +- log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) +- log = re.sub(r'^(wrote .* bytes at offset .*\n.*KiB.*ops.*sec.*\n){3}', ++ log = iotests.filter_qtest(self.vm_a.get_log()) ++ log = re.sub(r'^(wrote .* bytes at offset .*\n' ++ r'.*KiB.*ops.*sec.*\n?){3}', + '', log) +- log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) + self.assertEqual(log, '') + + # test that bitmap is still persistent +-- +2.48.1 + diff --git a/SOURCES/kvm-iotests-Add-qsd-migrate-case.patch b/SOURCES/kvm-iotests-Add-qsd-migrate-case.patch new file mode 100644 index 0000000..63c2513 --- /dev/null +++ b/SOURCES/kvm-iotests-Add-qsd-migrate-case.patch @@ -0,0 +1,244 @@ +From 21587defa46a2862be2322b6433dde23b7a9a5c9 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:06 +0100 +Subject: [PATCH 22/23] iotests: Add qsd-migrate case + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [21/22] 5467d4c29cf44bf1ad7bf3068baef0c0b4ee05ce (kmwolf/centos-qemu-kvm) + +Test that it's possible to migrate a VM that uses an image on shared +storage through qemu-storage-daemon. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Message-ID: <20250204211407.381505-16-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +(cherry picked from commit 3ea437ab3d561ca79b95a34c5128e370de4738e3) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/tests/qsd-migrate | 140 +++++++++++++++++++++++ + tests/qemu-iotests/tests/qsd-migrate.out | 59 ++++++++++ + 2 files changed, 199 insertions(+) + create mode 100755 tests/qemu-iotests/tests/qsd-migrate + create mode 100644 tests/qemu-iotests/tests/qsd-migrate.out + +diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate +new file mode 100755 +index 0000000000..de17562cb0 +--- /dev/null ++++ b/tests/qemu-iotests/tests/qsd-migrate +@@ -0,0 +1,140 @@ ++#!/usr/bin/env python3 ++# group: rw quick ++# ++# Copyright (C) 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 . ++# ++# Creator/Owner: Kevin Wolf ++ ++import iotests ++ ++from iotests import filter_qemu_io, filter_qtest ++ ++iotests.script_initialize(supported_fmts=['generic'], ++ supported_protocols=['file'], ++ supported_platforms=['linux']) ++ ++with iotests.FilePath('disk.img') as path, \ ++ iotests.FilePath('nbd-src.sock', base_dir=iotests.sock_dir) as nbd_src, \ ++ iotests.FilePath('nbd-dst.sock', base_dir=iotests.sock_dir) as nbd_dst, \ ++ iotests.FilePath('migrate.sock', base_dir=iotests.sock_dir) as mig_sock, \ ++ iotests.VM(path_suffix="-src") as vm_src, \ ++ iotests.VM(path_suffix="-dst") as vm_dst: ++ ++ img_size = '10M' ++ ++ iotests.log('Preparing disk...') ++ iotests.qemu_img_create('-f', iotests.imgfmt, path, img_size) ++ ++ iotests.log('Launching source QSD...') ++ qsd_src = iotests.QemuStorageDaemon( ++ '--blockdev', f'file,node-name=disk-file,filename={path}', ++ '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt', ++ '--nbd-server', f'addr.type=unix,addr.path={nbd_src}', ++ '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' ++ 'allow-inactive=true', ++ qmp=True, ++ ) ++ ++ iotests.log('Launching source VM...') ++ vm_src.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' ++ f'server.path={nbd_src},export=disk-fmt') ++ vm_src.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') ++ vm_src.launch() ++ ++ iotests.log('Launching destination QSD...') ++ qsd_dst = iotests.QemuStorageDaemon( ++ '--blockdev', f'file,node-name=disk-file,filename={path},active=off', ++ '--blockdev', f'{iotests.imgfmt},file=disk-file,node-name=disk-fmt,' ++ f'active=off', ++ '--nbd-server', f'addr.type=unix,addr.path={nbd_dst}', ++ '--export', 'nbd,id=exp0,node-name=disk-fmt,writable=true,' ++ 'allow-inactive=true', ++ qmp=True, ++ instance_id='b', ++ ) ++ ++ iotests.log('Launching destination VM...') ++ vm_dst.add_args('-blockdev', f'nbd,node-name=disk,server.type=unix,' ++ f'server.path={nbd_dst},export=disk-fmt') ++ vm_dst.add_args('-device', 'virtio-blk,drive=disk,id=virtio0') ++ vm_dst.add_args('-incoming', f'unix:{mig_sock}') ++ vm_dst.launch() ++ ++ iotests.log('\nTest I/O on the source') ++ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x11 0 4k', ++ use_log=True, qdev=True) ++ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', ++ use_log=True, qdev=True) ++ ++ iotests.log('\nStarting migration...') ++ ++ mig_caps = [ ++ {'capability': 'events', 'state': True}, ++ {'capability': 'pause-before-switchover', 'state': True}, ++ ] ++ vm_src.qmp_log('migrate-set-capabilities', capabilities=mig_caps) ++ vm_dst.qmp_log('migrate-set-capabilities', capabilities=mig_caps) ++ vm_src.qmp_log('migrate', uri=f'unix:{mig_sock}', ++ filters=[iotests.filter_qmp_testfiles]) ++ ++ vm_src.event_wait('MIGRATION', ++ match={'data': {'status': 'pre-switchover'}}) ++ ++ iotests.log('\nPre-switchover: Reconfigure QSD instances') ++ ++ iotests.log(qsd_src.qmp('blockdev-set-active', {'active': False})) ++ ++ # Reading is okay from both sides while the image is inactive. Note that ++ # the destination may have stale data until it activates the image, though. ++ vm_src.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', ++ use_log=True, qdev=True) ++ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read 0 4k', ++ use_log=True, qdev=True) ++ ++ iotests.log(qsd_dst.qmp('blockdev-set-active', {'active': True})) ++ ++ iotests.log('\nCompleting migration...') ++ ++ vm_src.qmp_log('migrate-continue', state='pre-switchover') ++ vm_dst.event_wait('MIGRATION', match={'data': {'status': 'completed'}}) ++ ++ iotests.log('\nTest I/O on the destination') ++ ++ # Now the destination must see what the source wrote ++ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x11 0 4k', ++ use_log=True, qdev=True) ++ ++ # And be able to overwrite it ++ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'write -P 0x22 0 4k', ++ use_log=True, qdev=True) ++ vm_dst.hmp_qemu_io('virtio0/virtio-backend', 'read -P 0x22 0 4k', ++ use_log=True, qdev=True) ++ ++ iotests.log('\nDone') ++ ++ vm_src.shutdown() ++ iotests.log('\n--- vm_src log ---') ++ log = vm_src.get_log() ++ if log: ++ iotests.log(log, [filter_qtest, filter_qemu_io]) ++ qsd_src.stop() ++ ++ vm_dst.shutdown() ++ iotests.log('\n--- vm_dst log ---') ++ log = vm_dst.get_log() ++ if log: ++ iotests.log(log, [filter_qtest, filter_qemu_io]) ++ qsd_dst.stop() +diff --git a/tests/qemu-iotests/tests/qsd-migrate.out b/tests/qemu-iotests/tests/qsd-migrate.out +new file mode 100644 +index 0000000000..4a5241e5d4 +--- /dev/null ++++ b/tests/qemu-iotests/tests/qsd-migrate.out +@@ -0,0 +1,59 @@ ++Preparing disk... ++Launching source QSD... ++Launching source VM... ++Launching destination QSD... ++Launching destination VM... ++ ++Test I/O on the source ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x11 0 4k\""}} ++{"return": ""} ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} ++{"return": ""} ++ ++Starting migration... ++{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} ++{"return": {}} ++{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [{"capability": "events", "state": true}, {"capability": "pause-before-switchover", "state": true}]}} ++{"return": {}} ++{"execute": "migrate", "arguments": {"uri": "unix:SOCK_DIR/PID-migrate.sock"}} ++{"return": {}} ++ ++Pre-switchover: Reconfigure QSD instances ++{"return": {}} ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} ++{"return": ""} ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read 0 4k\""}} ++{"return": ""} ++{"return": {}} ++ ++Completing migration... ++{"execute": "migrate-continue", "arguments": {"state": "pre-switchover"}} ++{"return": {}} ++ ++Test I/O on the destination ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x11 0 4k\""}} ++{"return": ""} ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"write -P 0x22 0 4k\""}} ++{"return": ""} ++{"execute": "human-monitor-command", "arguments": {"command-line": "qemu-io -d virtio0/virtio-backend \"read -P 0x22 0 4k\""}} ++{"return": ""} ++ ++Done ++ ++--- vm_src log --- ++wrote 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++ ++--- vm_dst log --- ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++wrote 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +-- +2.48.1 + diff --git a/SOURCES/kvm-iotests-test-NBD-TLS-iothread.patch b/SOURCES/kvm-iotests-test-NBD-TLS-iothread.patch deleted file mode 100644 index 5640a7e..0000000 --- a/SOURCES/kvm-iotests-test-NBD-TLS-iothread.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 88adaeaecb1d7753aa8ac3da40f617d93eaf8bdc Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Fri, 17 May 2024 21:50:15 -0500 -Subject: [PATCH 2/4] iotests: test NBD+TLS+iothread -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 244: qio: Inherit follow_coroutine_ctx across TLS -RH-Jira: RHEL-33440 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/2] 29c3128a158b7c49fa79c141a9adcc12693f7de4 (ebblake/centos-qemu-kvm) - -Prevent regressions when using NBD with TLS in the presence of -iothreads, adding coverage the fix to qio channels made in the -previous patch. - -The shell function pick_unused_port() was copied from -nbdkit.git/tests/functions.sh.in, where it had all authors from Red -Hat, agreeing to the resulting relicensing from 2-clause BSD to GPLv2. - -CC: qemu-stable@nongnu.org -CC: "Richard W.M. Jones" -Signed-off-by: Eric Blake -Message-ID: <20240531180639.1392905-6-eblake@redhat.com> -Reviewed-by: Daniel P. Berrangé -(cherry picked from commit a73c99378022ebb785481e84cfe1e81097546268) -Jira: https://issues.redhat.com/browse/RHEL-33440 -Signed-off-by: Eric Blake ---- - tests/qemu-iotests/tests/nbd-tls-iothread | 168 ++++++++++++++++++ - tests/qemu-iotests/tests/nbd-tls-iothread.out | 54 ++++++ - 2 files changed, 222 insertions(+) - create mode 100755 tests/qemu-iotests/tests/nbd-tls-iothread - create mode 100644 tests/qemu-iotests/tests/nbd-tls-iothread.out - -diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread b/tests/qemu-iotests/tests/nbd-tls-iothread -new file mode 100755 -index 0000000000..a2fb07206e ---- /dev/null -+++ b/tests/qemu-iotests/tests/nbd-tls-iothread -@@ -0,0 +1,168 @@ -+#!/usr/bin/env bash -+# group: rw quick -+# -+# Test of NBD+TLS+iothread -+# -+# 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 . -+# -+ -+# creator -+owner=eblake@redhat.com -+ -+seq=`basename $0` -+echo "QA output created by $seq" -+ -+status=1 # failure is the default! -+ -+_cleanup() -+{ -+ _cleanup_qemu -+ _cleanup_test_img -+ rm -f "$dst_image" -+ tls_x509_cleanup -+} -+trap "_cleanup; exit \$status" 0 1 2 3 15 -+ -+# get standard environment, filters and checks -+cd .. -+. ./common.rc -+. ./common.filter -+. ./common.qemu -+. ./common.tls -+. ./common.nbd -+ -+_supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below -+_supported_proto file -+ -+# pick_unused_port -+# -+# Picks and returns an "unused" port, setting the global variable -+# $port. -+# -+# This is inherently racy, but we need it because qemu does not currently -+# permit NBD+TLS over a Unix domain socket -+pick_unused_port () -+{ -+ if ! (ss --version) >/dev/null 2>&1; then -+ _notrun "ss utility required, skipped this test" -+ fi -+ -+ # Start at a random port to make it less likely that two parallel -+ # tests will conflict. -+ port=$(( 50000 + (RANDOM%15000) )) -+ while ss -ltn | grep -sqE ":$port\b"; do -+ ((port++)) -+ if [ $port -eq 65000 ]; then port=50000; fi -+ done -+ echo picked unused port -+} -+ -+tls_x509_init -+ -+size=1G -+DST_IMG="$TEST_DIR/dst.qcow2" -+ -+echo -+echo "== preparing TLS creds and spare port ==" -+ -+pick_unused_port -+tls_x509_create_root_ca "ca1" -+tls_x509_create_server "ca1" "server1" -+tls_x509_create_client "ca1" "client1" -+tls_obj_base=tls-creds-x509,id=tls0,verify-peer=true,dir="${tls_dir}" -+ -+echo -+echo "== preparing image ==" -+ -+_make_test_img $size -+$QEMU_IMG create -f qcow2 "$DST_IMG" $size | _filter_img_create -+ -+echo -+echo === Starting Src QEMU === -+echo -+ -+_launch_qemu -machine q35 \ -+ -object iothread,id=iothread0 \ -+ -object "${tls_obj_base}"/client1,endpoint=client \ -+ -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true, -+ "bus":"pcie.0"}' \ -+ -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0", -+ "bus":"root0", "iothread":"iothread0"}' \ -+ -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1", -+ "bus":"virtio_scsi_pci0.0"}' \ -+ -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false}, -+ "filename":"'"$TEST_IMG"'", "node-name":"drive_sys1"}' \ -+ -blockdev '{"driver":"qcow2", "node-name":"drive_image1", -+ "file":"drive_sys1"}' -+h1=$QEMU_HANDLE -+_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return' -+ -+echo -+echo === Starting Dst VM2 === -+echo -+ -+_launch_qemu -machine q35 \ -+ -object iothread,id=iothread0 \ -+ -object "${tls_obj_base}"/server1,endpoint=server \ -+ -device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true, -+ "bus":"pcie.0"}' \ -+ -device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0", -+ "bus":"root0", "iothread":"iothread0"}' \ -+ -device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1", -+ "bus":"virtio_scsi_pci0.0"}' \ -+ -blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false}, -+ "filename":"'"$DST_IMG"'", "node-name":"drive_sys1"}' \ -+ -blockdev '{"driver":"qcow2", "node-name":"drive_image1", -+ "file":"drive_sys1"}' \ -+ -incoming defer -+h2=$QEMU_HANDLE -+_send_qemu_cmd $h2 '{"execute": "qmp_capabilities"}' 'return' -+ -+echo -+echo === Dst VM: Enable NBD server for incoming storage migration === -+echo -+ -+_send_qemu_cmd $h2 '{"execute": "nbd-server-start", "arguments": -+ {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": "'$port'"}}, -+ "tls-creds": "tls0"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g" -+_send_qemu_cmd $h2 '{"execute": "block-export-add", "arguments": -+ {"node-name": "drive_image1", "type": "nbd", "writable": true, -+ "id": "drive_image1"}}' '{"return": {}}' -+ -+echo -+echo === Src VM: Mirror to dst NBD for outgoing storage migration === -+echo -+ -+_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments": -+ {"node-name": "mirror", "driver": "nbd", -+ "server": {"type": "inet", "host": "127.0.0.1", "port": "'$port'"}, -+ "export": "drive_image1", "tls-creds": "tls0", -+ "tls-hostname": "127.0.0.1"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g" -+_send_qemu_cmd $h1 '{"execute": "blockdev-mirror", "arguments": -+ {"sync": "full", "device": "drive_image1", "target": "mirror", -+ "job-id": "drive_image1_53"}}' '{"return": {}}' -+_timed_wait_for $h1 '"ready"' -+ -+echo -+echo === Cleaning up === -+echo -+ -+_send_qemu_cmd $h1 '{"execute":"quit"}' '' -+_send_qemu_cmd $h2 '{"execute":"quit"}' '' -+ -+echo "*** done" -+rm -f $seq.full -+status=0 -diff --git a/tests/qemu-iotests/tests/nbd-tls-iothread.out b/tests/qemu-iotests/tests/nbd-tls-iothread.out -new file mode 100644 -index 0000000000..1d83d4f903 ---- /dev/null -+++ b/tests/qemu-iotests/tests/nbd-tls-iothread.out -@@ -0,0 +1,54 @@ -+QA output created by nbd-tls-iothread -+ -+== preparing TLS creds and spare port == -+picked unused port -+Generating a self signed certificate... -+Generating a signed certificate... -+Generating a signed certificate... -+ -+== preparing image == -+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 -+Formatting 'TEST_DIR/dst.IMGFMT', fmt=IMGFMT size=1073741824 -+ -+=== Starting Src QEMU === -+ -+{"execute": "qmp_capabilities"} -+{"return": {}} -+ -+=== Starting Dst VM2 === -+ -+{"execute": "qmp_capabilities"} -+{"return": {}} -+ -+=== Dst VM: Enable NBD server for incoming storage migration === -+ -+{"execute": "nbd-server-start", "arguments": -+ {"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": PORT}}, -+ "tls-creds": "tls0"}} -+{"return": {}} -+{"execute": "block-export-add", "arguments": -+ {"node-name": "drive_image1", "type": "nbd", "writable": true, -+ "id": "drive_image1"}} -+{"return": {}} -+ -+=== Src VM: Mirror to dst NBD for outgoing storage migration === -+ -+{"execute": "blockdev-add", "arguments": -+ {"node-name": "mirror", "driver": "nbd", -+ "server": {"type": "inet", "host": "127.0.0.1", "port": PORT}, -+ "export": "drive_image1", "tls-creds": "tls0", -+ "tls-hostname": "127.0.0.1"}} -+{"return": {}} -+{"execute": "blockdev-mirror", "arguments": -+ {"sync": "full", "device": "drive_image1", "target": "mirror", -+ "job-id": "drive_image1_53"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "drive_image1_53"}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "drive_image1_53"}} -+{"return": {}} -+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "drive_image1_53"}} -+ -+=== Cleaning up === -+ -+{"execute":"quit"} -+{"execute":"quit"} -+*** done --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch b/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch new file mode 100644 index 0000000..5432fd3 --- /dev/null +++ b/SOURCES/kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch @@ -0,0 +1,287 @@ +From 07a472e19f11c6364e787e71c95c990b76aaf187 Mon Sep 17 00:00:00 2001 +From: Julia Suvorova +Date: Fri, 27 Sep 2024 12:47:40 +0200 +Subject: [PATCH 26/27] kvm: Allow kvm_arch_get/put_registers to accept Error** + +RH-Author: Julia Suvorova +RH-MergeRequest: 286: kvm: Allow kvm_arch_get/put_registers to accept Error** +RH-Jira: RHEL-60914 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Peter Xu +RH-Commit: [1/2] 2ab30f24245a52c4254a5b9238b1b2e966a8c6a2 + +This is necessary to provide discernible error messages to the caller. + +Signed-off-by: Julia Suvorova +Reviewed-by: Peter Xu +Link: https://lore.kernel.org/r/20240927104743.218468-2-jusual@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit a1676bb3047f28b292ecbce3a378ccc0b4721d47) +--- + accel/kvm/kvm-all.c | 41 +++++++++++++++++++++++++++++--------- + include/sysemu/kvm.h | 4 ++-- + target/arm/kvm.c | 4 ++-- + target/i386/kvm/kvm.c | 4 ++-- + target/loongarch/kvm/kvm.c | 4 ++-- + target/mips/kvm.c | 4 ++-- + target/ppc/kvm.c | 4 ++-- + target/riscv/kvm/kvm-cpu.c | 4 ++-- + target/s390x/kvm/kvm.c | 4 ++-- + 9 files changed, 48 insertions(+), 25 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index 75d11a07b2..a220178822 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2766,9 +2766,15 @@ void kvm_flush_coalesced_mmio_buffer(void) + static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg) + { + if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) { +- int ret = kvm_arch_get_registers(cpu); ++ Error *err = NULL; ++ int ret = kvm_arch_get_registers(cpu, &err); + if (ret) { +- error_report("Failed to get registers: %s", strerror(-ret)); ++ if (err) { ++ error_reportf_err(err, "Failed to synchronize CPU state: "); ++ } else { ++ error_report("Failed to get registers: %s", strerror(-ret)); ++ } ++ + cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); + vm_stop(RUN_STATE_INTERNAL_ERROR); + } +@@ -2786,9 +2792,15 @@ void kvm_cpu_synchronize_state(CPUState *cpu) + + static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg) + { +- int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE); ++ Error *err = NULL; ++ int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE, &err); + if (ret) { +- error_report("Failed to put registers after reset: %s", strerror(-ret)); ++ if (err) { ++ error_reportf_err(err, "Restoring resisters after reset: "); ++ } else { ++ error_report("Failed to put registers after reset: %s", ++ strerror(-ret)); ++ } + cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); + vm_stop(RUN_STATE_INTERNAL_ERROR); + } +@@ -2803,9 +2815,15 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu) + + static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) + { +- int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE); ++ Error *err = NULL; ++ int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE, &err); + if (ret) { +- error_report("Failed to put registers after init: %s", strerror(-ret)); ++ if (err) { ++ error_reportf_err(err, "Putting registers after init: "); ++ } else { ++ error_report("Failed to put registers after init: %s", ++ strerror(-ret)); ++ } + exit(1); + } + +@@ -2995,10 +3013,15 @@ int kvm_cpu_exec(CPUState *cpu) + MemTxAttrs attrs; + + if (cpu->vcpu_dirty) { +- ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE); ++ Error *err = NULL; ++ ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE, &err); + if (ret) { +- error_report("Failed to put registers after init: %s", +- strerror(-ret)); ++ if (err) { ++ error_reportf_err(err, "Putting registers after init: "); ++ } else { ++ error_report("Failed to put registers after init: %s", ++ strerror(-ret)); ++ } + ret = -1; + break; + } +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 9cf14ca3d5..d9ad723f78 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -359,7 +359,7 @@ int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run); + + int kvm_arch_process_async_events(CPUState *cpu); + +-int kvm_arch_get_registers(CPUState *cpu); ++int kvm_arch_get_registers(CPUState *cpu, Error **errp); + + /* state subset only touched by the VCPU itself during runtime */ + #define KVM_PUT_RUNTIME_STATE 1 +@@ -368,7 +368,7 @@ int kvm_arch_get_registers(CPUState *cpu); + /* full state set, modified during initialization or on vmload */ + #define KVM_PUT_FULL_STATE 3 + +-int kvm_arch_put_registers(CPUState *cpu, int level); ++int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp); + + int kvm_arch_get_default_type(MachineState *ms); + +diff --git a/target/arm/kvm.c b/target/arm/kvm.c +index 849e2e21b3..f1f1b5b375 100644 +--- a/target/arm/kvm.c ++++ b/target/arm/kvm.c +@@ -2042,7 +2042,7 @@ static int kvm_arch_put_sve(CPUState *cs) + return 0; + } + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + uint64_t val; + uint32_t fpr; +@@ -2226,7 +2226,7 @@ static int kvm_arch_get_sve(CPUState *cs) + return 0; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + uint64_t val; + unsigned int el; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 2b28c18693..423e6922d8 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -5121,7 +5121,7 @@ static int kvm_get_nested_state(X86CPU *cpu) + return ret; + } + +-int kvm_arch_put_registers(CPUState *cpu, int level) ++int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) + { + X86CPU *x86_cpu = X86_CPU(cpu); + int ret; +@@ -5209,7 +5209,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level) + return 0; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + X86CPU *cpu = X86_CPU(cs); + int ret; +diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c +index e1be6a6959..9204d4295d 100644 +--- a/target/loongarch/kvm/kvm.c ++++ b/target/loongarch/kvm/kvm.c +@@ -585,7 +585,7 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) + return ret; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + int ret; + +@@ -613,7 +613,7 @@ int kvm_arch_get_registers(CPUState *cs) + return ret; + } + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + int ret; + +diff --git a/target/mips/kvm.c b/target/mips/kvm.c +index a631ab544f..a98798c669 100644 +--- a/target/mips/kvm.c ++++ b/target/mips/kvm.c +@@ -1172,7 +1172,7 @@ static int kvm_mips_get_cp0_registers(CPUState *cs) + return ret; + } + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + CPUMIPSState *env = cpu_env(cs); + struct kvm_regs regs; +@@ -1207,7 +1207,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) + return ret; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + CPUMIPSState *env = cpu_env(cs); + int ret = 0; +diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c +index c942ff55b2..7daa097164 100644 +--- a/target/ppc/kvm.c ++++ b/target/ppc/kvm.c +@@ -902,7 +902,7 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu) + return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs); + } + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; +@@ -1207,7 +1207,7 @@ static int kvmppc_get_books_sregs(PowerPCCPU *cpu) + return 0; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; +diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c +index f6e3156b8d..2bfb112be0 100644 +--- a/target/riscv/kvm/kvm-cpu.c ++++ b/target/riscv/kvm/kvm-cpu.c +@@ -1192,7 +1192,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { + KVM_CAP_LAST_INFO + }; + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + int ret = 0; + +@@ -1237,7 +1237,7 @@ int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state) + return 0; + } + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + int ret = 0; + +diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c +index 45c23758e7..0d51a4ea6b 100644 +--- a/target/s390x/kvm/kvm.c ++++ b/target/s390x/kvm/kvm.c +@@ -472,7 +472,7 @@ static int can_sync_regs(CPUState *cs, int regs) + #define KVM_SYNC_REQUIRED_REGS (KVM_SYNC_GPRS | KVM_SYNC_ACRS | \ + KVM_SYNC_CRS | KVM_SYNC_PREFIX) + +-int kvm_arch_put_registers(CPUState *cs, int level) ++int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) + { + CPUS390XState *env = cpu_env(cs); + struct kvm_fpu fpu = {}; +@@ -598,7 +598,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) + return 0; + } + +-int kvm_arch_get_registers(CPUState *cs) ++int kvm_arch_get_registers(CPUState *cs, Error **errp) + { + CPUS390XState *env = cpu_env(cs); + struct kvm_fpu fpu; +-- +2.39.3 + diff --git a/SOURCES/kvm-kvm-Enable-KVM_SET_USER_MEMORY_REGION2-for-memslot.patch b/SOURCES/kvm-kvm-Enable-KVM_SET_USER_MEMORY_REGION2-for-memslot.patch deleted file mode 100644 index 10e98a7..0000000 --- a/SOURCES/kvm-kvm-Enable-KVM_SET_USER_MEMORY_REGION2-for-memslot.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 120157257ac239050779fdddc9abb56bd39958b3 Mon Sep 17 00:00:00 2001 -From: Chao Peng -Date: Wed, 20 Mar 2024 03:39:05 -0500 -Subject: [PATCH 029/100] kvm: Enable KVM_SET_USER_MEMORY_REGION2 for memslot - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [29/91] 9a08c8699f632cd046a6307e33bd053a7cc7db46 (bonzini/rhel-qemu-kvm) - -Switch to KVM_SET_USER_MEMORY_REGION2 when supported by KVM. - -With KVM_SET_USER_MEMORY_REGION2, QEMU can set up memory region that -backend'ed both by hva-based shared memory and guest memfd based private -memory. - -Signed-off-by: Chao Peng -Co-developed-by: Xiaoyao Li -Signed-off-by: Xiaoyao Li -Message-ID: <20240320083945.991426-10-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit ce5a983233b4ca94ced88c9581014346509b5c71) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 46 +++++++++++++++++++++++++++++++++------- - accel/kvm/trace-events | 2 +- - include/sysemu/kvm_int.h | 2 ++ - 3 files changed, 41 insertions(+), 9 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index a7b9a127dd..5ef55e4dd7 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -284,35 +284,58 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram, - static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, bool new) - { - KVMState *s = kvm_state; -- struct kvm_userspace_memory_region mem; -+ struct kvm_userspace_memory_region2 mem; - int ret; - - mem.slot = slot->slot | (kml->as_id << 16); - mem.guest_phys_addr = slot->start_addr; - mem.userspace_addr = (unsigned long)slot->ram; - mem.flags = slot->flags; -+ mem.guest_memfd = slot->guest_memfd; -+ mem.guest_memfd_offset = slot->guest_memfd_offset; - - if (slot->memory_size && !new && (mem.flags ^ slot->old_flags) & KVM_MEM_READONLY) { - /* Set the slot size to 0 before setting the slot to the desired - * value. This is needed based on KVM commit 75d61fbc. */ - mem.memory_size = 0; -- ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); -+ -+ if (kvm_guest_memfd_supported) { -+ ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, &mem); -+ } else { -+ ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); -+ } - if (ret < 0) { - goto err; - } - } - mem.memory_size = slot->memory_size; -- ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); -+ if (kvm_guest_memfd_supported) { -+ ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, &mem); -+ } else { -+ ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); -+ } - slot->old_flags = mem.flags; - err: - trace_kvm_set_user_memory(mem.slot >> 16, (uint16_t)mem.slot, mem.flags, - mem.guest_phys_addr, mem.memory_size, -- mem.userspace_addr, ret); -+ mem.userspace_addr, mem.guest_memfd, -+ mem.guest_memfd_offset, ret); - if (ret < 0) { -- error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d," -- " start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s", -- __func__, mem.slot, slot->start_addr, -- (uint64_t)mem.memory_size, strerror(errno)); -+ if (kvm_guest_memfd_supported) { -+ error_report("%s: KVM_SET_USER_MEMORY_REGION2 failed, slot=%d," -+ " start=0x%" PRIx64 ", size=0x%" PRIx64 "," -+ " flags=0x%" PRIx32 ", guest_memfd=%" PRId32 "," -+ " guest_memfd_offset=0x%" PRIx64 ": %s", -+ __func__, mem.slot, slot->start_addr, -+ (uint64_t)mem.memory_size, mem.flags, -+ mem.guest_memfd, (uint64_t)mem.guest_memfd_offset, -+ strerror(errno)); -+ } else { -+ error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d," -+ " start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s", -+ __func__, mem.slot, slot->start_addr, -+ (uint64_t)mem.memory_size, strerror(errno)); -+ } - } - return ret; - } -@@ -467,6 +490,10 @@ static int kvm_mem_flags(MemoryRegion *mr) - if (readonly && kvm_readonly_mem_allowed) { - flags |= KVM_MEM_READONLY; - } -+ if (memory_region_has_guest_memfd(mr)) { -+ assert(kvm_guest_memfd_supported); -+ flags |= KVM_MEM_GUEST_MEMFD; -+ } - return flags; - } - -@@ -1394,6 +1421,9 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, - mem->ram_start_offset = ram_start_offset; - mem->ram = ram; - mem->flags = kvm_mem_flags(mr); -+ mem->guest_memfd = mr->ram_block->guest_memfd; -+ mem->guest_memfd_offset = (uint8_t*)ram - mr->ram_block->host; -+ - kvm_slot_init_dirty_bitmap(mem); - err = kvm_set_user_memory_region(kml, mem, true); - if (err) { -diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events -index 9f599abc17..e8c52cb9e7 100644 ---- a/accel/kvm/trace-events -+++ b/accel/kvm/trace-events -@@ -15,7 +15,7 @@ kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d" - kvm_irqchip_release_virq(int virq) "virq %d" - kvm_set_ioeventfd_mmio(int fd, uint64_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%" PRIx64 " val=0x%x assign: %d size: %d match: %d" - kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%x val=0x%x assign: %d size: %d match: %d" --kvm_set_user_memory(uint16_t as, uint16_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) "AddrSpace#%d Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d" -+kvm_set_user_memory(uint16_t as, uint16_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, uint32_t fd, uint64_t fd_offset, int ret) "AddrSpace#%d Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " guest_memfd=%d" " guest_memfd_offset=0x%" PRIx64 " ret=%d" - kvm_clear_dirty_log(uint32_t slot, uint64_t start, uint32_t size) "slot#%"PRId32" start 0x%"PRIx64" size 0x%"PRIx32 - kvm_resample_fd_notify(int gsi) "gsi %d" - kvm_dirty_ring_full(int id) "vcpu %d" -diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h -index 3496be7997..a5a3fee411 100644 ---- a/include/sysemu/kvm_int.h -+++ b/include/sysemu/kvm_int.h -@@ -30,6 +30,8 @@ typedef struct KVMSlot - int as_id; - /* Cache of the offset in ram address space */ - ram_addr_t ram_start_offset; -+ int guest_memfd; -+ hwaddr guest_memfd_offset; - } KVMSlot; - - typedef struct KVMMemoryUpdate { --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-Introduce-support-for-memory_attributes.patch b/SOURCES/kvm-kvm-Introduce-support-for-memory_attributes.patch deleted file mode 100644 index 1f043a9..0000000 --- a/SOURCES/kvm-kvm-Introduce-support-for-memory_attributes.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 37e6c98987bb2d4be7ce1fdda4475cd0266271c3 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 20 Mar 2024 03:39:06 -0500 -Subject: [PATCH 027/100] kvm: Introduce support for memory_attributes - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [27/91] 1b4428289949478f7390196ae4b098c5e6f36bb0 (bonzini/rhel-qemu-kvm) - -Introduce the helper functions to set the attributes of a range of -memory to private or shared. - -This is necessary to notify KVM the private/shared attribute of each gpa -range. KVM needs the information to decide the GPA needs to be mapped at -hva-based shared memory or guest_memfd based private memory. - -Signed-off-by: Xiaoyao Li -Message-ID: <20240320083945.991426-11-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 0811baed49010a9b651b8029ab6b9828b09a884f) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 32 ++++++++++++++++++++++++++++++++ - include/sysemu/kvm.h | 4 ++++ - 2 files changed, 36 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 9bd235c969..272e945f52 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -91,6 +91,7 @@ bool kvm_msi_use_devid; - static bool kvm_has_guest_debug; - static int kvm_sstep_flags; - static bool kvm_immediate_exit; -+static uint64_t kvm_supported_memory_attributes; - static hwaddr kvm_max_slot_size = ~0; - - static const KVMCapabilityInfo kvm_required_capabilites[] = { -@@ -1266,6 +1267,36 @@ void kvm_set_max_memslot_size(hwaddr max_slot_size) - kvm_max_slot_size = max_slot_size; - } - -+static int kvm_set_memory_attributes(hwaddr start, uint64_t size, uint64_t attr) -+{ -+ struct kvm_memory_attributes attrs; -+ int r; -+ -+ assert((attr & kvm_supported_memory_attributes) == attr); -+ attrs.attributes = attr; -+ attrs.address = start; -+ attrs.size = size; -+ attrs.flags = 0; -+ -+ r = kvm_vm_ioctl(kvm_state, KVM_SET_MEMORY_ATTRIBUTES, &attrs); -+ if (r) { -+ error_report("failed to set memory (0x%" HWADDR_PRIx "+0x%" PRIx64 ") " -+ "with attr 0x%" PRIx64 " error '%s'", -+ start, size, attr, strerror(errno)); -+ } -+ return r; -+} -+ -+int kvm_set_memory_attributes_private(hwaddr start, uint64_t size) -+{ -+ return kvm_set_memory_attributes(start, size, KVM_MEMORY_ATTRIBUTE_PRIVATE); -+} -+ -+int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size) -+{ -+ return kvm_set_memory_attributes(start, size, 0); -+} -+ - /* Called with KVMMemoryListener.slots_lock held */ - static void kvm_set_phys_mem(KVMMemoryListener *kml, - MemoryRegionSection *section, bool add) -@@ -2387,6 +2418,7 @@ static int kvm_init(MachineState *ms) - goto err; - } - -+ kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES); - kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT); - s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS); - -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 54f4d83a37..f114ff6986 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -536,4 +536,8 @@ void kvm_mark_guest_state_protected(void); - * reported for the VM. - */ - bool kvm_hwpoisoned_mem(void); -+ -+int kvm_set_memory_attributes_private(hwaddr start, uint64_t size); -+int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size); -+ - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-add-support-for-guest-physical-bits.patch b/SOURCES/kvm-kvm-add-support-for-guest-physical-bits.patch deleted file mode 100644 index 97b94eb..0000000 --- a/SOURCES/kvm-kvm-add-support-for-guest-physical-bits.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 31cc494d69449811f4d995326479372da7c1241e Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 18 Mar 2024 16:53:35 +0100 -Subject: [PATCH 003/100] kvm: add support for guest physical bits - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [3/91] abb1ba3a584152d8efabd8255b86afe609f8ffbd (bonzini/rhel-qemu-kvm) - -Query kvm for supported guest physical address bits, in cpuid -function 80000008, eax[23:16]. Usually this is identical to host -physical address bits. With NPT or EPT being used this might be -restricted to 48 (max 4-level paging address space size) even if -the host cpu supports more physical address bits. - -When set pass this to the guest, using cpuid too. Guest firmware -can use this to figure how big the usable guest physical address -space is, so PCI bar mapping are actually reachable. - -Signed-off-by: Gerd Hoffmann -Reviewed-by: Xiaoyao Li -Reviewed-by: Zhao Liu -Message-ID: <20240318155336.156197-2-kraxel@redhat.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 0d08c423688edcca857f88dab20f1fc56de2b281) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm-cpu.c | 50 ++++++++++++++++++++++++++++++++------- - 1 file changed, 42 insertions(+), 8 deletions(-) - -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index b91af5051f..7ef94c681f 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -18,10 +18,32 @@ - #include "kvm_i386.h" - #include "hw/core/accel-cpu.h" - -+static void kvm_set_guest_phys_bits(CPUState *cs) -+{ -+ X86CPU *cpu = X86_CPU(cs); -+ uint32_t eax, guest_phys_bits; -+ -+ eax = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x80000008, 0, R_EAX); -+ guest_phys_bits = (eax >> 16) & 0xff; -+ if (!guest_phys_bits) { -+ return; -+ } -+ cpu->guest_phys_bits = guest_phys_bits; -+ if (cpu->guest_phys_bits > cpu->phys_bits) { -+ cpu->guest_phys_bits = cpu->phys_bits; -+ } -+ -+ if (cpu->host_phys_bits && cpu->host_phys_bits_limit && -+ cpu->guest_phys_bits > cpu->host_phys_bits_limit) { -+ cpu->guest_phys_bits = cpu->host_phys_bits_limit; -+ } -+} -+ - static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) - { - X86CPU *cpu = X86_CPU(cs); - CPUX86State *env = &cpu->env; -+ bool ret; - - /* - * The realize order is important, since x86_cpu_realize() checks if -@@ -32,13 +54,15 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) - * - * realize order: - * -- * x86_cpu_realize(): -- * -> x86_cpu_expand_features() -- * -> cpu_exec_realizefn(): -- * -> accel_cpu_common_realize() -- * kvm_cpu_realizefn() -> host_cpu_realizefn() -- * -> cpu_common_realizefn() -- * -> check/update ucode_rev, phys_bits, mwait -+ * x86_cpu_realizefn(): -+ * x86_cpu_expand_features() -+ * cpu_exec_realizefn(): -+ * accel_cpu_common_realize() -+ * kvm_cpu_realizefn() -+ * host_cpu_realizefn() -+ * kvm_set_guest_phys_bits() -+ * check/update ucode_rev, phys_bits, guest_phys_bits, mwait -+ * cpu_common_realizefn() (via xcc->parent_realize) - */ - if (cpu->max_features) { - if (enable_cpu_pm && kvm_has_waitpkg()) { -@@ -50,7 +74,17 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) - MSR_IA32_UCODE_REV); - } - } -- return host_cpu_realizefn(cs, errp); -+ ret = host_cpu_realizefn(cs, errp); -+ if (!ret) { -+ return ret; -+ } -+ -+ if ((env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) && -+ cpu->guest_phys_bits == -1) { -+ kvm_set_guest_phys_bits(cs); -+ } -+ -+ return true; - } - - static bool lmce_supported(void) --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-handle-KVM_EXIT_MEMORY_FAULT.patch b/SOURCES/kvm-kvm-handle-KVM_EXIT_MEMORY_FAULT.patch deleted file mode 100644 index 9baa06f..0000000 --- a/SOURCES/kvm-kvm-handle-KVM_EXIT_MEMORY_FAULT.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 33cc1b469689ee2bb7c4f745189472c74a0a98ab Mon Sep 17 00:00:00 2001 -From: Chao Peng -Date: Wed, 20 Mar 2024 03:39:08 -0500 -Subject: [PATCH 034/100] kvm: handle KVM_EXIT_MEMORY_FAULT - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [34/91] 59c672f6b19a3afcb61878775eb6425c6fdea6d5 (bonzini/rhel-qemu-kvm) - -Upon an KVM_EXIT_MEMORY_FAULT exit, userspace needs to do the memory -conversion on the RAMBlock to turn the memory into desired attribute, -switching between private and shared. - -Currently only KVM_MEMORY_EXIT_FLAG_PRIVATE in flags is valid when -KVM_EXIT_MEMORY_FAULT happens. - -Note, KVM_EXIT_MEMORY_FAULT makes sense only when the RAMBlock has -guest_memfd memory backend. - -Note, KVM_EXIT_MEMORY_FAULT returns with -EFAULT, so special handling is -added. - -When page is converted from shared to private, the original shared -memory can be discarded via ram_block_discard_range(). Note, shared -memory can be discarded only when it's not back'ed by hugetlb because -hugetlb is supposed to be pre-allocated and no need for discarding. - -Signed-off-by: Chao Peng -Co-developed-by: Xiaoyao Li -Signed-off-by: Xiaoyao Li - -Message-ID: <20240320083945.991426-13-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit c15e5684071d93174e446be318f49d8d59b15d6d) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 98 +++++++++++++++++++++++++++++++++++++----- - accel/kvm/trace-events | 2 + - include/sysemu/kvm.h | 2 + - 3 files changed, 92 insertions(+), 10 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 3f99efc8cc..09164e346c 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2900,6 +2900,69 @@ static void kvm_eat_signals(CPUState *cpu) - } while (sigismember(&chkset, SIG_IPI)); - } - -+int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private) -+{ -+ MemoryRegionSection section; -+ ram_addr_t offset; -+ MemoryRegion *mr; -+ RAMBlock *rb; -+ void *addr; -+ int ret = -1; -+ -+ trace_kvm_convert_memory(start, size, to_private ? "shared_to_private" : "private_to_shared"); -+ -+ if (!QEMU_PTR_IS_ALIGNED(start, qemu_real_host_page_size()) || -+ !QEMU_PTR_IS_ALIGNED(size, qemu_real_host_page_size())) { -+ return -1; -+ } -+ -+ if (!size) { -+ return -1; -+ } -+ -+ section = memory_region_find(get_system_memory(), start, size); -+ mr = section.mr; -+ if (!mr) { -+ return -1; -+ } -+ -+ if (!memory_region_has_guest_memfd(mr)) { -+ error_report("Converting non guest_memfd backed memory region " -+ "(0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s", -+ start, size, to_private ? "private" : "shared"); -+ goto out_unref; -+ } -+ -+ if (to_private) { -+ ret = kvm_set_memory_attributes_private(start, size); -+ } else { -+ ret = kvm_set_memory_attributes_shared(start, size); -+ } -+ if (ret) { -+ goto out_unref; -+ } -+ -+ addr = memory_region_get_ram_ptr(mr) + section.offset_within_region; -+ rb = qemu_ram_block_from_host(addr, false, &offset); -+ -+ if (to_private) { -+ if (rb->page_size != qemu_real_host_page_size()) { -+ /* -+ * shared memory is backed by hugetlb, which is supposed to be -+ * pre-allocated and doesn't need to be discarded -+ */ -+ goto out_unref; -+ } -+ ret = ram_block_discard_range(rb, offset, size); -+ } else { -+ ret = ram_block_discard_guest_memfd_range(rb, offset, size); -+ } -+ -+out_unref: -+ memory_region_unref(mr); -+ return ret; -+} -+ - int kvm_cpu_exec(CPUState *cpu) - { - struct kvm_run *run = cpu->kvm_run; -@@ -2967,18 +3030,20 @@ int kvm_cpu_exec(CPUState *cpu) - ret = EXCP_INTERRUPT; - break; - } -- fprintf(stderr, "error: kvm run failed %s\n", -- strerror(-run_ret)); -+ if (!(run_ret == -EFAULT && run->exit_reason == KVM_EXIT_MEMORY_FAULT)) { -+ fprintf(stderr, "error: kvm run failed %s\n", -+ strerror(-run_ret)); - #ifdef TARGET_PPC -- if (run_ret == -EBUSY) { -- fprintf(stderr, -- "This is probably because your SMT is enabled.\n" -- "VCPU can only run on primary threads with all " -- "secondary threads offline.\n"); -- } -+ if (run_ret == -EBUSY) { -+ fprintf(stderr, -+ "This is probably because your SMT is enabled.\n" -+ "VCPU can only run on primary threads with all " -+ "secondary threads offline.\n"); -+ } - #endif -- ret = -1; -- break; -+ ret = -1; -+ break; -+ } - } - - trace_kvm_run_exit(cpu->cpu_index, run->exit_reason); -@@ -3061,6 +3126,19 @@ int kvm_cpu_exec(CPUState *cpu) - break; - } - break; -+ case KVM_EXIT_MEMORY_FAULT: -+ trace_kvm_memory_fault(run->memory_fault.gpa, -+ run->memory_fault.size, -+ run->memory_fault.flags); -+ if (run->memory_fault.flags & ~KVM_MEMORY_EXIT_FLAG_PRIVATE) { -+ error_report("KVM_EXIT_MEMORY_FAULT: Unknown flag 0x%" PRIx64, -+ (uint64_t)run->memory_fault.flags); -+ ret = -1; -+ break; -+ } -+ ret = kvm_convert_memory(run->memory_fault.gpa, run->memory_fault.size, -+ run->memory_fault.flags & KVM_MEMORY_EXIT_FLAG_PRIVATE); -+ break; - default: - ret = kvm_arch_handle_exit(cpu, run); - break; -diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events -index e8c52cb9e7..681ccb667d 100644 ---- a/accel/kvm/trace-events -+++ b/accel/kvm/trace-events -@@ -31,3 +31,5 @@ kvm_cpu_exec(void) "" - kvm_interrupt_exit_request(void) "" - kvm_io_window_exit(void) "" - kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32 -+kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s" -+kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64 -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 9e4ab7ae89..74f23dff9c 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -542,4 +542,6 @@ int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp); - int kvm_set_memory_attributes_private(hwaddr start, uint64_t size); - int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size); - -+int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private); -+ - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-memory-Make-memory-type-private-by-default-if-it.patch b/SOURCES/kvm-kvm-memory-Make-memory-type-private-by-default-if-it.patch deleted file mode 100644 index 8f9756b..0000000 --- a/SOURCES/kvm-kvm-memory-Make-memory-type-private-by-default-if-it.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f9dc55dd179bb534d589af371c5c2a7886bd461e Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 20 Mar 2024 03:39:11 -0500 -Subject: [PATCH 030/100] kvm/memory: Make memory type private by default if it - has guest memfd backend - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [30/91] 5e21edf844b5629ee32c4075843b028561b97ae2 (bonzini/rhel-qemu-kvm) - -KVM side leaves the memory to shared by default, which may incur the -overhead of paging conversion on the first visit of each page. Because -the expectation is that page is likely to private for the VMs that -require private memory (has guest memfd). - -Explicitly set the memory to private when memory region has valid -guest memfd backend. - -Signed-off-by: Xiaoyao Li -Signed-off-by: Michael Roth -Message-ID: <20240320083945.991426-16-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit bd3bcf6962b664ca3bf9c60fdcc4534e8e3d0641) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 5ef55e4dd7..3f99efc8cc 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -1431,6 +1431,16 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, - strerror(-err)); - abort(); - } -+ -+ if (memory_region_has_guest_memfd(mr)) { -+ err = kvm_set_memory_attributes_private(start_addr, slot_size); -+ if (err) { -+ error_report("%s: failed to set memory attribute private: %s", -+ __func__, strerror(-err)); -+ exit(1); -+ } -+ } -+ - start_addr += slot_size; - ram_start_offset += slot_size; - ram += slot_size; --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch b/SOURCES/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch new file mode 100644 index 0000000..b4ed917 --- /dev/null +++ b/SOURCES/kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch @@ -0,0 +1,143 @@ +From 90a18a9e2e585413eba96ab96df4a878f6c405be Mon Sep 17 00:00:00 2001 +From: Ani Sinha +Date: Thu, 8 Aug 2024 17:08:38 +0530 +Subject: [PATCH 3/9] kvm: refactor core virtual machine creation into its own + function + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [2/7] 3db75ee31b109048ef2de5c7f193116ab8c185a7 (peterx/qemu-kvm) + +Refactoring the core logic around KVM_CREATE_VM into its own separate function +so that it can be called from other functions in subsequent patches. There is +no functional change in this patch. + +CC: pbonzini@redhat.com +CC: zhao1.liu@intel.com +Signed-off-by: Ani Sinha +Link: https://lore.kernel.org/r/20240808113838.1697366-1-anisinha@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 67388078da1cf6dac89e5a7c748cca3444d49690) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 89 ++++++++++++++++++++++++++++----------------- + 1 file changed, 56 insertions(+), 33 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index b51441523d..4f96d8b45e 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2385,6 +2385,60 @@ uint32_t kvm_dirty_ring_size(void) + return kvm_state->kvm_dirty_ring_size; + } + ++static int do_kvm_create_vm(MachineState *ms, int type) ++{ ++ KVMState *s; ++ int ret; ++ ++ s = KVM_STATE(ms->accelerator); ++ ++ do { ++ ret = kvm_ioctl(s, KVM_CREATE_VM, type); ++ } while (ret == -EINTR); ++ ++ if (ret < 0) { ++ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); ++ ++#ifdef TARGET_S390X ++ if (ret == -EINVAL) { ++ error_printf("Host kernel setup problem detected." ++ " Please verify:\n"); ++ error_printf("- for kernels supporting the" ++ " switch_amode or user_mode parameters, whether"); ++ error_printf(" user space is running in primary address space\n"); ++ error_printf("- for kernels supporting the vm.allocate_pgste" ++ " sysctl, whether it is enabled\n"); ++ } ++#elif defined(TARGET_PPC) ++ if (ret == -EINVAL) { ++ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", ++ (type == 2) ? "pr" : "hv"); ++ } ++#endif ++ } ++ ++ return ret; ++} ++ ++static int find_kvm_machine_type(MachineState *ms) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(ms); ++ int type; ++ ++ if (object_property_find(OBJECT(current_machine), "kvm-type")) { ++ g_autofree char *kvm_type; ++ kvm_type = object_property_get_str(OBJECT(current_machine), ++ "kvm-type", ++ &error_abort); ++ type = mc->kvm_type(ms, kvm_type); ++ } else if (mc->kvm_type) { ++ type = mc->kvm_type(ms, NULL); ++ } else { ++ type = kvm_arch_get_default_type(ms); ++ } ++ return type; ++} ++ + static int kvm_init(MachineState *ms) + { + MachineClass *mc = MACHINE_GET_CLASS(ms); +@@ -2467,45 +2521,14 @@ static int kvm_init(MachineState *ms) + } + s->as = g_new0(struct KVMAs, s->nr_as); + +- if (object_property_find(OBJECT(current_machine), "kvm-type")) { +- g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine), +- "kvm-type", +- &error_abort); +- type = mc->kvm_type(ms, kvm_type); +- } else if (mc->kvm_type) { +- type = mc->kvm_type(ms, NULL); +- } else { +- type = kvm_arch_get_default_type(ms); +- } +- ++ type = find_kvm_machine_type(ms); + if (type < 0) { + ret = -EINVAL; + goto err; + } + +- do { +- ret = kvm_ioctl(s, KVM_CREATE_VM, type); +- } while (ret == -EINTR); +- ++ ret = do_kvm_create_vm(ms, type); + if (ret < 0) { +- error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); +- +-#ifdef TARGET_S390X +- if (ret == -EINVAL) { +- error_printf("Host kernel setup problem detected." +- " Please verify:\n"); +- error_printf("- for kernels supporting the" +- " switch_amode or user_mode parameters, whether"); +- error_printf(" user space is running in primary address space\n"); +- error_printf("- for kernels supporting the vm.allocate_pgste" +- " sysctl, whether it is enabled\n"); +- } +-#elif defined(TARGET_PPC) +- if (ret == -EINVAL) { +- error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", +- (type == 2) ? "pr" : "hv"); +- } +-#endif + goto err; + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch b/SOURCES/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch new file mode 100644 index 0000000..3ebe06d --- /dev/null +++ b/SOURCES/kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch @@ -0,0 +1,131 @@ +From 66c634c4749d58c0c3644ace27a656c507433288 Mon Sep 17 00:00:00 2001 +From: Ani Sinha +Date: Wed, 28 Aug 2024 18:15:39 +0530 +Subject: [PATCH 2/9] kvm: replace fprintf with error_report()/printf() in + kvm_init() + +RH-Author: Peter Xu +RH-MergeRequest: 284: KVM: Dynamic sized kvm memslots array +RH-Jira: RHEL-57682 +RH-Acked-by: Juraj Marcin +RH-Commit: [1/7] 3dd0b67d3b6662001eb35201ca41b15d0dd97994 (peterx/qemu-kvm) + +error_report() is more appropriate for error situations. Replace fprintf with +error_report() and error_printf() as appropriate. Some improvement in error +reporting also happens as a part of this change. For example: + +From: +$ ./qemu-system-x86_64 --accel kvm +Could not access KVM kernel module: No such file or directory + +To: +$ ./qemu-system-x86_64 --accel kvm +qemu-system-x86_64: --accel kvm: Could not access KVM kernel module: No such file or directory + +CC: qemu-trivial@nongnu.org +CC: zhao1.liu@intel.com +CC: armbru@redhat.com +Reviewed-by: Zhao Liu +Reviewed-by: Markus Armbruster +Signed-off-by: Ani Sinha +Link: https://lore.kernel.org/r/20240828124539.62672-1-anisinha@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 804dfbe3ef5e950328b162ae85741be2e228544f) +Signed-off-by: Peter Xu +--- + accel/kvm/kvm-all.c | 40 ++++++++++++++++++---------------------- + 1 file changed, 18 insertions(+), 22 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index a220178822..b51441523d 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2427,7 +2427,7 @@ static int kvm_init(MachineState *ms) + QLIST_INIT(&s->kvm_parked_vcpus); + s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR); + if (s->fd == -1) { +- fprintf(stderr, "Could not access KVM kernel module: %m\n"); ++ error_report("Could not access KVM kernel module: %m"); + ret = -errno; + goto err; + } +@@ -2437,13 +2437,13 @@ static int kvm_init(MachineState *ms) + if (ret >= 0) { + ret = -EINVAL; + } +- fprintf(stderr, "kvm version too old\n"); ++ error_report("kvm version too old"); + goto err; + } + + if (ret > KVM_API_VERSION) { + ret = -EINVAL; +- fprintf(stderr, "kvm version not supported\n"); ++ error_report("kvm version not supported"); + goto err; + } + +@@ -2488,26 +2488,22 @@ static int kvm_init(MachineState *ms) + } while (ret == -EINTR); + + if (ret < 0) { +- fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret, +- strerror(-ret)); ++ error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret)); + + #ifdef TARGET_S390X + if (ret == -EINVAL) { +- fprintf(stderr, +- "Host kernel setup problem detected. Please verify:\n"); +- fprintf(stderr, "- for kernels supporting the switch_amode or" +- " user_mode parameters, whether\n"); +- fprintf(stderr, +- " user space is running in primary address space\n"); +- fprintf(stderr, +- "- for kernels supporting the vm.allocate_pgste sysctl, " +- "whether it is enabled\n"); ++ error_printf("Host kernel setup problem detected." ++ " Please verify:\n"); ++ error_printf("- for kernels supporting the" ++ " switch_amode or user_mode parameters, whether"); ++ error_printf(" user space is running in primary address space\n"); ++ error_printf("- for kernels supporting the vm.allocate_pgste" ++ " sysctl, whether it is enabled\n"); + } + #elif defined(TARGET_PPC) + if (ret == -EINVAL) { +- fprintf(stderr, +- "PPC KVM module is not loaded. Try modprobe kvm_%s.\n", +- (type == 2) ? "pr" : "hv"); ++ error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n", ++ (type == 2) ? "pr" : "hv"); + } + #endif + goto err; +@@ -2526,9 +2522,9 @@ static int kvm_init(MachineState *ms) + nc->name, nc->num, soft_vcpus_limit); + + if (nc->num > hard_vcpus_limit) { +- fprintf(stderr, "Number of %s cpus requested (%d) exceeds " +- "the maximum cpus supported by KVM (%d)\n", +- nc->name, nc->num, hard_vcpus_limit); ++ error_report("Number of %s cpus requested (%d) exceeds " ++ "the maximum cpus supported by KVM (%d)", ++ nc->name, nc->num, hard_vcpus_limit); + exit(1); + } + } +@@ -2542,8 +2538,8 @@ static int kvm_init(MachineState *ms) + } + if (missing_cap) { + ret = -EINVAL; +- fprintf(stderr, "kvm does not support %s\n%s", +- missing_cap->name, upgrade_note); ++ error_report("kvm does not support %s", missing_cap->name); ++ error_printf("%s", upgrade_note); + goto err; + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-kvm-tdx-Don-t-complain-when-converting-vMMIO-region-.patch b/SOURCES/kvm-kvm-tdx-Don-t-complain-when-converting-vMMIO-region-.patch deleted file mode 100644 index 7b578b5..0000000 --- a/SOURCES/kvm-kvm-tdx-Don-t-complain-when-converting-vMMIO-region-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From aeaa7061139202448d466b7e18682081f9cd2097 Mon Sep 17 00:00:00 2001 -From: Isaku Yamahata -Date: Thu, 29 Feb 2024 01:36:54 -0500 -Subject: [PATCH 035/100] kvm/tdx: Don't complain when converting vMMIO region - to shared - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [35/91] c42870771d7af5badc2e10d42be9b5620d72f95d (bonzini/rhel-qemu-kvm) - -Because vMMIO region needs to be shared region, guest TD may explicitly -convert such region from private to shared. Don't complain such -conversion. - -Signed-off-by: Isaku Yamahata -Signed-off-by: Xiaoyao Li -Message-ID: <20240229063726.610065-34-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit c5d9425ef4da9f43fc0903905ad415456d1ab843) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 09164e346c..6efaff90a7 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2927,9 +2927,22 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private) - } - - if (!memory_region_has_guest_memfd(mr)) { -- error_report("Converting non guest_memfd backed memory region " -- "(0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s", -- start, size, to_private ? "private" : "shared"); -+ /* -+ * Because vMMIO region must be shared, guest TD may convert vMMIO -+ * region to shared explicitly. Don't complain such case. See -+ * memory_region_type() for checking if the region is MMIO region. -+ */ -+ if (!to_private && -+ !memory_region_is_ram(mr) && -+ !memory_region_is_ram_device(mr) && -+ !memory_region_is_rom(mr) && -+ !memory_region_is_romd(mr)) { -+ ret = 0; -+ } else { -+ error_report("Convert non guest_memfd backed memory region " -+ "(0x%"HWADDR_PRIx" ,+ 0x%"HWADDR_PRIx") to %s", -+ start, size, to_private ? "private" : "shared"); -+ } - goto out_unref; - } - --- -2.39.3 - diff --git a/SOURCES/kvm-kvm-tdx-Ignore-memory-conversion-to-shared-of-unassi.patch b/SOURCES/kvm-kvm-tdx-Ignore-memory-conversion-to-shared-of-unassi.patch deleted file mode 100644 index c0f2bc6..0000000 --- a/SOURCES/kvm-kvm-tdx-Ignore-memory-conversion-to-shared-of-unassi.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 2b2dfff3e383c99d0f759a8c12659d1a0ce50e8e Mon Sep 17 00:00:00 2001 -From: Isaku Yamahata -Date: Thu, 29 Feb 2024 01:36:55 -0500 -Subject: [PATCH 036/100] kvm/tdx: Ignore memory conversion to shared of - unassigned region - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [36/91] 84515b9dcfc2e07b272bb2477acf6430e9d33f28 (bonzini/rhel-qemu-kvm) - -TDX requires vMMIO region to be shared. For KVM, MMIO region is the region -which kvm memslot isn't assigned to (except in-kernel emulation). -qemu has the memory region for vMMIO at each device level. - -While OVMF issues MapGPA(to-shared) conservatively on 32bit PCI MMIO -region, qemu doesn't find corresponding vMMIO region because it's before -PCI device allocation and memory_region_find() finds the device region, not -PCI bus region. It's safe to ignore MapGPA(to-shared) because when guest -accesses those region they use GPA with shared bit set for vMMIO. Ignore -memory conversion request of non-assigned region to shared and return -success. Otherwise OVMF is confused and panics there. - -Signed-off-by: Isaku Yamahata -Signed-off-by: Xiaoyao Li -Message-ID: <20240229063726.610065-35-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 565f4768bb9cf840b2f8cca41483bb91aa3196a3) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 6efaff90a7..f6268855b4 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2923,6 +2923,18 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private) - section = memory_region_find(get_system_memory(), start, size); - mr = section.mr; - if (!mr) { -+ /* -+ * Ignore converting non-assigned region to shared. -+ * -+ * TDX requires vMMIO region to be shared to inject #VE to guest. -+ * OVMF issues conservatively MapGPA(shared) on 32bit PCI MMIO region, -+ * and vIO-APIC 0xFEC00000 4K page. -+ * OVMF assigns 32bit PCI MMIO region to -+ * [top of low memory: typically 2GB=0xC000000, 0xFC00000) -+ */ -+ if (!to_private) { -+ return 0; -+ } - return -1; - } - --- -2.39.3 - diff --git a/SOURCES/kvm-linux-aio-add-IO_CMD_FDSYNC-command-support.patch b/SOURCES/kvm-linux-aio-add-IO_CMD_FDSYNC-command-support.patch deleted file mode 100644 index 1aba040..0000000 --- a/SOURCES/kvm-linux-aio-add-IO_CMD_FDSYNC-command-support.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 287ebf9f0b8a62dc49fd7802472c1ae57f653e44 Mon Sep 17 00:00:00 2001 -From: Prasad Pandit -Date: Thu, 25 Apr 2024 12:34:12 +0530 -Subject: [PATCH 1/5] linux-aio: add IO_CMD_FDSYNC command support - -RH-Author: Prasad Pandit -RH-MergeRequest: 249: linux-aio: add IO_CMD_FDSYNC command support -RH-Jira: RHEL-42411 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Kevin Wolf -RH-Commit: [1/1] 9beff6506d2eca7741b1c11b5acdc19b635c7c75 (pjp/cs-qemu-kvm) - -Libaio defines IO_CMD_FDSYNC command to sync all outstanding -asynchronous I/O operations, by flushing out file data to the -disk storage. Enable linux-aio to submit such aio request. - -When using aio=native without fdsync() support, QEMU creates -pthreads, and destroying these pthreads results in TLB flushes. -In a real-time guest environment, TLB flushes cause a latency -spike. This patch helps to avoid such spikes. - -Jira: https://issues.redhat.com/browse/RHEL-42411 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Prasad Pandit -Message-ID: <20240425070412.37248-1-ppandit@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 24687abf237e3c15816d689a8e4b08d7c3190dcb) -Signed-off-by: Prasad Pandit ---- - block/file-posix.c | 9 +++++++++ - block/linux-aio.c | 21 ++++++++++++++++++++- - include/block/raw-aio.h | 1 + - 3 files changed, 30 insertions(+), 1 deletion(-) - -diff --git a/block/file-posix.c b/block/file-posix.c -index 35684f7e21..9831b08fb6 100644 ---- a/block/file-posix.c -+++ b/block/file-posix.c -@@ -159,6 +159,7 @@ typedef struct BDRVRawState { - bool has_discard:1; - bool has_write_zeroes:1; - bool use_linux_aio:1; -+ bool has_laio_fdsync:1; - bool use_linux_io_uring:1; - int page_cache_inconsistent; /* errno from fdatasync failure */ - bool has_fallocate; -@@ -718,6 +719,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, - ret = -EINVAL; - goto fail; - } -+ if (s->use_linux_aio) { -+ s->has_laio_fdsync = laio_has_fdsync(s->fd); -+ } - #else - if (s->use_linux_aio) { - error_setg(errp, "aio=native was specified, but is not supported " -@@ -2599,6 +2603,11 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) - if (raw_check_linux_io_uring(s)) { - return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH); - } -+#endif -+#ifdef CONFIG_LINUX_AIO -+ if (s->has_laio_fdsync && raw_check_linux_aio(s)) { -+ return laio_co_submit(s->fd, 0, NULL, QEMU_AIO_FLUSH, 0); -+ } - #endif - return raw_thread_pool_submit(handle_aiocb_flush, &acb); - } -diff --git a/block/linux-aio.c b/block/linux-aio.c -index ec05d946f3..e3b5ec9aba 100644 ---- a/block/linux-aio.c -+++ b/block/linux-aio.c -@@ -384,6 +384,9 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset, - case QEMU_AIO_READ: - io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset); - break; -+ case QEMU_AIO_FLUSH: -+ io_prep_fdsync(iocbs, fd); -+ break; - /* Currently Linux kernel does not support other operations */ - default: - fprintf(stderr, "%s: invalid AIO request type 0x%x.\n", -@@ -412,7 +415,7 @@ int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov, - AioContext *ctx = qemu_get_current_aio_context(); - struct qemu_laiocb laiocb = { - .co = qemu_coroutine_self(), -- .nbytes = qiov->size, -+ .nbytes = qiov ? qiov->size : 0, - .ctx = aio_get_linux_aio(ctx), - .ret = -EINPROGRESS, - .is_read = (type == QEMU_AIO_READ), -@@ -486,3 +489,19 @@ void laio_cleanup(LinuxAioState *s) - } - g_free(s); - } -+ -+bool laio_has_fdsync(int fd) -+{ -+ struct iocb cb; -+ struct iocb *cbs[] = {&cb, NULL}; -+ -+ io_context_t ctx = 0; -+ io_setup(1, &ctx); -+ -+ /* check if host kernel supports IO_CMD_FDSYNC */ -+ io_prep_fdsync(&cb, fd); -+ int ret = io_submit(ctx, 1, cbs); -+ -+ io_destroy(ctx); -+ return (ret == -EINVAL) ? false : true; -+} -diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h -index 20e000b8ef..626706827f 100644 ---- a/include/block/raw-aio.h -+++ b/include/block/raw-aio.h -@@ -60,6 +60,7 @@ void laio_cleanup(LinuxAioState *s); - int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov, - int type, uint64_t dev_max_batch); - -+bool laio_has_fdsync(int); - void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context); - void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context); - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch b/SOURCES/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch new file mode 100644 index 0000000..e5f0642 --- /dev/null +++ b/SOURCES/kvm-linux-headers-Update-to-Linux-6.13-rc1.patch @@ -0,0 +1,1099 @@ +From 1b3ac759d88c02b43c3b649f72f70f8ca6df2fab Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:42 +0100 +Subject: [PATCH 07/19] linux-headers: Update to Linux 6.13-rc1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [7/16] 66249db1edfa93b4b5c2ae8afbb879f59568443c (thuth/qemu-kvm-cs9) + +This linux headers update includes required changes for +the gen17 CPU model. + +Signed-off-by: Hendrik Brueckner +Suggested-by: Thomas Huth +Message-ID: <20241206122751.189721-7-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 44fe383c274174405da79f5fcb028e39fe688036) +--- + include/standard-headers/drm/drm_fourcc.h | 1 + + include/standard-headers/linux/ethtool.h | 5 + + include/standard-headers/linux/pci_regs.h | 38 ++- + .../standard-headers/linux/virtio_crypto.h | 1 + + include/standard-headers/linux/virtio_pci.h | 131 ++++++++++ + linux-headers/asm-arm64/kvm.h | 6 + + linux-headers/asm-arm64/unistd_64.h | 4 + + linux-headers/asm-generic/mman-common.h | 3 + + linux-headers/asm-generic/mman.h | 4 + + linux-headers/asm-generic/unistd.h | 11 +- + linux-headers/asm-loongarch/kvm.h | 20 ++ + linux-headers/asm-loongarch/unistd_64.h | 4 + + linux-headers/asm-mips/mman.h | 3 + + linux-headers/asm-mips/unistd_n32.h | 4 + + linux-headers/asm-mips/unistd_n64.h | 4 + + linux-headers/asm-mips/unistd_o32.h | 4 + + linux-headers/asm-powerpc/unistd_32.h | 4 + + linux-headers/asm-powerpc/unistd_64.h | 4 + + linux-headers/asm-riscv/kvm.h | 4 + + linux-headers/asm-riscv/unistd_32.h | 4 + + linux-headers/asm-riscv/unistd_64.h | 4 + + linux-headers/asm-s390/kvm.h | 3 +- + linux-headers/asm-s390/unistd_32.h | 4 + + linux-headers/asm-s390/unistd_64.h | 4 + + linux-headers/asm-x86/kvm.h | 1 + + linux-headers/asm-x86/mman.h | 3 - + linux-headers/asm-x86/unistd_32.h | 4 + + linux-headers/asm-x86/unistd_64.h | 4 + + linux-headers/asm-x86/unistd_x32.h | 4 + + linux-headers/linux/iommufd.h | 224 +++++++++++++++++- + linux-headers/linux/kvm.h | 8 + + linux-headers/linux/psci.h | 5 + + linux-headers/linux/vfio.h | 2 +- + 33 files changed, 506 insertions(+), 23 deletions(-) + +diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h +index d4a2231306..708647776f 100644 +--- a/include/standard-headers/drm/drm_fourcc.h ++++ b/include/standard-headers/drm/drm_fourcc.h +@@ -1515,6 +1515,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. + */ + #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 ++#define AMD_FMT_MOD_TILE_GFX9_4K_D_X 22 + #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 + #define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26 + #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 +diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h +index b05e84825b..67c47912e5 100644 +--- a/include/standard-headers/linux/ethtool.h ++++ b/include/standard-headers/linux/ethtool.h +@@ -2526,6 +2526,11 @@ struct ethtool_link_settings { + uint8_t master_slave_state; + uint8_t rate_matching; + uint32_t reserved[7]; ++ /* Linux builds with -Wflex-array-member-not-at-end but does ++ * not use the "link_mode_masks" member. Leave it defined for ++ * userspace for now, and when userspace wants to start using ++ * -Wfamnae, we'll need a new solution. ++ */ + uint32_t link_mode_masks[]; + /* layout of link_mode_masks fields: + * uint32_t map_supported[link_mode_masks_nwords]; +diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h +index 12323b3334..1601c7ed5f 100644 +--- a/include/standard-headers/linux/pci_regs.h ++++ b/include/standard-headers/linux/pci_regs.h +@@ -340,7 +340,8 @@ + #define PCI_MSIX_ENTRY_UPPER_ADDR 0x4 /* Message Upper Address */ + #define PCI_MSIX_ENTRY_DATA 0x8 /* Message Data */ + #define PCI_MSIX_ENTRY_VECTOR_CTRL 0xc /* Vector Control */ +-#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 ++#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 /* Mask Bit */ ++#define PCI_MSIX_ENTRY_CTRL_ST 0xffff0000 /* Steering Tag */ + + /* CompactPCI Hotswap Register */ + +@@ -659,6 +660,7 @@ + #define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */ + #define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */ + #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ ++#define PCI_EXP_DEVCAP2_TPH_COMP_MASK 0x00003000 /* TPH completer support */ + #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ + #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ + #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ +@@ -678,6 +680,7 @@ + #define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */ + #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */ + #define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */ ++#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */ + #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ + #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ + #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ +@@ -1023,15 +1026,34 @@ + #define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */ + #define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */ + ++/* TPH Completer Support */ ++#define PCI_EXP_DEVCAP2_TPH_COMP_NONE 0x0 /* None */ ++#define PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY 0x1 /* TPH only */ ++#define PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH 0x3 /* TPH and Extended TPH */ ++ + /* TPH Requester */ + #define PCI_TPH_CAP 4 /* capability register */ +-#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */ +-#define PCI_TPH_LOC_NONE 0x000 /* no location */ +-#define PCI_TPH_LOC_CAP 0x200 /* in capability */ +-#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */ +-#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST table mask */ +-#define PCI_TPH_CAP_ST_SHIFT 16 /* ST table shift */ +-#define PCI_TPH_BASE_SIZEOF 0xc /* size with no ST table */ ++#define PCI_TPH_CAP_ST_NS 0x00000001 /* No ST Mode Supported */ ++#define PCI_TPH_CAP_ST_IV 0x00000002 /* Interrupt Vector Mode Supported */ ++#define PCI_TPH_CAP_ST_DS 0x00000004 /* Device Specific Mode Supported */ ++#define PCI_TPH_CAP_EXT_TPH 0x00000100 /* Ext TPH Requester Supported */ ++#define PCI_TPH_CAP_LOC_MASK 0x00000600 /* ST Table Location */ ++#define PCI_TPH_LOC_NONE 0x00000000 /* Not present */ ++#define PCI_TPH_LOC_CAP 0x00000200 /* In capability */ ++#define PCI_TPH_LOC_MSIX 0x00000400 /* In MSI-X */ ++#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST Table Size */ ++#define PCI_TPH_CAP_ST_SHIFT 16 /* ST Table Size shift */ ++#define PCI_TPH_BASE_SIZEOF 0xc /* Size with no ST table */ ++ ++#define PCI_TPH_CTRL 8 /* control register */ ++#define PCI_TPH_CTRL_MODE_SEL_MASK 0x00000007 /* ST Mode Select */ ++#define PCI_TPH_ST_NS_MODE 0x0 /* No ST Mode */ ++#define PCI_TPH_ST_IV_MODE 0x1 /* Interrupt Vector Mode */ ++#define PCI_TPH_ST_DS_MODE 0x2 /* Device Specific Mode */ ++#define PCI_TPH_CTRL_REQ_EN_MASK 0x00000300 /* TPH Requester Enable */ ++#define PCI_TPH_REQ_DISABLE 0x0 /* No TPH requests allowed */ ++#define PCI_TPH_REQ_TPH_ONLY 0x1 /* TPH only requests allowed */ ++#define PCI_TPH_REQ_EXT_TPH 0x3 /* Extended TPH requests allowed */ + + /* Downstream Port Containment */ + #define PCI_EXP_DPC_CAP 0x04 /* DPC Capability */ +diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h +index 68066dafb6..4d350ae595 100644 +--- a/include/standard-headers/linux/virtio_crypto.h ++++ b/include/standard-headers/linux/virtio_crypto.h +@@ -329,6 +329,7 @@ struct virtio_crypto_op_header { + VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x00) + #define VIRTIO_CRYPTO_AKCIPHER_DECRYPT \ + VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x01) ++ /* akcipher sign/verify opcodes are deprecated */ + #define VIRTIO_CRYPTO_AKCIPHER_SIGN \ + VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x02) + #define VIRTIO_CRYPTO_AKCIPHER_VERIFY \ +diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h +index 4010216103..b177ed8972 100644 +--- a/include/standard-headers/linux/virtio_pci.h ++++ b/include/standard-headers/linux/virtio_pci.h +@@ -40,6 +40,7 @@ + #define _LINUX_VIRTIO_PCI_H + + #include "standard-headers/linux/types.h" ++#include "standard-headers/linux/kernel.h" + + #ifndef VIRTIO_PCI_NO_LEGACY + +@@ -240,6 +241,17 @@ struct virtio_pci_cfg_cap { + #define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5 + #define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6 + ++/* Device parts access commands. */ ++#define VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY 0x7 ++#define VIRTIO_ADMIN_CMD_DEVICE_CAP_GET 0x8 ++#define VIRTIO_ADMIN_CMD_DRIVER_CAP_SET 0x9 ++#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_CREATE 0xa ++#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_DESTROY 0xd ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_GET 0xe ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET 0xf ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_SET 0x10 ++#define VIRTIO_ADMIN_CMD_DEV_MODE_SET 0x11 ++ + struct virtio_admin_cmd_hdr { + uint16_t opcode; + /* +@@ -286,4 +298,123 @@ struct virtio_admin_cmd_notify_info_result { + struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO]; + }; + ++#define VIRTIO_DEV_PARTS_CAP 0x0000 ++ ++struct virtio_dev_parts_cap { ++ uint8_t get_parts_resource_objects_limit; ++ uint8_t set_parts_resource_objects_limit; ++}; ++ ++#define MAX_CAP_ID __KERNEL_DIV_ROUND_UP(VIRTIO_DEV_PARTS_CAP + 1, 64) ++ ++struct virtio_admin_cmd_query_cap_id_result { ++ uint64_t supported_caps[MAX_CAP_ID]; ++}; ++ ++struct virtio_admin_cmd_cap_get_data { ++ uint16_t id; ++ uint8_t reserved[6]; ++}; ++ ++struct virtio_admin_cmd_cap_set_data { ++ uint16_t id; ++ uint8_t reserved[6]; ++ uint8_t cap_specific_data[]; ++}; ++ ++struct virtio_admin_cmd_resource_obj_cmd_hdr { ++ uint16_t type; ++ uint8_t reserved[2]; ++ uint32_t id; /* Indicates unique resource object id per resource object type */ ++}; ++ ++struct virtio_admin_cmd_resource_obj_create_data { ++ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; ++ uint64_t flags; ++ uint8_t resource_obj_specific_data[]; ++}; ++ ++#define VIRTIO_RESOURCE_OBJ_DEV_PARTS 0 ++ ++#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_GET 0 ++#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_SET 1 ++ ++struct virtio_resource_obj_dev_parts { ++ uint8_t type; ++ uint8_t reserved[7]; ++}; ++ ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_SIZE 0 ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_COUNT 1 ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_LIST 2 ++ ++struct virtio_admin_cmd_dev_parts_metadata_data { ++ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; ++ uint8_t type; ++ uint8_t reserved[7]; ++}; ++ ++#define VIRTIO_DEV_PART_F_OPTIONAL 0 ++ ++struct virtio_dev_part_hdr { ++ uint16_t part_type; ++ uint8_t flags; ++ uint8_t reserved; ++ union { ++ struct { ++ uint32_t offset; ++ uint32_t reserved; ++ } pci_common_cfg; ++ struct { ++ uint16_t index; ++ uint8_t reserved[6]; ++ } vq_index; ++ } selector; ++ uint32_t length; ++}; ++ ++struct virtio_dev_part { ++ struct virtio_dev_part_hdr hdr; ++ uint8_t value[]; ++}; ++ ++struct virtio_admin_cmd_dev_parts_metadata_result { ++ union { ++ struct { ++ uint32_t size; ++ uint32_t reserved; ++ } parts_size; ++ struct { ++ uint32_t count; ++ uint32_t reserved; ++ } hdr_list_count; ++ struct { ++ uint32_t count; ++ uint32_t reserved; ++ struct virtio_dev_part_hdr hdrs[]; ++ } hdr_list; ++ }; ++}; ++ ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_SELECTED 0 ++#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_ALL 1 ++ ++struct virtio_admin_cmd_dev_parts_get_data { ++ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; ++ uint8_t type; ++ uint8_t reserved[7]; ++ struct virtio_dev_part_hdr hdr_list[]; ++}; ++ ++struct virtio_admin_cmd_dev_parts_set_data { ++ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; ++ struct virtio_dev_part parts[]; ++}; ++ ++#define VIRTIO_ADMIN_CMD_DEV_MODE_F_STOPPED 0 ++ ++struct virtio_admin_cmd_dev_mode_set_data { ++ uint8_t flags; ++}; ++ + #endif +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index 2af9931ae9..dccd5d965f 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -473,6 +473,12 @@ enum { + */ + #define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0) + ++/* ++ * Shutdown caused by a PSCI v1.3 SYSTEM_OFF2 call. ++ * Valid only when the system event has a type of KVM_SYSTEM_EVENT_SHUTDOWN. ++ */ ++#define KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2 (1ULL << 0) ++ + /* run->fail_entry.hardware_entry_failure_reason codes. */ + #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0) + +diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h +index 99a1d70459..d4e90fff76 100644 +--- a/linux-headers/asm-arm64/unistd_64.h ++++ b/linux-headers/asm-arm64/unistd_64.h +@@ -319,6 +319,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-generic/mman-common.h b/linux-headers/asm-generic/mman-common.h +index 6ce1f1ceb4..1ea2c4c33b 100644 +--- a/linux-headers/asm-generic/mman-common.h ++++ b/linux-headers/asm-generic/mman-common.h +@@ -79,6 +79,9 @@ + + #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ + ++#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ ++#define MADV_GUARD_REMOVE 103 /* unguard range */ ++ + /* compatibility flags */ + #define MAP_FILE 0 + +diff --git a/linux-headers/asm-generic/mman.h b/linux-headers/asm-generic/mman.h +index 57e8195d0b..5e3d61ddbd 100644 +--- a/linux-headers/asm-generic/mman.h ++++ b/linux-headers/asm-generic/mman.h +@@ -19,4 +19,8 @@ + #define MCL_FUTURE 2 /* lock all future mappings */ + #define MCL_ONFAULT 4 /* lock all pages that are faulted in */ + ++#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ ++#define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack marker in the shadow stack */ ++ ++ + #endif /* __ASM_GENERIC_MMAN_H */ +diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h +index 5bf6148cac..88dc393c2b 100644 +--- a/linux-headers/asm-generic/unistd.h ++++ b/linux-headers/asm-generic/unistd.h +@@ -841,8 +841,17 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules) + #define __NR_mseal 462 + __SYSCALL(__NR_mseal, sys_mseal) + ++#define __NR_setxattrat 463 ++__SYSCALL(__NR_setxattrat, sys_setxattrat) ++#define __NR_getxattrat 464 ++__SYSCALL(__NR_getxattrat, sys_getxattrat) ++#define __NR_listxattrat 465 ++__SYSCALL(__NR_listxattrat, sys_listxattrat) ++#define __NR_removexattrat 466 ++__SYSCALL(__NR_removexattrat, sys_removexattrat) ++ + #undef __NR_syscalls +-#define __NR_syscalls 463 ++#define __NR_syscalls 467 + + /* + * 32 bit systems traditionally used different +diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h +index 70d89070bf..5f354f5c68 100644 +--- a/linux-headers/asm-loongarch/kvm.h ++++ b/linux-headers/asm-loongarch/kvm.h +@@ -8,6 +8,8 @@ + + #include + ++#define __KVM_HAVE_IRQ_LINE ++ + /* + * KVM LoongArch specific structures and definitions. + * +@@ -132,4 +134,22 @@ struct kvm_iocsr_entry { + #define KVM_IRQCHIP_NUM_PINS 64 + #define KVM_MAX_CORES 256 + ++#define KVM_DEV_LOONGARCH_IPI_GRP_REGS 0x40000001 ++ ++#define KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS 0x40000002 ++ ++#define KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS 0x40000003 ++#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU 0x0 ++#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE 0x1 ++#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE 0x2 ++ ++#define KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL 0x40000004 ++#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU 0x0 ++#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE 0x1 ++#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED 0x3 ++ ++#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS 0x40000005 ++#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000006 ++#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0 ++ + #endif /* __UAPI_ASM_LOONGARCH_KVM_H */ +diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h +index 887ea50cca..23fb96a8a7 100644 +--- a/linux-headers/asm-loongarch/unistd_64.h ++++ b/linux-headers/asm-loongarch/unistd_64.h +@@ -315,6 +315,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-mips/mman.h b/linux-headers/asm-mips/mman.h +index 9c48d9a21a..b700dae28c 100644 +--- a/linux-headers/asm-mips/mman.h ++++ b/linux-headers/asm-mips/mman.h +@@ -105,6 +105,9 @@ + + #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ + ++#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ ++#define MADV_GUARD_REMOVE 103 /* unguard range */ ++ + /* compatibility flags */ + #define MAP_FILE 0 + +diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h +index fc93b3be30..9a75719644 100644 +--- a/linux-headers/asm-mips/unistd_n32.h ++++ b/linux-headers/asm-mips/unistd_n32.h +@@ -391,5 +391,9 @@ + #define __NR_lsm_set_self_attr (__NR_Linux + 460) + #define __NR_lsm_list_modules (__NR_Linux + 461) + #define __NR_mseal (__NR_Linux + 462) ++#define __NR_setxattrat (__NR_Linux + 463) ++#define __NR_getxattrat (__NR_Linux + 464) ++#define __NR_listxattrat (__NR_Linux + 465) ++#define __NR_removexattrat (__NR_Linux + 466) + + #endif /* _ASM_UNISTD_N32_H */ +diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h +index e72a3eb2c9..7086783b0c 100644 +--- a/linux-headers/asm-mips/unistd_n64.h ++++ b/linux-headers/asm-mips/unistd_n64.h +@@ -367,5 +367,9 @@ + #define __NR_lsm_set_self_attr (__NR_Linux + 460) + #define __NR_lsm_list_modules (__NR_Linux + 461) + #define __NR_mseal (__NR_Linux + 462) ++#define __NR_setxattrat (__NR_Linux + 463) ++#define __NR_getxattrat (__NR_Linux + 464) ++#define __NR_listxattrat (__NR_Linux + 465) ++#define __NR_removexattrat (__NR_Linux + 466) + + #endif /* _ASM_UNISTD_N64_H */ +diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h +index b86eb0786c..b3825823e4 100644 +--- a/linux-headers/asm-mips/unistd_o32.h ++++ b/linux-headers/asm-mips/unistd_o32.h +@@ -437,5 +437,9 @@ + #define __NR_lsm_set_self_attr (__NR_Linux + 460) + #define __NR_lsm_list_modules (__NR_Linux + 461) + #define __NR_mseal (__NR_Linux + 462) ++#define __NR_setxattrat (__NR_Linux + 463) ++#define __NR_getxattrat (__NR_Linux + 464) ++#define __NR_listxattrat (__NR_Linux + 465) ++#define __NR_removexattrat (__NR_Linux + 466) + + #endif /* _ASM_UNISTD_O32_H */ +diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h +index 28627b6546..38ee4dc35d 100644 +--- a/linux-headers/asm-powerpc/unistd_32.h ++++ b/linux-headers/asm-powerpc/unistd_32.h +@@ -444,6 +444,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h +index 1fc42a8300..5e5f156834 100644 +--- a/linux-headers/asm-powerpc/unistd_64.h ++++ b/linux-headers/asm-powerpc/unistd_64.h +@@ -416,6 +416,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h +index e97db32964..3482c9a73d 100644 +--- a/linux-headers/asm-riscv/kvm.h ++++ b/linux-headers/asm-riscv/kvm.h +@@ -175,6 +175,10 @@ enum KVM_RISCV_ISA_EXT_ID { + KVM_RISCV_ISA_EXT_ZCF, + KVM_RISCV_ISA_EXT_ZCMOP, + KVM_RISCV_ISA_EXT_ZAWRS, ++ KVM_RISCV_ISA_EXT_SMNPM, ++ KVM_RISCV_ISA_EXT_SSNPM, ++ KVM_RISCV_ISA_EXT_SVADE, ++ KVM_RISCV_ISA_EXT_SVADU, + KVM_RISCV_ISA_EXT_MAX, + }; + +diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h +index 9625743dfd..74f6127aed 100644 +--- a/linux-headers/asm-riscv/unistd_32.h ++++ b/linux-headers/asm-riscv/unistd_32.h +@@ -310,6 +310,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h +index 95bca8ae81..bb6a15a2ec 100644 +--- a/linux-headers/asm-riscv/unistd_64.h ++++ b/linux-headers/asm-riscv/unistd_64.h +@@ -320,6 +320,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h +index 684c4e1205..ab5a6bce59 100644 +--- a/linux-headers/asm-s390/kvm.h ++++ b/linux-headers/asm-s390/kvm.h +@@ -469,7 +469,8 @@ struct kvm_s390_vm_cpu_subfunc { + __u8 kdsa[16]; /* with MSA9 */ + __u8 sortl[32]; /* with STFLE.150 */ + __u8 dfltcc[32]; /* with STFLE.151 */ +- __u8 reserved[1728]; ++ __u8 pfcr[16]; /* with STFLE.201 */ ++ __u8 reserved[1712]; + }; + + #define KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST 6 +diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h +index 7706c21b87..620201cb36 100644 +--- a/linux-headers/asm-s390/unistd_32.h ++++ b/linux-headers/asm-s390/unistd_32.h +@@ -435,5 +435,9 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + #endif /* _ASM_S390_UNISTD_32_H */ +diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h +index 62082d592d..e7e4a10aaf 100644 +--- a/linux-headers/asm-s390/unistd_64.h ++++ b/linux-headers/asm-s390/unistd_64.h +@@ -383,5 +383,9 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + #endif /* _ASM_S390_UNISTD_64_H */ +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index 4711ef2c3d..96589490c4 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -438,6 +438,7 @@ struct kvm_sync_regs { + #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5) + #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) + #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) ++#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) + + #define KVM_STATE_NESTED_FORMAT_VMX 0 + #define KVM_STATE_NESTED_FORMAT_SVM 1 +diff --git a/linux-headers/asm-x86/mman.h b/linux-headers/asm-x86/mman.h +index 46cdc941f9..ac1e627721 100644 +--- a/linux-headers/asm-x86/mman.h ++++ b/linux-headers/asm-x86/mman.h +@@ -5,9 +5,6 @@ + #define MAP_32BIT 0x40 /* only give out 32bit addresses */ + #define MAP_ABOVE4G 0x80 /* only map above 4GB */ + +-/* Flags for map_shadow_stack(2) */ +-#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ +- + #include + + #endif /* _ASM_X86_MMAN_H */ +diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h +index fb7b8b169b..a2eb492a75 100644 +--- a/linux-headers/asm-x86/unistd_32.h ++++ b/linux-headers/asm-x86/unistd_32.h +@@ -453,6 +453,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h +index 24c979be54..2f5fc400f5 100644 +--- a/linux-headers/asm-x86/unistd_64.h ++++ b/linux-headers/asm-x86/unistd_64.h +@@ -376,6 +376,10 @@ + #define __NR_lsm_set_self_attr 460 + #define __NR_lsm_list_modules 461 + #define __NR_mseal 462 ++#define __NR_setxattrat 463 ++#define __NR_getxattrat 464 ++#define __NR_listxattrat 465 ++#define __NR_removexattrat 466 + + + #endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h +index c23dd21a2d..fecd832e7f 100644 +--- a/linux-headers/asm-x86/unistd_x32.h ++++ b/linux-headers/asm-x86/unistd_x32.h +@@ -329,6 +329,10 @@ + #define __NR_lsm_set_self_attr (__X32_SYSCALL_BIT + 460) + #define __NR_lsm_list_modules (__X32_SYSCALL_BIT + 461) + #define __NR_mseal (__X32_SYSCALL_BIT + 462) ++#define __NR_setxattrat (__X32_SYSCALL_BIT + 463) ++#define __NR_getxattrat (__X32_SYSCALL_BIT + 464) ++#define __NR_listxattrat (__X32_SYSCALL_BIT + 465) ++#define __NR_removexattrat (__X32_SYSCALL_BIT + 466) + #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) + #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) + #define __NR_ioctl (__X32_SYSCALL_BIT + 514) +diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h +index 782baf477f..37aae16502 100644 +--- a/linux-headers/linux/iommufd.h ++++ b/linux-headers/linux/iommufd.h +@@ -51,6 +51,10 @@ enum { + IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c, + IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d, + IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e, ++ IOMMUFD_CMD_IOAS_MAP_FILE = 0x8f, ++ IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, ++ IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, ++ IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, + }; + + /** +@@ -213,6 +217,30 @@ struct iommu_ioas_map { + }; + #define IOMMU_IOAS_MAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP) + ++/** ++ * struct iommu_ioas_map_file - ioctl(IOMMU_IOAS_MAP_FILE) ++ * @size: sizeof(struct iommu_ioas_map_file) ++ * @flags: same as for iommu_ioas_map ++ * @ioas_id: same as for iommu_ioas_map ++ * @fd: the memfd to map ++ * @start: byte offset from start of file to map from ++ * @length: same as for iommu_ioas_map ++ * @iova: same as for iommu_ioas_map ++ * ++ * Set an IOVA mapping from a memfd file. All other arguments and semantics ++ * match those of IOMMU_IOAS_MAP. ++ */ ++struct iommu_ioas_map_file { ++ __u32 size; ++ __u32 flags; ++ __u32 ioas_id; ++ __s32 fd; ++ __aligned_u64 start; ++ __aligned_u64 length; ++ __aligned_u64 iova; ++}; ++#define IOMMU_IOAS_MAP_FILE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP_FILE) ++ + /** + * struct iommu_ioas_copy - ioctl(IOMMU_IOAS_COPY) + * @size: sizeof(struct iommu_ioas_copy) +@@ -359,11 +387,19 @@ struct iommu_vfio_ioas { + * enforced on device attachment + * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is + * valid. ++ * @IOMMU_HWPT_ALLOC_PASID: Requests a domain that can be used with PASID. The ++ * domain can be attached to any PASID on the device. ++ * Any domain attached to the non-PASID part of the ++ * device must also be flaged, otherwise attaching a ++ * PASID will blocked. ++ * If IOMMU does not support PASID it will return ++ * error (-EOPNOTSUPP). + */ + enum iommufd_hwpt_alloc_flags { + IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, + IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, + IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, ++ IOMMU_HWPT_ALLOC_PASID = 1 << 3, + }; + + /** +@@ -394,14 +430,36 @@ struct iommu_hwpt_vtd_s1 { + __u32 __reserved; + }; + ++/** ++ * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 nested STE ++ * (IOMMU_HWPT_DATA_ARM_SMMUV3) ++ * ++ * @ste: The first two double words of the user space Stream Table Entry for ++ * the translation. Must be little-endian. ++ * Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec) ++ * - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax ++ * - word-1: EATS, S1DSS, S1CIR, S1COR, S1CSH, S1STALLD ++ * ++ * -EIO will be returned if @ste is not legal or contains any non-allowed field. ++ * Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass ++ * nested domain will translate the same as the nesting parent. The S1 will ++ * install a Context Descriptor Table pointing at userspace memory translated ++ * by the nesting parent. ++ */ ++struct iommu_hwpt_arm_smmuv3 { ++ __aligned_le64 ste[2]; ++}; ++ + /** + * enum iommu_hwpt_data_type - IOMMU HWPT Data Type + * @IOMMU_HWPT_DATA_NONE: no data + * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table ++ * @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table + */ + enum iommu_hwpt_data_type { + IOMMU_HWPT_DATA_NONE = 0, + IOMMU_HWPT_DATA_VTD_S1 = 1, ++ IOMMU_HWPT_DATA_ARM_SMMUV3 = 2, + }; + + /** +@@ -409,7 +467,7 @@ enum iommu_hwpt_data_type { + * @size: sizeof(struct iommu_hwpt_alloc) + * @flags: Combination of enum iommufd_hwpt_alloc_flags + * @dev_id: The device to allocate this HWPT for +- * @pt_id: The IOAS or HWPT to connect this HWPT to ++ * @pt_id: The IOAS or HWPT or vIOMMU to connect this HWPT to + * @out_hwpt_id: The ID of the new HWPT + * @__reserved: Must be 0 + * @data_type: One of enum iommu_hwpt_data_type +@@ -428,11 +486,13 @@ enum iommu_hwpt_data_type { + * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a + * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags. + * +- * A user-managed nested HWPT will be created from a given parent HWPT via +- * @pt_id, in which the parent HWPT must be allocated previously via the +- * same ioctl from a given IOAS (@pt_id). In this case, the @data_type +- * must be set to a pre-defined type corresponding to an I/O page table +- * type supported by the underlying IOMMU hardware. ++ * A user-managed nested HWPT will be created from a given vIOMMU (wrapping a ++ * parent HWPT) or a parent HWPT via @pt_id, in which the parent HWPT must be ++ * allocated previously via the same ioctl from a given IOAS (@pt_id). In this ++ * case, the @data_type must be set to a pre-defined type corresponding to an ++ * I/O page table type supported by the underlying IOMMU hardware. The device ++ * via @dev_id and the vIOMMU via @pt_id must be associated to the same IOMMU ++ * instance. + * + * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and + * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr +@@ -484,15 +544,50 @@ struct iommu_hw_info_vtd { + __aligned_u64 ecap_reg; + }; + ++/** ++ * struct iommu_hw_info_arm_smmuv3 - ARM SMMUv3 hardware information ++ * (IOMMU_HW_INFO_TYPE_ARM_SMMUV3) ++ * ++ * @flags: Must be set to 0 ++ * @__reserved: Must be 0 ++ * @idr: Implemented features for ARM SMMU Non-secure programming interface ++ * @iidr: Information about the implementation and implementer of ARM SMMU, ++ * and architecture version supported ++ * @aidr: ARM SMMU architecture version ++ * ++ * For the details of @idr, @iidr and @aidr, please refer to the chapters ++ * from 6.3.1 to 6.3.6 in the SMMUv3 Spec. ++ * ++ * User space should read the underlying ARM SMMUv3 hardware information for ++ * the list of supported features. ++ * ++ * Note that these values reflect the raw HW capability, without any insight if ++ * any required kernel driver support is present. Bits may be set indicating the ++ * HW has functionality that is lacking kernel software support, such as BTM. If ++ * a VMM is using this information to construct emulated copies of these ++ * registers it should only forward bits that it knows it can support. ++ * ++ * In future, presence of required kernel support will be indicated in flags. ++ */ ++struct iommu_hw_info_arm_smmuv3 { ++ __u32 flags; ++ __u32 __reserved; ++ __u32 idr[6]; ++ __u32 iidr; ++ __u32 aidr; ++}; ++ + /** + * enum iommu_hw_info_type - IOMMU Hardware Info Types + * @IOMMU_HW_INFO_TYPE_NONE: Used by the drivers that do not report hardware + * info + * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type ++ * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type + */ + enum iommu_hw_info_type { + IOMMU_HW_INFO_TYPE_NONE = 0, + IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, ++ IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, + }; + + /** +@@ -627,9 +722,11 @@ struct iommu_hwpt_get_dirty_bitmap { + * enum iommu_hwpt_invalidate_data_type - IOMMU HWPT Cache Invalidation + * Data Type + * @IOMMU_HWPT_INVALIDATE_DATA_VTD_S1: Invalidation data for VTD_S1 ++ * @IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3: Invalidation data for ARM SMMUv3 + */ + enum iommu_hwpt_invalidate_data_type { + IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0, ++ IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3 = 1, + }; + + /** +@@ -668,10 +765,32 @@ struct iommu_hwpt_vtd_s1_invalidate { + __u32 __reserved; + }; + ++/** ++ * struct iommu_viommu_arm_smmuv3_invalidate - ARM SMMUv3 cahce invalidation ++ * (IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3) ++ * @cmd: 128-bit cache invalidation command that runs in SMMU CMDQ. ++ * Must be little-endian. ++ * ++ * Supported command list only when passing in a vIOMMU via @hwpt_id: ++ * CMDQ_OP_TLBI_NSNH_ALL ++ * CMDQ_OP_TLBI_NH_VA ++ * CMDQ_OP_TLBI_NH_VAA ++ * CMDQ_OP_TLBI_NH_ALL ++ * CMDQ_OP_TLBI_NH_ASID ++ * CMDQ_OP_ATC_INV ++ * CMDQ_OP_CFGI_CD ++ * CMDQ_OP_CFGI_CD_ALL ++ * ++ * -EIO will be returned if the command is not supported. ++ */ ++struct iommu_viommu_arm_smmuv3_invalidate { ++ __aligned_le64 cmd[2]; ++}; ++ + /** + * struct iommu_hwpt_invalidate - ioctl(IOMMU_HWPT_INVALIDATE) + * @size: sizeof(struct iommu_hwpt_invalidate) +- * @hwpt_id: ID of a nested HWPT for cache invalidation ++ * @hwpt_id: ID of a nested HWPT or a vIOMMU, for cache invalidation + * @data_uptr: User pointer to an array of driver-specific cache invalidation + * data. + * @data_type: One of enum iommu_hwpt_invalidate_data_type, defining the data +@@ -682,8 +801,11 @@ struct iommu_hwpt_vtd_s1_invalidate { + * Output the number of requests successfully handled by kernel. + * @__reserved: Must be 0. + * +- * Invalidate the iommu cache for user-managed page table. Modifications on a +- * user-managed page table should be followed by this operation to sync cache. ++ * Invalidate iommu cache for user-managed page table or vIOMMU. Modifications ++ * on a user-managed page table should be followed by this operation, if a HWPT ++ * is passed in via @hwpt_id. Other caches, such as device cache or descriptor ++ * cache can be flushed if a vIOMMU is passed in via the @hwpt_id field. ++ * + * Each ioctl can support one or more cache invalidation requests in the array + * that has a total size of @entry_len * @entry_num. + * +@@ -797,4 +919,88 @@ struct iommu_fault_alloc { + __u32 out_fault_fd; + }; + #define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC) ++ ++/** ++ * enum iommu_viommu_type - Virtual IOMMU Type ++ * @IOMMU_VIOMMU_TYPE_DEFAULT: Reserved for future use ++ * @IOMMU_VIOMMU_TYPE_ARM_SMMUV3: ARM SMMUv3 driver specific type ++ */ ++enum iommu_viommu_type { ++ IOMMU_VIOMMU_TYPE_DEFAULT = 0, ++ IOMMU_VIOMMU_TYPE_ARM_SMMUV3 = 1, ++}; ++ ++/** ++ * struct iommu_viommu_alloc - ioctl(IOMMU_VIOMMU_ALLOC) ++ * @size: sizeof(struct iommu_viommu_alloc) ++ * @flags: Must be 0 ++ * @type: Type of the virtual IOMMU. Must be defined in enum iommu_viommu_type ++ * @dev_id: The device's physical IOMMU will be used to back the virtual IOMMU ++ * @hwpt_id: ID of a nesting parent HWPT to associate to ++ * @out_viommu_id: Output virtual IOMMU ID for the allocated object ++ * ++ * Allocate a virtual IOMMU object, representing the underlying physical IOMMU's ++ * virtualization support that is a security-isolated slice of the real IOMMU HW ++ * that is unique to a specific VM. Operations global to the IOMMU are connected ++ * to the vIOMMU, such as: ++ * - Security namespace for guest owned ID, e.g. guest-controlled cache tags ++ * - Non-device-affiliated event reporting, e.g. invalidation queue errors ++ * - Access to a sharable nesting parent pagetable across physical IOMMUs ++ * - Virtualization of various platforms IDs, e.g. RIDs and others ++ * - Delivery of paravirtualized invalidation ++ * - Direct assigned invalidation queues ++ * - Direct assigned interrupts ++ */ ++struct iommu_viommu_alloc { ++ __u32 size; ++ __u32 flags; ++ __u32 type; ++ __u32 dev_id; ++ __u32 hwpt_id; ++ __u32 out_viommu_id; ++}; ++#define IOMMU_VIOMMU_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIOMMU_ALLOC) ++ ++/** ++ * struct iommu_vdevice_alloc - ioctl(IOMMU_VDEVICE_ALLOC) ++ * @size: sizeof(struct iommu_vdevice_alloc) ++ * @viommu_id: vIOMMU ID to associate with the virtual device ++ * @dev_id: The physical device to allocate a virtual instance on the vIOMMU ++ * @out_vdevice_id: Object handle for the vDevice. Pass to IOMMU_DESTORY ++ * @virt_id: Virtual device ID per vIOMMU, e.g. vSID of ARM SMMUv3, vDeviceID ++ * of AMD IOMMU, and vRID of a nested Intel VT-d to a Context Table ++ * ++ * Allocate a virtual device instance (for a physical device) against a vIOMMU. ++ * This instance holds the device's information (related to its vIOMMU) in a VM. ++ */ ++struct iommu_vdevice_alloc { ++ __u32 size; ++ __u32 viommu_id; ++ __u32 dev_id; ++ __u32 out_vdevice_id; ++ __aligned_u64 virt_id; ++}; ++#define IOMMU_VDEVICE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEVICE_ALLOC) ++ ++/** ++ * struct iommu_ioas_change_process - ioctl(VFIO_IOAS_CHANGE_PROCESS) ++ * @size: sizeof(struct iommu_ioas_change_process) ++ * @__reserved: Must be 0 ++ * ++ * This transfers pinned memory counts for every memory map in every IOAS ++ * in the context to the current process. This only supports maps created ++ * with IOMMU_IOAS_MAP_FILE, and returns EINVAL if other maps are present. ++ * If the ioctl returns a failure status, then nothing is changed. ++ * ++ * This API is useful for transferring operation of a device from one process ++ * to another, such as during userland live update. ++ */ ++struct iommu_ioas_change_process { ++ __u32 size; ++ __u32 __reserved; ++}; ++ ++#define IOMMU_IOAS_CHANGE_PROCESS \ ++ _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) ++ + #endif +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 49dd1b30ce..3bcd4eabe3 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1150,7 +1150,15 @@ enum kvm_device_type { + #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME + KVM_DEV_TYPE_RISCV_AIA, + #define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA ++ KVM_DEV_TYPE_LOONGARCH_IPI, ++#define KVM_DEV_TYPE_LOONGARCH_IPI KVM_DEV_TYPE_LOONGARCH_IPI ++ KVM_DEV_TYPE_LOONGARCH_EIOINTC, ++#define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC ++ KVM_DEV_TYPE_LOONGARCH_PCHPIC, ++#define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC ++ + KVM_DEV_TYPE_MAX, ++ + }; + + struct kvm_vfio_spapr_tce { +diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h +index 74f3cb5007..a982afd498 100644 +--- a/linux-headers/linux/psci.h ++++ b/linux-headers/linux/psci.h +@@ -59,6 +59,7 @@ + #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) + #define PSCI_1_1_FN_MEM_PROTECT PSCI_0_2_FN(19) + #define PSCI_1_1_FN_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN(20) ++#define PSCI_1_3_FN_SYSTEM_OFF2 PSCI_0_2_FN(21) + + #define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) + #define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) +@@ -68,6 +69,7 @@ + + #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) + #define PSCI_1_1_FN64_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN64(20) ++#define PSCI_1_3_FN64_SYSTEM_OFF2 PSCI_0_2_FN64(21) + + /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ + #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff +@@ -100,6 +102,9 @@ + #define PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET 0 + #define PSCI_1_1_RESET_TYPE_VENDOR_START 0x80000000U + ++/* PSCI v1.3 hibernate type for SYSTEM_OFF2 */ ++#define PSCI_1_3_OFF_TYPE_HIBERNATE_OFF BIT(0) ++ + /* PSCI version decoding (independent of PSCI version) */ + #define PSCI_VERSION_MAJOR_SHIFT 16 + #define PSCI_VERSION_MINOR_MASK \ +diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h +index b4be37b225..1b5e254d6a 100644 +--- a/linux-headers/linux/vfio.h ++++ b/linux-headers/linux/vfio.h +@@ -35,7 +35,7 @@ + #define VFIO_EEH 5 + + /* Two-stage IOMMU */ +-#define VFIO_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ ++#define __VFIO_RESERVED_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ + + #define VFIO_SPAPR_TCE_v2_IOMMU 7 + +-- +2.39.3 + diff --git a/SOURCES/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch b/SOURCES/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch new file mode 100644 index 0000000..5dcd477 --- /dev/null +++ b/SOURCES/kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch @@ -0,0 +1,2559 @@ +From cec04b18c1f11b527df9d80148e3dda9d6d24997 Mon Sep 17 00:00:00 2001 +From: Bibo Mao +Date: Mon, 28 Oct 2024 10:38:09 +0800 +Subject: [PATCH 01/19] linux-headers: Update to Linux v6.12-rc5 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [1/16] c6470d080ff4bea31d04d40220bda9854610bf6b (thuth/qemu-kvm-cs9) + +update linux-headers to v6.12-rc5. Pass to compile on aarch64, arm, +loongarch64, x86_64, i386, riscv64,riscv32 softmmu and linux-user. + +Signed-off-by: Bibo Mao +Acked-by: Song Gao +Message-Id: <20241028023809.1554405-4-maobibo@loongson.cn> +Signed-off-by: Song Gao +(cherry picked from commit 0d2eeef77a33315187df8519491a900bde4a3d83) +Signed-off-by: Thomas Huth +--- + include/standard-headers/drm/drm_fourcc.h | 43 +++ + include/standard-headers/linux/const.h | 17 + + include/standard-headers/linux/ethtool.h | 226 ++++++++++++ + include/standard-headers/linux/fuse.h | 22 +- + .../linux/input-event-codes.h | 2 + + include/standard-headers/linux/pci_regs.h | 41 ++- + .../standard-headers/linux/virtio_balloon.h | 16 +- + include/standard-headers/linux/virtio_gpu.h | 1 + + linux-headers/asm-arm64/mman.h | 9 + + linux-headers/asm-arm64/unistd.h | 25 +- + linux-headers/asm-arm64/unistd_64.h | 324 +++++++++++++++++ + linux-headers/asm-generic/unistd.h | 6 +- + linux-headers/asm-loongarch/kvm.h | 24 ++ + linux-headers/asm-loongarch/kvm_para.h | 21 ++ + linux-headers/asm-loongarch/unistd.h | 4 +- + linux-headers/asm-loongarch/unistd_64.h | 320 +++++++++++++++++ + linux-headers/asm-riscv/kvm.h | 7 + + linux-headers/asm-riscv/unistd.h | 41 +-- + linux-headers/asm-riscv/unistd_32.h | 315 +++++++++++++++++ + linux-headers/asm-riscv/unistd_64.h | 325 ++++++++++++++++++ + linux-headers/asm-x86/kvm.h | 2 + + linux-headers/asm-x86/unistd_64.h | 1 + + linux-headers/asm-x86/unistd_x32.h | 1 + + linux-headers/linux/bits.h | 3 + + linux-headers/linux/const.h | 17 + + linux-headers/linux/iommufd.h | 143 +++++++- + linux-headers/linux/kvm.h | 23 +- + linux-headers/linux/mman.h | 1 + + linux-headers/linux/psp-sev.h | 28 ++ + 29 files changed, 1915 insertions(+), 93 deletions(-) + create mode 100644 linux-headers/asm-arm64/unistd_64.h + create mode 100644 linux-headers/asm-loongarch/kvm_para.h + create mode 100644 linux-headers/asm-loongarch/unistd_64.h + create mode 100644 linux-headers/asm-riscv/unistd_32.h + create mode 100644 linux-headers/asm-riscv/unistd_64.h + +diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h +index b72917073d..d4a2231306 100644 +--- a/include/standard-headers/drm/drm_fourcc.h ++++ b/include/standard-headers/drm/drm_fourcc.h +@@ -701,6 +701,31 @@ extern "C" { + */ + #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) + ++/* ++ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression ++ * on integrated graphics ++ * ++ * The main surface is Tile 4 and at plane index 0. For semi-planar formats ++ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices ++ * 0 and 1, respectively. The CCS for all planes are stored outside of the ++ * GEM object in a reserved memory area dedicated for the storage of the ++ * CCS data for all compressible GEM objects. ++ */ ++#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16) ++ ++/* ++ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression ++ * on discrete graphics ++ * ++ * The main surface is Tile 4 and at plane index 0. For semi-planar formats ++ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices ++ * 0 and 1, respectively. The CCS for all planes are stored outside of the ++ * GEM object in a reserved memory area dedicated for the storage of the ++ * CCS data for all compressible GEM objects. The GEM object must be stored in ++ * contiguous memory with a size aligned to 64KB ++ */ ++#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17) ++ + /* + * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks + * +@@ -1475,6 +1500,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + #define AMD_FMT_MOD_TILE_VER_GFX10 2 + #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 + #define AMD_FMT_MOD_TILE_VER_GFX11 4 ++#define AMD_FMT_MOD_TILE_VER_GFX12 5 + + /* + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical +@@ -1485,6 +1511,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + /* + * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has + * GFX9 as canonical version. ++ * ++ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. + */ + #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 + #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 +@@ -1492,6 +1520,21 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) + #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 + #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 + ++/* Gfx12 swizzle modes: ++ * 0 - LINEAR ++ * 1 - 256B_2D - 2D block dimensions ++ * 2 - 4KB_2D ++ * 3 - 64KB_2D ++ * 4 - 256KB_2D ++ * 5 - 4KB_3D - 3D block dimensions ++ * 6 - 64KB_3D ++ * 7 - 256KB_3D ++ */ ++#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 ++#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 ++#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 ++#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 ++ + #define AMD_FMT_MOD_DCC_BLOCK_64B 0 + #define AMD_FMT_MOD_DCC_BLOCK_128B 1 + #define AMD_FMT_MOD_DCC_BLOCK_256B 2 +diff --git a/include/standard-headers/linux/const.h b/include/standard-headers/linux/const.h +index 1eb84b5087..2122610de7 100644 +--- a/include/standard-headers/linux/const.h ++++ b/include/standard-headers/linux/const.h +@@ -28,6 +28,23 @@ + #define _BITUL(x) (_UL(1) << (x)) + #define _BITULL(x) (_ULL(1) << (x)) + ++#if !defined(__ASSEMBLY__) ++/* ++ * Missing __asm__ support ++ * ++ * __BIT128() would not work in the __asm__ code, as it shifts an ++ * 'unsigned __init128' data type as direct representation of ++ * 128 bit constants is not supported in the gcc compiler, as ++ * they get silently truncated. ++ * ++ * TODO: Please revisit this implementation when gcc compiler ++ * starts representing 128 bit constants directly like long ++ * and unsigned long etc. Subsequently drop the comment for ++ * GENMASK_U128() which would then start supporting __asm__ code. ++ */ ++#define _BIT128(x) ((unsigned __int128)(1) << (x)) ++#endif ++ + #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) + #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) + +diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h +index b0b4b68410..b05e84825b 100644 +--- a/include/standard-headers/linux/ethtool.h ++++ b/include/standard-headers/linux/ethtool.h +@@ -752,6 +752,197 @@ enum ethtool_module_power_mode { + ETHTOOL_MODULE_POWER_MODE_HIGH, + }; + ++/** ++ * enum ethtool_c33_pse_ext_state - groups of PSE extended states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION: Group of error_condition states ++ * @ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID: Group of mr_mps_valid states ++ * @ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE: Group of mr_pse_enable states ++ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED: Group of option_detect_ted ++ * states ++ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM: Group of option_vport_lim states ++ * @ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED: Group of ovld_detected states ++ * @ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE: Group of pd_dll_power_type ++ * states ++ * @ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE: Group of power_not_available ++ * states ++ * @ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED: Group of short_detected states ++ */ ++enum ethtool_c33_pse_ext_state { ++ ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION = 1, ++ ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID, ++ ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE, ++ ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED, ++ ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM, ++ ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED, ++ ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE, ++ ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE, ++ ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_mr_mps_valid - mr_mps_valid states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD: Underload ++ * state ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN: Port is not ++ * connected ++ * ++ * The PSE monitors either the DC or AC Maintain Power Signature ++ * (MPS, see 33.2.9.1). This variable indicates the presence or absence of ++ * a valid MPS. ++ */ ++enum ethtool_c33_pse_ext_substate_mr_mps_valid { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD = 1, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_error_condition - error_condition states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT: Non-existing ++ * port number ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT: Undefined port ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT: Internal ++ * hardware fault ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON: ++ * Communication error after force on ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS: Unknown ++ * port status ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF: Host ++ * crash turn off ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN: ++ * Host crash force shutdown ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE: Configuration ++ * change ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP: Over ++ * temperature detected ++ * ++ * error_condition is a variable indicating the status of ++ * implementation-specific fault conditions or optionally other system faults ++ * that prevent the PSE from meeting the specifications in Table 33–11 and that ++ * require the PSE not to source power. These error conditions are different ++ * from those monitored by the state diagrams in Figure 33–10. ++ */ ++enum ethtool_c33_pse_ext_substate_error_condition { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT = 1, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_mr_pse_enable - mr_pse_enable states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE: Disable ++ * pin active ++ * ++ * mr_pse_enable is control variable that selects PSE operation and test ++ * functions. ++ */ ++enum ethtool_c33_pse_ext_substate_mr_pse_enable { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE = 1, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_option_detect_ted - option_detect_ted ++ * states functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS: Detection ++ * in process ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR: ++ * Connection check error ++ * ++ * option_detect_ted is a variable indicating if detection can be performed ++ * by the PSE during the ted_timer interval. ++ */ ++enum ethtool_c33_pse_ext_substate_option_detect_ted { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS = 1, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_option_vport_lim - option_vport_lim states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE: Main supply ++ * voltage is high ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE: Main supply ++ * voltage is low ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION: Voltage ++ * injection into the port ++ * ++ * option_vport_lim is an optional variable indicates if VPSE is out of the ++ * operating range during normal operating state. ++ */ ++enum ethtool_c33_pse_ext_substate_option_vport_lim { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE = 1, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_ovld_detected - ovld_detected states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD: Overload state ++ * ++ * ovld_detected is a variable indicating if the PSE output current has been ++ * in an overload condition (see 33.2.7.6) for at least TCUT of a one-second ++ * sliding time. ++ */ ++enum ethtool_c33_pse_ext_substate_ovld_detected { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD = 1, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_power_not_available - power_not_available ++ * states functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED: Power ++ * budget exceeded for the controller ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET: ++ * Configured port power limit exceeded controller power budget ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT: ++ * Power request from PD exceeds port limit ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT: Power ++ * denied due to Hardware power limit ++ * ++ * power_not_available is a variable that is asserted in an ++ * implementation-dependent manner when the PSE is no longer capable of ++ * sourcing sufficient power to support the attached PD. Sufficient power ++ * is defined by classification; see 33.2.6. ++ */ ++enum ethtool_c33_pse_ext_substate_power_not_available { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED = 1, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT, ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT, ++}; ++ ++/** ++ * enum ethtool_c33_pse_ext_substate_short_detected - short_detected states ++ * functions. IEEE 802.3-2022 33.2.4.4 Variables ++ * ++ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION: Short ++ * condition was detected ++ * ++ * short_detected is a variable indicating if the PSE output current has been ++ * in a short circuit condition for TLIM within a sliding window (see 33.2.7.7). ++ */ ++enum ethtool_c33_pse_ext_substate_short_detected { ++ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION = 1, ++}; ++ + /** + * enum ethtool_pse_types - Types of PSE controller. + * @ETHTOOL_PSE_UNKNOWN: Type of PSE controller is unknown +@@ -877,6 +1068,24 @@ enum ethtool_mm_verify_status { + ETHTOOL_MM_VERIFY_STATUS_DISABLED, + }; + ++/** ++ * enum ethtool_module_fw_flash_status - plug-in module firmware flashing status ++ * @ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED: The firmware flashing process has ++ * started. ++ * @ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS: The firmware flashing process ++ * is in progress. ++ * @ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED: The firmware flashing process was ++ * completed successfully. ++ * @ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR: The firmware flashing process was ++ * stopped due to an error. ++ */ ++enum ethtool_module_fw_flash_status { ++ ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED = 1, ++ ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS, ++ ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED, ++ ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR, ++}; ++ + /** + * struct ethtool_gstrings - string set for data tagging + * @cmd: Command number = %ETHTOOL_GSTRINGS +@@ -1845,6 +2054,7 @@ enum ethtool_link_mode_bit_indices { + ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99, + ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100, + ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101, ++ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT = 102, + + /* must be last entry */ + __ETHTOOL_LINK_MODE_MASK_NBITS +@@ -2323,4 +2533,20 @@ struct ethtool_link_settings { + * uint32_t map_lp_advertising[link_mode_masks_nwords]; + */ + }; ++ ++/** ++ * enum phy_upstream - Represents the upstream component a given PHY device ++ * is connected to, as in what is on the other end of the MII bus. Most PHYs ++ * will be attached to an Ethernet MAC controller, but in some cases, there's ++ * an intermediate PHY used as a media-converter, which will driver another ++ * MII interface as its output. ++ * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port, ++ * or ethernet controller) ++ * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter) ++ */ ++enum phy_upstream { ++ PHY_UPSTREAM_MAC, ++ PHY_UPSTREAM_PHY, ++}; ++ + #endif /* _LINUX_ETHTOOL_H */ +diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h +index bac9dbc49f..889e12ad15 100644 +--- a/include/standard-headers/linux/fuse.h ++++ b/include/standard-headers/linux/fuse.h +@@ -217,6 +217,9 @@ + * - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag + * - add FUSE_NO_EXPORT_SUPPORT init flag + * - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag ++ * ++ * 7.41 ++ * - add FUSE_ALLOW_IDMAP + */ + + #ifndef _LINUX_FUSE_H +@@ -248,7 +251,7 @@ + #define FUSE_KERNEL_VERSION 7 + + /** Minor version number of this interface */ +-#define FUSE_KERNEL_MINOR_VERSION 40 ++#define FUSE_KERNEL_MINOR_VERSION 41 + + /** The node ID of the root inode */ + #define FUSE_ROOT_ID 1 +@@ -417,6 +420,7 @@ struct fuse_file_lock { + * FUSE_NO_EXPORT_SUPPORT: explicitly disable export support + * FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit + * of the request ID indicates resend requests ++ * FUSE_ALLOW_IDMAP: allow creation of idmapped mounts + */ + #define FUSE_ASYNC_READ (1 << 0) + #define FUSE_POSIX_LOCKS (1 << 1) +@@ -462,6 +466,7 @@ struct fuse_file_lock { + + /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ + #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP ++#define FUSE_ALLOW_IDMAP (1ULL << 40) + + /** + * CUSE INIT request/reply flags +@@ -980,6 +985,21 @@ struct fuse_fallocate_in { + */ + #define FUSE_UNIQUE_RESEND (1ULL << 63) + ++/** ++ * This value will be set by the kernel to ++ * (struct fuse_in_header).{uid,gid} fields in ++ * case when: ++ * - fuse daemon enabled FUSE_ALLOW_IDMAP ++ * - idmapping information is not available and uid/gid ++ * can not be mapped in accordance with an idmapping. ++ * ++ * Note: an idmapping information always available ++ * for inode creation operations like: ++ * FUSE_MKNOD, FUSE_SYMLINK, FUSE_MKDIR, FUSE_TMPFILE, ++ * FUSE_CREATE and FUSE_RENAME2 (with RENAME_WHITEOUT). ++ */ ++#define FUSE_INVALID_UIDGID ((uint32_t)(-1)) ++ + struct fuse_in_header { + uint32_t len; + uint32_t opcode; +diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h +index 2221b0c383..50b2b7497e 100644 +--- a/include/standard-headers/linux/input-event-codes.h ++++ b/include/standard-headers/linux/input-event-codes.h +@@ -618,6 +618,8 @@ + #define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */ + #define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */ + #define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */ ++#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */ ++#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/ + + #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ + #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ +diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h +index 94c00996e6..12323b3334 100644 +--- a/include/standard-headers/linux/pci_regs.h ++++ b/include/standard-headers/linux/pci_regs.h +@@ -634,9 +634,11 @@ + #define PCI_EXP_RTCTL_SENFEE 0x0002 /* System Error on Non-Fatal Error */ + #define PCI_EXP_RTCTL_SEFEE 0x0004 /* System Error on Fatal Error */ + #define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */ +-#define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */ ++#define PCI_EXP_RTCTL_RRS_SVE 0x0010 /* Config RRS Software Visibility Enable */ ++#define PCI_EXP_RTCTL_CRSSVE PCI_EXP_RTCTL_RRS_SVE /* compatibility */ + #define PCI_EXP_RTCAP 0x1e /* Root Capabilities */ +-#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ ++#define PCI_EXP_RTCAP_RRS_SV 0x0001 /* Config RRS Software Visibility */ ++#define PCI_EXP_RTCAP_CRSVIS PCI_EXP_RTCAP_RRS_SV /* compatibility */ + #define PCI_EXP_RTSTA 0x20 /* Root Status */ + #define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */ + #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ +@@ -740,6 +742,7 @@ + #define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ + #define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */ + #define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */ ++#define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ + #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ + #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ + #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE +@@ -1121,6 +1124,40 @@ + #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0 + #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4 + ++/* Native PCIe Enclosure Management */ ++#define PCI_NPEM_CAP 0x04 /* NPEM capability register */ ++#define PCI_NPEM_CAP_CAPABLE 0x00000001 /* NPEM Capable */ ++ ++#define PCI_NPEM_CTRL 0x08 /* NPEM control register */ ++#define PCI_NPEM_CTRL_ENABLE 0x00000001 /* NPEM Enable */ ++ ++/* ++ * Native PCIe Enclosure Management indication bits and Reset command bit ++ * are corresponding for capability and control registers. ++ */ ++#define PCI_NPEM_CMD_RESET 0x00000002 /* Reset Command */ ++#define PCI_NPEM_IND_OK 0x00000004 /* OK */ ++#define PCI_NPEM_IND_LOCATE 0x00000008 /* Locate */ ++#define PCI_NPEM_IND_FAIL 0x00000010 /* Fail */ ++#define PCI_NPEM_IND_REBUILD 0x00000020 /* Rebuild */ ++#define PCI_NPEM_IND_PFA 0x00000040 /* Predicted Failure Analysis */ ++#define PCI_NPEM_IND_HOTSPARE 0x00000080 /* Hot Spare */ ++#define PCI_NPEM_IND_ICA 0x00000100 /* In Critical Array */ ++#define PCI_NPEM_IND_IFA 0x00000200 /* In Failed Array */ ++#define PCI_NPEM_IND_IDT 0x00000400 /* Device Type */ ++#define PCI_NPEM_IND_DISABLED 0x00000800 /* Disabled */ ++#define PCI_NPEM_IND_SPEC_0 0x01000000 ++#define PCI_NPEM_IND_SPEC_1 0x02000000 ++#define PCI_NPEM_IND_SPEC_2 0x04000000 ++#define PCI_NPEM_IND_SPEC_3 0x08000000 ++#define PCI_NPEM_IND_SPEC_4 0x10000000 ++#define PCI_NPEM_IND_SPEC_5 0x20000000 ++#define PCI_NPEM_IND_SPEC_6 0x40000000 ++#define PCI_NPEM_IND_SPEC_7 0x80000000 ++ ++#define PCI_NPEM_STATUS 0x0c /* NPEM status register */ ++#define PCI_NPEM_STATUS_CC 0x00000001 /* Command Completed */ ++ + /* Data Object Exchange */ + #define PCI_DOE_CAP 0x04 /* DOE Capabilities Register */ + #define PCI_DOE_CAP_INT_SUP 0x00000001 /* Interrupt Support */ +diff --git a/include/standard-headers/linux/virtio_balloon.h b/include/standard-headers/linux/virtio_balloon.h +index f343bfefd8..3121cd2e0e 100644 +--- a/include/standard-headers/linux/virtio_balloon.h ++++ b/include/standard-headers/linux/virtio_balloon.h +@@ -71,7 +71,13 @@ struct virtio_balloon_config { + #define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */ + #define VIRTIO_BALLOON_S_HTLB_PGALLOC 8 /* Hugetlb page allocations */ + #define VIRTIO_BALLOON_S_HTLB_PGFAIL 9 /* Hugetlb page allocation failures */ +-#define VIRTIO_BALLOON_S_NR 10 ++#define VIRTIO_BALLOON_S_OOM_KILL 10 /* OOM killer invocations */ ++#define VIRTIO_BALLOON_S_ALLOC_STALL 11 /* Stall count of memory allocatoin */ ++#define VIRTIO_BALLOON_S_ASYNC_SCAN 12 /* Amount of memory scanned asynchronously */ ++#define VIRTIO_BALLOON_S_DIRECT_SCAN 13 /* Amount of memory scanned directly */ ++#define VIRTIO_BALLOON_S_ASYNC_RECLAIM 14 /* Amount of memory reclaimed asynchronously */ ++#define VIRTIO_BALLOON_S_DIRECT_RECLAIM 15 /* Amount of memory reclaimed directly */ ++#define VIRTIO_BALLOON_S_NR 16 + + #define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { \ + VIRTIO_BALLOON_S_NAMES_prefix "swap-in", \ +@@ -83,7 +89,13 @@ struct virtio_balloon_config { + VIRTIO_BALLOON_S_NAMES_prefix "available-memory", \ + VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", \ + VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", \ +- VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \ ++ VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "oom-kills", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "alloc-stalls", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "async-scans", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "direct-scans", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "async-reclaims", \ ++ VIRTIO_BALLOON_S_NAMES_prefix "direct-reclaims" \ + } + + #define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("") +diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h +index 2db643ed8f..6459fdb9fb 100644 +--- a/include/standard-headers/linux/virtio_gpu.h ++++ b/include/standard-headers/linux/virtio_gpu.h +@@ -311,6 +311,7 @@ struct virtio_gpu_cmd_submit { + #define VIRTIO_GPU_CAPSET_VIRGL2 2 + /* 3 is reserved for gfxstream */ + #define VIRTIO_GPU_CAPSET_VENUS 4 ++#define VIRTIO_GPU_CAPSET_DRM 6 + + /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ + struct virtio_gpu_get_capset_info { +diff --git a/linux-headers/asm-arm64/mman.h b/linux-headers/asm-arm64/mman.h +index d0dbfe9587..7b500a3a7b 100644 +--- a/linux-headers/asm-arm64/mman.h ++++ b/linux-headers/asm-arm64/mman.h +@@ -7,4 +7,13 @@ + #define PROT_BTI 0x10 /* BTI guarded page */ + #define PROT_MTE 0x20 /* Normal Tagged mapping */ + ++/* Override any generic PKEY permission defines */ ++#define PKEY_DISABLE_EXECUTE 0x4 ++#define PKEY_DISABLE_READ 0x8 ++#undef PKEY_ACCESS_MASK ++#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ ++ PKEY_DISABLE_WRITE |\ ++ PKEY_DISABLE_READ |\ ++ PKEY_DISABLE_EXECUTE) ++ + #endif /* ! _UAPI__ASM_MMAN_H */ +diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h +index ce2ee8f1e3..df36f23876 100644 +--- a/linux-headers/asm-arm64/unistd.h ++++ b/linux-headers/asm-arm64/unistd.h +@@ -1,25 +1,2 @@ + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +-/* +- * Copyright (C) 2012 ARM Ltd. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +- * +- * 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 . +- */ +- +-#define __ARCH_WANT_RENAMEAT +-#define __ARCH_WANT_NEW_STAT +-#define __ARCH_WANT_SET_GET_RLIMIT +-#define __ARCH_WANT_TIME32_SYSCALLS +-#define __ARCH_WANT_SYS_CLONE3 +-#define __ARCH_WANT_MEMFD_SECRET +- +-#include ++#include +diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h +new file mode 100644 +index 0000000000..99a1d70459 +--- /dev/null ++++ b/linux-headers/asm-arm64/unistd_64.h +@@ -0,0 +1,324 @@ ++#ifndef _ASM_UNISTD_64_H ++#define _ASM_UNISTD_64_H ++ ++#define __NR_io_setup 0 ++#define __NR_io_destroy 1 ++#define __NR_io_submit 2 ++#define __NR_io_cancel 3 ++#define __NR_io_getevents 4 ++#define __NR_setxattr 5 ++#define __NR_lsetxattr 6 ++#define __NR_fsetxattr 7 ++#define __NR_getxattr 8 ++#define __NR_lgetxattr 9 ++#define __NR_fgetxattr 10 ++#define __NR_listxattr 11 ++#define __NR_llistxattr 12 ++#define __NR_flistxattr 13 ++#define __NR_removexattr 14 ++#define __NR_lremovexattr 15 ++#define __NR_fremovexattr 16 ++#define __NR_getcwd 17 ++#define __NR_lookup_dcookie 18 ++#define __NR_eventfd2 19 ++#define __NR_epoll_create1 20 ++#define __NR_epoll_ctl 21 ++#define __NR_epoll_pwait 22 ++#define __NR_dup 23 ++#define __NR_dup3 24 ++#define __NR_fcntl 25 ++#define __NR_inotify_init1 26 ++#define __NR_inotify_add_watch 27 ++#define __NR_inotify_rm_watch 28 ++#define __NR_ioctl 29 ++#define __NR_ioprio_set 30 ++#define __NR_ioprio_get 31 ++#define __NR_flock 32 ++#define __NR_mknodat 33 ++#define __NR_mkdirat 34 ++#define __NR_unlinkat 35 ++#define __NR_symlinkat 36 ++#define __NR_linkat 37 ++#define __NR_renameat 38 ++#define __NR_umount2 39 ++#define __NR_mount 40 ++#define __NR_pivot_root 41 ++#define __NR_nfsservctl 42 ++#define __NR_statfs 43 ++#define __NR_fstatfs 44 ++#define __NR_truncate 45 ++#define __NR_ftruncate 46 ++#define __NR_fallocate 47 ++#define __NR_faccessat 48 ++#define __NR_chdir 49 ++#define __NR_fchdir 50 ++#define __NR_chroot 51 ++#define __NR_fchmod 52 ++#define __NR_fchmodat 53 ++#define __NR_fchownat 54 ++#define __NR_fchown 55 ++#define __NR_openat 56 ++#define __NR_close 57 ++#define __NR_vhangup 58 ++#define __NR_pipe2 59 ++#define __NR_quotactl 60 ++#define __NR_getdents64 61 ++#define __NR_lseek 62 ++#define __NR_read 63 ++#define __NR_write 64 ++#define __NR_readv 65 ++#define __NR_writev 66 ++#define __NR_pread64 67 ++#define __NR_pwrite64 68 ++#define __NR_preadv 69 ++#define __NR_pwritev 70 ++#define __NR_sendfile 71 ++#define __NR_pselect6 72 ++#define __NR_ppoll 73 ++#define __NR_signalfd4 74 ++#define __NR_vmsplice 75 ++#define __NR_splice 76 ++#define __NR_tee 77 ++#define __NR_readlinkat 78 ++#define __NR_newfstatat 79 ++#define __NR_fstat 80 ++#define __NR_sync 81 ++#define __NR_fsync 82 ++#define __NR_fdatasync 83 ++#define __NR_sync_file_range 84 ++#define __NR_timerfd_create 85 ++#define __NR_timerfd_settime 86 ++#define __NR_timerfd_gettime 87 ++#define __NR_utimensat 88 ++#define __NR_acct 89 ++#define __NR_capget 90 ++#define __NR_capset 91 ++#define __NR_personality 92 ++#define __NR_exit 93 ++#define __NR_exit_group 94 ++#define __NR_waitid 95 ++#define __NR_set_tid_address 96 ++#define __NR_unshare 97 ++#define __NR_futex 98 ++#define __NR_set_robust_list 99 ++#define __NR_get_robust_list 100 ++#define __NR_nanosleep 101 ++#define __NR_getitimer 102 ++#define __NR_setitimer 103 ++#define __NR_kexec_load 104 ++#define __NR_init_module 105 ++#define __NR_delete_module 106 ++#define __NR_timer_create 107 ++#define __NR_timer_gettime 108 ++#define __NR_timer_getoverrun 109 ++#define __NR_timer_settime 110 ++#define __NR_timer_delete 111 ++#define __NR_clock_settime 112 ++#define __NR_clock_gettime 113 ++#define __NR_clock_getres 114 ++#define __NR_clock_nanosleep 115 ++#define __NR_syslog 116 ++#define __NR_ptrace 117 ++#define __NR_sched_setparam 118 ++#define __NR_sched_setscheduler 119 ++#define __NR_sched_getscheduler 120 ++#define __NR_sched_getparam 121 ++#define __NR_sched_setaffinity 122 ++#define __NR_sched_getaffinity 123 ++#define __NR_sched_yield 124 ++#define __NR_sched_get_priority_max 125 ++#define __NR_sched_get_priority_min 126 ++#define __NR_sched_rr_get_interval 127 ++#define __NR_restart_syscall 128 ++#define __NR_kill 129 ++#define __NR_tkill 130 ++#define __NR_tgkill 131 ++#define __NR_sigaltstack 132 ++#define __NR_rt_sigsuspend 133 ++#define __NR_rt_sigaction 134 ++#define __NR_rt_sigprocmask 135 ++#define __NR_rt_sigpending 136 ++#define __NR_rt_sigtimedwait 137 ++#define __NR_rt_sigqueueinfo 138 ++#define __NR_rt_sigreturn 139 ++#define __NR_setpriority 140 ++#define __NR_getpriority 141 ++#define __NR_reboot 142 ++#define __NR_setregid 143 ++#define __NR_setgid 144 ++#define __NR_setreuid 145 ++#define __NR_setuid 146 ++#define __NR_setresuid 147 ++#define __NR_getresuid 148 ++#define __NR_setresgid 149 ++#define __NR_getresgid 150 ++#define __NR_setfsuid 151 ++#define __NR_setfsgid 152 ++#define __NR_times 153 ++#define __NR_setpgid 154 ++#define __NR_getpgid 155 ++#define __NR_getsid 156 ++#define __NR_setsid 157 ++#define __NR_getgroups 158 ++#define __NR_setgroups 159 ++#define __NR_uname 160 ++#define __NR_sethostname 161 ++#define __NR_setdomainname 162 ++#define __NR_getrlimit 163 ++#define __NR_setrlimit 164 ++#define __NR_getrusage 165 ++#define __NR_umask 166 ++#define __NR_prctl 167 ++#define __NR_getcpu 168 ++#define __NR_gettimeofday 169 ++#define __NR_settimeofday 170 ++#define __NR_adjtimex 171 ++#define __NR_getpid 172 ++#define __NR_getppid 173 ++#define __NR_getuid 174 ++#define __NR_geteuid 175 ++#define __NR_getgid 176 ++#define __NR_getegid 177 ++#define __NR_gettid 178 ++#define __NR_sysinfo 179 ++#define __NR_mq_open 180 ++#define __NR_mq_unlink 181 ++#define __NR_mq_timedsend 182 ++#define __NR_mq_timedreceive 183 ++#define __NR_mq_notify 184 ++#define __NR_mq_getsetattr 185 ++#define __NR_msgget 186 ++#define __NR_msgctl 187 ++#define __NR_msgrcv 188 ++#define __NR_msgsnd 189 ++#define __NR_semget 190 ++#define __NR_semctl 191 ++#define __NR_semtimedop 192 ++#define __NR_semop 193 ++#define __NR_shmget 194 ++#define __NR_shmctl 195 ++#define __NR_shmat 196 ++#define __NR_shmdt 197 ++#define __NR_socket 198 ++#define __NR_socketpair 199 ++#define __NR_bind 200 ++#define __NR_listen 201 ++#define __NR_accept 202 ++#define __NR_connect 203 ++#define __NR_getsockname 204 ++#define __NR_getpeername 205 ++#define __NR_sendto 206 ++#define __NR_recvfrom 207 ++#define __NR_setsockopt 208 ++#define __NR_getsockopt 209 ++#define __NR_shutdown 210 ++#define __NR_sendmsg 211 ++#define __NR_recvmsg 212 ++#define __NR_readahead 213 ++#define __NR_brk 214 ++#define __NR_munmap 215 ++#define __NR_mremap 216 ++#define __NR_add_key 217 ++#define __NR_request_key 218 ++#define __NR_keyctl 219 ++#define __NR_clone 220 ++#define __NR_execve 221 ++#define __NR_mmap 222 ++#define __NR_fadvise64 223 ++#define __NR_swapon 224 ++#define __NR_swapoff 225 ++#define __NR_mprotect 226 ++#define __NR_msync 227 ++#define __NR_mlock 228 ++#define __NR_munlock 229 ++#define __NR_mlockall 230 ++#define __NR_munlockall 231 ++#define __NR_mincore 232 ++#define __NR_madvise 233 ++#define __NR_remap_file_pages 234 ++#define __NR_mbind 235 ++#define __NR_get_mempolicy 236 ++#define __NR_set_mempolicy 237 ++#define __NR_migrate_pages 238 ++#define __NR_move_pages 239 ++#define __NR_rt_tgsigqueueinfo 240 ++#define __NR_perf_event_open 241 ++#define __NR_accept4 242 ++#define __NR_recvmmsg 243 ++#define __NR_wait4 260 ++#define __NR_prlimit64 261 ++#define __NR_fanotify_init 262 ++#define __NR_fanotify_mark 263 ++#define __NR_name_to_handle_at 264 ++#define __NR_open_by_handle_at 265 ++#define __NR_clock_adjtime 266 ++#define __NR_syncfs 267 ++#define __NR_setns 268 ++#define __NR_sendmmsg 269 ++#define __NR_process_vm_readv 270 ++#define __NR_process_vm_writev 271 ++#define __NR_kcmp 272 ++#define __NR_finit_module 273 ++#define __NR_sched_setattr 274 ++#define __NR_sched_getattr 275 ++#define __NR_renameat2 276 ++#define __NR_seccomp 277 ++#define __NR_getrandom 278 ++#define __NR_memfd_create 279 ++#define __NR_bpf 280 ++#define __NR_execveat 281 ++#define __NR_userfaultfd 282 ++#define __NR_membarrier 283 ++#define __NR_mlock2 284 ++#define __NR_copy_file_range 285 ++#define __NR_preadv2 286 ++#define __NR_pwritev2 287 ++#define __NR_pkey_mprotect 288 ++#define __NR_pkey_alloc 289 ++#define __NR_pkey_free 290 ++#define __NR_statx 291 ++#define __NR_io_pgetevents 292 ++#define __NR_rseq 293 ++#define __NR_kexec_file_load 294 ++#define __NR_pidfd_send_signal 424 ++#define __NR_io_uring_setup 425 ++#define __NR_io_uring_enter 426 ++#define __NR_io_uring_register 427 ++#define __NR_open_tree 428 ++#define __NR_move_mount 429 ++#define __NR_fsopen 430 ++#define __NR_fsconfig 431 ++#define __NR_fsmount 432 ++#define __NR_fspick 433 ++#define __NR_pidfd_open 434 ++#define __NR_clone3 435 ++#define __NR_close_range 436 ++#define __NR_openat2 437 ++#define __NR_pidfd_getfd 438 ++#define __NR_faccessat2 439 ++#define __NR_process_madvise 440 ++#define __NR_epoll_pwait2 441 ++#define __NR_mount_setattr 442 ++#define __NR_quotactl_fd 443 ++#define __NR_landlock_create_ruleset 444 ++#define __NR_landlock_add_rule 445 ++#define __NR_landlock_restrict_self 446 ++#define __NR_memfd_secret 447 ++#define __NR_process_mrelease 448 ++#define __NR_futex_waitv 449 ++#define __NR_set_mempolicy_home_node 450 ++#define __NR_cachestat 451 ++#define __NR_fchmodat2 452 ++#define __NR_map_shadow_stack 453 ++#define __NR_futex_wake 454 ++#define __NR_futex_wait 455 ++#define __NR_futex_requeue 456 ++#define __NR_statmount 457 ++#define __NR_listmount 458 ++#define __NR_lsm_get_self_attr 459 ++#define __NR_lsm_set_self_attr 460 ++#define __NR_lsm_list_modules 461 ++#define __NR_mseal 462 ++ ++ ++#endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h +index d983c48a3b..5bf6148cac 100644 +--- a/linux-headers/asm-generic/unistd.h ++++ b/linux-headers/asm-generic/unistd.h +@@ -737,7 +737,7 @@ __SC_COMP(__NR_pselect6_time64, sys_pselect6, compat_sys_pselect6_time64) + #define __NR_ppoll_time64 414 + __SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) + #define __NR_io_pgetevents_time64 416 +-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) ++__SC_COMP(__NR_io_pgetevents_time64, sys_io_pgetevents, compat_sys_io_pgetevents_time64) + #define __NR_recvmmsg_time64 417 + __SC_COMP(__NR_recvmmsg_time64, sys_recvmmsg, compat_sys_recvmmsg_time64) + #define __NR_mq_timedsend_time64 418 +@@ -776,12 +776,8 @@ __SYSCALL(__NR_fsmount, sys_fsmount) + __SYSCALL(__NR_fspick, sys_fspick) + #define __NR_pidfd_open 434 + __SYSCALL(__NR_pidfd_open, sys_pidfd_open) +- +-#ifdef __ARCH_WANT_SYS_CLONE3 + #define __NR_clone3 435 + __SYSCALL(__NR_clone3, sys_clone3) +-#endif +- + #define __NR_close_range 436 + __SYSCALL(__NR_close_range, sys_close_range) + #define __NR_openat2 437 +diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h +index f9abef3823..70d89070bf 100644 +--- a/linux-headers/asm-loongarch/kvm.h ++++ b/linux-headers/asm-loongarch/kvm.h +@@ -64,6 +64,7 @@ struct kvm_fpu { + #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL) + #define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL) + #define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL) ++#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x50000ULL) + #define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL) + #define KVM_CSR_IDX_MASK 0x7fff + #define KVM_CPUCFG_IDX_MASK 0x7fff +@@ -77,11 +78,34 @@ struct kvm_fpu { + /* Debugging: Special instruction for software breakpoint */ + #define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) + ++/* LBT registers */ ++#define KVM_REG_LOONGARCH_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) ++#define KVM_REG_LOONGARCH_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) ++#define KVM_REG_LOONGARCH_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) ++#define KVM_REG_LOONGARCH_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) ++#define KVM_REG_LOONGARCH_LBT_EFLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) ++#define KVM_REG_LOONGARCH_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) ++ + #define LOONGARCH_REG_SHIFT 3 + #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) + #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) + #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) ++ ++/* Device Control API on vm fd */ ++#define KVM_LOONGARCH_VM_FEAT_CTRL 0 ++#define KVM_LOONGARCH_VM_FEAT_LSX 0 ++#define KVM_LOONGARCH_VM_FEAT_LASX 1 ++#define KVM_LOONGARCH_VM_FEAT_X86BT 2 ++#define KVM_LOONGARCH_VM_FEAT_ARMBT 3 ++#define KVM_LOONGARCH_VM_FEAT_MIPSBT 4 ++#define KVM_LOONGARCH_VM_FEAT_PMU 5 ++#define KVM_LOONGARCH_VM_FEAT_PV_IPI 6 ++#define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7 ++ ++/* Device Control API on vcpu fd */ + #define KVM_LOONGARCH_VCPU_CPUCFG 0 ++#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1 ++#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0 + + struct kvm_debug_exit_arch { + }; +diff --git a/linux-headers/asm-loongarch/kvm_para.h b/linux-headers/asm-loongarch/kvm_para.h +new file mode 100644 +index 0000000000..4ba4ad8db1 +--- /dev/null ++++ b/linux-headers/asm-loongarch/kvm_para.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _ASM_KVM_PARA_H ++#define _ASM_KVM_PARA_H ++ ++#include ++ ++/* ++ * CPUCFG index area: 0x40000000 -- 0x400000ff ++ * SW emulation for KVM hypervirsor ++ */ ++#define CPUCFG_KVM_BASE 0x40000000 ++#define CPUCFG_KVM_SIZE 0x100 ++#define CPUCFG_KVM_SIG (CPUCFG_KVM_BASE + 0) ++#define KVM_SIGNATURE "KVM\0" ++#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4) ++#define KVM_FEATURE_IPI 1 ++#define KVM_FEATURE_STEAL_TIME 2 ++/* BIT 24 - 31 are features configurable by user space vmm */ ++#define KVM_FEATURE_VIRT_EXTIOI 24 ++ ++#endif /* _ASM_KVM_PARA_H */ +diff --git a/linux-headers/asm-loongarch/unistd.h b/linux-headers/asm-loongarch/unistd.h +index fcb668984f..1f01980f9c 100644 +--- a/linux-headers/asm-loongarch/unistd.h ++++ b/linux-headers/asm-loongarch/unistd.h +@@ -1,5 +1,3 @@ + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +-#define __ARCH_WANT_SYS_CLONE +-#define __ARCH_WANT_SYS_CLONE3 + +-#include ++#include +diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h +new file mode 100644 +index 0000000000..887ea50cca +--- /dev/null ++++ b/linux-headers/asm-loongarch/unistd_64.h +@@ -0,0 +1,320 @@ ++#ifndef _ASM_UNISTD_64_H ++#define _ASM_UNISTD_64_H ++ ++#define __NR_io_setup 0 ++#define __NR_io_destroy 1 ++#define __NR_io_submit 2 ++#define __NR_io_cancel 3 ++#define __NR_io_getevents 4 ++#define __NR_setxattr 5 ++#define __NR_lsetxattr 6 ++#define __NR_fsetxattr 7 ++#define __NR_getxattr 8 ++#define __NR_lgetxattr 9 ++#define __NR_fgetxattr 10 ++#define __NR_listxattr 11 ++#define __NR_llistxattr 12 ++#define __NR_flistxattr 13 ++#define __NR_removexattr 14 ++#define __NR_lremovexattr 15 ++#define __NR_fremovexattr 16 ++#define __NR_getcwd 17 ++#define __NR_lookup_dcookie 18 ++#define __NR_eventfd2 19 ++#define __NR_epoll_create1 20 ++#define __NR_epoll_ctl 21 ++#define __NR_epoll_pwait 22 ++#define __NR_dup 23 ++#define __NR_dup3 24 ++#define __NR_fcntl 25 ++#define __NR_inotify_init1 26 ++#define __NR_inotify_add_watch 27 ++#define __NR_inotify_rm_watch 28 ++#define __NR_ioctl 29 ++#define __NR_ioprio_set 30 ++#define __NR_ioprio_get 31 ++#define __NR_flock 32 ++#define __NR_mknodat 33 ++#define __NR_mkdirat 34 ++#define __NR_unlinkat 35 ++#define __NR_symlinkat 36 ++#define __NR_linkat 37 ++#define __NR_umount2 39 ++#define __NR_mount 40 ++#define __NR_pivot_root 41 ++#define __NR_nfsservctl 42 ++#define __NR_statfs 43 ++#define __NR_fstatfs 44 ++#define __NR_truncate 45 ++#define __NR_ftruncate 46 ++#define __NR_fallocate 47 ++#define __NR_faccessat 48 ++#define __NR_chdir 49 ++#define __NR_fchdir 50 ++#define __NR_chroot 51 ++#define __NR_fchmod 52 ++#define __NR_fchmodat 53 ++#define __NR_fchownat 54 ++#define __NR_fchown 55 ++#define __NR_openat 56 ++#define __NR_close 57 ++#define __NR_vhangup 58 ++#define __NR_pipe2 59 ++#define __NR_quotactl 60 ++#define __NR_getdents64 61 ++#define __NR_lseek 62 ++#define __NR_read 63 ++#define __NR_write 64 ++#define __NR_readv 65 ++#define __NR_writev 66 ++#define __NR_pread64 67 ++#define __NR_pwrite64 68 ++#define __NR_preadv 69 ++#define __NR_pwritev 70 ++#define __NR_sendfile 71 ++#define __NR_pselect6 72 ++#define __NR_ppoll 73 ++#define __NR_signalfd4 74 ++#define __NR_vmsplice 75 ++#define __NR_splice 76 ++#define __NR_tee 77 ++#define __NR_readlinkat 78 ++#define __NR_newfstatat 79 ++#define __NR_fstat 80 ++#define __NR_sync 81 ++#define __NR_fsync 82 ++#define __NR_fdatasync 83 ++#define __NR_sync_file_range 84 ++#define __NR_timerfd_create 85 ++#define __NR_timerfd_settime 86 ++#define __NR_timerfd_gettime 87 ++#define __NR_utimensat 88 ++#define __NR_acct 89 ++#define __NR_capget 90 ++#define __NR_capset 91 ++#define __NR_personality 92 ++#define __NR_exit 93 ++#define __NR_exit_group 94 ++#define __NR_waitid 95 ++#define __NR_set_tid_address 96 ++#define __NR_unshare 97 ++#define __NR_futex 98 ++#define __NR_set_robust_list 99 ++#define __NR_get_robust_list 100 ++#define __NR_nanosleep 101 ++#define __NR_getitimer 102 ++#define __NR_setitimer 103 ++#define __NR_kexec_load 104 ++#define __NR_init_module 105 ++#define __NR_delete_module 106 ++#define __NR_timer_create 107 ++#define __NR_timer_gettime 108 ++#define __NR_timer_getoverrun 109 ++#define __NR_timer_settime 110 ++#define __NR_timer_delete 111 ++#define __NR_clock_settime 112 ++#define __NR_clock_gettime 113 ++#define __NR_clock_getres 114 ++#define __NR_clock_nanosleep 115 ++#define __NR_syslog 116 ++#define __NR_ptrace 117 ++#define __NR_sched_setparam 118 ++#define __NR_sched_setscheduler 119 ++#define __NR_sched_getscheduler 120 ++#define __NR_sched_getparam 121 ++#define __NR_sched_setaffinity 122 ++#define __NR_sched_getaffinity 123 ++#define __NR_sched_yield 124 ++#define __NR_sched_get_priority_max 125 ++#define __NR_sched_get_priority_min 126 ++#define __NR_sched_rr_get_interval 127 ++#define __NR_restart_syscall 128 ++#define __NR_kill 129 ++#define __NR_tkill 130 ++#define __NR_tgkill 131 ++#define __NR_sigaltstack 132 ++#define __NR_rt_sigsuspend 133 ++#define __NR_rt_sigaction 134 ++#define __NR_rt_sigprocmask 135 ++#define __NR_rt_sigpending 136 ++#define __NR_rt_sigtimedwait 137 ++#define __NR_rt_sigqueueinfo 138 ++#define __NR_rt_sigreturn 139 ++#define __NR_setpriority 140 ++#define __NR_getpriority 141 ++#define __NR_reboot 142 ++#define __NR_setregid 143 ++#define __NR_setgid 144 ++#define __NR_setreuid 145 ++#define __NR_setuid 146 ++#define __NR_setresuid 147 ++#define __NR_getresuid 148 ++#define __NR_setresgid 149 ++#define __NR_getresgid 150 ++#define __NR_setfsuid 151 ++#define __NR_setfsgid 152 ++#define __NR_times 153 ++#define __NR_setpgid 154 ++#define __NR_getpgid 155 ++#define __NR_getsid 156 ++#define __NR_setsid 157 ++#define __NR_getgroups 158 ++#define __NR_setgroups 159 ++#define __NR_uname 160 ++#define __NR_sethostname 161 ++#define __NR_setdomainname 162 ++#define __NR_getrusage 165 ++#define __NR_umask 166 ++#define __NR_prctl 167 ++#define __NR_getcpu 168 ++#define __NR_gettimeofday 169 ++#define __NR_settimeofday 170 ++#define __NR_adjtimex 171 ++#define __NR_getpid 172 ++#define __NR_getppid 173 ++#define __NR_getuid 174 ++#define __NR_geteuid 175 ++#define __NR_getgid 176 ++#define __NR_getegid 177 ++#define __NR_gettid 178 ++#define __NR_sysinfo 179 ++#define __NR_mq_open 180 ++#define __NR_mq_unlink 181 ++#define __NR_mq_timedsend 182 ++#define __NR_mq_timedreceive 183 ++#define __NR_mq_notify 184 ++#define __NR_mq_getsetattr 185 ++#define __NR_msgget 186 ++#define __NR_msgctl 187 ++#define __NR_msgrcv 188 ++#define __NR_msgsnd 189 ++#define __NR_semget 190 ++#define __NR_semctl 191 ++#define __NR_semtimedop 192 ++#define __NR_semop 193 ++#define __NR_shmget 194 ++#define __NR_shmctl 195 ++#define __NR_shmat 196 ++#define __NR_shmdt 197 ++#define __NR_socket 198 ++#define __NR_socketpair 199 ++#define __NR_bind 200 ++#define __NR_listen 201 ++#define __NR_accept 202 ++#define __NR_connect 203 ++#define __NR_getsockname 204 ++#define __NR_getpeername 205 ++#define __NR_sendto 206 ++#define __NR_recvfrom 207 ++#define __NR_setsockopt 208 ++#define __NR_getsockopt 209 ++#define __NR_shutdown 210 ++#define __NR_sendmsg 211 ++#define __NR_recvmsg 212 ++#define __NR_readahead 213 ++#define __NR_brk 214 ++#define __NR_munmap 215 ++#define __NR_mremap 216 ++#define __NR_add_key 217 ++#define __NR_request_key 218 ++#define __NR_keyctl 219 ++#define __NR_clone 220 ++#define __NR_execve 221 ++#define __NR_mmap 222 ++#define __NR_fadvise64 223 ++#define __NR_swapon 224 ++#define __NR_swapoff 225 ++#define __NR_mprotect 226 ++#define __NR_msync 227 ++#define __NR_mlock 228 ++#define __NR_munlock 229 ++#define __NR_mlockall 230 ++#define __NR_munlockall 231 ++#define __NR_mincore 232 ++#define __NR_madvise 233 ++#define __NR_remap_file_pages 234 ++#define __NR_mbind 235 ++#define __NR_get_mempolicy 236 ++#define __NR_set_mempolicy 237 ++#define __NR_migrate_pages 238 ++#define __NR_move_pages 239 ++#define __NR_rt_tgsigqueueinfo 240 ++#define __NR_perf_event_open 241 ++#define __NR_accept4 242 ++#define __NR_recvmmsg 243 ++#define __NR_wait4 260 ++#define __NR_prlimit64 261 ++#define __NR_fanotify_init 262 ++#define __NR_fanotify_mark 263 ++#define __NR_name_to_handle_at 264 ++#define __NR_open_by_handle_at 265 ++#define __NR_clock_adjtime 266 ++#define __NR_syncfs 267 ++#define __NR_setns 268 ++#define __NR_sendmmsg 269 ++#define __NR_process_vm_readv 270 ++#define __NR_process_vm_writev 271 ++#define __NR_kcmp 272 ++#define __NR_finit_module 273 ++#define __NR_sched_setattr 274 ++#define __NR_sched_getattr 275 ++#define __NR_renameat2 276 ++#define __NR_seccomp 277 ++#define __NR_getrandom 278 ++#define __NR_memfd_create 279 ++#define __NR_bpf 280 ++#define __NR_execveat 281 ++#define __NR_userfaultfd 282 ++#define __NR_membarrier 283 ++#define __NR_mlock2 284 ++#define __NR_copy_file_range 285 ++#define __NR_preadv2 286 ++#define __NR_pwritev2 287 ++#define __NR_pkey_mprotect 288 ++#define __NR_pkey_alloc 289 ++#define __NR_pkey_free 290 ++#define __NR_statx 291 ++#define __NR_io_pgetevents 292 ++#define __NR_rseq 293 ++#define __NR_kexec_file_load 294 ++#define __NR_pidfd_send_signal 424 ++#define __NR_io_uring_setup 425 ++#define __NR_io_uring_enter 426 ++#define __NR_io_uring_register 427 ++#define __NR_open_tree 428 ++#define __NR_move_mount 429 ++#define __NR_fsopen 430 ++#define __NR_fsconfig 431 ++#define __NR_fsmount 432 ++#define __NR_fspick 433 ++#define __NR_pidfd_open 434 ++#define __NR_clone3 435 ++#define __NR_close_range 436 ++#define __NR_openat2 437 ++#define __NR_pidfd_getfd 438 ++#define __NR_faccessat2 439 ++#define __NR_process_madvise 440 ++#define __NR_epoll_pwait2 441 ++#define __NR_mount_setattr 442 ++#define __NR_quotactl_fd 443 ++#define __NR_landlock_create_ruleset 444 ++#define __NR_landlock_add_rule 445 ++#define __NR_landlock_restrict_self 446 ++#define __NR_process_mrelease 448 ++#define __NR_futex_waitv 449 ++#define __NR_set_mempolicy_home_node 450 ++#define __NR_cachestat 451 ++#define __NR_fchmodat2 452 ++#define __NR_map_shadow_stack 453 ++#define __NR_futex_wake 454 ++#define __NR_futex_wait 455 ++#define __NR_futex_requeue 456 ++#define __NR_statmount 457 ++#define __NR_listmount 458 ++#define __NR_lsm_get_self_attr 459 ++#define __NR_lsm_set_self_attr 460 ++#define __NR_lsm_list_modules 461 ++#define __NR_mseal 462 ++ ++ ++#endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h +index e878e7cc39..e97db32964 100644 +--- a/linux-headers/asm-riscv/kvm.h ++++ b/linux-headers/asm-riscv/kvm.h +@@ -168,6 +168,13 @@ enum KVM_RISCV_ISA_EXT_ID { + KVM_RISCV_ISA_EXT_ZTSO, + KVM_RISCV_ISA_EXT_ZACAS, + KVM_RISCV_ISA_EXT_SSCOFPMF, ++ KVM_RISCV_ISA_EXT_ZIMOP, ++ KVM_RISCV_ISA_EXT_ZCA, ++ KVM_RISCV_ISA_EXT_ZCB, ++ KVM_RISCV_ISA_EXT_ZCD, ++ KVM_RISCV_ISA_EXT_ZCF, ++ KVM_RISCV_ISA_EXT_ZCMOP, ++ KVM_RISCV_ISA_EXT_ZAWRS, + KVM_RISCV_ISA_EXT_MAX, + }; + +diff --git a/linux-headers/asm-riscv/unistd.h b/linux-headers/asm-riscv/unistd.h +index 950ab3fd44..81896bbbf7 100644 +--- a/linux-headers/asm-riscv/unistd.h ++++ b/linux-headers/asm-riscv/unistd.h +@@ -14,41 +14,10 @@ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ ++#include + +-#if defined(__LP64__) && !defined(__SYSCALL_COMPAT) +-#define __ARCH_WANT_NEW_STAT +-#define __ARCH_WANT_SET_GET_RLIMIT +-#endif /* __LP64__ */ +- +-#define __ARCH_WANT_SYS_CLONE3 +-#define __ARCH_WANT_MEMFD_SECRET +- +-#include +- +-/* +- * Allows the instruction cache to be flushed from userspace. Despite RISC-V +- * having a direct 'fence.i' instruction available to userspace (which we +- * can't trap!), that's not actually viable when running on Linux because the +- * kernel might schedule a process on another hart. There is no way for +- * userspace to handle this without invoking the kernel (as it doesn't know the +- * thread->hart mappings), so we've defined a RISC-V specific system call to +- * flush the instruction cache. +- * +- * __NR_riscv_flush_icache is defined to flush the instruction cache over an +- * address range, with the flush applying to either all threads or just the +- * caller. We don't currently do anything with the address range, that's just +- * in there for forwards compatibility. +- */ +-#ifndef __NR_riscv_flush_icache +-#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) +-#endif +-__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache) +- +-/* +- * Allows userspace to query the kernel for CPU architecture and +- * microarchitecture details across a given set of CPUs. +- */ +-#ifndef __NR_riscv_hwprobe +-#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14) ++#if __BITS_PER_LONG == 64 ++#include ++#else ++#include + #endif +-__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe) +diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h +new file mode 100644 +index 0000000000..9625743dfd +--- /dev/null ++++ b/linux-headers/asm-riscv/unistd_32.h +@@ -0,0 +1,315 @@ ++#ifndef _ASM_UNISTD_32_H ++#define _ASM_UNISTD_32_H ++ ++#define __NR_io_setup 0 ++#define __NR_io_destroy 1 ++#define __NR_io_submit 2 ++#define __NR_io_cancel 3 ++#define __NR_setxattr 5 ++#define __NR_lsetxattr 6 ++#define __NR_fsetxattr 7 ++#define __NR_getxattr 8 ++#define __NR_lgetxattr 9 ++#define __NR_fgetxattr 10 ++#define __NR_listxattr 11 ++#define __NR_llistxattr 12 ++#define __NR_flistxattr 13 ++#define __NR_removexattr 14 ++#define __NR_lremovexattr 15 ++#define __NR_fremovexattr 16 ++#define __NR_getcwd 17 ++#define __NR_lookup_dcookie 18 ++#define __NR_eventfd2 19 ++#define __NR_epoll_create1 20 ++#define __NR_epoll_ctl 21 ++#define __NR_epoll_pwait 22 ++#define __NR_dup 23 ++#define __NR_dup3 24 ++#define __NR_fcntl64 25 ++#define __NR_inotify_init1 26 ++#define __NR_inotify_add_watch 27 ++#define __NR_inotify_rm_watch 28 ++#define __NR_ioctl 29 ++#define __NR_ioprio_set 30 ++#define __NR_ioprio_get 31 ++#define __NR_flock 32 ++#define __NR_mknodat 33 ++#define __NR_mkdirat 34 ++#define __NR_unlinkat 35 ++#define __NR_symlinkat 36 ++#define __NR_linkat 37 ++#define __NR_umount2 39 ++#define __NR_mount 40 ++#define __NR_pivot_root 41 ++#define __NR_nfsservctl 42 ++#define __NR_statfs64 43 ++#define __NR_fstatfs64 44 ++#define __NR_truncate64 45 ++#define __NR_ftruncate64 46 ++#define __NR_fallocate 47 ++#define __NR_faccessat 48 ++#define __NR_chdir 49 ++#define __NR_fchdir 50 ++#define __NR_chroot 51 ++#define __NR_fchmod 52 ++#define __NR_fchmodat 53 ++#define __NR_fchownat 54 ++#define __NR_fchown 55 ++#define __NR_openat 56 ++#define __NR_close 57 ++#define __NR_vhangup 58 ++#define __NR_pipe2 59 ++#define __NR_quotactl 60 ++#define __NR_getdents64 61 ++#define __NR_llseek 62 ++#define __NR_read 63 ++#define __NR_write 64 ++#define __NR_readv 65 ++#define __NR_writev 66 ++#define __NR_pread64 67 ++#define __NR_pwrite64 68 ++#define __NR_preadv 69 ++#define __NR_pwritev 70 ++#define __NR_sendfile64 71 ++#define __NR_signalfd4 74 ++#define __NR_vmsplice 75 ++#define __NR_splice 76 ++#define __NR_tee 77 ++#define __NR_readlinkat 78 ++#define __NR_sync 81 ++#define __NR_fsync 82 ++#define __NR_fdatasync 83 ++#define __NR_sync_file_range 84 ++#define __NR_timerfd_create 85 ++#define __NR_acct 89 ++#define __NR_capget 90 ++#define __NR_capset 91 ++#define __NR_personality 92 ++#define __NR_exit 93 ++#define __NR_exit_group 94 ++#define __NR_waitid 95 ++#define __NR_set_tid_address 96 ++#define __NR_unshare 97 ++#define __NR_set_robust_list 99 ++#define __NR_get_robust_list 100 ++#define __NR_getitimer 102 ++#define __NR_setitimer 103 ++#define __NR_kexec_load 104 ++#define __NR_init_module 105 ++#define __NR_delete_module 106 ++#define __NR_timer_create 107 ++#define __NR_timer_getoverrun 109 ++#define __NR_timer_delete 111 ++#define __NR_syslog 116 ++#define __NR_ptrace 117 ++#define __NR_sched_setparam 118 ++#define __NR_sched_setscheduler 119 ++#define __NR_sched_getscheduler 120 ++#define __NR_sched_getparam 121 ++#define __NR_sched_setaffinity 122 ++#define __NR_sched_getaffinity 123 ++#define __NR_sched_yield 124 ++#define __NR_sched_get_priority_max 125 ++#define __NR_sched_get_priority_min 126 ++#define __NR_restart_syscall 128 ++#define __NR_kill 129 ++#define __NR_tkill 130 ++#define __NR_tgkill 131 ++#define __NR_sigaltstack 132 ++#define __NR_rt_sigsuspend 133 ++#define __NR_rt_sigaction 134 ++#define __NR_rt_sigprocmask 135 ++#define __NR_rt_sigpending 136 ++#define __NR_rt_sigqueueinfo 138 ++#define __NR_rt_sigreturn 139 ++#define __NR_setpriority 140 ++#define __NR_getpriority 141 ++#define __NR_reboot 142 ++#define __NR_setregid 143 ++#define __NR_setgid 144 ++#define __NR_setreuid 145 ++#define __NR_setuid 146 ++#define __NR_setresuid 147 ++#define __NR_getresuid 148 ++#define __NR_setresgid 149 ++#define __NR_getresgid 150 ++#define __NR_setfsuid 151 ++#define __NR_setfsgid 152 ++#define __NR_times 153 ++#define __NR_setpgid 154 ++#define __NR_getpgid 155 ++#define __NR_getsid 156 ++#define __NR_setsid 157 ++#define __NR_getgroups 158 ++#define __NR_setgroups 159 ++#define __NR_uname 160 ++#define __NR_sethostname 161 ++#define __NR_setdomainname 162 ++#define __NR_getrusage 165 ++#define __NR_umask 166 ++#define __NR_prctl 167 ++#define __NR_getcpu 168 ++#define __NR_getpid 172 ++#define __NR_getppid 173 ++#define __NR_getuid 174 ++#define __NR_geteuid 175 ++#define __NR_getgid 176 ++#define __NR_getegid 177 ++#define __NR_gettid 178 ++#define __NR_sysinfo 179 ++#define __NR_mq_open 180 ++#define __NR_mq_unlink 181 ++#define __NR_mq_notify 184 ++#define __NR_mq_getsetattr 185 ++#define __NR_msgget 186 ++#define __NR_msgctl 187 ++#define __NR_msgrcv 188 ++#define __NR_msgsnd 189 ++#define __NR_semget 190 ++#define __NR_semctl 191 ++#define __NR_semop 193 ++#define __NR_shmget 194 ++#define __NR_shmctl 195 ++#define __NR_shmat 196 ++#define __NR_shmdt 197 ++#define __NR_socket 198 ++#define __NR_socketpair 199 ++#define __NR_bind 200 ++#define __NR_listen 201 ++#define __NR_accept 202 ++#define __NR_connect 203 ++#define __NR_getsockname 204 ++#define __NR_getpeername 205 ++#define __NR_sendto 206 ++#define __NR_recvfrom 207 ++#define __NR_setsockopt 208 ++#define __NR_getsockopt 209 ++#define __NR_shutdown 210 ++#define __NR_sendmsg 211 ++#define __NR_recvmsg 212 ++#define __NR_readahead 213 ++#define __NR_brk 214 ++#define __NR_munmap 215 ++#define __NR_mremap 216 ++#define __NR_add_key 217 ++#define __NR_request_key 218 ++#define __NR_keyctl 219 ++#define __NR_clone 220 ++#define __NR_execve 221 ++#define __NR_mmap2 222 ++#define __NR_fadvise64_64 223 ++#define __NR_swapon 224 ++#define __NR_swapoff 225 ++#define __NR_mprotect 226 ++#define __NR_msync 227 ++#define __NR_mlock 228 ++#define __NR_munlock 229 ++#define __NR_mlockall 230 ++#define __NR_munlockall 231 ++#define __NR_mincore 232 ++#define __NR_madvise 233 ++#define __NR_remap_file_pages 234 ++#define __NR_mbind 235 ++#define __NR_get_mempolicy 236 ++#define __NR_set_mempolicy 237 ++#define __NR_migrate_pages 238 ++#define __NR_move_pages 239 ++#define __NR_rt_tgsigqueueinfo 240 ++#define __NR_perf_event_open 241 ++#define __NR_accept4 242 ++#define __NR_riscv_hwprobe 258 ++#define __NR_riscv_flush_icache 259 ++#define __NR_prlimit64 261 ++#define __NR_fanotify_init 262 ++#define __NR_fanotify_mark 263 ++#define __NR_name_to_handle_at 264 ++#define __NR_open_by_handle_at 265 ++#define __NR_syncfs 267 ++#define __NR_setns 268 ++#define __NR_sendmmsg 269 ++#define __NR_process_vm_readv 270 ++#define __NR_process_vm_writev 271 ++#define __NR_kcmp 272 ++#define __NR_finit_module 273 ++#define __NR_sched_setattr 274 ++#define __NR_sched_getattr 275 ++#define __NR_renameat2 276 ++#define __NR_seccomp 277 ++#define __NR_getrandom 278 ++#define __NR_memfd_create 279 ++#define __NR_bpf 280 ++#define __NR_execveat 281 ++#define __NR_userfaultfd 282 ++#define __NR_membarrier 283 ++#define __NR_mlock2 284 ++#define __NR_copy_file_range 285 ++#define __NR_preadv2 286 ++#define __NR_pwritev2 287 ++#define __NR_pkey_mprotect 288 ++#define __NR_pkey_alloc 289 ++#define __NR_pkey_free 290 ++#define __NR_statx 291 ++#define __NR_rseq 293 ++#define __NR_kexec_file_load 294 ++#define __NR_clock_gettime64 403 ++#define __NR_clock_settime64 404 ++#define __NR_clock_adjtime64 405 ++#define __NR_clock_getres_time64 406 ++#define __NR_clock_nanosleep_time64 407 ++#define __NR_timer_gettime64 408 ++#define __NR_timer_settime64 409 ++#define __NR_timerfd_gettime64 410 ++#define __NR_timerfd_settime64 411 ++#define __NR_utimensat_time64 412 ++#define __NR_pselect6_time64 413 ++#define __NR_ppoll_time64 414 ++#define __NR_io_pgetevents_time64 416 ++#define __NR_recvmmsg_time64 417 ++#define __NR_mq_timedsend_time64 418 ++#define __NR_mq_timedreceive_time64 419 ++#define __NR_semtimedop_time64 420 ++#define __NR_rt_sigtimedwait_time64 421 ++#define __NR_futex_time64 422 ++#define __NR_sched_rr_get_interval_time64 423 ++#define __NR_pidfd_send_signal 424 ++#define __NR_io_uring_setup 425 ++#define __NR_io_uring_enter 426 ++#define __NR_io_uring_register 427 ++#define __NR_open_tree 428 ++#define __NR_move_mount 429 ++#define __NR_fsopen 430 ++#define __NR_fsconfig 431 ++#define __NR_fsmount 432 ++#define __NR_fspick 433 ++#define __NR_pidfd_open 434 ++#define __NR_clone3 435 ++#define __NR_close_range 436 ++#define __NR_openat2 437 ++#define __NR_pidfd_getfd 438 ++#define __NR_faccessat2 439 ++#define __NR_process_madvise 440 ++#define __NR_epoll_pwait2 441 ++#define __NR_mount_setattr 442 ++#define __NR_quotactl_fd 443 ++#define __NR_landlock_create_ruleset 444 ++#define __NR_landlock_add_rule 445 ++#define __NR_landlock_restrict_self 446 ++#define __NR_memfd_secret 447 ++#define __NR_process_mrelease 448 ++#define __NR_futex_waitv 449 ++#define __NR_set_mempolicy_home_node 450 ++#define __NR_cachestat 451 ++#define __NR_fchmodat2 452 ++#define __NR_map_shadow_stack 453 ++#define __NR_futex_wake 454 ++#define __NR_futex_wait 455 ++#define __NR_futex_requeue 456 ++#define __NR_statmount 457 ++#define __NR_listmount 458 ++#define __NR_lsm_get_self_attr 459 ++#define __NR_lsm_set_self_attr 460 ++#define __NR_lsm_list_modules 461 ++#define __NR_mseal 462 ++ ++ ++#endif /* _ASM_UNISTD_32_H */ +diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h +new file mode 100644 +index 0000000000..95bca8ae81 +--- /dev/null ++++ b/linux-headers/asm-riscv/unistd_64.h +@@ -0,0 +1,325 @@ ++#ifndef _ASM_UNISTD_64_H ++#define _ASM_UNISTD_64_H ++ ++#define __NR_io_setup 0 ++#define __NR_io_destroy 1 ++#define __NR_io_submit 2 ++#define __NR_io_cancel 3 ++#define __NR_io_getevents 4 ++#define __NR_setxattr 5 ++#define __NR_lsetxattr 6 ++#define __NR_fsetxattr 7 ++#define __NR_getxattr 8 ++#define __NR_lgetxattr 9 ++#define __NR_fgetxattr 10 ++#define __NR_listxattr 11 ++#define __NR_llistxattr 12 ++#define __NR_flistxattr 13 ++#define __NR_removexattr 14 ++#define __NR_lremovexattr 15 ++#define __NR_fremovexattr 16 ++#define __NR_getcwd 17 ++#define __NR_lookup_dcookie 18 ++#define __NR_eventfd2 19 ++#define __NR_epoll_create1 20 ++#define __NR_epoll_ctl 21 ++#define __NR_epoll_pwait 22 ++#define __NR_dup 23 ++#define __NR_dup3 24 ++#define __NR_fcntl 25 ++#define __NR_inotify_init1 26 ++#define __NR_inotify_add_watch 27 ++#define __NR_inotify_rm_watch 28 ++#define __NR_ioctl 29 ++#define __NR_ioprio_set 30 ++#define __NR_ioprio_get 31 ++#define __NR_flock 32 ++#define __NR_mknodat 33 ++#define __NR_mkdirat 34 ++#define __NR_unlinkat 35 ++#define __NR_symlinkat 36 ++#define __NR_linkat 37 ++#define __NR_umount2 39 ++#define __NR_mount 40 ++#define __NR_pivot_root 41 ++#define __NR_nfsservctl 42 ++#define __NR_statfs 43 ++#define __NR_fstatfs 44 ++#define __NR_truncate 45 ++#define __NR_ftruncate 46 ++#define __NR_fallocate 47 ++#define __NR_faccessat 48 ++#define __NR_chdir 49 ++#define __NR_fchdir 50 ++#define __NR_chroot 51 ++#define __NR_fchmod 52 ++#define __NR_fchmodat 53 ++#define __NR_fchownat 54 ++#define __NR_fchown 55 ++#define __NR_openat 56 ++#define __NR_close 57 ++#define __NR_vhangup 58 ++#define __NR_pipe2 59 ++#define __NR_quotactl 60 ++#define __NR_getdents64 61 ++#define __NR_lseek 62 ++#define __NR_read 63 ++#define __NR_write 64 ++#define __NR_readv 65 ++#define __NR_writev 66 ++#define __NR_pread64 67 ++#define __NR_pwrite64 68 ++#define __NR_preadv 69 ++#define __NR_pwritev 70 ++#define __NR_sendfile 71 ++#define __NR_pselect6 72 ++#define __NR_ppoll 73 ++#define __NR_signalfd4 74 ++#define __NR_vmsplice 75 ++#define __NR_splice 76 ++#define __NR_tee 77 ++#define __NR_readlinkat 78 ++#define __NR_newfstatat 79 ++#define __NR_fstat 80 ++#define __NR_sync 81 ++#define __NR_fsync 82 ++#define __NR_fdatasync 83 ++#define __NR_sync_file_range 84 ++#define __NR_timerfd_create 85 ++#define __NR_timerfd_settime 86 ++#define __NR_timerfd_gettime 87 ++#define __NR_utimensat 88 ++#define __NR_acct 89 ++#define __NR_capget 90 ++#define __NR_capset 91 ++#define __NR_personality 92 ++#define __NR_exit 93 ++#define __NR_exit_group 94 ++#define __NR_waitid 95 ++#define __NR_set_tid_address 96 ++#define __NR_unshare 97 ++#define __NR_futex 98 ++#define __NR_set_robust_list 99 ++#define __NR_get_robust_list 100 ++#define __NR_nanosleep 101 ++#define __NR_getitimer 102 ++#define __NR_setitimer 103 ++#define __NR_kexec_load 104 ++#define __NR_init_module 105 ++#define __NR_delete_module 106 ++#define __NR_timer_create 107 ++#define __NR_timer_gettime 108 ++#define __NR_timer_getoverrun 109 ++#define __NR_timer_settime 110 ++#define __NR_timer_delete 111 ++#define __NR_clock_settime 112 ++#define __NR_clock_gettime 113 ++#define __NR_clock_getres 114 ++#define __NR_clock_nanosleep 115 ++#define __NR_syslog 116 ++#define __NR_ptrace 117 ++#define __NR_sched_setparam 118 ++#define __NR_sched_setscheduler 119 ++#define __NR_sched_getscheduler 120 ++#define __NR_sched_getparam 121 ++#define __NR_sched_setaffinity 122 ++#define __NR_sched_getaffinity 123 ++#define __NR_sched_yield 124 ++#define __NR_sched_get_priority_max 125 ++#define __NR_sched_get_priority_min 126 ++#define __NR_sched_rr_get_interval 127 ++#define __NR_restart_syscall 128 ++#define __NR_kill 129 ++#define __NR_tkill 130 ++#define __NR_tgkill 131 ++#define __NR_sigaltstack 132 ++#define __NR_rt_sigsuspend 133 ++#define __NR_rt_sigaction 134 ++#define __NR_rt_sigprocmask 135 ++#define __NR_rt_sigpending 136 ++#define __NR_rt_sigtimedwait 137 ++#define __NR_rt_sigqueueinfo 138 ++#define __NR_rt_sigreturn 139 ++#define __NR_setpriority 140 ++#define __NR_getpriority 141 ++#define __NR_reboot 142 ++#define __NR_setregid 143 ++#define __NR_setgid 144 ++#define __NR_setreuid 145 ++#define __NR_setuid 146 ++#define __NR_setresuid 147 ++#define __NR_getresuid 148 ++#define __NR_setresgid 149 ++#define __NR_getresgid 150 ++#define __NR_setfsuid 151 ++#define __NR_setfsgid 152 ++#define __NR_times 153 ++#define __NR_setpgid 154 ++#define __NR_getpgid 155 ++#define __NR_getsid 156 ++#define __NR_setsid 157 ++#define __NR_getgroups 158 ++#define __NR_setgroups 159 ++#define __NR_uname 160 ++#define __NR_sethostname 161 ++#define __NR_setdomainname 162 ++#define __NR_getrlimit 163 ++#define __NR_setrlimit 164 ++#define __NR_getrusage 165 ++#define __NR_umask 166 ++#define __NR_prctl 167 ++#define __NR_getcpu 168 ++#define __NR_gettimeofday 169 ++#define __NR_settimeofday 170 ++#define __NR_adjtimex 171 ++#define __NR_getpid 172 ++#define __NR_getppid 173 ++#define __NR_getuid 174 ++#define __NR_geteuid 175 ++#define __NR_getgid 176 ++#define __NR_getegid 177 ++#define __NR_gettid 178 ++#define __NR_sysinfo 179 ++#define __NR_mq_open 180 ++#define __NR_mq_unlink 181 ++#define __NR_mq_timedsend 182 ++#define __NR_mq_timedreceive 183 ++#define __NR_mq_notify 184 ++#define __NR_mq_getsetattr 185 ++#define __NR_msgget 186 ++#define __NR_msgctl 187 ++#define __NR_msgrcv 188 ++#define __NR_msgsnd 189 ++#define __NR_semget 190 ++#define __NR_semctl 191 ++#define __NR_semtimedop 192 ++#define __NR_semop 193 ++#define __NR_shmget 194 ++#define __NR_shmctl 195 ++#define __NR_shmat 196 ++#define __NR_shmdt 197 ++#define __NR_socket 198 ++#define __NR_socketpair 199 ++#define __NR_bind 200 ++#define __NR_listen 201 ++#define __NR_accept 202 ++#define __NR_connect 203 ++#define __NR_getsockname 204 ++#define __NR_getpeername 205 ++#define __NR_sendto 206 ++#define __NR_recvfrom 207 ++#define __NR_setsockopt 208 ++#define __NR_getsockopt 209 ++#define __NR_shutdown 210 ++#define __NR_sendmsg 211 ++#define __NR_recvmsg 212 ++#define __NR_readahead 213 ++#define __NR_brk 214 ++#define __NR_munmap 215 ++#define __NR_mremap 216 ++#define __NR_add_key 217 ++#define __NR_request_key 218 ++#define __NR_keyctl 219 ++#define __NR_clone 220 ++#define __NR_execve 221 ++#define __NR_mmap 222 ++#define __NR_fadvise64 223 ++#define __NR_swapon 224 ++#define __NR_swapoff 225 ++#define __NR_mprotect 226 ++#define __NR_msync 227 ++#define __NR_mlock 228 ++#define __NR_munlock 229 ++#define __NR_mlockall 230 ++#define __NR_munlockall 231 ++#define __NR_mincore 232 ++#define __NR_madvise 233 ++#define __NR_remap_file_pages 234 ++#define __NR_mbind 235 ++#define __NR_get_mempolicy 236 ++#define __NR_set_mempolicy 237 ++#define __NR_migrate_pages 238 ++#define __NR_move_pages 239 ++#define __NR_rt_tgsigqueueinfo 240 ++#define __NR_perf_event_open 241 ++#define __NR_accept4 242 ++#define __NR_recvmmsg 243 ++#define __NR_riscv_hwprobe 258 ++#define __NR_riscv_flush_icache 259 ++#define __NR_wait4 260 ++#define __NR_prlimit64 261 ++#define __NR_fanotify_init 262 ++#define __NR_fanotify_mark 263 ++#define __NR_name_to_handle_at 264 ++#define __NR_open_by_handle_at 265 ++#define __NR_clock_adjtime 266 ++#define __NR_syncfs 267 ++#define __NR_setns 268 ++#define __NR_sendmmsg 269 ++#define __NR_process_vm_readv 270 ++#define __NR_process_vm_writev 271 ++#define __NR_kcmp 272 ++#define __NR_finit_module 273 ++#define __NR_sched_setattr 274 ++#define __NR_sched_getattr 275 ++#define __NR_renameat2 276 ++#define __NR_seccomp 277 ++#define __NR_getrandom 278 ++#define __NR_memfd_create 279 ++#define __NR_bpf 280 ++#define __NR_execveat 281 ++#define __NR_userfaultfd 282 ++#define __NR_membarrier 283 ++#define __NR_mlock2 284 ++#define __NR_copy_file_range 285 ++#define __NR_preadv2 286 ++#define __NR_pwritev2 287 ++#define __NR_pkey_mprotect 288 ++#define __NR_pkey_alloc 289 ++#define __NR_pkey_free 290 ++#define __NR_statx 291 ++#define __NR_io_pgetevents 292 ++#define __NR_rseq 293 ++#define __NR_kexec_file_load 294 ++#define __NR_pidfd_send_signal 424 ++#define __NR_io_uring_setup 425 ++#define __NR_io_uring_enter 426 ++#define __NR_io_uring_register 427 ++#define __NR_open_tree 428 ++#define __NR_move_mount 429 ++#define __NR_fsopen 430 ++#define __NR_fsconfig 431 ++#define __NR_fsmount 432 ++#define __NR_fspick 433 ++#define __NR_pidfd_open 434 ++#define __NR_clone3 435 ++#define __NR_close_range 436 ++#define __NR_openat2 437 ++#define __NR_pidfd_getfd 438 ++#define __NR_faccessat2 439 ++#define __NR_process_madvise 440 ++#define __NR_epoll_pwait2 441 ++#define __NR_mount_setattr 442 ++#define __NR_quotactl_fd 443 ++#define __NR_landlock_create_ruleset 444 ++#define __NR_landlock_add_rule 445 ++#define __NR_landlock_restrict_self 446 ++#define __NR_memfd_secret 447 ++#define __NR_process_mrelease 448 ++#define __NR_futex_waitv 449 ++#define __NR_set_mempolicy_home_node 450 ++#define __NR_cachestat 451 ++#define __NR_fchmodat2 452 ++#define __NR_map_shadow_stack 453 ++#define __NR_futex_wake 454 ++#define __NR_futex_wait 455 ++#define __NR_futex_requeue 456 ++#define __NR_statmount 457 ++#define __NR_listmount 458 ++#define __NR_lsm_get_self_attr 459 ++#define __NR_lsm_set_self_attr 460 ++#define __NR_lsm_list_modules 461 ++#define __NR_mseal 462 ++ ++ ++#endif /* _ASM_UNISTD_64_H */ +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index 1c8f918234..4711ef2c3d 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -106,6 +106,7 @@ struct kvm_ioapic_state { + + #define KVM_RUN_X86_SMM (1 << 0) + #define KVM_RUN_X86_BUS_LOCK (1 << 1) ++#define KVM_RUN_X86_GUEST_MODE (1 << 2) + + /* for KVM_GET_REGS and KVM_SET_REGS */ + struct kvm_regs { +@@ -436,6 +437,7 @@ struct kvm_sync_regs { + #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4) + #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5) + #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) ++#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) + + #define KVM_STATE_NESTED_FORMAT_VMX 0 + #define KVM_STATE_NESTED_FORMAT_SVM 1 +diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h +index da439afee1..24c979be54 100644 +--- a/linux-headers/asm-x86/unistd_64.h ++++ b/linux-headers/asm-x86/unistd_64.h +@@ -336,6 +336,7 @@ + #define __NR_statx 332 + #define __NR_io_pgetevents 333 + #define __NR_rseq 334 ++#define __NR_uretprobe 335 + #define __NR_pidfd_send_signal 424 + #define __NR_io_uring_setup 425 + #define __NR_io_uring_enter 426 +diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h +index 4fcb607c72..c23dd21a2d 100644 +--- a/linux-headers/asm-x86/unistd_x32.h ++++ b/linux-headers/asm-x86/unistd_x32.h +@@ -289,6 +289,7 @@ + #define __NR_statx (__X32_SYSCALL_BIT + 332) + #define __NR_io_pgetevents (__X32_SYSCALL_BIT + 333) + #define __NR_rseq (__X32_SYSCALL_BIT + 334) ++#define __NR_uretprobe (__X32_SYSCALL_BIT + 335) + #define __NR_pidfd_send_signal (__X32_SYSCALL_BIT + 424) + #define __NR_io_uring_setup (__X32_SYSCALL_BIT + 425) + #define __NR_io_uring_enter (__X32_SYSCALL_BIT + 426) +diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h +index d9897771be..c0d00c0a98 100644 +--- a/linux-headers/linux/bits.h ++++ b/linux-headers/linux/bits.h +@@ -12,4 +12,7 @@ + (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & \ + (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h)))) + ++#define __GENMASK_U128(h, l) \ ++ ((_BIT128((h)) << 1) - (_BIT128(l))) ++ + #endif /* _LINUX_BITS_H */ +diff --git a/linux-headers/linux/const.h b/linux-headers/linux/const.h +index 1eb84b5087..2122610de7 100644 +--- a/linux-headers/linux/const.h ++++ b/linux-headers/linux/const.h +@@ -28,6 +28,23 @@ + #define _BITUL(x) (_UL(1) << (x)) + #define _BITULL(x) (_ULL(1) << (x)) + ++#if !defined(__ASSEMBLY__) ++/* ++ * Missing __asm__ support ++ * ++ * __BIT128() would not work in the __asm__ code, as it shifts an ++ * 'unsigned __init128' data type as direct representation of ++ * 128 bit constants is not supported in the gcc compiler, as ++ * they get silently truncated. ++ * ++ * TODO: Please revisit this implementation when gcc compiler ++ * starts representing 128 bit constants directly like long ++ * and unsigned long etc. Subsequently drop the comment for ++ * GENMASK_U128() which would then start supporting __asm__ code. ++ */ ++#define _BIT128(x) ((unsigned __int128)(1) << (x)) ++#endif ++ + #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) + #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) + +diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h +index 72e8f4b9dd..782baf477f 100644 +--- a/linux-headers/linux/iommufd.h ++++ b/linux-headers/linux/iommufd.h +@@ -4,8 +4,8 @@ + #ifndef _IOMMUFD_H + #define _IOMMUFD_H + +-#include + #include ++#include + + #define IOMMUFD_TYPE (';') + +@@ -37,19 +37,20 @@ + enum { + IOMMUFD_CMD_BASE = 0x80, + IOMMUFD_CMD_DESTROY = IOMMUFD_CMD_BASE, +- IOMMUFD_CMD_IOAS_ALLOC, +- IOMMUFD_CMD_IOAS_ALLOW_IOVAS, +- IOMMUFD_CMD_IOAS_COPY, +- IOMMUFD_CMD_IOAS_IOVA_RANGES, +- IOMMUFD_CMD_IOAS_MAP, +- IOMMUFD_CMD_IOAS_UNMAP, +- IOMMUFD_CMD_OPTION, +- IOMMUFD_CMD_VFIO_IOAS, +- IOMMUFD_CMD_HWPT_ALLOC, +- IOMMUFD_CMD_GET_HW_INFO, +- IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING, +- IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP, +- IOMMUFD_CMD_HWPT_INVALIDATE, ++ IOMMUFD_CMD_IOAS_ALLOC = 0x81, ++ IOMMUFD_CMD_IOAS_ALLOW_IOVAS = 0x82, ++ IOMMUFD_CMD_IOAS_COPY = 0x83, ++ IOMMUFD_CMD_IOAS_IOVA_RANGES = 0x84, ++ IOMMUFD_CMD_IOAS_MAP = 0x85, ++ IOMMUFD_CMD_IOAS_UNMAP = 0x86, ++ IOMMUFD_CMD_OPTION = 0x87, ++ IOMMUFD_CMD_VFIO_IOAS = 0x88, ++ IOMMUFD_CMD_HWPT_ALLOC = 0x89, ++ IOMMUFD_CMD_GET_HW_INFO = 0x8a, ++ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING = 0x8b, ++ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c, ++ IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d, ++ IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e, + }; + + /** +@@ -356,10 +357,13 @@ struct iommu_vfio_ioas { + * the parent HWPT in a nesting configuration. + * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is + * enforced on device attachment ++ * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is ++ * valid. + */ + enum iommufd_hwpt_alloc_flags { + IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, + IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, ++ IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, + }; + + /** +@@ -396,8 +400,8 @@ struct iommu_hwpt_vtd_s1 { + * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table + */ + enum iommu_hwpt_data_type { +- IOMMU_HWPT_DATA_NONE, +- IOMMU_HWPT_DATA_VTD_S1, ++ IOMMU_HWPT_DATA_NONE = 0, ++ IOMMU_HWPT_DATA_VTD_S1 = 1, + }; + + /** +@@ -411,6 +415,9 @@ enum iommu_hwpt_data_type { + * @data_type: One of enum iommu_hwpt_data_type + * @data_len: Length of the type specific data + * @data_uptr: User pointer to the type specific data ++ * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of ++ * IOMMU_HWPT_FAULT_ID_VALID is set. ++ * @__reserved2: Padding to 64-bit alignment. Must be 0. + * + * Explicitly allocate a hardware page table object. This is the same object + * type that is returned by iommufd_device_attach() and represents the +@@ -441,6 +448,8 @@ struct iommu_hwpt_alloc { + __u32 data_type; + __u32 data_len; + __aligned_u64 data_uptr; ++ __u32 fault_id; ++ __u32 __reserved2; + }; + #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) + +@@ -482,8 +491,8 @@ struct iommu_hw_info_vtd { + * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type + */ + enum iommu_hw_info_type { +- IOMMU_HW_INFO_TYPE_NONE, +- IOMMU_HW_INFO_TYPE_INTEL_VTD, ++ IOMMU_HW_INFO_TYPE_NONE = 0, ++ IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, + }; + + /** +@@ -620,7 +629,7 @@ struct iommu_hwpt_get_dirty_bitmap { + * @IOMMU_HWPT_INVALIDATE_DATA_VTD_S1: Invalidation data for VTD_S1 + */ + enum iommu_hwpt_invalidate_data_type { +- IOMMU_HWPT_INVALIDATE_DATA_VTD_S1, ++ IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0, + }; + + /** +@@ -692,4 +701,100 @@ struct iommu_hwpt_invalidate { + __u32 __reserved; + }; + #define IOMMU_HWPT_INVALIDATE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_INVALIDATE) ++ ++/** ++ * enum iommu_hwpt_pgfault_flags - flags for struct iommu_hwpt_pgfault ++ * @IOMMU_PGFAULT_FLAGS_PASID_VALID: The pasid field of the fault data is ++ * valid. ++ * @IOMMU_PGFAULT_FLAGS_LAST_PAGE: It's the last fault of a fault group. ++ */ ++enum iommu_hwpt_pgfault_flags { ++ IOMMU_PGFAULT_FLAGS_PASID_VALID = (1 << 0), ++ IOMMU_PGFAULT_FLAGS_LAST_PAGE = (1 << 1), ++}; ++ ++/** ++ * enum iommu_hwpt_pgfault_perm - perm bits for struct iommu_hwpt_pgfault ++ * @IOMMU_PGFAULT_PERM_READ: request for read permission ++ * @IOMMU_PGFAULT_PERM_WRITE: request for write permission ++ * @IOMMU_PGFAULT_PERM_EXEC: (PCIE 10.4.1) request with a PASID that has the ++ * Execute Requested bit set in PASID TLP Prefix. ++ * @IOMMU_PGFAULT_PERM_PRIV: (PCIE 10.4.1) request with a PASID that has the ++ * Privileged Mode Requested bit set in PASID TLP ++ * Prefix. ++ */ ++enum iommu_hwpt_pgfault_perm { ++ IOMMU_PGFAULT_PERM_READ = (1 << 0), ++ IOMMU_PGFAULT_PERM_WRITE = (1 << 1), ++ IOMMU_PGFAULT_PERM_EXEC = (1 << 2), ++ IOMMU_PGFAULT_PERM_PRIV = (1 << 3), ++}; ++ ++/** ++ * struct iommu_hwpt_pgfault - iommu page fault data ++ * @flags: Combination of enum iommu_hwpt_pgfault_flags ++ * @dev_id: id of the originated device ++ * @pasid: Process Address Space ID ++ * @grpid: Page Request Group Index ++ * @perm: Combination of enum iommu_hwpt_pgfault_perm ++ * @addr: Fault address ++ * @length: a hint of how much data the requestor is expecting to fetch. For ++ * example, if the PRI initiator knows it is going to do a 10MB ++ * transfer, it could fill in 10MB and the OS could pre-fault in ++ * 10MB of IOVA. It's default to 0 if there's no such hint. ++ * @cookie: kernel-managed cookie identifying a group of fault messages. The ++ * cookie number encoded in the last page fault of the group should ++ * be echoed back in the response message. ++ */ ++struct iommu_hwpt_pgfault { ++ __u32 flags; ++ __u32 dev_id; ++ __u32 pasid; ++ __u32 grpid; ++ __u32 perm; ++ __u64 addr; ++ __u32 length; ++ __u32 cookie; ++}; ++ ++/** ++ * enum iommufd_page_response_code - Return status of fault handlers ++ * @IOMMUFD_PAGE_RESP_SUCCESS: Fault has been handled and the page tables ++ * populated, retry the access. This is the ++ * "Success" defined in PCI 10.4.2.1. ++ * @IOMMUFD_PAGE_RESP_INVALID: Could not handle this fault, don't retry the ++ * access. This is the "Invalid Request" in PCI ++ * 10.4.2.1. ++ */ ++enum iommufd_page_response_code { ++ IOMMUFD_PAGE_RESP_SUCCESS = 0, ++ IOMMUFD_PAGE_RESP_INVALID = 1, ++}; ++ ++/** ++ * struct iommu_hwpt_page_response - IOMMU page fault response ++ * @cookie: The kernel-managed cookie reported in the fault message. ++ * @code: One of response code in enum iommufd_page_response_code. ++ */ ++struct iommu_hwpt_page_response { ++ __u32 cookie; ++ __u32 code; ++}; ++ ++/** ++ * struct iommu_fault_alloc - ioctl(IOMMU_FAULT_QUEUE_ALLOC) ++ * @size: sizeof(struct iommu_fault_alloc) ++ * @flags: Must be 0 ++ * @out_fault_id: The ID of the new FAULT ++ * @out_fault_fd: The fd of the new FAULT ++ * ++ * Explicitly allocate a fault handling object. ++ */ ++struct iommu_fault_alloc { ++ __u32 size; ++ __u32 flags; ++ __u32 out_fault_id; ++ __u32 out_fault_fd; ++}; ++#define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC) + #endif +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index c93876ca0b..49dd1b30ce 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -192,11 +192,20 @@ struct kvm_xen_exit { + /* Flags that describe what fields in emulation_failure hold valid data. */ + #define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0) + ++/* ++ * struct kvm_run can be modified by userspace at any time, so KVM must be ++ * careful to avoid TOCTOU bugs. In order to protect KVM, HINT_UNSAFE_IN_KVM() ++ * renames fields in struct kvm_run from to __unsafe when ++ * compiled into the kernel, ensuring that any use within KVM is obvious and ++ * gets extra scrutiny. ++ */ ++#define HINT_UNSAFE_IN_KVM(_symbol) _symbol ++ + /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ + struct kvm_run { + /* in */ + __u8 request_interrupt_window; +- __u8 immediate_exit; ++ __u8 HINT_UNSAFE_IN_KVM(immediate_exit); + __u8 padding1[6]; + + /* out */ +@@ -913,6 +922,9 @@ struct kvm_enable_cap { + #define KVM_CAP_MEMORY_ATTRIBUTES 233 + #define KVM_CAP_GUEST_MEMFD 234 + #define KVM_CAP_VM_TYPES 235 ++#define KVM_CAP_PRE_FAULT_MEMORY 236 ++#define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 ++#define KVM_CAP_X86_GUEST_MODE 238 + + struct kvm_irq_routing_irqchip { + __u32 irqchip; +@@ -1544,4 +1556,13 @@ struct kvm_create_guest_memfd { + __u64 reserved[6]; + }; + ++#define KVM_PRE_FAULT_MEMORY _IOWR(KVMIO, 0xd5, struct kvm_pre_fault_memory) ++ ++struct kvm_pre_fault_memory { ++ __u64 gpa; ++ __u64 size; ++ __u64 flags; ++ __u64 padding[5]; ++}; ++ + #endif /* __LINUX_KVM_H */ +diff --git a/linux-headers/linux/mman.h b/linux-headers/linux/mman.h +index 4e8cb60780..2b83059586 100644 +--- a/linux-headers/linux/mman.h ++++ b/linux-headers/linux/mman.h +@@ -17,6 +17,7 @@ + #define MAP_SHARED 0x01 /* Share changes */ + #define MAP_PRIVATE 0x02 /* Changes are private */ + #define MAP_SHARED_VALIDATE 0x03 /* share + validate extension flags */ ++#define MAP_DROPPABLE 0x08 /* Zero memory under memory pressure. */ + + /* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page +diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h +index c3046c6bff..17bf191573 100644 +--- a/linux-headers/linux/psp-sev.h ++++ b/linux-headers/linux/psp-sev.h +@@ -31,6 +31,7 @@ enum { + SNP_PLATFORM_STATUS, + SNP_COMMIT, + SNP_SET_CONFIG, ++ SNP_VLEK_LOAD, + + SEV_MAX, + }; +@@ -50,6 +51,7 @@ typedef enum { + SEV_RET_INVALID_PLATFORM_STATE, + SEV_RET_INVALID_GUEST_STATE, + SEV_RET_INAVLID_CONFIG, ++ SEV_RET_INVALID_CONFIG = SEV_RET_INAVLID_CONFIG, + SEV_RET_INVALID_LEN, + SEV_RET_ALREADY_OWNED, + SEV_RET_INVALID_CERTIFICATE, +@@ -214,6 +216,32 @@ struct sev_user_data_snp_config { + __u8 rsvd1[52]; + } __attribute__((packed)); + ++/** ++ * struct sev_data_snp_vlek_load - SNP_VLEK_LOAD structure ++ * ++ * @len: length of the command buffer read by the PSP ++ * @vlek_wrapped_version: version of wrapped VLEK hashstick (Must be 0h) ++ * @rsvd: reserved ++ * @vlek_wrapped_address: address of a wrapped VLEK hashstick ++ * (struct sev_user_data_snp_wrapped_vlek_hashstick) ++ */ ++struct sev_user_data_snp_vlek_load { ++ __u32 len; /* In */ ++ __u8 vlek_wrapped_version; /* In */ ++ __u8 rsvd[3]; /* In */ ++ __u64 vlek_wrapped_address; /* In */ ++} __attribute__((packed)); ++ ++/** ++ * struct sev_user_data_snp_vlek_wrapped_vlek_hashstick - Wrapped VLEK data ++ * ++ * @data: Opaque data provided by AMD KDS (as described in SEV-SNP Firmware ABI ++ * 1.54, SNP_VLEK_LOAD) ++ */ ++struct sev_user_data_snp_wrapped_vlek_hashstick { ++ __u8 data[432]; /* In */ ++} __attribute__((packed)); ++ + /** + * struct sev_issue_cmd - SEV ioctl parameters + * +-- +2.39.3 + diff --git a/SOURCES/kvm-linux-headers-Update-to-current-kvm-next.patch b/SOURCES/kvm-linux-headers-Update-to-current-kvm-next.patch deleted file mode 100644 index 2fd35fd..0000000 --- a/SOURCES/kvm-linux-headers-Update-to-current-kvm-next.patch +++ /dev/null @@ -1,189 +0,0 @@ -From c3e2bc3319882c16fa36eafc7a613073746cfc8b Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Thu, 30 May 2024 06:16:14 -0500 -Subject: [PATCH 052/100] linux-headers: Update to current kvm/next - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [52/91] df77e867072f60110b8387a54ba2db6226b35007 (bonzini/rhel-qemu-kvm) - -This updates kernel headers to commit 6f627b425378 ("KVM: SVM: Add module -parameter to enable SEV-SNP", 2024-05-12). The SNP host patches will -be included in Linux 6.11, to be released next July. - -Also brings in an linux-headers/linux/vhost.h fix from v6.9-rc4. - -Co-developed-by: Michael Roth -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-3-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 5f69e42da5b40a2213f4db70ca461f554abca686) -Signed-off-by: Paolo Bonzini ---- - linux-headers/asm-loongarch/kvm.h | 4 +++ - linux-headers/asm-riscv/kvm.h | 1 + - linux-headers/asm-x86/kvm.h | 52 ++++++++++++++++++++++++++++++- - linux-headers/linux/vhost.h | 15 ++++----- - 4 files changed, 64 insertions(+), 8 deletions(-) - -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index 109785922c..f9abef3823 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -17,6 +17,8 @@ - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 - #define KVM_DIRTY_LOG_PAGE_OFFSET 64 - -+#define KVM_GUESTDBG_USE_SW_BP 0x00010000 -+ - /* - * for KVM_GET_REGS and KVM_SET_REGS - */ -@@ -72,6 +74,8 @@ struct kvm_fpu { - - #define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) - #define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) -+/* Debugging: Special instruction for software breakpoint */ -+#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) - - #define LOONGARCH_REG_SHIFT 3 - #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) -diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h -index b1c503c295..e878e7cc39 100644 ---- a/linux-headers/asm-riscv/kvm.h -+++ b/linux-headers/asm-riscv/kvm.h -@@ -167,6 +167,7 @@ enum KVM_RISCV_ISA_EXT_ID { - KVM_RISCV_ISA_EXT_ZFA, - KVM_RISCV_ISA_EXT_ZTSO, - KVM_RISCV_ISA_EXT_ZACAS, -+ KVM_RISCV_ISA_EXT_SSCOFPMF, - KVM_RISCV_ISA_EXT_MAX, - }; - -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index 31c95c2dfe..1c8f918234 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -695,6 +695,11 @@ enum sev_cmd_id { - /* Second time is the charm; improved versions of the above ioctls. */ - KVM_SEV_INIT2, - -+ /* SNP-specific commands */ -+ KVM_SEV_SNP_LAUNCH_START = 100, -+ KVM_SEV_SNP_LAUNCH_UPDATE, -+ KVM_SEV_SNP_LAUNCH_FINISH, -+ - KVM_SEV_NR_MAX, - }; - -@@ -709,7 +714,9 @@ struct kvm_sev_cmd { - struct kvm_sev_init { - __u64 vmsa_features; - __u32 flags; -- __u32 pad[9]; -+ __u16 ghcb_version; -+ __u16 pad1; -+ __u32 pad2[8]; - }; - - struct kvm_sev_launch_start { -@@ -820,6 +827,48 @@ struct kvm_sev_receive_update_data { - __u32 pad2; - }; - -+struct kvm_sev_snp_launch_start { -+ __u64 policy; -+ __u8 gosvw[16]; -+ __u16 flags; -+ __u8 pad0[6]; -+ __u64 pad1[4]; -+}; -+ -+/* Kept in sync with firmware values for simplicity. */ -+#define KVM_SEV_SNP_PAGE_TYPE_NORMAL 0x1 -+#define KVM_SEV_SNP_PAGE_TYPE_ZERO 0x3 -+#define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED 0x4 -+#define KVM_SEV_SNP_PAGE_TYPE_SECRETS 0x5 -+#define KVM_SEV_SNP_PAGE_TYPE_CPUID 0x6 -+ -+struct kvm_sev_snp_launch_update { -+ __u64 gfn_start; -+ __u64 uaddr; -+ __u64 len; -+ __u8 type; -+ __u8 pad0; -+ __u16 flags; -+ __u32 pad1; -+ __u64 pad2[4]; -+}; -+ -+#define KVM_SEV_SNP_ID_BLOCK_SIZE 96 -+#define KVM_SEV_SNP_ID_AUTH_SIZE 4096 -+#define KVM_SEV_SNP_FINISH_DATA_SIZE 32 -+ -+struct kvm_sev_snp_launch_finish { -+ __u64 id_block_uaddr; -+ __u64 id_auth_uaddr; -+ __u8 id_block_en; -+ __u8 auth_key_en; -+ __u8 vcek_disabled; -+ __u8 host_data[KVM_SEV_SNP_FINISH_DATA_SIZE]; -+ __u8 pad0[3]; -+ __u16 flags; -+ __u64 pad1[4]; -+}; -+ - #define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) - #define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) - -@@ -870,5 +919,6 @@ struct kvm_hyperv_eventfd { - #define KVM_X86_SW_PROTECTED_VM 1 - #define KVM_X86_SEV_VM 2 - #define KVM_X86_SEV_ES_VM 3 -+#define KVM_X86_SNP_VM 4 - - #endif /* _ASM_X86_KVM_H */ -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index bea6973906..b95dd84eef 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -179,12 +179,6 @@ - /* Get the config size */ - #define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x79, __u32) - --/* Get the count of all virtqueues */ --#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32) -- --/* Get the number of virtqueue groups. */ --#define VHOST_VDPA_GET_GROUP_NUM _IOR(VHOST_VIRTIO, 0x81, __u32) -- - /* Get the number of address spaces. */ - #define VHOST_VDPA_GET_AS_NUM _IOR(VHOST_VIRTIO, 0x7A, unsigned int) - -@@ -228,10 +222,17 @@ - #define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, \ - struct vhost_vring_state) - -+ -+/* Get the count of all virtqueues */ -+#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32) -+ -+/* Get the number of virtqueue groups. */ -+#define VHOST_VDPA_GET_GROUP_NUM _IOR(VHOST_VIRTIO, 0x81, __u32) -+ - /* Get the queue size of a specific virtqueue. - * userspace set the vring index in vhost_vring_state.index - * kernel set the queue size in vhost_vring_state.num - */ --#define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x80, \ -+#define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x82, \ - struct vhost_vring_state) - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-linux-headers-update-to-current-kvm-next.patch b/SOURCES/kvm-linux-headers-update-to-current-kvm-next.patch deleted file mode 100644 index 4c3dd73..0000000 --- a/SOURCES/kvm-linux-headers-update-to-current-kvm-next.patch +++ /dev/null @@ -1,2471 +0,0 @@ -From 530296e1669c9730f261a269d5b911ea56dfcce7 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 23 Apr 2024 11:46:47 +0200 -Subject: [PATCH 017/100] linux-headers: update to current kvm/next - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [17/91] 5660d4967f10a84802de16c24540e95095eaffd5 (bonzini/rhel-qemu-kvm) - -Signed-off-by: Paolo Bonzini -(cherry picked from commit ab0c7fb22b56523f24d6e127cd4d10ecff67bf85) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86.c | 8 - - include/standard-headers/asm-x86/bootparam.h | 17 +- - include/standard-headers/asm-x86/kvm_para.h | 3 +- - include/standard-headers/asm-x86/setup_data.h | 83 +++ - include/standard-headers/linux/ethtool.h | 48 ++ - include/standard-headers/linux/fuse.h | 39 +- - .../linux/input-event-codes.h | 1 + - include/standard-headers/linux/virtio_gpu.h | 2 + - include/standard-headers/linux/virtio_pci.h | 10 +- - include/standard-headers/linux/virtio_snd.h | 154 ++++ - linux-headers/asm-arm64/kvm.h | 15 +- - linux-headers/asm-arm64/sve_context.h | 11 + - linux-headers/asm-generic/bitsperlong.h | 4 + - linux-headers/asm-loongarch/kvm.h | 2 - - linux-headers/asm-mips/kvm.h | 2 - - linux-headers/asm-powerpc/kvm.h | 45 +- - linux-headers/asm-riscv/kvm.h | 3 +- - linux-headers/asm-s390/kvm.h | 315 +++++++- - linux-headers/asm-x86/kvm.h | 328 ++++++++- - linux-headers/linux/bits.h | 15 + - linux-headers/linux/kvm.h | 689 +----------------- - linux-headers/linux/psp-sev.h | 59 ++ - linux-headers/linux/vhost.h | 7 + - 23 files changed, 1120 insertions(+), 740 deletions(-) - create mode 100644 include/standard-headers/asm-x86/setup_data.h - create mode 100644 linux-headers/linux/bits.h - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index ffbda48917..84a4801977 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -679,14 +679,6 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state) - return dev; - } - --struct setup_data { -- uint64_t next; -- uint32_t type; -- uint32_t len; -- uint8_t data[]; --} __attribute__((packed)); -- -- - /* - * The entry point into the kernel for PVH boot is different from - * the native entry point. The PVH entry is defined by the x86/HVM -diff --git a/include/standard-headers/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h -index 0b06d2bff1..b582a105c0 100644 ---- a/include/standard-headers/asm-x86/bootparam.h -+++ b/include/standard-headers/asm-x86/bootparam.h -@@ -2,21 +2,7 @@ - #ifndef _ASM_X86_BOOTPARAM_H - #define _ASM_X86_BOOTPARAM_H - --/* setup_data/setup_indirect types */ --#define SETUP_NONE 0 --#define SETUP_E820_EXT 1 --#define SETUP_DTB 2 --#define SETUP_PCI 3 --#define SETUP_EFI 4 --#define SETUP_APPLE_PROPERTIES 5 --#define SETUP_JAILHOUSE 6 --#define SETUP_CC_BLOB 7 --#define SETUP_IMA 8 --#define SETUP_RNG_SEED 9 --#define SETUP_ENUM_MAX SETUP_RNG_SEED -- --#define SETUP_INDIRECT (1<<31) --#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) -+#include "standard-headers/asm-x86/setup_data.h" - - /* ram_size flags */ - #define RAMDISK_IMAGE_START_MASK 0x07FF -@@ -38,6 +24,7 @@ - #define XLF_EFI_KEXEC (1<<4) - #define XLF_5LEVEL (1<<5) - #define XLF_5LEVEL_ENABLED (1<<6) -+#define XLF_MEM_ENCRYPTION (1<<7) - - - #endif /* _ASM_X86_BOOTPARAM_H */ -diff --git a/include/standard-headers/asm-x86/kvm_para.h b/include/standard-headers/asm-x86/kvm_para.h -index f0235e58a1..9a011d20f0 100644 ---- a/include/standard-headers/asm-x86/kvm_para.h -+++ b/include/standard-headers/asm-x86/kvm_para.h -@@ -92,7 +92,7 @@ struct kvm_clock_pairing { - #define KVM_ASYNC_PF_DELIVERY_AS_INT (1 << 3) - - /* MSR_KVM_ASYNC_PF_INT */ --#define KVM_ASYNC_PF_VEC_MASK GENMASK(7, 0) -+#define KVM_ASYNC_PF_VEC_MASK __GENMASK(7, 0) - - /* MSR_KVM_MIGRATION_CONTROL */ - #define KVM_MIGRATION_READY (1 << 0) -@@ -142,7 +142,6 @@ struct kvm_vcpu_pv_apf_data { - uint32_t token; - - uint8_t pad[56]; -- uint32_t enabled; - }; - - #define KVM_PV_EOI_BIT 0 -diff --git a/include/standard-headers/asm-x86/setup_data.h b/include/standard-headers/asm-x86/setup_data.h -new file mode 100644 -index 0000000000..09355f54c5 ---- /dev/null -+++ b/include/standard-headers/asm-x86/setup_data.h -@@ -0,0 +1,83 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _ASM_X86_SETUP_DATA_H -+#define _ASM_X86_SETUP_DATA_H -+ -+/* setup_data/setup_indirect types */ -+#define SETUP_NONE 0 -+#define SETUP_E820_EXT 1 -+#define SETUP_DTB 2 -+#define SETUP_PCI 3 -+#define SETUP_EFI 4 -+#define SETUP_APPLE_PROPERTIES 5 -+#define SETUP_JAILHOUSE 6 -+#define SETUP_CC_BLOB 7 -+#define SETUP_IMA 8 -+#define SETUP_RNG_SEED 9 -+#define SETUP_ENUM_MAX SETUP_RNG_SEED -+ -+#define SETUP_INDIRECT (1<<31) -+#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) -+ -+#ifndef __ASSEMBLY__ -+ -+#include "standard-headers/linux/types.h" -+ -+/* extensible setup data list node */ -+struct setup_data { -+ uint64_t next; -+ uint32_t type; -+ uint32_t len; -+ uint8_t data[]; -+}; -+ -+/* extensible setup indirect data node */ -+struct setup_indirect { -+ uint32_t type; -+ uint32_t reserved; /* Reserved, must be set to zero. */ -+ uint64_t len; -+ uint64_t addr; -+}; -+ -+/* -+ * The E820 memory region entry of the boot protocol ABI: -+ */ -+struct boot_e820_entry { -+ uint64_t addr; -+ uint64_t size; -+ uint32_t type; -+} QEMU_PACKED; -+ -+/* -+ * The boot loader is passing platform information via this Jailhouse-specific -+ * setup data structure. -+ */ -+struct jailhouse_setup_data { -+ struct { -+ uint16_t version; -+ uint16_t compatible_version; -+ } QEMU_PACKED hdr; -+ struct { -+ uint16_t pm_timer_address; -+ uint16_t num_cpus; -+ uint64_t pci_mmconfig_base; -+ uint32_t tsc_khz; -+ uint32_t apic_khz; -+ uint8_t standard_ioapic; -+ uint8_t cpu_ids[255]; -+ } QEMU_PACKED v1; -+ struct { -+ uint32_t flags; -+ } QEMU_PACKED v2; -+} QEMU_PACKED; -+ -+/* -+ * IMA buffer setup data information from the previous kernel during kexec -+ */ -+struct ima_setup_data { -+ uint64_t addr; -+ uint64_t size; -+} QEMU_PACKED; -+ -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* _ASM_X86_SETUP_DATA_H */ -diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h -index dfb54eff6f..01503784d2 100644 ---- a/include/standard-headers/linux/ethtool.h -+++ b/include/standard-headers/linux/ethtool.h -@@ -2023,6 +2023,53 @@ static inline int ethtool_validate_duplex(uint8_t duplex) - #define IPV4_FLOW 0x10 /* hash only */ - #define IPV6_FLOW 0x11 /* hash only */ - #define ETHER_FLOW 0x12 /* spec only (ether_spec) */ -+ -+/* Used for GTP-U IPv4 and IPv6. -+ * The format of GTP packets only includes -+ * elements such as TEID and GTP version. -+ * It is primarily intended for data communication of the UE. -+ */ -+#define GTPU_V4_FLOW 0x13 /* hash only */ -+#define GTPU_V6_FLOW 0x14 /* hash only */ -+ -+/* Use for GTP-C IPv4 and v6. -+ * The format of these GTP packets does not include TEID. -+ * Primarily expected to be used for communication -+ * to create sessions for UE data communication, -+ * commonly referred to as CSR (Create Session Request). -+ */ -+#define GTPC_V4_FLOW 0x15 /* hash only */ -+#define GTPC_V6_FLOW 0x16 /* hash only */ -+ -+/* Use for GTP-C IPv4 and v6. -+ * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID. -+ * After session creation, it becomes this packet. -+ * This is mainly used for requests to realize UE handover. -+ */ -+#define GTPC_TEID_V4_FLOW 0x17 /* hash only */ -+#define GTPC_TEID_V6_FLOW 0x18 /* hash only */ -+ -+/* Use for GTP-U and extended headers for the PSC (PDU Session Container). -+ * The format of these GTP packets includes TEID and QFI. -+ * In 5G communication using UPF (User Plane Function), -+ * data communication with this extended header is performed. -+ */ -+#define GTPU_EH_V4_FLOW 0x19 /* hash only */ -+#define GTPU_EH_V6_FLOW 0x1a /* hash only */ -+ -+/* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers. -+ * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by -+ * UL/DL included in the PSC. -+ * There are differences in the data included based on Downlink/Uplink, -+ * and can be used to distinguish packets. -+ * The functions described so far are useful when you want to -+ * handle communication from the mobile network in UPF, PGW, etc. -+ */ -+#define GTPU_UL_V4_FLOW 0x1b /* hash only */ -+#define GTPU_UL_V6_FLOW 0x1c /* hash only */ -+#define GTPU_DL_V4_FLOW 0x1d /* hash only */ -+#define GTPU_DL_V6_FLOW 0x1e /* hash only */ -+ - /* Flag to enable additional fields in struct ethtool_rx_flow_spec */ - #define FLOW_EXT 0x80000000 - #define FLOW_MAC_EXT 0x40000000 -@@ -2037,6 +2084,7 @@ static inline int ethtool_validate_duplex(uint8_t duplex) - #define RXH_IP_DST (1 << 5) - #define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */ - #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ -+#define RXH_GTP_TEID (1 << 8) /* teid in case of GTP */ - #define RXH_DISCARD (1 << 31) - - #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL -diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h -index fc0dcd10ae..bac9dbc49f 100644 ---- a/include/standard-headers/linux/fuse.h -+++ b/include/standard-headers/linux/fuse.h -@@ -211,6 +211,12 @@ - * 7.39 - * - add FUSE_DIRECT_IO_ALLOW_MMAP - * - add FUSE_STATX and related structures -+ * -+ * 7.40 -+ * - add max_stack_depth to fuse_init_out, add FUSE_PASSTHROUGH init flag -+ * - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag -+ * - add FUSE_NO_EXPORT_SUPPORT init flag -+ * - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag - */ - - #ifndef _LINUX_FUSE_H -@@ -242,7 +248,7 @@ - #define FUSE_KERNEL_VERSION 7 - - /** Minor version number of this interface */ --#define FUSE_KERNEL_MINOR_VERSION 39 -+#define FUSE_KERNEL_MINOR_VERSION 40 - - /** The node ID of the root inode */ - #define FUSE_ROOT_ID 1 -@@ -349,6 +355,7 @@ struct fuse_file_lock { - * FOPEN_STREAM: the file is stream-like (no file position at all) - * FOPEN_NOFLUSH: don't flush data cache on close (unless FUSE_WRITEBACK_CACHE) - * FOPEN_PARALLEL_DIRECT_WRITES: Allow concurrent direct writes on the same inode -+ * FOPEN_PASSTHROUGH: passthrough read/write io for this open file - */ - #define FOPEN_DIRECT_IO (1 << 0) - #define FOPEN_KEEP_CACHE (1 << 1) -@@ -357,6 +364,7 @@ struct fuse_file_lock { - #define FOPEN_STREAM (1 << 4) - #define FOPEN_NOFLUSH (1 << 5) - #define FOPEN_PARALLEL_DIRECT_WRITES (1 << 6) -+#define FOPEN_PASSTHROUGH (1 << 7) - - /** - * INIT request/reply flags -@@ -406,6 +414,9 @@ struct fuse_file_lock { - * symlink and mknod (single group that matches parent) - * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation - * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. -+ * FUSE_NO_EXPORT_SUPPORT: explicitly disable export support -+ * FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit -+ * of the request ID indicates resend requests - */ - #define FUSE_ASYNC_READ (1 << 0) - #define FUSE_POSIX_LOCKS (1 << 1) -@@ -445,6 +456,9 @@ struct fuse_file_lock { - #define FUSE_CREATE_SUPP_GROUP (1ULL << 34) - #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) - #define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) -+#define FUSE_PASSTHROUGH (1ULL << 37) -+#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38) -+#define FUSE_HAS_RESEND (1ULL << 39) - - /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ - #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP -@@ -631,6 +645,7 @@ enum fuse_notify_code { - FUSE_NOTIFY_STORE = 4, - FUSE_NOTIFY_RETRIEVE = 5, - FUSE_NOTIFY_DELETE = 6, -+ FUSE_NOTIFY_RESEND = 7, - FUSE_NOTIFY_CODE_MAX, - }; - -@@ -757,7 +772,7 @@ struct fuse_create_in { - struct fuse_open_out { - uint64_t fh; - uint32_t open_flags; -- uint32_t padding; -+ int32_t backing_id; - }; - - struct fuse_release_in { -@@ -873,7 +888,8 @@ struct fuse_init_out { - uint16_t max_pages; - uint16_t map_alignment; - uint32_t flags2; -- uint32_t unused[7]; -+ uint32_t max_stack_depth; -+ uint32_t unused[6]; - }; - - #define CUSE_INIT_INFO_MAX 4096 -@@ -956,6 +972,14 @@ struct fuse_fallocate_in { - uint32_t padding; - }; - -+/** -+ * FUSE request unique ID flag -+ * -+ * Indicates whether this is a resend request. The receiver should handle this -+ * request accordingly. -+ */ -+#define FUSE_UNIQUE_RESEND (1ULL << 63) -+ - struct fuse_in_header { - uint32_t len; - uint32_t opcode; -@@ -1045,9 +1069,18 @@ struct fuse_notify_retrieve_in { - uint64_t dummy4; - }; - -+struct fuse_backing_map { -+ int32_t fd; -+ uint32_t flags; -+ uint64_t padding; -+}; -+ - /* Device ioctls: */ - #define FUSE_DEV_IOC_MAGIC 229 - #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t) -+#define FUSE_DEV_IOC_BACKING_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 1, \ -+ struct fuse_backing_map) -+#define FUSE_DEV_IOC_BACKING_CLOSE _IOW(FUSE_DEV_IOC_MAGIC, 2, uint32_t) - - struct fuse_lseek_in { - uint64_t fh; -diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h -index f6bab08540..2221b0c383 100644 ---- a/include/standard-headers/linux/input-event-codes.h -+++ b/include/standard-headers/linux/input-event-codes.h -@@ -602,6 +602,7 @@ - - #define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */ - #define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */ -+#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */ - - #define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */ - #define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */ -diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h -index 2da48d3d4c..2db643ed8f 100644 ---- a/include/standard-headers/linux/virtio_gpu.h -+++ b/include/standard-headers/linux/virtio_gpu.h -@@ -309,6 +309,8 @@ struct virtio_gpu_cmd_submit { - - #define VIRTIO_GPU_CAPSET_VIRGL 1 - #define VIRTIO_GPU_CAPSET_VIRGL2 2 -+/* 3 is reserved for gfxstream */ -+#define VIRTIO_GPU_CAPSET_VENUS 4 - - /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ - struct virtio_gpu_get_capset_info { -diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h -index 3e2bc2c97e..4010216103 100644 ---- a/include/standard-headers/linux/virtio_pci.h -+++ b/include/standard-headers/linux/virtio_pci.h -@@ -240,7 +240,7 @@ struct virtio_pci_cfg_cap { - #define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5 - #define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6 - --struct QEMU_PACKED virtio_admin_cmd_hdr { -+struct virtio_admin_cmd_hdr { - uint16_t opcode; - /* - * 1 - SR-IOV -@@ -252,20 +252,20 @@ struct QEMU_PACKED virtio_admin_cmd_hdr { - uint64_t group_member_id; - }; - --struct QEMU_PACKED virtio_admin_cmd_status { -+struct virtio_admin_cmd_status { - uint16_t status; - uint16_t status_qualifier; - /* Unused, reserved for future extensions. */ - uint8_t reserved2[4]; - }; - --struct QEMU_PACKED virtio_admin_cmd_legacy_wr_data { -+struct virtio_admin_cmd_legacy_wr_data { - uint8_t offset; /* Starting offset of the register(s) to write. */ - uint8_t reserved[7]; - uint8_t registers[]; - }; - --struct QEMU_PACKED virtio_admin_cmd_legacy_rd_data { -+struct virtio_admin_cmd_legacy_rd_data { - uint8_t offset; /* Starting offset of the register(s) to read. */ - }; - -@@ -275,7 +275,7 @@ struct QEMU_PACKED virtio_admin_cmd_legacy_rd_data { - - #define VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO 4 - --struct QEMU_PACKED virtio_admin_cmd_notify_info_data { -+struct virtio_admin_cmd_notify_info_data { - uint8_t flags; /* 0 = end of list, 1 = owner device, 2 = member device */ - uint8_t bar; /* BAR of the member or the owner device */ - uint8_t padding[6]; -diff --git a/include/standard-headers/linux/virtio_snd.h b/include/standard-headers/linux/virtio_snd.h -index 1af96b9fc6..860f12e0a4 100644 ---- a/include/standard-headers/linux/virtio_snd.h -+++ b/include/standard-headers/linux/virtio_snd.h -@@ -7,6 +7,14 @@ - - #include "standard-headers/linux/virtio_types.h" - -+/******************************************************************************* -+ * FEATURE BITS -+ */ -+enum { -+ /* device supports control elements */ -+ VIRTIO_SND_F_CTLS = 0 -+}; -+ - /******************************************************************************* - * CONFIGURATION SPACE - */ -@@ -17,6 +25,8 @@ struct virtio_snd_config { - uint32_t streams; - /* # of available channel maps */ - uint32_t chmaps; -+ /* # of available control elements */ -+ uint32_t controls; - }; - - enum { -@@ -55,6 +65,15 @@ enum { - /* channel map control request types */ - VIRTIO_SND_R_CHMAP_INFO = 0x0200, - -+ /* control element request types */ -+ VIRTIO_SND_R_CTL_INFO = 0x0300, -+ VIRTIO_SND_R_CTL_ENUM_ITEMS, -+ VIRTIO_SND_R_CTL_READ, -+ VIRTIO_SND_R_CTL_WRITE, -+ VIRTIO_SND_R_CTL_TLV_READ, -+ VIRTIO_SND_R_CTL_TLV_WRITE, -+ VIRTIO_SND_R_CTL_TLV_COMMAND, -+ - /* jack event types */ - VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000, - VIRTIO_SND_EVT_JACK_DISCONNECTED, -@@ -63,6 +82,9 @@ enum { - VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100, - VIRTIO_SND_EVT_PCM_XRUN, - -+ /* control element event types */ -+ VIRTIO_SND_EVT_CTL_NOTIFY = 0x1200, -+ - /* common status codes */ - VIRTIO_SND_S_OK = 0x8000, - VIRTIO_SND_S_BAD_MSG, -@@ -331,4 +353,136 @@ struct virtio_snd_chmap_info { - uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE]; - }; - -+/******************************************************************************* -+ * CONTROL ELEMENTS MESSAGES -+ */ -+struct virtio_snd_ctl_hdr { -+ /* VIRTIO_SND_R_CTL_XXX */ -+ struct virtio_snd_hdr hdr; -+ /* 0 ... virtio_snd_config::controls - 1 */ -+ uint32_t control_id; -+}; -+ -+/* supported roles for control elements */ -+enum { -+ VIRTIO_SND_CTL_ROLE_UNDEFINED = 0, -+ VIRTIO_SND_CTL_ROLE_VOLUME, -+ VIRTIO_SND_CTL_ROLE_MUTE, -+ VIRTIO_SND_CTL_ROLE_GAIN -+}; -+ -+/* supported value types for control elements */ -+enum { -+ VIRTIO_SND_CTL_TYPE_BOOLEAN = 0, -+ VIRTIO_SND_CTL_TYPE_INTEGER, -+ VIRTIO_SND_CTL_TYPE_INTEGER64, -+ VIRTIO_SND_CTL_TYPE_ENUMERATED, -+ VIRTIO_SND_CTL_TYPE_BYTES, -+ VIRTIO_SND_CTL_TYPE_IEC958 -+}; -+ -+/* supported access rights for control elements */ -+enum { -+ VIRTIO_SND_CTL_ACCESS_READ = 0, -+ VIRTIO_SND_CTL_ACCESS_WRITE, -+ VIRTIO_SND_CTL_ACCESS_VOLATILE, -+ VIRTIO_SND_CTL_ACCESS_INACTIVE, -+ VIRTIO_SND_CTL_ACCESS_TLV_READ, -+ VIRTIO_SND_CTL_ACCESS_TLV_WRITE, -+ VIRTIO_SND_CTL_ACCESS_TLV_COMMAND -+}; -+ -+struct virtio_snd_ctl_info { -+ /* common header */ -+ struct virtio_snd_info hdr; -+ /* element role (VIRTIO_SND_CTL_ROLE_XXX) */ -+ uint32_t role; -+ /* element value type (VIRTIO_SND_CTL_TYPE_XXX) */ -+ uint32_t type; -+ /* element access right bit map (1 << VIRTIO_SND_CTL_ACCESS_XXX) */ -+ uint32_t access; -+ /* # of members in the element value */ -+ uint32_t count; -+ /* index for an element with a non-unique name */ -+ uint32_t index; -+ /* name identifier string for the element */ -+ uint8_t name[44]; -+ /* additional information about the element's value */ -+ union { -+ /* VIRTIO_SND_CTL_TYPE_INTEGER */ -+ struct { -+ /* minimum supported value */ -+ uint32_t min; -+ /* maximum supported value */ -+ uint32_t max; -+ /* fixed step size for value (0 = variable size) */ -+ uint32_t step; -+ } integer; -+ /* VIRTIO_SND_CTL_TYPE_INTEGER64 */ -+ struct { -+ /* minimum supported value */ -+ uint64_t min; -+ /* maximum supported value */ -+ uint64_t max; -+ /* fixed step size for value (0 = variable size) */ -+ uint64_t step; -+ } integer64; -+ /* VIRTIO_SND_CTL_TYPE_ENUMERATED */ -+ struct { -+ /* # of options supported for value */ -+ uint32_t items; -+ } enumerated; -+ } value; -+}; -+ -+struct virtio_snd_ctl_enum_item { -+ /* option name */ -+ uint8_t item[64]; -+}; -+ -+struct virtio_snd_ctl_iec958 { -+ /* AES/IEC958 channel status bits */ -+ uint8_t status[24]; -+ /* AES/IEC958 subcode bits */ -+ uint8_t subcode[147]; -+ /* nothing */ -+ uint8_t pad; -+ /* AES/IEC958 subframe bits */ -+ uint8_t dig_subframe[4]; -+}; -+ -+struct virtio_snd_ctl_value { -+ union { -+ /* VIRTIO_SND_CTL_TYPE_BOOLEAN|INTEGER value */ -+ uint32_t integer[128]; -+ /* VIRTIO_SND_CTL_TYPE_INTEGER64 value */ -+ uint64_t integer64[64]; -+ /* VIRTIO_SND_CTL_TYPE_ENUMERATED value (option indexes) */ -+ uint32_t enumerated[128]; -+ /* VIRTIO_SND_CTL_TYPE_BYTES value */ -+ uint8_t bytes[512]; -+ /* VIRTIO_SND_CTL_TYPE_IEC958 value */ -+ struct virtio_snd_ctl_iec958 iec958; -+ } value; -+}; -+ -+/* supported event reason types */ -+enum { -+ /* element's value has changed */ -+ VIRTIO_SND_CTL_EVT_MASK_VALUE = 0, -+ /* element's information has changed */ -+ VIRTIO_SND_CTL_EVT_MASK_INFO, -+ /* element's metadata has changed */ -+ VIRTIO_SND_CTL_EVT_MASK_TLV -+}; -+ -+struct virtio_snd_ctl_event { -+ /* VIRTIO_SND_EVT_CTL_NOTIFY */ -+ struct virtio_snd_hdr hdr; -+ /* 0 ... virtio_snd_config::controls - 1 */ -+ uint16_t control_id; -+ /* event reason bit map (1 << VIRTIO_SND_CTL_EVT_MASK_XXX) */ -+ uint16_t mask; -+}; -+ - #endif /* VIRTIO_SND_IF_H */ -diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h -index c59ea55cd8..2af9931ae9 100644 ---- a/linux-headers/asm-arm64/kvm.h -+++ b/linux-headers/asm-arm64/kvm.h -@@ -37,9 +37,7 @@ - #include - #include - --#define __KVM_HAVE_GUEST_DEBUG - #define __KVM_HAVE_IRQ_LINE --#define __KVM_HAVE_READONLY_MEM - #define __KVM_HAVE_VCPU_EVENTS - - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -@@ -76,11 +74,11 @@ struct kvm_regs { - - /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ - #define KVM_ARM_DEVICE_TYPE_SHIFT 0 --#define KVM_ARM_DEVICE_TYPE_MASK GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, \ -- KVM_ARM_DEVICE_TYPE_SHIFT) -+#define KVM_ARM_DEVICE_TYPE_MASK __GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, \ -+ KVM_ARM_DEVICE_TYPE_SHIFT) - #define KVM_ARM_DEVICE_ID_SHIFT 16 --#define KVM_ARM_DEVICE_ID_MASK GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, \ -- KVM_ARM_DEVICE_ID_SHIFT) -+#define KVM_ARM_DEVICE_ID_MASK __GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, \ -+ KVM_ARM_DEVICE_ID_SHIFT) - - /* Supported device IDs */ - #define KVM_ARM_DEVICE_VGIC_V2 0 -@@ -162,6 +160,11 @@ struct kvm_sync_regs { - __u64 device_irq_level; - }; - -+/* Bits for run->s.regs.device_irq_level */ -+#define KVM_ARM_DEV_EL1_VTIMER (1 << 0) -+#define KVM_ARM_DEV_EL1_PTIMER (1 << 1) -+#define KVM_ARM_DEV_PMU (1 << 2) -+ - /* - * PMU filter structure. Describe a range of events with a particular - * action. To be used with KVM_ARM_VCPU_PMU_V3_FILTER. -diff --git a/linux-headers/asm-arm64/sve_context.h b/linux-headers/asm-arm64/sve_context.h -index 1d0e3e1d09..d1b1ec8cb1 100644 ---- a/linux-headers/asm-arm64/sve_context.h -+++ b/linux-headers/asm-arm64/sve_context.h -@@ -13,6 +13,17 @@ - - #define __SVE_VQ_BYTES 16 /* number of bytes per quadword */ - -+/* -+ * Yes, __SVE_VQ_MAX is 512 QUADWORDS. -+ * -+ * To help ensure forward portability, this is much larger than the -+ * current maximum value defined by the SVE architecture. While arrays -+ * or static allocations can be sized based on this value, watch out! -+ * It will waste a surprisingly large amount of memory. -+ * -+ * Dynamic sizing based on the actual runtime vector length is likely to -+ * be preferable for most purposes. -+ */ - #define __SVE_VQ_MIN 1 - #define __SVE_VQ_MAX 512 - -diff --git a/linux-headers/asm-generic/bitsperlong.h b/linux-headers/asm-generic/bitsperlong.h -index 75f320fa91..1fb4f0c9f2 100644 ---- a/linux-headers/asm-generic/bitsperlong.h -+++ b/linux-headers/asm-generic/bitsperlong.h -@@ -24,4 +24,8 @@ - #endif - #endif - -+#ifndef __BITS_PER_LONG_LONG -+#define __BITS_PER_LONG_LONG 64 -+#endif -+ - #endif /* __ASM_GENERIC_BITS_PER_LONG */ -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index 923d0bd382..109785922c 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -14,8 +14,6 @@ - * Some parts derived from the x86 version of this file. - */ - --#define __KVM_HAVE_READONLY_MEM -- - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 - #define KVM_DIRTY_LOG_PAGE_OFFSET 64 - -diff --git a/linux-headers/asm-mips/kvm.h b/linux-headers/asm-mips/kvm.h -index edcf717c43..9673dc9cb3 100644 ---- a/linux-headers/asm-mips/kvm.h -+++ b/linux-headers/asm-mips/kvm.h -@@ -20,8 +20,6 @@ - * Some parts derived from the x86 version of this file. - */ - --#define __KVM_HAVE_READONLY_MEM -- - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 - - /* -diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h -index 9f18fa090f..1691297a76 100644 ---- a/linux-headers/asm-powerpc/kvm.h -+++ b/linux-headers/asm-powerpc/kvm.h -@@ -28,7 +28,6 @@ - #define __KVM_HAVE_PPC_SMT - #define __KVM_HAVE_IRQCHIP - #define __KVM_HAVE_IRQ_LINE --#define __KVM_HAVE_GUEST_DEBUG - - /* Not always available, but if it is, this is the correct offset. */ - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -@@ -733,4 +732,48 @@ struct kvm_ppc_xive_eq { - #define KVM_XIVE_TIMA_PAGE_OFFSET 0 - #define KVM_XIVE_ESB_PAGE_OFFSET 4 - -+/* for KVM_PPC_GET_PVINFO */ -+ -+#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) -+ -+struct kvm_ppc_pvinfo { -+ /* out */ -+ __u32 flags; -+ __u32 hcall[4]; -+ __u8 pad[108]; -+}; -+ -+/* for KVM_PPC_GET_SMMU_INFO */ -+#define KVM_PPC_PAGE_SIZES_MAX_SZ 8 -+ -+struct kvm_ppc_one_page_size { -+ __u32 page_shift; /* Page shift (or 0) */ -+ __u32 pte_enc; /* Encoding in the HPTE (>>12) */ -+}; -+ -+struct kvm_ppc_one_seg_page_size { -+ __u32 page_shift; /* Base page shift of segment (or 0) */ -+ __u32 slb_enc; /* SLB encoding for BookS */ -+ struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ]; -+}; -+ -+#define KVM_PPC_PAGE_SIZES_REAL 0x00000001 -+#define KVM_PPC_1T_SEGMENTS 0x00000002 -+#define KVM_PPC_NO_HASH 0x00000004 -+ -+struct kvm_ppc_smmu_info { -+ __u64 flags; -+ __u32 slb_size; -+ __u16 data_keys; /* # storage keys supported for data */ -+ __u16 instr_keys; /* # storage keys supported for instructions */ -+ struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; -+}; -+ -+/* for KVM_PPC_RESIZE_HPT_{PREPARE,COMMIT} */ -+struct kvm_ppc_resize_hpt { -+ __u64 flags; -+ __u32 shift; -+ __u32 pad; -+}; -+ - #endif /* __LINUX_KVM_POWERPC_H */ -diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h -index 7499e88a94..b1c503c295 100644 ---- a/linux-headers/asm-riscv/kvm.h -+++ b/linux-headers/asm-riscv/kvm.h -@@ -16,7 +16,6 @@ - #include - - #define __KVM_HAVE_IRQ_LINE --#define __KVM_HAVE_READONLY_MEM - - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 - -@@ -166,6 +165,8 @@ enum KVM_RISCV_ISA_EXT_ID { - KVM_RISCV_ISA_EXT_ZVFH, - KVM_RISCV_ISA_EXT_ZVFHMIN, - KVM_RISCV_ISA_EXT_ZFA, -+ KVM_RISCV_ISA_EXT_ZTSO, -+ KVM_RISCV_ISA_EXT_ZACAS, - KVM_RISCV_ISA_EXT_MAX, - }; - -diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h -index 023a2763a9..684c4e1205 100644 ---- a/linux-headers/asm-s390/kvm.h -+++ b/linux-headers/asm-s390/kvm.h -@@ -12,7 +12,320 @@ - #include - - #define __KVM_S390 --#define __KVM_HAVE_GUEST_DEBUG -+ -+struct kvm_s390_skeys { -+ __u64 start_gfn; -+ __u64 count; -+ __u64 skeydata_addr; -+ __u32 flags; -+ __u32 reserved[9]; -+}; -+ -+#define KVM_S390_CMMA_PEEK (1 << 0) -+ -+/** -+ * kvm_s390_cmma_log - Used for CMMA migration. -+ * -+ * Used both for input and output. -+ * -+ * @start_gfn: Guest page number to start from. -+ * @count: Size of the result buffer. -+ * @flags: Control operation mode via KVM_S390_CMMA_* flags -+ * @remaining: Used with KVM_S390_GET_CMMA_BITS. Indicates how many dirty -+ * pages are still remaining. -+ * @mask: Used with KVM_S390_SET_CMMA_BITS. Bitmap of bits to actually set -+ * in the PGSTE. -+ * @values: Pointer to the values buffer. -+ * -+ * Used in KVM_S390_{G,S}ET_CMMA_BITS ioctls. -+ */ -+struct kvm_s390_cmma_log { -+ __u64 start_gfn; -+ __u32 count; -+ __u32 flags; -+ union { -+ __u64 remaining; -+ __u64 mask; -+ }; -+ __u64 values; -+}; -+ -+#define KVM_S390_RESET_POR 1 -+#define KVM_S390_RESET_CLEAR 2 -+#define KVM_S390_RESET_SUBSYSTEM 4 -+#define KVM_S390_RESET_CPU_INIT 8 -+#define KVM_S390_RESET_IPL 16 -+ -+/* for KVM_S390_MEM_OP */ -+struct kvm_s390_mem_op { -+ /* in */ -+ __u64 gaddr; /* the guest address */ -+ __u64 flags; /* flags */ -+ __u32 size; /* amount of bytes */ -+ __u32 op; /* type of operation */ -+ __u64 buf; /* buffer in userspace */ -+ union { -+ struct { -+ __u8 ar; /* the access register number */ -+ __u8 key; /* access key, ignored if flag unset */ -+ __u8 pad1[6]; /* ignored */ -+ __u64 old_addr; /* ignored if cmpxchg flag unset */ -+ }; -+ __u32 sida_offset; /* offset into the sida */ -+ __u8 reserved[32]; /* ignored */ -+ }; -+}; -+/* types for kvm_s390_mem_op->op */ -+#define KVM_S390_MEMOP_LOGICAL_READ 0 -+#define KVM_S390_MEMOP_LOGICAL_WRITE 1 -+#define KVM_S390_MEMOP_SIDA_READ 2 -+#define KVM_S390_MEMOP_SIDA_WRITE 3 -+#define KVM_S390_MEMOP_ABSOLUTE_READ 4 -+#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5 -+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6 -+ -+/* flags for kvm_s390_mem_op->flags */ -+#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) -+#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) -+#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2) -+ -+/* flags specifying extension support via KVM_CAP_S390_MEM_OP_EXTENSION */ -+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0) -+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1) -+ -+struct kvm_s390_psw { -+ __u64 mask; -+ __u64 addr; -+}; -+ -+/* valid values for type in kvm_s390_interrupt */ -+#define KVM_S390_SIGP_STOP 0xfffe0000u -+#define KVM_S390_PROGRAM_INT 0xfffe0001u -+#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u -+#define KVM_S390_RESTART 0xfffe0003u -+#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u -+#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u -+#define KVM_S390_MCHK 0xfffe1000u -+#define KVM_S390_INT_CLOCK_COMP 0xffff1004u -+#define KVM_S390_INT_CPU_TIMER 0xffff1005u -+#define KVM_S390_INT_VIRTIO 0xffff2603u -+#define KVM_S390_INT_SERVICE 0xffff2401u -+#define KVM_S390_INT_EMERGENCY 0xffff1201u -+#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u -+/* Anything below 0xfffe0000u is taken by INT_IO */ -+#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \ -+ (((schid)) | \ -+ ((ssid) << 16) | \ -+ ((cssid) << 18) | \ -+ ((ai) << 26)) -+#define KVM_S390_INT_IO_MIN 0x00000000u -+#define KVM_S390_INT_IO_MAX 0xfffdffffu -+#define KVM_S390_INT_IO_AI_MASK 0x04000000u -+ -+ -+struct kvm_s390_interrupt { -+ __u32 type; -+ __u32 parm; -+ __u64 parm64; -+}; -+ -+struct kvm_s390_io_info { -+ __u16 subchannel_id; -+ __u16 subchannel_nr; -+ __u32 io_int_parm; -+ __u32 io_int_word; -+}; -+ -+struct kvm_s390_ext_info { -+ __u32 ext_params; -+ __u32 pad; -+ __u64 ext_params2; -+}; -+ -+struct kvm_s390_pgm_info { -+ __u64 trans_exc_code; -+ __u64 mon_code; -+ __u64 per_address; -+ __u32 data_exc_code; -+ __u16 code; -+ __u16 mon_class_nr; -+ __u8 per_code; -+ __u8 per_atmid; -+ __u8 exc_access_id; -+ __u8 per_access_id; -+ __u8 op_access_id; -+#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01 -+#define KVM_S390_PGM_FLAGS_ILC_0 0x02 -+#define KVM_S390_PGM_FLAGS_ILC_1 0x04 -+#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06 -+#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08 -+ __u8 flags; -+ __u8 pad[2]; -+}; -+ -+struct kvm_s390_prefix_info { -+ __u32 address; -+}; -+ -+struct kvm_s390_extcall_info { -+ __u16 code; -+}; -+ -+struct kvm_s390_emerg_info { -+ __u16 code; -+}; -+ -+#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01 -+struct kvm_s390_stop_info { -+ __u32 flags; -+}; -+ -+struct kvm_s390_mchk_info { -+ __u64 cr14; -+ __u64 mcic; -+ __u64 failing_storage_address; -+ __u32 ext_damage_code; -+ __u32 pad; -+ __u8 fixed_logout[16]; -+}; -+ -+struct kvm_s390_irq { -+ __u64 type; -+ union { -+ struct kvm_s390_io_info io; -+ struct kvm_s390_ext_info ext; -+ struct kvm_s390_pgm_info pgm; -+ struct kvm_s390_emerg_info emerg; -+ struct kvm_s390_extcall_info extcall; -+ struct kvm_s390_prefix_info prefix; -+ struct kvm_s390_stop_info stop; -+ struct kvm_s390_mchk_info mchk; -+ char reserved[64]; -+ } u; -+}; -+ -+struct kvm_s390_irq_state { -+ __u64 buf; -+ __u32 flags; /* will stay unused for compatibility reasons */ -+ __u32 len; -+ __u32 reserved[4]; /* will stay unused for compatibility reasons */ -+}; -+ -+struct kvm_s390_ucas_mapping { -+ __u64 user_addr; -+ __u64 vcpu_addr; -+ __u64 length; -+}; -+ -+struct kvm_s390_pv_sec_parm { -+ __u64 origin; -+ __u64 length; -+}; -+ -+struct kvm_s390_pv_unp { -+ __u64 addr; -+ __u64 size; -+ __u64 tweak; -+}; -+ -+enum pv_cmd_dmp_id { -+ KVM_PV_DUMP_INIT, -+ KVM_PV_DUMP_CONFIG_STOR_STATE, -+ KVM_PV_DUMP_COMPLETE, -+ KVM_PV_DUMP_CPU, -+}; -+ -+struct kvm_s390_pv_dmp { -+ __u64 subcmd; -+ __u64 buff_addr; -+ __u64 buff_len; -+ __u64 gaddr; /* For dump storage state */ -+ __u64 reserved[4]; -+}; -+ -+enum pv_cmd_info_id { -+ KVM_PV_INFO_VM, -+ KVM_PV_INFO_DUMP, -+}; -+ -+struct kvm_s390_pv_info_dump { -+ __u64 dump_cpu_buffer_len; -+ __u64 dump_config_mem_buffer_per_1m; -+ __u64 dump_config_finalize_len; -+}; -+ -+struct kvm_s390_pv_info_vm { -+ __u64 inst_calls_list[4]; -+ __u64 max_cpus; -+ __u64 max_guests; -+ __u64 max_guest_addr; -+ __u64 feature_indication; -+}; -+ -+struct kvm_s390_pv_info_header { -+ __u32 id; -+ __u32 len_max; -+ __u32 len_written; -+ __u32 reserved; -+}; -+ -+struct kvm_s390_pv_info { -+ struct kvm_s390_pv_info_header header; -+ union { -+ struct kvm_s390_pv_info_dump dump; -+ struct kvm_s390_pv_info_vm vm; -+ }; -+}; -+ -+enum pv_cmd_id { -+ KVM_PV_ENABLE, -+ KVM_PV_DISABLE, -+ KVM_PV_SET_SEC_PARMS, -+ KVM_PV_UNPACK, -+ KVM_PV_VERIFY, -+ KVM_PV_PREP_RESET, -+ KVM_PV_UNSHARE_ALL, -+ KVM_PV_INFO, -+ KVM_PV_DUMP, -+ KVM_PV_ASYNC_CLEANUP_PREPARE, -+ KVM_PV_ASYNC_CLEANUP_PERFORM, -+}; -+ -+struct kvm_pv_cmd { -+ __u32 cmd; /* Command to be executed */ -+ __u16 rc; /* Ultravisor return code */ -+ __u16 rrc; /* Ultravisor return reason code */ -+ __u64 data; /* Data or address */ -+ __u32 flags; /* flags for future extensions. Must be 0 for now */ -+ __u32 reserved[3]; -+}; -+ -+struct kvm_s390_zpci_op { -+ /* in */ -+ __u32 fh; /* target device */ -+ __u8 op; /* operation to perform */ -+ __u8 pad[3]; -+ union { -+ /* for KVM_S390_ZPCIOP_REG_AEN */ -+ struct { -+ __u64 ibv; /* Guest addr of interrupt bit vector */ -+ __u64 sb; /* Guest addr of summary bit */ -+ __u32 flags; -+ __u32 noi; /* Number of interrupts */ -+ __u8 isc; /* Guest interrupt subclass */ -+ __u8 sbo; /* Offset of guest summary bit vector */ -+ __u16 pad; -+ } reg_aen; -+ __u64 reserved[8]; -+ } u; -+}; -+ -+/* types for kvm_s390_zpci_op->op */ -+#define KVM_S390_ZPCIOP_REG_AEN 0 -+#define KVM_S390_ZPCIOP_DEREG_AEN 1 -+ -+/* flags for kvm_s390_zpci_op->u.reg_aen.flags */ -+#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0) - - /* Device control API: s390-specific devices */ - #define KVM_DEV_FLIC_GET_ALL_IRQS 1 -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index 003fb74534..31c95c2dfe 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -7,6 +7,8 @@ - * - */ - -+#include -+#include - #include - #include - #include -@@ -40,7 +42,6 @@ - #define __KVM_HAVE_IRQ_LINE - #define __KVM_HAVE_MSI - #define __KVM_HAVE_USER_NMI --#define __KVM_HAVE_GUEST_DEBUG - #define __KVM_HAVE_MSIX - #define __KVM_HAVE_MCE - #define __KVM_HAVE_PIT_STATE2 -@@ -49,7 +50,6 @@ - #define __KVM_HAVE_DEBUGREGS - #define __KVM_HAVE_XSAVE - #define __KVM_HAVE_XCRS --#define __KVM_HAVE_READONLY_MEM - - /* Architectural interrupt line count. */ - #define KVM_NR_INTERRUPTS 256 -@@ -455,8 +455,13 @@ struct kvm_sync_regs { - - #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 - --/* attributes for system fd (group 0) */ --#define KVM_X86_XCOMP_GUEST_SUPP 0 -+/* vendor-independent attributes for system fd (group 0) */ -+#define KVM_X86_GRP_SYSTEM 0 -+# define KVM_X86_XCOMP_GUEST_SUPP 0 -+ -+/* vendor-specific groups and attributes for system fd */ -+#define KVM_X86_GRP_SEV 1 -+# define KVM_X86_SEV_VMSA_FEATURES 0 - - struct kvm_vmx_nested_state_data { - __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; -@@ -524,9 +529,310 @@ struct kvm_pmu_event_filter { - #define KVM_PMU_EVENT_ALLOW 0 - #define KVM_PMU_EVENT_DENY 1 - --#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0) -+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS _BITUL(0) - #define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS) - -+/* for KVM_CAP_MCE */ -+struct kvm_x86_mce { -+ __u64 status; -+ __u64 addr; -+ __u64 misc; -+ __u64 mcg_status; -+ __u8 bank; -+ __u8 pad1[7]; -+ __u64 pad2[3]; -+}; -+ -+/* for KVM_CAP_XEN_HVM */ -+#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0) -+#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) -+#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) -+#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) -+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4) -+#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5) -+#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6) -+#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7) -+#define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA (1 << 8) -+ -+struct kvm_xen_hvm_config { -+ __u32 flags; -+ __u32 msr; -+ __u64 blob_addr_32; -+ __u64 blob_addr_64; -+ __u8 blob_size_32; -+ __u8 blob_size_64; -+ __u8 pad2[30]; -+}; -+ -+struct kvm_xen_hvm_attr { -+ __u16 type; -+ __u16 pad[3]; -+ union { -+ __u8 long_mode; -+ __u8 vector; -+ __u8 runstate_update_flag; -+ union { -+ __u64 gfn; -+#define KVM_XEN_INVALID_GFN ((__u64)-1) -+ __u64 hva; -+ } shared_info; -+ struct { -+ __u32 send_port; -+ __u32 type; /* EVTCHNSTAT_ipi / EVTCHNSTAT_interdomain */ -+ __u32 flags; -+#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0) -+#define KVM_XEN_EVTCHN_UPDATE (1 << 1) -+#define KVM_XEN_EVTCHN_RESET (1 << 2) -+ /* -+ * Events sent by the guest are either looped back to -+ * the guest itself (potentially on a different port#) -+ * or signalled via an eventfd. -+ */ -+ union { -+ struct { -+ __u32 port; -+ __u32 vcpu; -+ __u32 priority; -+ } port; -+ struct { -+ __u32 port; /* Zero for eventfd */ -+ __s32 fd; -+ } eventfd; -+ __u32 padding[4]; -+ } deliver; -+ } evtchn; -+ __u32 xen_version; -+ __u64 pad[8]; -+ } u; -+}; -+ -+ -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ -+#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 -+#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 -+#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2 -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ -+#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3 -+#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4 -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG */ -+#define KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG 0x5 -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA */ -+#define KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA 0x6 -+ -+struct kvm_xen_vcpu_attr { -+ __u16 type; -+ __u16 pad[3]; -+ union { -+ __u64 gpa; -+#define KVM_XEN_INVALID_GPA ((__u64)-1) -+ __u64 hva; -+ __u64 pad[8]; -+ struct { -+ __u64 state; -+ __u64 state_entry_time; -+ __u64 time_running; -+ __u64 time_runnable; -+ __u64 time_blocked; -+ __u64 time_offline; -+ } runstate; -+ __u32 vcpu_id; -+ struct { -+ __u32 port; -+ __u32 priority; -+ __u64 expires_ns; -+ } timer; -+ __u8 vector; -+ } u; -+}; -+ -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ -+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0 -+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1 -+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2 -+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3 -+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4 -+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5 -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ -+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6 -+#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7 -+#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8 -+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA */ -+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA 0x9 -+ -+/* Secure Encrypted Virtualization command */ -+enum sev_cmd_id { -+ /* Guest initialization commands */ -+ KVM_SEV_INIT = 0, -+ KVM_SEV_ES_INIT, -+ /* Guest launch commands */ -+ KVM_SEV_LAUNCH_START, -+ KVM_SEV_LAUNCH_UPDATE_DATA, -+ KVM_SEV_LAUNCH_UPDATE_VMSA, -+ KVM_SEV_LAUNCH_SECRET, -+ KVM_SEV_LAUNCH_MEASURE, -+ KVM_SEV_LAUNCH_FINISH, -+ /* Guest migration commands (outgoing) */ -+ KVM_SEV_SEND_START, -+ KVM_SEV_SEND_UPDATE_DATA, -+ KVM_SEV_SEND_UPDATE_VMSA, -+ KVM_SEV_SEND_FINISH, -+ /* Guest migration commands (incoming) */ -+ KVM_SEV_RECEIVE_START, -+ KVM_SEV_RECEIVE_UPDATE_DATA, -+ KVM_SEV_RECEIVE_UPDATE_VMSA, -+ KVM_SEV_RECEIVE_FINISH, -+ /* Guest status and debug commands */ -+ KVM_SEV_GUEST_STATUS, -+ KVM_SEV_DBG_DECRYPT, -+ KVM_SEV_DBG_ENCRYPT, -+ /* Guest certificates commands */ -+ KVM_SEV_CERT_EXPORT, -+ /* Attestation report */ -+ KVM_SEV_GET_ATTESTATION_REPORT, -+ /* Guest Migration Extension */ -+ KVM_SEV_SEND_CANCEL, -+ -+ /* Second time is the charm; improved versions of the above ioctls. */ -+ KVM_SEV_INIT2, -+ -+ KVM_SEV_NR_MAX, -+}; -+ -+struct kvm_sev_cmd { -+ __u32 id; -+ __u32 pad0; -+ __u64 data; -+ __u32 error; -+ __u32 sev_fd; -+}; -+ -+struct kvm_sev_init { -+ __u64 vmsa_features; -+ __u32 flags; -+ __u32 pad[9]; -+}; -+ -+struct kvm_sev_launch_start { -+ __u32 handle; -+ __u32 policy; -+ __u64 dh_uaddr; -+ __u32 dh_len; -+ __u32 pad0; -+ __u64 session_uaddr; -+ __u32 session_len; -+ __u32 pad1; -+}; -+ -+struct kvm_sev_launch_update_data { -+ __u64 uaddr; -+ __u32 len; -+ __u32 pad0; -+}; -+ -+ -+struct kvm_sev_launch_secret { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u32 pad0; -+ __u64 guest_uaddr; -+ __u32 guest_len; -+ __u32 pad1; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+ __u32 pad2; -+}; -+ -+struct kvm_sev_launch_measure { -+ __u64 uaddr; -+ __u32 len; -+ __u32 pad0; -+}; -+ -+struct kvm_sev_guest_status { -+ __u32 handle; -+ __u32 policy; -+ __u32 state; -+}; -+ -+struct kvm_sev_dbg { -+ __u64 src_uaddr; -+ __u64 dst_uaddr; -+ __u32 len; -+ __u32 pad0; -+}; -+ -+struct kvm_sev_attestation_report { -+ __u8 mnonce[16]; -+ __u64 uaddr; -+ __u32 len; -+ __u32 pad0; -+}; -+ -+struct kvm_sev_send_start { -+ __u32 policy; -+ __u32 pad0; -+ __u64 pdh_cert_uaddr; -+ __u32 pdh_cert_len; -+ __u32 pad1; -+ __u64 plat_certs_uaddr; -+ __u32 plat_certs_len; -+ __u32 pad2; -+ __u64 amd_certs_uaddr; -+ __u32 amd_certs_len; -+ __u32 pad3; -+ __u64 session_uaddr; -+ __u32 session_len; -+ __u32 pad4; -+}; -+ -+struct kvm_sev_send_update_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u32 pad0; -+ __u64 guest_uaddr; -+ __u32 guest_len; -+ __u32 pad1; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+ __u32 pad2; -+}; -+ -+struct kvm_sev_receive_start { -+ __u32 handle; -+ __u32 policy; -+ __u64 pdh_uaddr; -+ __u32 pdh_len; -+ __u32 pad0; -+ __u64 session_uaddr; -+ __u32 session_len; -+ __u32 pad1; -+}; -+ -+struct kvm_sev_receive_update_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u32 pad0; -+ __u64 guest_uaddr; -+ __u32 guest_len; -+ __u32 pad1; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+ __u32 pad2; -+}; -+ -+#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) -+#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) -+ -+struct kvm_hyperv_eventfd { -+ __u32 conn_id; -+ __s32 fd; -+ __u32 flags; -+ __u32 padding[3]; -+}; -+ -+#define KVM_HYPERV_CONN_ID_MASK 0x00ffffff -+#define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0) -+ - /* - * Masked event layout. - * Bits Description -@@ -547,10 +853,10 @@ struct kvm_pmu_event_filter { - ((__u64)(!!(exclude)) << 55)) - - #define KVM_PMU_MASKED_ENTRY_EVENT_SELECT \ -- (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32)) --#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (GENMASK_ULL(63, 56)) --#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (GENMASK_ULL(15, 8)) --#define KVM_PMU_MASKED_ENTRY_EXCLUDE (BIT_ULL(55)) -+ (__GENMASK_ULL(7, 0) | __GENMASK_ULL(35, 32)) -+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (__GENMASK_ULL(63, 56)) -+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (__GENMASK_ULL(15, 8)) -+#define KVM_PMU_MASKED_ENTRY_EXCLUDE (_BITULL(55)) - #define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56) - - /* for KVM_{GET,SET,HAS}_DEVICE_ATTR */ -@@ -558,9 +864,11 @@ struct kvm_pmu_event_filter { - #define KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */ - - /* x86-specific KVM_EXIT_HYPERCALL flags. */ --#define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0) -+#define KVM_EXIT_HYPERCALL_LONG_MODE _BITULL(0) - - #define KVM_X86_DEFAULT_VM 0 - #define KVM_X86_SW_PROTECTED_VM 1 -+#define KVM_X86_SEV_VM 2 -+#define KVM_X86_SEV_ES_VM 3 - - #endif /* _ASM_X86_KVM_H */ -diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h -new file mode 100644 -index 0000000000..d9897771be ---- /dev/null -+++ b/linux-headers/linux/bits.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* bits.h: Macros for dealing with bitmasks. */ -+ -+#ifndef _LINUX_BITS_H -+#define _LINUX_BITS_H -+ -+#define __GENMASK(h, l) \ -+ (((~_UL(0)) - (_UL(1) << (l)) + 1) & \ -+ (~_UL(0) >> (__BITS_PER_LONG - 1 - (h)))) -+ -+#define __GENMASK_ULL(h, l) \ -+ (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & \ -+ (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h)))) -+ -+#endif /* _LINUX_BITS_H */ -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 17839229b2..038731cdef 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -16,6 +16,11 @@ - - #define KVM_API_VERSION 12 - -+/* -+ * Backwards-compatible definitions. -+ */ -+#define __KVM_HAVE_GUEST_DEBUG -+ - /* for KVM_SET_USER_MEMORY_REGION */ - struct kvm_userspace_memory_region { - __u32 slot; -@@ -85,43 +90,6 @@ struct kvm_pit_config { - - #define KVM_PIT_SPEAKER_DUMMY 1 - --struct kvm_s390_skeys { -- __u64 start_gfn; -- __u64 count; -- __u64 skeydata_addr; -- __u32 flags; -- __u32 reserved[9]; --}; -- --#define KVM_S390_CMMA_PEEK (1 << 0) -- --/** -- * kvm_s390_cmma_log - Used for CMMA migration. -- * -- * Used both for input and output. -- * -- * @start_gfn: Guest page number to start from. -- * @count: Size of the result buffer. -- * @flags: Control operation mode via KVM_S390_CMMA_* flags -- * @remaining: Used with KVM_S390_GET_CMMA_BITS. Indicates how many dirty -- * pages are still remaining. -- * @mask: Used with KVM_S390_SET_CMMA_BITS. Bitmap of bits to actually set -- * in the PGSTE. -- * @values: Pointer to the values buffer. -- * -- * Used in KVM_S390_{G,S}ET_CMMA_BITS ioctls. -- */ --struct kvm_s390_cmma_log { -- __u64 start_gfn; -- __u32 count; -- __u32 flags; -- union { -- __u64 remaining; -- __u64 mask; -- }; -- __u64 values; --}; -- - struct kvm_hyperv_exit { - #define KVM_EXIT_HYPERV_SYNIC 1 - #define KVM_EXIT_HYPERV_HCALL 2 -@@ -313,11 +281,6 @@ struct kvm_run { - __u32 ipb; - } s390_sieic; - /* KVM_EXIT_S390_RESET */ --#define KVM_S390_RESET_POR 1 --#define KVM_S390_RESET_CLEAR 2 --#define KVM_S390_RESET_SUBSYSTEM 4 --#define KVM_S390_RESET_CPU_INIT 8 --#define KVM_S390_RESET_IPL 16 - __u64 s390_reset_flags; - /* KVM_EXIT_S390_UCONTROL */ - struct { -@@ -532,43 +495,6 @@ struct kvm_translation { - __u8 pad[5]; - }; - --/* for KVM_S390_MEM_OP */ --struct kvm_s390_mem_op { -- /* in */ -- __u64 gaddr; /* the guest address */ -- __u64 flags; /* flags */ -- __u32 size; /* amount of bytes */ -- __u32 op; /* type of operation */ -- __u64 buf; /* buffer in userspace */ -- union { -- struct { -- __u8 ar; /* the access register number */ -- __u8 key; /* access key, ignored if flag unset */ -- __u8 pad1[6]; /* ignored */ -- __u64 old_addr; /* ignored if cmpxchg flag unset */ -- }; -- __u32 sida_offset; /* offset into the sida */ -- __u8 reserved[32]; /* ignored */ -- }; --}; --/* types for kvm_s390_mem_op->op */ --#define KVM_S390_MEMOP_LOGICAL_READ 0 --#define KVM_S390_MEMOP_LOGICAL_WRITE 1 --#define KVM_S390_MEMOP_SIDA_READ 2 --#define KVM_S390_MEMOP_SIDA_WRITE 3 --#define KVM_S390_MEMOP_ABSOLUTE_READ 4 --#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5 --#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6 -- --/* flags for kvm_s390_mem_op->flags */ --#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) --#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) --#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2) -- --/* flags specifying extension support via KVM_CAP_S390_MEM_OP_EXTENSION */ --#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0) --#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1) -- - /* for KVM_INTERRUPT */ - struct kvm_interrupt { - /* in */ -@@ -633,124 +559,6 @@ struct kvm_mp_state { - __u32 mp_state; - }; - --struct kvm_s390_psw { -- __u64 mask; -- __u64 addr; --}; -- --/* valid values for type in kvm_s390_interrupt */ --#define KVM_S390_SIGP_STOP 0xfffe0000u --#define KVM_S390_PROGRAM_INT 0xfffe0001u --#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u --#define KVM_S390_RESTART 0xfffe0003u --#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u --#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u --#define KVM_S390_MCHK 0xfffe1000u --#define KVM_S390_INT_CLOCK_COMP 0xffff1004u --#define KVM_S390_INT_CPU_TIMER 0xffff1005u --#define KVM_S390_INT_VIRTIO 0xffff2603u --#define KVM_S390_INT_SERVICE 0xffff2401u --#define KVM_S390_INT_EMERGENCY 0xffff1201u --#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u --/* Anything below 0xfffe0000u is taken by INT_IO */ --#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \ -- (((schid)) | \ -- ((ssid) << 16) | \ -- ((cssid) << 18) | \ -- ((ai) << 26)) --#define KVM_S390_INT_IO_MIN 0x00000000u --#define KVM_S390_INT_IO_MAX 0xfffdffffu --#define KVM_S390_INT_IO_AI_MASK 0x04000000u -- -- --struct kvm_s390_interrupt { -- __u32 type; -- __u32 parm; -- __u64 parm64; --}; -- --struct kvm_s390_io_info { -- __u16 subchannel_id; -- __u16 subchannel_nr; -- __u32 io_int_parm; -- __u32 io_int_word; --}; -- --struct kvm_s390_ext_info { -- __u32 ext_params; -- __u32 pad; -- __u64 ext_params2; --}; -- --struct kvm_s390_pgm_info { -- __u64 trans_exc_code; -- __u64 mon_code; -- __u64 per_address; -- __u32 data_exc_code; -- __u16 code; -- __u16 mon_class_nr; -- __u8 per_code; -- __u8 per_atmid; -- __u8 exc_access_id; -- __u8 per_access_id; -- __u8 op_access_id; --#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01 --#define KVM_S390_PGM_FLAGS_ILC_0 0x02 --#define KVM_S390_PGM_FLAGS_ILC_1 0x04 --#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06 --#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08 -- __u8 flags; -- __u8 pad[2]; --}; -- --struct kvm_s390_prefix_info { -- __u32 address; --}; -- --struct kvm_s390_extcall_info { -- __u16 code; --}; -- --struct kvm_s390_emerg_info { -- __u16 code; --}; -- --#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01 --struct kvm_s390_stop_info { -- __u32 flags; --}; -- --struct kvm_s390_mchk_info { -- __u64 cr14; -- __u64 mcic; -- __u64 failing_storage_address; -- __u32 ext_damage_code; -- __u32 pad; -- __u8 fixed_logout[16]; --}; -- --struct kvm_s390_irq { -- __u64 type; -- union { -- struct kvm_s390_io_info io; -- struct kvm_s390_ext_info ext; -- struct kvm_s390_pgm_info pgm; -- struct kvm_s390_emerg_info emerg; -- struct kvm_s390_extcall_info extcall; -- struct kvm_s390_prefix_info prefix; -- struct kvm_s390_stop_info stop; -- struct kvm_s390_mchk_info mchk; -- char reserved[64]; -- } u; --}; -- --struct kvm_s390_irq_state { -- __u64 buf; -- __u32 flags; /* will stay unused for compatibility reasons */ -- __u32 len; -- __u32 reserved[4]; /* will stay unused for compatibility reasons */ --}; -- - /* for KVM_SET_GUEST_DEBUG */ - - #define KVM_GUESTDBG_ENABLE 0x00000001 -@@ -806,50 +614,6 @@ struct kvm_enable_cap { - __u8 pad[64]; - }; - --/* for KVM_PPC_GET_PVINFO */ -- --#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) -- --struct kvm_ppc_pvinfo { -- /* out */ -- __u32 flags; -- __u32 hcall[4]; -- __u8 pad[108]; --}; -- --/* for KVM_PPC_GET_SMMU_INFO */ --#define KVM_PPC_PAGE_SIZES_MAX_SZ 8 -- --struct kvm_ppc_one_page_size { -- __u32 page_shift; /* Page shift (or 0) */ -- __u32 pte_enc; /* Encoding in the HPTE (>>12) */ --}; -- --struct kvm_ppc_one_seg_page_size { -- __u32 page_shift; /* Base page shift of segment (or 0) */ -- __u32 slb_enc; /* SLB encoding for BookS */ -- struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ]; --}; -- --#define KVM_PPC_PAGE_SIZES_REAL 0x00000001 --#define KVM_PPC_1T_SEGMENTS 0x00000002 --#define KVM_PPC_NO_HASH 0x00000004 -- --struct kvm_ppc_smmu_info { -- __u64 flags; -- __u32 slb_size; -- __u16 data_keys; /* # storage keys supported for data */ -- __u16 instr_keys; /* # storage keys supported for instructions */ -- struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; --}; -- --/* for KVM_PPC_RESIZE_HPT_{PREPARE,COMMIT} */ --struct kvm_ppc_resize_hpt { -- __u64 flags; -- __u32 shift; -- __u32 pad; --}; -- - #define KVMIO 0xAE - - /* machine type bits, to be used as argument to KVM_CREATE_VM */ -@@ -919,9 +683,7 @@ struct kvm_ppc_resize_hpt { - /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ - #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 - #define KVM_CAP_USER_NMI 22 --#ifdef __KVM_HAVE_GUEST_DEBUG - #define KVM_CAP_SET_GUEST_DEBUG 23 --#endif - #ifdef __KVM_HAVE_PIT - #define KVM_CAP_REINJECT_CONTROL 24 - #endif -@@ -1152,8 +914,6 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_GUEST_MEMFD 234 - #define KVM_CAP_VM_TYPES 235 - --#ifdef KVM_CAP_IRQ_ROUTING -- - struct kvm_irq_routing_irqchip { - __u32 irqchip; - __u32 pin; -@@ -1218,42 +978,6 @@ struct kvm_irq_routing { - struct kvm_irq_routing_entry entries[]; - }; - --#endif -- --#ifdef KVM_CAP_MCE --/* x86 MCE */ --struct kvm_x86_mce { -- __u64 status; -- __u64 addr; -- __u64 misc; -- __u64 mcg_status; -- __u8 bank; -- __u8 pad1[7]; -- __u64 pad2[3]; --}; --#endif -- --#ifdef KVM_CAP_XEN_HVM --#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0) --#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1) --#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) --#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) --#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4) --#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5) --#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6) --#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7) -- --struct kvm_xen_hvm_config { -- __u32 flags; -- __u32 msr; -- __u64 blob_addr_32; -- __u64 blob_addr_64; -- __u8 blob_size_32; -- __u8 blob_size_64; -- __u8 pad2[30]; --}; --#endif -- - #define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) - /* - * Available with KVM_CAP_IRQFD_RESAMPLE -@@ -1438,11 +1162,6 @@ struct kvm_vfio_spapr_tce { - struct kvm_userspace_memory_region2) - - /* enable ucontrol for s390 */ --struct kvm_s390_ucas_mapping { -- __u64 user_addr; -- __u64 vcpu_addr; -- __u64 length; --}; - #define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) - #define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) - #define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long) -@@ -1637,89 +1356,6 @@ struct kvm_enc_region { - #define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3) - #define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4) - --struct kvm_s390_pv_sec_parm { -- __u64 origin; -- __u64 length; --}; -- --struct kvm_s390_pv_unp { -- __u64 addr; -- __u64 size; -- __u64 tweak; --}; -- --enum pv_cmd_dmp_id { -- KVM_PV_DUMP_INIT, -- KVM_PV_DUMP_CONFIG_STOR_STATE, -- KVM_PV_DUMP_COMPLETE, -- KVM_PV_DUMP_CPU, --}; -- --struct kvm_s390_pv_dmp { -- __u64 subcmd; -- __u64 buff_addr; -- __u64 buff_len; -- __u64 gaddr; /* For dump storage state */ -- __u64 reserved[4]; --}; -- --enum pv_cmd_info_id { -- KVM_PV_INFO_VM, -- KVM_PV_INFO_DUMP, --}; -- --struct kvm_s390_pv_info_dump { -- __u64 dump_cpu_buffer_len; -- __u64 dump_config_mem_buffer_per_1m; -- __u64 dump_config_finalize_len; --}; -- --struct kvm_s390_pv_info_vm { -- __u64 inst_calls_list[4]; -- __u64 max_cpus; -- __u64 max_guests; -- __u64 max_guest_addr; -- __u64 feature_indication; --}; -- --struct kvm_s390_pv_info_header { -- __u32 id; -- __u32 len_max; -- __u32 len_written; -- __u32 reserved; --}; -- --struct kvm_s390_pv_info { -- struct kvm_s390_pv_info_header header; -- union { -- struct kvm_s390_pv_info_dump dump; -- struct kvm_s390_pv_info_vm vm; -- }; --}; -- --enum pv_cmd_id { -- KVM_PV_ENABLE, -- KVM_PV_DISABLE, -- KVM_PV_SET_SEC_PARMS, -- KVM_PV_UNPACK, -- KVM_PV_VERIFY, -- KVM_PV_PREP_RESET, -- KVM_PV_UNSHARE_ALL, -- KVM_PV_INFO, -- KVM_PV_DUMP, -- KVM_PV_ASYNC_CLEANUP_PREPARE, -- KVM_PV_ASYNC_CLEANUP_PERFORM, --}; -- --struct kvm_pv_cmd { -- __u32 cmd; /* Command to be executed */ -- __u16 rc; /* Ultravisor return code */ -- __u16 rrc; /* Ultravisor return reason code */ -- __u64 data; /* Data or address */ -- __u32 flags; /* flags for future extensions. Must be 0 for now */ -- __u32 reserved[3]; --}; -- - /* Available with KVM_CAP_S390_PROTECTED */ - #define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd) - -@@ -1733,58 +1369,6 @@ struct kvm_pv_cmd { - #define KVM_XEN_HVM_GET_ATTR _IOWR(KVMIO, 0xc8, struct kvm_xen_hvm_attr) - #define KVM_XEN_HVM_SET_ATTR _IOW(KVMIO, 0xc9, struct kvm_xen_hvm_attr) - --struct kvm_xen_hvm_attr { -- __u16 type; -- __u16 pad[3]; -- union { -- __u8 long_mode; -- __u8 vector; -- __u8 runstate_update_flag; -- struct { -- __u64 gfn; --#define KVM_XEN_INVALID_GFN ((__u64)-1) -- } shared_info; -- struct { -- __u32 send_port; -- __u32 type; /* EVTCHNSTAT_ipi / EVTCHNSTAT_interdomain */ -- __u32 flags; --#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0) --#define KVM_XEN_EVTCHN_UPDATE (1 << 1) --#define KVM_XEN_EVTCHN_RESET (1 << 2) -- /* -- * Events sent by the guest are either looped back to -- * the guest itself (potentially on a different port#) -- * or signalled via an eventfd. -- */ -- union { -- struct { -- __u32 port; -- __u32 vcpu; -- __u32 priority; -- } port; -- struct { -- __u32 port; /* Zero for eventfd */ -- __s32 fd; -- } eventfd; -- __u32 padding[4]; -- } deliver; -- } evtchn; -- __u32 xen_version; -- __u64 pad[8]; -- } u; --}; -- -- --/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ --#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 --#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 --#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2 --/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ --#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3 --#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4 --/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG */ --#define KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG 0x5 -- - /* Per-vCPU Xen attributes */ - #define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr) - #define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr) -@@ -1795,242 +1379,6 @@ struct kvm_xen_hvm_attr { - #define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2) - #define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2) - --struct kvm_xen_vcpu_attr { -- __u16 type; -- __u16 pad[3]; -- union { -- __u64 gpa; --#define KVM_XEN_INVALID_GPA ((__u64)-1) -- __u64 pad[8]; -- struct { -- __u64 state; -- __u64 state_entry_time; -- __u64 time_running; -- __u64 time_runnable; -- __u64 time_blocked; -- __u64 time_offline; -- } runstate; -- __u32 vcpu_id; -- struct { -- __u32 port; -- __u32 priority; -- __u64 expires_ns; -- } timer; -- __u8 vector; -- } u; --}; -- --/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ --#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0 --#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1 --#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2 --#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3 --#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4 --#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5 --/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ --#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6 --#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7 --#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8 -- --/* Secure Encrypted Virtualization command */ --enum sev_cmd_id { -- /* Guest initialization commands */ -- KVM_SEV_INIT = 0, -- KVM_SEV_ES_INIT, -- /* Guest launch commands */ -- KVM_SEV_LAUNCH_START, -- KVM_SEV_LAUNCH_UPDATE_DATA, -- KVM_SEV_LAUNCH_UPDATE_VMSA, -- KVM_SEV_LAUNCH_SECRET, -- KVM_SEV_LAUNCH_MEASURE, -- KVM_SEV_LAUNCH_FINISH, -- /* Guest migration commands (outgoing) */ -- KVM_SEV_SEND_START, -- KVM_SEV_SEND_UPDATE_DATA, -- KVM_SEV_SEND_UPDATE_VMSA, -- KVM_SEV_SEND_FINISH, -- /* Guest migration commands (incoming) */ -- KVM_SEV_RECEIVE_START, -- KVM_SEV_RECEIVE_UPDATE_DATA, -- KVM_SEV_RECEIVE_UPDATE_VMSA, -- KVM_SEV_RECEIVE_FINISH, -- /* Guest status and debug commands */ -- KVM_SEV_GUEST_STATUS, -- KVM_SEV_DBG_DECRYPT, -- KVM_SEV_DBG_ENCRYPT, -- /* Guest certificates commands */ -- KVM_SEV_CERT_EXPORT, -- /* Attestation report */ -- KVM_SEV_GET_ATTESTATION_REPORT, -- /* Guest Migration Extension */ -- KVM_SEV_SEND_CANCEL, -- -- KVM_SEV_NR_MAX, --}; -- --struct kvm_sev_cmd { -- __u32 id; -- __u64 data; -- __u32 error; -- __u32 sev_fd; --}; -- --struct kvm_sev_launch_start { -- __u32 handle; -- __u32 policy; -- __u64 dh_uaddr; -- __u32 dh_len; -- __u64 session_uaddr; -- __u32 session_len; --}; -- --struct kvm_sev_launch_update_data { -- __u64 uaddr; -- __u32 len; --}; -- -- --struct kvm_sev_launch_secret { -- __u64 hdr_uaddr; -- __u32 hdr_len; -- __u64 guest_uaddr; -- __u32 guest_len; -- __u64 trans_uaddr; -- __u32 trans_len; --}; -- --struct kvm_sev_launch_measure { -- __u64 uaddr; -- __u32 len; --}; -- --struct kvm_sev_guest_status { -- __u32 handle; -- __u32 policy; -- __u32 state; --}; -- --struct kvm_sev_dbg { -- __u64 src_uaddr; -- __u64 dst_uaddr; -- __u32 len; --}; -- --struct kvm_sev_attestation_report { -- __u8 mnonce[16]; -- __u64 uaddr; -- __u32 len; --}; -- --struct kvm_sev_send_start { -- __u32 policy; -- __u64 pdh_cert_uaddr; -- __u32 pdh_cert_len; -- __u64 plat_certs_uaddr; -- __u32 plat_certs_len; -- __u64 amd_certs_uaddr; -- __u32 amd_certs_len; -- __u64 session_uaddr; -- __u32 session_len; --}; -- --struct kvm_sev_send_update_data { -- __u64 hdr_uaddr; -- __u32 hdr_len; -- __u64 guest_uaddr; -- __u32 guest_len; -- __u64 trans_uaddr; -- __u32 trans_len; --}; -- --struct kvm_sev_receive_start { -- __u32 handle; -- __u32 policy; -- __u64 pdh_uaddr; -- __u32 pdh_len; -- __u64 session_uaddr; -- __u32 session_len; --}; -- --struct kvm_sev_receive_update_data { -- __u64 hdr_uaddr; -- __u32 hdr_len; -- __u64 guest_uaddr; -- __u32 guest_len; -- __u64 trans_uaddr; -- __u32 trans_len; --}; -- --#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) --#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) --#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -- --struct kvm_assigned_pci_dev { -- __u32 assigned_dev_id; -- __u32 busnr; -- __u32 devfn; -- __u32 flags; -- __u32 segnr; -- union { -- __u32 reserved[11]; -- }; --}; -- --#define KVM_DEV_IRQ_HOST_INTX (1 << 0) --#define KVM_DEV_IRQ_HOST_MSI (1 << 1) --#define KVM_DEV_IRQ_HOST_MSIX (1 << 2) -- --#define KVM_DEV_IRQ_GUEST_INTX (1 << 8) --#define KVM_DEV_IRQ_GUEST_MSI (1 << 9) --#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10) -- --#define KVM_DEV_IRQ_HOST_MASK 0x00ff --#define KVM_DEV_IRQ_GUEST_MASK 0xff00 -- --struct kvm_assigned_irq { -- __u32 assigned_dev_id; -- __u32 host_irq; /* ignored (legacy field) */ -- __u32 guest_irq; -- __u32 flags; -- union { -- __u32 reserved[12]; -- }; --}; -- --struct kvm_assigned_msix_nr { -- __u32 assigned_dev_id; -- __u16 entry_nr; -- __u16 padding; --}; -- --#define KVM_MAX_MSIX_PER_DEV 256 --struct kvm_assigned_msix_entry { -- __u32 assigned_dev_id; -- __u32 gsi; -- __u16 entry; /* The index of entry in the MSI-X table */ -- __u16 padding[3]; --}; -- --#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) --#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) -- --/* Available with KVM_CAP_ARM_USER_IRQ */ -- --/* Bits for run->s.regs.device_irq_level */ --#define KVM_ARM_DEV_EL1_VTIMER (1 << 0) --#define KVM_ARM_DEV_EL1_PTIMER (1 << 1) --#define KVM_ARM_DEV_PMU (1 << 2) -- --struct kvm_hyperv_eventfd { -- __u32 conn_id; -- __s32 fd; -- __u32 flags; -- __u32 padding[3]; --}; -- --#define KVM_HYPERV_CONN_ID_MASK 0x00ffffff --#define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0) -- - #define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0) - #define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1) - -@@ -2176,33 +1524,6 @@ struct kvm_stats_desc { - /* Available with KVM_CAP_S390_ZPCI_OP */ - #define KVM_S390_ZPCI_OP _IOW(KVMIO, 0xd1, struct kvm_s390_zpci_op) - --struct kvm_s390_zpci_op { -- /* in */ -- __u32 fh; /* target device */ -- __u8 op; /* operation to perform */ -- __u8 pad[3]; -- union { -- /* for KVM_S390_ZPCIOP_REG_AEN */ -- struct { -- __u64 ibv; /* Guest addr of interrupt bit vector */ -- __u64 sb; /* Guest addr of summary bit */ -- __u32 flags; -- __u32 noi; /* Number of interrupts */ -- __u8 isc; /* Guest interrupt subclass */ -- __u8 sbo; /* Offset of guest summary bit vector */ -- __u16 pad; -- } reg_aen; -- __u64 reserved[8]; -- } u; --}; -- --/* types for kvm_s390_zpci_op->op */ --#define KVM_S390_ZPCIOP_REG_AEN 0 --#define KVM_S390_ZPCIOP_DEREG_AEN 1 -- --/* flags for kvm_s390_zpci_op->u.reg_aen.flags */ --#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0) -- - /* Available with KVM_CAP_MEMORY_ATTRIBUTES */ - #define KVM_SET_MEMORY_ATTRIBUTES _IOW(KVMIO, 0xd2, struct kvm_memory_attributes) - -diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h -index bcb21339ee..c3046c6bff 100644 ---- a/linux-headers/linux/psp-sev.h -+++ b/linux-headers/linux/psp-sev.h -@@ -28,6 +28,9 @@ enum { - SEV_PEK_CERT_IMPORT, - SEV_GET_ID, /* This command is deprecated, use SEV_GET_ID2 */ - SEV_GET_ID2, -+ SNP_PLATFORM_STATUS, -+ SNP_COMMIT, -+ SNP_SET_CONFIG, - - SEV_MAX, - }; -@@ -69,6 +72,12 @@ typedef enum { - SEV_RET_RESOURCE_LIMIT, - SEV_RET_SECURE_DATA_INVALID, - SEV_RET_INVALID_KEY = 0x27, -+ SEV_RET_INVALID_PAGE_SIZE, -+ SEV_RET_INVALID_PAGE_STATE, -+ SEV_RET_INVALID_MDATA_ENTRY, -+ SEV_RET_INVALID_PAGE_OWNER, -+ SEV_RET_INVALID_PAGE_AEAD_OFLOW, -+ SEV_RET_RMP_INIT_REQUIRED, - SEV_RET_MAX, - } sev_ret_code; - -@@ -155,6 +164,56 @@ struct sev_user_data_get_id2 { - __u32 length; /* In/Out */ - } __attribute__((packed)); - -+/** -+ * struct sev_user_data_snp_status - SNP status -+ * -+ * @api_major: API major version -+ * @api_minor: API minor version -+ * @state: current platform state -+ * @is_rmp_initialized: whether RMP is initialized or not -+ * @rsvd: reserved -+ * @build_id: firmware build id for the API version -+ * @mask_chip_id: whether chip id is present in attestation reports or not -+ * @mask_chip_key: whether attestation reports are signed or not -+ * @vlek_en: VLEK (Version Loaded Endorsement Key) hashstick is loaded -+ * @rsvd1: reserved -+ * @guest_count: the number of guest currently managed by the firmware -+ * @current_tcb_version: current TCB version -+ * @reported_tcb_version: reported TCB version -+ */ -+struct sev_user_data_snp_status { -+ __u8 api_major; /* Out */ -+ __u8 api_minor; /* Out */ -+ __u8 state; /* Out */ -+ __u8 is_rmp_initialized:1; /* Out */ -+ __u8 rsvd:7; -+ __u32 build_id; /* Out */ -+ __u32 mask_chip_id:1; /* Out */ -+ __u32 mask_chip_key:1; /* Out */ -+ __u32 vlek_en:1; /* Out */ -+ __u32 rsvd1:29; -+ __u32 guest_count; /* Out */ -+ __u64 current_tcb_version; /* Out */ -+ __u64 reported_tcb_version; /* Out */ -+} __attribute__((packed)); -+ -+/** -+ * struct sev_user_data_snp_config - system wide configuration value for SNP. -+ * -+ * @reported_tcb: the TCB version to report in the guest attestation report. -+ * @mask_chip_id: whether chip id is present in attestation reports or not -+ * @mask_chip_key: whether attestation reports are signed or not -+ * @rsvd: reserved -+ * @rsvd1: reserved -+ */ -+struct sev_user_data_snp_config { -+ __u64 reported_tcb ; /* In */ -+ __u32 mask_chip_id:1; /* In */ -+ __u32 mask_chip_key:1; /* In */ -+ __u32 rsvd:30; /* In */ -+ __u8 rsvd1[52]; -+} __attribute__((packed)); -+ - /** - * struct sev_issue_cmd - SEV ioctl parameters - * -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index 649560c685..bea6973906 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -227,4 +227,11 @@ - */ - #define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, \ - struct vhost_vring_state) -+ -+/* Get the queue size of a specific virtqueue. -+ * userspace set the vring index in vhost_vring_state.index -+ * kernel set the queue size in vhost_vring_state.num -+ */ -+#define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x80, \ -+ struct vhost_vring_state) - #endif --- -2.39.3 - diff --git a/SOURCES/kvm-machine-allow-early-use-of-machine_require_guest_mem.patch b/SOURCES/kvm-machine-allow-early-use-of-machine_require_guest_mem.patch deleted file mode 100644 index 6524d6a..0000000 --- a/SOURCES/kvm-machine-allow-early-use-of-machine_require_guest_mem.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 9f485c8df885bcd1ff6c5692463c6168bfec07fb Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 31 May 2024 13:29:53 +0200 -Subject: [PATCH 054/100] machine: allow early use of - machine_require_guest_memfd - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [54/91] fd8c1a6624d5f27268215c8aa70dfc9d37bdb981 (bonzini/rhel-qemu-kvm) - -Ask the ConfidentialGuestSupport object whether to use guest_memfd -for KVM-backend private memory. This bool can be set in instance_init -(or user_complete) so that it is available when the machine is created. - -Signed-off-by: Paolo Bonzini -(cherry picked from commit dc0d28ca46c0e7ee3c055ad4da24022995bd3765) -Signed-off-by: Paolo Bonzini ---- - hw/core/machine.c | 2 +- - include/exec/confidential-guest-support.h | 5 +++++ - include/hw/boards.h | 1 - - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 07b994e136..2055e0d312 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -1482,7 +1482,7 @@ bool machine_mem_merge(MachineState *machine) - - bool machine_require_guest_memfd(MachineState *machine) - { -- return machine->require_guest_memfd; -+ return machine->cgs && machine->cgs->require_guest_memfd; - } - - static char *cpu_slot_to_string(const CPUArchId *cpu) -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index e5b188cffb..02dc4e518f 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -31,6 +31,11 @@ OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, - struct ConfidentialGuestSupport { - Object parent; - -+ /* -+ * True if the machine should use guest_memfd for RAM. -+ */ -+ bool require_guest_memfd; -+ - /* - * ready: flag set by CGS initialization code once it's ready to - * start executing instructions in a potentially-secure -diff --git a/include/hw/boards.h b/include/hw/boards.h -index 815a1c4b26..0d1f9533ef 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -373,7 +373,6 @@ struct MachineState { - char *dt_compatible; - bool dump_guest_core; - bool mem_merge; -- bool require_guest_memfd; - bool usb; - bool usb_disabled; - char *firmware; --- -2.39.3 - diff --git a/SOURCES/kvm-memory-Introduce-memory_region_init_ram_guest_memfd.patch b/SOURCES/kvm-memory-Introduce-memory_region_init_ram_guest_memfd.patch deleted file mode 100644 index 538e82d..0000000 --- a/SOURCES/kvm-memory-Introduce-memory_region_init_ram_guest_memfd.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 331c58d87dde8b4757e1d1e09d9b16bac2952d22 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 30 May 2024 06:16:15 -0500 -Subject: [PATCH 081/100] memory: Introduce - memory_region_init_ram_guest_memfd() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [81/91] d5b0898d791f3f90d1acda0230f96ca9bf5be5e4 (bonzini/rhel-qemu-kvm) - -Introduce memory_region_init_ram_guest_memfd() to allocate private -guset memfd on the MemoryRegion initialization. It's for the use case of -TDVF, which must be private on TDX case. - -Signed-off-by: Xiaoyao Li -Signed-off-by: Michael Roth -Signed-off-by: Pankaj Gupta -Message-ID: <20240530111643.1091816-4-pankaj.gupta@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit a0aa6db7ce72a08703774107185e639e73e7754c) -Signed-off-by: Paolo Bonzini ---- - include/exec/memory.h | 6 ++++++ - system/memory.c | 24 ++++++++++++++++++++++++ - 2 files changed, 30 insertions(+) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 679a847685..1e351f6fc8 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -1603,6 +1603,12 @@ bool memory_region_init_ram(MemoryRegion *mr, - uint64_t size, - Error **errp); - -+bool memory_region_init_ram_guest_memfd(MemoryRegion *mr, -+ Object *owner, -+ const char *name, -+ uint64_t size, -+ Error **errp); -+ - /** - * memory_region_init_rom: Initialize a ROM memory region. - * -diff --git a/system/memory.c b/system/memory.c -index c756950c0c..b09065eef3 100644 ---- a/system/memory.c -+++ b/system/memory.c -@@ -3606,6 +3606,30 @@ bool memory_region_init_ram(MemoryRegion *mr, - return true; - } - -+bool memory_region_init_ram_guest_memfd(MemoryRegion *mr, -+ Object *owner, -+ const char *name, -+ uint64_t size, -+ Error **errp) -+{ -+ DeviceState *owner_dev; -+ -+ if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size, -+ RAM_GUEST_MEMFD, errp)) { -+ return false; -+ } -+ /* This will assert if owner is neither NULL nor a DeviceState. -+ * We only want the owner here for the purposes of defining a -+ * unique name for migration. TODO: Ideally we should implement -+ * a naming scheme for Objects which are not DeviceStates, in -+ * which case we can relax this restriction. -+ */ -+ owner_dev = DEVICE(owner); -+ vmstate_register_ram(mr, owner_dev); -+ -+ return true; -+} -+ - bool memory_region_init_rom(MemoryRegion *mr, - Object *owner, - const char *name, --- -2.39.3 - diff --git a/SOURCES/kvm-migration-Add-helper-to-get-target-runstate.patch b/SOURCES/kvm-migration-Add-helper-to-get-target-runstate.patch new file mode 100644 index 0000000..7c58ada --- /dev/null +++ b/SOURCES/kvm-migration-Add-helper-to-get-target-runstate.patch @@ -0,0 +1,84 @@ +From 21e971c2d7a8aee5cb95b7714c15374331add796 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:33 -0500 +Subject: [PATCH 02/23] migration: Add helper to get target runstate + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/22] d1b2ee0d6a878e71ad04ace9fd82d8aab2d5217b (kmwolf/centos-qemu-kvm) + +In 99% cases, after QEMU migrates to dest host, it tries to detect the +target VM runstate using global_state_get_runstate(). + +There's one outlier so far which is Xen that won't send global state. +That's the major reason why global_state_received() check was always there +together with global_state_get_runstate(). + +However it's utterly confusing why global_state_received() has anything to +do with "let's start VM or not". + +Provide a helper to explain it, then we have an unified entry for getting +the target dest QEMU runstate after migration. + +Suggested-by: Fabiano Rosas +Signed-off-by: Peter Xu +Message-Id: <20241206230838.1111496-2-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 7815f69867da92335055d4b5248430b0f122ce4e) +Signed-off-by: Kevin Wolf +--- + migration/migration.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 3dea06d577..c7a9e2e026 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -135,6 +135,21 @@ static bool migration_needs_multiple_sockets(void) + return migrate_multifd() || migrate_postcopy_preempt(); + } + ++static RunState migration_get_target_runstate(void) ++{ ++ /* ++ * When the global state is not migrated, it means we don't know the ++ * runstate of the src QEMU. We don't have much choice but assuming ++ * the VM is running. NOTE: this is pretty rare case, so far only Xen ++ * uses it. ++ */ ++ if (!global_state_received()) { ++ return RUN_STATE_RUNNING; ++ } ++ ++ return global_state_get_runstate(); ++} ++ + static bool transport_supports_multi_channels(MigrationAddress *addr) + { + if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { +@@ -727,8 +742,7 @@ static void process_incoming_migration_bh(void *opaque) + * unless we really are starting the VM. + */ + if (!migrate_late_block_activate() || +- (autostart && (!global_state_received() || +- runstate_is_live(global_state_get_runstate())))) { ++ (autostart && runstate_is_live(migration_get_target_runstate()))) { + /* Make sure all file formats throw away their mutable metadata. + * If we get an error here, just don't restart the VM yet. */ + bdrv_activate_all(&local_err); +@@ -751,8 +765,7 @@ static void process_incoming_migration_bh(void *opaque) + + dirty_bitmap_mig_before_vm_start(); + +- if (!global_state_received() || +- runstate_is_live(global_state_get_runstate())) { ++ if (runstate_is_live(migration_get_target_runstate())) { + if (autostart) { + vm_start(); + } else { +-- +2.48.1 + diff --git a/SOURCES/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch b/SOURCES/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch new file mode 100644 index 0000000..45c09e0 --- /dev/null +++ b/SOURCES/kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch @@ -0,0 +1,116 @@ +From 090cdb81ce6913f1c5989853d0af0dbb2f1d3f9f Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Wed, 20 Nov 2024 11:01:32 -0500 +Subject: [PATCH] migration: Allow pipes to keep working for fd migrations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Peter Xu +RH-MergeRequest: 301: migration: Allow pipes to keep working for fd migrations +RH-Jira: RHEL-66089 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 8b62be63720f81e9d1633844917ab6992d99566f (peterx/qemu-kvm) + +Libvirt may still use pipes for old file migrations in fd: URI form, +especially when loading old images dumped from Libvirt's compression +algorithms. + +In that case, Libvirt needs to compress / uncompress the images on its own +over the migration binary stream, and pipes are passed over to QEMU for +outgoing / incoming migrations in "fd:" URIs. + +For future such use case, it should be suggested to use mapped-ram when +saving such VM image. However there can still be old images that was +compressed in such way, so libvirt needs to be able to load those images, +uncompress them and use the same pipe mechanism to pass that over to QEMU. + +It means, even if new file migrations can be gradually moved over to +mapped-ram (after Libvirt start supporting it), Libvirt still needs the +uncompressor for the old images to be able to load like before. + +Meanwhile since Libvirt currently exposes the compression capability to +guest images, it may needs its own lifecycle management to move that over +to mapped-ram, maybe can be done after mapped-ram saved the image, however +Dan and PeterK raised concern on temporary double disk space consumption. +I suppose for now the easiest is to enable pipes for both sides of "fd:" +migrations, until all things figured out from Libvirt side on how to move +on. + +And for "channels" QMP interface support on "migrate" / "migrate-incoming" +commands, we'll also need to move away from pipe. But let's leave that for +later too. + +So far, still allow pipes to happen like before on both save/load sides, +just like we would allow sockets to pass. + +Cc: qemu-stable +Cc: Fabiano Rosas +Cc: Peter Krempa +Cc: Daniel P. Berrangé +Fixes: c55deb860c ("migration: Deprecate fd: for file migration") +Reviewed-by: Fabiano Rosas +Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 87ae45e602e2943d58509e470e3a1d4ba084ab2f) +Signed-off-by: Peter Xu +--- + migration/fd.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +diff --git a/migration/fd.c b/migration/fd.c +index aab5189eac..9bf9be6acb 100644 +--- a/migration/fd.c ++++ b/migration/fd.c +@@ -25,6 +25,29 @@ + #include "io/channel-util.h" + #include "trace.h" + ++static bool fd_is_pipe(int fd) ++{ ++ struct stat statbuf; ++ ++ if (fstat(fd, &statbuf) == -1) { ++ return false; ++ } ++ ++ return S_ISFIFO(statbuf.st_mode); ++} ++ ++static bool migration_fd_valid(int fd) ++{ ++ if (fd_is_socket(fd)) { ++ return true; ++ } ++ ++ if (fd_is_pipe(fd)) { ++ return true; ++ } ++ ++ return false; ++} + + void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) + { +@@ -34,7 +57,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error ** + return; + } + +- if (!fd_is_socket(fd)) { ++ if (!migration_fd_valid(fd)) { + warn_report("fd: migration to a file is deprecated." + " Use file: instead."); + } +@@ -68,7 +91,7 @@ void fd_start_incoming_migration(const char *fdname, Error **errp) + return; + } + +- if (!fd_is_socket(fd)) { ++ if (!migration_fd_valid(fd)) { + warn_report("fd: migration to a file is deprecated." + " Use file: instead."); + } +-- +2.39.3 + diff --git a/SOURCES/kvm-migration-Ensure-vmstate_save-sets-errp.patch b/SOURCES/kvm-migration-Ensure-vmstate_save-sets-errp.patch new file mode 100644 index 0000000..6493c3e --- /dev/null +++ b/SOURCES/kvm-migration-Ensure-vmstate_save-sets-errp.patch @@ -0,0 +1,92 @@ +From 91f67a47a3fd31be578988d7ac11bb814314ec5a Mon Sep 17 00:00:00 2001 +From: Hanna Czenczek +Date: Tue, 15 Oct 2024 19:04:37 +0200 +Subject: [PATCH] migration: Ensure vmstate_save() sets errp + +RH-Author: Hanna Czenczek +RH-MergeRequest: 295: migration: Ensure vmstate_save() sets errp +RH-Jira: RHEL-67844 +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Jon Maloy +RH-Commit: [1/1] df65f254fa6bf241b1fd4f4d2101f137d2a6e44b (hreitz/qemu-kvm-c-9-s) + +migration/savevm.c contains some calls to vmstate_save() that are +followed by migrate_set_error() if the integer return value indicates an +error. migrate_set_error() requires that the `Error *` object passed to +it is set. Therefore, vmstate_save() is assumed to always set *errp on +error. + +Right now, that assumption is not met: vmstate_save_state_v() (called +internally by vmstate_save()) will not set *errp if +vmstate_subsection_save() or vmsd->post_save() fail. Fix that by adding +an *errp parameter to vmstate_subsection_save(), and by generating a +generic error in case post_save() fails (as is already done for +pre_save()). + +Without this patch, qemu will crash after vmstate_subsection_save() or +post_save() have failed inside of a vmstate_save() call (unless +migrate_set_error() then happen to discard the new error because +s->error is already set). This happens e.g. when receiving the state +from a virtio-fs back-end (virtiofsd) fails. + +Signed-off-by: Hanna Czenczek +Link: https://lore.kernel.org/r/20241015170437.310358-1-hreitz@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 37dfcba1a04989830c706f9cbc00450e5d3a7447) +Signed-off-by: Hanna Czenczek +--- + migration/vmstate.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/migration/vmstate.c b/migration/vmstate.c +index ef26f26ccd..d19b42630a 100644 +--- a/migration/vmstate.c ++++ b/migration/vmstate.c +@@ -22,7 +22,8 @@ + #include "trace.h" + + static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, +- void *opaque, JSONWriter *vmdesc); ++ void *opaque, JSONWriter *vmdesc, ++ Error **errp); + static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + void *opaque); + +@@ -440,12 +441,13 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, + json_writer_end_array(vmdesc); + } + +- ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc); ++ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc, errp); + + if (vmsd->post_save) { + int ps_ret = vmsd->post_save(opaque); +- if (!ret) { ++ if (!ret && ps_ret) { + ret = ps_ret; ++ error_setg(errp, "post-save failed: %s", vmsd->name); + } + } + return ret; +@@ -517,7 +519,8 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + } + + static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, +- void *opaque, JSONWriter *vmdesc) ++ void *opaque, JSONWriter *vmdesc, ++ Error **errp) + { + const VMStateDescription * const *sub = vmsd->subsections; + bool vmdesc_has_subsections = false; +@@ -545,7 +548,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, + qemu_put_byte(f, len); + qemu_put_buffer(f, (uint8_t *)vmsdsub->name, len); + qemu_put_be32(f, vmsdsub->version_id); +- ret = vmstate_save_state(f, vmsdsub, opaque, vmdesc); ++ ret = vmstate_save_state_with_err(f, vmsdsub, opaque, vmdesc, errp); + if (ret) { + return ret; + } +-- +2.45.1 + diff --git a/SOURCES/kvm-migration-block-Apply-late-block-active-behavior-to-.patch b/SOURCES/kvm-migration-block-Apply-late-block-active-behavior-to-.patch new file mode 100644 index 0000000..f052aa3 --- /dev/null +++ b/SOURCES/kvm-migration-block-Apply-late-block-active-behavior-to-.patch @@ -0,0 +1,72 @@ +From 149fdbbe765e0153a533d5bed653e7de16f8ad9b Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:36 -0500 +Subject: [PATCH 05/23] migration/block: Apply late-block-active behavior to + postcopy + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [4/22] 1ba47fc6bb9e3b244f75b2f29a89b9fd4014deea (kmwolf/centos-qemu-kvm) + +Postcopy never cared about late-block-active. However there's no mention +in the capability that it doesn't apply to postcopy. + +Considering that we _assumed_ late activation is always good, do that too +for postcopy unconditionally, just like precopy. After this patch, we +should have unified the behavior across all. + +Signed-off-by: Peter Xu +Reviewed-by: Fabiano Rosas +Message-Id: <20241206230838.1111496-5-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 61f2b489987c51159c53101a072c6aa901b50506) +Signed-off-by: Kevin Wolf +--- + migration/savevm.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/migration/savevm.c b/migration/savevm.c +index 6bb404b9c8..a0c4befdc1 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -2156,22 +2156,21 @@ static void loadvm_postcopy_handle_run_bh(void *opaque) + + trace_vmstate_downtime_checkpoint("dst-postcopy-bh-announced"); + +- /* Make sure all file formats throw away their mutable metadata. +- * If we get an error here, just don't restart the VM yet. */ +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- local_err = NULL; +- autostart = false; +- } +- +- trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); +- + dirty_bitmap_mig_before_vm_start(); + + if (autostart) { +- /* Hold onto your hats, starting the CPU */ +- vm_start(); ++ /* ++ * Make sure all file formats throw away their mutable metadata. ++ * If we get an error here, just don't restart the VM yet. ++ */ ++ bdrv_activate_all(&local_err); ++ trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); ++ if (local_err) { ++ error_report_err(local_err); ++ local_err = NULL; ++ } else { ++ vm_start(); ++ } + } else { + /* leave it paused and let management decide when to start the CPU */ + runstate_set(RUN_STATE_PAUSED); +-- +2.48.1 + diff --git a/SOURCES/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch b/SOURCES/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch new file mode 100644 index 0000000..f0a36d4 --- /dev/null +++ b/SOURCES/kvm-migration-block-Fix-possible-race-with-block_inactiv.patch @@ -0,0 +1,78 @@ +From 703a2b932f8b6e06f4a1c0cdfdf7f4cf030a6e38 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:37 -0500 +Subject: [PATCH 06/23] migration/block: Fix possible race with block_inactive + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [5/22] 6300de6a4a19d4648e5a5503ef8cec557fe8e666 (kmwolf/centos-qemu-kvm) + +Src QEMU sets block_inactive=true very early before the invalidation takes +place. It means if something wrong happened during setting the flag but +before reaching qemu_savevm_state_complete_precopy_non_iterable() where it +did the invalidation work, it'll make block_inactive flag inconsistent. + +For example, think about when qemu_savevm_state_complete_precopy_iterable() +can fail: it will have block_inactive set to true even if all block drives +are active. + +Fix that by only update the flag after the invalidation is done. + +No Fixes for any commit, because it's not an issue if bdrv_activate_all() +is re-entrant upon all-active disks - false positive block_inactive can +bring nothing more than "trying to active the blocks but they're already +active". However let's still do it right to avoid the inconsistent flag +v.s. reality. + +Signed-off-by: Peter Xu +Reviewed-by: Fabiano Rosas +Message-Id: <20241206230838.1111496-6-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 8c97c5a476d146b35b2873ef73df601216a494d9) +Signed-off-by: Kevin Wolf +--- + migration/migration.c | 9 +++------ + migration/savevm.c | 2 ++ + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index 8a262e01ff..784b7e9b90 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -2779,14 +2779,11 @@ static int migration_completion_precopy(MigrationState *s, + goto out_unlock; + } + +- /* +- * Inactivate disks except in COLO, and track that we have done so in order +- * to remember to reactivate them if migration fails or is cancelled. +- */ +- s->block_inactive = !migrate_colo(); + migration_rate_set(RATE_LIMIT_DISABLED); ++ ++ /* Inactivate disks except in COLO */ + ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false, +- s->block_inactive); ++ !migrate_colo()); + out_unlock: + bql_unlock(); + return ret; +diff --git a/migration/savevm.c b/migration/savevm.c +index a0c4befdc1..b88dadd904 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1577,6 +1577,8 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + qemu_file_set_error(f, ret); + return ret; + } ++ /* Remember that we did this */ ++ s->block_inactive = true; + } + if (!in_postcopy) { + /* Postcopy stream will still be going */ +-- +2.48.1 + diff --git a/SOURCES/kvm-migration-block-Make-late-block-active-the-default.patch b/SOURCES/kvm-migration-block-Make-late-block-active-the-default.patch new file mode 100644 index 0000000..9313498 --- /dev/null +++ b/SOURCES/kvm-migration-block-Make-late-block-active-the-default.patch @@ -0,0 +1,94 @@ +From 5a3017fbfb1081fc0a074ee53e1ad7ba8489c8c1 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:35 -0500 +Subject: [PATCH 04/23] migration/block: Make late-block-active the default + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [3/22] 74d95ded9153bf0969ede7d7d2708e9452d7cd11 (kmwolf/centos-qemu-kvm) + +Migration capability 'late-block-active' controls when the block drives +will be activated. If enabled, block drives will only be activated until +VM starts, either src runstate was "live" (RUNNING, or SUSPENDED), or it'll +be postponed until qmp_cont(). + +Let's do this unconditionally. There's no harm to delay activation of +block drives. Meanwhile there's no ABI breakage if dest does it, because +src QEMU has nothing to do with it, so it's no concern on ABI breakage. + +IIUC we could avoid introducing this cap when introducing it before, but +now it's still not too late to just always do it. Cap now prone to +removal, but it'll be for later patches. + +Signed-off-by: Peter Xu +Reviewed-by: Fabiano Rosas +Message-Id: <20241206230838.1111496-4-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit fca9aef1c8d8fc4482cc541638dbfac76dc125d6) +Signed-off-by: Kevin Wolf +--- + migration/migration.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/migration/migration.c b/migration/migration.c +index c7a9e2e026..8a262e01ff 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -735,24 +735,6 @@ static void process_incoming_migration_bh(void *opaque) + + trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter"); + +- /* If capability late_block_activate is set: +- * Only fire up the block code now if we're going to restart the +- * VM, else 'cont' will do it. +- * This causes file locking to happen; so we don't want it to happen +- * unless we really are starting the VM. +- */ +- if (!migrate_late_block_activate() || +- (autostart && runstate_is_live(migration_get_target_runstate()))) { +- /* Make sure all file formats throw away their mutable metadata. +- * If we get an error here, just don't restart the VM yet. */ +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- local_err = NULL; +- autostart = false; +- } +- } +- + /* + * This must happen after all error conditions are dealt with and + * we're sure the VM is going to be running on this host. +@@ -767,7 +749,25 @@ static void process_incoming_migration_bh(void *opaque) + + if (runstate_is_live(migration_get_target_runstate())) { + if (autostart) { +- vm_start(); ++ /* ++ * Block activation is always delayed until VM starts, either ++ * here (which means we need to start the dest VM right now..), ++ * or until qmp_cont() later. ++ * ++ * We used to have cap 'late-block-activate' but now we do this ++ * unconditionally, as it has no harm but only benefit. E.g., ++ * it's not part of migration ABI on the time of disk activation. ++ * ++ * Make sure all file formats throw away their mutable ++ * metadata. If error, don't restart the VM yet. ++ */ ++ bdrv_activate_all(&local_err); ++ if (local_err) { ++ error_report_err(local_err); ++ local_err = NULL; ++ } else { ++ vm_start(); ++ } + } else { + runstate_set(RUN_STATE_PAUSED); + } +-- +2.48.1 + diff --git a/SOURCES/kvm-migration-block-Rewrite-disk-activation.patch b/SOURCES/kvm-migration-block-Rewrite-disk-activation.patch new file mode 100644 index 0000000..dc8cb1d --- /dev/null +++ b/SOURCES/kvm-migration-block-Rewrite-disk-activation.patch @@ -0,0 +1,565 @@ +From f478efadbb1629028af0e65e8408fe49256b2f17 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:38 -0500 +Subject: [PATCH 07/23] migration/block: Rewrite disk activation + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [6/22] cd000f0b00e6f768288f340e1801dd5a236d430c (kmwolf/centos-qemu-kvm) + +This patch proposes a flag to maintain disk activation status globally. It +mostly rewrites disk activation mgmt for QEMU, including COLO and QMP +command xen_save_devices_state. + +Backgrounds +=========== + +We have two problems on disk activations, one resolved, one not. + +Problem 1: disk activation recover (for switchover interruptions) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When migration is either cancelled or failed during switchover, especially +when after the disks are inactivated, QEMU needs to remember re-activate +the disks again before vm starts. + +It used to be done separately in two paths: one in qmp_migrate_cancel(), +the other one in the failure path of migration_completion(). + +It used to be fixed in different commits, all over the places in QEMU. So +these are the relevant changes I saw, I'm not sure if it's complete list: + + - In 2016, commit fe904ea824 ("migration: regain control of images when + migration fails to complete") + + - In 2017, commit 1d2acc3162 ("migration: re-active images while migration + been canceled after inactive them") + + - In 2023, commit 6dab4c93ec ("migration: Attempt disk reactivation in + more failure scenarios") + +Now since we have a slightly better picture maybe we can unify the +reactivation in a single path. + +One side benefit of doing so is, we can move the disk operation outside QMP +command "migrate_cancel". It's possible that in the future we may want to +make "migrate_cancel" be OOB-compatible, while that requires the command +doesn't need BQL in the first place. This will already do that and make +migrate_cancel command lightweight. + +Problem 2: disk invalidation on top of invalidated disks +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is an unresolved bug for current QEMU. Link in "Resolves:" at the +end. It turns out besides the src switchover phase (problem 1 above), QEMU +also needs to remember block activation on destination. + +Consider two continuous migration in a row, where the VM was always paused. +In that scenario, the disks are not activated even until migration +completed in the 1st round. When the 2nd round starts, if QEMU doesn't +know the status of the disks, it needs to try inactivate the disk again. + +Here the issue is the block layer API bdrv_inactivate_all() will crash a +QEMU if invoked on already inactive disks for the 2nd migration. For +detail, see the bug link at the end. + +Implementation +============== + +This patch proposes to maintain disk activation with a global flag, so we +know: + + - If we used to inactivate disks for migration, but migration got + cancelled, or failed, QEMU will know it should reactivate the disks. + + - On incoming side, if the disks are never activated but then another + migration is triggered, QEMU should be able to tell that inactivate is + not needed for the 2nd migration. + +We used to have disk_inactive, but it only solves the 1st issue, not the +2nd. Also, it's done in completely separate paths so it's extremely hard +to follow either how the flag changes, or the duration that the flag is +valid, and when we will reactivate the disks. + +Convert the existing disk_inactive flag into that global flag (also invert +its naming), and maintain the disk activation status for the whole +lifecycle of qemu. That includes the incoming QEMU. + +Put both of the error cases of source migration (failure, cancelled) +together into migration_iteration_finish(), which will be invoked for +either of the scenario. So from that part QEMU should behave the same as +before. However with such global maintenance on disk activation status, we +not only cleanup quite a few temporary paths that we try to maintain the +disk activation status (e.g. in postcopy code), meanwhile it fixes the +crash for problem 2 in one shot. + +For freshly started QEMU, the flag is initialized to TRUE showing that the +QEMU owns the disks by default. + +For incoming migrated QEMU, the flag will be initialized to FALSE once and +for all showing that the dest QEMU doesn't own the disks until switchover. +That is guaranteed by the "once" variable. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2395 +Signed-off-by: Peter Xu +Reviewed-by: Fabiano Rosas +Message-Id: <20241206230838.1111496-7-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit 8597af76153a87068b675d8099063c3ad8695773) +Signed-off-by: Kevin Wolf +--- + include/migration/misc.h | 4 ++ + migration/block-active.c | 94 ++++++++++++++++++++++++++++++++++++++++ + migration/colo.c | 2 +- + migration/meson.build | 1 + + migration/migration.c | 80 ++++++++-------------------------- + migration/migration.h | 5 +-- + migration/savevm.c | 33 ++++++-------- + migration/trace-events | 3 ++ + monitor/qmp-cmds.c | 8 +--- + 9 files changed, 139 insertions(+), 91 deletions(-) + create mode 100644 migration/block-active.c + +diff --git a/include/migration/misc.h b/include/migration/misc.h +index bfadc5613b..35ca8e1194 100644 +--- a/include/migration/misc.h ++++ b/include/migration/misc.h +@@ -111,4 +111,8 @@ bool migration_in_bg_snapshot(void); + /* migration/block-dirty-bitmap.c */ + void dirty_bitmap_mig_init(void); + ++/* Wrapper for block active/inactive operations */ ++bool migration_block_activate(Error **errp); ++bool migration_block_inactivate(void); ++ + #endif +diff --git a/migration/block-active.c b/migration/block-active.c +new file mode 100644 +index 0000000000..d477cf8182 +--- /dev/null ++++ b/migration/block-active.c +@@ -0,0 +1,94 @@ ++/* ++ * Block activation tracking for migration purpose ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ * ++ * Copyright (C) 2024 Red Hat, Inc. ++ */ ++#include "qemu/osdep.h" ++#include "block/block.h" ++#include "qapi/error.h" ++#include "migration/migration.h" ++#include "qemu/error-report.h" ++#include "trace.h" ++ ++/* ++ * Migration-only cache to remember the block layer activation status. ++ * Protected by BQL. ++ * ++ * We need this because.. ++ * ++ * - Migration can fail after block devices are invalidated (during ++ * switchover phase). When that happens, we need to be able to recover ++ * the block drive status by re-activating them. ++ * ++ * - Currently bdrv_inactivate_all() is not safe to be invoked on top of ++ * invalidated drives (even if bdrv_activate_all() is actually safe to be ++ * called any time!). It means remembering this could help migration to ++ * make sure it won't invalidate twice in a row, crashing QEMU. It can ++ * happen when we migrate a PAUSED VM from host1 to host2, then migrate ++ * again to host3 without starting it. TODO: a cleaner solution is to ++ * allow safe invoke of bdrv_inactivate_all() at anytime, like ++ * bdrv_activate_all(). ++ * ++ * For freshly started QEMU, the flag is initialized to TRUE reflecting the ++ * scenario where QEMU owns block device ownerships. ++ * ++ * For incoming QEMU taking a migration stream, the flag is initialized to ++ * FALSE reflecting that the incoming side doesn't own the block devices, ++ * not until switchover happens. ++ */ ++static bool migration_block_active; ++ ++/* Setup the disk activation status */ ++void migration_block_active_setup(bool active) ++{ ++ migration_block_active = active; ++} ++ ++bool migration_block_activate(Error **errp) ++{ ++ ERRP_GUARD(); ++ ++ assert(bql_locked()); ++ ++ if (migration_block_active) { ++ trace_migration_block_activation("active-skipped"); ++ return true; ++ } ++ ++ trace_migration_block_activation("active"); ++ ++ bdrv_activate_all(errp); ++ if (*errp) { ++ error_report_err(error_copy(*errp)); ++ return false; ++ } ++ ++ migration_block_active = true; ++ return true; ++} ++ ++bool migration_block_inactivate(void) ++{ ++ int ret; ++ ++ assert(bql_locked()); ++ ++ if (!migration_block_active) { ++ trace_migration_block_activation("inactive-skipped"); ++ return true; ++ } ++ ++ trace_migration_block_activation("inactive"); ++ ++ ret = bdrv_inactivate_all(); ++ if (ret) { ++ error_report("%s: bdrv_inactivate_all() failed: %d", ++ __func__, ret); ++ return false; ++ } ++ ++ migration_block_active = false; ++ return true; ++} +diff --git a/migration/colo.c b/migration/colo.c +index 6449490221..ab903f34cb 100644 +--- a/migration/colo.c ++++ b/migration/colo.c +@@ -836,7 +836,7 @@ static void *colo_process_incoming_thread(void *opaque) + + /* Make sure all file formats throw away their mutable metadata */ + bql_lock(); +- bdrv_activate_all(&local_err); ++ migration_block_activate(&local_err); + bql_unlock(); + if (local_err) { + error_report_err(local_err); +diff --git a/migration/meson.build b/migration/meson.build +index 5ce2acb41e..6b79861d3c 100644 +--- a/migration/meson.build ++++ b/migration/meson.build +@@ -11,6 +11,7 @@ migration_files = files( + + system_ss.add(files( + 'block-dirty-bitmap.c', ++ 'block-active.c', + 'channel.c', + 'channel-block.c', + 'dirtyrate.c', +diff --git a/migration/migration.c b/migration/migration.c +index 784b7e9b90..38631d1206 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -730,7 +730,6 @@ static void qemu_start_incoming_migration(const char *uri, bool has_channels, + + static void process_incoming_migration_bh(void *opaque) + { +- Error *local_err = NULL; + MigrationIncomingState *mis = opaque; + + trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter"); +@@ -761,11 +760,7 @@ static void process_incoming_migration_bh(void *opaque) + * Make sure all file formats throw away their mutable + * metadata. If error, don't restart the VM yet. + */ +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- local_err = NULL; +- } else { ++ if (migration_block_activate(NULL)) { + vm_start(); + } + } else { +@@ -1562,16 +1557,6 @@ static void migrate_fd_cancel(MigrationState *s) + } + } + } +- if (s->state == MIGRATION_STATUS_CANCELLING && s->block_inactive) { +- Error *local_err = NULL; +- +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- } else { +- s->block_inactive = false; +- } +- } + } + + void migration_add_notifier_mode(NotifierWithReturn *notify, +@@ -1890,6 +1875,12 @@ void qmp_migrate_incoming(const char *uri, bool has_channels, + return; + } + ++ /* ++ * Newly setup incoming QEMU. Mark the block active state to reflect ++ * that the src currently owns the disks. ++ */ ++ migration_block_active_setup(false); ++ + once = false; + } + +@@ -2542,7 +2533,6 @@ static int postcopy_start(MigrationState *ms, Error **errp) + QIOChannelBuffer *bioc; + QEMUFile *fb; + uint64_t bandwidth = migrate_max_postcopy_bandwidth(); +- bool restart_block = false; + int cur_state = MIGRATION_STATUS_ACTIVE; + + if (migrate_postcopy_preempt()) { +@@ -2578,13 +2568,10 @@ static int postcopy_start(MigrationState *ms, Error **errp) + goto fail; + } + +- ret = bdrv_inactivate_all(); +- if (ret < 0) { +- error_setg_errno(errp, -ret, "%s: Failed in bdrv_inactivate_all()", +- __func__); ++ if (!migration_block_inactivate()) { ++ error_setg(errp, "%s: Failed in bdrv_inactivate_all()", __func__); + goto fail; + } +- restart_block = true; + + /* + * Cause any non-postcopiable, but iterative devices to +@@ -2654,8 +2641,6 @@ static int postcopy_start(MigrationState *ms, Error **errp) + goto fail_closefb; + } + +- restart_block = false; +- + /* Now send that blob */ + if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) { + error_setg(errp, "%s: Failed to send packaged data", __func__); +@@ -2700,17 +2685,7 @@ fail_closefb: + fail: + migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE, + MIGRATION_STATUS_FAILED); +- if (restart_block) { +- /* A failure happened early enough that we know the destination hasn't +- * accessed block devices, so we're safe to recover. +- */ +- Error *local_err = NULL; +- +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- } +- } ++ migration_block_activate(NULL); + migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL); + bql_unlock(); + return -1; +@@ -2808,31 +2783,6 @@ static void migration_completion_postcopy(MigrationState *s) + trace_migration_completion_postcopy_end_after_complete(); + } + +-static void migration_completion_failed(MigrationState *s, +- int current_active_state) +-{ +- if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE || +- s->state == MIGRATION_STATUS_DEVICE)) { +- /* +- * If not doing postcopy, vm_start() will be called: let's +- * regain control on images. +- */ +- Error *local_err = NULL; +- +- bql_lock(); +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_report_err(local_err); +- } else { +- s->block_inactive = false; +- } +- bql_unlock(); +- } +- +- migrate_set_state(&s->state, current_active_state, +- MIGRATION_STATUS_FAILED); +-} +- + /** + * migration_completion: Used by migration_thread when there's not much left. + * The caller 'breaks' the loop when this returns. +@@ -2886,7 +2836,8 @@ fail: + error_free(local_err); + } + +- migration_completion_failed(s, current_active_state); ++ migrate_set_state(&s->state, current_active_state, ++ MIGRATION_STATUS_FAILED); + } + + /** +@@ -3309,6 +3260,11 @@ static void migration_iteration_finish(MigrationState *s) + case MIGRATION_STATUS_FAILED: + case MIGRATION_STATUS_CANCELLED: + case MIGRATION_STATUS_CANCELLING: ++ /* ++ * Re-activate the block drives if they're inactivated. Note, COLO ++ * shouldn't use block_active at all, so it should be no-op there. ++ */ ++ migration_block_activate(NULL); + if (runstate_is_live(s->vm_old_state)) { + if (!runstate_check(RUN_STATE_SHUTDOWN)) { + vm_start(); +@@ -3869,6 +3825,8 @@ static void migration_instance_init(Object *obj) + ms->state = MIGRATION_STATUS_NONE; + ms->mbps = -1; + ms->pages_per_second = -1; ++ /* Freshly started QEMU owns all the block devices */ ++ migration_block_active_setup(true); + qemu_sem_init(&ms->pause_sem, 0); + qemu_mutex_init(&ms->error_mutex); + +diff --git a/migration/migration.h b/migration/migration.h +index 38aa1402d5..5b17c1344d 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -356,9 +356,6 @@ struct MigrationState { + /* Flag set once the migration thread is running (and needs joining) */ + bool migration_thread_running; + +- /* Flag set once the migration thread called bdrv_inactivate_all */ +- bool block_inactive; +- + /* Migration is waiting for guest to unplug device */ + QemuSemaphore wait_unplug_sem; + +@@ -537,4 +534,6 @@ int migration_rp_wait(MigrationState *s); + */ + void migration_rp_kick(MigrationState *s); + ++/* migration/block-active.c */ ++void migration_block_active_setup(bool active); + #endif +diff --git a/migration/savevm.c b/migration/savevm.c +index b88dadd904..7f8d177462 100644 +--- a/migration/savevm.c ++++ b/migration/savevm.c +@@ -1566,19 +1566,18 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, + } + + if (inactivate_disks) { +- /* Inactivate before sending QEMU_VM_EOF so that the +- * bdrv_activate_all() on the other end won't fail. */ +- ret = bdrv_inactivate_all(); +- if (ret) { +- error_setg(&local_err, "%s: bdrv_inactivate_all() failed (%d)", +- __func__, ret); ++ /* ++ * Inactivate before sending QEMU_VM_EOF so that the ++ * bdrv_activate_all() on the other end won't fail. ++ */ ++ if (!migration_block_inactivate()) { ++ error_setg(&local_err, "%s: bdrv_inactivate_all() failed", ++ __func__); + migrate_set_error(ms, local_err); + error_report_err(local_err); +- qemu_file_set_error(f, ret); ++ qemu_file_set_error(f, -EFAULT); + return ret; + } +- /* Remember that we did this */ +- s->block_inactive = true; + } + if (!in_postcopy) { + /* Postcopy stream will still be going */ +@@ -2142,7 +2141,6 @@ static int loadvm_postcopy_handle_listen(MigrationIncomingState *mis) + + static void loadvm_postcopy_handle_run_bh(void *opaque) + { +- Error *local_err = NULL; + MigrationIncomingState *mis = opaque; + + trace_vmstate_downtime_checkpoint("dst-postcopy-bh-enter"); +@@ -2165,12 +2163,11 @@ static void loadvm_postcopy_handle_run_bh(void *opaque) + * Make sure all file formats throw away their mutable metadata. + * If we get an error here, just don't restart the VM yet. + */ +- bdrv_activate_all(&local_err); ++ bool success = migration_block_activate(NULL); ++ + trace_vmstate_downtime_checkpoint("dst-postcopy-bh-cache-invalidated"); +- if (local_err) { +- error_report_err(local_err); +- local_err = NULL; +- } else { ++ ++ if (success) { + vm_start(); + } + } else { +@@ -3214,11 +3211,7 @@ void qmp_xen_save_devices_state(const char *filename, bool has_live, bool live, + * side of the migration take control of the images. + */ + if (live && !saved_vm_running) { +- ret = bdrv_inactivate_all(); +- if (ret) { +- error_setg(errp, "%s: bdrv_inactivate_all() failed (%d)", +- __func__, ret); +- } ++ migration_block_inactivate(); + } + } + +diff --git a/migration/trace-events b/migration/trace-events +index 0b7c3324fb..62141dc2ff 100644 +--- a/migration/trace-events ++++ b/migration/trace-events +@@ -377,3 +377,6 @@ migration_block_progression(unsigned percent) "Completed %u%%" + # page_cache.c + migration_pagecache_init(int64_t max_num_items) "Setting cache buckets to %" PRId64 + migration_pagecache_insert(void) "Error allocating page" ++ ++# block-active.c ++migration_block_activation(const char *name) "%s" +diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c +index 76f21e8af3..6f76d9beaf 100644 +--- a/monitor/qmp-cmds.c ++++ b/monitor/qmp-cmds.c +@@ -31,6 +31,7 @@ + #include "qapi/type-helpers.h" + #include "hw/mem/memory-device.h" + #include "hw/intc/intc.h" ++#include "migration/misc.h" + + NameInfo *qmp_query_name(Error **errp) + { +@@ -103,13 +104,8 @@ void qmp_cont(Error **errp) + * Continuing after completed migration. Images have been + * inactivated to allow the destination to take control. Need to + * get control back now. +- * +- * If there are no inactive block nodes (e.g. because the VM was +- * just paused rather than completing a migration), +- * bdrv_inactivate_all() simply doesn't do anything. + */ +- bdrv_activate_all(&local_err); +- if (local_err) { ++ if (!migration_block_activate(&local_err)) { + error_propagate(errp, local_err); + return; + } +-- +2.48.1 + diff --git a/SOURCES/kvm-migration-block-active-Remove-global-active-flag.patch b/SOURCES/kvm-migration-block-active-Remove-global-active-flag.patch new file mode 100644 index 0000000..7ae5712 --- /dev/null +++ b/SOURCES/kvm-migration-block-active-Remove-global-active-flag.patch @@ -0,0 +1,158 @@ +From a0ebf9fca3b4c6a11c4476c1d1a67fecce7c7e3e Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:13:55 +0100 +Subject: [PATCH 11/23] migration/block-active: Remove global active flag + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [10/22] 4bdf1da765bde05e2d427fc3ccca10bcc9f1dfbe (kmwolf/centos-qemu-kvm) + +Block devices have an individual active state, a single global flag +can't cover this correctly. This becomes more important as we allow +users to manually manage which nodes are active or inactive. + +Now that it's allowed to call bdrv_inactivate_all() even when some +nodes are already inactive, we can remove the flag and just +unconditionally call bdrv_inactivate_all() and, more importantly, +bdrv_activate_all() before we make use of the nodes. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Message-ID: <20250204211407.381505-5-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit c2a189976e211c9ff782538d5a5ed5e5cffeccd6) +Signed-off-by: Kevin Wolf +--- + migration/block-active.c | 46 ---------------------------------------- + migration/migration.c | 8 ------- + migration/migration.h | 2 -- + 3 files changed, 56 deletions(-) + +diff --git a/migration/block-active.c b/migration/block-active.c +index d477cf8182..40e986aade 100644 +--- a/migration/block-active.c ++++ b/migration/block-active.c +@@ -12,51 +12,12 @@ + #include "qemu/error-report.h" + #include "trace.h" + +-/* +- * Migration-only cache to remember the block layer activation status. +- * Protected by BQL. +- * +- * We need this because.. +- * +- * - Migration can fail after block devices are invalidated (during +- * switchover phase). When that happens, we need to be able to recover +- * the block drive status by re-activating them. +- * +- * - Currently bdrv_inactivate_all() is not safe to be invoked on top of +- * invalidated drives (even if bdrv_activate_all() is actually safe to be +- * called any time!). It means remembering this could help migration to +- * make sure it won't invalidate twice in a row, crashing QEMU. It can +- * happen when we migrate a PAUSED VM from host1 to host2, then migrate +- * again to host3 without starting it. TODO: a cleaner solution is to +- * allow safe invoke of bdrv_inactivate_all() at anytime, like +- * bdrv_activate_all(). +- * +- * For freshly started QEMU, the flag is initialized to TRUE reflecting the +- * scenario where QEMU owns block device ownerships. +- * +- * For incoming QEMU taking a migration stream, the flag is initialized to +- * FALSE reflecting that the incoming side doesn't own the block devices, +- * not until switchover happens. +- */ +-static bool migration_block_active; +- +-/* Setup the disk activation status */ +-void migration_block_active_setup(bool active) +-{ +- migration_block_active = active; +-} +- + bool migration_block_activate(Error **errp) + { + ERRP_GUARD(); + + assert(bql_locked()); + +- if (migration_block_active) { +- trace_migration_block_activation("active-skipped"); +- return true; +- } +- + trace_migration_block_activation("active"); + + bdrv_activate_all(errp); +@@ -65,7 +26,6 @@ bool migration_block_activate(Error **errp) + return false; + } + +- migration_block_active = true; + return true; + } + +@@ -75,11 +35,6 @@ bool migration_block_inactivate(void) + + assert(bql_locked()); + +- if (!migration_block_active) { +- trace_migration_block_activation("inactive-skipped"); +- return true; +- } +- + trace_migration_block_activation("inactive"); + + ret = bdrv_inactivate_all(); +@@ -89,6 +44,5 @@ bool migration_block_inactivate(void) + return false; + } + +- migration_block_active = false; + return true; + } +diff --git a/migration/migration.c b/migration/migration.c +index 38631d1206..999d4cac54 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -1875,12 +1875,6 @@ void qmp_migrate_incoming(const char *uri, bool has_channels, + return; + } + +- /* +- * Newly setup incoming QEMU. Mark the block active state to reflect +- * that the src currently owns the disks. +- */ +- migration_block_active_setup(false); +- + once = false; + } + +@@ -3825,8 +3819,6 @@ static void migration_instance_init(Object *obj) + ms->state = MIGRATION_STATUS_NONE; + ms->mbps = -1; + ms->pages_per_second = -1; +- /* Freshly started QEMU owns all the block devices */ +- migration_block_active_setup(true); + qemu_sem_init(&ms->pause_sem, 0); + qemu_mutex_init(&ms->error_mutex); + +diff --git a/migration/migration.h b/migration/migration.h +index 5b17c1344d..c38d2a37e4 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -534,6 +534,4 @@ int migration_rp_wait(MigrationState *s); + */ + void migration_rp_kick(MigrationState *s); + +-/* migration/block-active.c */ +-void migration_block_active_setup(bool active); + #endif +-- +2.48.1 + diff --git a/SOURCES/kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch b/SOURCES/kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch deleted file mode 100644 index f65d293..0000000 --- a/SOURCES/kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 6f60c86c5dd747ba68cb4a11084e7b021769e70b Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Thu, 22 Aug 2024 09:35:29 -0500 -Subject: [PATCH] nbd/server: CVE-2024-7409: Avoid use-after-free when closing - server - -RH-Author: Eric Blake -RH-MergeRequest: 266: nbd/server: CVE-2024-7409: Avoid use-after-free when closing server -RH-Jira: RHEL-52617 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Hanna Czenczek -RH-Commit: [1/1] e6e12c985cd13dd14336d98ab0719c789b5e914d (ebblake/centos-qemu-kvm) - -Commit 3e7ef738 plugged the use-after-free of the global nbd_server -object, but overlooked a use-after-free of nbd_server->listener. -Although this race is harder to hit, notice that our shutdown path -first drops the reference count of nbd_server->listener, then triggers -actions that can result in a pending client reaching the -nbd_blockdev_client_closed() callback, which in turn calls -qio_net_listener_set_client_func on a potentially stale object. - -If we know we don't want any more clients to connect, and have already -told the listener socket to shut down, then we should not be trying to -update the listener socket's associated function. - -Reproducer: - -> #!/usr/bin/python3 -> -> import os -> from threading import Thread -> -> def start_stop(): -> while 1: -> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-start", -+"arguments":{"addr":{"type":"unix","data":{"path":"/tmp/nbd-sock"}}}}\'') -> os.system('virsh qemu-monitor-command VM \'{"execute": "nbd-server-stop"}\'') -> -> def nbd_list(): -> while 1: -> os.system('/path/to/build/qemu-nbd -L -k /tmp/nbd-sock') -> -> def test(): -> sst = Thread(target=start_stop) -> sst.start() -> nlt = Thread(target=nbd_list) -> nlt.start() -> -> sst.join() -> nlt.join() -> -> test() - -Fixes: CVE-2024-7409 -Fixes: 3e7ef738c8 ("nbd/server: CVE-2024-7409: Close stray clients at server-stop") -CC: qemu-stable@nongnu.org -Reported-by: Andrey Drobyshev -Signed-off-by: Eric Blake -Message-ID: <20240822143617.800419-2-eblake@redhat.com> -Reviewed-by: Stefan Hajnoczi - -(cherry picked from commit 3874f5f73c441c52f1c699c848d463b0eda01e4c) -Jira: https://issues.redhat.com/browse/RHEL-52617 -Signed-off-by: Eric Blake ---- - blockdev-nbd.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/blockdev-nbd.c b/blockdev-nbd.c -index f73409ae49..b36f41b7c5 100644 ---- a/blockdev-nbd.c -+++ b/blockdev-nbd.c -@@ -92,10 +92,13 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, - - static void nbd_update_server_watch(NBDServerData *s) - { -- if (!s->max_connections || s->connections < s->max_connections) { -- qio_net_listener_set_client_func(s->listener, nbd_accept, NULL, NULL); -- } else { -- qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL); -+ if (s->listener) { -+ if (!s->max_connections || s->connections < s->max_connections) { -+ qio_net_listener_set_client_func(s->listener, nbd_accept, NULL, -+ NULL); -+ } else { -+ qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL); -+ } - } - } - -@@ -113,6 +116,7 @@ static void nbd_server_free(NBDServerData *server) - */ - qio_net_listener_disconnect(server->listener); - object_unref(OBJECT(server->listener)); -+ server->listener = NULL; - QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) { - qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH, - NULL); --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-CVE-2024-7409-Cap-default-max-connections.patch b/SOURCES/kvm-nbd-server-CVE-2024-7409-Cap-default-max-connections.patch deleted file mode 100644 index 5459a51..0000000 --- a/SOURCES/kvm-nbd-server-CVE-2024-7409-Cap-default-max-connections.patch +++ /dev/null @@ -1,184 +0,0 @@ -From f76d73f62555ad73081558c1f56bcb832fbb8c35 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Tue, 6 Aug 2024 13:53:00 -0500 -Subject: [PATCH 098/100] nbd/server: CVE-2024-7409: Cap default - max-connections to 100 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 262: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) -RH-Jira: RHEL-52617 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/4] 1fb3b8cd9781a66bba2f4a6bee2b320e96de86aa (redhat/centos-stream/src/qemu-kvm) - -Allowing an unlimited number of clients to any web service is a recipe -for a rudimentary denial of service attack: the client merely needs to -open lots of sockets without closing them, until qemu no longer has -any more fds available to allocate. - -For qemu-nbd, we default to allowing only 1 connection unless more are -explicitly asked for (-e or --shared); this was historically picked as -a nice default (without an explicit -t, a non-persistent qemu-nbd goes -away after a client disconnects, without needing any additional -follow-up commands), and we are not going to change that interface now -(besides, someday we want to point people towards qemu-storage-daemon -instead of qemu-nbd). - -But for qemu proper, and the newer qemu-storage-daemon, the QMP -nbd-server-start command has historically had a default of unlimited -number of connections, in part because unlike qemu-nbd it is -inherently persistent until nbd-server-stop. Allowing multiple client -sockets is particularly useful for clients that can take advantage of -MULTI_CONN (creating parallel sockets to increase throughput), -although known clients that do so (such as libnbd's nbdcopy) typically -use only 8 or 16 connections (the benefits of scaling diminish once -more sockets are competing for kernel attention). Picking a number -large enough for typical use cases, but not unlimited, makes it -slightly harder for a malicious client to perform a denial of service -merely by opening lots of connections withot progressing through the -handshake. - -This change does not eliminate CVE-2024-7409 on its own, but reduces -the chance for fd exhaustion or unlimited memory usage as an attack -surface. On the other hand, by itself, it makes it more obvious that -with a finite limit, we have the problem of an unauthenticated client -holding 100 fds opened as a way to block out a legitimate client from -being able to connect; thus, later patches will further add timeouts -to reject clients that are not making progress. - -This is an INTENTIONAL change in behavior, and will break any client -of nbd-server-start that was not passing an explicit max-connections -parameter, yet expects more than 100 simultaneous connections. We are -not aware of any such client (as stated above, most clients aware of -MULTI_CONN get by just fine on 8 or 16 connections, and probably cope -with later connections failing by relying on the earlier connections; -libvirt has not yet been passing max-connections, but generally -creates NBD servers with the intent for a single client for the sake -of live storage migration; meanwhile, the KubeSAN project anticipates -a large cluster sharing multiple clients [up to 8 per node, and up to -100 nodes in a cluster], but it currently uses qemu-nbd with an -explicit --shared=0 rather than qemu-storage-daemon with -nbd-server-start). - -We considered using a deprecation period (declare that omitting -max-parameters is deprecated, and make it mandatory in 3 releases - -then we don't need to pick an arbitrary default); that has zero risk -of breaking any apps that accidentally depended on more than 100 -connections, and where such breakage might not be noticed under unit -testing but only under the larger loads of production usage. But it -does not close the denial-of-service hole until far into the future, -and requires all apps to change to add the parameter even if 100 was -good enough. It also has a drawback that any app (like libvirt) that -is accidentally relying on an unlimited default should seriously -consider their own CVE now, at which point they are going to change to -pass explicit max-connections sooner than waiting for 3 qemu releases. -Finally, if our changed default breaks an app, that app can always -pass in an explicit max-parameters with a larger value. - -It is also intentional that the HMP interface to nbd-server-start is -not changed to expose max-connections (any client needing to fine-tune -things should be using QMP). - -Suggested-by: Daniel P. Berrangé -Signed-off-by: Eric Blake -Message-ID: <20240807174943.771624-12-eblake@redhat.com> -Reviewed-by: Daniel P. Berrangé -[ericb: Expand commit message to summarize Dan's argument for why we -break corner-case back-compat behavior without a deprecation period] -Signed-off-by: Eric Blake - -(cherry picked from commit c8a76dbd90c2f48df89b75bef74917f90a59b623) -Jira: https://issues.redhat.com/browse/RHEL-52617 -Signed-off-by: Eric Blake ---- - block/monitor/block-hmp-cmds.c | 3 ++- - blockdev-nbd.c | 8 ++++++++ - include/block/nbd.h | 7 +++++++ - qapi/block-export.json | 4 ++-- - 4 files changed, 19 insertions(+), 3 deletions(-) - -diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c -index d954bec6f1..bdf2eb50b6 100644 ---- a/block/monitor/block-hmp-cmds.c -+++ b/block/monitor/block-hmp-cmds.c -@@ -402,7 +402,8 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) - goto exit; - } - -- nbd_server_start(addr, NULL, NULL, 0, &local_err); -+ nbd_server_start(addr, NULL, NULL, NBD_DEFAULT_MAX_CONNECTIONS, -+ &local_err); - qapi_free_SocketAddress(addr); - if (local_err != NULL) { - goto exit; -diff --git a/blockdev-nbd.c b/blockdev-nbd.c -index 267a1de903..24ba5382db 100644 ---- a/blockdev-nbd.c -+++ b/blockdev-nbd.c -@@ -170,6 +170,10 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds, - - void nbd_server_start_options(NbdServerOptions *arg, Error **errp) - { -+ if (!arg->has_max_connections) { -+ arg->max_connections = NBD_DEFAULT_MAX_CONNECTIONS; -+ } -+ - nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz, - arg->max_connections, errp); - } -@@ -182,6 +186,10 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr, - { - SocketAddress *addr_flat = socket_address_flatten(addr); - -+ if (!has_max_connections) { -+ max_connections = NBD_DEFAULT_MAX_CONNECTIONS; -+ } -+ - nbd_server_start(addr_flat, tls_creds, tls_authz, max_connections, errp); - qapi_free_SocketAddress(addr_flat); - } -diff --git a/include/block/nbd.h b/include/block/nbd.h -index 1d4d65922d..d4f8b21aec 100644 ---- a/include/block/nbd.h -+++ b/include/block/nbd.h -@@ -39,6 +39,13 @@ extern const BlockExportDriver blk_exp_nbd; - */ - #define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10 - -+/* -+ * NBD_DEFAULT_MAX_CONNECTIONS: Number of client sockets to allow at -+ * once; must be large enough to allow a MULTI_CONN-aware client like -+ * nbdcopy to create its typical number of 8-16 sockets. -+ */ -+#define NBD_DEFAULT_MAX_CONNECTIONS 100 -+ - /* Handshake phase structs - this struct is passed on the wire */ - - typedef struct NBDOption { -diff --git a/qapi/block-export.json b/qapi/block-export.json -index 3919a2d5b9..f45e4fd481 100644 ---- a/qapi/block-export.json -+++ b/qapi/block-export.json -@@ -28,7 +28,7 @@ - # @max-connections: The maximum number of connections to allow at the - # same time, 0 for unlimited. Setting this to 1 also stops the - # server from advertising multiple client support (since 5.2; --# default: 0) -+# default: 100) - # - # Since: 4.2 - ## -@@ -63,7 +63,7 @@ - # @max-connections: The maximum number of connections to allow at the - # same time, 0 for unlimited. Setting this to 1 also stops the - # server from advertising multiple client support (since 5.2; --# default: 0). -+# default: 100). - # - # Errors: - # - if the server is already running --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-CVE-2024-7409-Close-stray-clients-at-serv.patch b/SOURCES/kvm-nbd-server-CVE-2024-7409-Close-stray-clients-at-serv.patch deleted file mode 100644 index 2ba16e5..0000000 --- a/SOURCES/kvm-nbd-server-CVE-2024-7409-Close-stray-clients-at-serv.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 6522c68268f00c9c5665f8f98cf6ed1984124cf3 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Wed, 7 Aug 2024 12:23:13 -0500 -Subject: [PATCH 100/100] nbd/server: CVE-2024-7409: Close stray clients at - server-stop -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 262: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) -RH-Jira: RHEL-52617 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [4/4] c00bb5a7e73446e9f071ef83e4f1576f73a17059 (redhat/centos-stream/src/qemu-kvm) - -A malicious client can attempt to connect to an NBD server, and then -intentionally delay progress in the handshake, including if it does -not know the TLS secrets. Although the previous two patches reduce -this behavior by capping the default max-connections parameter and -killing slow clients, they did not eliminate the possibility of a -client waiting to close the socket until after the QMP nbd-server-stop -command is executed, at which point qemu would SEGV when trying to -dereference the NULL nbd_server global which is no longer present. -This amounts to a denial of service attack. Worse, if another NBD -server is started before the malicious client disconnects, I cannot -rule out additional adverse effects when the old client interferes -with the connection count of the new server (although the most likely -is a crash due to an assertion failure when checking -nbd_server->connections > 0). - -For environments without this patch, the CVE can be mitigated by -ensuring (such as via a firewall) that only trusted clients can -connect to an NBD server. Note that using frameworks like libvirt -that ensure that TLS is used and that nbd-server-stop is not executed -while any trusted clients are still connected will only help if there -is also no possibility for an untrusted client to open a connection -but then stall on the NBD handshake. - -Given the previous patches, it would be possible to guarantee that no -clients remain connected by having nbd-server-stop sleep for longer -than the default handshake deadline before finally freeing the global -nbd_server object, but that could make QMP non-responsive for a long -time. So intead, this patch fixes the problem by tracking all client -sockets opened while the server is running, and forcefully closing any -such sockets remaining without a completed handshake at the time of -nbd-server-stop, then waiting until the coroutines servicing those -sockets notice the state change. nbd-server-stop now has a second -AIO_WAIT_WHILE_UNLOCKED (the first is indirectly through the -blk_exp_close_all_type() that disconnects all clients that completed -handshakes), but forced socket shutdown is enough to progress the -coroutines and quickly tear down all clients before the server is -freed, thus finally fixing the CVE. - -This patch relies heavily on the fact that nbd/server.c guarantees -that it only calls nbd_blockdev_client_closed() from the main loop -(see the assertion in nbd_client_put() and the hoops used in -nbd_client_put_nonzero() to achieve that); if we did not have that -guarantee, we would also need a mutex protecting our accesses of the -list of connections to survive re-entrancy from independent iothreads. - -Although I did not actually try to test old builds, it looks like this -problem has existed since at least commit 862172f45c (v2.12.0, 2017) - -even back when that patch started using a QIONetListener to handle -listening on multiple sockets, nbd_server_free() was already unaware -that the nbd_blockdev_client_closed callback can be reached later by a -client thread that has not completed handshakes (and therefore the -client's socket never got added to the list closed in -nbd_export_close_all), despite that patch intentionally tearing down -the QIONetListener to prevent new clients. - -Reported-by: Alexander Ivanov -Fixes: CVE-2024-7409 -CC: qemu-stable@nongnu.org -Signed-off-by: Eric Blake -Message-ID: <20240807174943.771624-14-eblake@redhat.com> -Reviewed-by: Daniel P. Berrangé - -(cherry picked from commit 3e7ef738c8462c45043a1d39f702a0990406a3b3) -Jira: https://issues.redhat.com/browse/RHEL-52617 -Signed-off-by: Eric Blake ---- - blockdev-nbd.c | 35 ++++++++++++++++++++++++++++++++++- - 1 file changed, 34 insertions(+), 1 deletion(-) - -diff --git a/blockdev-nbd.c b/blockdev-nbd.c -index 24ba5382db..f73409ae49 100644 ---- a/blockdev-nbd.c -+++ b/blockdev-nbd.c -@@ -21,12 +21,18 @@ - #include "io/channel-socket.h" - #include "io/net-listener.h" - -+typedef struct NBDConn { -+ QIOChannelSocket *cioc; -+ QLIST_ENTRY(NBDConn) next; -+} NBDConn; -+ - typedef struct NBDServerData { - QIONetListener *listener; - QCryptoTLSCreds *tlscreds; - char *tlsauthz; - uint32_t max_connections; - uint32_t connections; -+ QLIST_HEAD(, NBDConn) conns; - } NBDServerData; - - static NBDServerData *nbd_server; -@@ -51,6 +57,14 @@ int nbd_server_max_connections(void) - - static void nbd_blockdev_client_closed(NBDClient *client, bool ignored) - { -+ NBDConn *conn = nbd_client_owner(client); -+ -+ assert(qemu_in_main_thread() && nbd_server); -+ -+ object_unref(OBJECT(conn->cioc)); -+ QLIST_REMOVE(conn, next); -+ g_free(conn); -+ - nbd_client_put(client); - assert(nbd_server->connections > 0); - nbd_server->connections--; -@@ -60,14 +74,20 @@ static void nbd_blockdev_client_closed(NBDClient *client, bool ignored) - static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, - gpointer opaque) - { -+ NBDConn *conn = g_new0(NBDConn, 1); -+ -+ assert(qemu_in_main_thread() && nbd_server); - nbd_server->connections++; -+ object_ref(OBJECT(cioc)); -+ conn->cioc = cioc; -+ QLIST_INSERT_HEAD(&nbd_server->conns, conn, next); - nbd_update_server_watch(nbd_server); - - qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server"); - /* TODO - expose handshake timeout as QMP option */ - nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS, - nbd_server->tlscreds, nbd_server->tlsauthz, -- nbd_blockdev_client_closed, NULL); -+ nbd_blockdev_client_closed, conn); - } - - static void nbd_update_server_watch(NBDServerData *s) -@@ -81,12 +101,25 @@ static void nbd_update_server_watch(NBDServerData *s) - - static void nbd_server_free(NBDServerData *server) - { -+ NBDConn *conn, *tmp; -+ - if (!server) { - return; - } - -+ /* -+ * Forcefully close the listener socket, and any clients that have -+ * not yet disconnected on their own. -+ */ - qio_net_listener_disconnect(server->listener); - object_unref(OBJECT(server->listener)); -+ QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) { -+ qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH, -+ NULL); -+ } -+ -+ AIO_WAIT_WHILE_UNLOCKED(NULL, server->connections > 0); -+ - if (server->tlscreds) { - object_unref(OBJECT(server->tlscreds)); - } --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-CVE-2024-7409-Drop-non-negotiating-client.patch b/SOURCES/kvm-nbd-server-CVE-2024-7409-Drop-non-negotiating-client.patch deleted file mode 100644 index e1755c2..0000000 --- a/SOURCES/kvm-nbd-server-CVE-2024-7409-Drop-non-negotiating-client.patch +++ /dev/null @@ -1,135 +0,0 @@ -From ca30846351f1136d15f55717a5534ad927f7cf52 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Thu, 8 Aug 2024 16:05:08 -0500 -Subject: [PATCH 099/100] nbd/server: CVE-2024-7409: Drop non-negotiating - clients -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 262: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) -RH-Jira: RHEL-52617 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [3/4] 8008a1067766951d9752bcc41c2127a07fce934d (redhat/centos-stream/src/qemu-kvm) - -A client that opens a socket but does not negotiate is merely hogging -qemu's resources (an open fd and a small amount of memory); and a -malicious client that can access the port where NBD is listening can -attempt a denial of service attack by intentionally opening and -abandoning lots of unfinished connections. The previous patch put a -default bound on the number of such ongoing connections, but once that -limit is hit, no more clients can connect (including legitimate ones). -The solution is to insist that clients complete handshake within a -reasonable time limit, defaulting to 10 seconds. A client that has -not successfully completed NBD_OPT_GO by then (including the case of -where the client didn't know TLS credentials to even reach the point -of NBD_OPT_GO) is wasting our time and does not deserve to stay -connected. Later patches will allow fine-tuning the limit away from -the default value (including disabling it for doing integration -testing of the handshake process itself). - -Note that this patch in isolation actually makes it more likely to see -qemu SEGV after nbd-server-stop, as any client socket still connected -when the server shuts down will now be closed after 10 seconds rather -than at the client's whims. That will be addressed in the next patch. - -For a demo of this patch in action: -$ qemu-nbd -f raw -r -t -e 10 file & -$ nbdsh --opt-mode -c ' -H = list() -for i in range(20): - print(i) - H.insert(i, nbd.NBD()) - H[i].set_opt_mode(True) - H[i].connect_uri("nbd://localhost") -' -$ kill $! - -where later connections get to start progressing once earlier ones are -forcefully dropped for taking too long, rather than hanging. - -Suggested-by: Daniel P. Berrangé -Signed-off-by: Eric Blake -Message-ID: <20240807174943.771624-13-eblake@redhat.com> -Reviewed-by: Daniel P. Berrangé -[eblake: rebase to changes earlier in series, reduce scope of timer] -Signed-off-by: Eric Blake - -(cherry picked from commit b9b72cb3ce15b693148bd09cef7e50110566d8a0) -Jira: https://issues.redhat.com/browse/RHEL-52617 -Signed-off-by: Eric Blake ---- - nbd/server.c | 28 +++++++++++++++++++++++++++- - nbd/trace-events | 1 + - 2 files changed, 28 insertions(+), 1 deletion(-) - -diff --git a/nbd/server.c b/nbd/server.c -index e50012499f..39285cc971 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -3186,22 +3186,48 @@ static void nbd_client_receive_next_request(NBDClient *client) - } - } - -+static void nbd_handshake_timer_cb(void *opaque) -+{ -+ QIOChannel *ioc = opaque; -+ -+ trace_nbd_handshake_timer_cb(); -+ qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL); -+} -+ - static coroutine_fn void nbd_co_client_start(void *opaque) - { - NBDClient *client = opaque; - Error *local_err = NULL; -+ QEMUTimer *handshake_timer = NULL; - - qemu_co_mutex_init(&client->send_lock); - -- /* TODO - utilize client->handshake_max_secs */ -+ /* -+ * Create a timer to bound the time spent in negotiation. If the -+ * timer expires, it is likely nbd_negotiate will fail because the -+ * socket was shutdown. -+ */ -+ if (client->handshake_max_secs > 0) { -+ handshake_timer = aio_timer_new(qemu_get_aio_context(), -+ QEMU_CLOCK_REALTIME, -+ SCALE_NS, -+ nbd_handshake_timer_cb, -+ client->sioc); -+ timer_mod(handshake_timer, -+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + -+ client->handshake_max_secs * NANOSECONDS_PER_SECOND); -+ } -+ - if (nbd_negotiate(client, &local_err)) { - if (local_err) { - error_report_err(local_err); - } -+ timer_free(handshake_timer); - client_close(client, false); - return; - } - -+ timer_free(handshake_timer); - WITH_QEMU_LOCK_GUARD(&client->lock) { - nbd_client_receive_next_request(client); - } -diff --git a/nbd/trace-events b/nbd/trace-events -index 00ae3216a1..cbd0a4ab7e 100644 ---- a/nbd/trace-events -+++ b/nbd/trace-events -@@ -76,6 +76,7 @@ nbd_co_receive_request_payload_received(uint64_t cookie, uint64_t len) "Payload - nbd_co_receive_ext_payload_compliance(uint64_t from, uint64_t len) "client sent non-compliant write without payload flag: from=0x%" PRIx64 ", len=0x%" PRIx64 - nbd_co_receive_align_compliance(const char *op, uint64_t from, uint64_t len, uint32_t align) "client sent non-compliant unaligned %s request: from=0x%" PRIx64 ", len=0x%" PRIx64 ", align=0x%" PRIx32 - nbd_trip(void) "Reading request" -+nbd_handshake_timer_cb(void) "client took too long to negotiate" - - # client-connection.c - nbd_connect_thread_sleep(uint64_t timeout) "timeout %" PRIu64 --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch b/SOURCES/kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch deleted file mode 100644 index 7614df8..0000000 --- a/SOURCES/kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch +++ /dev/null @@ -1,330 +0,0 @@ -From af6f51ad3482513e3ac047eb203f9dc623d47088 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Mon, 8 Apr 2024 11:00:44 -0500 -Subject: [PATCH 2/2] nbd/server: Mark negotiation functions as coroutine_fn - -RH-Author: Eric Blake -RH-MergeRequest: 239: avoid destination hang on NBD+TLS storage migration -RH-Jira: RHEL-33440 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [2/2] acf61b854f80365993d24bcd1d110ed3518b22fa (ebblake/centos-qemu-kvm) - -nbd_negotiate() is already marked coroutine_fn. And given the fix in -the previous patch to have nbd_negotiate_handle_starttls not create -and wait on a g_main_loop (as that would violate coroutine -constraints), it is worth marking the rest of the related static -functions reachable only during option negotiation as also being -coroutine_fn. - -Suggested-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Eric Blake -Message-ID: <20240408160214.1200629-6-eblake@redhat.com> -Reviewed-by: Vladimir Sementsov-Ogievskiy -[eblake: drop one spurious coroutine_fn marking] -Signed-off-by: Eric Blake - -Jira: https://issues.redhat.com/browse/RHEL-33440 -(cherry picked from commit 4fa333e08dd96395a99ea8dd9e4c73a29dd23344) -Signed-off-by: Eric Blake ---- - nbd/server.c | 102 +++++++++++++++++++++++++++++---------------------- - 1 file changed, 59 insertions(+), 43 deletions(-) - -diff --git a/nbd/server.c b/nbd/server.c -index 98ae0e1632..892797bb11 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -195,8 +195,9 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option, - - /* Send a reply header, including length, but no payload. - * Return -errno on error, 0 on success. */ --static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, -- uint32_t len, Error **errp) -+static coroutine_fn int -+nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, -+ uint32_t len, Error **errp) - { - NBDOptionReply rep; - -@@ -211,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type, - - /* Send a reply header with default 0 length. - * Return -errno on error, 0 on success. */ --static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type, -- Error **errp) -+static coroutine_fn int -+nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp) - { - return nbd_negotiate_send_rep_len(client, type, 0, errp); - } - - /* Send an error reply. - * Return -errno on error, 0 on success. */ --static int G_GNUC_PRINTF(4, 0) -+static coroutine_fn int G_GNUC_PRINTF(4, 0) - nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type, - Error **errp, const char *fmt, va_list va) - { -@@ -259,7 +260,7 @@ nbd_sanitize_name(const char *name) - - /* Send an error reply. - * Return -errno on error, 0 on success. */ --static int G_GNUC_PRINTF(4, 5) -+static coroutine_fn int G_GNUC_PRINTF(4, 5) - nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type, - Error **errp, const char *fmt, ...) - { -@@ -275,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type, - /* Drop remainder of the current option, and send a reply with the - * given error type and message. Return -errno on read or write - * failure; or 0 if connection is still live. */ --static int G_GNUC_PRINTF(4, 0) -+static coroutine_fn int G_GNUC_PRINTF(4, 0) - nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp, - const char *fmt, va_list va) - { -@@ -288,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp, - return ret; - } - --static int G_GNUC_PRINTF(4, 5) -+static coroutine_fn int G_GNUC_PRINTF(4, 5) - nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp, - const char *fmt, ...) - { -@@ -302,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp, - return ret; - } - --static int G_GNUC_PRINTF(3, 4) -+static coroutine_fn int G_GNUC_PRINTF(3, 4) - nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) - { - int ret; -@@ -319,8 +320,9 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) - * If @check_nul, require that no NUL bytes appear in buffer. - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. */ --static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, -- bool check_nul, Error **errp) -+static coroutine_fn int -+nbd_opt_read(NBDClient *client, void *buffer, size_t size, -+ bool check_nul, Error **errp) - { - if (size > client->optlen) { - return nbd_opt_invalid(client, errp, -@@ -343,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, - /* Drop size bytes from the unparsed payload of the current option. - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. */ --static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp) -+static coroutine_fn int -+nbd_opt_skip(NBDClient *client, size_t size, Error **errp) - { - if (size > client->optlen) { - return nbd_opt_invalid(client, errp, -@@ -366,8 +369,9 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp) - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. - */ --static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, -- Error **errp) -+static coroutine_fn int -+nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, -+ Error **errp) - { - int ret; - uint32_t len; -@@ -402,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, - - /* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload. - * Return -errno on error, 0 on success. */ --static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, -- Error **errp) -+static coroutine_fn int -+nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp) - { - ERRP_GUARD(); - size_t name_len, desc_len; -@@ -444,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, - - /* Process the NBD_OPT_LIST command, with a potential series of replies. - * Return -errno on error, 0 on success. */ --static int nbd_negotiate_handle_list(NBDClient *client, Error **errp) -+static coroutine_fn int -+nbd_negotiate_handle_list(NBDClient *client, Error **errp) - { - NBDExport *exp; - assert(client->opt == NBD_OPT_LIST); -@@ -459,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp) - return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp); - } - --static void nbd_check_meta_export(NBDClient *client, NBDExport *exp) -+static coroutine_fn void -+nbd_check_meta_export(NBDClient *client, NBDExport *exp) - { - if (exp != client->contexts.exp) { - client->contexts.count = 0; -@@ -468,8 +474,9 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp) - - /* Send a reply to NBD_OPT_EXPORT_NAME. - * Return -errno on error, 0 on success. */ --static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, -- Error **errp) -+static coroutine_fn int -+nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, -+ Error **errp) - { - ERRP_GUARD(); - g_autofree char *name = NULL; -@@ -536,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, - /* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes. - * The buffer does NOT include the info type prefix. - * Return -errno on error, 0 if ready to send more. */ --static int nbd_negotiate_send_info(NBDClient *client, -- uint16_t info, uint32_t length, void *buf, -- Error **errp) -+static coroutine_fn int -+nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length, -+ void *buf, Error **errp) - { - int rc; - -@@ -565,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client, - * -errno transmission error occurred or @fatal was requested, errp is set - * 0 error message successfully sent to client, errp is not set - */ --static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp) -+static coroutine_fn int -+nbd_reject_length(NBDClient *client, bool fatal, Error **errp) - { - int ret; - -@@ -583,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp) - /* Handle NBD_OPT_INFO and NBD_OPT_GO. - * Return -errno on error, 0 if ready for next option, and 1 to move - * into transmission phase. */ --static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) -+static coroutine_fn int -+nbd_negotiate_handle_info(NBDClient *client, Error **errp) - { - int rc; - g_autofree char *name = NULL; -@@ -755,7 +764,8 @@ struct NBDTLSServerHandshakeData { - Coroutine *co; - }; - --static void nbd_server_tls_handshake(QIOTask *task, void *opaque) -+static void -+nbd_server_tls_handshake(QIOTask *task, void *opaque) - { - struct NBDTLSServerHandshakeData *data = opaque; - -@@ -768,8 +778,8 @@ static void nbd_server_tls_handshake(QIOTask *task, void *opaque) - - /* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the - * new channel for all further (now-encrypted) communication. */ --static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, -- Error **errp) -+static coroutine_fn QIOChannel * -+nbd_negotiate_handle_starttls(NBDClient *client, Error **errp) - { - QIOChannel *ioc; - QIOChannelTLS *tioc; -@@ -821,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, - * - * For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead. - */ --static int nbd_negotiate_send_meta_context(NBDClient *client, -- const char *context, -- uint32_t context_id, -- Error **errp) -+static coroutine_fn int -+nbd_negotiate_send_meta_context(NBDClient *client, const char *context, -+ uint32_t context_id, Error **errp) - { - NBDOptionReplyMetaContext opt; - struct iovec iov[] = { -@@ -849,8 +858,9 @@ static int nbd_negotiate_send_meta_context(NBDClient *client, - * Return true if @query matches @pattern, or if @query is empty when - * the @client is performing _LIST_. - */ --static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, -- const char *query) -+static coroutine_fn bool -+nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, -+ const char *query) - { - if (!*query) { - trace_nbd_negotiate_meta_query_parse("empty"); -@@ -867,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, - /* - * Return true and adjust @str in place if it begins with @prefix. - */ --static bool nbd_strshift(const char **str, const char *prefix) -+static coroutine_fn bool -+nbd_strshift(const char **str, const char *prefix) - { - size_t len = strlen(prefix); - -@@ -883,8 +894,9 @@ static bool nbd_strshift(const char **str, const char *prefix) - * Handle queries to 'base' namespace. For now, only the base:allocation - * context is available. Return true if @query has been handled. - */ --static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, -- const char *query) -+static coroutine_fn bool -+nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, -+ const char *query) - { - if (!nbd_strshift(&query, "base:")) { - return false; -@@ -903,8 +915,9 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta, - * and qemu:allocation-depth contexts are available. Return true if @query - * has been handled. - */ --static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, -- const char *query) -+static coroutine_fn bool -+nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, -+ const char *query) - { - size_t i; - -@@ -968,8 +981,9 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta, - * - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. */ --static int nbd_negotiate_meta_query(NBDClient *client, -- NBDMetaContexts *meta, Error **errp) -+static coroutine_fn int -+nbd_negotiate_meta_query(NBDClient *client, -+ NBDMetaContexts *meta, Error **errp) - { - int ret; - g_autofree char *query = NULL; -@@ -1008,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client, - * Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT - * - * Return -errno on I/O error, or 0 if option was completely handled. */ --static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp) -+static coroutine_fn int -+nbd_negotiate_meta_queries(NBDClient *client, Error **errp) - { - int ret; - g_autofree char *export_name = NULL; -@@ -1136,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp) - * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, - * errp is not set - */ --static int nbd_negotiate_options(NBDClient *client, Error **errp) -+static coroutine_fn int -+nbd_negotiate_options(NBDClient *client, Error **errp) - { - uint32_t flags; - bool fixedNewstyle = false; --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-Plumb-in-new-args-to-nbd_client_add.patch b/SOURCES/kvm-nbd-server-Plumb-in-new-args-to-nbd_client_add.patch deleted file mode 100644 index 6b4c670..0000000 --- a/SOURCES/kvm-nbd-server-Plumb-in-new-args-to-nbd_client_add.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 70acef52a99e5114699f5fa58de5f0b5c031b880 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Wed, 7 Aug 2024 08:50:01 -0500 -Subject: [PATCH 097/100] nbd/server: Plumb in new args to nbd_client_add() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 262: nbd/server: fix CVE-2024-7409 (qemu crash on nbd-server-stop) -RH-Jira: RHEL-52617 -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/4] 7614e294e1f5b7861386950ae994bea166d19950 (redhat/centos-stream/src/qemu-kvm) - -Upcoming patches to fix a CVE need to track an opaque pointer passed -in by the owner of a client object, as well as request for a time -limit on how fast negotiation must complete. Prepare for that by -changing the signature of nbd_client_new() and adding an accessor to -get at the opaque pointer, although for now the two servers -(qemu-nbd.c and blockdev-nbd.c) do not change behavior even though -they pass in a new default timeout value. - -Suggested-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Eric Blake -Message-ID: <20240807174943.771624-11-eblake@redhat.com> -Reviewed-by: Daniel P. Berrangé -[eblake: s/LIMIT/MAX_SECS/ as suggested by Dan] -Signed-off-by: Eric Blake - -(cherry picked from commit fb1c2aaa981e0a2fa6362c9985f1296b74f055ac) -Jira: https://issues.redhat.com/browse/RHEL-52617 -Signed-off-by: Eric Blake ---- - blockdev-nbd.c | 6 ++++-- - include/block/nbd.h | 11 ++++++++++- - nbd/server.c | 20 +++++++++++++++++--- - qemu-nbd.c | 4 +++- - 4 files changed, 34 insertions(+), 7 deletions(-) - -diff --git a/blockdev-nbd.c b/blockdev-nbd.c -index 213012435f..267a1de903 100644 ---- a/blockdev-nbd.c -+++ b/blockdev-nbd.c -@@ -64,8 +64,10 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, - nbd_update_server_watch(nbd_server); - - qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server"); -- nbd_client_new(cioc, nbd_server->tlscreds, nbd_server->tlsauthz, -- nbd_blockdev_client_closed); -+ /* TODO - expose handshake timeout as QMP option */ -+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS, -+ nbd_server->tlscreds, nbd_server->tlsauthz, -+ nbd_blockdev_client_closed, NULL); - } - - static void nbd_update_server_watch(NBDServerData *s) -diff --git a/include/block/nbd.h b/include/block/nbd.h -index 4e7bd6342f..1d4d65922d 100644 ---- a/include/block/nbd.h -+++ b/include/block/nbd.h -@@ -33,6 +33,12 @@ typedef struct NBDMetaContexts NBDMetaContexts; - - extern const BlockExportDriver blk_exp_nbd; - -+/* -+ * NBD_DEFAULT_HANDSHAKE_MAX_SECS: Number of seconds in which client must -+ * succeed at NBD_OPT_GO before being forcefully dropped as too slow. -+ */ -+#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10 -+ - /* Handshake phase structs - this struct is passed on the wire */ - - typedef struct NBDOption { -@@ -403,9 +409,12 @@ AioContext *nbd_export_aio_context(NBDExport *exp); - NBDExport *nbd_export_find(const char *name); - - void nbd_client_new(QIOChannelSocket *sioc, -+ uint32_t handshake_max_secs, - QCryptoTLSCreds *tlscreds, - const char *tlsauthz, -- void (*close_fn)(NBDClient *, bool)); -+ void (*close_fn)(NBDClient *, bool), -+ void *owner); -+void *nbd_client_owner(NBDClient *client); - void nbd_client_get(NBDClient *client); - void nbd_client_put(NBDClient *client); - -diff --git a/nbd/server.c b/nbd/server.c -index 892797bb11..e50012499f 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -124,12 +124,14 @@ struct NBDMetaContexts { - struct NBDClient { - int refcount; /* atomic */ - void (*close_fn)(NBDClient *client, bool negotiated); -+ void *owner; - - QemuMutex lock; - - NBDExport *exp; - QCryptoTLSCreds *tlscreds; - char *tlsauthz; -+ uint32_t handshake_max_secs; - QIOChannelSocket *sioc; /* The underlying data channel */ - QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */ - -@@ -3191,6 +3193,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque) - - qemu_co_mutex_init(&client->send_lock); - -+ /* TODO - utilize client->handshake_max_secs */ - if (nbd_negotiate(client, &local_err)) { - if (local_err) { - error_report_err(local_err); -@@ -3205,14 +3208,17 @@ static coroutine_fn void nbd_co_client_start(void *opaque) - } - - /* -- * Create a new client listener using the given channel @sioc. -+ * Create a new client listener using the given channel @sioc and @owner. - * Begin servicing it in a coroutine. When the connection closes, call -- * @close_fn with an indication of whether the client completed negotiation. -+ * @close_fn with an indication of whether the client completed negotiation -+ * within @handshake_max_secs seconds (0 for unbounded). - */ - void nbd_client_new(QIOChannelSocket *sioc, -+ uint32_t handshake_max_secs, - QCryptoTLSCreds *tlscreds, - const char *tlsauthz, -- void (*close_fn)(NBDClient *, bool)) -+ void (*close_fn)(NBDClient *, bool), -+ void *owner) - { - NBDClient *client; - Coroutine *co; -@@ -3225,13 +3231,21 @@ void nbd_client_new(QIOChannelSocket *sioc, - object_ref(OBJECT(client->tlscreds)); - } - client->tlsauthz = g_strdup(tlsauthz); -+ client->handshake_max_secs = handshake_max_secs; - client->sioc = sioc; - qio_channel_set_delay(QIO_CHANNEL(sioc), false); - object_ref(OBJECT(client->sioc)); - client->ioc = QIO_CHANNEL(sioc); - object_ref(OBJECT(client->ioc)); - client->close_fn = close_fn; -+ client->owner = owner; - - co = qemu_coroutine_create(nbd_co_client_start, client); - qemu_coroutine_enter(co); - } -+ -+void * -+nbd_client_owner(NBDClient *client) -+{ -+ return client->owner; -+} -diff --git a/qemu-nbd.c b/qemu-nbd.c -index d7b3ccab21..48e2fa5858 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -390,7 +390,9 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc, - - nb_fds++; - nbd_update_server_watch(); -- nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed); -+ /* TODO - expose handshake timeout as command line option */ -+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS, -+ tlscreds, tlsauthz, nbd_client_closed, NULL); - } - - static void nbd_update_server_watch(void) --- -2.39.3 - diff --git a/SOURCES/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch b/SOURCES/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch new file mode 100644 index 0000000..c28bb0f --- /dev/null +++ b/SOURCES/kvm-nbd-server-Silence-server-warnings-on-port-probes.patch @@ -0,0 +1,105 @@ +From 908997de5fa9470549347d66f7c8e125989fa4b1 Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Fri, 15 Nov 2024 13:55:53 -0600 +Subject: [PATCH 1/3] nbd-server: Silence server warnings on port probes + +RH-Author: Eric Blake +RH-MergeRequest: 333: nbd-server: Silence server warnings on port probes +RH-Jira: RHEL-67863 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] c09db866ba3028702996ab1db459061cbf9e8bfa (ebblake/centos-qemu-kvm) + +While testing the use of qemu-nbd in a Pod of a Kubernetes cluster, I +got LOTS of log messages of the forms: + +qemu-nbd: option negotiation failed: Failed to read flags: Unexpected end-of-file before all data were read +qemu-nbd: option negotiation failed: Failed to read flags: Unable to read from socket: Connection reset by peer + +While it is nice to warn about clients that aren't following protocol +(in case it helps diagnosing bugs in those clients), a mere port probe +(where the client never write()s any bytes, and where we might even +hit EPIPE in trying to send our greeting to the client) is NOT +abnormal, but merely serves to pollute the log. And Kubernetes +_really_ likes to do port probes to determine whether a given Pod is +up and running. + +Easy ways to demonstrate the above port probes: +$ qemu-nbd -r -f raw path/to/file & +$ nc localhost 10809 +Message-ID: <20241115195638.1132007-2-eblake@redhat.com> +Reviewed-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit efd3dda312129b91986f85976afbda58d40f757f) +Signed-off-by: Eric Blake +--- + nbd/server.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/nbd/server.c b/nbd/server.c +index c30e687fc8..f64e47270c 100644 +--- a/nbd/server.c ++++ b/nbd/server.c +@@ -1150,8 +1150,8 @@ nbd_negotiate_meta_queries(NBDClient *client, Error **errp) + * Return: + * -errno on error, errp is set + * 0 on successful negotiation, errp is not set +- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, +- * errp is not set ++ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never ++ * wrote anything (i.e. port probe); errp is not set + */ + static coroutine_fn int + nbd_negotiate_options(NBDClient *client, Error **errp) +@@ -1175,8 +1175,13 @@ nbd_negotiate_options(NBDClient *client, Error **errp) + ... Rest of request + */ + +- if (nbd_read32(client->ioc, &flags, "flags", errp) < 0) { +- return -EIO; ++ /* ++ * Intentionally ignore errors on this first read - we do not want ++ * to be noisy about a mere port probe, but only for clients that ++ * start talking the protocol and then quit abruptly. ++ */ ++ if (nbd_read32(client->ioc, &flags, "flags", NULL) < 0) { ++ return 1; + } + client->mode = NBD_MODE_EXPORT_NAME; + trace_nbd_negotiate_options_flags(flags); +@@ -1383,8 +1388,8 @@ nbd_negotiate_options(NBDClient *client, Error **errp) + * Return: + * -errno on error, errp is set + * 0 on successful negotiation, errp is not set +- * 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect, +- * errp is not set ++ * 1 if client sent NBD_OPT_ABORT (i.e. on valid disconnect) or never ++ * wrote anything (i.e. port probe); errp is not set + */ + static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) + { +@@ -1415,9 +1420,12 @@ static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp) + stq_be_p(buf + 8, NBD_OPTS_MAGIC); + stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES); + +- if (nbd_write(client->ioc, buf, 18, errp) < 0) { +- error_prepend(errp, "write failed: "); +- return -EINVAL; ++ /* ++ * Be silent about failure to write our greeting: there is nothing ++ * wrong with a client testing if our port is alive. ++ */ ++ if (nbd_write(client->ioc, buf, 18, NULL) < 0) { ++ return 1; + } + ret = nbd_negotiate_options(client, errp); + if (ret != 0) { +-- +2.48.1 + diff --git a/SOURCES/kvm-nbd-server-Support-inactive-nodes.patch b/SOURCES/kvm-nbd-server-Support-inactive-nodes.patch new file mode 100644 index 0000000..c37a341 --- /dev/null +++ b/SOURCES/kvm-nbd-server-Support-inactive-nodes.patch @@ -0,0 +1,68 @@ +From 77ec8365bf04afadee0a2dd7354deedd57606c54 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 4 Feb 2025 22:14:04 +0100 +Subject: [PATCH 20/23] nbd/server: Support inactive nodes + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [19/22] 8c113dd6a862b1f4ad4e5d498f4e70a5dbfdfb32 (kmwolf/centos-qemu-kvm) + +In order to support running an NBD export on inactive nodes, we must +make sure to return errors for any operations that aren't allowed on +inactive nodes. Reads are the only operation we know we need for +inactive images, so to err on the side of caution, return errors for +everything else, even if some operations could possibly be okay. + +Signed-off-by: Kevin Wolf +Acked-by: Fabiano Rosas +Message-ID: <20250204211407.381505-14-kwolf@redhat.com> +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Eric Blake +Signed-off-by: Kevin Wolf +(cherry picked from commit 2e73a17c68f4d80023dc616e596e8c1f3ea8dd75) +Signed-off-by: Kevin Wolf +--- + nbd/server.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/nbd/server.c b/nbd/server.c +index f64e47270c..2076fb2666 100644 +--- a/nbd/server.c ++++ b/nbd/server.c +@@ -2026,6 +2026,7 @@ static void nbd_export_delete(BlockExport *blk_exp) + const BlockExportDriver blk_exp_nbd = { + .type = BLOCK_EXPORT_TYPE_NBD, + .instance_size = sizeof(NBDExport), ++ .supports_inactive = true, + .create = nbd_export_create, + .delete = nbd_export_delete, + .request_shutdown = nbd_export_request_shutdown, +@@ -2920,6 +2921,22 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, + NBDExport *exp = client->exp; + char *msg; + size_t i; ++ bool inactive; ++ ++ WITH_GRAPH_RDLOCK_GUARD() { ++ inactive = bdrv_is_inactive(blk_bs(exp->common.blk)); ++ if (inactive) { ++ switch (request->type) { ++ case NBD_CMD_READ: ++ /* These commands are allowed on inactive nodes */ ++ break; ++ default: ++ /* Return an error for the rest */ ++ return nbd_send_generic_reply(client, request, -EPERM, ++ "export is inactive", errp); ++ } ++ } ++ } + + switch (request->type) { + case NBD_CMD_CACHE: +-- +2.48.1 + diff --git a/SOURCES/kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch b/SOURCES/kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch deleted file mode 100644 index 9f65e99..0000000 --- a/SOURCES/kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch +++ /dev/null @@ -1,208 +0,0 @@ -From ae9ebfc4ebd6f146951f04cf9e12eeaaf4c2387e Mon Sep 17 00:00:00 2001 -From: Zhu Yangyang -Date: Mon, 8 Apr 2024 11:00:43 -0500 -Subject: [PATCH 1/2] nbd/server: do not poll within a coroutine context - -RH-Author: Eric Blake -RH-MergeRequest: 239: avoid destination hang on NBD+TLS storage migration -RH-Jira: RHEL-33440 -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Miroslav Rezanina -RH-Commit: [1/2] 27963e92aacca8ed43994113b645f472fba8f8bc (ebblake/centos-qemu-kvm) - -Coroutines are not supposed to block. Instead, they should yield. - -The client performs TLS upgrade outside of an AIOContext, during -synchronous handshake; this still requires g_main_loop. But the -server responds to TLS upgrade inside a coroutine, so a nested -g_main_loop is wrong. Since the two callbacks no longer share more -than the setting of data.complete and data.error, it's just as easy to -use static helpers instead of trying to share a common code path. It -is also possible to add assertions that no other code is interfering -with the eventual path to qio reaching the callback, whether or not it -required a yield or main loop. - -Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation") -Signed-off-by: Zhu Yangyang -[eblake: move callbacks to their use point, add assertions] -Signed-off-by: Eric Blake -Message-ID: <20240408160214.1200629-5-eblake@redhat.com> -Reviewed-by: Vladimir Sementsov-Ogievskiy - -Jira: https://issues.redhat.com/browse/RHEL-33440 -(cherry picked from commit ae6d91a7e9b77abb029ed3fa9fad461422286942) -Signed-off-by: Eric Blake ---- - nbd/client.c | 28 ++++++++++++++++++++++++---- - nbd/common.c | 11 ----------- - nbd/nbd-internal.h | 10 ---------- - nbd/server.c | 28 +++++++++++++++++++++++----- - 4 files changed, 47 insertions(+), 30 deletions(-) - -diff --git a/nbd/client.c b/nbd/client.c -index 29ffc609a4..c89c750467 100644 ---- a/nbd/client.c -+++ b/nbd/client.c -@@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict, - return 1; - } - -+/* Callback to learn when QIO TLS upgrade is complete */ -+struct NBDTLSClientHandshakeData { -+ bool complete; -+ Error *error; -+ GMainLoop *loop; -+}; -+ -+static void nbd_client_tls_handshake(QIOTask *task, void *opaque) -+{ -+ struct NBDTLSClientHandshakeData *data = opaque; -+ -+ qio_task_propagate_error(task, &data->error); -+ data->complete = true; -+ if (data->loop) { -+ g_main_loop_quit(data->loop); -+ } -+} -+ - static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, - QCryptoTLSCreds *tlscreds, - const char *hostname, Error **errp) - { - int ret; - QIOChannelTLS *tioc; -- struct NBDTLSHandshakeData data = { 0 }; -+ struct NBDTLSClientHandshakeData data = { 0 }; - - ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp); - if (ret <= 0) { -@@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, - return NULL; - } - qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); -- data.loop = g_main_loop_new(g_main_context_default(), FALSE); - trace_nbd_receive_starttls_tls_handshake(); - qio_channel_tls_handshake(tioc, -- nbd_tls_handshake, -+ nbd_client_tls_handshake, - &data, - NULL, - NULL); - - if (!data.complete) { -+ data.loop = g_main_loop_new(g_main_context_default(), FALSE); - g_main_loop_run(data.loop); -+ assert(data.complete); -+ g_main_loop_unref(data.loop); - } -- g_main_loop_unref(data.loop); -+ - if (data.error) { - error_propagate(errp, data.error); - object_unref(OBJECT(tioc)); -diff --git a/nbd/common.c b/nbd/common.c -index 3247c1d618..589a748cfe 100644 ---- a/nbd/common.c -+++ b/nbd/common.c -@@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp) - } - - --void nbd_tls_handshake(QIOTask *task, -- void *opaque) --{ -- struct NBDTLSHandshakeData *data = opaque; -- -- qio_task_propagate_error(task, &data->error); -- data->complete = true; -- g_main_loop_quit(data->loop); --} -- -- - const char *nbd_opt_lookup(uint32_t opt) - { - switch (opt) { -diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h -index dfa02f77ee..91895106a9 100644 ---- a/nbd/nbd-internal.h -+++ b/nbd/nbd-internal.h -@@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size, - return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0; - } - --struct NBDTLSHandshakeData { -- GMainLoop *loop; -- bool complete; -- Error *error; --}; -- -- --void nbd_tls_handshake(QIOTask *task, -- void *opaque); -- - int nbd_drop(QIOChannel *ioc, size_t size, Error **errp); - - #endif -diff --git a/nbd/server.c b/nbd/server.c -index c3484cc1eb..98ae0e1632 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -748,6 +748,23 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) - return rc; - } - -+/* Callback to learn when QIO TLS upgrade is complete */ -+struct NBDTLSServerHandshakeData { -+ bool complete; -+ Error *error; -+ Coroutine *co; -+}; -+ -+static void nbd_server_tls_handshake(QIOTask *task, void *opaque) -+{ -+ struct NBDTLSServerHandshakeData *data = opaque; -+ -+ qio_task_propagate_error(task, &data->error); -+ data->complete = true; -+ if (!qemu_coroutine_entered(data->co)) { -+ aio_co_wake(data->co); -+ } -+} - - /* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the - * new channel for all further (now-encrypted) communication. */ -@@ -756,7 +773,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, - { - QIOChannel *ioc; - QIOChannelTLS *tioc; -- struct NBDTLSHandshakeData data = { 0 }; -+ struct NBDTLSServerHandshakeData data = { 0 }; - - assert(client->opt == NBD_OPT_STARTTLS); - -@@ -777,17 +794,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, - - qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls"); - trace_nbd_negotiate_handle_starttls_handshake(); -- data.loop = g_main_loop_new(g_main_context_default(), FALSE); -+ data.co = qemu_coroutine_self(); - qio_channel_tls_handshake(tioc, -- nbd_tls_handshake, -+ nbd_server_tls_handshake, - &data, - NULL, - NULL); - - if (!data.complete) { -- g_main_loop_run(data.loop); -+ qemu_coroutine_yield(); -+ assert(data.complete); - } -- g_main_loop_unref(data.loop); -+ - if (data.error) { - object_unref(OBJECT(tioc)); - error_propagate(errp, data.error); --- -2.39.3 - diff --git a/SOURCES/kvm-net-Fix-announce_self.patch b/SOURCES/kvm-net-Fix-announce_self.patch new file mode 100644 index 0000000..7c99e5c --- /dev/null +++ b/SOURCES/kvm-net-Fix-announce_self.patch @@ -0,0 +1,82 @@ +From ba42b9bf3f193bbc7f47d494bdc888e881539f4b Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Fri, 17 Jan 2025 12:17:08 +0100 +Subject: [PATCH 01/23] net: Fix announce_self +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 338: net: Fix announce_self +RH-Jira: RHEL-73891 +RH-Acked-by: Eugenio Pérez +RH-Acked-by: Cindy Lu +RH-Commit: [1/1] dfee696c1c444af0ba2b2d3d8c7012385e84885c (lvivier/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-73891 + +b9ad513e1876 ("net: Remove receive_raw()") adds an iovec entry +in qemu_deliver_packet_iov() to add the virtio-net header +in the data when QEMU_NET_PACKET_FLAG_RAW is set but forgets +to increase the number of iovec entries in the array, so +receive_iov() will only send the first entry (the virtio-net +entry, full of 0) and no data. The packet will be discarded. + +The only user of QEMU_NET_PACKET_FLAG_RAW is announce_self. + +We can see the problem with tcpdump: + +- QEMU parameters: + + .. -monitor stdio \ + -netdev bridge,id=netdev0,br=virbr0 \ + -device virtio-net,mac=9a:2b:2c:2d:2e:2f,netdev=netdev0 \ + +- HMP command: + + (qemu) announce_self + +- TCP dump: + + $ sudo tcpdump -nxi virbr0 + + without the fix: + + + + with the fix: + + ARP, Reverse Request who-is 9a:2b:2c:2d:2e:2f tell 9a:2b:2c:2d:2e:2f, length 46 + 0x0000: 0001 0800 0604 0003 9a2b 2c2d 2e2f 0000 + 0x0010: 0000 9a2b 2c2d 2e2f 0000 0000 0000 0000 + 0x0020: 0000 0000 0000 0000 0000 0000 0000 + +Reported-by: Xiaohui Li +Bug: https://issues.redhat.com/browse/RHEL-73891 +Fixes: b9ad513e1876 ("net: Remove receive_raw()") +Cc: akihiko.odaki@daynix.com +Signed-off-by: Laurent Vivier +Reviewed-by: Akihiko Odaki +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev +(cherry picked from commit 84dfdcbff33fff185528501be408c25c44499f32) +Signed-off-by: Laurent Vivier +--- + net/net.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/net.c b/net/net.c +index fc1125111c..94f51b6e5f 100644 +--- a/net/net.c ++++ b/net/net.c +@@ -828,6 +828,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, + iov_copy[0].iov_len = nc->vnet_hdr_len; + memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov)); + iov = iov_copy; ++ iovcnt++; + } + + if (nc->info->receive_iov) { +-- +2.48.1 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch b/SOURCES/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch new file mode 100644 index 0000000..204b045 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch @@ -0,0 +1,71 @@ +From df7e7db91357db9f4abd07d2bc5fb44216a2f286 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Fri, 17 Jan 2025 16:22:35 -0500 +Subject: [PATCH 1/4] pc-bios/s390-ccw: Abort IPL on invalid loadparm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 332: Fix boot problems when falling back from network to another boot device on s390x [RHEL9] +RH-Jira: RHEL-72716 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Jon Maloy +RH-Commit: [1/4] 4d19e5051374f8939bc86c5fc9eb02dede6d83d3 (thuth/qemu-kvm-cs) + +Because the loadparm specifies an exact kernel the user wants to boot, if the +loadparm is invalid it must represent a misconfiguration of the guest. Thus we +should abort the IPL immediately, without attempting to use other devices, to +avoid booting into an unintended guest image. + +Signed-off-by: Jared Rossi +Message-ID: <20250117212235.1324063-2-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 64fa0de46ee3cc972af5d3ce8c5dc0db8198cd2b) +--- + pc-bios/s390-ccw/bootmap.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index 56f2f75640..0f8baa0198 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -336,8 +336,7 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, + + debug_print_int("loadparm", loadparm); + if (loadparm >= MAX_BOOT_ENTRIES) { +- puts("loadparm value greater than max number of boot entries allowed"); +- return -EINVAL; ++ panic("loadparm value greater than max number of boot entries allowed"); + } + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +@@ -348,8 +347,8 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, + + block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl); + if (block_nr == NULL_BLOCK_NR) { +- puts("Cannot find Boot Map Table Entry"); +- return -EIO; ++ printf("The requested boot entry (%d) is invalid\n", loadparm); ++ panic("Invalid loadparm"); + } + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +@@ -792,8 +791,12 @@ static int ipl_scsi(void) + + debug_print_int("loadparm", loadparm); + if (loadparm >= MAX_BOOT_ENTRIES) { +- puts("loadparm value greater than max number of boot entries allowed"); +- return -EINVAL; ++ panic("loadparm value greater than max number of boot entries allowed"); ++ } ++ ++ if (!valid_entries[loadparm]) { ++ printf("The requested boot entry (%d) is invalid\n", loadparm); ++ panic("Invalid loadparm"); + } + + return zipl_run(&prog_table->entry[loadparm].scsi); +-- +2.48.0 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch b/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch new file mode 100644 index 0000000..83c0a3c --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch @@ -0,0 +1,60 @@ +From 77dab9f12b3c4cdaacea1dff687cf1c49e95f304 Mon Sep 17 00:00:00 2001 +From: Jens Remus +Date: Tue, 1 Oct 2024 17:36:16 +0200 +Subject: [PATCH 21/27] pc-bios/s390-ccw: Clarify alignment is in bytes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [21/23] d00be9e7c87cb047d20b729f2ac539fe624f5ce0 (thuth/qemu-kvm-cs9) + +The assembler directive .align [1] has architecture-dependent behavior, +which may be ambiguous for the reader. Some architectures perform the +alignment in bytes, others in power of two. s390 does in bytes. + +Use the directive .balign [2] instead, to clarify that the alignment +request is in bytes. No functional change. + +[1] https://sourceware.org/binutils/docs/as/Align.html +[2] https://sourceware.org/binutils/docs/as/Balign.html + +Signed-off-by: Jens Remus +Reviewed-by: Marc Hartmayer +Message-ID: <20241001153618.17791-2-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +(cherry picked from commit c58df213af7ec8924d219025a593b8f3ac475f16) +--- + pc-bios/s390-ccw/start.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S +index 061b06591c..576fc12c06 100644 +--- a/pc-bios/s390-ccw/start.S ++++ b/pc-bios/s390-ccw/start.S +@@ -112,7 +112,7 @@ io_new_code: + lctlg %c6,%c6,0(%r15) + br %r14 + +- .align 8 ++ .balign 8 + bss_start_literal: + .quad __bss_start + disabled_wait_psw: +@@ -125,7 +125,7 @@ io_new_mask: + .quad 0x0000000180000000 + + .bss +- .align 8 ++ .balign 8 + stack: + .space STACK_SIZE + .size stack,STACK_SIZE +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch b/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch new file mode 100644 index 0000000..95d42fc --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch @@ -0,0 +1,83 @@ +From 7a5f9ea3bb8ff78bd93eb2cee9b8be876e745346 Mon Sep 17 00:00:00 2001 +From: Jens Remus +Date: Tue, 1 Oct 2024 17:36:17 +0200 +Subject: [PATCH 22/27] pc-bios/s390-ccw: Don't generate TEXTRELs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [22/23] 8d8b2959be6c798f24e1991252fe6c680a6c6025 (thuth/qemu-kvm-cs9) + +Commit 7cd50cbe4ca3 ("pc-bios/s390-ccw: Don't use __bss_start with the +"larl" instruction") introduced the address constant bss_start_literal +for __bss_start in the .text section, which introduced a relocation in +code (i.e. TEXTREL). The dedicated constant is required, as __bss_start +may not necessarily be aligned on a 2-byte boundary (see subject commit +for details). + +Move the constant to the .data section to get rid of the relocation in +the .text section. Add the linker option -z text to prevent TEXTRELs to +get introduced in the future. + +Note that the R_390_RELATIVE relocations are taken care of by function +glue() in include/hw/elf_ops.h.inc introduced by commit 5dce07e1cb67 +("elf-loader: Provide the possibility to relocate s390 ELF files"). + +Reported-by: Marc Hartmayer +Signed-off-by: Jens Remus +Reviewed-by: Marc Hartmayer +Message-ID: <20241001153618.17791-3-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +(cherry picked from commit 3259b4424a85d9cdfd1a33ed6030a6c51c1b9b8b) +--- + pc-bios/s390-ccw/Makefile | 2 +- + pc-bios/s390-ccw/start.S | 7 +++++-- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index db9e8f0892..38254e22df 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -46,7 +46,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables + EXTRA_CFLAGS += -msoft-float + EXTRA_CFLAGS += -std=gnu99 + EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) +-LDFLAGS += -Wl,-pie -nostdlib -z noexecstack ++LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text + + cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null + cc-option = if $(call cc-test, $1); then \ +diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S +index 576fc12c06..b70213e412 100644 +--- a/pc-bios/s390-ccw/start.S ++++ b/pc-bios/s390-ccw/start.S +@@ -113,8 +113,6 @@ io_new_code: + br %r14 + + .balign 8 +-bss_start_literal: +- .quad __bss_start + disabled_wait_psw: + .quad 0x0002000180000000,0x0000000000000000 + enabled_wait_psw: +@@ -124,6 +122,11 @@ external_new_mask: + io_new_mask: + .quad 0x0000000180000000 + ++.data ++ .balign 8 ++bss_start_literal: ++ .quad __bss_start ++ + .bss + .balign 8 + stack: +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch b/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch new file mode 100644 index 0000000..b513e7d --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch @@ -0,0 +1,426 @@ +From 41a56360a0f4124252180132e28c166792ee8853 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:46 -0400 +Subject: [PATCH 13/27] pc-bios/s390-ccw: Enable failed IPL to return after + error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [13/23] c86e8a72a631081348e88ac1df99c2eec8ca27dd (thuth/qemu-kvm-cs9) + +Remove panic-on-error from IPL functions such that a return code is propagated +back to the main IPL calling function (rather than terminating immediately), +which facilitates possible error recovery in the future. + +A select few panics remain, which indicate fatal non-devices errors that must +result in termination. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-13-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 0181e23713114fd4c33326c3372aaf48dcfb412a) +--- + pc-bios/s390-ccw/bootmap.c | 53 ++++++++++++++++++-------- + pc-bios/s390-ccw/cio.c | 3 +- + pc-bios/s390-ccw/jump2ipl.c | 5 ++- + pc-bios/s390-ccw/main.c | 32 +++++++++------- + pc-bios/s390-ccw/s390-ccw.h | 2 +- + pc-bios/s390-ccw/virtio-blkdev.c | 2 +- + pc-bios/s390-ccw/virtio.c | 65 +++++++++++++++++++++----------- + pc-bios/s390-ccw/virtio.h | 2 +- + 8 files changed, 108 insertions(+), 56 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index 95ef9104d0..56f2f75640 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -62,15 +62,34 @@ static void *s2_prev_blk = _s2; + static void *s2_cur_blk = _s2 + MAX_SECTOR_SIZE; + static void *s2_next_blk = _s2 + MAX_SECTOR_SIZE * 2; + +-static inline void verify_boot_info(BootInfo *bip) ++static inline int verify_boot_info(BootInfo *bip) + { +- IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo"); +- IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version"); +- IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL"); +- IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD"); +- IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch"); +- IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size), +- "Bad block size in zIPL section of the 1st record."); ++ if (!magic_match(bip->magic, ZIPL_MAGIC)) { ++ puts("No zIPL sig in BootInfo"); ++ return -EINVAL; ++ } ++ if (bip->version != BOOT_INFO_VERSION) { ++ puts("Wrong zIPL version"); ++ return -EINVAL; ++ } ++ if (bip->bp_type != BOOT_INFO_BP_TYPE_IPL) { ++ puts("DASD is not for IPL"); ++ return -ENODEV; ++ } ++ if (bip->dev_type != BOOT_INFO_DEV_TYPE_ECKD) { ++ puts("DASD is not ECKD"); ++ return -ENODEV; ++ } ++ if (bip->flags != BOOT_INFO_FLAGS_ARCH) { ++ puts("Not for this arch"); ++ return -EINVAL; ++ } ++ if (!block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size)) { ++ puts("Bad block size in zIPL section of 1st record"); ++ return -EINVAL; ++ } ++ ++ return 0; + } + + static void eckd_format_chs(ExtEckdBlockPtr *ptr, bool ldipl, +@@ -367,8 +386,8 @@ static int run_eckd_boot_script(block_number_t bmt_block_nr, + puts("Unknown script entry type"); + return -EINVAL; + } +- write_reset_psw(bms->entry[i].address.load_address); /* no return */ +- jump_to_IPL_code(0); /* no return */ ++ write_reset_psw(bms->entry[i].address.load_address); ++ jump_to_IPL_code(0); + return -1; + } + +@@ -1067,16 +1086,19 @@ void zipl_load(void) + + if (vdev->is_cdrom) { + ipl_iso_el_torito(); +- panic("\n! Cannot IPL this ISO image !\n"); ++ puts("Failed to IPL this ISO image!"); ++ return; + } + + if (virtio_get_device_type() == VIRTIO_ID_NET) { + netmain(); +- panic("\n! Cannot IPL from this network !\n"); ++ puts("Failed to IPL from this network!"); ++ return; + } + + if (ipl_scsi()) { +- panic("\n! Cannot IPL this SCSI device !\n"); ++ puts("Failed to IPL from this SCSI device!"); ++ return; + } + + switch (virtio_get_device_type()) { +@@ -1087,8 +1109,9 @@ void zipl_load(void) + zipl_load_vscsi(); + break; + default: +- panic("\n! Unknown IPL device type !\n"); ++ puts("Unknown IPL device type!"); ++ return; + } + +- puts("zIPL load failed."); ++ puts("zIPL load failed!"); + } +diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c +index 7b09a38c96..5d543da73f 100644 +--- a/pc-bios/s390-ccw/cio.c ++++ b/pc-bios/s390-ccw/cio.c +@@ -59,7 +59,8 @@ uint16_t cu_type(SubChannelId schid) + }; + + if (do_cio(schid, CU_TYPE_UNKNOWN, ptr2u32(&sense_id_ccw), CCW_FMT1)) { +- panic("Failed to run SenseID CCw\n"); ++ puts("Failed to run SenseID CCW"); ++ return CU_TYPE_UNKNOWN; + } + + return sense_data.cu_type; +diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c +index 80b7f6a1f3..8db1764ff3 100644 +--- a/pc-bios/s390-ccw/jump2ipl.c ++++ b/pc-bios/s390-ccw/jump2ipl.c +@@ -33,7 +33,7 @@ static void jump_to_IPL_addr(void) + /* should not return */ + } + +-void jump_to_IPL_code(uint64_t address) ++int jump_to_IPL_code(uint64_t address) + { + /* store the subsystem information _after_ the bootmap was loaded */ + write_subsystem_identification(); +@@ -68,7 +68,8 @@ void jump_to_IPL_code(uint64_t address) + asm volatile("lghi %%r1,1\n\t" + "diag %%r1,%%r1,0x308\n\t" + : : : "1", "memory"); +- panic("\n! IPL returns !\n"); ++ puts("IPL code jump failed"); ++ return -1; + } + + void jump_to_low_kernel(void) +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index fc44da3161..34ef27d7a6 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -77,6 +77,9 @@ static int is_dev_possibly_bootable(int dev_no, int sch_no) + + enable_subchannel(blk_schid); + cutype = cu_type(blk_schid); ++ if (cutype == CU_TYPE_UNKNOWN) { ++ return -EIO; ++ } + + /* + * Note: we always have to run virtio_is_supported() here to make +@@ -194,10 +197,10 @@ static void boot_setup(void) + have_iplb = store_iplb(&iplb); + } + +-static void find_boot_device(void) ++static bool find_boot_device(void) + { + VDev *vdev = virtio_get_device(); +- bool found; ++ bool found = false; + + switch (iplb.pbt) { + case S390_IPL_TYPE_CCW: +@@ -215,10 +218,10 @@ static void find_boot_device(void) + found = find_subch(iplb.scsi.devno); + break; + default: +- panic("List-directed IPL not supported yet!\n"); ++ puts("Unsupported IPLB"); + } + +- IPL_assert(found, "Boot device not found\n"); ++ return found; + } + + static int virtio_setup(void) +@@ -244,11 +247,13 @@ static int virtio_setup(void) + ret = virtio_scsi_setup_device(blk_schid); + break; + default: +- panic("\n! No IPL device available !\n"); ++ puts("\n! No IPL device available !\n"); ++ return -1; + } + +- if (!ret) { +- IPL_assert(virtio_ipl_disk_is_valid(), "No valid IPL device detected"); ++ if (!ret && !virtio_ipl_disk_is_valid()) { ++ puts("No valid IPL device detected"); ++ return -ENODEV; + } + + return ret; +@@ -259,16 +264,16 @@ static void ipl_boot_device(void) + switch (cutype) { + case CU_TYPE_DASD_3990: + case CU_TYPE_DASD_2107: +- dasd_ipl(blk_schid, cutype); /* no return */ ++ dasd_ipl(blk_schid, cutype); + break; + case CU_TYPE_VIRTIO: +- if (virtio_setup() == 0) { +- zipl_load(); /* Only returns in case of errors */ ++ if (virtio_setup()) { ++ return; /* Only returns in case of errors */ + } ++ zipl_load(); + break; + default: + printf("Attempting to boot from unexpected device type 0x%X\n", cutype); +- panic("\nBoot failed.\n"); + } + } + +@@ -301,12 +306,11 @@ void main(void) + sclp_setup(); + css_setup(); + boot_setup(); +- if (have_iplb) { +- find_boot_device(); ++ if (have_iplb && find_boot_device()) { + ipl_boot_device(); + } else { + probe_boot_device(); + } + +- panic("Failed to load OS from hard disk\n"); ++ panic("Failed to IPL. Halting..."); + } +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index 344ad15655..6cdce3e5e5 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -78,7 +78,7 @@ void zipl_load(void); + + /* jump2ipl.c */ + void write_reset_psw(uint64_t psw); +-void jump_to_IPL_code(uint64_t address); ++int jump_to_IPL_code(uint64_t address); + void jump_to_low_kernel(void); + + /* menu.c */ +diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c +index 1c585f034b..7b2d1e20f4 100644 +--- a/pc-bios/s390-ccw/virtio-blkdev.c ++++ b/pc-bios/s390-ccw/virtio-blkdev.c +@@ -59,7 +59,7 @@ int virtio_read_many(unsigned long sector, void *load_addr, int sec_num) + case VIRTIO_ID_SCSI: + return virtio_scsi_read_many(vdev, sector, load_addr, sec_num); + } +- panic("\n! No readable IPL device !\n"); ++ + return -1; + } + +diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c +index 8c6b0a8a92..8b5a370bb3 100644 +--- a/pc-bios/s390-ccw/virtio.c ++++ b/pc-bios/s390-ccw/virtio.c +@@ -217,16 +217,19 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd) + return 0; + } + +-void virtio_setup_ccw(VDev *vdev) ++int virtio_setup_ccw(VDev *vdev) + { +- int i, rc, cfg_size = 0; ++ int i, cfg_size = 0; + uint8_t status; + struct VirtioFeatureDesc { + uint32_t features; + uint8_t index; + } __attribute__((packed)) feats; + +- IPL_assert(virtio_is_supported(vdev->schid), "PE"); ++ if (!virtio_is_supported(vdev->schid)) { ++ puts("Virtio unsupported for this device ID"); ++ return -ENODEV; ++ } + /* device ID has been established now */ + + vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ +@@ -235,8 +238,10 @@ void virtio_setup_ccw(VDev *vdev) + run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); + + status = VIRTIO_CONFIG_S_ACKNOWLEDGE; +- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); +- IPL_assert(rc == 0, "Could not write ACKNOWLEDGE status to host"); ++ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { ++ puts("Could not write ACKNOWLEDGE status to host"); ++ return -EIO; ++ } + + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: +@@ -255,27 +260,37 @@ void virtio_setup_ccw(VDev *vdev) + cfg_size = sizeof(vdev->config.scsi); + break; + default: +- panic("Unsupported virtio device\n"); ++ puts("Unsupported virtio device"); ++ return -ENODEV; + } + + status |= VIRTIO_CONFIG_S_DRIVER; +- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); +- IPL_assert(rc == 0, "Could not write DRIVER status to host"); ++ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { ++ puts("Could not write DRIVER status to host"); ++ return -EIO; ++ } + + /* Feature negotiation */ + for (i = 0; i < ARRAY_SIZE(vdev->guest_features); i++) { + feats.features = 0; + feats.index = i; +- rc = run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false); +- IPL_assert(rc == 0, "Could not get features bits"); ++ if (run_ccw(vdev, CCW_CMD_READ_FEAT, &feats, sizeof(feats), false)) { ++ puts("Could not get features bits"); ++ return -EIO; ++ } ++ + vdev->guest_features[i] &= bswap32(feats.features); + feats.features = bswap32(vdev->guest_features[i]); +- rc = run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false); +- IPL_assert(rc == 0, "Could not set features bits"); ++ if (run_ccw(vdev, CCW_CMD_WRITE_FEAT, &feats, sizeof(feats), false)) { ++ puts("Could not set features bits"); ++ return -EIO; ++ } + } + +- rc = run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false); +- IPL_assert(rc == 0, "Could not get virtio device configuration"); ++ if (run_ccw(vdev, CCW_CMD_READ_CONF, &vdev->config, cfg_size, false)) { ++ puts("Could not get virtio device configuration"); ++ return -EIO; ++ } + + for (i = 0; i < vdev->nr_vqs; i++) { + VqInfo info = { +@@ -289,19 +304,27 @@ void virtio_setup_ccw(VDev *vdev) + .num = 0, + }; + +- rc = run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), false); +- IPL_assert(rc == 0, "Could not get virtio device VQ configuration"); ++ if (run_ccw(vdev, CCW_CMD_READ_VQ_CONF, &config, sizeof(config), ++ false)) { ++ puts("Could not get virtio device VQ config"); ++ return -EIO; ++ } + info.num = config.num; + vring_init(&vdev->vrings[i], &info); + vdev->vrings[i].schid = vdev->schid; +- IPL_assert( +- run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false) == 0, +- "Cannot set VQ info"); ++ if (run_ccw(vdev, CCW_CMD_SET_VQ, &info, sizeof(info), false)) { ++ puts("Cannot set VQ info"); ++ return -EIO; ++ } + } + + status |= VIRTIO_CONFIG_S_DRIVER_OK; +- rc = run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false); +- IPL_assert(rc == 0, "Could not write DRIVER_OK status to host"); ++ if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { ++ puts("Could not write DRIVER_OK status to host"); ++ return -EIO; ++ } ++ ++ return 0; + } + + bool virtio_is_supported(SubChannelId schid) +diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h +index 6f9a558ff5..9faf3986b1 100644 +--- a/pc-bios/s390-ccw/virtio.h ++++ b/pc-bios/s390-ccw/virtio.h +@@ -274,7 +274,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags); + int vr_poll(VRing *vr); + int vring_wait_reply(void); + int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); +-void virtio_setup_ccw(VDev *vdev); ++int virtio_setup_ccw(VDev *vdev); + + int virtio_net_init(void *mac_addr); + +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch b/SOURCES/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch new file mode 100644 index 0000000..ef42b92 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch @@ -0,0 +1,159 @@ +From 7059f85f0f29707de0115cd05d951592137d9814 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Thu, 16 Jan 2025 12:58:25 +0100 +Subject: [PATCH 3/4] pc-bios/s390-ccw: Fix boot problem with virtio-net + devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 332: Fix boot problems when falling back from network to another boot device on s390x [RHEL9] +RH-Jira: RHEL-72716 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Jon Maloy +RH-Commit: [3/4] e7428f24f109aeade9fe0622ecc259dd251cd08e (thuth/qemu-kvm-cs) + +When we are trying to boot from virtio-net devices, the +s390-ccw bios currently leaves the virtio-net device enabled +after using it. That means that the receiving virt queues will +continue to happily write incoming network packets into memory. +This can corrupt data of the following boot process. For example, +if you set up a second guest on a virtual network and create a +lot of broadcast traffic there, e.g. with: + + ping -i 0.02 -s 1400 -b 192.168.1.255 + +and then you try to boot a guest with two boot devices, a network +device first (which should not be bootable) and e.g. a bootable SCSI +CD second, then this guest will fail to load the kernel from the CD +image: + + $ qemu-system-s390x -m 2G -nographic -device virtio-scsi-ccw \ + -netdev tap,id=net0 -device virtio-net-ccw,netdev=net0,bootindex=1 \ + -drive if=none,file=test.iso,format=raw,id=cd1 \ + -device scsi-cd,drive=cd1,bootindex=2 + LOADPARM=[ ] + + Network boot device detected + Network boot starting... + Using MAC address: 52:54:00:12:34:56 + Requesting information via DHCP: done + Using IPv4 address: 192.168.1.76 + Using TFTP server: 192.168.1.1 + Trying pxelinux.cfg files... + TFTP error: ICMP ERROR "port unreachable" + Receiving data: 0 KBytes + Repeating TFTP read request... + TFTP error: ICMP ERROR "port unreachable" + Failed to load OS from network. + Failed to IPL from this network! + LOADPARM=[ ] + + Using virtio-scsi. + + ! virtio-scsi:setup:inquiry: response VS RESP=ff ! + ERROR: No suitable device for IPL. Halting... + +We really have to shut up the virtio-net devices after we're not +using it anymore. The easiest way to do this is to simply reset +the device, so let's do that now. + +Reviewed-by: Jared Rossi +Reviewed-by: Eric Farman +Tested-by: Jared Rossi +Message-ID: <20250116115826.192047-3-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 68c95ed1db070f7545e487e742715f01a545aab0) +--- + pc-bios/s390-ccw/netmain.c | 33 +++++++++++++++++++++++---------- + pc-bios/s390-ccw/virtio-net.c | 5 +++++ + pc-bios/s390-ccw/virtio.h | 1 + + 3 files changed, 29 insertions(+), 10 deletions(-) + +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index e46e470db4..335ea9b63e 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -153,19 +153,10 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len) + return rc; + } + +-static int net_init(filename_ip_t *fn_ip) ++static int net_init_ip(filename_ip_t *fn_ip) + { + int rc; + +- memset(fn_ip, 0, sizeof(filename_ip_t)); +- +- rc = virtio_net_init(mac); +- if (rc < 0) { +- puts("Could not initialize network device"); +- return -101; +- } +- fn_ip->fd = rc; +- + printf(" Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + +@@ -221,11 +212,33 @@ static int net_init(filename_ip_t *fn_ip) + return rc; + } + ++static int net_init(filename_ip_t *fn_ip) ++{ ++ int rc; ++ ++ memset(fn_ip, 0, sizeof(filename_ip_t)); ++ ++ rc = virtio_net_init(mac); ++ if (rc < 0) { ++ puts("Could not initialize network device"); ++ return -101; ++ } ++ fn_ip->fd = rc; ++ ++ rc = net_init_ip(fn_ip); ++ if (rc < 0) { ++ virtio_net_deinit(); ++ } ++ ++ return rc; ++} ++ + static void net_release(filename_ip_t *fn_ip) + { + if (fn_ip->ip_version == 4) { + dhcp_send_release(fn_ip->fd); + } ++ virtio_net_deinit(); + } + + /** +diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c +index 578c89d0c5..301445bf97 100644 +--- a/pc-bios/s390-ccw/virtio-net.c ++++ b/pc-bios/s390-ccw/virtio-net.c +@@ -140,3 +140,8 @@ int recv(int fd, void *buf, int maxlen, int flags) + + return len; + } ++ ++void virtio_net_deinit(void) ++{ ++ virtio_reset(virtio_get_device()); ++} +diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h +index f13fa6f5fe..5c5e808a50 100644 +--- a/pc-bios/s390-ccw/virtio.h ++++ b/pc-bios/s390-ccw/virtio.h +@@ -278,5 +278,6 @@ int virtio_reset(VDev *vdev); + int virtio_setup_ccw(VDev *vdev); + + int virtio_net_init(void *mac_addr); ++void virtio_net_deinit(void); + + #endif /* VIRTIO_H */ +-- +2.48.0 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch b/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch new file mode 100644 index 0000000..6b5269f --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch @@ -0,0 +1,63 @@ +From 499df84ffe62c783d35d5e67cd0d0c35ba6bd44c Mon Sep 17 00:00:00 2001 +From: Marc Hartmayer +Date: Tue, 1 Oct 2024 17:36:18 +0200 +Subject: [PATCH 23/27] pc-bios/s390-ccw: Introduce `EXTRA_LDFLAGS` +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [23/23] e27a9f3997924573bbacc1a7cf48004b2daeaaaa (thuth/qemu-kvm-cs9) + +Some packaging tools want to override `LDFLAGS` when building QEMU, this will +result in a build error as most likely no `-nostdlib` flag is passed. Introduce +`EXTRA_LDFLAGS` so that the packager can override `LDFLAGS` without breaking the +build. + +Signed-off-by: Marc Hartmayer +Message-ID: <20241001153618.17791-4-mhartmay@linux.ibm.com> +Reviewed-by: Thomas Huth +[thuth: Drop the hunk to netbook.mak which is not necessary anymore] +Signed-off-by: Thomas Huth +(cherry picked from commit 694d79ffce996c0993cebccc07c2ab6fc281e7d0) +--- + pc-bios/s390-ccw/Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index 38254e22df..dc69dd484f 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -4,6 +4,7 @@ all: build-all + + include config-host.mak + CFLAGS = -O2 -g -I $(SRC_PATH)/../../include/hw/s390x/ipl ++LDFLAGS ?= + MAKEFLAGS += -rR + + GIT_SUBMODULES = roms/SLOF +@@ -46,7 +47,7 @@ EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables + EXTRA_CFLAGS += -msoft-float + EXTRA_CFLAGS += -std=gnu99 + EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) +-LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text ++EXTRA_LDFLAGS += -Wl,-pie -nostdlib -z noexecstack -z text + + cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null + cc-option = if $(call cc-test, $1); then \ +@@ -111,7 +112,7 @@ libnet.a: $(LIBNETOBJS) + build-all: s390-ccw.img + + s390-ccw.elf: $(OBJECTS) libnet.a libc.a +- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) ++ $(call quiet-command,$(CC) $(EXTRA_LDFLAGS) $(LDFLAGS) -o $@ $^,Linking) + + s390-ccw.img: s390-ccw.elf + $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch b/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch new file mode 100644 index 0000000..1b243e5 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch @@ -0,0 +1,263 @@ +From 5dd12012ec95bbac035a7a8b22216082def604f3 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:37 -0400 +Subject: [PATCH 03/27] pc-bios/s390-ccw: Link the netboot code into the main + s390-ccw.img binary +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/23] d369fc67aa9e10ba97618182e8f9681d151bcc49 (thuth/qemu-kvm-cs9) + +We originally built a separate binary for the netboot code since it +was considered as experimental and we could not be sure that the +necessary SLOF module had been checked out. Time passed, the code +proved its usefulness, and the build system nowadays makes sure that +the SLOF module is checked out if you have a s390x compiler available +for building the s390-ccw bios. So there is no real compelling reason +anymore to keep the netboot code in a separate binary. Linking the +code together with the main s390-ccw.img will make future enhancements +much easier, like supporting more than one boot device. + +Co-authored by: Thomas Huth +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-4-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 8e5739ce4b0b04d7121cb2b29521acde2a8f3a24) +--- + pc-bios/s390-ccw/Makefile | 13 +++++++------ + pc-bios/s390-ccw/bootmap.c | 2 +- + pc-bios/s390-ccw/cio.h | 2 ++ + pc-bios/s390-ccw/iplb.h | 4 ++-- + pc-bios/s390-ccw/main.c | 10 +++++++--- + pc-bios/s390-ccw/netboot.mak | 14 -------------- + pc-bios/s390-ccw/netmain.c | 15 ++------------- + pc-bios/s390-ccw/s390-ccw.h | 3 +++ + pc-bios/s390-ccw/virtio.h | 1 - + 9 files changed, 24 insertions(+), 40 deletions(-) + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index 3f4232636e..cf6859823a 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -32,19 +32,20 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d + + .PHONY : all clean build-all distclean + +-OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ +- virtio.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o ++OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \ ++ virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o + + SLOF_DIR := $(SRC_PATH)/../../roms/SLOF + + LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include ++LIBNET_INC := -I$(SLOF_DIR)/lib/libnet + + EXTRA_CFLAGS += -Wall + EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE + EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables + EXTRA_CFLAGS += -msoft-float + EXTRA_CFLAGS += -std=gnu99 +-EXTRA_CFLAGS += $(LIBC_INC) ++EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) + LDFLAGS += -Wl,-pie -nostdlib -z noexecstack + + cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null +@@ -62,9 +63,9 @@ config-cc.mak: Makefile + + include $(SRC_PATH)/netboot.mak + +-build-all: s390-ccw.img s390-netboot.img ++build-all: s390-ccw.img + +-s390-ccw.elf: $(OBJECTS) libc.a ++s390-ccw.elf: $(OBJECTS) libnet.a libc.a + $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) + + s390-ccw.img: s390-ccw.elf +@@ -72,7 +73,7 @@ s390-ccw.img: s390-ccw.elf + + $(OBJECTS): Makefile + +-ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS)) ++ALL_OBJS = $(sort $(OBJECTS) $(LIBCOBJS) $(LIBNETOBJS)) + -include $(ALL_OBJS:%.o=%.d) + + clean: +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index 3cc79706be..414c3f1b47 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -929,7 +929,7 @@ void zipl_load(void) + } + + if (virtio_get_device_type() == VIRTIO_ID_NET) { +- jump_to_IPL_code(vdev->netboot_start_addr); ++ netmain(); + } + + ipl_scsi(); +diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h +index 8b18153deb..6a5e86ba01 100644 +--- a/pc-bios/s390-ccw/cio.h ++++ b/pc-bios/s390-ccw/cio.h +@@ -361,6 +361,8 @@ typedef struct CcwSearchIdData { + uint8_t record; + } __attribute__((packed)) CcwSearchIdData; + ++extern SubChannelId net_schid; ++ + int enable_mss_facility(void); + void enable_subchannel(SubChannelId schid); + uint16_t cu_type(SubChannelId schid); +diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h +index cb6ac8a880..3758698468 100644 +--- a/pc-bios/s390-ccw/iplb.h ++++ b/pc-bios/s390-ccw/iplb.h +@@ -87,9 +87,9 @@ extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); + struct QemuIplParameters { + uint8_t qipl_flags; + uint8_t reserved1[3]; +- uint64_t netboot_start_addr; ++ uint64_t reserved2; + uint32_t boot_menu_timeout; +- uint8_t reserved2[12]; ++ uint8_t reserved3[12]; + } __attribute__ ((packed)); + typedef struct QemuIplParameters QemuIplParameters; + +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index 203df20965..fc44da3161 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -38,8 +38,13 @@ LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ + */ + void write_subsystem_identification(void) + { +- lowcore->subchannel_id = blk_schid.sch_id; +- lowcore->subchannel_nr = blk_schid.sch_no; ++ if (cutype == CU_TYPE_VIRTIO && virtio_get_device_type() == VIRTIO_ID_NET) { ++ lowcore->subchannel_id = net_schid.sch_id; ++ lowcore->subchannel_nr = net_schid.sch_no; ++ } else { ++ lowcore->subchannel_id = blk_schid.sch_id; ++ lowcore->subchannel_nr = blk_schid.sch_no; ++ } + lowcore->io_int_parm = 0; + } + +@@ -231,7 +236,6 @@ static int virtio_setup(void) + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: + puts("Network boot device detected"); +- vdev->netboot_start_addr = qipl.netboot_start_addr; + return 0; + case VIRTIO_ID_BLOCK: + ret = virtio_blk_setup_device(blk_schid); +diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak +index d2b3d8ee74..0a24257ff4 100644 +--- a/pc-bios/s390-ccw/netboot.mak ++++ b/pc-bios/s390-ccw/netboot.mak +@@ -1,18 +1,4 @@ + +-NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o +- +-LIBNET_INC := -I$(SLOF_DIR)/lib/libnet +- +-NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000 +- +-$(NETOBJS): EXTRA_CFLAGS += $(LIBC_INC) $(LIBNET_INC) +- +-s390-netboot.elf: $(NETOBJS) libnet.a libc.a +- $(call quiet-command,$(CC) $(NETLDFLAGS) -o $@ $^,Linking) +- +-s390-netboot.img: s390-netboot.elf +- $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) +- + # libc files: + + LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index 509119be15..bc6ad8695f 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -41,7 +41,6 @@ + #define DEFAULT_TFTP_RETRIES 20 + + extern char _start[]; +-void write_iplb_location(void) {} + + #define KERNEL_ADDR ((void *)0L) + #define KERNEL_MAX_SIZE ((long)_start) +@@ -50,10 +49,9 @@ void write_iplb_location(void) {} + /* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */ + #define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4) + +-IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE))); + static char cfgbuf[2048]; + +-static SubChannelId net_schid = { .one = 1 }; ++SubChannelId net_schid = { .one = 1 }; + static uint8_t mac[6]; + static uint64_t dest_timer; + +@@ -438,15 +436,6 @@ static int net_try_direct_tftp_load(filename_ip_t *fn_ip) + return rc; + } + +-void write_subsystem_identification(void) +-{ +- SubChannelId *schid = (SubChannelId *) 184; +- uint32_t *zeroes = (uint32_t *) 188; +- +- *schid = net_schid; +- *zeroes = 0; +-} +- + static bool find_net_dev(Schib *schib, int dev_no) + { + int i, r; +@@ -509,7 +498,7 @@ static void virtio_setup(void) + IPL_assert(found, "No virtio net device found"); + } + +-void main(void) ++void netmain(void) + { + filename_ip_t fn_ip; + int rc, fnlen; +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index 6f6d95d170..6abb34e563 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -55,6 +55,9 @@ void write_iplb_location(void); + unsigned int get_loadparm_index(void); + void main(void); + ++/* netmain.c */ ++void netmain(void); ++ + /* sclp.c */ + void sclp_print(const char *string); + void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask); +diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h +index 85bd9d1695..6f9a558ff5 100644 +--- a/pc-bios/s390-ccw/virtio.h ++++ b/pc-bios/s390-ccw/virtio.h +@@ -253,7 +253,6 @@ struct VDev { + uint8_t scsi_dev_heads; + bool scsi_device_selected; + ScsiDevice selected_scsi_device; +- uint64_t netboot_start_addr; + uint32_t max_transfer; + uint32_t guest_features[2]; + }; +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch b/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch new file mode 100644 index 0000000..9e35834 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch @@ -0,0 +1,141 @@ +From 053fe7407d61ea7f885ae3a75b8dff18712e97fc Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Fri, 21 Jun 2024 09:40:11 +0200 +Subject: [PATCH 06/27] pc-bios/s390-ccw: Merge netboot.mak into the main + Makefile +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/23] a0f3671677000e9bf00557df773fd72d9f9768a7 (thuth/qemu-kvm-cs9) + +Now that the netboot code has been merged into the main s390-ccw.img, +it also does not make sense to keep the build rules in a separate +file. Thus let's merge netboot.mak into the main Makefile. + +Message-Id: <20240621082422.136217-7-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit f1fdadda36f73c9a4a96f92deb3062528cd12acc) +--- + pc-bios/s390-ccw/Makefile | 47 +++++++++++++++++++++++++++++++++++- + pc-bios/s390-ccw/netboot.mak | 45 ---------------------------------- + 2 files changed, 46 insertions(+), 46 deletions(-) + delete mode 100644 pc-bios/s390-ccw/netboot.mak + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index cf6859823a..27cbb354af 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -61,7 +61,52 @@ config-cc.mak: Makefile + $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak + -include config-cc.mak + +-include $(SRC_PATH)/netboot.mak ++# libc files: ++ ++LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ ++ -MMD -MP -MT $@ -MF $(@:%.o=%.d) ++ ++CTYPE_OBJS = isdigit.o isxdigit.o toupper.o ++%.o : $(SLOF_DIR)/lib/libc/ctype/%.c ++ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) ++ ++STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \ ++ strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \ ++ memset.o memcpy.o memmove.o memcmp.o ++%.o : $(SLOF_DIR)/lib/libc/string/%.c ++ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) ++ ++STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o ++%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c ++ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) ++ ++STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ ++ printf.o putc.o puts.o putchar.o stdchnls.o fileno.o ++%.o : $(SLOF_DIR)/lib/libc/stdio/%.c ++ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) ++ ++sbrk.o: $(SLOF_DIR)/slof/sbrk.c ++ $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) ++ ++LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o ++ ++libc.a: $(LIBCOBJS) ++ $(call quiet-command,$(AR) -rc $@ $^,Creating static library) ++ ++# libnet files: ++ ++LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \ ++ dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o ++LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ ++ -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d) ++ ++%.o : $(SLOF_DIR)/lib/libnet/%.c ++ $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling) ++ ++libnet.a: $(LIBNETOBJS) ++ $(call quiet-command,$(AR) -rc $@ $^,Creating static library) ++ ++# Main targets: + + build-all: s390-ccw.img + +diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak +deleted file mode 100644 +index 0a24257ff4..0000000000 +--- a/pc-bios/s390-ccw/netboot.mak ++++ /dev/null +@@ -1,45 +0,0 @@ +- +-# libc files: +- +-LIBC_CFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ +- -MMD -MP -MT $@ -MF $(@:%.o=%.d) +- +-CTYPE_OBJS = isdigit.o isxdigit.o toupper.o +-%.o : $(SLOF_DIR)/lib/libc/ctype/%.c +- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) +- +-STRING_OBJS = strcat.o strchr.o strrchr.o strcpy.o strlen.o strncpy.o \ +- strcmp.o strncmp.o strcasecmp.o strncasecmp.o strstr.o \ +- memset.o memcpy.o memmove.o memcmp.o +-%.o : $(SLOF_DIR)/lib/libc/string/%.c +- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) +- +-STDLIB_OBJS = atoi.o atol.o strtoul.o strtol.o rand.o malloc.o free.o +-%.o : $(SLOF_DIR)/lib/libc/stdlib/%.c +- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) +- +-STDIO_OBJS = sprintf.o snprintf.o vfprintf.o vsnprintf.o vsprintf.o fprintf.o \ +- printf.o putc.o puts.o putchar.o stdchnls.o fileno.o +-%.o : $(SLOF_DIR)/lib/libc/stdio/%.c +- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) +- +-sbrk.o: $(SLOF_DIR)/slof/sbrk.c +- $(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,Compiling) +- +-LIBCOBJS := $(STRING_OBJS) $(CTYPE_OBJS) $(STDLIB_OBJS) $(STDIO_OBJS) sbrk.o +- +-libc.a: $(LIBCOBJS) +- $(call quiet-command,$(AR) -rc $@ $^,Creating static library) +- +-# libnet files: +- +-LIBNETOBJS := args.o dhcp.o dns.o icmpv6.o ipv6.o tcp.o udp.o bootp.o \ +- dhcpv6.o ethernet.o ipv4.o ndp.o tftp.o pxelinux.o +-LIBNETCFLAGS = $(EXTRA_CFLAGS) $(CFLAGS) $(LIBC_INC) $(LIBNET_INC) \ +- -DDHCPARCH=0x1F -MMD -MP -MT $@ -MF $(@:%.o=%.d) +- +-%.o : $(SLOF_DIR)/lib/libnet/%.c +- $(call quiet-command,$(CC) $(LIBNETCFLAGS) -c -o $@ $<,Compiling) +- +-libnet.a: $(LIBNETOBJS) +- $(call quiet-command,$(AR) -rc $@ $^,Creating static library) +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch b/SOURCES/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch new file mode 100644 index 0000000..8a5c675 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch @@ -0,0 +1,45 @@ +From 7e73d3ad9a7e3f047f8ef79131065e4386e1bc00 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 11 Nov 2024 14:11:20 +0100 +Subject: [PATCH 09/10] pc-bios/s390-ccw: Re-initialize receive queue index + before each boot attempt +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/8] 3337c7737fa2eb33f1a27230ae1d6e0f2580a539 (thuth/qemu-kvm-cs9) + +Now that we can boot from multiple boot devices, we have to make sure +to reinitialize static variables like rx_last_idx to avoid that they +contain garbage data during the second boot attempt (which can lead to +crashes when the code tries to access the wrong ring data). + +Message-ID: <20241111131120.317796-1-thuth@redhat.com> +Reviewed-by: Jared Rossi +Signed-off-by: Thomas Huth +(cherry picked from commit 6ba1f714c00f8839a8df9f643e0058f00da3fd25) +--- + pc-bios/s390-ccw/virtio-net.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c +index f9854a22c3..578c89d0c5 100644 +--- a/pc-bios/s390-ccw/virtio-net.c ++++ b/pc-bios/s390-ccw/virtio-net.c +@@ -51,6 +51,8 @@ int virtio_net_init(void *mac_addr) + void *buf; + int i; + ++ rx_last_idx = 0; ++ + vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT; + virtio_setup_ccw(vdev); + +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch new file mode 100644 index 0000000..5e0fd94 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch @@ -0,0 +1,177 @@ +From 032b512a919662ce65b173416815e29e8f5fb904 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:44 -0400 +Subject: [PATCH 11/27] pc-bios/s390-ccw: Remove panics from DASD IPL path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [11/23] 941e1e76db8d35a6ad6ca2e2a401e2ac122efd09 (thuth/qemu-kvm-cs9) + +Remove panic-on-error from DASD IPL specific functions so that error recovery +may be possible in the future. + +Functions that would previously panic now provide a return code. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-11-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 1d5c7f078e938e6844f404429dd70bc52b39dac6) +--- + pc-bios/s390-ccw/dasd-ipl.c | 66 ++++++++++++++++++++----------------- + pc-bios/s390-ccw/dasd-ipl.h | 2 +- + 2 files changed, 37 insertions(+), 31 deletions(-) + +diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c +index ae751adec1..babece95ea 100644 +--- a/pc-bios/s390-ccw/dasd-ipl.c ++++ b/pc-bios/s390-ccw/dasd-ipl.c +@@ -111,38 +111,29 @@ static void make_readipl(void) + ccwIplRead->count = 0x18; /* Read 0x18 bytes of data */ + } + +-static void run_readipl(SubChannelId schid, uint16_t cutype) ++static int run_readipl(SubChannelId schid, uint16_t cutype) + { +- if (do_cio(schid, cutype, 0x00, CCW_FMT0)) { +- panic("dasd-ipl: Failed to run Read IPL channel program\n"); +- } ++ return do_cio(schid, cutype, 0x00, CCW_FMT0); + } + + /* + * The architecture states that IPL1 data should consist of a psw followed by + * format-0 READ and TIC CCWs. Let's sanity check. + */ +-static void check_ipl1(void) ++static bool check_ipl1(void) + { + Ccw0 *ccwread = (Ccw0 *)0x08; + Ccw0 *ccwtic = (Ccw0 *)0x10; + +- if (ccwread->cmd_code != CCW_CMD_DASD_READ || +- ccwtic->cmd_code != CCW_CMD_TIC) { +- panic("dasd-ipl: IPL1 data invalid. Is this disk really bootable?\n"); +- } ++ return (ccwread->cmd_code == CCW_CMD_DASD_READ && ++ ccwtic->cmd_code == CCW_CMD_TIC); + } + +-static void check_ipl2(uint32_t ipl2_addr) ++static bool check_ipl2(uint32_t ipl2_addr) + { + Ccw0 *ccw = u32toptr(ipl2_addr); + +- if (ipl2_addr == 0x00) { +- panic("IPL2 address invalid. Is this disk really bootable?\n"); +- } +- if (ccw->cmd_code == 0x00) { +- panic("IPL2 ccw data invalid. Is this disk really bootable?\n"); +- } ++ return (ipl2_addr != 0x00 && ccw->cmd_code != 0x00); + } + + static uint32_t read_ipl2_addr(void) +@@ -188,52 +179,67 @@ static void ipl1_fixup(void) + ccwSearchTic->cda = ptr2u32(ccwSearchID); + } + +-static void run_ipl1(SubChannelId schid, uint16_t cutype) ++static int run_ipl1(SubChannelId schid, uint16_t cutype) + { + uint32_t startAddr = 0x08; + +- if (do_cio(schid, cutype, startAddr, CCW_FMT0)) { +- panic("dasd-ipl: Failed to run IPL1 channel program\n"); +- } ++ return do_cio(schid, cutype, startAddr, CCW_FMT0); + } + +-static void run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr) ++static int run_ipl2(SubChannelId schid, uint16_t cutype, uint32_t addr) + { +- if (run_dynamic_ccw_program(schid, cutype, addr)) { +- panic("dasd-ipl: Failed to run IPL2 channel program\n"); +- } ++ return run_dynamic_ccw_program(schid, cutype, addr); + } + + /* + * Limitations in vfio-ccw support complicate the IPL process. Details can + * be found in docs/devel/s390-dasd-ipl.rst + */ +-void dasd_ipl(SubChannelId schid, uint16_t cutype) ++int dasd_ipl(SubChannelId schid, uint16_t cutype) + { + PSWLegacy *pswl = (PSWLegacy *) 0x00; + uint32_t ipl2_addr; + + /* Construct Read IPL CCW and run it to read IPL1 from boot disk */ + make_readipl(); +- run_readipl(schid, cutype); ++ if (run_readipl(schid, cutype)) { ++ puts("Failed to run Read IPL channel program"); ++ return -EIO; ++ } ++ + ipl2_addr = read_ipl2_addr(); +- check_ipl1(); ++ ++ if (!check_ipl1()) { ++ puts("IPL1 invalid for DASD-IPL"); ++ return -EINVAL; ++ } + + /* + * Fixup IPL1 channel program to account for vfio-ccw limitations, then run + * it to read IPL2 channel program from boot disk. + */ + ipl1_fixup(); +- run_ipl1(schid, cutype); +- check_ipl2(ipl2_addr); ++ if (run_ipl1(schid, cutype)) { ++ puts("Failed to run IPL1 channel program"); ++ return -EIO; ++ } ++ ++ if (!check_ipl2(ipl2_addr)) { ++ puts("IPL2 invalid for DASD-IPL"); ++ return -EINVAL; ++ } + + /* + * Run IPL2 channel program to read operating system code from boot disk + */ +- run_ipl2(schid, cutype, ipl2_addr); ++ if (run_ipl2(schid, cutype, ipl2_addr)) { ++ puts("Failed to run IPL2 channel program"); ++ return -EIO; ++ } + + /* Transfer control to the guest operating system */ + pswl->mask |= PSW_MASK_EAMODE; /* Force z-mode */ + pswl->addr |= PSW_MASK_BAMODE; /* ... */ + jump_to_low_kernel(); ++ return -1; + } +diff --git a/pc-bios/s390-ccw/dasd-ipl.h b/pc-bios/s390-ccw/dasd-ipl.h +index c394828906..eb1898c84a 100644 +--- a/pc-bios/s390-ccw/dasd-ipl.h ++++ b/pc-bios/s390-ccw/dasd-ipl.h +@@ -11,6 +11,6 @@ + #ifndef DASD_IPL_H + #define DASD_IPL_H + +-void dasd_ipl(SubChannelId schid, uint16_t cutype); ++int dasd_ipl(SubChannelId schid, uint16_t cutype); + + #endif /* DASD_IPL_H */ +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch new file mode 100644 index 0000000..fa854a1 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch @@ -0,0 +1,475 @@ +From 237d714205394102a4cd60eeeddc12b98bfbfa3f Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:42 -0400 +Subject: [PATCH 09/27] pc-bios/s390-ccw: Remove panics from ECKD IPL path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [9/23] 1e6ecba95979a5bc12bd74c1b0bc631ccfbd57ec (thuth/qemu-kvm-cs9) + +Remove panic-on-error from ECKD block device IPL specific functions so that +error recovery may be possible in the future. + +Functions that would previously panic now provide a return code. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-9-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 806315279d5c629e1cc3a945bcfba3fe5482d84b) +--- + pc-bios/s390-ccw/bootmap.c | 187 +++++++++++++++++++++++++------------ + pc-bios/s390-ccw/bootmap.h | 1 + + 2 files changed, 130 insertions(+), 58 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index af73254acb..b9596e28c7 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -145,14 +145,17 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, + bool more_data; + + memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs)); +- read_block(blk, bprs, "BPRS read failed"); ++ if (virtio_read(blk, bprs)) { ++ puts("BPRS read failed"); ++ return ERROR_BLOCK_NR; ++ } + + do { + more_data = false; + for (j = 0;; j++) { + block_nr = gen_eckd_block_num(&bprs[j].xeckd, ldipl); + if (is_null_block_number(block_nr)) { /* end of chunk */ +- break; ++ return NULL_BLOCK_NR; + } + + /* we need the updated blockno for the next indirect entry +@@ -163,15 +166,20 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, + } + + /* List directed pointer does not store block size */ +- IPL_assert(ldipl || block_size_ok(bprs[j].xeckd.bptr.size), +- "bad chunk block size"); ++ if (!ldipl && !block_size_ok(bprs[j].xeckd.bptr.size)) { ++ puts("Bad chunk block size"); ++ return ERROR_BLOCK_NR; ++ } + + if (!eckd_valid_address(&bprs[j].xeckd, ldipl)) { + /* + * If an invalid address is found during LD-IPL then break and +- * retry as CCW ++ * retry as CCW-IPL, otherwise abort on error + */ +- IPL_assert(ldipl, "bad chunk ECKD addr"); ++ if (!ldipl) { ++ puts("Bad chunk ECKD address"); ++ return ERROR_BLOCK_NR; ++ } + break; + } + +@@ -189,7 +197,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, + * I.e. the next ptr must point to the unused memory area + */ + memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs)); +- read_block(block_nr, bprs, "BPRS continuation read failed"); ++ if (virtio_read(block_nr, bprs)) { ++ puts("BPRS continuation read failed"); ++ return ERROR_BLOCK_NR; ++ } + more_data = true; + break; + } +@@ -198,7 +209,10 @@ static block_number_t load_eckd_segments(block_number_t blk, bool ldipl, + * to memory (address). + */ + rc = virtio_read_many(block_nr, (void *)(*address), count + 1); +- IPL_assert(rc == 0, "code chunk read failed"); ++ if (rc != 0) { ++ puts("Code chunk read failed"); ++ return ERROR_BLOCK_NR; ++ } + + *address += (count + 1) * virtio_get_block_size(); + } +@@ -232,7 +246,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + + /* Get Stage1b data */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(s1b_block_nr, s1b, "Cannot read stage1b boot loader"); ++ if (virtio_read(s1b_block_nr, s1b)) { ++ puts("Cannot read stage1b boot loader"); ++ return -EIO; ++ } + + memset(_s2, FREE_SPACE_FILLER, sizeof(_s2)); + +@@ -244,7 +261,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + break; + } + +- read_block(cur_block_nr, s2_cur_blk, "Cannot read stage2 boot loader"); ++ if (virtio_read(cur_block_nr, s2_cur_blk)) { ++ puts("Cannot read stage2 boot loader"); ++ return -EIO; ++ } + + if (find_zipl_boot_menu_banner(&banner_offset)) { + /* +@@ -252,8 +272,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + * possibility of menu data spanning multiple blocks. + */ + if (prev_block_nr) { +- read_block(prev_block_nr, s2_prev_blk, +- "Cannot read stage2 boot loader"); ++ if (virtio_read(prev_block_nr, s2_prev_blk)) { ++ puts("Cannot read stage2 boot loader"); ++ return -EIO; ++ } + } + + if (i + 1 < STAGE2_BLK_CNT_MAX) { +@@ -261,8 +283,10 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + } + + if (next_block_nr && !is_null_block_number(next_block_nr)) { +- read_block(next_block_nr, s2_next_blk, +- "Cannot read stage2 boot loader"); ++ if (virtio_read(next_block_nr, s2_next_blk)) { ++ puts("Cannot read stage2 boot loader"); ++ return -EIO; ++ } + } + + return menu_get_zipl_boot_index(s2_cur_blk + banner_offset); +@@ -275,7 +299,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + return 0; + } + +-static void run_eckd_boot_script(block_number_t bmt_block_nr, ++static int run_eckd_boot_script(block_number_t bmt_block_nr, + block_number_t s1b_block_nr) + { + int i; +@@ -292,17 +316,28 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr, + } + + debug_print_int("loadparm", loadparm); +- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than" +- " maximum number of boot entries allowed"); ++ if (loadparm >= MAX_BOOT_ENTRIES) { ++ puts("loadparm value greater than max number of boot entries allowed"); ++ return -EINVAL; ++ } + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(bmt_block_nr, sec, "Cannot read Boot Map Table"); ++ if (virtio_read(bmt_block_nr, sec)) { ++ puts("Cannot read Boot Map Table"); ++ return -EIO; ++ } + + block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl); +- IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry"); ++ if (block_nr == NULL_BLOCK_NR) { ++ puts("Cannot find Boot Map Table Entry"); ++ return -EIO; ++ } + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(block_nr, sec, "Cannot read Boot Map Script"); ++ if (virtio_read(block_nr, sec)) { ++ puts("Cannot read Boot Map Script"); ++ return -EIO; ++ } + + for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD || + bms->entry[i].type == BOOT_SCRIPT_SIGNATURE; i++) { +@@ -317,21 +352,27 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr, + + do { + block_nr = load_eckd_segments(block_nr, ldipl, &address); +- } while (block_nr != -1); ++ if (block_nr == ERROR_BLOCK_NR) { ++ return ldipl ? 0 : -EIO; ++ } ++ } while (block_nr != NULL_BLOCK_NR); + } + + if (ldipl && bms->entry[i].type != BOOT_SCRIPT_EXEC) { + /* Abort LD-IPL and retry as CCW-IPL */ +- return; ++ return 0; + } + +- IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC, +- "Unknown script entry type"); ++ if (bms->entry[i].type != BOOT_SCRIPT_EXEC) { ++ puts("Unknown script entry type"); ++ return -EINVAL; ++ } + write_reset_psw(bms->entry[i].address.load_address); /* no return */ + jump_to_IPL_code(0); /* no return */ ++ return -1; + } + +-static void ipl_eckd_cdl(void) ++static int ipl_eckd_cdl(void) + { + XEckdMbr *mbr; + EckdCdlIpl2 *ipl2 = (void *)sec; +@@ -342,20 +383,23 @@ static void ipl_eckd_cdl(void) + puts("CDL"); + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(1, ipl2, "Cannot read IPL2 record at block 1"); ++ if (virtio_read(1, ipl2)) { ++ puts("Cannot read IPL2 record at block 1"); ++ return -EIO; ++ } + + mbr = &ipl2->mbr; + if (!magic_match(mbr, ZIPL_MAGIC)) { + puts("No zIPL section in IPL2 record."); +- return; ++ return 0; + } + if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { + puts("Bad block size in zIPL section of IPL2 record."); +- return; ++ return 0; + } + if (mbr->dev_type != DEV_TYPE_ECKD) { + puts("Non-ECKD device type in zIPL section of IPL2 record."); +- return; ++ return 0; + } + + /* save pointer to Boot Map Table */ +@@ -365,19 +409,21 @@ static void ipl_eckd_cdl(void) + s1b_block_nr = eckd_block_num(&ipl2->stage1.seek[0].chs); + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(2, vlbl, "Cannot read Volume Label at block 2"); ++ if (virtio_read(2, vlbl)) { ++ puts("Cannot read Volume Label at block 2"); ++ return -EIO; ++ } + if (!magic_match(vlbl->key, VOL1_MAGIC)) { + puts("Invalid magic of volume label block."); +- return; ++ return 0; + } + if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { + puts("Invalid magic of volser block."); +- return; ++ return 0; + } + print_volser(vlbl->f.volser); + +- run_eckd_boot_script(bmt_block_nr, s1b_block_nr); +- /* no return */ ++ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr); + } + + static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) +@@ -403,7 +449,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) + print_volser(vlbl->volser); + } + +-static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) ++static int ipl_eckd_ldl(ECKD_IPL_mode_t mode) + { + block_number_t bmt_block_nr, s1b_block_nr; + EckdLdlIpl1 *ipl1 = (void *)sec; +@@ -415,10 +461,13 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) + /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */ + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(0, sec, "Cannot read block 0 to grab boot info."); ++ if (virtio_read(0, sec)) { ++ puts("Cannot read block 0 to grab boot info."); ++ return -EIO; ++ } + if (mode == ECKD_LDL_UNLABELED) { + if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { +- return; /* not applicable layout */ ++ return 0; /* not applicable layout */ + } + puts("unlabeled LDL."); + } +@@ -430,8 +479,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) + /* save pointer to Stage1b Data */ + s1b_block_nr = eckd_block_num(&ipl1->stage1.seek[0].chs); + +- run_eckd_boot_script(bmt_block_nr, s1b_block_nr); +- /* no return */ ++ return run_eckd_boot_script(bmt_block_nr, s1b_block_nr); + } + + static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr) +@@ -441,7 +489,10 @@ static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr) + BootRecord *br; + + blockno = gen_eckd_block_num(ptr, 0); +- read_block(blockno, tmp_sec, "Cannot read boot record"); ++ if (virtio_read(blockno, tmp_sec)) { ++ puts("Cannot read boot record"); ++ return ERROR_BLOCK_NR; ++ } + br = (BootRecord *)tmp_sec; + if (!magic_match(br->magic, ZIPL_MAGIC)) { + /* If the boot record is invalid, return and try CCW-IPL instead */ +@@ -470,7 +521,7 @@ static void print_eckd_msg(void) + printf("%s", msg); + } + +-static void ipl_eckd(void) ++static int ipl_eckd(void) + { + IplVolumeLabel *vlbl = (void *)sec; + LDL_VTOC *vtoc = (void *)sec; +@@ -480,7 +531,10 @@ static void ipl_eckd(void) + + /* Block 2 can contain either the CDL VOL1 label or the LDL VTOC */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(2, vlbl, "Cannot read block 2"); ++ if (virtio_read(2, vlbl)) { ++ puts("Cannot read block 2"); ++ return -EIO; ++ } + + /* + * First check for a list-directed-format pointer which would +@@ -488,36 +542,53 @@ static void ipl_eckd(void) + */ + if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) { + ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br); +- if (ldipl_bmt) { ++ switch (ldipl_bmt) { ++ case ERROR_BLOCK_NR: ++ return -EIO; ++ case NULL_BLOCK_NR: ++ break; /* Invalid BMT but the device may still boot with CCW-IPL */ ++ default: + puts("List-Directed"); +- /* LD-IPL does not use the S1B bock, just make it NULL */ +- run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR); +- /* Only return in error, retry as CCW-IPL */ ++ /* ++ * LD-IPL does not use the S1B bock, just make it NULL_BLOCK_NR. ++ * In some failure cases retry IPL before aborting. ++ */ ++ if (run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR)) { ++ return -EIO; ++ } ++ /* Non-fatal error, retry as CCW-IPL */ + printf("Retrying IPL "); + print_eckd_msg(); + } + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(2, vtoc, "Cannot read block 2"); ++ if (virtio_read(2, vtoc)) { ++ puts("Cannot read block 2"); ++ return -EIO; ++ } + } + + /* Not list-directed */ + if (magic_match(vtoc->magic, VOL1_MAGIC)) { +- ipl_eckd_cdl(); /* may return in error */ ++ if (ipl_eckd_cdl()) { ++ return -1; ++ } + } + + if (magic_match(vtoc->magic, CMS1_MAGIC)) { +- ipl_eckd_ldl(ECKD_CMS); /* no return */ ++ return ipl_eckd_ldl(ECKD_CMS); + } + if (magic_match(vtoc->magic, LNX1_MAGIC)) { +- ipl_eckd_ldl(ECKD_LDL); /* no return */ ++ return ipl_eckd_ldl(ECKD_LDL); + } + +- ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */ ++ if (ipl_eckd_ldl(ECKD_LDL_UNLABELED)) { ++ return -1; ++ } + /* + * Ok, it is not a LDL by any means. + * It still might be a CDL with zero record keys for IPL1 and IPL2 + */ +- ipl_eckd_cdl(); ++ return ipl_eckd_cdl(); + } + + /*********************************************************************** +@@ -910,7 +981,7 @@ static bool has_iso_signature(void) + * Bus specific IPL sequences + */ + +-static void zipl_load_vblk(void) ++static int zipl_load_vblk(void) + { + int blksize = virtio_get_block_size(); + +@@ -919,7 +990,7 @@ static void zipl_load_vblk(void) + virtio_assume_iso9660(); + } + if (ipl_iso_el_torito()) { +- return; ++ return 0; + } + } + +@@ -927,21 +998,21 @@ static void zipl_load_vblk(void) + puts("Using guessed DASD geometry."); + virtio_assume_eckd(); + } +- ipl_eckd(); ++ return ipl_eckd(); + } + +-static void zipl_load_vscsi(void) ++static int zipl_load_vscsi(void) + { + if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) { + /* Is it an ISO image in non-CD drive? */ + if (ipl_iso_el_torito()) { +- return; ++ return 0; + } + } + + puts("Using guessed DASD geometry."); + virtio_assume_eckd(); +- ipl_eckd(); ++ return ipl_eckd(); + } + + /*********************************************************************** +diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h +index 3cb573b86b..95943441d3 100644 +--- a/pc-bios/s390-ccw/bootmap.h ++++ b/pc-bios/s390-ccw/bootmap.h +@@ -16,6 +16,7 @@ + + typedef uint64_t block_number_t; + #define NULL_BLOCK_NR 0xffffffffffffffffULL ++#define ERROR_BLOCK_NR 0xfffffffffffffffeULL + + #define FREE_SPACE_FILLER '\xAA' + +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch new file mode 100644 index 0000000..0304180 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch @@ -0,0 +1,269 @@ +From b850578315ad498d581d8f09c9dfcd0d1dea1a5e Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:41 -0400 +Subject: [PATCH 08/27] pc-bios/s390-ccw: Remove panics from ISO IPL path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/23] 92ab09f2df4bcdc721aca11c4a75439ebd72212c (thuth/qemu-kvm-cs9) + +Remove panic-on-error from IPL ISO El Torito specific functions so that error +recovery may be possible in the future. + +Functions that would previously panic now provide a return code. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-8-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit bef2b8dd1a36fc79cabcda48e667f2cba476924c) +--- + pc-bios/s390-ccw/bootmap.c | 87 ++++++++++++++++++++++++------------- + pc-bios/s390-ccw/bootmap.h | 15 +++---- + pc-bios/s390-ccw/s390-ccw.h | 1 + + 3 files changed, 65 insertions(+), 38 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index 414c3f1b47..af73254acb 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -678,8 +678,10 @@ static bool is_iso_bc_entry_compatible(IsoBcSection *s) + if (s->unused || !s->sector_count) { + return false; + } +- read_iso_sector(bswap32(s->load_rba), magic_sec, +- "Failed to read image sector 0"); ++ if (virtio_read(bswap32(s->load_rba), magic_sec)) { ++ puts("Failed to read image sector 0"); ++ return false; ++ } + + /* Checking bytes 8 - 32 for S390 Linux magic */ + return !memcmp(magic_sec + 8, linux_s390_magic, 24); +@@ -692,28 +694,35 @@ static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH]; + /* Remained directory space in bytes */ + static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH]; + +-static inline uint32_t iso_get_file_size(uint32_t load_rba) ++static inline long iso_get_file_size(uint32_t load_rba) + { + IsoVolDesc *vd = (IsoVolDesc *)sec; + IsoDirHdr *cur_record = &vd->vd.primary.rootdir; + uint8_t *temp = sec + ISO_SECTOR_SIZE; + int level = 0; + +- read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec, +- "Failed to read ISO primary descriptor"); ++ if (virtio_read(ISO_PRIMARY_VD_SECTOR, sec)) { ++ puts("Failed to read ISO primary descriptor"); ++ return -EIO; ++ } ++ + sec_loc[0] = iso_733_to_u32(cur_record->ext_loc); + dir_rem[0] = 0; + sec_offset[0] = 0; + + while (level >= 0) { +- IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE, +- "Directory tree structure violation"); ++ if (sec_offset[level] > ISO_SECTOR_SIZE) { ++ puts("Directory tree structure violation"); ++ return -EIO; ++ } + + cur_record = (IsoDirHdr *)(temp + sec_offset[level]); + + if (sec_offset[level] == 0) { +- read_iso_sector(sec_loc[level], temp, +- "Failed to read ISO directory"); ++ if (virtio_read(sec_loc[level], temp)) { ++ puts("Failed to read ISO directory"); ++ return -EIO; ++ } + if (dir_rem[level] == 0) { + /* Skip self and parent records */ + dir_rem[level] = iso_733_to_u32(cur_record->data_len) - +@@ -758,8 +767,10 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba) + if (dir_rem[level] == 0) { + /* Nothing remaining */ + level--; +- read_iso_sector(sec_loc[level], temp, +- "Failed to read ISO directory"); ++ if (virtio_read(sec_loc[level], temp)) { ++ puts("Failed to read ISO directory"); ++ return -EIO; ++ } + } + } + +@@ -774,19 +785,24 @@ static void load_iso_bc_entry(IsoBcSection *load) + * is padded and ISO_SECTOR_SIZE bytes aligned + */ + uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT; +- uint32_t real_size = iso_get_file_size(bswap32(s.load_rba)); ++ long real_size = iso_get_file_size(bswap32(s.load_rba)); + +- if (real_size) { ++ if (real_size > 0) { + /* Round up blocks to load */ + blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE; + puts("ISO boot image size verified"); + } else { + puts("ISO boot image size could not be verified"); ++ if (real_size < 0) { ++ return; ++ } + } + +- read_iso_boot_image(bswap32(s.load_rba), ++ if (read_iso_boot_image(bswap32(s.load_rba), + (void *)((uint64_t)bswap16(s.load_segment)), +- blks_to_load); ++ blks_to_load)) { ++ return; ++ } + + jump_to_low_kernel(); + } +@@ -809,17 +825,18 @@ static uint32_t find_iso_bc(void) + return bswap32(et->bc_offset); + } + } +- read_iso_sector(block_num++, sec, +- "Failed to read ISO volume descriptor"); ++ if (virtio_read(block_num++, sec)) { ++ puts("Failed to read ISO volume descriptor"); ++ return 0; ++ } + } + + return 0; + } + +-static IsoBcSection *find_iso_bc_entry(void) ++static IsoBcSection *find_iso_bc_entry(uint32_t offset) + { + IsoBcEntry *e = (IsoBcEntry *)sec; +- uint32_t offset = find_iso_bc(); + int i; + unsigned int loadparm = get_loadparm_index(); + +@@ -827,11 +844,13 @@ static IsoBcSection *find_iso_bc_entry(void) + return NULL; + } + +- read_iso_sector(offset, sec, "Failed to read El Torito boot catalog"); ++ if (virtio_read(offset, sec)) { ++ puts("Failed to read El Torito boot catalog"); ++ return NULL; ++ } + + if (!is_iso_bc_valid(e)) { + /* The validation entry is mandatory */ +- panic("No valid boot catalog found!\n"); + return NULL; + } + +@@ -851,19 +870,25 @@ static IsoBcSection *find_iso_bc_entry(void) + } + } + +- panic("No suitable boot entry found on ISO-9660 media!\n"); +- + return NULL; + } + +-static void ipl_iso_el_torito(void) ++static int ipl_iso_el_torito(void) + { +- IsoBcSection *s = find_iso_bc_entry(); ++ uint32_t offset = find_iso_bc(); ++ if (!offset) { ++ return 0; ++ } ++ ++ IsoBcSection *s = find_iso_bc_entry(offset); + + if (s) { +- load_iso_bc_entry(s); +- /* no return */ ++ load_iso_bc_entry(s); /* only return in error */ ++ return -1; + } ++ ++ puts("No suitable boot entry found on ISO-9660 media!"); ++ return -EIO; + } + + /** +@@ -893,7 +918,9 @@ static void zipl_load_vblk(void) + if (blksize != VIRTIO_ISO_BLOCK_SIZE) { + virtio_assume_iso9660(); + } +- ipl_iso_el_torito(); ++ if (ipl_iso_el_torito()) { ++ return; ++ } + } + + if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) { +@@ -907,7 +934,9 @@ static void zipl_load_vscsi(void) + { + if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) { + /* Is it an ISO image in non-CD drive? */ +- ipl_iso_el_torito(); ++ if (ipl_iso_el_torito()) { ++ return; ++ } + } + + puts("Using guessed DASD geometry."); +diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h +index 4a7d8a91f1..3cb573b86b 100644 +--- a/pc-bios/s390-ccw/bootmap.h ++++ b/pc-bios/s390-ccw/bootmap.h +@@ -385,17 +385,14 @@ static inline uint32_t iso_733_to_u32(uint64_t x) + + #define ISO_PRIMARY_VD_SECTOR 16 + +-static inline void read_iso_sector(uint32_t block_offset, void *buf, +- const char *errmsg) +-{ +- IPL_assert(virtio_read_many(block_offset, buf, 1) == 0, errmsg); +-} +- +-static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr, ++static inline int read_iso_boot_image(uint32_t block_offset, void *load_addr, + uint32_t blks_to_load) + { +- IPL_assert(virtio_read_many(block_offset, load_addr, blks_to_load) == 0, +- "Failed to read boot image!"); ++ if (virtio_read_many(block_offset, load_addr, blks_to_load)) { ++ puts("Failed to read boot image!"); ++ return -1; ++ } ++ return 0; + } + + #define ISO9660_MAX_DIR_DEPTH 8 +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index 6abb34e563..3e844abd71 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -30,6 +30,7 @@ typedef unsigned long long u64; + #define EIO 1 + #define EBUSY 2 + #define ENODEV 3 ++#define EINVAL 4 + + #ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch new file mode 100644 index 0000000..6507ce1 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch @@ -0,0 +1,130 @@ +From e572d55c45c5c84e386034b0f853476326a08197 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:45 -0400 +Subject: [PATCH 12/27] pc-bios/s390-ccw: Remove panics from Netboot IPL path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [12/23] dd193b7e37849dc338d66ac40786e22ff050ae20 (thuth/qemu-kvm-cs9) + +Remove panic-on-error from Netboot specific functions so that error recovery +may be possible in the future. + +Functions that would previously panic now provide a return code. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-12-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit f1a2a6e41ef76e02ddc5ede3dd042ef96b4fb8d2) +--- + pc-bios/s390-ccw/bootmap.c | 1 + + pc-bios/s390-ccw/netmain.c | 17 +++++++++++------ + pc-bios/s390-ccw/s390-ccw.h | 2 +- + pc-bios/s390-ccw/virtio-net.c | 7 +++++-- + 4 files changed, 18 insertions(+), 9 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index 652807a16a..95ef9104d0 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -1072,6 +1072,7 @@ void zipl_load(void) + + if (virtio_get_device_type() == VIRTIO_ID_NET) { + netmain(); ++ panic("\n! Cannot IPL from this network !\n"); + } + + if (ipl_scsi()) { +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index bc6ad8695f..d1a6c9a91c 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -464,7 +464,7 @@ static bool find_net_dev(Schib *schib, int dev_no) + return false; + } + +-static void virtio_setup(void) ++static bool virtio_setup(void) + { + Schib schib; + int ssid; +@@ -495,10 +495,10 @@ static void virtio_setup(void) + } + } + +- IPL_assert(found, "No virtio net device found"); ++ return found; + } + +-void netmain(void) ++int netmain(void) + { + filename_ip_t fn_ip; + int rc, fnlen; +@@ -506,11 +506,15 @@ void netmain(void) + sclp_setup(); + puts("Network boot starting..."); + +- virtio_setup(); ++ if (!virtio_setup()) { ++ puts("No virtio net device found."); ++ return -1; ++ } + + rc = net_init(&fn_ip); + if (rc) { +- panic("Network initialization failed. Halting."); ++ puts("Network initialization failed."); ++ return -1; + } + + fnlen = strlen(fn_ip.filename); +@@ -528,5 +532,6 @@ void netmain(void) + jump_to_low_kernel(); + } + +- panic("Failed to load OS from network."); ++ puts("Failed to load OS from network."); ++ return -1; + } +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index 3e844abd71..344ad15655 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -57,7 +57,7 @@ unsigned int get_loadparm_index(void); + void main(void); + + /* netmain.c */ +-void netmain(void); ++int netmain(void); + + /* sclp.c */ + void sclp_print(const char *string); +diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c +index 2fcb0a58c5..f9854a22c3 100644 +--- a/pc-bios/s390-ccw/virtio-net.c ++++ b/pc-bios/s390-ccw/virtio-net.c +@@ -54,8 +54,11 @@ int virtio_net_init(void *mac_addr) + vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT; + virtio_setup_ccw(vdev); + +- IPL_assert(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT, +- "virtio-net device does not support the MAC address feature"); ++ if (!(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT)) { ++ puts("virtio-net device does not support the MAC address feature"); ++ return -1; ++ } ++ + memcpy(mac_addr, vdev->config.net.mac, ETH_ALEN); + + for (i = 0; i < 64; i++) { +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch new file mode 100644 index 0000000..2d4fba4 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch @@ -0,0 +1,554 @@ +From 23033a524625ad13448eda28d429d9265b213a7f Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:43 -0400 +Subject: [PATCH 10/27] pc-bios/s390-ccw: Remove panics from SCSI IPL path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [10/23] 4d8c58a0563e8977b045e7990deabe97c0614708 (thuth/qemu-kvm-cs9) + +Remove panic-on-error from virtio-scsi IPL specific functions so that error +recovery may be possible in the future. + +Functions that would previously panic now provide a return code. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-10-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit facd91ac1af75b657fc80189fe9cb026bb1abdbc) +--- + pc-bios/s390-ccw/bootmap.c | 88 ++++++++++++++----- + pc-bios/s390-ccw/virtio-blkdev.c | 4 +- + pc-bios/s390-ccw/virtio-scsi.c | 143 +++++++++++++++++++++---------- + 3 files changed, 164 insertions(+), 71 deletions(-) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index b9596e28c7..652807a16a 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -595,7 +595,7 @@ static int ipl_eckd(void) + * IPL a SCSI disk + */ + +-static void zipl_load_segment(ComponentEntry *entry) ++static int zipl_load_segment(ComponentEntry *entry) + { + const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr)); + ScsiBlockPtr *bprs = (void *)sec; +@@ -615,7 +615,10 @@ static void zipl_load_segment(ComponentEntry *entry) + do { + memset(bprs, FREE_SPACE_FILLER, bprs_size); + fill_hex_val(blk_no, &blockno, sizeof(blockno)); +- read_block(blockno, bprs, err_msg); ++ if (virtio_read(blockno, bprs)) { ++ puts(err_msg); ++ return -EIO; ++ } + + for (i = 0;; i++) { + uint64_t *cur_desc = (void *)&bprs[i]; +@@ -643,23 +646,37 @@ static void zipl_load_segment(ComponentEntry *entry) + } + address = virtio_load_direct(cur_desc[0], cur_desc[1], 0, + (void *)address); +- IPL_assert(address != -1, "zIPL load segment failed"); ++ if (!address) { ++ puts("zIPL load segment failed"); ++ return -EIO; ++ } + } + } while (blockno); ++ ++ return 0; + } + + /* Run a zipl program */ +-static void zipl_run(ScsiBlockPtr *pte) ++static int zipl_run(ScsiBlockPtr *pte) + { + ComponentHeader *header; + ComponentEntry *entry; + uint8_t tmp_sec[MAX_SECTOR_SIZE]; + +- read_block(pte->blockno, tmp_sec, "Cannot read header"); ++ if (virtio_read(pte->blockno, tmp_sec)) { ++ puts("Cannot read header"); ++ return -EIO; ++ } + header = (ComponentHeader *)tmp_sec; + +- IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header"); +- IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type"); ++ if (!magic_match(tmp_sec, ZIPL_MAGIC)) { ++ puts("No zIPL magic in header"); ++ return -EINVAL; ++ } ++ if (header->type != ZIPL_COMP_HEADER_IPL) { ++ puts("Bad header type"); ++ return -EINVAL; ++ } + + dputs("start loading images\n"); + +@@ -674,22 +691,30 @@ static void zipl_run(ScsiBlockPtr *pte) + continue; + } + +- zipl_load_segment(entry); ++ if (zipl_load_segment(entry)) { ++ return -1; ++ } + + entry++; + +- IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE), +- "Wrong entry value"); ++ if ((uint8_t *)(&entry[1]) > (tmp_sec + MAX_SECTOR_SIZE)) { ++ puts("Wrong entry value"); ++ return -EINVAL; ++ } + } + +- IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry"); ++ if (entry->component_type != ZIPL_COMP_ENTRY_EXEC) { ++ puts("No EXEC entry"); ++ return -EINVAL; ++ } + + /* should not return */ + write_reset_psw(entry->compdat.load_psw); + jump_to_IPL_code(0); ++ return -1; + } + +-static void ipl_scsi(void) ++static int ipl_scsi(void) + { + ScsiMbr *mbr = (void *)sec; + int program_table_entries = 0; +@@ -700,10 +725,13 @@ static void ipl_scsi(void) + + /* Grab the MBR */ + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +- read_block(0, mbr, "Cannot read block 0"); ++ if (virtio_read(0, mbr)) { ++ puts("Cannot read block 0"); ++ return -EIO; ++ } + + if (!magic_match(mbr->magic, ZIPL_MAGIC)) { +- return; ++ return 0; + } + + puts("Using SCSI scheme."); +@@ -711,11 +739,20 @@ static void ipl_scsi(void) + IPL_check(mbr->version_id == 1, + "Unknown MBR layout version, assuming version 1"); + debug_print_int("program table", mbr->pt.blockno); +- IPL_assert(mbr->pt.blockno, "No Program Table"); ++ if (!mbr->pt.blockno) { ++ puts("No Program Table"); ++ return -EINVAL; ++ } + + /* Parse the program table */ +- read_block(mbr->pt.blockno, sec, "Error reading Program Table"); +- IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT"); ++ if (virtio_read(mbr->pt.blockno, sec)) { ++ puts("Error reading Program Table"); ++ return -EIO; ++ } ++ if (!magic_match(sec, ZIPL_MAGIC)) { ++ puts("No zIPL magic in Program Table"); ++ return -EINVAL; ++ } + + for (i = 0; i < MAX_BOOT_ENTRIES; i++) { + if (prog_table->entry[i].scsi.blockno) { +@@ -725,17 +762,22 @@ static void ipl_scsi(void) + } + + debug_print_int("program table entries", program_table_entries); +- IPL_assert(program_table_entries != 0, "Empty Program Table"); ++ if (program_table_entries == 0) { ++ puts("Empty Program Table"); ++ return -EINVAL; ++ } + + if (menu_is_enabled_enum()) { + loadparm = menu_get_enum_boot_index(valid_entries); + } + + debug_print_int("loadparm", loadparm); +- IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than" +- " maximum number of boot entries allowed"); ++ if (loadparm >= MAX_BOOT_ENTRIES) { ++ puts("loadparm value greater than max number of boot entries allowed"); ++ return -EINVAL; ++ } + +- zipl_run(&prog_table->entry[loadparm].scsi); /* no return */ ++ return zipl_run(&prog_table->entry[loadparm].scsi); + } + + /*********************************************************************** +@@ -1032,7 +1074,9 @@ void zipl_load(void) + netmain(); + } + +- ipl_scsi(); ++ if (ipl_scsi()) { ++ panic("\n! Cannot IPL this SCSI device !\n"); ++ } + + switch (virtio_get_device_type()) { + case VIRTIO_ID_BLOCK: +diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c +index 2666326801..1c585f034b 100644 +--- a/pc-bios/s390-ccw/virtio-blkdev.c ++++ b/pc-bios/s390-ccw/virtio-blkdev.c +@@ -73,13 +73,13 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list + unsigned long addr = (unsigned long)load_addr; + + if (sec_len != virtio_get_block_size()) { +- return -1; ++ return 0; + } + + printf("."); + status = virtio_read_many(sec, (void *)addr, sec_num); + if (status) { +- panic("I/O Error"); ++ return 0; + } + addr += sec_num * virtio_get_block_size(); + +diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c +index 6b4a1caf8a..71db75ce7b 100644 +--- a/pc-bios/s390-ccw/virtio-scsi.c ++++ b/pc-bios/s390-ccw/virtio-scsi.c +@@ -26,7 +26,7 @@ static uint8_t scsi_inquiry_std_response[256]; + static ScsiInquiryEvpdPages scsi_inquiry_evpd_pages_response; + static ScsiInquiryEvpdBl scsi_inquiry_evpd_bl_response; + +-static inline void vs_assert(bool term, const char **msgs) ++static inline bool vs_assert(bool term, const char **msgs) + { + if (!term) { + int i = 0; +@@ -35,11 +35,13 @@ static inline void vs_assert(bool term, const char **msgs) + while (msgs[i]) { + printf("%s", msgs[i++]); + } +- panic(" !\n"); ++ puts(" !"); + } ++ ++ return term; + } + +-static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, ++static bool virtio_scsi_verify_response(VirtioScsiCmdResp *resp, + const char *title) + { + const char *mr[] = { +@@ -56,8 +58,8 @@ static void virtio_scsi_verify_response(VirtioScsiCmdResp *resp, + 0 + }; + +- vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr); +- vs_assert(resp->status == CDB_STATUS_GOOD, ms); ++ return vs_assert(resp->response == VIRTIO_SCSI_S_OK, mr) && ++ vs_assert(resp->status == CDB_STATUS_GOOD, ms); + } + + static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, +@@ -78,24 +80,31 @@ static void prepare_request(VDev *vdev, const void *cdb, int cdb_size, + } + } + +-static inline void vs_io_assert(bool term, const char *msg) ++static inline bool vs_io_assert(bool term, const char *msg) + { +- if (!term) { +- virtio_scsi_verify_response(&resp, msg); ++ if (!term && !virtio_scsi_verify_response(&resp, msg)) { ++ return false; + } ++ ++ return true; + } + +-static void vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, ++static int vs_run(const char *title, VirtioCmd *cmd, VDev *vdev, + const void *cdb, int cdb_size, + void *data, uint32_t data_size) + { + prepare_request(vdev, cdb, cdb_size, data, data_size); +- vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title); ++ if (!vs_io_assert(virtio_run(vdev, VR_REQUEST, cmd) == 0, title)) { ++ puts(title); ++ return -EIO; ++ } ++ ++ return 0; + } + + /* SCSI protocol implementation routines */ + +-static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, ++static int scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, + void *data, uint32_t data_size) + { + ScsiCdbInquiry cdb = { +@@ -110,12 +119,13 @@ static bool scsi_inquiry(VDev *vdev, uint8_t evpd, uint8_t page, + { data, data_size, VRING_DESC_F_WRITE }, + }; + +- vs_run("inquiry", inquiry, vdev, &cdb, sizeof(cdb), data, data_size); ++ int ret = vs_run("inquiry", inquiry, ++ vdev, &cdb, sizeof(cdb), data, data_size); + +- return virtio_scsi_response_ok(&resp); ++ return ret ? ret : virtio_scsi_response_ok(&resp); + } + +-static bool scsi_test_unit_ready(VDev *vdev) ++static int scsi_test_unit_ready(VDev *vdev) + { + ScsiCdbTestUnitReady cdb = { + .command = 0x00, +@@ -131,7 +141,7 @@ static bool scsi_test_unit_ready(VDev *vdev) + return virtio_scsi_response_ok(&resp); + } + +-static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) ++static int scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) + { + ScsiCdbReportLuns cdb = { + .command = 0xa0, +@@ -144,13 +154,13 @@ static bool scsi_report_luns(VDev *vdev, void *data, uint32_t data_size) + { data, data_size, VRING_DESC_F_WRITE }, + }; + +- vs_run("report luns", report_luns, ++ int ret = vs_run("report luns", report_luns, + vdev, &cdb, sizeof(cdb), data, data_size); + +- return virtio_scsi_response_ok(&resp); ++ return ret ? ret : virtio_scsi_response_ok(&resp); + } + +-static bool scsi_read_10(VDev *vdev, ++static int scsi_read_10(VDev *vdev, + unsigned long sector, int sectors, void *data, + unsigned int data_size) + { +@@ -168,12 +178,13 @@ static bool scsi_read_10(VDev *vdev, + debug_print_int("read_10 sector", sector); + debug_print_int("read_10 sectors", sectors); + +- vs_run("read(10)", read_10, vdev, &cdb, sizeof(cdb), data, data_size); ++ int ret = vs_run("read(10)", read_10, ++ vdev, &cdb, sizeof(cdb), data, data_size); + +- return virtio_scsi_response_ok(&resp); ++ return ret ? ret : virtio_scsi_response_ok(&resp); + } + +-static bool scsi_read_capacity(VDev *vdev, ++static int scsi_read_capacity(VDev *vdev, + void *data, uint32_t data_size) + { + ScsiCdbReadCapacity16 cdb = { +@@ -187,10 +198,10 @@ static bool scsi_read_capacity(VDev *vdev, + { data, data_size, VRING_DESC_F_WRITE }, + }; + +- vs_run("read capacity", read_capacity_16, ++ int ret = vs_run("read capacity", read_capacity_16, + vdev, &cdb, sizeof(cdb), data, data_size); + +- return virtio_scsi_response_ok(&resp); ++ return ret ? ret : virtio_scsi_response_ok(&resp); + } + + /* virtio-scsi routines */ +@@ -207,7 +218,7 @@ static int virtio_scsi_locate_device(VDev *vdev) + static uint8_t data[16 + 8 * 63]; + ScsiLunReport *r = (void *) data; + ScsiDevice *sdev = vdev->scsi_device; +- int i, luns; ++ int i, ret, luns; + + /* QEMU has hardcoded channel #0 in many places. + * If this hardcoded value is ever changed, we'll need to add code for +@@ -233,13 +244,21 @@ static int virtio_scsi_locate_device(VDev *vdev) + sdev->channel = channel; + sdev->target = target; + sdev->lun = 0; /* LUN has to be 0 for REPORT LUNS */ +- if (!scsi_report_luns(vdev, data, sizeof(data))) { ++ ret = scsi_report_luns(vdev, data, sizeof(data)); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ else if (ret == 0) { + if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { + continue; + } + printf("target 0x%X\n", target); +- virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); ++ if (!virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs")) { ++ return -EIO; ++ } + } ++ + if (r->lun_list_len == 0) { + printf("no LUNs for target 0x%X\n", target); + continue; +@@ -283,7 +302,9 @@ int virtio_scsi_read_many(VDev *vdev, + data_size = sector_count * virtio_get_block_size() * f; + if (!scsi_read_10(vdev, sector * f, sector_count * f, load_addr, + data_size)) { +- virtio_scsi_verify_response(&resp, "virtio-scsi:read_many"); ++ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:read_many")) { ++ return -1; ++ } + } + load_addr += data_size; + sector += sector_count; +@@ -352,11 +373,16 @@ static int virtio_scsi_setup(VDev *vdev) + uint8_t code = resp.sense[0] & SCSI_SENSE_CODE_MASK; + uint8_t sense_key = resp.sense[2] & SCSI_SENSE_KEY_MASK; + +- IPL_assert(resp.sense_len != 0, "virtio-scsi:setup: no SENSE data"); ++ if (resp.sense_len == 0) { ++ puts("virtio-scsi: setup: no SENSE data"); ++ return -EINVAL; ++ } + +- IPL_assert(retry_test_unit_ready && code == 0x70 && +- sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION, +- "virtio-scsi:setup: cannot retry"); ++ if (!retry_test_unit_ready || code != 0x70 || ++ sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) { ++ puts("virtio-scsi:setup: cannot retry"); ++ return -EIO; ++ } + + /* retry on CHECK_CONDITION/UNIT_ATTENTION as it + * may not designate a real error, but it may be +@@ -367,16 +393,22 @@ static int virtio_scsi_setup(VDev *vdev) + continue; + } + +- virtio_scsi_verify_response(&resp, "virtio-scsi:setup"); ++ if (!virtio_scsi_verify_response(&resp, "virtio-scsi:setup")) { ++ return -1; ++ } + } + + /* read and cache SCSI INQUIRY response */ +- if (!scsi_inquiry(vdev, ++ ret = scsi_inquiry(vdev, + SCSI_INQUIRY_STANDARD, + SCSI_INQUIRY_STANDARD_NONE, + scsi_inquiry_std_response, +- sizeof(scsi_inquiry_std_response))) { +- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:inquiry"); ++ sizeof(scsi_inquiry_std_response)); ++ if (ret < 1) { ++ if (ret != 0 || !virtio_scsi_verify_response(&resp, ++ "virtio-scsi:setup:inquiry")) { ++ return -1; ++ } + } + + if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { +@@ -385,12 +417,16 @@ static int virtio_scsi_setup(VDev *vdev) + vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; + } + +- if (!scsi_inquiry(vdev, ++ ret = scsi_inquiry(vdev, + SCSI_INQUIRY_EVPD, + SCSI_INQUIRY_EVPD_SUPPORTED_PAGES, + evpd, +- sizeof(*evpd))) { +- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:supported_pages"); ++ sizeof(*evpd)); ++ if (ret < 1) { ++ if (ret != 0 || !virtio_scsi_verify_response(&resp, ++ "virtio-scsi:setup:supported_pages")) { ++ return -1; ++ } + } + + debug_print_int("EVPD length", evpd->page_length); +@@ -402,12 +438,16 @@ static int virtio_scsi_setup(VDev *vdev) + continue; + } + +- if (!scsi_inquiry(vdev, ++ ret = scsi_inquiry(vdev, + SCSI_INQUIRY_EVPD, + SCSI_INQUIRY_EVPD_BLOCK_LIMITS, + evpd_bl, +- sizeof(*evpd_bl))) { +- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:blocklimits"); ++ sizeof(*evpd_bl)); ++ if (ret < 1) { ++ if (ret != 0 || !virtio_scsi_verify_response(&resp, ++ "virtio-scsi:setup:blocklimits")) { ++ return -1; ++ } + } + + debug_print_int("max transfer", evpd_bl->max_transfer); +@@ -423,8 +463,12 @@ static int virtio_scsi_setup(VDev *vdev) + vdev->max_transfer = MIN_NON_ZERO(VIRTIO_SCSI_MAX_SECTORS, + vdev->max_transfer); + +- if (!scsi_read_capacity(vdev, data, data_size)) { +- virtio_scsi_verify_response(&resp, "virtio-scsi:setup:read_capacity"); ++ ret = scsi_read_capacity(vdev, data, data_size); ++ if (ret < 1) { ++ if (ret != 0 || !virtio_scsi_verify_response(&resp, ++ "virtio-scsi:setup:read_capacity")) { ++ return -1; ++ } + } + scsi_parse_capacity_report(data, &vdev->scsi_last_block, + (uint32_t *) &vdev->scsi_block_size); +@@ -439,10 +483,15 @@ int virtio_scsi_setup_device(SubChannelId schid) + vdev->schid = schid; + virtio_setup_ccw(vdev); + +- IPL_assert(vdev->config.scsi.sense_size == VIRTIO_SCSI_SENSE_SIZE, +- "Config: sense size mismatch"); +- IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, +- "Config: CDB size mismatch"); ++ if (vdev->config.scsi.sense_size != VIRTIO_SCSI_SENSE_SIZE) { ++ puts("Config: sense size mismatch"); ++ return -EINVAL; ++ } ++ ++ if (vdev->config.scsi.cdb_size != VIRTIO_SCSI_CDB_SIZE) { ++ puts("Config: CDB size mismatch"); ++ return -EINVAL; ++ } + + puts("Using virtio-scsi."); + +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch b/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch new file mode 100644 index 0000000..037d987 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch @@ -0,0 +1,1208 @@ +From 4207901122ef7ad3f08ed2e387bd133cc4a35baf Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:36 -0400 +Subject: [PATCH 02/27] pc-bios/s390-ccw: Use the libc from SLOF and remove + sclp prints +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/23] ee701f93051e2bfb79da5cbbd089b24490bca128 (thuth/qemu-kvm-cs9) + +We are already using the libc from SLOF for the s390-netboot.img, and +this libc implementation is way more complete and accurate than the +simple implementation that we currently use for the s390-ccw.img binary. +Since we are now always assuming that the SLOF submodule is available +when building the s390-ccw bios (see commit bf6903f6944f), we can drop +the simple implementation and use the SLOF libc for the s390-ccw.img +binary, too. + +Additionally replace sclp_print calls with puts/printf now that it is +available. + +Co-authored by: Thomas Huth +Signed-off-by: Jared Rossi +Message-ID: <20241020012953.1380075-3-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 9f4278837dc770266c8a026696dd91a525dd2682) +--- + pc-bios/s390-ccw/Makefile | 15 +++-- + pc-bios/s390-ccw/bootmap.c | 47 ++++++------- + pc-bios/s390-ccw/bootmap.h | 4 +- + pc-bios/s390-ccw/cio.c | 78 ++++++++++------------ + pc-bios/s390-ccw/dasd-ipl.c | 5 +- + pc-bios/s390-ccw/jump2ipl.c | 5 +- + pc-bios/s390-ccw/libc.c | 88 ------------------------ + pc-bios/s390-ccw/libc.h | 89 ------------------------- + pc-bios/s390-ccw/main.c | 14 ++-- + pc-bios/s390-ccw/menu.c | 51 +++++++------- + pc-bios/s390-ccw/netboot.mak | 3 - + pc-bios/s390-ccw/netmain.c | 10 +-- + pc-bios/s390-ccw/s390-ccw.h | 30 +++------ + pc-bios/s390-ccw/sclp.c | 7 +- + pc-bios/s390-ccw/virtio-blkdev.c | 6 +- + pc-bios/s390-ccw/virtio-scsi.c | 17 ++--- + pc-bios/s390-ccw/virtio.c | 2 +- + tests/tcg/s390x/Makefile.softmmu-target | 2 +- + tests/tcg/s390x/console.c | 3 + + 19 files changed, 140 insertions(+), 336 deletions(-) + delete mode 100644 pc-bios/s390-ccw/libc.c + delete mode 100644 pc-bios/s390-ccw/libc.h + +diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile +index 6207911b53..3f4232636e 100644 +--- a/pc-bios/s390-ccw/Makefile ++++ b/pc-bios/s390-ccw/Makefile +@@ -33,13 +33,18 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d + .PHONY : all clean build-all distclean + + OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \ +- virtio.o virtio-scsi.o virtio-blkdev.o libc.o cio.o dasd-ipl.o ++ virtio.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o ++ ++SLOF_DIR := $(SRC_PATH)/../../roms/SLOF ++ ++LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include + + EXTRA_CFLAGS += -Wall + EXTRA_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -fno-common -fPIE + EXTRA_CFLAGS += -fwrapv -fno-strict-aliasing -fno-asynchronous-unwind-tables + EXTRA_CFLAGS += -msoft-float + EXTRA_CFLAGS += -std=gnu99 ++EXTRA_CFLAGS += $(LIBC_INC) + LDFLAGS += -Wl,-pie -nostdlib -z noexecstack + + cc-test = $(CC) -Werror $1 -c -o /dev/null -xc /dev/null >/dev/null 2>/dev/null +@@ -55,18 +60,18 @@ config-cc.mak: Makefile + $(call cc-option,-march=z900,-march=z10)) 3> config-cc.mak + -include config-cc.mak + ++include $(SRC_PATH)/netboot.mak ++ + build-all: s390-ccw.img s390-netboot.img + +-s390-ccw.elf: $(OBJECTS) +- $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $(OBJECTS),Linking) ++s390-ccw.elf: $(OBJECTS) libc.a ++ $(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^,Linking) + + s390-ccw.img: s390-ccw.elf + $(call quiet-command,$(STRIP) --strip-unneeded $< -o $@,Stripping $< into) + + $(OBJECTS): Makefile + +-include $(SRC_PATH)/netboot.mak +- + ALL_OBJS = $(sort $(OBJECTS) $(NETOBJS) $(LIBCOBJS) $(LIBNETOBJS)) + -include $(ALL_OBJS:%.o=%.d) + +diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c +index a2137449dc..3cc79706be 100644 +--- a/pc-bios/s390-ccw/bootmap.c ++++ b/pc-bios/s390-ccw/bootmap.c +@@ -8,7 +8,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "bootmap.h" +@@ -21,7 +22,7 @@ + + #ifdef DEBUG_FALLBACK + #define dputs(txt) \ +- do { sclp_print("zipl: " txt); } while (0) ++ do { printf("zipl: " txt); } while (0) + #else + #define dputs(fmt, ...) \ + do { } while (0) +@@ -270,7 +271,7 @@ static int eckd_get_boot_menu_index(block_number_t s1b_block_nr) + prev_block_nr = cur_block_nr; + } + +- sclp_print("No zipl boot menu data found. Booting default entry."); ++ printf("No zipl boot menu data found. Booting default entry."); + return 0; + } + +@@ -338,22 +339,22 @@ static void ipl_eckd_cdl(void) + block_number_t bmt_block_nr, s1b_block_nr; + + /* we have just read the block #0 and recognized it as "IPL1" */ +- sclp_print("CDL\n"); ++ puts("CDL"); + + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(1, ipl2, "Cannot read IPL2 record at block 1"); + + mbr = &ipl2->mbr; + if (!magic_match(mbr, ZIPL_MAGIC)) { +- sclp_print("No zIPL section in IPL2 record.\n"); ++ puts("No zIPL section in IPL2 record."); + return; + } + if (!block_size_ok(mbr->blockptr.xeckd.bptr.size)) { +- sclp_print("Bad block size in zIPL section of IPL2 record.\n"); ++ puts("Bad block size in zIPL section of IPL2 record."); + return; + } + if (mbr->dev_type != DEV_TYPE_ECKD) { +- sclp_print("Non-ECKD device type in zIPL section of IPL2 record.\n"); ++ puts("Non-ECKD device type in zIPL section of IPL2 record."); + return; + } + +@@ -366,11 +367,11 @@ static void ipl_eckd_cdl(void) + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); + read_block(2, vlbl, "Cannot read Volume Label at block 2"); + if (!magic_match(vlbl->key, VOL1_MAGIC)) { +- sclp_print("Invalid magic of volume label block.\n"); ++ puts("Invalid magic of volume label block."); + return; + } + if (!magic_match(vlbl->f.key, VOL1_MAGIC)) { +- sclp_print("Invalid magic of volser block.\n"); ++ puts("Invalid magic of volser block."); + return; + } + print_volser(vlbl->f.volser); +@@ -384,8 +385,8 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) + LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */ + char msg[4] = { '?', '.', '\n', '\0' }; + +- sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL"); +- sclp_print(" version "); ++ printf((mode == ECKD_CMS) ? "CMS" : "LDL"); ++ printf(" version "); + switch (vlbl->LDL_version) { + case LDL1_VERSION: + msg[0] = '1'; +@@ -398,7 +399,7 @@ static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode) + msg[1] = '?'; + break; + } +- sclp_print(msg); ++ printf("%s", msg); + print_volser(vlbl->volser); + } + +@@ -419,7 +420,7 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) + if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) { + return; /* not applicable layout */ + } +- sclp_print("unlabeled LDL.\n"); ++ puts("unlabeled LDL."); + } + verify_boot_info(&ipl1->bip); + +@@ -466,7 +467,7 @@ static void print_eckd_msg(void) + *p-- = ' '; + } + } +- sclp_print(msg); ++ printf("%s", msg); + } + + static void ipl_eckd(void) +@@ -488,11 +489,11 @@ static void ipl_eckd(void) + if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) { + ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br); + if (ldipl_bmt) { +- sclp_print("List-Directed\n"); ++ puts("List-Directed"); + /* LD-IPL does not use the S1B bock, just make it NULL */ + run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR); + /* Only return in error, retry as CCW-IPL */ +- sclp_print("Retrying IPL "); ++ printf("Retrying IPL "); + print_eckd_msg(); + } + memset(sec, FREE_SPACE_FILLER, sizeof(sec)); +@@ -634,7 +635,7 @@ static void ipl_scsi(void) + return; + } + +- sclp_print("Using SCSI scheme.\n"); ++ puts("Using SCSI scheme."); + debug_print_int("MBR Version", mbr->version_id); + IPL_check(mbr->version_id == 1, + "Unknown MBR layout version, assuming version 1"); +@@ -743,7 +744,7 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba) + if (cur_record->file_flags & 0x2) { + /* Subdirectory */ + if (level == ISO9660_MAX_DIR_DEPTH - 1) { +- sclp_print("ISO-9660 directory depth limit exceeded\n"); ++ puts("ISO-9660 directory depth limit exceeded"); + } else { + level++; + sec_loc[level] = iso_733_to_u32(cur_record->ext_loc); +@@ -778,9 +779,9 @@ static void load_iso_bc_entry(IsoBcSection *load) + if (real_size) { + /* Round up blocks to load */ + blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE; +- sclp_print("ISO boot image size verified\n"); ++ puts("ISO boot image size verified"); + } else { +- sclp_print("ISO boot image size could not be verified\n"); ++ puts("ISO boot image size could not be verified"); + } + + read_iso_boot_image(bswap32(s.load_rba), +@@ -896,7 +897,7 @@ static void zipl_load_vblk(void) + } + + if (blksize != VIRTIO_DASD_DEFAULT_BLOCK_SIZE) { +- sclp_print("Using guessed DASD geometry.\n"); ++ puts("Using guessed DASD geometry."); + virtio_assume_eckd(); + } + ipl_eckd(); +@@ -909,7 +910,7 @@ static void zipl_load_vscsi(void) + ipl_iso_el_torito(); + } + +- sclp_print("Using guessed DASD geometry.\n"); ++ puts("Using guessed DASD geometry."); + virtio_assume_eckd(); + ipl_eckd(); + } +@@ -944,5 +945,5 @@ void zipl_load(void) + panic("\n! Unknown IPL device type !\n"); + } + +- sclp_print("zIPL load failed.\n"); ++ puts("zIPL load failed."); + } +diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h +index d4690a88c2..4a7d8a91f1 100644 +--- a/pc-bios/s390-ccw/bootmap.h ++++ b/pc-bios/s390-ccw/bootmap.h +@@ -336,9 +336,7 @@ static inline void print_volser(const void *volser) + + ebcdic_to_ascii((char *)volser, ascii, 6); + ascii[6] = '\0'; +- sclp_print("VOLSER=["); +- sclp_print(ascii); +- sclp_print("]\n"); ++ printf("VOLSER=[%s]\n", ascii); + } + + static inline bool unused_space(const void *p, size_t size) +diff --git a/pc-bios/s390-ccw/cio.c b/pc-bios/s390-ccw/cio.c +index 83ca27ab41..7b09a38c96 100644 +--- a/pc-bios/s390-ccw/cio.c ++++ b/pc-bios/s390-ccw/cio.c +@@ -11,7 +11,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "helper.h" +@@ -90,9 +91,9 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) + char msgline[512]; + + if (sd->config_info & 0x8000) { +- sclp_print("Eckd Dasd Sense Data (fmt 24-bytes):\n"); ++ puts("Eckd Dasd Sense Data (fmt 24-bytes):"); + } else { +- sclp_print("Eckd Dasd Sense Data (fmt 32-bytes):\n"); ++ puts("Eckd Dasd Sense Data (fmt 32-bytes):"); + } + + strcat(msgline, " Sense Condition Flags :"); +@@ -158,22 +159,21 @@ static void print_eckd_dasd_sense_data(SenseDataEckdDasd *sd) + if (sd->status[1] & SNS_STAT2_IMPRECISE_END) { + strcat(msgline, " [Imprecise-End]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); +- +- print_int(" Residual Count =", sd->res_count); +- print_int(" Phys Drive ID =", sd->phys_drive_id); +- print_int(" low cyl address =", sd->low_cyl_addr); +- print_int(" head addr & hi cyl =", sd->head_high_cyl_addr); +- print_int(" format/message =", sd->fmt_msg); +- print_int(" fmt-dependent[0-7] =", sd->fmt_dependent_info[0]); +- print_int(" fmt-dependent[8-15]=", sd->fmt_dependent_info[1]); +- print_int(" prog action code =", sd->program_action_code); +- print_int(" Configuration info =", sd->config_info); +- print_int(" mcode / hi-cyl =", sd->mcode_hicyl); +- print_int(" cyl & head addr [0]=", sd->cyl_head_addr[0]); +- print_int(" cyl & head addr [1]=", sd->cyl_head_addr[1]); +- print_int(" cyl & head addr [2]=", sd->cyl_head_addr[2]); ++ puts(msgline); ++ ++ printf(" Residual Count = 0x%X\n", sd->res_count); ++ printf(" Phys Drive ID = 0x%X\n", sd->phys_drive_id); ++ printf(" low cyl address = 0x%X\n", sd->low_cyl_addr); ++ printf(" head addr & hi cyl = 0x%X\n", sd->head_high_cyl_addr); ++ printf(" format/message = 0x%X\n", sd->fmt_msg); ++ printf(" fmt-dependent[0-7] = 0x%llX\n", sd->fmt_dependent_info[0]); ++ printf(" fmt-dependent[8-15]= 0x%llX\n", sd->fmt_dependent_info[1]); ++ printf(" prog action code = 0x%X\n", sd->program_action_code); ++ printf(" Configuration info = 0x%X\n", sd->config_info); ++ printf(" mcode / hi-cyl = 0x%X\n", sd->mcode_hicyl); ++ printf(" cyl & head addr [0]= 0x%X\n", sd->cyl_head_addr[0]); ++ printf(" cyl & head addr [1]= 0x%X\n", sd->cyl_head_addr[1]); ++ printf(" cyl & head addr [2]= 0x%X\n", sd->cyl_head_addr[2]); + } + + static void print_irb_err(Irb *irb) +@@ -182,7 +182,7 @@ static void print_irb_err(Irb *irb) + uint64_t prev_ccw = *(uint64_t *)u32toptr(irb->scsw.cpa - 8); + char msgline[256]; + +- sclp_print("Interrupt Response Block Data:\n"); ++ puts("Interrupt Response Block Data:"); + + strcat(msgline, " Function Ctrl :"); + if (irb->scsw.ctrl & SCSW_FCTL_START_FUNC) { +@@ -194,8 +194,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) { + strcat(msgline, " [Clear]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Activity Ctrl :"); +@@ -220,8 +219,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_ACTL_SUSPENDED) { + strcat(msgline, " [Suspended]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Status Ctrl :"); +@@ -240,9 +238,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.ctrl & SCSW_SCTL_STATUS_PEND) { + strcat(msgline, " [Status-Pending]"); + } +- +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Device Status :"); +@@ -270,8 +266,7 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.dstat & SCSW_DSTAT_UEXCP) { + strcat(msgline, " [Unit-Exception]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + + msgline[0] = '\0'; + strcat(msgline, " Channel Status :"); +@@ -299,12 +294,11 @@ static void print_irb_err(Irb *irb) + if (irb->scsw.cstat & SCSW_CSTAT_CHAINCHK) { + strcat(msgline, " [Chaining-Check]"); + } +- strcat(msgline, "\n"); +- sclp_print(msgline); ++ puts(msgline); + +- print_int(" cpa=", irb->scsw.cpa); +- print_int(" prev_ccw=", prev_ccw); +- print_int(" this_ccw=", this_ccw); ++ printf(" cpa= 0x%X\n", irb->scsw.cpa); ++ printf(" prev_ccw= 0x%llX\n", prev_ccw); ++ printf(" this_ccw= 0x%llX\n", this_ccw); + } + + /* +@@ -341,7 +335,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) + return -1; + } + if (rc) { +- print_int("ssch failed with cc=", rc); ++ printf("ssch failed with cc= 0x%x\n", rc); + return rc; + } + +@@ -350,7 +344,7 @@ static int __do_cio(SubChannelId schid, uint32_t ccw_addr, int fmt, Irb *irb) + /* collect status */ + rc = tsch(schid, irb); + if (rc) { +- print_int("tsch failed with cc=", rc); ++ printf("tsch failed with cc= 0x%X\n", rc); + } + + return rc; +@@ -406,12 +400,12 @@ int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt) + continue; + } + +- sclp_print("cio device error\n"); +- print_int(" ssid ", schid.ssid); +- print_int(" cssid ", schid.cssid); +- print_int(" sch_no", schid.sch_no); +- print_int(" ctrl-unit type", cutype); +- sclp_print("\n"); ++ printf("cio device error\n"); ++ printf(" ssid 0x%X\n", schid.ssid); ++ printf(" cssid 0x%X\n", schid.cssid); ++ printf(" sch_no 0x%X\n", schid.sch_no); ++ printf(" ctrl-unit type 0x%X\n", cutype); ++ printf("\n"); + print_irb_err(&irb); + if (cutype == CU_TYPE_DASD_3990 || cutype == CU_TYPE_DASD_2107 || + cutype == CU_TYPE_UNKNOWN) { +diff --git a/pc-bios/s390-ccw/dasd-ipl.c b/pc-bios/s390-ccw/dasd-ipl.c +index 254bb1a15e..ae751adec1 100644 +--- a/pc-bios/s390-ccw/dasd-ipl.c ++++ b/pc-bios/s390-ccw/dasd-ipl.c +@@ -8,7 +8,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + #include "dasd-ipl.h" +@@ -82,7 +83,7 @@ static int run_dynamic_ccw_program(SubChannelId schid, uint16_t cutype, + do { + has_next = dynamic_cp_fixup(cpa, &next_cpa); + +- print_int("executing ccw chain at ", cpa); ++ printf("executing ccw chain at 0x%X\n", cpa); + enable_prefixing(); + rc = do_cio(schid, cutype, cpa, CCW_FMT0); + disable_prefixing(); +diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c +index 78f5f46533..80b7f6a1f3 100644 +--- a/pc-bios/s390-ccw/jump2ipl.c ++++ b/pc-bios/s390-ccw/jump2ipl.c +@@ -6,7 +6,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "s390-arch.h" + +@@ -57,7 +58,7 @@ void jump_to_IPL_code(uint64_t address) + debug_print_int("set IPL addr to", address ?: *reset_psw & PSW_MASK_SHORT_ADDR); + + /* Ensure the guest output starts fresh */ +- sclp_print("\n"); ++ printf("\n"); + + /* + * HACK ALERT. +diff --git a/pc-bios/s390-ccw/libc.c b/pc-bios/s390-ccw/libc.c +deleted file mode 100644 +index 3187923950..0000000000 +--- a/pc-bios/s390-ccw/libc.c ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* +- * libc-style definitions and functions +- * +- * Copyright 2018 IBM Corp. +- * Author(s): Collin L. Walling +- * +- * This code 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. +- */ +- +-#include "libc.h" +-#include "s390-ccw.h" +- +-/** +- * atoui: +- * @str: the string to be converted. +- * +- * Given a string @str, convert it to an integer. Leading spaces are +- * ignored. Any other non-numerical value will terminate the conversion +- * and return 0. This function only handles numbers between 0 and +- * UINT64_MAX inclusive. +- * +- * Returns: an integer converted from the string @str, or the number 0 +- * if an error occurred. +- */ +-uint64_t atoui(const char *str) +-{ +- int val = 0; +- +- if (!str || !str[0]) { +- return 0; +- } +- +- while (*str == ' ') { +- str++; +- } +- +- while (*str) { +- if (!isdigit(*(unsigned char *)str)) { +- break; +- } +- val = val * 10 + *str - '0'; +- str++; +- } +- +- return val; +-} +- +-/** +- * uitoa: +- * @num: an integer (base 10) to be converted. +- * @str: a pointer to a string to store the conversion. +- * @len: the length of the passed string. +- * +- * Given an integer @num, convert it to a string. The string @str must be +- * allocated beforehand. The resulting string will be null terminated and +- * returned. This function only handles numbers between 0 and UINT64_MAX +- * inclusive. +- * +- * Returns: the string @str of the converted integer @num +- */ +-char *uitoa(uint64_t num, char *str, size_t len) +-{ +- long num_idx = 1; /* account for NUL */ +- uint64_t tmp = num; +- +- IPL_assert(str != NULL, "uitoa: no space allocated to store string"); +- +- /* Count indices of num */ +- while ((tmp /= 10) != 0) { +- num_idx++; +- } +- +- /* Check if we have enough space for num and NUL */ +- IPL_assert(len > num_idx, "uitoa: array too small for conversion"); +- +- str[num_idx--] = '\0'; +- +- /* Convert int to string */ +- while (num_idx >= 0) { +- str[num_idx--] = num % 10 + '0'; +- num /= 10; +- } +- +- return str; +-} +diff --git a/pc-bios/s390-ccw/libc.h b/pc-bios/s390-ccw/libc.h +deleted file mode 100644 +index bcdc45732d..0000000000 +--- a/pc-bios/s390-ccw/libc.h ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* +- * libc-style definitions and functions +- * +- * Copyright (c) 2013 Alexander Graf +- * +- * This code 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. +- */ +- +-#ifndef S390_CCW_LIBC_H +-#define S390_CCW_LIBC_H +- +-typedef unsigned long size_t; +-typedef int bool; +-typedef unsigned char uint8_t; +-typedef unsigned short uint16_t; +-typedef unsigned int uint32_t; +-typedef unsigned long long uint64_t; +- +-static inline void *memset(void *s, int c, size_t n) +-{ +- size_t i; +- unsigned char *p = s; +- +- for (i = 0; i < n; i++) { +- p[i] = c; +- } +- +- return s; +-} +- +-static inline void *memcpy(void *s1, const void *s2, size_t n) +-{ +- uint8_t *dest = s1; +- const uint8_t *src = s2; +- size_t i; +- +- for (i = 0; i < n; i++) { +- dest[i] = src[i]; +- } +- +- return s1; +-} +- +-static inline int memcmp(const void *s1, const void *s2, size_t n) +-{ +- size_t i; +- const uint8_t *p1 = s1, *p2 = s2; +- +- for (i = 0; i < n; i++) { +- if (p1[i] != p2[i]) { +- return p1[i] > p2[i] ? 1 : -1; +- } +- } +- +- return 0; +-} +- +-static inline size_t strlen(const char *str) +-{ +- size_t i; +- for (i = 0; *str; i++) { +- str++; +- } +- return i; +-} +- +-static inline char *strcat(char *dest, const char *src) +-{ +- int i; +- char *dest_end = dest + strlen(dest); +- +- for (i = 0; i <= strlen(src); i++) { +- dest_end[i] = src[i]; +- } +- return dest; +-} +- +-static inline int isdigit(int c) +-{ +- return (c >= '0') && (c <= '9'); +-} +- +-uint64_t atoui(const char *str); +-char *uitoa(uint64_t num, char *str, size_t len); +- +-#endif +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index 5506798098..203df20965 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -8,7 +8,9 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include ++#include + #include "helper.h" + #include "s390-arch.h" + #include "s390-ccw.h" +@@ -50,7 +52,7 @@ void write_iplb_location(void) + + unsigned int get_loadparm_index(void) + { +- return atoui(loadparm_str); ++ return atoi(loadparm_str); + } + + static int is_dev_possibly_bootable(int dev_no, int sch_no) +@@ -176,7 +178,7 @@ static void boot_setup(void) + + sclp_get_loadparm_ascii(loadparm_str); + memcpy(lpmsg + 10, loadparm_str, 8); +- sclp_print(lpmsg); ++ puts(lpmsg); + + /* + * Clear out any potential S390EP magic (see jump_to_low_kernel()), +@@ -228,7 +230,7 @@ static int virtio_setup(void) + + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: +- sclp_print("Network boot device detected\n"); ++ puts("Network boot device detected"); + vdev->netboot_start_addr = qipl.netboot_start_addr; + return 0; + case VIRTIO_ID_BLOCK: +@@ -261,7 +263,7 @@ static void ipl_boot_device(void) + } + break; + default: +- print_int("Attempting to boot from unexpected device type", cutype); ++ printf("Attempting to boot from unexpected device type 0x%X\n", cutype); + panic("\nBoot failed.\n"); + } + } +@@ -287,7 +289,7 @@ static void probe_boot_device(void) + } + } + +- sclp_print("Could not find a suitable boot device (none specified)\n"); ++ puts("Could not find a suitable boot device (none specified)"); + } + + void main(void) +diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c +index d601952d3e..84062e94af 100644 +--- a/pc-bios/s390-ccw/menu.c ++++ b/pc-bios/s390-ccw/menu.c +@@ -9,7 +9,10 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include ++#include ++#include + #include "s390-ccw.h" + #include "sclp.h" + #include "s390-time.h" +@@ -93,7 +96,7 @@ static int read_prompt(char *buf, size_t len) + case KEYCODE_BACKSP: + if (idx > 0) { + buf[--idx] = 0; +- sclp_print("\b \b"); ++ printf("\b \b"); + } + continue; + case KEYCODE_ENTER: +@@ -103,7 +106,7 @@ static int read_prompt(char *buf, size_t len) + /* Echo input and add to buffer */ + if (idx < len) { + buf[idx++] = inp[0]; +- sclp_print(inp); ++ printf("%s", inp); + } + } + } +@@ -140,22 +143,19 @@ static int get_index(void) + } + } + +- return atoui(buf); ++ return atoi(buf); + } + + static void boot_menu_prompt(bool retry) + { +- char tmp[11]; +- + if (retry) { +- sclp_print("\nError: undefined configuration" ++ printf("\nError: undefined configuration" + "\nPlease choose:\n"); + } else if (timeout > 0) { +- sclp_print("Please choose (default will boot in "); +- sclp_print(uitoa(timeout / 1000, tmp, sizeof(tmp))); +- sclp_print(" seconds):\n"); ++ printf("Please choose (default will boot in %d seconds):\n", ++ (int)(timeout / 1000)); + } else { +- sclp_print("Please choose:\n"); ++ puts("Please choose:"); + } + } + +@@ -163,7 +163,6 @@ static int get_boot_index(bool *valid_entries) + { + int boot_index; + bool retry = false; +- char tmp[5]; + + do { + boot_menu_prompt(retry); +@@ -172,8 +171,7 @@ static int get_boot_index(bool *valid_entries) + } while (boot_index < 0 || boot_index >= MAX_BOOT_ENTRIES || + !valid_entries[boot_index]); + +- sclp_print("\nBooting entry #"); +- sclp_print(uitoa(boot_index, tmp, sizeof(tmp))); ++ printf("\nBooting entry #%d", boot_index); + + return boot_index; + } +@@ -187,9 +185,9 @@ static int zipl_print_entry(const char *data, size_t len) + buf[len] = '\n'; + buf[len + 1] = '\0'; + +- sclp_print(buf); ++ printf("%s", buf); + +- return buf[0] == ' ' ? atoui(buf + 1) : atoui(buf); ++ return buf[0] == ' ' ? atoi(buf + 1) : atoi(buf); + } + + int menu_get_zipl_boot_index(const char *menu_data) +@@ -209,7 +207,7 @@ int menu_get_zipl_boot_index(const char *menu_data) + } + + /* Print banner */ +- sclp_print("s390-ccw zIPL Boot Menu\n\n"); ++ puts("s390-ccw zIPL Boot Menu\n"); + menu_data += strlen(menu_data) + 1; + + /* Print entries */ +@@ -221,37 +219,34 @@ int menu_get_zipl_boot_index(const char *menu_data) + valid_entries[entry] = true; + + if (entry == 0) { +- sclp_print("\n"); ++ printf("\n"); + } + } + +- sclp_print("\n"); ++ printf("\n"); + return get_boot_index(valid_entries); + } + + int menu_get_enum_boot_index(bool *valid_entries) + { +- char tmp[3]; + int i; + +- sclp_print("s390-ccw Enumerated Boot Menu.\n\n"); ++ puts("s390-ccw Enumerated Boot Menu.\n"); + + for (i = 0; i < MAX_BOOT_ENTRIES; i++) { + if (valid_entries[i]) { + if (i < 10) { +- sclp_print(" "); ++ printf(" "); + } +- sclp_print("["); +- sclp_print(uitoa(i, tmp, sizeof(tmp))); +- sclp_print("]"); ++ printf("[%d]", i); + if (i == 0) { +- sclp_print(" default\n"); ++ printf(" default\n"); + } +- sclp_print("\n"); ++ printf("\n"); + } + } + +- sclp_print("\n"); ++ printf("\n"); + return get_boot_index(valid_entries); + } + +diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak +index 046aa35587..d2b3d8ee74 100644 +--- a/pc-bios/s390-ccw/netboot.mak ++++ b/pc-bios/s390-ccw/netboot.mak +@@ -1,9 +1,6 @@ + +-SLOF_DIR := $(SRC_PATH)/../../roms/SLOF +- + NETOBJS := start.o sclp.o cio.o virtio.o virtio-net.o jump2ipl.o netmain.o + +-LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include + LIBNET_INC := -I$(SLOF_DIR)/lib/libnet + + NETLDFLAGS := $(LDFLAGS) -Wl,-Ttext=0x7800000 +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index 5cd619b2d6..509119be15 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -293,7 +293,7 @@ static int load_kernel_with_initrd(filename_ip_t *fn_ip, + printf("Loading pxelinux.cfg entry '%s'\n", entry->label); + + if (!entry->kernel) { +- printf("Kernel entry is missing!\n"); ++ puts("Kernel entry is missing!\n"); + return -1; + } + +@@ -515,13 +515,13 @@ void main(void) + int rc, fnlen; + + sclp_setup(); +- sclp_print("Network boot starting...\n"); ++ puts("Network boot starting..."); + + virtio_setup(); + + rc = net_init(&fn_ip); + if (rc) { +- panic("Network initialization failed. Halting.\n"); ++ panic("Network initialization failed. Halting."); + } + + fnlen = strlen(fn_ip.filename); +@@ -535,9 +535,9 @@ void main(void) + net_release(&fn_ip); + + if (rc > 0) { +- sclp_print("Network loading done, starting kernel...\n"); ++ puts("Network loading done, starting kernel..."); + jump_to_low_kernel(); + } + +- panic("Failed to load OS from network\n"); ++ panic("Failed to load OS from network."); + } +diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h +index c977a52b50..6f6d95d170 100644 +--- a/pc-bios/s390-ccw/s390-ccw.h ++++ b/pc-bios/s390-ccw/s390-ccw.h +@@ -13,6 +13,11 @@ + + /* #define DEBUG */ + ++#include ++#include ++#include ++#include ++ + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; +@@ -26,9 +31,6 @@ typedef unsigned long long u64; + #define EBUSY 2 + #define ENODEV 3 + +-#ifndef NULL +-#define NULL 0 +-#endif + #ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + #endif +@@ -87,7 +89,7 @@ bool menu_is_enabled_enum(void); + __attribute__ ((__noreturn__)) + static inline void panic(const char *string) + { +- sclp_print(string); ++ printf("ERROR: %s\n ", string); + disabled_wait(); + } + +@@ -109,20 +111,10 @@ static inline void fill_hex_val(char *out, void *ptr, unsigned size) + } + } + +-static inline void print_int(const char *desc, u64 addr) +-{ +- char out[] = ": 0xffffffffffffffff\n"; +- +- fill_hex_val(&out[4], &addr, sizeof(addr)); +- +- sclp_print(desc); +- sclp_print(out); +-} +- + static inline void debug_print_int(const char *desc, u64 addr) + { + #ifdef DEBUG +- print_int(desc, addr); ++ printf("%s 0x%X\n", desc, addr); + #endif + } + +@@ -147,18 +139,14 @@ static inline void debug_print_addr(const char *desc, void *p) + static inline void IPL_assert(bool term, const char *message) + { + if (!term) { +- sclp_print("\n! "); +- sclp_print(message); +- panic(" !\n"); /* no return */ ++ panic(message); /* no return */ + } + } + + static inline void IPL_check(bool term, const char *message) + { + if (!term) { +- sclp_print("\n! WARNING: "); +- sclp_print(message); +- sclp_print(" !\n"); ++ printf("WARNING: %s\n", message); + } + } + +diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c +index 7251f9af4d..4a07de018d 100644 +--- a/pc-bios/s390-ccw/sclp.c ++++ b/pc-bios/s390-ccw/sclp.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "sclp.h" + +@@ -101,11 +101,6 @@ long write(int fd, const void *str, size_t len) + return len; + } + +-void sclp_print(const char *str) +-{ +- write(1, str, strlen(str)); +-} +- + void sclp_get_loadparm_ascii(char *loadparm) + { + +diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c +index a81207b52e..2666326801 100644 +--- a/pc-bios/s390-ccw/virtio-blkdev.c ++++ b/pc-bios/s390-ccw/virtio-blkdev.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "virtio.h" + #include "virtio-scsi.h" +@@ -76,7 +76,7 @@ unsigned long virtio_load_direct(unsigned long rec_list1, unsigned long rec_list + return -1; + } + +- sclp_print("."); ++ printf("."); + status = virtio_read_many(sec, (void *)addr, sec_num); + if (status) { + panic("I/O Error"); +@@ -230,7 +230,7 @@ int virtio_blk_setup_device(SubChannelId schid) + vdev->schid = schid; + virtio_setup_ccw(vdev); + +- sclp_print("Using virtio-blk.\n"); ++ puts("Using virtio-blk."); + + return 0; + } +diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c +index d1a84b937c..6b4a1caf8a 100644 +--- a/pc-bios/s390-ccw/virtio-scsi.c ++++ b/pc-bios/s390-ccw/virtio-scsi.c +@@ -9,7 +9,8 @@ + * directory. + */ + +-#include "libc.h" ++#include ++#include + #include "s390-ccw.h" + #include "virtio.h" + #include "scsi.h" +@@ -30,9 +31,9 @@ static inline void vs_assert(bool term, const char **msgs) + if (!term) { + int i = 0; + +- sclp_print("\n! "); ++ printf("\n! "); + while (msgs[i]) { +- sclp_print(msgs[i++]); ++ printf("%s", msgs[i++]); + } + panic(" !\n"); + } +@@ -236,11 +237,11 @@ static int virtio_scsi_locate_device(VDev *vdev) + if (resp.response == VIRTIO_SCSI_S_BAD_TARGET) { + continue; + } +- print_int("target", target); ++ printf("target 0x%X\n", target); + virtio_scsi_verify_response(&resp, "SCSI cannot report LUNs"); + } + if (r->lun_list_len == 0) { +- print_int("no LUNs for target", target); ++ printf("no LUNs for target 0x%X\n", target); + continue; + } + luns = r->lun_list_len / 8; +@@ -264,7 +265,7 @@ static int virtio_scsi_locate_device(VDev *vdev) + } + } + +- sclp_print("Warning: Could not locate a usable virtio-scsi device\n"); ++ puts("Warning: Could not locate a usable virtio-scsi device"); + return -ENODEV; + } + +@@ -379,7 +380,7 @@ static int virtio_scsi_setup(VDev *vdev) + } + + if (virtio_scsi_inquiry_response_is_cdrom(scsi_inquiry_std_response)) { +- sclp_print("SCSI CD-ROM detected.\n"); ++ puts("SCSI CD-ROM detected."); + vdev->is_cdrom = true; + vdev->scsi_block_size = VIRTIO_ISO_BLOCK_SIZE; + } +@@ -443,7 +444,7 @@ int virtio_scsi_setup_device(SubChannelId schid) + IPL_assert(vdev->config.scsi.cdb_size == VIRTIO_SCSI_CDB_SIZE, + "Config: CDB size mismatch"); + +- sclp_print("Using virtio-scsi.\n"); ++ puts("Using virtio-scsi."); + + return virtio_scsi_setup(vdev); + } +diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c +index 5edd058d88..8c6b0a8a92 100644 +--- a/pc-bios/s390-ccw/virtio.c ++++ b/pc-bios/s390-ccw/virtio.c +@@ -8,7 +8,7 @@ + * directory. + */ + +-#include "libc.h" ++#include + #include "s390-ccw.h" + #include "cio.h" + #include "virtio.h" +diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target +index f60f94b090..90964a2ccb 100644 +--- a/tests/tcg/s390x/Makefile.softmmu-target ++++ b/tests/tcg/s390x/Makefile.softmmu-target +@@ -2,7 +2,7 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x + VPATH+=$(S390X_SRC) + QEMU_OPTS+=-action panic=exit-failure -nographic $(EXTFLAGS) -kernel + LINK_SCRIPT=$(S390X_SRC)/softmmu.ld +-CFLAGS+=-ggdb -O0 ++CFLAGS+=-ggdb -O0 -I$(SRC_PATH)/include/hw/s390x/ipl/ + LDFLAGS=-nostdlib -static + + %.o: %.S +diff --git a/tests/tcg/s390x/console.c b/tests/tcg/s390x/console.c +index d43ce3f44b..6c26f04949 100644 +--- a/tests/tcg/s390x/console.c ++++ b/tests/tcg/s390x/console.c +@@ -4,7 +4,10 @@ + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ ++ + #include "../../../pc-bios/s390-ccw/sclp.c" ++#include "../../../roms/SLOF/lib/libc/string/memset.c" ++#include "../../../roms/SLOF/lib/libc/string/memcpy.c" + + void __sys_outc(char c) + { +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch b/SOURCES/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch new file mode 100644 index 0000000..137eec6 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch @@ -0,0 +1,72 @@ +From 77d5de6e13404df1cb5c3beb0e656ee328732457 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Thu, 16 Jan 2025 12:58:26 +0100 +Subject: [PATCH 4/4] pc-bios/s390-ccw/netmain: Fix error messages with regards + to the TFTP server +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 332: Fix boot problems when falling back from network to another boot device on s390x [RHEL9] +RH-Jira: RHEL-72716 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Jon Maloy +RH-Commit: [4/4] a4ce330588044d40b94da46905d1021e7610cbf6 (thuth/qemu-kvm-cs) + +The code in net_init_ip() currently bails out early if "rc" is less +than 0, so the if-statements that check for negative "rc" codes to +print out some specific error messages with regards to the TFTP server +are never reached. Move them earlier to bring that dead code back to +life. + +Reviewed-by: Jared Rossi +Reviewed-by: Eric Farman +Tested-by: Jared Rossi +Message-ID: <20250116115826.192047-4-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit bbfa7f8558d5346b6884108ad50df3517fe17358) +--- + pc-bios/s390-ccw/netmain.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index 335ea9b63e..719a547ada 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -168,6 +168,14 @@ static int net_init_ip(filename_ip_t *fn_ip) + if (fn_ip->ip_version == 4) { + set_ipv4_address(fn_ip->own_ip); + } ++ } else if (rc == -2) { ++ printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n", ++ (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF, ++ (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); ++ return -102; ++ } else if (rc == -4 || rc == -3) { ++ puts("Can't obtain TFTP server IP address"); ++ return -107; + } else { + puts("Could not get IP address"); + return -101; +@@ -183,17 +191,6 @@ static int net_init_ip(filename_ip_t *fn_ip) + printf(" Using IPv6 address: %s\n", ip6_str); + } + +- if (rc == -2) { +- printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n", +- (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF, +- (fn_ip->server_ip >> 8) & 0xFF, fn_ip->server_ip & 0xFF); +- return -102; +- } +- if (rc == -4 || rc == -3) { +- puts("Can't obtain TFTP server IP address"); +- return -107; +- } +- + printf(" Using TFTP server: "); + if (fn_ip->ip_version == 4) { + printf("%d.%d.%d.%d\n", +-- +2.48.0 + diff --git a/SOURCES/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch b/SOURCES/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch new file mode 100644 index 0000000..7a511b0 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch @@ -0,0 +1,70 @@ +From ede25f511ad49a8a7cc2d18a613775c1f706cf36 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Thu, 16 Jan 2025 12:58:24 +0100 +Subject: [PATCH 2/4] pc-bios/s390-ccw/virtio: Add a function to reset a virtio + device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 332: Fix boot problems when falling back from network to another boot device on s390x [RHEL9] +RH-Jira: RHEL-72716 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Jon Maloy +RH-Commit: [2/4] 99a826ae269ca45cf3092c75c45eaf2f8704576a (thuth/qemu-kvm-cs) + +To be able to properly silence a virtio device after using it, +we need a global function to reset the device. + +Reviewed-by: Jared Rossi +Reviewed-by: Eric Farman +Tested-by: Jared Rossi +Message-ID: <20250116115826.192047-2-thuth@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 3936d0556383829b8db9518aed8badfed6513953) +--- + pc-bios/s390-ccw/virtio.c | 7 ++++++- + pc-bios/s390-ccw/virtio.h | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c +index 8b5a370bb3..cd6c99c7e3 100644 +--- a/pc-bios/s390-ccw/virtio.c ++++ b/pc-bios/s390-ccw/virtio.c +@@ -217,6 +217,11 @@ int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd) + return 0; + } + ++int virtio_reset(VDev *vdev) ++{ ++ return run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); ++} ++ + int virtio_setup_ccw(VDev *vdev) + { + int i, cfg_size = 0; +@@ -235,7 +240,7 @@ int virtio_setup_ccw(VDev *vdev) + vdev->config.blk.blk_size = 0; /* mark "illegal" - setup started... */ + vdev->guessed_disk_nature = VIRTIO_GDN_NONE; + +- run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0, false); ++ virtio_reset(vdev); + + status = VIRTIO_CONFIG_S_ACKNOWLEDGE; + if (run_ccw(vdev, CCW_CMD_WRITE_STATUS, &status, sizeof(status), false)) { +diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h +index 9faf3986b1..f13fa6f5fe 100644 +--- a/pc-bios/s390-ccw/virtio.h ++++ b/pc-bios/s390-ccw/virtio.h +@@ -274,6 +274,7 @@ void vring_send_buf(VRing *vr, void *p, int len, int flags); + int vr_poll(VRing *vr); + int vring_wait_reply(void); + int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); ++int virtio_reset(VDev *vdev); + int virtio_setup_ccw(VDev *vdev); + + int virtio_net_init(void *mac_addr); +-- +2.48.0 + diff --git a/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch b/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch new file mode 100644 index 0000000..80006bf --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch @@ -0,0 +1,227 @@ +From 4fcfb2ccd90ffc1e0b121b3e5dbab1cdcba8ce4e Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:51 -0400 +Subject: [PATCH 18/27] pc-bios/s390x: Enable multi-device boot loop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [18/23] 2aa3154bfb1c73a6054b1161ae284925e6069c48 (thuth/qemu-kvm-cs9) + +Allow attempts to boot from multiple IPL devices. If the first device fails to +IPL, select the pre-built IPLB for the next device in the boot order and attempt +to IPL from it. Continue this process until IPL is successful or there are no +devices left to try. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-18-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit f697bed22f58eff9b2893ac2fe3d511847398400) +--- + pc-bios/s390-ccw/iplb.h | 24 ++++++++++++++++++++ + pc-bios/s390-ccw/jump2ipl.c | 7 +++--- + pc-bios/s390-ccw/main.c | 45 +++++++++++++++++++++++-------------- + pc-bios/s390-ccw/netmain.c | 2 +- + 4 files changed, 57 insertions(+), 21 deletions(-) + +diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h +index 16643f5879..08f259ff31 100644 +--- a/pc-bios/s390-ccw/iplb.h ++++ b/pc-bios/s390-ccw/iplb.h +@@ -17,9 +17,11 @@ + #endif + + #include ++#include + + extern QemuIplParameters qipl; + extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); ++extern bool have_iplb; + + #define S390_IPL_TYPE_FCP 0x00 + #define S390_IPL_TYPE_CCW 0x02 +@@ -49,4 +51,26 @@ static inline bool set_iplb(IplParameterBlock *iplb) + return manage_iplb(iplb, false); + } + ++/* ++ * The IPL started on the device, but failed in some way. If the IPLB chain ++ * still has more devices left to try, use the next device in order. ++ */ ++static inline bool load_next_iplb(void) ++{ ++ IplParameterBlock *next_iplb; ++ ++ if (qipl.chain_len < 1) { ++ return false; ++ } ++ ++ qipl.index++; ++ next_iplb = (IplParameterBlock *) qipl.next_iplb; ++ memcpy(&iplb, next_iplb, sizeof(IplParameterBlock)); ++ ++ qipl.chain_len--; ++ qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock); ++ ++ return true; ++} ++ + #endif /* IPLB_H */ +diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c +index 99d18947d1..86321d0f46 100644 +--- a/pc-bios/s390-ccw/jump2ipl.c ++++ b/pc-bios/s390-ccw/jump2ipl.c +@@ -45,9 +45,10 @@ int jump_to_IPL_code(uint64_t address) + */ + if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { + iplb.devno = qipl.index; +- if (!set_iplb(&iplb)) { +- panic("Failed to set IPLB"); +- } ++ } ++ ++ if (have_iplb && !set_iplb(&iplb)) { ++ panic("Failed to set IPLB"); + } + + /* +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index ab4709e16e..a4d1c05aac 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -23,7 +23,7 @@ static SubChannelId blk_schid = { .one = 1 }; + static char loadparm_str[LOADPARM_LEN + 1]; + QemuIplParameters qipl; + IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); +-static bool have_iplb; ++bool have_iplb; + static uint16_t cutype; + LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */ + +@@ -55,6 +55,12 @@ void write_iplb_location(void) + } + } + ++static void copy_qipl(void) ++{ ++ QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; ++ memcpy(&qipl, early_qipl, sizeof(QemuIplParameters)); ++} ++ + unsigned int get_loadparm_index(void) + { + return atoi(loadparm_str); +@@ -152,6 +158,7 @@ static void menu_setup(void) + + /* If loadparm was set to any other value, then do not enable menu */ + if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) { ++ menu_set_parms(qipl.qipl_flags & ~BOOT_MENU_FLAG_MASK, 0); + return; + } + +@@ -183,7 +190,6 @@ static void css_setup(void) + static void boot_setup(void) + { + char lpmsg[] = "LOADPARM=[________]\n"; +- have_iplb = store_iplb(&iplb); + + if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { + ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); +@@ -191,6 +197,10 @@ static void boot_setup(void) + sclp_get_loadparm_ascii(loadparm_str); + } + ++ if (have_iplb) { ++ menu_setup(); ++ } ++ + memcpy(lpmsg + 10, loadparm_str, 8); + puts(lpmsg); + +@@ -208,6 +218,7 @@ static bool find_boot_device(void) + + switch (iplb.pbt) { + case S390_IPL_TYPE_CCW: ++ vdev->scsi_device_selected = false; + debug_print_int("device no. ", iplb.ccw.devno); + blk_schid.ssid = iplb.ccw.ssid & 0x3; + debug_print_int("ssid ", blk_schid.ssid); +@@ -231,15 +242,8 @@ static bool find_boot_device(void) + static int virtio_setup(void) + { + VDev *vdev = virtio_get_device(); +- QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS; + int ret; + +- memcpy(&qipl, early_qipl, sizeof(QemuIplParameters)); +- +- if (have_iplb) { +- menu_setup(); +- } +- + switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: + puts("Network boot device detected"); +@@ -271,10 +275,9 @@ static void ipl_boot_device(void) + dasd_ipl(blk_schid, cutype); + break; + case CU_TYPE_VIRTIO: +- if (virtio_setup()) { +- return; /* Only returns in case of errors */ ++ if (virtio_setup() == 0) { ++ zipl_load(); + } +- zipl_load(); + break; + default: + printf("Attempting to boot from unexpected device type 0x%X\n", cutype); +@@ -307,14 +310,22 @@ static void probe_boot_device(void) + + void main(void) + { ++ copy_qipl(); + sclp_setup(); + css_setup(); +- boot_setup(); +- if (have_iplb && find_boot_device()) { +- ipl_boot_device(); +- } else { ++ have_iplb = store_iplb(&iplb); ++ if (!have_iplb) { + probe_boot_device(); + } + +- panic("Failed to IPL. Halting..."); ++ while (have_iplb) { ++ boot_setup(); ++ if (have_iplb && find_boot_device()) { ++ ipl_boot_device(); ++ } ++ have_iplb = load_next_iplb(); ++ } ++ ++ panic("No suitable device for IPL. Halting..."); ++ + } +diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c +index d1a6c9a91c..e46e470db4 100644 +--- a/pc-bios/s390-ccw/netmain.c ++++ b/pc-bios/s390-ccw/netmain.c +@@ -478,7 +478,7 @@ static bool virtio_setup(void) + */ + enable_mss_facility(); + +- if (store_iplb(&iplb)) { ++ if (have_iplb || store_iplb(&iplb)) { + IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected"); + dev_no = iplb.ccw.devno; + debug_print_int("device no. ", dev_no); +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch b/SOURCES/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch new file mode 100644 index 0000000..ebf1a48 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch @@ -0,0 +1,43 @@ +From 32ddd9e68b04cb231fa0adcaeacbbe6373a1972f Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Fri, 8 Nov 2024 14:41:36 -0500 +Subject: [PATCH 07/10] pc-bios/s390x: Initialize cdrom type to false for each + IPL device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/8] 994d24c3292a38f5bc7fd87d7227e5beb8abc30b (thuth/qemu-kvm-cs9) + +Clear information about cdrom type so that current IPL device isn't tainted +by stale data from previous devices. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241108194136.2833932-1-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 8c797468116d19940fb758efa749eae414616e3a) +--- + pc-bios/s390-ccw/main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index a4d1c05aac..7509755e36 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -242,6 +242,7 @@ static bool find_boot_device(void) + static int virtio_setup(void) + { + VDev *vdev = virtio_get_device(); ++ vdev->is_cdrom = false; + int ret; + + switch (vdev->senseid.cu_model) { +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch b/SOURCES/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch new file mode 100644 index 0000000..f0764e6 --- /dev/null +++ b/SOURCES/kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch @@ -0,0 +1,55 @@ +From d5fd6b575f36c09bb6ef11d3e1e4e698577637c3 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Thu, 14 Nov 2024 11:19:52 -0500 +Subject: [PATCH 08/10] pc-bios/s390x: Initialize machine loadparm before + probing IPL devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/8] 5f9bca4a83d6a1bde08504d2655f486708765e6e (thuth/qemu-kvm-cs9) + +Commit bb185de423 ("s390x: Add individual loadparm assignment to +CCW device") allowed boot devices to be assigned a loadparm value independent +of the machine value, however, when no boot devices are defined, the machine +loadparm becomes ignored. Therefore, let's check the machine loadparm +prior to probing the devices. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241114161952.3508554-1-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 1056ca1e70dc6e0458238141bcebfb7810cede6d) +--- + pc-bios/s390-ccw/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index 7509755e36..76bf743900 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -191,7 +191,7 @@ static void boot_setup(void) + { + char lpmsg[] = "LOADPARM=[________]\n"; + +- if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { ++ if (have_iplb && memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { + ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); + } else { + sclp_get_loadparm_ascii(loadparm_str); +@@ -316,6 +316,7 @@ void main(void) + css_setup(); + have_iplb = store_iplb(&iplb); + if (!have_iplb) { ++ boot_setup(); + probe_boot_device(); + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch b/SOURCES/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch new file mode 100644 index 0000000..32064ea --- /dev/null +++ b/SOURCES/kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch @@ -0,0 +1,75 @@ +From d06f8670b9304c66d45e2270a4f5b462ed6cbe09 Mon Sep 17 00:00:00 2001 +From: Ani Sinha +Date: Wed, 16 Oct 2024 17:21:34 +0530 +Subject: [PATCH 1/9] pc: q35: Bump max_cpus to 4096 vcpus +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Ani Sinha +RH-MergeRequest: 273: pc: q35: Bump max_cpus to 4096 vcpus +RH-Jira: RHEL-11043 +RH-Acked-by: Igor Mammedov +RH-Acked-by: Daniel P. Berrangé +RH-Acked-by: MST +RH-Commit: [1/1] 23caa8c9e4f34c3114701b7a5bb25002a9372b2e (anisinha/centos-qemu-kvm) + +This is the downstream change equivalent of the upstream QEMU commit +e4e98c7e ("pc: q35: Bump max_cpus to 4096 vcpus") + +Since upstream Linux kernel commit +f10a570b093e6 ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs") +Linux kernel can support upto a maximum number of 4096 vcpus when MAXSMP is +enabled in the kernel. This upstream change has been backported to c9s kernel +already. Please see JIRA https://issues.redhat.com/browse/RHEL-11579 and the +following commit authored by Vitaly Kuznetsov: +a85f846be686b0a ("KVM: x86: Add CONFIG_KVM_MAX_NR_VCPUS to allow up to 4096 vCPUs") + +At present, QEMU has been tested to correctly boot a linux guest with 4096 +vcpus using edk2 that has the fixes corresponding to the following two upstream +edk2 PRs: + +https://github.com/tianocore/edk2/pull/5410 +https://github.com/tianocore/edk2/pull/5418 + +The changes corresponding to the above two upstream edk2 PRs has been included +in the downstream c9s edk2 with the following MR: +https://gitlab.com/redhat/centos-stream/src/edk2/-/merge_requests/59 + +So bump up the value max_cpus to 4096 for RHEL q35 machines versions 9.6 and +newer. Q35 RHEL machines versions 9.4 and older continue to support 710 maximum +vcpus as before for compatibility reasons. + +See also https://gitlab.com/redhat/centos-stream/src/qemu-kvm/-/merge_requests/236 + +Signed-off-by: Ani Sinha +--- + hw/i386/pc_q35.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 7606007bda..578f63524f 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -344,7 +344,7 @@ static void pc_q35_machine_options(MachineClass *m) + m->default_display = "std"; + m->default_nic = "e1000e"; + m->no_floppy = 1; +- m->max_cpus = 710; ++ m->max_cpus = 4096; + m->no_parallel = 1; + machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); + machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); +@@ -687,6 +687,9 @@ static void pc_q35_rhel_machine_9_4_0_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + pc_q35_rhel_machine_9_6_0_options(m); ++ ++ /* older RHEL machines continue to support 710 vcpus */ ++ m->max_cpus = 710; + m->desc = "RHEL-9.4.0 PC (Q35 + ICH9, 2009)"; + m->alias = NULL; + pcmc->smbios_stream_product = "RHEL"; +-- +2.39.3 + diff --git a/SOURCES/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch b/SOURCES/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch new file mode 100644 index 0000000..e5fe2c7 --- /dev/null +++ b/SOURCES/kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch @@ -0,0 +1,76 @@ +From 8a9811c6442d2d836d7483e3b4af969df43b1781 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Tue, 3 Dec 2024 13:19:28 +0100 +Subject: [PATCH] pci: ensure valid link status bits for downstream ports + +RH-Author: Sebastian Ott +RH-MergeRequest: 329: pci: ensure valid link status bits for downstream ports +RH-Jira: RHEL-65616 +RH-Acked-by: Eric Auger +RH-Acked-by: Gavin Shan +RH-Acked-by: Shaoqin Huang +RH-Acked-by: Cornelia Huck +RH-Commit: [1/1] 93a557766cbc12314e83cdf2c89b6ca9275f0c45 (seott1/cos-qemu-kvm) + +PCI hotplug for downstream endpoints on arm fails because Linux' +PCIe hotplug driver doesn't like the QEMU provided LNKSTA: + + pcieport 0000:08:01.0: pciehp: Slot(2): Card present + pcieport 0000:08:01.0: pciehp: Slot(2): Link Up + pcieport 0000:08:01.0: pciehp: Slot(2): Cannot train link: status 0x2000 + +There's 2 cases where LNKSTA isn't setup properly: +* the downstream device has no express capability +* max link width of the bridge is 0 + +Move the sanity checks added via 88c869198aa63 +("pci: Sanity test minimum downstream LNKSTA") outside of the +branch to make sure downstream ports always have a valid LNKSTA. + +Signed-off-by: Sebastian Ott +Tested-by: Zhenyu Zhang +Message-Id: <20241203121928.14861-1-sebott@redhat.com> +Reviewed-by: Alex Williamson +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 694632fd44987cc4618612a38ad151047524a590) +JIRA: https://issues.redhat.com/browse/RHEL-65616 +Signed-off-by: Sebastian Ott +--- + hw/pci/pcie.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c +index 4b2f0805c6..9cb137c30f 100644 +--- a/hw/pci/pcie.c ++++ b/hw/pci/pcie.c +@@ -1080,18 +1080,22 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev) + if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) { + lnksta &= ~PCI_EXP_LNKSTA_NLW; + lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW; +- } else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { +- lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); + } + + if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) { + lnksta &= ~PCI_EXP_LNKSTA_CLS; + lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS; +- } else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { +- lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); + } + } + ++ if (!(lnksta & PCI_EXP_LNKSTA_NLW)) { ++ lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1); ++ } ++ ++ if (!(lnksta & PCI_EXP_LNKSTA_CLS)) { ++ lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT); ++ } ++ + pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA, + PCI_EXP_LNKSTA_CLS | PCI_EXP_LNKSTA_NLW); + pci_word_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA, lnksta & +-- +2.48.0 + diff --git a/SOURCES/kvm-pci-host-q35-Move-PAM-initialization-above-SMRAM-ini.patch b/SOURCES/kvm-pci-host-q35-Move-PAM-initialization-above-SMRAM-ini.patch deleted file mode 100644 index 2c21dde..0000000 --- a/SOURCES/kvm-pci-host-q35-Move-PAM-initialization-above-SMRAM-ini.patch +++ /dev/null @@ -1,68 +0,0 @@ -From c0a65c752cd83dea27cbeb34074d65fb2c5a6b59 Mon Sep 17 00:00:00 2001 -From: Isaku Yamahata -Date: Wed, 20 Mar 2024 03:39:13 -0500 -Subject: [PATCH 008/100] pci-host/q35: Move PAM initialization above SMRAM - initialization - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [8/91] 22a9221d4726e872aa0f0dc25ae9d823c0611547 (bonzini/rhel-qemu-kvm) - -In mch_realize(), process PAM initialization before SMRAM initialization so -that later patch can skill all the SMRAM related with a single check. - -Signed-off-by: Isaku Yamahata -Signed-off-by: Xiaoyao Li -Signed-off-by: Michael Roth -Message-ID: <20240320083945.991426-18-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 42c11ae2416dcbcd694ec3ee574fe2f3e70099ae) -Signed-off-by: Paolo Bonzini ---- - hw/pci-host/q35.c | 19 ++++++++++--------- - 1 file changed, 10 insertions(+), 9 deletions(-) - -diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c -index 0d7d4e3f08..98d4a7c253 100644 ---- a/hw/pci-host/q35.c -+++ b/hw/pci-host/q35.c -@@ -568,6 +568,16 @@ static void mch_realize(PCIDevice *d, Error **errp) - /* setup pci memory mapping */ - pc_pci_as_mapping_init(mch->system_memory, mch->pci_address_space); - -+ /* PAM */ -+ init_pam(&mch->pam_regions[0], OBJECT(mch), mch->ram_memory, -+ mch->system_memory, mch->pci_address_space, -+ PAM_BIOS_BASE, PAM_BIOS_SIZE); -+ for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) { -+ init_pam(&mch->pam_regions[i + 1], OBJECT(mch), mch->ram_memory, -+ mch->system_memory, mch->pci_address_space, -+ PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); -+ } -+ - /* if *disabled* show SMRAM to all CPUs */ - memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", - mch->pci_address_space, MCH_HOST_BRIDGE_SMRAM_C_BASE, -@@ -634,15 +644,6 @@ static void mch_realize(PCIDevice *d, Error **errp) - - object_property_add_const_link(qdev_get_machine(), "smram", - OBJECT(&mch->smram)); -- -- init_pam(&mch->pam_regions[0], OBJECT(mch), mch->ram_memory, -- mch->system_memory, mch->pci_address_space, -- PAM_BIOS_BASE, PAM_BIOS_SIZE); -- for (i = 0; i < ARRAY_SIZE(mch->pam_regions) - 1; ++i) { -- init_pam(&mch->pam_regions[i + 1], OBJECT(mch), mch->ram_memory, -- mch->system_memory, mch->pci_address_space, -- PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); -- } - } - - uint64_t mch_mcfg_base(void) --- -2.39.3 - diff --git a/SOURCES/kvm-physmem-Introduce-ram_block_discard_guest_memfd_rang.patch b/SOURCES/kvm-physmem-Introduce-ram_block_discard_guest_memfd_rang.patch deleted file mode 100644 index 66e0423..0000000 --- a/SOURCES/kvm-physmem-Introduce-ram_block_discard_guest_memfd_rang.patch +++ /dev/null @@ -1,83 +0,0 @@ -From c70f6e7e3461e6562c0591079cc71068bf0f2ed8 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 20 Mar 2024 03:39:07 -0500 -Subject: [PATCH 033/100] physmem: Introduce - ram_block_discard_guest_memfd_range() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [33/91] b6169fa8d752d83977b18897be24f6ab9f3d3472 (bonzini/rhel-qemu-kvm) - -When memory page is converted from private to shared, the original -private memory is back'ed by guest_memfd. Introduce -ram_block_discard_guest_memfd_range() for discarding memory in -guest_memfd. - -Based on a patch by Isaku Yamahata . - -Signed-off-by: Xiaoyao Li -Reviewed-by: David Hildenbrand -Signed-off-by: Michael Roth -Message-ID: <20240320083945.991426-12-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit b2e9426c04fdd32d93a3a37db6b0c2e67c88c335) -Signed-off-by: Paolo Bonzini ---- - include/exec/cpu-common.h | 2 ++ - system/physmem.c | 23 +++++++++++++++++++++++ - 2 files changed, 25 insertions(+) - -diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h -index 6346df17ce..6d5318895a 100644 ---- a/include/exec/cpu-common.h -+++ b/include/exec/cpu-common.h -@@ -159,6 +159,8 @@ typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque); - - int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque); - int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length); -+int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start, -+ size_t length); - - #endif - -diff --git a/system/physmem.c b/system/physmem.c -index 5ebcf5be11..c3d04ca921 100644 ---- a/system/physmem.c -+++ b/system/physmem.c -@@ -3721,6 +3721,29 @@ err: - return ret; - } - -+int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start, -+ size_t length) -+{ -+ int ret = -1; -+ -+#ifdef CONFIG_FALLOCATE_PUNCH_HOLE -+ ret = fallocate(rb->guest_memfd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, -+ start, length); -+ -+ if (ret) { -+ ret = -errno; -+ error_report("%s: Failed to fallocate %s:%" PRIx64 " +%zx (%d)", -+ __func__, rb->idstr, start, length, ret); -+ } -+#else -+ ret = -ENOSYS; -+ error_report("%s: fallocate not available %s:%" PRIx64 " +%zx (%d)", -+ __func__, rb->idstr, start, length, ret); -+#endif -+ -+ return ret; -+} -+ - bool ramblock_is_pmem(RAMBlock *rb) - { - return rb->flags & RAM_PMEM; --- -2.39.3 - diff --git a/SOURCES/kvm-ppc-pef-switch-to-use-confidential_guest_kvm_init-re.patch b/SOURCES/kvm-ppc-pef-switch-to-use-confidential_guest_kvm_init-re.patch deleted file mode 100644 index 037442c..0000000 --- a/SOURCES/kvm-ppc-pef-switch-to-use-confidential_guest_kvm_init-re.patch +++ /dev/null @@ -1,140 +0,0 @@ -From cfb109b393e019398a52f66a5ff0e9581c841335 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 29 Feb 2024 01:00:37 -0500 -Subject: [PATCH 013/100] ppc/pef: switch to use - confidential_guest_kvm_init/reset() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [13/91] e25c498fc79a4c8e22ca41d9cbd06e40b4cf1f11 (bonzini/rhel-qemu-kvm) - -Use the unified interface to call confidential guest related kvm_init() -and kvm_reset(), to avoid exposing pef specific functions. - -As a bonus, pef.h goes away since there is no direct call from sPAPR -board code to PEF code anymore. - -Signed-off-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -(cherry picked from commit 00a238b1a845fd5f0acd771664c5e184a63ed9b6) -Signed-off-by: Paolo Bonzini ---- - hw/ppc/pef.c | 9 ++++++--- - hw/ppc/spapr.c | 10 +++++++--- - include/hw/ppc/pef.h | 17 ----------------- - 3 files changed, 13 insertions(+), 23 deletions(-) - delete mode 100644 include/hw/ppc/pef.h - -diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c -index d28ed3ba73..47553348b1 100644 ---- a/hw/ppc/pef.c -+++ b/hw/ppc/pef.c -@@ -15,7 +15,6 @@ - #include "sysemu/kvm.h" - #include "migration/blocker.h" - #include "exec/confidential-guest-support.h" --#include "hw/ppc/pef.h" - - #define TYPE_PEF_GUEST "pef-guest" - OBJECT_DECLARE_SIMPLE_TYPE(PefGuest, PEF_GUEST) -@@ -93,7 +92,7 @@ static int kvmppc_svm_off(Error **errp) - #endif - } - --int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+static int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) { - return 0; -@@ -107,7 +106,7 @@ int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - return kvmppc_svm_init(cgs, errp); - } - --int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp) -+static int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp) - { - if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) { - return 0; -@@ -131,6 +130,10 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest, - - static void pef_guest_class_init(ObjectClass *oc, void *data) - { -+ ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); -+ -+ klass->kvm_init = pef_kvm_init; -+ klass->kvm_reset = pef_kvm_reset; - } - - static void pef_guest_init(Object *obj) -diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index a258d81846..6f6f0fd790 100644 ---- a/hw/ppc/spapr.c -+++ b/hw/ppc/spapr.c -@@ -75,6 +75,7 @@ - #include "hw/virtio/vhost-scsi-common.h" - - #include "exec/ram_addr.h" -+#include "exec/confidential-guest-support.h" - #include "hw/usb.h" - #include "qemu/config-file.h" - #include "qemu/error-report.h" -@@ -87,7 +88,6 @@ - #include "hw/ppc/spapr_tpm_proxy.h" - #include "hw/ppc/spapr_nvdimm.h" - #include "hw/ppc/spapr_numa.h" --#include "hw/ppc/pef.h" - - #include "monitor/monitor.h" - -@@ -1715,7 +1715,9 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) - qemu_guest_getrandom_nofail(spapr->fdt_rng_seed, 32); - } - -- pef_kvm_reset(machine->cgs, &error_fatal); -+ if (machine->cgs) { -+ confidential_guest_kvm_reset(machine->cgs, &error_fatal); -+ } - spapr_caps_apply(spapr); - spapr_nested_reset(spapr); - if (spapr->svm_allowed) { -@@ -2844,7 +2846,9 @@ static void spapr_machine_init(MachineState *machine) - /* - * if Secure VM (PEF) support is configured, then initialize it - */ -- pef_kvm_init(machine->cgs, &error_fatal); -+ if (machine->cgs) { -+ confidential_guest_kvm_init(machine->cgs, &error_fatal); -+ } - - msi_nonbroken = true; - -diff --git a/include/hw/ppc/pef.h b/include/hw/ppc/pef.h -deleted file mode 100644 -index 707dbe524c..0000000000 ---- a/include/hw/ppc/pef.h -+++ /dev/null -@@ -1,17 +0,0 @@ --/* -- * PEF (Protected Execution Facility) for POWER support -- * -- * Copyright Red Hat. -- * -- * This work is licensed under the terms of the GNU GPL, version 2 or later. -- * See the COPYING file in the top-level directory. -- * -- */ -- --#ifndef HW_PPC_PEF_H --#define HW_PPC_PEF_H -- --int pef_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); --int pef_kvm_reset(ConfidentialGuestSupport *cgs, Error **errp); -- --#endif /* HW_PPC_PEF_H */ --- -2.39.3 - diff --git a/SOURCES/kvm-q35-Introduce-smm_ranges-property-for-q35-pci-host.patch b/SOURCES/kvm-q35-Introduce-smm_ranges-property-for-q35-pci-host.patch deleted file mode 100644 index c7f121b..0000000 --- a/SOURCES/kvm-q35-Introduce-smm_ranges-property-for-q35-pci-host.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 83bb32c25472b500738a54ac8f2ad0f5c496acf1 Mon Sep 17 00:00:00 2001 -From: Isaku Yamahata -Date: Wed, 20 Mar 2024 03:39:14 -0500 -Subject: [PATCH 009/100] q35: Introduce smm_ranges property for q35-pci-host - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [9/91] 931156772bfc2085e7241eecc56cf6eca3dac1fd (bonzini/rhel-qemu-kvm) - -Add a q35 property to check whether or not SMM ranges, e.g. SMRAM, TSEG, -etc... exist for the target platform. TDX doesn't support SMM and doesn't -play nice with QEMU modifying related guest memory ranges. - -Signed-off-by: Isaku Yamahata -Co-developed-by: Sean Christopherson -Signed-off-by: Sean Christopherson -Signed-off-by: Xiaoyao Li -Signed-off-by: Michael Roth -Message-ID: <20240320083945.991426-19-michael.roth@amd.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit b07bf7b73fd02d24a7baa64a580f4974b86bbc86) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc_q35.c | 2 ++ - hw/pci-host/q35.c | 42 +++++++++++++++++++++++++++------------ - include/hw/i386/pc.h | 1 + - include/hw/pci-host/q35.h | 1 + - 4 files changed, 33 insertions(+), 13 deletions(-) - -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 9adcdadce8..dedc86eec9 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -219,6 +219,8 @@ static void pc_q35_init(MachineState *machine) - x86ms->above_4g_mem_size, NULL); - object_property_set_bool(phb, PCI_HOST_BYPASS_IOMMU, - pcms->default_bus_bypass_iommu, NULL); -+ object_property_set_bool(phb, PCI_HOST_PROP_SMM_RANGES, -+ x86_machine_is_smm_enabled(x86ms), NULL); - sysbus_realize_and_unref(SYS_BUS_DEVICE(phb), &error_fatal); - - /* pci */ -diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c -index 98d4a7c253..0b6cbaed7e 100644 ---- a/hw/pci-host/q35.c -+++ b/hw/pci-host/q35.c -@@ -179,6 +179,8 @@ static Property q35_host_props[] = { - mch.below_4g_mem_size, 0), - DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost, - mch.above_4g_mem_size, 0), -+ DEFINE_PROP_BOOL(PCI_HOST_PROP_SMM_RANGES, Q35PCIHost, -+ mch.has_smm_ranges, true), - DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true), - DEFINE_PROP_END_OF_LIST(), - }; -@@ -214,6 +216,7 @@ static void q35_host_initfn(Object *obj) - /* mch's object_initialize resets the default value, set it again */ - qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE, - Q35_PCI_HOST_HOLE64_SIZE_DEFAULT); -+ - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32", - q35_host_get_pci_hole_start, - NULL, NULL, NULL); -@@ -476,6 +479,10 @@ static void mch_write_config(PCIDevice *d, - mch_update_pciexbar(mch); - } - -+ if (!mch->has_smm_ranges) { -+ return; -+ } -+ - if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM, - MCH_HOST_BRIDGE_SMRAM_SIZE)) { - mch_update_smram(mch); -@@ -494,10 +501,13 @@ static void mch_write_config(PCIDevice *d, - static void mch_update(MCHPCIState *mch) - { - mch_update_pciexbar(mch); -+ - mch_update_pam(mch); -- mch_update_smram(mch); -- mch_update_ext_tseg_mbytes(mch); -- mch_update_smbase_smram(mch); -+ if (mch->has_smm_ranges) { -+ mch_update_smram(mch); -+ mch_update_ext_tseg_mbytes(mch); -+ mch_update_smbase_smram(mch); -+ } - - /* - * pci hole goes from end-of-low-ram to io-apic. -@@ -538,18 +548,20 @@ static void mch_reset(DeviceState *qdev) - pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR, - MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT); - -- d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT; -- d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT; -- d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK; -- d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK; -+ if (mch->has_smm_ranges) { -+ d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT; -+ d->config[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_DEFAULT; -+ d->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK; -+ d->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK; - -- if (mch->ext_tseg_mbytes > 0) { -- pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES, -- MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY); -- } -+ if (mch->ext_tseg_mbytes > 0) { -+ pci_set_word(d->config + MCH_HOST_BRIDGE_EXT_TSEG_MBYTES, -+ MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY); -+ } - -- d->config[MCH_HOST_BRIDGE_F_SMBASE] = 0; -- d->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0xff; -+ d->config[MCH_HOST_BRIDGE_F_SMBASE] = 0; -+ d->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0xff; -+ } - - mch_update(mch); - } -@@ -578,6 +590,10 @@ static void mch_realize(PCIDevice *d, Error **errp) - PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); - } - -+ if (!mch->has_smm_ranges) { -+ return; -+ } -+ - /* if *disabled* show SMRAM to all CPUs */ - memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", - mch->pci_address_space, MCH_HOST_BRIDGE_SMRAM_C_BASE, -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 87420783ab..467e7fb52f 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -164,6 +164,7 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level); - #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" - #define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size" - #define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size" -+#define PCI_HOST_PROP_SMM_RANGES "smm-ranges" - - - void pc_pci_as_mapping_init(MemoryRegion *system_memory, -diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h -index bafcbe6752..22fadfa3ed 100644 ---- a/include/hw/pci-host/q35.h -+++ b/include/hw/pci-host/q35.h -@@ -50,6 +50,7 @@ struct MCHPCIState { - MemoryRegion tseg_blackhole, tseg_window; - MemoryRegion smbase_blackhole, smbase_window; - bool has_smram_at_smbase; -+ bool has_smm_ranges; - Range pci_hole; - uint64_t below_4g_mem_size; - uint64_t above_4g_mem_size; --- -2.39.3 - diff --git a/SOURCES/kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch b/SOURCES/kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch deleted file mode 100644 index 00cdae0..0000000 --- a/SOURCES/kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 97739ee2ed20856fe395248d399dfc7f9ab4f33d Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Thu, 11 Apr 2024 15:06:01 +0200 -Subject: [PATCH 1/4] qcow2: Don't open data_file with BDRV_O_NO_IO - -RH-Author: Hana Czenczek -RH-MergeRequest: 1: CVE 2024-4467 (PRDSC) -RH-Jira: RHEL-35611 -RH-CVE: CVE-2024-4467 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Eric Blake -RH-Commit: [1/4] f9843ce5c519901654a7d8ba43ee95ce25ca13c2 - -One use case for 'qemu-img info' is verifying that untrusted images -don't reference an unwanted external file, be it as a backing file or an -external data file. To make sure that calling 'qemu-img info' can't -already have undesired side effects with a malicious image, just don't -open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do -I/O, we don't need to have it open. - -This changes the output of iotests case 061, which used 'qemu-img info' -to show that opening an image with an invalid data file fails. After -this patch, it succeeds. Replace this part of the test with a qemu-io -call, but keep the final 'qemu-img info' to show that the invalid data -file is correctly displayed in the output. - -Signed-off-by: Kevin Wolf -Reviewed-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Hanna Czenczek -Upstream: N/A, embargoed -Signed-off-by: Hanna Czenczek ---- - block/qcow2.c | 17 ++++++++++++++++- - tests/qemu-iotests/061 | 6 ++++-- - tests/qemu-iotests/061.out | 8 ++++++-- - 3 files changed, 26 insertions(+), 5 deletions(-) - -diff --git a/block/qcow2.c b/block/qcow2.c -index 0ebd455dc8..a4cffb628c 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -1642,7 +1642,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, - goto fail; - } - -- if (open_data_file) { -+ if (open_data_file && (flags & BDRV_O_NO_IO)) { -+ /* -+ * Don't open the data file for 'qemu-img info' so that it can be used -+ * to verify that an untrusted qcow2 image doesn't refer to external -+ * files. -+ * -+ * Note: This still makes has_data_file() return true. -+ */ -+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { -+ s->data_file = NULL; -+ } else { -+ s->data_file = bs->file; -+ } -+ qdict_extract_subqdict(options, NULL, "data-file."); -+ qdict_del(options, "data-file"); -+ } else if (open_data_file) { - /* Open external data file */ - bdrv_graph_co_rdunlock(); - s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs, -diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 -index 53c7d428e3..b71ac097d1 100755 ---- a/tests/qemu-iotests/061 -+++ b/tests/qemu-iotests/061 -@@ -326,12 +326,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" - echo - _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M - $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" --_img_info --format-specific -+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt -+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io - TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts - - echo - $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" --_img_info --format-specific -+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt -+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io - TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts - - echo -diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out -index 139fc68177..24c33add7c 100644 ---- a/tests/qemu-iotests/061.out -+++ b/tests/qemu-iotests/061.out -@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 - qemu-img: data-file can only be set for images that use an external data file - - Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data --qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory -+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - image: TEST_DIR/t.IMGFMT - file format: IMGFMT - virtual size: 64 MiB (67108864 bytes) -@@ -560,7 +562,9 @@ Format specific information: - corrupt: false - extended l2: false - --qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image -+qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image -+read 4096/4096 bytes at offset 0 -+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) - image: TEST_DIR/t.IMGFMT - file format: IMGFMT - virtual size: 64 MiB (67108864 bytes) --- -2.39.3 - diff --git a/SOURCES/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch b/SOURCES/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch new file mode 100644 index 0000000..1339593 --- /dev/null +++ b/SOURCES/kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch @@ -0,0 +1,128 @@ +From dbd3404564697435456f654f297a6ad4a6a7a351 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 19 Nov 2024 13:03:53 +0100 +Subject: [PATCH 1/4] qdev: Fix set_pci_devfn() to visit option only once + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 316: qdev-monitor: avoid QemuOpts in QMP device_add +RH-Jira: RHEL-39948 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Czenczek +RH-Commit: [1/4] 03b399f0fb3aff073206bb5280da41ce4f4ea251 (stefanha/centos-stream-qemu-kvm) + +pci_devfn properties accept either a string or an integer as input. To +implement this, set_pci_devfn() first tries to visit the option as a +string, and if that fails, it visits it as an integer instead. While the +QemuOpts visitor happens to accept this, it is invalid according to the +visitor interface. QObject input visitors run into an assertion failure +when this is done. + +QObject input visitors are used with the JSON syntax version of -device +on the command line: + +$ ./qemu-system-x86_64 -enable-kvm -M q35 -device pcie-pci-bridge,id=pci.1,bus=pcie.0 -blockdev null-co,node-name=disk -device '{ "driver": "virtio-blk-pci", "drive": "disk", "id": "virtio-disk0", "bus": "pci.1", "addr": 1 }' +qemu-system-x86_64: ../qapi/qobject-input-visitor.c:143: QObject *qobject_input_try_get_object(QObjectInputVisitor *, const char *, _Bool): Assertion `removed' failed. + +The proper way to accept both strings and integers is using the +alternate mechanism, which tells us the type of the input before it's +visited. With this information, we can directly visit it as the right +type. + +This fixes set_pci_devfn() by using the alternate mechanism. + +Cc: qemu-stable@nongnu.org +Reported-by: Peter Maydell +Signed-off-by: Kevin Wolf +Message-ID: <20241119120353.57812-1-kwolf@redhat.com> +Acked-by: Paolo Bonzini +Reviewed-by: Markus Armbruster +Signed-off-by: Kevin Wolf +(cherry picked from commit 5102f9df4a9a7adfbd902f9515c3f8f53dba288e) +Signed-off-by: Stefan Hajnoczi +--- + hw/core/qdev-properties-system.c | 54 +++++++++++++++++++++----------- + 1 file changed, 36 insertions(+), 18 deletions(-) + +diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c +index 5cd527cdba..b182dc293a 100644 +--- a/hw/core/qdev-properties-system.c ++++ b/hw/core/qdev-properties-system.c +@@ -820,39 +820,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) + { + Property *prop = opaque; ++ g_autofree GenericAlternate *alt; + int32_t value, *ptr = object_field_prop_ptr(obj, prop); + unsigned int slot, fn, n; +- char *str; ++ g_autofree char *str = NULL; ++ ++ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) { ++ return; ++ } ++ ++ switch (alt->type) { ++ case QTYPE_QSTRING: ++ if (!visit_type_str(v, name, &str, errp)) { ++ goto out; ++ } + +- if (!visit_type_str(v, name, &str, NULL)) { ++ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { ++ fn = 0; ++ if (sscanf(str, "%x%n", &slot, &n) != 1) { ++ goto invalid; ++ } ++ } ++ if (str[n] != '\0' || fn > 7 || slot > 31) { ++ goto invalid; ++ } ++ *ptr = slot << 3 | fn; ++ break; ++ ++ case QTYPE_QNUM: + if (!visit_type_int32(v, name, &value, errp)) { +- return; ++ goto out; + } + if (value < -1 || value > 255) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + name ? name : "null", "a value between -1 and 255"); +- return; ++ goto out; + } + *ptr = value; +- return; +- } ++ break; + +- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) { +- fn = 0; +- if (sscanf(str, "%x%n", &slot, &n) != 1) { +- goto invalid; +- } +- } +- if (str[n] != '\0' || fn > 7 || slot > 31) { +- goto invalid; ++ default: ++ error_setg(errp, "Invalid parameter type for '%s', expected int or str", ++ name ? name : "null"); ++ goto out; + } +- *ptr = slot << 3 | fn; +- g_free(str); +- return; ++ ++ goto out; + + invalid: + error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str); +- g_free(str); ++out: ++ visit_end_alternate(v, (void **) &alt); + } + + static int print_pci_devfn(Object *obj, Property *prop, char *dest, +-- +2.39.3 + diff --git a/SOURCES/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch b/SOURCES/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch new file mode 100644 index 0000000..40d54f5 --- /dev/null +++ b/SOURCES/kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch @@ -0,0 +1,131 @@ +From 16596225b9a4c686f6c0b0f5400681f3eed599ca Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 27 Aug 2024 15:27:50 -0400 +Subject: [PATCH 3/4] qdev-monitor: avoid QemuOpts in QMP device_add +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 316: qdev-monitor: avoid QemuOpts in QMP device_add +RH-Jira: RHEL-39948 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Czenczek +RH-Commit: [3/4] 1f6efb07255700e00243d067b5468b6840270ed0 (stefanha/centos-stream-qemu-kvm) + +The QMP device_add monitor command converts the QDict arguments to +QemuOpts and then back again to QDict. This process only supports scalar +types. Device properties like virtio-blk-pci's iothread-vq-mapping (an +array of objects) are silently dropped by qemu_opts_from_qdict() during +the QemuOpts conversion even though QAPI is capable of validating them. +As a result, hotplugging virtio-blk-pci devices with the +iothread-vq-mapping property does not work as expected (the property is +ignored). + +Get rid of the QemuOpts conversion in qmp_device_add() and call +qdev_device_add_from_qdict() with from_json=true. Using the QMP +command's QDict arguments directly allows non-scalar properties. + +The HMP is also adjusted since qmp_device_add()'s now expects properly +typed JSON arguments and cannot be used from HMP anymore. Move the code +that was previously in qmp_device_add() (with QemuOpts conversion and +from_json=false) into hmp_device_add() so that its behavior is +unchanged. + +This patch changes the behavior of QMP device_add but not HMP +device_add. QMP clients that sent incorrectly typed device_add QMP +commands no longer work. This is a breaking change but clients should be +using the correct types already. See the netdev_add QAPIfication in +commit db2a380c8457 for similar reasoning and object-add in commit +9151e59a8b6e. Unlike those commits, we continue to rely on 'gen': false +for the time being. + +Markus helped me figure this out and even provided a draft patch. The +code ended up very close to what he suggested. + +Suggested-by: Markus Armbruster +Cc: Daniel P. Berrangé +Signed-off-by: Stefan Hajnoczi +Message-ID: <20240827192751.948633-2-stefanha@redhat.com> +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit be93fd53723cbdca675bd9ed112dae5cabbe1e91) +Signed-off-by: Stefan Hajnoczi +--- + system/qdev-monitor.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c +index 6af6ef7d66..8b27cc42b0 100644 +--- a/system/qdev-monitor.c ++++ b/system/qdev-monitor.c +@@ -849,18 +849,9 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict) + + void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) + { +- QemuOpts *opts; + DeviceState *dev; + +- opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, errp); +- if (!opts) { +- return; +- } +- if (!monitor_cur_is_qmp() && qdev_device_help(opts)) { +- qemu_opts_del(opts); +- return; +- } +- dev = qdev_device_add(opts, errp); ++ dev = qdev_device_add_from_qdict(qdict, true, errp); + if (!dev) { + /* + * Drain all pending RCU callbacks. This is done because +@@ -872,9 +863,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) + * to the user + */ + drain_call_rcu(); +- +- qemu_opts_del(opts); +- return; + } + object_unref(OBJECT(dev)); + } +@@ -967,8 +955,34 @@ void qmp_device_del(const char *id, Error **errp) + void hmp_device_add(Monitor *mon, const QDict *qdict) + { + Error *err = NULL; ++ QemuOpts *opts; ++ DeviceState *dev; + +- qmp_device_add((QDict *)qdict, NULL, &err); ++ opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &err); ++ if (!opts) { ++ goto out; ++ } ++ if (qdev_device_help(opts)) { ++ qemu_opts_del(opts); ++ return; ++ } ++ dev = qdev_device_add(opts, &err); ++ if (!dev) { ++ /* ++ * Drain all pending RCU callbacks. This is done because ++ * some bus related operations can delay a device removal ++ * (in this case this can happen if device is added and then ++ * removed due to a configuration error) ++ * to a RCU callback, but user might expect that this interface ++ * will finish its job completely once qmp command returns result ++ * to the user ++ */ ++ drain_call_rcu(); ++ ++ qemu_opts_del(opts); ++ } ++ object_unref(dev); ++out: + hmp_handle_error(mon, err); + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch b/SOURCES/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch new file mode 100644 index 0000000..9abce97 --- /dev/null +++ b/SOURCES/kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch @@ -0,0 +1,80 @@ +From 04cfa8cf613e924c40c457d8373763a650568813 Mon Sep 17 00:00:00 2001 +From: Dehan Meng +Date: Wed, 25 Dec 2024 16:37:44 +0800 +Subject: [PATCH 3/4] qemu-ga: Optimize freeze-hook script logic of logging + error + +RH-Author: 6-dehan +RH-MergeRequest: 323: qemu-ga: Optimize freeze-hook script logic of logging error +RH-Jira: RHEL-52278 +RH-Acked-by: Konstantin Kostiuk +RH-Acked-by: Yan Vugenfirer +RH-Commit: [1/1] 8ec4bf5d91ccd8f4b8a14c9dccfdc7a30db80834 (6-dehan/centos-qemu-kvm) + +Make sure the error log of fsfreeze hooks +when freeze/thaw/snapshot could be logged +to system logs if the default logfile of +qga can't be written or other situations + +Reviewed-by: Konstantin Kostiuk +Reviewed-by: Yan Vugenfirer +Signed-off-by: Dehan Meng +--- + scripts/qemu-guest-agent/fsfreeze-hook | 36 +++++++++++++++++++++++--- + 1 file changed, 32 insertions(+), 4 deletions(-) + +diff --git a/scripts/qemu-guest-agent/fsfreeze-hook b/scripts/qemu-guest-agent/fsfreeze-hook +index 70536ba3e3..d5d8d4daf8 100755 +--- a/scripts/qemu-guest-agent/fsfreeze-hook ++++ b/scripts/qemu-guest-agent/fsfreeze-hook +@@ -19,15 +19,43 @@ is_ignored_file() { + return 1 + } + ++USE_SYSLOG=0 ++# if log file is not writable, fallback to syslog ++[ ! -w "$LOGFILE" ] && USE_SYSLOG=1 ++# try to update log file and fallback to syslog if it fails ++touch "$LOGFILE" &>/dev/null || USE_SYSLOG=1 ++ ++# Ensure the log file is writable, fallback to syslog if not ++log_message() { ++ local message="$1" ++ if [ "$USE_SYSLOG" -eq 0 ]; then ++ printf "%s: %s\n" "$(date)" "$message" >>"$LOGFILE" ++ else ++ logger -t qemu-ga-freeze-hook "$message" ++ fi ++} ++ + # Iterate executables in directory "fsfreeze-hook.d" with the specified args + [ ! -d "$FSFREEZE_D" ] && exit 0 ++ + for file in "$FSFREEZE_D"/* ; do + is_ignored_file "$file" && continue + [ -x "$file" ] || continue +- printf "$(date): execute $file $@\n" >>$LOGFILE +- "$file" "$@" >>$LOGFILE 2>&1 +- STATUS=$? +- printf "$(date): $file finished with status=$STATUS\n" >>$LOGFILE ++ ++ log_message "Executing $file $@" ++ if [ "$USE_SYSLOG" -eq 0 ]; then ++ "$file" "$@" >>"$LOGFILE" 2>&1 ++ STATUS=$? ++ else ++ "$file" "$@" 2>&1 | logger -t qemu-ga-freeze-hook ++ STATUS=${PIPESTATUS[0]} ++ fi ++ ++ if [ $STATUS -ne 0 ]; then ++ log_message "Error: $file finished with status=$STATUS" ++ else ++ log_message "$file finished successfully" ++ fi + done + + exit 0 +-- +2.39.3 + diff --git a/SOURCES/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch b/SOURCES/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch new file mode 100644 index 0000000..8ea78b1 --- /dev/null +++ b/SOURCES/kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch @@ -0,0 +1,54 @@ +From adae9bf218efc9e43f24bda6989f09aa63141694 Mon Sep 17 00:00:00 2001 +From: Konstantin Kostiuk +Date: Mon, 16 Dec 2024 17:45:52 +0200 +Subject: [PATCH 4/4] qga: Add log to guest-fsfreeze-thaw command +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: 6-dehan +RH-MergeRequest: 324: qga: Add log to guest-fsfreeze-thaw command +RH-Jira: RHEL-56340 +RH-Acked-by: Konstantin Kostiuk +RH-Acked-by: Yan Vugenfirer +RH-Commit: [1/1] 794ed8728c0ecc0c9050c6d5380cc2f8d7bb7723 (6-dehan/centos-qemu-kvm) + +Signed-off-by: Konstantin Kostiuk +Reviewed-by: Daniel P. Berrangé +--- + qga/commands-posix.c | 2 ++ + qga/commands-win32.c | 3 +++ + 2 files changed, 5 insertions(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index c2bd0b4316..49e40f9127 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -806,8 +806,10 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp) + int ret; + + ret = qmp_guest_fsfreeze_do_thaw(errp); ++ + if (ret >= 0) { + ga_unset_frozen(ga_state); ++ slog("guest-fsthaw called"); + execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); + } else { + ret = 0; +diff --git a/qga/commands-win32.c b/qga/commands-win32.c +index 61b36da469..1aea6cd167 100644 +--- a/qga/commands-win32.c ++++ b/qga/commands-win32.c +@@ -1273,6 +1273,9 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp) + qga_vss_fsfreeze(&i, false, NULL, errp); + + ga_unset_frozen(ga_state); ++ ++ slog("guest-fsthaw called"); ++ + return i; + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-qga-skip-bind-mounts-in-fs-list.patch b/SOURCES/kvm-qga-skip-bind-mounts-in-fs-list.patch new file mode 100644 index 0000000..bd12189 --- /dev/null +++ b/SOURCES/kvm-qga-skip-bind-mounts-in-fs-list.patch @@ -0,0 +1,94 @@ +From 5f23535420c40755a2da63915b3c5a1c3eb185bd Mon Sep 17 00:00:00 2001 +From: Jean-Louis Dupond +Date: Wed, 2 Oct 2024 12:06:35 +0200 +Subject: [PATCH 17/19] qga: skip bind mounts in fs list + +RH-Author: Konstantin Kostiuk +RH-MergeRequest: 306: qga: skip bind mounts in fs list +RH-Jira: RHEL-71940 +RH-Acked-by: yvugenfi +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 02f3a54f06caec953351bfdd6b25b91986d822c9 (kkostiuk/redhat-centos-stream-src-qemu-kvm) + +The filesystem list in build_fs_mount_list should skip bind mounts. +This because we end up in locking situations when doing fsFreeze. Like +mentioned in [1] and [2]. + +Next to that, the build_fs_mount_list call did a fallback via +build_fs_mount_list_from_mtab if mountinfo did not exist. +There it skipped bind mounts, but this is broken for newer OS. +This as mounts does not return the path of the bind mount but the +underlying dev/partition, so S_ISDIR will never return true in +dev_major_minor call. + +This patch simply checks the existing devmajor:devminor tuple in the +mounts, and if it already exists, this means we have the same devices +mounted again, a bind mount. So skip this. + +Same approach is used in open-vm-tools [3]. + +[1]: https://gitlab.com/qemu-project/qemu/-/issues/592 +[2]: https://gitlab.com/qemu-project/qemu/-/issues/520 +[3]: https://github.com/vmware/open-vm-tools/commit/d58847b497e212737007958c945af1df22a8ab58 + +Signed-off-by: Jean-Louis Dupond +Reviewed-by: Konstantin Kostiuk +Link: https://lore.kernel.org/r/20241002100634.162499-2-jean-louis@dupond.be +Signed-off-by: Konstantin Kostiuk +--- + qga/commands-linux.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/qga/commands-linux.c b/qga/commands-linux.c +index 51d5e3d927..426b040ab8 100644 +--- a/qga/commands-linux.c ++++ b/qga/commands-linux.c +@@ -59,6 +59,22 @@ static int dev_major_minor(const char *devpath, + return -1; + } + ++/* ++ * Check if we already have the devmajor:devminor in the mounts ++ * If thats the case return true. ++ */ ++static bool dev_exists(FsMountList *mounts, unsigned int devmajor, unsigned int devminor) ++{ ++ FsMount *mount; ++ ++ QTAILQ_FOREACH(mount, mounts, next) { ++ if (mount->devmajor == devmajor && mount->devminor == devminor) { ++ return true; ++ } ++ } ++ return false; ++} ++ + static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) + { + struct mntent *ment; +@@ -89,6 +105,10 @@ static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) + /* Skip bind mounts */ + continue; + } ++ if (dev_exists(mounts, devmajor, devminor)) { ++ /* Skip already existing devices (bind mounts) */ ++ continue; ++ } + + mount = g_new0(FsMount, 1); + mount->dirname = g_strdup(ment->mnt_dir); +@@ -172,6 +192,11 @@ bool build_fs_mount_list(FsMountList *mounts, Error **errp) + } + } + ++ if (dev_exists(mounts, devmajor, devminor)) { ++ /* Skip already existing devices (bind mounts) */ ++ continue; ++ } ++ + mount = g_new0(FsMount, 1); + mount->dirname = g_strdup(line + dir_s); + mount->devtype = g_strdup(dash + type_s); +-- +2.39.3 + diff --git a/SOURCES/kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch b/SOURCES/kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch deleted file mode 100644 index c60570e..0000000 --- a/SOURCES/kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch +++ /dev/null @@ -1,129 +0,0 @@ -From fef17d3466deba9b4d581604de1c64c210d1a454 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Fri, 17 May 2024 21:50:14 -0500 -Subject: [PATCH 1/4] qio: Inherit follow_coroutine_ctx across TLS -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Eric Blake -RH-MergeRequest: 244: qio: Inherit follow_coroutine_ctx across TLS -RH-Jira: RHEL-33440 -RH-Acked-by: Kevin Wolf -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/2] 447b144638a1f032fa036838f5f1839628389fe5 (ebblake/centos-qemu-kvm) - -Since qemu 8.2, the combination of NBD + TLS + iothread crashes on an -assertion failure: - -qemu-kvm: ../io/channel.c:534: void qio_channel_restart_read(void *): Assertion `qemu_get_current_aio_context() == qemu_coroutine_get_aio_context(co)' failed. - -It turns out that when we removed AioContext locking, we did so by -having NBD tell its qio channels that it wanted to opt in to -qio_channel_set_follow_coroutine_ctx(); but while we opted in on the -main channel, we did not opt in on the TLS wrapper channel. -qemu-iotests has coverage of NBD+iothread and NBD+TLS, but apparently -no coverage of NBD+TLS+iothread, or we would have noticed this -regression sooner. (I'll add that in the next patch) - -But while we could manually opt in to the TLS channel in nbd/server.c -(a one-line change), it is more generic if all qio channels that wrap -other channels inherit the follow status, in the same way that they -inherit feature bits. - -CC: Stefan Hajnoczi -CC: Daniel P. Berrangé -CC: qemu-stable@nongnu.org -Fixes: https://issues.redhat.com/browse/RHEL-34786 -Fixes: 06e0f098 ("io: follow coroutine AioContext in qio_channel_yield()", v8.2.0) -Signed-off-by: Eric Blake -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Daniel P. Berrangé -Message-ID: <20240518025246.791593-5-eblake@redhat.com> -(cherry picked from commit 199e84de1c903ba5aa1f7256310bbc4a20dd930b) -Jira: https://issues.redhat.com/browse/RHEL-33440 -Signed-off-by: Eric Blake ---- - io/channel-tls.c | 26 +++++++++++++++----------- - io/channel-websock.c | 1 + - 2 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/io/channel-tls.c b/io/channel-tls.c -index 1d9c9c72bf..67b9700006 100644 ---- a/io/channel-tls.c -+++ b/io/channel-tls.c -@@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master, - const char *aclname, - Error **errp) - { -- QIOChannelTLS *ioc; -+ QIOChannelTLS *tioc; -+ QIOChannel *ioc; - -- ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); -+ tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); -+ ioc = QIO_CHANNEL(tioc); - -- ioc->master = master; -+ tioc->master = master; -+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; - if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { -- qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN); -+ qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); - } - object_ref(OBJECT(master)); - -- ioc->session = qcrypto_tls_session_new( -+ tioc->session = qcrypto_tls_session_new( - creds, - NULL, - aclname, - QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, - errp); -- if (!ioc->session) { -+ if (!tioc->session) { - goto error; - } - - qcrypto_tls_session_set_callbacks( -- ioc->session, -+ tioc->session, - qio_channel_tls_write_handler, - qio_channel_tls_read_handler, -- ioc); -+ tioc); - -- trace_qio_channel_tls_new_server(ioc, master, creds, aclname); -- return ioc; -+ trace_qio_channel_tls_new_server(tioc, master, creds, aclname); -+ return tioc; - - error: -- object_unref(OBJECT(ioc)); -+ object_unref(OBJECT(tioc)); - return NULL; - } - -@@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master, - ioc = QIO_CHANNEL(tioc); - - tioc->master = master; -+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; - if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { - qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); - } -diff --git a/io/channel-websock.c b/io/channel-websock.c -index a12acc27cf..de39f0d182 100644 ---- a/io/channel-websock.c -+++ b/io/channel-websock.c -@@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master) - ioc = QIO_CHANNEL(wioc); - - wioc->master = master; -+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; - if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { - qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); - } --- -2.39.3 - diff --git a/SOURCES/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch b/SOURCES/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch new file mode 100644 index 0000000..db8efd2 --- /dev/null +++ b/SOURCES/kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch @@ -0,0 +1,73 @@ +From a99282ca32a1fef256c1fc155ef4f43aed9e1e48 Mon Sep 17 00:00:00 2001 +From: Peter Xu +Date: Fri, 6 Dec 2024 18:08:34 -0500 +Subject: [PATCH 03/23] qmp/cont: Only activate disks if migration completed + +RH-Author: Kevin Wolf +RH-MergeRequest: 339: QMP command for block device reactivation after migration +RH-Jira: RHEL-54296 RHEL-78397 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [2/22] 942fea0b972c992c52e6a1c85172afe899e4e312 (kmwolf/centos-qemu-kvm) + +As the comment says, the activation of disks is for the case where +migration has completed, rather than when QEMU is still during +migration (RUN_STATE_INMIGRATE). + +Move the code over to reflect what the comment is describing. + +Cc: Kevin Wolf +Cc: Markus Armbruster +Signed-off-by: Peter Xu +Reviewed-by: Fabiano Rosas +Message-Id: <20241206230838.1111496-3-peterx@redhat.com> +Signed-off-by: Fabiano Rosas +(cherry picked from commit e4e5e89bbd8e731e86735d9d25b7b5f49e8f08b6) +Signed-off-by: Kevin Wolf +--- + monitor/qmp-cmds.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c +index f84a0dc523..76f21e8af3 100644 +--- a/monitor/qmp-cmds.c ++++ b/monitor/qmp-cmds.c +@@ -96,21 +96,23 @@ void qmp_cont(Error **errp) + } + } + +- /* Continuing after completed migration. Images have been inactivated to +- * allow the destination to take control. Need to get control back now. +- * +- * If there are no inactive block nodes (e.g. because the VM was just +- * paused rather than completing a migration), bdrv_inactivate_all() simply +- * doesn't do anything. */ +- bdrv_activate_all(&local_err); +- if (local_err) { +- error_propagate(errp, local_err); +- return; +- } +- + if (runstate_check(RUN_STATE_INMIGRATE)) { + autostart = 1; + } else { ++ /* ++ * Continuing after completed migration. Images have been ++ * inactivated to allow the destination to take control. Need to ++ * get control back now. ++ * ++ * If there are no inactive block nodes (e.g. because the VM was ++ * just paused rather than completing a migration), ++ * bdrv_inactivate_all() simply doesn't do anything. ++ */ ++ bdrv_activate_all(&local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } + vm_start(); + } + } +-- +2.48.1 + diff --git a/SOURCES/kvm-rhel-9.4.0-machine-type-compat-for-virtio-gpu-migrat.patch b/SOURCES/kvm-rhel-9.4.0-machine-type-compat-for-virtio-gpu-migrat.patch deleted file mode 100644 index c6948ae..0000000 --- a/SOURCES/kvm-rhel-9.4.0-machine-type-compat-for-virtio-gpu-migrat.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 97334815c4a7cf0911b30c1366bbe67e883c57dd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Wed, 5 Jun 2024 10:28:20 +0400 -Subject: [PATCH 4/4] rhel 9.4.0 machine type compat for virtio-gpu migration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Marc-André Lureau -RH-MergeRequest: 246: virtio-gpu: fix v2 migration -RH-Jira: RHEL-34621 -RH-Acked-by: Peter Xu -RH-Acked-by: Thomas Huth -RH-Commit: [2/2] 2a895d510453e83bb45dfb39b7751bcc2f309cc5 (marcandre.lureau-rh/qemu-kvm-centos) - -Signed-off-by: Marc-André Lureau ---- - hw/core/machine.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index cf1d7faaaf..92609aae27 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -310,6 +310,8 @@ GlobalProperty hw_compat_rhel_9_5[] = { - { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" }, - /* hw_compat_rhel_9_5 from hw_compat_8_2 */ - { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, -+ /* hw_compat_rhel_9_5 from hw_compat_8_2 */ -+ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, - }; - const size_t hw_compat_rhel_9_5_len = G_N_ELEMENTS(hw_compat_rhel_9_5); - --- -2.39.3 - diff --git a/SOURCES/kvm-runstate-skip-initial-CPU-reset-if-reset-is-not-actu.patch b/SOURCES/kvm-runstate-skip-initial-CPU-reset-if-reset-is-not-actu.patch deleted file mode 100644 index 4f757bf..0000000 --- a/SOURCES/kvm-runstate-skip-initial-CPU-reset-if-reset-is-not-actu.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 4c93bec108f7e3918a2ef91b51cec477ade38cc3 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 18 Mar 2024 17:45:56 -0400 -Subject: [PATCH 018/100] runstate: skip initial CPU reset if reset is not - actually possible -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [18/91] ced267fdaadbf2072c1897223522457a006e6c81 (bonzini/rhel-qemu-kvm) - -Right now, the system reset is concluded by a call to -cpu_synchronize_all_post_reset() in order to sync any changes -that the machine reset callback applied to the CPU state. - -However, for VMs with encrypted state such as SEV-ES guests (currently -the only case of guests with non-resettable CPUs) this cannot be done, -because guest state has already been finalized by machine-init-done notifiers. -cpu_synchronize_all_post_reset() does nothing on these guests, and actually -we would like to make it fail if called once guest has been encrypted. -So, assume that boards that support non-resettable CPUs do not touch -CPU state and that all such setup is done before, at the time of -cpu_synchronize_all_post_init(). - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Paolo Bonzini -(cherry picked from commit 08b2d15cdd0d3fbbe37ce23bf192b770db3a7539) -Signed-off-by: Paolo Bonzini ---- - system/runstate.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/system/runstate.c b/system/runstate.c -index d6ab860eca..cb4905a40f 100644 ---- a/system/runstate.c -+++ b/system/runstate.c -@@ -501,7 +501,20 @@ void qemu_system_reset(ShutdownCause reason) - default: - qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); - } -- cpu_synchronize_all_post_reset(); -+ -+ /* -+ * Some boards use the machine reset callback to point CPUs to the firmware -+ * entry point. Assume that this is not the case for boards that support -+ * non-resettable CPUs (currently used only for confidential guests), in -+ * which case cpu_synchronize_all_post_init() is enough because -+ * it does _more_ than cpu_synchronize_all_post_reset(). -+ */ -+ if (cpus_are_resettable()) { -+ cpu_synchronize_all_post_reset(); -+ } else { -+ assert(runstate_check(RUN_STATE_PRELAUNCH)); -+ } -+ - vm_set_suspended(false); - } - --- -2.39.3 - diff --git a/SOURCES/kvm-s390-Switch-to-use-confidential_guest_kvm_init.patch b/SOURCES/kvm-s390-Switch-to-use-confidential_guest_kvm_init.patch deleted file mode 100644 index bc6e4e3..0000000 --- a/SOURCES/kvm-s390-Switch-to-use-confidential_guest_kvm_init.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 4ebc58d4a7a3d4a20f20f1cd3f21082b80097fe2 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 29 Feb 2024 01:00:38 -0500 -Subject: [PATCH 014/100] s390: Switch to use confidential_guest_kvm_init() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [14/91] 8c9e09ec9976c00b41c02868fff034286a341468 (bonzini/rhel-qemu-kvm) - -Use unified confidential_guest_kvm_init() for consistency with -other architectures. - -Signed-off-by: Xiaoyao Li -Message-Id: <20240229060038.606591-1-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit a14a2b0148e657cc526b7a75f2a1937628764e7a) -Signed-off-by: Paolo Bonzini ---- - hw/s390x/s390-virtio-ccw.c | 5 ++++- - target/s390x/kvm/pv.c | 10 +++++++++- - target/s390x/kvm/pv.h | 14 -------------- - 3 files changed, 13 insertions(+), 16 deletions(-) - -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 9ad54682c6..828ce6e87e 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -14,6 +14,7 @@ - #include "qemu/osdep.h" - #include "qapi/error.h" - #include "exec/ram_addr.h" -+#include "exec/confidential-guest-support.h" - #include "hw/s390x/s390-virtio-hcall.h" - #include "hw/s390x/sclp.h" - #include "hw/s390x/s390_flic.h" -@@ -260,7 +261,9 @@ static void ccw_init(MachineState *machine) - s390_init_cpus(machine); - - /* Need CPU model to be determined before we can set up PV */ -- s390_pv_init(machine->cgs, &error_fatal); -+ if (machine->cgs) { -+ confidential_guest_kvm_init(machine->cgs, &error_fatal); -+ } - - s390_flic_init(); - -diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c -index 7ca7faec73..dde836d21a 100644 ---- a/target/s390x/kvm/pv.c -+++ b/target/s390x/kvm/pv.c -@@ -334,12 +334,17 @@ static bool s390_pv_guest_check(ConfidentialGuestSupport *cgs, Error **errp) - return s390_pv_check_cpus(errp); - } - --int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) -+static int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - if (!object_dynamic_cast(OBJECT(cgs), TYPE_S390_PV_GUEST)) { - return 0; - } - -+ if (!kvm_enabled()) { -+ error_setg(errp, "Protected Virtualization requires KVM"); -+ return -1; -+ } -+ - if (!s390_has_feat(S390_FEAT_UNPACK)) { - error_setg(errp, - "CPU model does not support Protected Virtualization"); -@@ -364,6 +369,9 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest, - - static void s390_pv_guest_class_init(ObjectClass *oc, void *data) - { -+ ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); -+ -+ klass->kvm_init = s390_pv_kvm_init; - } - - static void s390_pv_guest_init(Object *obj) -diff --git a/target/s390x/kvm/pv.h b/target/s390x/kvm/pv.h -index 5877d28ff1..4b40817439 100644 ---- a/target/s390x/kvm/pv.h -+++ b/target/s390x/kvm/pv.h -@@ -80,18 +80,4 @@ static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len, - static inline int kvm_s390_dump_completion_data(void *buff) { return 0; } - #endif /* CONFIG_KVM */ - --int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); --static inline int s390_pv_init(ConfidentialGuestSupport *cgs, Error **errp) --{ -- if (!cgs) { -- return 0; -- } -- if (kvm_enabled()) { -- return s390_pv_kvm_init(cgs, errp); -- } -- -- error_setg(errp, "Protected Virtualization requires KVM"); -- return -1; --} -- - #endif /* HW_S390_PV_H */ --- -2.39.3 - diff --git a/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch b/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch new file mode 100644 index 0000000..3440acb --- /dev/null +++ b/SOURCES/kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch @@ -0,0 +1,362 @@ +From 20a4a01fde02a619cee994af92721592e7d91716 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:48 -0400 +Subject: [PATCH 15/27] s390x: Add individual loadparm assignment to CCW device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [15/23] c4eaab72e6246db7295593b86f097773aa4f49b7 (thuth/qemu-kvm-cs9) + +Add a loadparm property to the VirtioCcwDevice object so that different +loadparms can be defined on a per-device basis for CCW boot devices. + +The machine/global loadparm is still supported. If both a global and per-device +loadparm are defined, the per-device value will override the global value for +that device, but any other devices that do not specify a per-device loadparm +will still use the global loadparm. + +It is invalid to assign a loadparm to a non-boot device. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-15-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit bb185de42339025db9bbd5aa11f3f644c2a077f8) +--- + hw/s390x/ccw-device.c | 46 +++++++++++++++++++++++++ + hw/s390x/ccw-device.h | 2 ++ + hw/s390x/ipl.c | 68 ++++++++++++++++++++++--------------- + hw/s390x/ipl.h | 3 +- + hw/s390x/s390-virtio-ccw.c | 18 +--------- + hw/s390x/sclp.c | 9 ++--- + include/hw/s390x/ipl/qipl.h | 1 + + pc-bios/s390-ccw/main.c | 10 ++++-- + 8 files changed, 102 insertions(+), 55 deletions(-) + +diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c +index a7d682e5af..4e54f34b1c 100644 +--- a/hw/s390x/ccw-device.c ++++ b/hw/s390x/ccw-device.c +@@ -13,6 +13,10 @@ + #include "ccw-device.h" + #include "hw/qdev-properties.h" + #include "qemu/module.h" ++#include "ipl.h" ++#include "qapi/visitor.h" ++#include "qemu/ctype.h" ++#include "qapi/error.h" + + static void ccw_device_refill_ids(CcwDevice *dev) + { +@@ -37,10 +41,52 @@ static bool ccw_device_realize(CcwDevice *dev, Error **errp) + return true; + } + ++static void ccw_device_get_loadparm(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ CcwDevice *dev = CCW_DEVICE(obj); ++ char *str = g_strndup((char *) dev->loadparm, sizeof(dev->loadparm)); ++ ++ visit_type_str(v, name, &str, errp); ++ g_free(str); ++} ++ ++static void ccw_device_set_loadparm(Object *obj, Visitor *v, ++ const char *name, void *opaque, ++ Error **errp) ++{ ++ CcwDevice *dev = CCW_DEVICE(obj); ++ char *val; ++ int index; ++ ++ index = object_property_get_int(obj, "bootindex", NULL); ++ ++ if (index < 0) { ++ error_setg(errp, "LOADPARM is only valid for boot devices!"); ++ } ++ ++ if (!visit_type_str(v, name, &val, errp)) { ++ return; ++ } ++ ++ s390_ipl_fmt_loadparm(dev->loadparm, val, errp); ++} ++ ++static const PropertyInfo ccw_loadparm = { ++ .name = "ccw_loadparm", ++ .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass" ++ " to the guest loader/kernel", ++ .get = ccw_device_get_loadparm, ++ .set = ccw_device_set_loadparm, ++}; ++ + static Property ccw_device_properties[] = { + DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno), + DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id), + DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id), ++ DEFINE_PROP("loadparm", CcwDevice, loadparm, ccw_loadparm, ++ typeof(uint8_t[8])), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/s390x/ccw-device.h b/hw/s390x/ccw-device.h +index 5feeb0ee7a..1e1737c0f3 100644 +--- a/hw/s390x/ccw-device.h ++++ b/hw/s390x/ccw-device.h +@@ -26,6 +26,8 @@ struct CcwDevice { + CssDevId dev_id; + /* The actual busid of the virtual subchannel. */ + CssDevId subch_id; ++ /* If set, use this loadparm value when device is boot target */ ++ uint8_t loadparm[8]; + }; + typedef struct CcwDevice CcwDevice; + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index 8a0a3e6961..d83832d975 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -34,6 +34,7 @@ + #include "qemu/config-file.h" + #include "qemu/cutils.h" + #include "qemu/option.h" ++#include "qemu/ctype.h" + #include "standard-headers/linux/virtio_ids.h" + + #define KERN_IMAGE_START 0x010000UL +@@ -397,12 +398,43 @@ static CcwDevice *s390_get_ccw_device(DeviceState *dev_st, int *devtype) + return ccw_dev; + } + ++void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp) ++{ ++ int i; ++ ++ /* Initialize the loadparm with spaces */ ++ memset(loadparm, ' ', LOADPARM_LEN); ++ for (i = 0; i < LOADPARM_LEN && str[i]; i++) { ++ uint8_t c = qemu_toupper(str[i]); /* mimic HMC */ ++ ++ if (qemu_isalnum(c) || c == '.' || c == ' ') { ++ loadparm[i] = c; ++ } else { ++ error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)", ++ c, c); ++ return; ++ } ++ } ++} ++ ++void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) ++{ ++ int i; ++ ++ /* Initialize the loadparm with EBCDIC spaces (0x40) */ ++ memset(ebcdic_lp, '@', LOADPARM_LEN); ++ for (i = 0; i < LOADPARM_LEN && ascii_lp[i]; i++) { ++ ebcdic_lp[i] = ascii2ebcdic[(uint8_t) ascii_lp[i]]; ++ } ++} ++ + static bool s390_gen_initial_iplb(S390IPLState *ipl) + { + DeviceState *dev_st; + CcwDevice *ccw_dev = NULL; + SCSIDevice *sd; + int devtype; ++ uint8_t *lp; + + dev_st = get_boot_device(0); + if (dev_st) { +@@ -413,6 +445,8 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) + * Currently allow IPL only from CCW devices. + */ + if (ccw_dev) { ++ lp = ccw_dev->loadparm; ++ + switch (devtype) { + case CCW_DEVTYPE_SCSI: + sd = SCSI_DEVICE(dev_st); +@@ -445,40 +479,20 @@ static bool s390_gen_initial_iplb(S390IPLState *ipl) + break; + } + +- if (!s390_ipl_set_loadparm(ipl->iplb.loadparm)) { +- ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; ++ /* If the device loadparm is empty use the global machine loadparm */ ++ if (memcmp(lp, NO_LOADPARM, 8) == 0) { ++ lp = S390_CCW_MACHINE(qdev_get_machine())->loadparm; + } + ++ s390_ipl_convert_loadparm((char *)lp, ipl->iplb.loadparm); ++ ipl->iplb.flags |= DIAG308_FLAGS_LP_VALID; ++ + return true; + } + + return false; + } + +-int s390_ipl_set_loadparm(uint8_t *loadparm) +-{ +- MachineState *machine = MACHINE(qdev_get_machine()); +- char *lp = object_property_get_str(OBJECT(machine), "loadparm", NULL); +- +- if (lp) { +- int i; +- +- /* lp is an uppercase string without leading/embedded spaces */ +- for (i = 0; i < 8 && lp[i]; i++) { +- loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]]; +- } +- +- if (i < 8) { +- memset(loadparm + i, 0x40, 8 - i); /* fill with EBCDIC spaces */ +- } +- +- g_free(lp); +- return 0; +- } +- +- return -1; +-} +- + static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, + int virtio_id) + { +@@ -534,7 +548,7 @@ static void update_machine_ipl_properties(IplParameterBlock *iplb) + ascii_loadparm[i] = 0; + object_property_set_str(machine, "loadparm", ascii_loadparm, &err); + } else { +- object_property_set_str(machine, "loadparm", "", &err); ++ object_property_set_str(machine, "loadparm", " ", &err); + } + if (err) { + warn_report_err(err); +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index fa394c339d..b670bad551 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -21,7 +21,8 @@ + + #define DIAG308_FLAGS_LP_VALID 0x80 + +-int s390_ipl_set_loadparm(uint8_t *loadparm); ++void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); ++void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); + void s390_ipl_update_diag308(IplParameterBlock *iplb); + int s390_ipl_prepare_pv_header(Error **errp); + int s390_ipl_pv_unpack(void); +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 5113313aa8..ef2a9687c7 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -722,28 +722,12 @@ static void machine_set_loadparm(Object *obj, Visitor *v, + { + S390CcwMachineState *ms = S390_CCW_MACHINE(obj); + char *val; +- int i; + + if (!visit_type_str(v, name, &val, errp)) { + return; + } + +- for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) { +- uint8_t c = qemu_toupper(val[i]); /* mimic HMC */ +- +- if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') || +- (c == ' ')) { +- ms->loadparm[i] = c; +- } else { +- error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)", +- c, c); +- return; +- } +- } +- +- for (; i < sizeof(ms->loadparm); i++) { +- ms->loadparm[i] = ' '; /* pad right with spaces */ +- } ++ s390_ipl_fmt_loadparm(ms->loadparm, val, errp); + } + + static void ccw_machine_class_init(ObjectClass *oc, void *data) +diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c +index e725dcd5fd..8757626b5c 100644 +--- a/hw/s390x/sclp.c ++++ b/hw/s390x/sclp.c +@@ -110,7 +110,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) + MachineState *machine = MACHINE(qdev_get_machine()); + int cpu_count; + int rnsize, rnmax; +- IplParameterBlock *ipib = s390_ipl_get_iplb(); + int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len); + int offset_cpu = s390_has_feat(S390_FEAT_EXTENDED_LENGTH_SCCB) ? + offsetof(ReadInfo, entries) : +@@ -171,12 +170,8 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) + read_info->rnmax2 = cpu_to_be64(rnmax); + } + +- if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) { +- memcpy(&read_info->loadparm, &ipib->loadparm, +- sizeof(read_info->loadparm)); +- } else { +- s390_ipl_set_loadparm(read_info->loadparm); +- } ++ s390_ipl_convert_loadparm((char *)S390_CCW_MACHINE(machine)->loadparm, ++ read_info->loadparm); + + sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); + } +diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h +index 0ef04af027..b67d2ae061 100644 +--- a/include/hw/s390x/ipl/qipl.h ++++ b/include/hw/s390x/ipl/qipl.h +@@ -18,6 +18,7 @@ + + #define QIPL_ADDRESS 0xcc + #define LOADPARM_LEN 8 ++#define NO_LOADPARM "\0\0\0\0\0\0\0\0" + + /* + * The QEMU IPL Parameters will be stored at absolute address +diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c +index 34ef27d7a6..ab4709e16e 100644 +--- a/pc-bios/s390-ccw/main.c ++++ b/pc-bios/s390-ccw/main.c +@@ -183,8 +183,14 @@ static void css_setup(void) + static void boot_setup(void) + { + char lpmsg[] = "LOADPARM=[________]\n"; ++ have_iplb = store_iplb(&iplb); ++ ++ if (memcmp(iplb.loadparm, NO_LOADPARM, LOADPARM_LEN) != 0) { ++ ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN); ++ } else { ++ sclp_get_loadparm_ascii(loadparm_str); ++ } + +- sclp_get_loadparm_ascii(loadparm_str); + memcpy(lpmsg + 10, loadparm_str, 8); + puts(lpmsg); + +@@ -193,8 +199,6 @@ static void boot_setup(void) + * so we don't taint our decision-making process during a reboot. + */ + memset((char *)S390EP, 0, 6); +- +- have_iplb = store_iplb(&iplb); + } + + static bool find_boot_device(void) +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch b/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch new file mode 100644 index 0000000..059798a --- /dev/null +++ b/SOURCES/kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch @@ -0,0 +1,264 @@ +From 9d333e9e7614676aac3a39b0f4a5f5d67323b23d Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:50 -0400 +Subject: [PATCH 17/27] s390x: Rebuild IPLB for SCSI device directly from + DIAG308 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [17/23] d0326ad7958cc82496bf57fd09bbc877c5b8c0ac (thuth/qemu-kvm-cs9) + +Because virtio-scsi type devices use a non-architected IPLB pbt code they cannot +be set and stored normally. Instead, the IPLB must be rebuilt during re-ipl. + +As s390x does not natively support multiple boot devices, the devno field is +used to store the position in the boot order for the device. + +Handling the rebuild as part of DIAG308 removes the need to check the devices +for invalid IPLBs later in the IPL. + +Signed-off-by: Jared Rossi +Acked-by: Thomas Huth +Message-ID: <20241020012953.1380075-17-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 455e3bc3f74ee76964efec2e0c646db15095d0d2) +--- + hw/s390x/ipl.c | 74 ++++++------------------------------- + hw/s390x/ipl.h | 11 ++++-- + include/hw/s390x/ipl/qipl.h | 3 +- + pc-bios/s390-ccw/jump2ipl.c | 11 ++++-- + target/s390x/diag.c | 9 ++++- + 5 files changed, 38 insertions(+), 70 deletions(-) + +diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c +index f4576f8822..5fbd43c346 100644 +--- a/hw/s390x/ipl.c ++++ b/hw/s390x/ipl.c +@@ -448,7 +448,6 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp) + + static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + { +- S390IPLState *ipl = get_ipl_device(); + CcwDevice *ccw_dev = NULL; + SCSIDevice *sd; + int devtype; +@@ -481,9 +480,6 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + iplb->ccw.ssid = ccw_dev->sch->ssid & 3; + break; + case CCW_DEVTYPE_VIRTIO_NET: +- /* The S390IPLState netboot is true if ANY IPLB may use netboot */ +- ipl->netboot = true; +- /* Fall through to CCW_DEVTYPE_VIRTIO case */ + case CCW_DEVTYPE_VIRTIO: + iplb->len = cpu_to_be32(S390_IPLB_MIN_CCW_LEN); + iplb->blk0_len = +@@ -508,6 +504,16 @@ static bool s390_build_iplb(DeviceState *dev_st, IplParameterBlock *iplb) + return false; + } + ++void s390_rebuild_iplb(uint16_t dev_index, IplParameterBlock *iplb) ++{ ++ S390IPLState *ipl = get_ipl_device(); ++ uint16_t index; ++ index = ipl->rebuilt_iplb ? ipl->iplb_index : dev_index; ++ ++ ipl->rebuilt_iplb = s390_build_iplb(get_boot_device(index), iplb); ++ ipl->iplb_index = index; ++} ++ + static bool s390_init_all_iplbs(S390IPLState *ipl) + { + int iplb_num = 0; +@@ -564,44 +570,6 @@ static bool s390_init_all_iplbs(S390IPLState *ipl) + return iplb_num; + } + +-static bool is_virtio_ccw_device_of_type(IplParameterBlock *iplb, +- int virtio_id) +-{ +- uint8_t cssid; +- uint8_t ssid; +- uint16_t devno; +- uint16_t schid; +- SubchDev *sch = NULL; +- +- if (iplb->pbt != S390_IPL_TYPE_CCW) { +- return false; +- } +- +- devno = be16_to_cpu(iplb->ccw.devno); +- ssid = iplb->ccw.ssid & 3; +- +- for (schid = 0; schid < MAX_SCHID; schid++) { +- for (cssid = 0; cssid < MAX_CSSID; cssid++) { +- sch = css_find_subch(1, cssid, ssid, schid); +- +- if (sch && sch->devno == devno) { +- return sch->id.cu_model == virtio_id; +- } +- } +- } +- return false; +-} +- +-static bool is_virtio_net_device(IplParameterBlock *iplb) +-{ +- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_NET); +-} +- +-static bool is_virtio_scsi_device(IplParameterBlock *iplb) +-{ +- return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI); +-} +- + static void update_machine_ipl_properties(IplParameterBlock *iplb) + { + Object *machine = qdev_get_machine(); +@@ -641,7 +609,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb) + ipl->iplb = *iplb; + ipl->iplb_valid = true; + } +- ipl->netboot = is_virtio_net_device(iplb); ++ + update_machine_ipl_properties(iplb); + } + +@@ -668,32 +636,14 @@ IplParameterBlock *s390_ipl_get_iplb(void) + void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) + { + S390IPLState *ipl = get_ipl_device(); +- + if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) { + /* use CPU 0 for full resets */ + ipl->reset_cpu_index = 0; + } else { + ipl->reset_cpu_index = cs->cpu_index; + } +- ipl->reset_type = reset_type; + +- if (reset_type == S390_RESET_REIPL && +- ipl->iplb_valid && +- !ipl->netboot && +- ipl->iplb.pbt == S390_IPL_TYPE_CCW && +- is_virtio_scsi_device(&ipl->iplb)) { +- CcwDevice *ccw_dev = s390_get_ccw_device(get_boot_device(0), NULL); +- +- if (ccw_dev && +- cpu_to_be16(ccw_dev->sch->devno) == ipl->iplb.ccw.devno && +- (ccw_dev->sch->ssid & 3) == ipl->iplb.ccw.ssid) { +- /* +- * this is the original boot device's SCSI +- * so restore IPL parameter info from it +- */ +- ipl->iplb_valid = s390_build_iplb(get_boot_device(0), &ipl->iplb); +- } +- } ++ ipl->reset_type = reset_type; + if (reset_type == S390_RESET_MODIFIED_CLEAR || + reset_type == S390_RESET_LOAD_NORMAL || + reset_type == S390_RESET_PV) { +diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h +index 54eb48fd6e..d7d0b7bfd2 100644 +--- a/hw/s390x/ipl.h ++++ b/hw/s390x/ipl.h +@@ -24,6 +24,7 @@ + + void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); + void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); ++void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb); + void s390_ipl_update_diag308(IplParameterBlock *iplb); + int s390_ipl_prepare_pv_header(Error **errp); + int s390_ipl_pv_unpack(void); +@@ -65,7 +66,8 @@ struct S390IPLState { + bool enforce_bios; + bool iplb_valid; + bool iplb_valid_pv; +- bool netboot; ++ bool rebuilt_iplb; ++ uint16_t iplb_index; + /* reset related properties don't have to be migrated or reset */ + enum s390_reset reset_type; + int reset_cpu_index; +@@ -172,11 +174,14 @@ static inline bool iplb_valid_pv(IplParameterBlock *iplb) + + static inline bool iplb_valid(IplParameterBlock *iplb) + { ++ uint32_t len = be32_to_cpu(iplb->len); ++ + switch (iplb->pbt) { + case S390_IPL_TYPE_FCP: +- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN; ++ return len >= S390_IPLB_MIN_FCP_LEN; + case S390_IPL_TYPE_CCW: +- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN; ++ return len >= S390_IPLB_MIN_CCW_LEN; ++ case S390_IPL_TYPE_QEMU_SCSI: + default: + return false; + } +diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h +index 1da4f75aa8..6824391111 100644 +--- a/include/hw/s390x/ipl/qipl.h ++++ b/include/hw/s390x/ipl/qipl.h +@@ -29,7 +29,8 @@ + */ + struct QemuIplParameters { + uint8_t qipl_flags; +- uint8_t reserved1[3]; ++ uint8_t index; ++ uint8_t reserved1[2]; + uint64_t reserved2; + uint32_t boot_menu_timeout; + uint8_t reserved3[2]; +diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c +index 8db1764ff3..99d18947d1 100644 +--- a/pc-bios/s390-ccw/jump2ipl.c ++++ b/pc-bios/s390-ccw/jump2ipl.c +@@ -39,10 +39,15 @@ int jump_to_IPL_code(uint64_t address) + write_subsystem_identification(); + write_iplb_location(); + +- /* prevent unknown IPL types in the guest */ ++ /* ++ * The IPLB for QEMU SCSI type devices must be rebuilt during re-ipl. The ++ * iplb.devno is set to the boot position of the target SCSI device. ++ */ + if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) { +- iplb.pbt = S390_IPL_TYPE_CCW; +- set_iplb(&iplb); ++ iplb.devno = qipl.index; ++ if (!set_iplb(&iplb)) { ++ panic("Failed to set IPLB"); ++ } + } + + /* +diff --git a/target/s390x/diag.c b/target/s390x/diag.c +index 27ffd48576..a1fd54ddac 100644 +--- a/target/s390x/diag.c ++++ b/target/s390x/diag.c +@@ -133,7 +133,14 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra) + + valid = subcode == DIAG308_PV_SET ? iplb_valid_pv(iplb) : iplb_valid(iplb); + if (!valid) { +- env->regs[r1 + 1] = DIAG_308_RC_INVALID; ++ if (subcode == DIAG308_SET && iplb->pbt == S390_IPL_TYPE_QEMU_SCSI) { ++ s390_rebuild_iplb(iplb->devno, iplb); ++ s390_ipl_update_diag308(iplb); ++ env->regs[r1 + 1] = DIAG_308_RC_OK; ++ } else { ++ env->regs[r1 + 1] = DIAG_308_RC_INVALID; ++ } ++ + goto out; + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch b/SOURCES/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch new file mode 100644 index 0000000..1d01e97 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-Add-PLO-extension-facility.patch @@ -0,0 +1,221 @@ +From 67be3df75a0e2e3c0986bb8e482d8e4220dcbb44 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:50 +0100 +Subject: [PATCH 15/19] s390x/cpumodel: Add PLO-extension facility +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [15/16] 73ba29ed81fe2cab1419fb63b12a37c568a2d3ca (thuth/qemu-kvm-cs9) + +The PLO-extension facility introduces numerous locking related +subfunctions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-15-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 393c835e341e8921d1d6ae45da308e85176c4f00) +--- + target/s390x/cpu_features.c | 1 + + target/s390x/cpu_features_def.h.inc | 39 +++++++++++++++++++++++++ + target/s390x/cpu_models.c | 38 ++++++++++++++++++++++++ + target/s390x/gen-features.c | 45 +++++++++++++++++++++++++++++ + 4 files changed, 123 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index 5f8b02f12c..4b5be6798e 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -240,6 +240,7 @@ void s390_get_deprecated_features(S390FeatBitmap features) + /* indexed by feature group number for easy lookup */ + static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"), ++ FEAT_GROUP_INIT("plo_ext", PLO_EXT, "PLO-extension facility"), + FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"), + FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"), + FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced with gen17"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index fe7e1bd19c..e23e603a79 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -93,6 +93,7 @@ DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") + DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") + DEF_FEAT(SIF, "sif", STFL, 85, "Sequential-instruction-fetching facility") + DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") ++DEF_FEAT(PLO_EXT, "plo-ext", STFL, 87, "PLO-extension facility") + DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") + DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") + DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2") +@@ -180,6 +181,44 @@ DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store + DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)") + DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (64 bit in general registers)") + DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)") ++DEF_FEAT(PLO_CLO, "plo-clo", PLO, 24, "PLO Compare and load (256 bit in parameter list)") ++DEF_FEAT(PLO_CSO, "plo-cso", PLO, 25, "PLO Compare and swap (256 bit in parameter list)") ++DEF_FEAT(PLO_DCSO, "plo-dcso", PLO, 26, "PLO Double compare and swap (256 bit in parameter list)") ++DEF_FEAT(PLO_CSSTO, "plo-cssto", PLO, 27, "PLO Compare and swap and store (256 bit in parameter list)") ++DEF_FEAT(PLO_CSDSTO, "plo-csdsto", PLO, 28, "PLO Compare and swap and double store (256 bit in parameter list)") ++DEF_FEAT(PLO_CSTSTO, "plo-cststo", PLO, 29, "PLO Compare and swap and trible store (256 bit in parameter list)") ++DEF_FEAT(PLO_TCS, "plo-tcs", PLO, 30, "Triple compare and swap (32 bit in parameter list)") ++DEF_FEAT(PLO_TCSG, "plo-tcsg", PLO, 31, "Triple compare and swap (64 bit in parameter list)") ++DEF_FEAT(PLO_TCSX, "plo-tcsx", PLO, 32, "Triple compare and swap (128 bit in parameter list)") ++DEF_FEAT(PLO_TCSO, "plo-tcso", PLO, 33, "Triple compare and swap (256 bit in parameter list)") ++DEF_FEAT(PLO_QCS, "plo-qcs", PLO, 34, "Quadruple compare and swap (32 bit in parameter list)") ++DEF_FEAT(PLO_QCSG, "plo-qcsg", PLO, 35, "Quadruple compare and swap (64 bit in parameter list)") ++DEF_FEAT(PLO_QCSX, "plo-qcsx", PLO, 36, "Quadruple compare and swap (128 bit in parameter list)") ++DEF_FEAT(PLO_QCSO, "plo-qcso", PLO, 37, "Quadruple compare and swap (256 bit in parameter list)") ++DEF_FEAT(PLO_LO, "plo-lo", PLO, 38, "Load (256 bit in parameter list)") ++DEF_FEAT(PLO_DLX, "plo-dlx", PLO, 39, "Double load (128 bit in parameter list)") ++DEF_FEAT(PLO_DLO, "plo-dlo", PLO, 40, "Double load (256 bit in parameter list)") ++DEF_FEAT(PLO_TL, "plo-tl", PLO, 41, "Triple load (32 bit in parameter list)") ++DEF_FEAT(PLO_TLG, "plo-tlg", PLO, 42, "Triple load (64 bit in parameter list)") ++DEF_FEAT(PLO_TLX, "plo-tlx", PLO, 43, "Triple load (128 bit in parameter list)") ++DEF_FEAT(PLO_TLO, "plo-tlo", PLO, 44, "Triple load (256 bit in parameter list)") ++DEF_FEAT(PLO_QL, "plo-ql", PLO, 45, "Quadruple load (32 bit in parameter list)") ++DEF_FEAT(PLO_QLG, "plo-qlg", PLO, 46, "Quadruple load (64 bit in parameter list)") ++DEF_FEAT(PLO_QLX, "plo-qlx", PLO, 47, "Quadruple load (128 bit in parameter list)") ++DEF_FEAT(PLO_QLO, "plo-qlo", PLO, 48, "Quadruple load (256 bit in parameter list)") ++DEF_FEAT(PLO_STO, "plo-sto", PLO, 49, "Store (256 bit in parameter list)") ++DEF_FEAT(PLO_DST, "plo-dst", PLO, 50, "Double store (32 bit in parameter list)") ++DEF_FEAT(PLO_DSTG, "plo-dstg", PLO, 51, "Double store (64 bit in parameter list)") ++DEF_FEAT(PLO_DSTX, "plo-dstx", PLO, 52, "Double store (128 bit in parameter list)") ++DEF_FEAT(PLO_DSTO, "plo-dsto", PLO, 53, "Double store (256 bit in parameter list)") ++DEF_FEAT(PLO_TST, "plo-tst", PLO, 54, "Triple store (32 bit in parameter list)") ++DEF_FEAT(PLO_TSTG, "plo-tstg", PLO, 55, "Triple store (64 bit in parameter list)") ++DEF_FEAT(PLO_TSTX, "plo-tstx", PLO, 56, "Triple store (128 bit in parameter list)") ++DEF_FEAT(PLO_TSTO, "plo-tsto", PLO, 57, "Triple store (256 bit in parameter list)") ++DEF_FEAT(PLO_QST, "plo-qst", PLO, 58, "Quadruple store (32 bit in parameter list)") ++DEF_FEAT(PLO_QSTG, "plo-qstg", PLO, 59, "Quadruple store (64 bit in parameter list)") ++DEF_FEAT(PLO_QSTX, "plo-qstx", PLO, 60, "Quadruple store (128 bit in parameter list)") ++DEF_FEAT(PLO_QSTO, "plo-qsto", PLO, 61, "Quadruple store (256 bit in parameter list)") + + /* Features exposed via the PTFF instruction. */ + DEF_FEAT(PTFF_QTO, "ptff-qto", PTFF, 1, "PTFF Query TOD Offset") +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 32b5bb7509..d2798c0f38 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -516,6 +516,44 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, + { S390_FEAT_INEFF_NC_TX, S390_FEAT_TRANSACTIONAL_EXE }, ++ { S390_FEAT_PLO_CLO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_CSO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DCSO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_CSSTO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_CSDSTO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_CSTSTO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TCS, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TCSG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TCSX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TCSO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QCS, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QCSG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QCSX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QCSO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_LO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DLX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DLO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TL, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TLG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TLX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TLO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QL, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QLG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QLX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QLO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_STO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DST, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DSTG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DSTX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_DSTO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TST, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TSTG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TSTX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_TSTO, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QST, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QSTG, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QSTX, S390_FEAT_PLO_EXT }, ++ { S390_FEAT_PLO_QSTO, S390_FEAT_PLO_EXT }, + }; + int i; + +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 6d00ffcda7..680d45d303 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -46,6 +46,47 @@ + S390_FEAT_PLO_CSTSTGR, \ + S390_FEAT_PLO_CSTSTX + ++#define S390_FEAT_GROUP_PLO_EXT \ ++ S390_FEAT_PLO_EXT, \ ++ S390_FEAT_PLO_CLO, \ ++ S390_FEAT_PLO_CSO, \ ++ S390_FEAT_PLO_DCSO, \ ++ S390_FEAT_PLO_CSSTO, \ ++ S390_FEAT_PLO_CSDSTO, \ ++ S390_FEAT_PLO_CSTSTO, \ ++ S390_FEAT_PLO_TCS, \ ++ S390_FEAT_PLO_TCSG, \ ++ S390_FEAT_PLO_TCSX, \ ++ S390_FEAT_PLO_TCSO, \ ++ S390_FEAT_PLO_QCS, \ ++ S390_FEAT_PLO_QCSG, \ ++ S390_FEAT_PLO_QCSX, \ ++ S390_FEAT_PLO_QCSO, \ ++ S390_FEAT_PLO_LO, \ ++ S390_FEAT_PLO_DLX, \ ++ S390_FEAT_PLO_DLO, \ ++ S390_FEAT_PLO_TL, \ ++ S390_FEAT_PLO_TLG, \ ++ S390_FEAT_PLO_TLX, \ ++ S390_FEAT_PLO_TLO, \ ++ S390_FEAT_PLO_QL, \ ++ S390_FEAT_PLO_QLG, \ ++ S390_FEAT_PLO_QLX, \ ++ S390_FEAT_PLO_QLO, \ ++ S390_FEAT_PLO_STO, \ ++ S390_FEAT_PLO_DST, \ ++ S390_FEAT_PLO_DSTG, \ ++ S390_FEAT_PLO_DSTX, \ ++ S390_FEAT_PLO_DSTO, \ ++ S390_FEAT_PLO_TST, \ ++ S390_FEAT_PLO_TSTG, \ ++ S390_FEAT_PLO_TSTX, \ ++ S390_FEAT_PLO_TSTO, \ ++ S390_FEAT_PLO_QST, \ ++ S390_FEAT_PLO_QSTG, \ ++ S390_FEAT_PLO_QSTX, \ ++ S390_FEAT_PLO_QSTO ++ + #define S390_FEAT_GROUP_TOD_CLOCK_STEERING \ + S390_FEAT_TOD_CLOCK_STEERING, \ + S390_FEAT_PTFF_QTO, \ +@@ -320,6 +361,9 @@ + static uint16_t group_PLO[] = { + S390_FEAT_GROUP_PLO, + }; ++static uint16_t group_PLO_EXT[] = { ++ S390_FEAT_GROUP_PLO_EXT, ++}; + static uint16_t group_TOD_CLOCK_STEERING[] = { + S390_FEAT_GROUP_TOD_CLOCK_STEERING, + }; +@@ -936,6 +980,7 @@ typedef struct { + *******************************/ + static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(PLO), ++ FEAT_GROUP_INITIALIZER(PLO_EXT), + FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING), + FEAT_GROUP_INITIALIZER(GEN13_PTFF), + FEAT_GROUP_INITIALIZER(GEN17_PTFF), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch b/SOURCES/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch new file mode 100644 index 0000000..403a2e5 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch @@ -0,0 +1,43 @@ +From 6de82922c2fe7cad72f275d5ef49cabfe0a5e169 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:48 +0100 +Subject: [PATCH 13/19] s390x/cpumodel: Add Sequential-Instruction-Fetching + facility +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [13/16] a858363caecc3bb6b09182ff43427d1677ebbed9 (thuth/qemu-kvm-cs9) + +The sequential instruction fetching facility provides few guarantees, +for example, to avoid stop machine calls on enabling/disabling kprobes. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-13-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit a5fa8bee72847406bfc32e15c8e41c0a2a0812e1) +--- + target/s390x/cpu_features_def.h.inc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 2c1d1cd98a..09a80844a7 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -91,6 +91,7 @@ DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packe + DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") + DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") + DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") ++DEF_FEAT(SIF, "sif", STFL, 85, "Sequential-instruction-fetching facility") + DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") + DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") + DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch b/SOURCES/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch new file mode 100644 index 0000000..3a4d243 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch @@ -0,0 +1,90 @@ +From aeb20f5f209002675477b17e87577cd793151457 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:41 +0100 +Subject: [PATCH 06/19] s390x/cpumodel: Add ptff Query Time-Stamp Event (QTSE) + support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [6/16] 515643e8201e25958e81e36c22de0192eb1f1a19 (thuth/qemu-kvm-cs9) + +Introduce a new PTFF subfunction to query-stamp events. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-6-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit eba6f49128fbcf75d19acb6aef250d0664d03e9e) +--- + target/s390x/cpu_features.c | 1 + + target/s390x/cpu_features_def.h.inc | 1 + + target/s390x/gen-features.c | 9 +++++++++ + 3 files changed, 11 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index 9ba127e386..385a2ff860 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -241,6 +241,7 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"), + FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"), + FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"), ++ FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced with gen17"), + FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"), + FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"), + FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 2132837ffe..f96cb5a7d8 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -181,6 +181,7 @@ DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query Steering Information") + DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock") + DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information") + DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User") ++DEF_FEAT(PTFF_QTSE, "ptff-qtse", PTFF, 6, "PTFF Query Time-Stamp Event") + DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information Extended") + DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User Extended") + DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset") +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 3326e7df43..302b653214 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -64,6 +64,9 @@ + S390_FEAT_PTFF_STOE, \ + S390_FEAT_PTFF_STOUE + ++#define S390_FEAT_GROUP_GEN17_PTFF \ ++ S390_FEAT_PTFF_QTSE ++ + #define S390_FEAT_GROUP_MSA \ + S390_FEAT_MSA, \ + S390_FEAT_KMAC_DEA, \ +@@ -318,6 +321,11 @@ static uint16_t group_GEN13_PTFF[] = { + static uint16_t group_MULTIPLE_EPOCH_PTFF[] = { + S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF, + }; ++ ++static uint16_t group_GEN17_PTFF[] = { ++ S390_FEAT_GROUP_GEN17_PTFF, ++}; ++ + static uint16_t group_MSA[] = { + S390_FEAT_GROUP_MSA, + }; +@@ -918,6 +926,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(PLO), + FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING), + FEAT_GROUP_INITIALIZER(GEN13_PTFF), ++ FEAT_GROUP_INITIALIZER(GEN17_PTFF), + FEAT_GROUP_INITIALIZER(MSA), + FEAT_GROUP_INITIALIZER(MSA_EXT_1), + FEAT_GROUP_INITIALIZER(MSA_EXT_2), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch b/SOURCES/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch new file mode 100644 index 0000000..d754098 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch @@ -0,0 +1,169 @@ +From 2bf72baa123e5d55d9ebe62f457d22df4c53ef70 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:43 +0100 +Subject: [PATCH 08/19] s390x/cpumodel: add Concurrent-functions facility + support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [8/16] a98bb888a032f696ded722a8e614612f20b070f6 (thuth/qemu-kvm-cs9) + +The Concurrent-functions facility introduces the new instruction +Perform Functions with Concurrent Results (PFCR) with few subfunctions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-8-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit c9ea365dce32bc114dacd7cfca7c478a82459b47) +--- + target/s390x/cpu_features.c | 2 ++ + target/s390x/cpu_features.h | 1 + + target/s390x/cpu_features_def.h.inc | 8 ++++++++ + target/s390x/cpu_models.c | 5 +++++ + target/s390x/gen-features.c | 13 +++++++++++++ + target/s390x/kvm/kvm.c | 6 ++++++ + 6 files changed, 35 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index 385a2ff860..5f8b02f12c 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -93,6 +93,7 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type, + case S390_FEAT_TYPE_KDSA: + case S390_FEAT_TYPE_SORTL: + case S390_FEAT_TYPE_DFLTCC: ++ case S390_FEAT_TYPE_PFCR: + set_be_bit(0, data); /* query is always available */ + break; + default: +@@ -263,6 +264,7 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), + FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), + FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), ++ FEAT_GROUP_INIT("ccf", CONCURRENT_FUNCTIONS, "Concurrent-functions facility"), + }; + + const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group) +diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h +index 661a8cd6db..5635839d03 100644 +--- a/target/s390x/cpu_features.h ++++ b/target/s390x/cpu_features.h +@@ -44,6 +44,7 @@ typedef enum { + S390_FEAT_TYPE_SORTL, + S390_FEAT_TYPE_DFLTCC, + S390_FEAT_TYPE_UV_FEAT_GUEST, ++ S390_FEAT_TYPE_PFCR, + } S390FeatType; + + /* Definition of a CPU feature */ +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index f96cb5a7d8..09872ab3d8 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -116,6 +116,7 @@ DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") + DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") + DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") + DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") ++DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") + + /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ + DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility") +@@ -413,3 +414,10 @@ DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block" + /* Features exposed via the UV-CALL instruction */ + DEF_FEAT(UV_FEAT_AP, "appv", UV_FEAT_GUEST, 4, "AP instructions installed for secure guests") + DEF_FEAT(UV_FEAT_AP_INTR, "appvi", UV_FEAT_GUEST, 5, "AP instructions interruption support for secure guests") ++ ++/* Features exposed via the PFCR instruction (concurrent-functions facility). */ ++DEF_FEAT(PFCR_QAF, "pfcr-qaf", PFCR, 0, "PFCR Query-Available-Functions") ++DEF_FEAT(PFCR_CSDST, "pfcr-csdst", PFCR, 1, "PFCR Compare-and-Swap-and-Double-Store (32)") ++DEF_FEAT(PFCR_CSDSTG, "pfcr-csdstg", PFCR, 2, "PFCR Compare-and-Swap-and-Double-Store (64)") ++DEF_FEAT(PFCR_CSTST, "pfcr-cstst", PFCR, 3, "PFCR Compare-and-Swap-and-Triple-Store (32)") ++DEF_FEAT(PFCR_CSTSTG, "pfcr-cststg", PFCR, 4, "PFCR Compare-and-Swap-and-Triple-Store (64)") +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 93fbe7e6c8..1a7627b010 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -507,6 +507,11 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING }, + { S390_FEAT_UV_FEAT_AP, S390_FEAT_AP }, + { S390_FEAT_UV_FEAT_AP_INTR, S390_FEAT_UV_FEAT_AP }, ++ { S390_FEAT_PFCR_QAF, S390_FEAT_CCF_BASE }, ++ { S390_FEAT_PFCR_CSDST, S390_FEAT_CCF_BASE }, ++ { S390_FEAT_PFCR_CSDSTG, S390_FEAT_CCF_BASE }, ++ { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, ++ { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, + }; + int i; + +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 302b653214..6d00ffcda7 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -308,6 +308,14 @@ + S390_FEAT_DEFLATE_XPND, \ + S390_FEAT_DEFLATE_F0 + ++#define S390_FEAT_GROUP_CONCURRENT_FUNCTIONS \ ++ S390_FEAT_CCF_BASE, \ ++ S390_FEAT_PFCR_QAF, \ ++ S390_FEAT_PFCR_CSDST, \ ++ S390_FEAT_PFCR_CSDSTG, \ ++ S390_FEAT_PFCR_CSTST, \ ++ S390_FEAT_PFCR_CSTSTG ++ + /* cpu feature groups */ + static uint16_t group_PLO[] = { + S390_FEAT_GROUP_PLO, +@@ -398,6 +406,10 @@ static uint16_t group_DEFLATE_CONVERSION[] = { + S390_FEAT_GROUP_DEFLATE_CONVERSION, + }; + ++static uint16_t group_CONCURRENT_FUNCTIONS[] = { ++ S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, ++}; ++ + /* Base features (in order of release) + * Only non-hypervisor managed features belong here. + * Base feature sets are static meaning they do not change in future QEMU +@@ -948,6 +960,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), + FEAT_GROUP_INITIALIZER(ENH_SORT), + FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), ++ FEAT_GROUP_INITIALIZER(CONCURRENT_FUNCTIONS), + }; + + #define QEMU_FEAT_INITIALIZER(_name) \ +diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c +index 0d51a4ea6b..7a0ca5570f 100644 +--- a/target/s390x/kvm/kvm.c ++++ b/target/s390x/kvm/kvm.c +@@ -2195,6 +2195,9 @@ static int query_cpu_subfunc(S390FeatBitmap features) + if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { + s390_add_from_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); + } ++ if (test_bit(S390_FEAT_CCF_BASE, features)) { ++ s390_add_from_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); ++ } + return 0; + } + +@@ -2248,6 +2251,9 @@ static int configure_cpu_subfunc(const S390FeatBitmap features) + if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { + s390_fill_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); + } ++ if (test_bit(S390_FEAT_CCF_BASE, features)) { ++ s390_fill_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); ++ } + return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); + } + +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch b/SOURCES/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch new file mode 100644 index 0000000..db4b689 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch @@ -0,0 +1,56 @@ +From f6cefb05d503f1082a483bd57b10f764f160ac71 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:47 +0100 +Subject: [PATCH 12/19] s390x/cpumodel: add + Ineffective-nonconstrained-transaction facility +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [12/16] 0b6f6157f96303f11e65db8a11d7ca1fbdeef238 (thuth/qemu-kvm-cs9) + +This facility indicates reduced support for noncontrained +transactional-execution. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-12-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 12417b713c1fffc26c680e99e3429f055eb9af2e) +--- + target/s390x/cpu_features_def.h.inc | 1 + + target/s390x/cpu_models.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index df154d145f..2c1d1cd98a 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -112,6 +112,7 @@ DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 + DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility") + DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility") + DEF_FEAT(NNPA, "nnpa", STFL, 165, "NNPA facility") ++DEF_FEAT(INEFF_NC_TX, "ineff_nc_tx", STFL, 170, "Ineffective-nonconstrained-transaction facility") + DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH2, "vxpdeh2", STFL, 192, "Vector-Packed-Decimal-Enhancement facility 2") + DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") + DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 262e3daf3e..32b5bb7509 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -515,6 +515,7 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_PFCR_CSDSTG, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, ++ { S390_FEAT_INEFF_NC_TX, S390_FEAT_TRANSACTIONAL_EXE }, + }; + int i; + +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch b/SOURCES/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch new file mode 100644 index 0000000..c3362b6 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch @@ -0,0 +1,42 @@ +From 330241441464585dcc5c0786356b7f467cc882f9 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:45 +0100 +Subject: [PATCH 10/19] s390x/cpumodel: add + Miscellaneous-Instruction-Extensions Facility 4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [10/16] 980ca7cdce99ccba7332de703ac9ec6f5e771d4b (thuth/qemu-kvm-cs9) + +This facility introduces few new instructions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-10-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit e68e5ea6fe87c0177ea6421045c1d46f223a861e) +--- + target/s390x/cpu_features_def.h.inc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 0b7be0e6e9..8be2e0e46d 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -90,6 +90,7 @@ DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2") + DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility") + DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") + DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") ++DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") + DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") + DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") + DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch b/SOURCES/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch new file mode 100644 index 0000000..b8cbca4 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch @@ -0,0 +1,56 @@ +From 8f781722a638bce5472ddc47af7b85da28fc4c9d Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:44 +0100 +Subject: [PATCH 09/19] s390x/cpumodel: add Vector Enhancements facility 3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [9/16] 5dd3aa305276bb7b75feb570d669bd0a9ab224dd (thuth/qemu-kvm-cs9) + +The Vector Enhancements facility 3 introduces new instructions and +extends support for doubleword/quadword elements. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-9-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 0b2c66a3fa5ccecf26ea011d97d65a986b42b4d8) +--- + target/s390x/cpu_features_def.h.inc | 1 + + target/s390x/cpu_models.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 09872ab3d8..0b7be0e6e9 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -116,6 +116,7 @@ DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") + DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") + DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") + DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") ++DEF_FEAT(VECTOR_ENH3, "vxeh3", STFL, 198, "Vector Enhancements facility 3") + DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") + + /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 1a7627b010..05a2d15a70 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -461,6 +461,8 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, + { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, ++ { S390_FEAT_VECTOR_ENH2, S390_FEAT_VECTOR_ENH }, ++ { S390_FEAT_VECTOR_ENH3, S390_FEAT_VECTOR_ENH2 }, + { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, + { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, + { S390_FEAT_CMM_NT, S390_FEAT_CMM }, +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch b/SOURCES/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch new file mode 100644 index 0000000..efb3e81 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch @@ -0,0 +1,56 @@ +From 080e7d91315bbeef35726159cbab01c51d0dc63e Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:46 +0100 +Subject: [PATCH 11/19] s390x/cpumodel: add Vector-Packed-Decimal-Enhancement + facility 3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [11/16] a653881aae9e26d0644b0d47bbfaaf8d22fb622a (thuth/qemu-kvm-cs9) + +This facility introduces new capabilities for the signed-pack-decimal +format. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-11-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit db4c208abde53a7ed16d566bf63a3520894bba8d) +--- + target/s390x/cpu_features_def.h.inc | 1 + + target/s390x/cpu_models.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 8be2e0e46d..df154d145f 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -118,6 +118,7 @@ DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") + DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") + DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") + DEF_FEAT(VECTOR_ENH3, "vxeh3", STFL, 198, "Vector Enhancements facility 3") ++DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH3, "vxpdeh3", STFL, 199, "Vector-Packed-Decimal-Enhancement facility 3") + DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") + + /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 05a2d15a70..262e3daf3e 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -460,6 +460,7 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, ++ { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2 }, + { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, + { S390_FEAT_VECTOR_ENH2, S390_FEAT_VECTOR_ENH }, + { S390_FEAT_VECTOR_ENH3, S390_FEAT_VECTOR_ENH2 }, +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-msa10-subfunctions.patch b/SOURCES/kvm-s390x-cpumodel-add-msa10-subfunctions.patch new file mode 100644 index 0000000..a75075b --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-msa10-subfunctions.patch @@ -0,0 +1,133 @@ +From c479543e70213d3638e78122a3ff32a7fbf2cfb5 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:37 +0100 +Subject: [PATCH 02/19] s390x/cpumodel: add msa10 subfunctions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [2/16] 9b27810af579a1814c195a8c9453d4a95f3b0654 (thuth/qemu-kvm-cs9) + +MSA10 introduces new AES XTS subfunctions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Christian Borntraeger +Message-ID: <20241206122751.189721-2-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 1029cd5b9827ba6aa7f5e02eed1928a928e2fa5e) +--- + target/s390x/cpu_features.c | 2 ++ + target/s390x/cpu_features_def.h.inc | 6 ++++++ + target/s390x/cpu_models.c | 4 ++++ + target/s390x/gen-features.c | 20 ++++++++++++++++++++ + 4 files changed, 32 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index cb4e2b8920..a3c239595a 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -252,6 +252,8 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("msa8", MSA_EXT_8, "Message-security-assist-extension 8 facility"), + FEAT_GROUP_INIT("msa9", MSA_EXT_9, "Message-security-assist-extension 9 facility"), + FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"), ++ FEAT_GROUP_INIT("msa10", MSA_EXT_10, "Message-security-assist-extension 10 facility"), ++ FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), + FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), + FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), + FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index c53ac13352..104d186c3f 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -233,6 +233,10 @@ DEF_FEAT(KM_XTS_AES_128, "km-xts-aes-128", KM, 50, "KM XTS-AES-128") + DEF_FEAT(KM_XTS_AES_256, "km-xts-aes-256", KM, 52, "KM XTS-AES-256") + DEF_FEAT(KM_XTS_EAES_128, "km-xts-eaes-128", KM, 58, "KM XTS-Encrypted-AES-128") + DEF_FEAT(KM_XTS_EAES_256, "km-xts-eaes-256", KM, 60, "KM XTS-Encrypted-AES-256") ++DEF_FEAT(KM_FULL_XTS_AES_128, "km-full-xts-aes-128", KM, 82, "KM Full-XTS-AES-128") ++DEF_FEAT(KM_FULL_XTS_AES_256, "km-full-xts-aes-256", KM, 84, "KM Full-XTS-AES-256") ++DEF_FEAT(KM_FULL_XTS_EAES_128, "km-full-xts-eaes-128", KM, 90, "KM Full-XTS-Encrypted-AES-128") ++DEF_FEAT(KM_FULL_XTS_EAES_256, "km-full-xts-eaes-256", KM, 92, "KM Full-XTS-Encrypted-AES-256") + + /* Features exposed via the KIMD instruction. */ + DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1") +@@ -264,6 +268,8 @@ DEF_FEAT(PCKMO_ETDEA_256, "pckmo-etdea-192", PCKMO, 3, "PCKMO Encrypted-TDEA-192 + DEF_FEAT(PCKMO_AES_128, "pckmo-aes-128", PCKMO, 18, "PCKMO Encrypted-AES-128-Key") + DEF_FEAT(PCKMO_AES_192, "pckmo-aes-192", PCKMO, 19, "PCKMO Encrypted-AES-192-Key") + DEF_FEAT(PCKMO_AES_256, "pckmo-aes-256", PCKMO, 20, "PCKMO Encrypted-AES-256-Key") ++DEF_FEAT(PCKMO_AES_XTS_128_DK, "pckmo-aes-xts-128-dk", PCKMO, 21, "PCKMO Encrypt-AES-XTS-128-Double-Key") ++DEF_FEAT(PCKMO_AES_XTS_256_DK, "pckmo-aes-xts-256-dk", PCKMO, 22, "PCKMO Encrypt-AES-XTS-256-Double-Key") + DEF_FEAT(PCKMO_ECC_P256, "pckmo-ecc-p256", PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key") + DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key") + DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key") +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 9ee30310c6..313640ca12 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -480,6 +480,10 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, + { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, + { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, ++ { S390_FEAT_KM_FULL_XTS_AES_128, S390_FEAT_MSA_EXT_4 }, ++ { S390_FEAT_KM_FULL_XTS_AES_256, S390_FEAT_MSA_EXT_4 }, ++ { S390_FEAT_KM_FULL_XTS_EAES_128, S390_FEAT_MSA_EXT_4 }, ++ { S390_FEAT_KM_FULL_XTS_EAES_256, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, + { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, + { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 2b2bfc3736..06c3bf64f3 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -246,6 +246,16 @@ + S390_FEAT_PCKMO_ECC_ED25519, \ + S390_FEAT_PCKMO_ECC_ED448 + ++#define S390_FEAT_GROUP_MSA_EXT_10 \ ++ S390_FEAT_KM_FULL_XTS_AES_128, \ ++ S390_FEAT_KM_FULL_XTS_AES_256, \ ++ S390_FEAT_KM_FULL_XTS_EAES_128, \ ++ S390_FEAT_KM_FULL_XTS_EAES_256 ++ ++#define S390_FEAT_GROUP_MSA_EXT_10_PCKMO \ ++ S390_FEAT_PCKMO_AES_XTS_128_DK, \ ++ S390_FEAT_PCKMO_AES_XTS_256_DK ++ + #define S390_FEAT_GROUP_ENH_SORT \ + S390_FEAT_ESORT_BASE, \ + S390_FEAT_SORTL_SFLR, \ +@@ -307,10 +317,18 @@ static uint16_t group_MSA_EXT_9[] = { + S390_FEAT_GROUP_MSA_EXT_9, + }; + ++static uint16_t group_MSA_EXT_10[] = { ++ S390_FEAT_GROUP_MSA_EXT_10, ++}; ++ + static uint16_t group_MSA_EXT_9_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_9_PCKMO, + }; + ++static uint16_t group_MSA_EXT_10_PCKMO[] = { ++ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, ++}; ++ + static uint16_t group_ENH_SORT[] = { + S390_FEAT_GROUP_ENH_SORT, + }; +@@ -858,6 +876,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(MSA_EXT_8), + FEAT_GROUP_INITIALIZER(MSA_EXT_9), + FEAT_GROUP_INITIALIZER(MSA_EXT_9_PCKMO), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_10), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), + FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), + FEAT_GROUP_INITIALIZER(ENH_SORT), + FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-msa11-subfunctions.patch b/SOURCES/kvm-s390x-cpumodel-add-msa11-subfunctions.patch new file mode 100644 index 0000000..452b873 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-msa11-subfunctions.patch @@ -0,0 +1,148 @@ +From 07bd1e9aee50f5239d73c7c506b4a1851f36585b Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:38 +0100 +Subject: [PATCH 03/19] s390x/cpumodel: add msa11 subfunctions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [3/16] 939476a6a4b38f269f1a419110c38ab42f545d6f (thuth/qemu-kvm-cs9) + +MSA11 introduces new HMAC subfunctions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Christian Borntraeger +Message-ID: <20241206122751.189721-3-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 11dc9020824c81552b021fbe0e2910e0348e7f8e) +--- + target/s390x/cpu_features.c | 2 ++ + target/s390x/cpu_features_def.h.inc | 10 ++++++++++ + target/s390x/cpu_models.c | 8 ++++++++ + target/s390x/gen-features.c | 24 ++++++++++++++++++++++++ + 4 files changed, 44 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index a3c239595a..36930feccd 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -254,6 +254,8 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa10", MSA_EXT_10, "Message-security-assist-extension 10 facility"), + FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), ++ FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), ++ FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), + FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), + FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), + FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 104d186c3f..15ea51fc54 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -200,6 +200,14 @@ DEF_FEAT(KMAC_AES_256, "kmac-aes-256", KMAC, 20, "KMAC AES-256") + DEF_FEAT(KMAC_EAES_128, "kmac-eaes-128", KMAC, 26, "KMAC Encrypted-AES-128") + DEF_FEAT(KMAC_EAES_192, "kmac-eaes-192", KMAC, 27, "KMAC Encrypted-AES-192") + DEF_FEAT(KMAC_EAES_256, "kmac-eaes-256", KMAC, 28, "KMAC Encrypted-AES-256") ++DEF_FEAT(KMAC_HMAC_SHA_224, "kmac-hmac-sha-224", KMAC, 112, "KMAC HMAC-SHA-224") ++DEF_FEAT(KMAC_HMAC_SHA_256, "kmac-hmac-sha-246", KMAC, 113, "KMAC HMAC-SHA-256") ++DEF_FEAT(KMAC_HMAC_SHA_384, "kmac-hmac-sha-384", KMAC, 114, "KMAC HMAC-SHA-384") ++DEF_FEAT(KMAC_HMAC_SHA_512, "kmac-hmac-sha-512", KMAC, 115, "KMAC HMAC-SHA-512") ++DEF_FEAT(KMAC_HMAC_ESHA_224, "kmac-hmac-esha-224", KMAC, 120, "KMAC HMAC-Encrypted-SHA-224") ++DEF_FEAT(KMAC_HMAC_ESHA_256, "kmac-hmac-esha-246", KMAC, 121, "KMAC HMAC-Encrypted-SHA-256") ++DEF_FEAT(KMAC_HMAC_ESHA_384, "kmac-hmac-esha-384", KMAC, 122, "KMAC HMAC-Encrypted-SHA-384") ++DEF_FEAT(KMAC_HMAC_ESHA_512, "kmac-hmac-esha-512", KMAC, 123, "KMAC HMAC-Encrypted-SHA-512") + + /* Features exposed via the KMC instruction. */ + DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA") +@@ -275,6 +283,8 @@ DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Ke + DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key") + DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key") + DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key") ++DEF_FEAT(PCKMO_HMAC_512, "pckmo-hmac-512", PCKMO, 118, "PCKMO Encrypt-HMAC-512-Key") ++DEF_FEAT(PCKMO_HMAC_1024, "pckmo-hmac-1024", PCKMO, 122, "PCKMO Encrypt-HMAC-1024-Key") + + /* Features exposed via the KMCTR instruction. */ + DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA") +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 313640ca12..93fbe7e6c8 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -480,6 +480,14 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, + { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, + { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, ++ { S390_FEAT_KMAC_HMAC_SHA_224, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_SHA_256, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_SHA_384, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_SHA_512, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_ESHA_224, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_ESHA_256, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_ESHA_384, S390_FEAT_MSA_EXT_3 }, ++ { S390_FEAT_KMAC_HMAC_ESHA_512, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KM_FULL_XTS_AES_128, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_KM_FULL_XTS_AES_256, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_KM_FULL_XTS_EAES_128, S390_FEAT_MSA_EXT_4 }, +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 06c3bf64f3..d6305f945a 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -256,6 +256,20 @@ + S390_FEAT_PCKMO_AES_XTS_128_DK, \ + S390_FEAT_PCKMO_AES_XTS_256_DK + ++#define S390_FEAT_GROUP_MSA_EXT_11 \ ++ S390_FEAT_KMAC_HMAC_SHA_224, \ ++ S390_FEAT_KMAC_HMAC_SHA_256, \ ++ S390_FEAT_KMAC_HMAC_SHA_384, \ ++ S390_FEAT_KMAC_HMAC_SHA_512, \ ++ S390_FEAT_KMAC_HMAC_ESHA_224, \ ++ S390_FEAT_KMAC_HMAC_ESHA_256, \ ++ S390_FEAT_KMAC_HMAC_ESHA_384, \ ++ S390_FEAT_KMAC_HMAC_ESHA_512 ++ ++#define S390_FEAT_GROUP_MSA_EXT_11_PCKMO \ ++ S390_FEAT_PCKMO_HMAC_512, \ ++ S390_FEAT_PCKMO_HMAC_1024 ++ + #define S390_FEAT_GROUP_ENH_SORT \ + S390_FEAT_ESORT_BASE, \ + S390_FEAT_SORTL_SFLR, \ +@@ -321,6 +335,10 @@ static uint16_t group_MSA_EXT_10[] = { + S390_FEAT_GROUP_MSA_EXT_10, + }; + ++static uint16_t group_MSA_EXT_11[] = { ++ S390_FEAT_GROUP_MSA_EXT_11, ++}; ++ + static uint16_t group_MSA_EXT_9_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_9_PCKMO, + }; +@@ -329,6 +347,10 @@ static uint16_t group_MSA_EXT_10_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_10_PCKMO, + }; + ++static uint16_t group_MSA_EXT_11_PCKMO[] = { ++ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, ++}; ++ + static uint16_t group_ENH_SORT[] = { + S390_FEAT_GROUP_ENH_SORT, + }; +@@ -878,6 +900,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(MSA_EXT_9_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_10), + FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_11), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), + FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), + FEAT_GROUP_INITIALIZER(ENH_SORT), + FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-msa12-changes.patch b/SOURCES/kvm-s390x-cpumodel-add-msa12-changes.patch new file mode 100644 index 0000000..9363031 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-msa12-changes.patch @@ -0,0 +1,88 @@ +From 0d5a636211e9f21547a077c8c5ab244b59f747f3 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:39 +0100 +Subject: [PATCH 04/19] s390x/cpumodel: add msa12 changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [4/16] 32004bb7366a66319c54a0f23ad16f2ad093aa5e (thuth/qemu-kvm-cs9) + +MSA12 changes the KIMD/KLMD instruction format for SHA3/SHAKE. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Christian Borntraeger +Message-ID: <20241206122751.189721-4-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 496fc02e0e532f8917fa96e45fa531231e821c31) +--- + target/s390x/cpu_features.c | 1 + + target/s390x/cpu_features_def.h.inc | 1 + + target/s390x/gen-features.c | 8 ++++++++ + 3 files changed, 10 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index 36930feccd..0e0b37ab95 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -256,6 +256,7 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), + FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), ++ FEAT_GROUP_INIT("msa12", MSA_EXT_12, "Message-security-assist-extension 12 facility"), + FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), + FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), + FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 15ea51fc54..2e5dc96984 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -90,6 +90,7 @@ DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2") + DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility") + DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") + DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") ++DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") + DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") + DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") + DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2") +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index d6305f945a..ab9ad51d5e 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -270,6 +270,9 @@ + S390_FEAT_PCKMO_HMAC_512, \ + S390_FEAT_PCKMO_HMAC_1024 + ++#define S390_FEAT_GROUP_MSA_EXT_12 \ ++ S390_FEAT_MSA_EXT_12 ++ + #define S390_FEAT_GROUP_ENH_SORT \ + S390_FEAT_ESORT_BASE, \ + S390_FEAT_SORTL_SFLR, \ +@@ -339,6 +342,10 @@ static uint16_t group_MSA_EXT_11[] = { + S390_FEAT_GROUP_MSA_EXT_11, + }; + ++static uint16_t group_MSA_EXT_12[] = { ++ S390_FEAT_GROUP_MSA_EXT_12, ++}; ++ + static uint16_t group_MSA_EXT_9_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_9_PCKMO, + }; +@@ -902,6 +909,7 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_11), + FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_12), + FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), + FEAT_GROUP_INITIALIZER(ENH_SORT), + FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-add-msa13-subfunctions.patch b/SOURCES/kvm-s390x-cpumodel-add-msa13-subfunctions.patch new file mode 100644 index 0000000..eff2cf6 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-add-msa13-subfunctions.patch @@ -0,0 +1,200 @@ +From 8c33d73160a6cf737c1519c10430378ff4ee13f9 Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:40 +0100 +Subject: [PATCH 05/19] s390x/cpumodel: add msa13 subfunctions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [5/16] ccd6aeea425b605d0c6155ef8e386b22394e210e (thuth/qemu-kvm-cs9) + +MSA13 introduces query authentication information (QAI) subfunctions. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-5-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit ba4614fdacc2ea55060ddb48bdb2ebd21d0c3464) +--- + target/s390x/cpu_features.c | 2 ++ + target/s390x/cpu_features_def.h.inc | 12 ++++++++++++ + target/s390x/gen-features.c | 26 ++++++++++++++++++++++++++ + 3 files changed, 40 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index 0e0b37ab95..9ba127e386 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -257,6 +257,8 @@ static S390FeatGroupDef s390_feature_groups[] = { + FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), + FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa12", MSA_EXT_12, "Message-security-assist-extension 12 facility"), ++ FEAT_GROUP_INIT("msa13", MSA_EXT_13, "Message-security-assist-extension 13 facility"), ++ FEAT_GROUP_INIT("msa13_pckmo", MSA_EXT_13_PCKMO, "Message-security-assist-extension 13 PCKMO subfunctions"), + FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), + FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), + FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 2e5dc96984..2132837ffe 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -209,6 +209,7 @@ DEF_FEAT(KMAC_HMAC_ESHA_224, "kmac-hmac-esha-224", KMAC, 120, "KMAC HMAC-Encrypt + DEF_FEAT(KMAC_HMAC_ESHA_256, "kmac-hmac-esha-246", KMAC, 121, "KMAC HMAC-Encrypted-SHA-256") + DEF_FEAT(KMAC_HMAC_ESHA_384, "kmac-hmac-esha-384", KMAC, 122, "KMAC HMAC-Encrypted-SHA-384") + DEF_FEAT(KMAC_HMAC_ESHA_512, "kmac-hmac-esha-512", KMAC, 123, "KMAC HMAC-Encrypted-SHA-512") ++DEF_FEAT(KMAC_QAI, "kmac-qai", KMAC, 127, "KMAC Query-Authentication-Information") + + /* Features exposed via the KMC instruction. */ + DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA") +@@ -246,6 +247,7 @@ DEF_FEAT(KM_FULL_XTS_AES_128, "km-full-xts-aes-128", KM, 82, "KM Full-XTS-AES-12 + DEF_FEAT(KM_FULL_XTS_AES_256, "km-full-xts-aes-256", KM, 84, "KM Full-XTS-AES-256") + DEF_FEAT(KM_FULL_XTS_EAES_128, "km-full-xts-eaes-128", KM, 90, "KM Full-XTS-Encrypted-AES-128") + DEF_FEAT(KM_FULL_XTS_EAES_256, "km-full-xts-eaes-256", KM, 92, "KM Full-XTS-Encrypted-AES-256") ++DEF_FEAT(KM_QAI, "km-qai", KM, 127, "KM Query-Authentication-Information") + + /* Features exposed via the KIMD instruction. */ + DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1") +@@ -258,6 +260,7 @@ DEF_FEAT(KIMD_SHA3_512, "kimd-sha3-512", KIMD, 35, "KIMD SHA3-512") + DEF_FEAT(KIMD_SHAKE_128, "kimd-shake-128", KIMD, 36, "KIMD SHAKE-128") + DEF_FEAT(KIMD_SHAKE_256, "kimd-shake-256", KIMD, 37, "KIMD SHAKE-256") + DEF_FEAT(KIMD_GHASH, "kimd-ghash", KIMD, 65, "KIMD GHASH") ++DEF_FEAT(KIMD_QAI, "kimd-qai", KIMD, 127, "KIMD Query-Authentication-Information") + + /* Features exposed via the KLMD instruction. */ + DEF_FEAT(KLMD_SHA_1, "klmd-sha-1", KLMD, 1, "KLMD SHA-1") +@@ -269,6 +272,7 @@ DEF_FEAT(KLMD_SHA3_384, "klmd-sha3-384", KLMD, 34, "KLMD SHA3-384") + DEF_FEAT(KLMD_SHA3_512, "klmd-sha3-512", KLMD, 35, "KLMD SHA3-512") + DEF_FEAT(KLMD_SHAKE_128, "klmd-shake-128", KLMD, 36, "KLMD SHAKE-128") + DEF_FEAT(KLMD_SHAKE_256, "klmd-shake-256", KLMD, 37, "KLMD SHAKE-256") ++DEF_FEAT(KLMD_QAI, "klmd-qai", KLMD, 127, "KLMD Query-Authentication-Information") + + /* Features exposed via the PCKMO instruction. */ + DEF_FEAT(PCKMO_EDEA, "pckmo-edea", PCKMO, 1, "PCKMO Encrypted-DEA-Key") +@@ -286,6 +290,7 @@ DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC- + DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key") + DEF_FEAT(PCKMO_HMAC_512, "pckmo-hmac-512", PCKMO, 118, "PCKMO Encrypt-HMAC-512-Key") + DEF_FEAT(PCKMO_HMAC_1024, "pckmo-hmac-1024", PCKMO, 122, "PCKMO Encrypt-HMAC-1024-Key") ++DEF_FEAT(PCKMO_QAI, "pckmo-qai", PCKMO, 127, "PCKMO Query-Authentication-Information") + + /* Features exposed via the KMCTR instruction. */ + DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA") +@@ -300,6 +305,7 @@ DEF_FEAT(KMCTR_AES_256, "kmctr-aes-256", KMCTR, 20, "KMCTR AES-256") + DEF_FEAT(KMCTR_EAES_128, "kmctr-eaes-128", KMCTR, 26, "KMCTR Encrypted-AES-128") + DEF_FEAT(KMCTR_EAES_192, "kmctr-eaes-192", KMCTR, 27, "KMCTR Encrypted-AES-192") + DEF_FEAT(KMCTR_EAES_256, "kmctr-eaes-256", KMCTR, 28, "KMCTR Encrypted-AES-256") ++DEF_FEAT(KMCTR_QAI, "kmctr-qai", KMCTR, 127, "KMCTR Query-Authentication-Information") + + /* Features exposed via the KMF instruction. */ + DEF_FEAT(KMF_DEA, "kmf-dea", KMF, 1, "KMF DEA") +@@ -314,6 +320,7 @@ DEF_FEAT(KMF_AES_256, "kmf-aes-256", KMF, 20, "KMF AES-256") + DEF_FEAT(KMF_EAES_128, "kmf-eaes-128", KMF, 26, "KMF Encrypted-AES-128") + DEF_FEAT(KMF_EAES_192, "kmf-eaes-192", KMF, 27, "KMF Encrypted-AES-192") + DEF_FEAT(KMF_EAES_256, "kmf-eaes-256", KMF, 28, "KMF Encrypted-AES-256") ++DEF_FEAT(KMF_QAI, "kmf-qai", KMF, 127, "KMF Query-Authentication-Information") + + /* Features exposed via the KMO instruction. */ + DEF_FEAT(KMO_DEA, "kmo-dea", KMO, 1, "KMO DEA") +@@ -328,6 +335,7 @@ DEF_FEAT(KMO_AES_256, "kmo-aes-256", KMO, 20, "KMO AES-256") + DEF_FEAT(KMO_EAES_128, "kmo-eaes-128", KMO, 26, "KMO Encrypted-AES-128") + DEF_FEAT(KMO_EAES_192, "kmo-eaes-192", KMO, 27, "KMO Encrypted-AES-192") + DEF_FEAT(KMO_EAES_256, "kmo-eaes-256", KMO, 28, "KMO Encrypted-AES-256") ++DEF_FEAT(KMO_QAI, "kmo-qai", KMO, 127, "KMO Query-Authentication-Information") + + /* Features exposed via the PCC instruction. */ + DEF_FEAT(PCC_CMAC_DEA, "pcc-cmac-dea", PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA") +@@ -353,11 +361,13 @@ DEF_FEAT(PCC_SCALAR_MULT_ED25519, "pcc-scalar-mult-ed25519", PCC, 72, "PCC Scala + DEF_FEAT(PCC_SCALAR_MULT_ED448, "pcc-scalar-mult-ed448", PCC, 73, "PCC Scalar-Multiply-Ed448") + DEF_FEAT(PCC_SCALAR_MULT_X25519, "pcc-scalar-mult-x25519", PCC, 80, "PCC Scalar-Multiply-X25519") + DEF_FEAT(PCC_SCALAR_MULT_X448, "pcc-scalar-mult-x448", PCC, 81, "PCC Scalar-Multiply-X448") ++DEF_FEAT(PCC_QAI, "pcc-qai", PCC, 127, "PCC Query-Authentication-Information") + + /* Features exposed via the PPNO/PRNO instruction. */ + DEF_FEAT(PPNO_SHA_512_DRNG, "ppno-sha-512-drng", PPNO, 3, "PPNO SHA-512-DRNG") + DEF_FEAT(PRNO_TRNG_QRTCR, "prno-trng-qrtcr", PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio") + DEF_FEAT(PRNO_TRNG, "prno-trng", PPNO, 114, "PRNO TRNG") ++DEF_FEAT(PRNO_QAI, "prno-qai", PPNO, 127, "PRNO Query-Authentication-Information") + + /* Features exposed via the KMA instruction. */ + DEF_FEAT(KMA_GCM_AES_128, "kma-gcm-aes-128", KMA, 18, "KMA GCM-AES-128") +@@ -366,6 +376,7 @@ DEF_FEAT(KMA_GCM_AES_256, "kma-gcm-aes-256", KMA, 20, "KMA GCM-AES-256") + DEF_FEAT(KMA_GCM_EAES_128, "kma-gcm-eaes-128", KMA, 26, "KMA GCM-Encrypted-AES-128") + DEF_FEAT(KMA_GCM_EAES_192, "kma-gcm-eaes-192", KMA, 27, "KMA GCM-Encrypted-AES-192") + DEF_FEAT(KMA_GCM_EAES_256, "kma-gcm-eaes-256", KMA, 28, "KMA GCM-Encrypted-AES-256") ++DEF_FEAT(KMA_QAI, "kma-qai", KMA, 127, "KMA Query-Authentication-Information") + + /* Features exposed via the KDSA instruction. */ + DEF_FEAT(KDSA_ECDSA_VERIFY_P256, "kdsa-ecdsa-verify-p256", KDSA, 1, "KDSA ECDSA-Verify-P256") +@@ -383,6 +394,7 @@ DEF_FEAT(KDSA_EDDSA_SIGN_ED25519, "kdsa-eddsa-sign-ed25519", KDSA, 40, "KDSA EdD + DEF_FEAT(KDSA_EDDSA_SIGN_ED448, "kdsa-eddsa-sign-ed448", KDSA, 44, "KDSA EdDSA-Sign-Ed448") + DEF_FEAT(KDSA_EEDDSA_SIGN_ED25519, "kdsa-eeddsa-sign-ed25519", KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519") + DEF_FEAT(KDSA_EEDDSA_SIGN_ED448, "kdsa-eeddsa-sign-ed448", KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448") ++DEF_FEAT(KDSA_QAI, "kdsa-qai", KDSA, 127, "KDSA Query-Authentication-Information") + + /* Features exposed via the SORTL instruction. */ + DEF_FEAT(SORTL_SFLR, "sortl-sflr", SORTL, 1, "SORTL SFLR") +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index ab9ad51d5e..3326e7df43 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -273,6 +273,22 @@ + #define S390_FEAT_GROUP_MSA_EXT_12 \ + S390_FEAT_MSA_EXT_12 + ++#define S390_FEAT_GROUP_MSA_EXT_13 \ ++ S390_FEAT_KDSA_QAI, \ ++ S390_FEAT_KIMD_QAI, \ ++ S390_FEAT_KLMD_QAI, \ ++ S390_FEAT_KMAC_QAI, \ ++ S390_FEAT_KMA_QAI, \ ++ S390_FEAT_KMCTR_QAI, \ ++ S390_FEAT_KMF_QAI, \ ++ S390_FEAT_KMO_QAI, \ ++ S390_FEAT_KM_QAI, \ ++ S390_FEAT_PCC_QAI, \ ++ S390_FEAT_PRNO_QAI ++ ++#define S390_FEAT_GROUP_MSA_EXT_13_PCKMO \ ++ S390_FEAT_PCKMO_QAI ++ + #define S390_FEAT_GROUP_ENH_SORT \ + S390_FEAT_ESORT_BASE, \ + S390_FEAT_SORTL_SFLR, \ +@@ -346,6 +362,10 @@ static uint16_t group_MSA_EXT_12[] = { + S390_FEAT_GROUP_MSA_EXT_12, + }; + ++static uint16_t group_MSA_EXT_13[] = { ++ S390_FEAT_GROUP_MSA_EXT_13, ++}; ++ + static uint16_t group_MSA_EXT_9_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_9_PCKMO, + }; +@@ -358,6 +378,10 @@ static uint16_t group_MSA_EXT_11_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_11_PCKMO, + }; + ++static uint16_t group_MSA_EXT_13_PCKMO[] = { ++ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, ++}; ++ + static uint16_t group_ENH_SORT[] = { + S390_FEAT_GROUP_ENH_SORT, + }; +@@ -910,6 +934,8 @@ static FeatGroupDefSpec FeatGroupDef[] = { + FEAT_GROUP_INITIALIZER(MSA_EXT_11), + FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_12), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_13), ++ FEAT_GROUP_INITIALIZER(MSA_EXT_13_PCKMO), + FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), + FEAT_GROUP_INITIALIZER(ENH_SORT), + FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch b/SOURCES/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch new file mode 100644 index 0000000..5549f39 --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-correct-PLO-feature-wording.patch @@ -0,0 +1,69 @@ +From 148121817c34fa55226b2f02fd6d3f987e95fb3c Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:49 +0100 +Subject: [PATCH 14/19] s390x/cpumodel: correct PLO feature wording +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [14/16] a30038e374c8ee61d3c8f0546f55ec5ab5b73421 (thuth/qemu-kvm-cs9) + +The PLO functions 0, 4, 8, 12, 16, and 20 use 32-bit registers +values. The plo-*gr variants use 64-bit instead and, thus, correct +the wording. + +Signed-off-by: Hendrik Brueckner +Reviewed-by: Janosch Frank +Message-ID: <20241206122751.189721-14-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 5a0a136df71b858d01f346af4a30ae1da23e8b3c) +--- + target/s390x/cpu_features_def.h.inc | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc +index 09a80844a7..fe7e1bd19c 100644 +--- a/target/s390x/cpu_features_def.h.inc ++++ b/target/s390x/cpu_features_def.h.inc +@@ -158,27 +158,27 @@ DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed") + /* Features exposed via the PLO instruction. */ + DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)") + DEF_FEAT(PLO_CLG, "plo-clg", PLO, 1, "PLO Compare and load (64 bit in parameter list)") +-DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (32 bit in general registers)") ++DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (64 bit in general registers)") + DEF_FEAT(PLO_CLX, "plo-clx", PLO, 3, "PLO Compare and load (128 bit in parameter list)") + DEF_FEAT(PLO_CS, "plo-cs", PLO, 4, "PLO Compare and swap (32 bit in general registers)") + DEF_FEAT(PLO_CSG, "plo-csg", PLO, 5, "PLO Compare and swap (64 bit in parameter list)") +-DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (32 bit in general registers)") ++DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (64 bit in general registers)") + DEF_FEAT(PLO_CSX, "plo-csx", PLO, 7, "PLO Compare and swap (128 bit in parameter list)") + DEF_FEAT(PLO_DCS, "plo-dcs", PLO, 8, "PLO Double compare and swap (32 bit in general registers)") + DEF_FEAT(PLO_DCSG, "plo-dcsg", PLO, 9, "PLO Double compare and swap (64 bit in parameter list)") +-DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (32 bit in general registers)") ++DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (64 bit in general registers)") + DEF_FEAT(PLO_DCSX, "plo-dcsx", PLO, 11, "PLO Double compare and swap (128 bit in parameter list)") + DEF_FEAT(PLO_CSST, "plo-csst", PLO, 12, "PLO Compare and swap and store (32 bit in general registers)") + DEF_FEAT(PLO_CSSTG, "plo-csstg", PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)") +-DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (32 bit in general registers)") ++DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (64 bit in general registers)") + DEF_FEAT(PLO_CSSTX, "plo-csstx", PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)") + DEF_FEAT(PLO_CSDST, "plo-csdst", PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)") + DEF_FEAT(PLO_CSDSTG, "plo-csdstg", PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)") +-DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)") ++DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (64 bit in general registers)") + DEF_FEAT(PLO_CSDSTX, "plo-csdstx", PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)") + DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)") + DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)") +-DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)") ++DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (64 bit in general registers)") + DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)") + + /* Features exposed via the PTFF instruction. */ +-- +2.39.3 + diff --git a/SOURCES/kvm-s390x-cpumodel-gen17-model.patch b/SOURCES/kvm-s390x-cpumodel-gen17-model.patch new file mode 100644 index 0000000..8a63b9e --- /dev/null +++ b/SOURCES/kvm-s390x-cpumodel-gen17-model.patch @@ -0,0 +1,107 @@ +From 1b45ebaf1903c54a37f5a4324242cb17caf1064e Mon Sep 17 00:00:00 2001 +From: Hendrik Brueckner +Date: Fri, 6 Dec 2024 13:27:51 +0100 +Subject: [PATCH 16/19] s390x/cpumodel: gen17 model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 304: CPU model for new IBM Z gen17 hardware +RH-Jira: RHEL-50212 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Cornelia Huck +RH-Commit: [16/16] c8cc00616e56ab99971aa930938b8ee36f9a909b (thuth/qemu-kvm-cs9) + +This commit introduces the definition of the gen17a/gen17b CPU model. + +Signed-off-by: Hendrik Brueckner +Message-ID: <20241206122751.189721-16-brueckner@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 21b8db229901a51f16aebe342c0508f588ea5006) +--- + target/s390x/cpu_models.c | 2 ++ + target/s390x/gen-features.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index d2798c0f38..14c4d63a5a 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -97,6 +97,8 @@ static S390CPUDef s390_cpu_defs[] = { + CPUDEF_INIT(0x8562, 15, 1, 47, 0x08000000U, "gen15b", "IBM z15 T02 GA1"), + CPUDEF_INIT(0x3931, 16, 1, 47, 0x08000000U, "gen16a", "IBM 3931 GA1"), + CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"), ++ CPUDEF_INIT(0x9175, 17, 1, 47, 0x08000000U, "gen17a", "IBM 9175 GA1"), ++ CPUDEF_INIT(0x9176, 17, 1, 47, 0x08000000U, "gen17b", "IBM 9176 GA1"), + }; + + #define QEMU_MAX_CPU_TYPE 0x8561 +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 680d45d303..41840677ce 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -561,6 +561,13 @@ static uint16_t base_GEN15_GA1[] = { + + #define base_GEN16_GA1 EmptyFeat + ++static uint16_t base_GEN17_GA1[] = { ++ S390_FEAT_MISC_INSTRUCTION_EXT4, ++ S390_FEAT_SIF, ++ S390_FEAT_GROUP_MSA_EXT_12, ++ S390_FEAT_GROUP_PLO_EXT, ++}; ++ + /* Full features (in order of release) + * Automatically includes corresponding base features. + * Full features are all features this hardware supports even if kvm/QEMU do not +@@ -715,6 +722,20 @@ static uint16_t full_GEN16_GA1[] = { + S390_FEAT_UV_FEAT_AP_INTR, + }; + ++static uint16_t full_GEN17_GA1[] = { ++ S390_FEAT_VECTOR_ENH3, ++ S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, ++ S390_FEAT_INEFF_NC_TX, ++ S390_FEAT_GROUP_GEN17_PTFF, ++ S390_FEAT_GROUP_MSA_EXT_10, ++ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, ++ S390_FEAT_GROUP_MSA_EXT_11, ++ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, ++ S390_FEAT_GROUP_MSA_EXT_13, ++ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, ++ S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, ++}; ++ + + /* Default features (in order of release) + * Automatically includes corresponding base features. +@@ -810,6 +831,17 @@ static uint16_t default_GEN16_GA1[] = { + S390_FEAT_PAIE, + }; + ++static uint16_t default_GEN17_GA1[] = { ++ S390_FEAT_VECTOR_ENH3, ++ S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, ++ S390_FEAT_GROUP_MSA_EXT_10, ++ S390_FEAT_GROUP_MSA_EXT_10_PCKMO, ++ S390_FEAT_GROUP_MSA_EXT_11, ++ S390_FEAT_GROUP_MSA_EXT_11_PCKMO, ++ S390_FEAT_GROUP_MSA_EXT_13, ++ S390_FEAT_GROUP_MSA_EXT_13_PCKMO, ++}; ++ + /* QEMU (CPU model) features */ + + static uint16_t qemu_V2_11[] = { +@@ -958,6 +990,7 @@ static CpuFeatDefSpec CpuFeatDef[] = { + CPU_FEAT_INITIALIZER(GEN14_GA2), + CPU_FEAT_INITIALIZER(GEN15_GA1), + CPU_FEAT_INITIALIZER(GEN16_GA1), ++ CPU_FEAT_INITIALIZER(GEN17_GA1), + }; + + #define FEAT_GROUP_INITIALIZER(_name) \ +-- +2.39.3 + diff --git a/SOURCES/kvm-scripts-update-linux-header.sh-be-more-src-tree-frie.patch b/SOURCES/kvm-scripts-update-linux-header.sh-be-more-src-tree-frie.patch deleted file mode 100644 index 2c0fb91..0000000 --- a/SOURCES/kvm-scripts-update-linux-header.sh-be-more-src-tree-frie.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 3d197f42afea6d0b176c2b26b772965692ffeab3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Tue, 14 May 2024 18:42:44 +0100 -Subject: [PATCH 047/100] scripts/update-linux-header.sh: be more src tree - friendly -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [47/91] c4165cc8bf79c3f96912e8210b3bb3565add288f (bonzini/rhel-qemu-kvm) - -Running "install_headers" in the Linux source tree is fairly -unfriendly as out-of-tree builds will start complaining about the -kernel source being non-pristine. As we have a temporary directory for -the install we should also do the build step here. So now we have: - - $tmpdir/ - $blddir/ - $hdrdir/ - -Reviewed-by: Pierrick Bouvier -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Alex Bennée -Message-Id: <20240514174253.694591-3-alex.bennee@linaro.org> -(cherry picked from commit b51ddd937f11f76614d4b36d14d8778df242661c) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 80 +++++++++++++++++---------------- - 1 file changed, 41 insertions(+), 39 deletions(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index 5f20434d5c..4431ba4d54 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -27,6 +27,8 @@ - # types like "__u64". This work is done in the cp_portable function. - - tmpdir=$(mktemp -d) -+hdrdir="$tmpdir/headers" -+blddir="$tmpdir/build" - linux="$1" - output="$2" - -@@ -111,56 +113,56 @@ for arch in $ARCHLIST; do - arch_var=ARCH - fi - -- make -C "$linux" INSTALL_HDR_PATH="$tmpdir" $arch_var=$arch headers_install -+ make -C "$linux" O="$blddir" INSTALL_HDR_PATH="$hdrdir" $arch_var=$arch headers_install - - rm -rf "$output/linux-headers/asm-$arch" - mkdir -p "$output/linux-headers/asm-$arch" - for header in kvm.h unistd.h bitsperlong.h mman.h; do -- cp "$tmpdir/include/asm/$header" "$output/linux-headers/asm-$arch" -+ cp "$hdrdir/include/asm/$header" "$output/linux-headers/asm-$arch" - done - - if [ $arch = mips ]; then -- cp "$tmpdir/include/asm/sgidefs.h" "$output/linux-headers/asm-mips/" -- cp "$tmpdir/include/asm/unistd_o32.h" "$output/linux-headers/asm-mips/" -- cp "$tmpdir/include/asm/unistd_n32.h" "$output/linux-headers/asm-mips/" -- cp "$tmpdir/include/asm/unistd_n64.h" "$output/linux-headers/asm-mips/" -+ cp "$hdrdir/include/asm/sgidefs.h" "$output/linux-headers/asm-mips/" -+ cp "$hdrdir/include/asm/unistd_o32.h" "$output/linux-headers/asm-mips/" -+ cp "$hdrdir/include/asm/unistd_n32.h" "$output/linux-headers/asm-mips/" -+ cp "$hdrdir/include/asm/unistd_n64.h" "$output/linux-headers/asm-mips/" - fi - if [ $arch = powerpc ]; then -- cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-powerpc/" -- cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-powerpc/" -+ cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-powerpc/" -+ cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-powerpc/" - fi - - rm -rf "$output/include/standard-headers/asm-$arch" - mkdir -p "$output/include/standard-headers/asm-$arch" - if [ $arch = s390 ]; then -- cp_portable "$tmpdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" -- cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-s390/" -- cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-s390/" -+ cp_portable "$hdrdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" -+ cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-s390/" -+ cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-s390/" - fi - if [ $arch = arm ]; then -- cp "$tmpdir/include/asm/unistd-eabi.h" "$output/linux-headers/asm-arm/" -- cp "$tmpdir/include/asm/unistd-oabi.h" "$output/linux-headers/asm-arm/" -- cp "$tmpdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/" -+ cp "$hdrdir/include/asm/unistd-eabi.h" "$output/linux-headers/asm-arm/" -+ cp "$hdrdir/include/asm/unistd-oabi.h" "$output/linux-headers/asm-arm/" -+ cp "$hdrdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/" - fi - if [ $arch = arm64 ]; then -- cp "$tmpdir/include/asm/sve_context.h" "$output/linux-headers/asm-arm64/" -+ cp "$hdrdir/include/asm/sve_context.h" "$output/linux-headers/asm-arm64/" - fi - if [ $arch = x86 ]; then -- cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" -- cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" -- cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" -- cp_portable "$tmpdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch" -+ cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" -+ cp "$hdrdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" -+ cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" -+ cp_portable "$hdrdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch" - # Remove everything except the macros from bootparam.h avoiding the - # unnecessary import of several video/ist/etc headers - sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' \ -- "$tmpdir/include/asm/bootparam.h" > "$tmpdir/bootparam.h" -- cp_portable "$tmpdir/bootparam.h" \ -+ "$hdrdir/include/asm/bootparam.h" > "$hdrdir/bootparam.h" -+ cp_portable "$hdrdir/bootparam.h" \ - "$output/include/standard-headers/asm-$arch" -- cp_portable "$tmpdir/include/asm/setup_data.h" \ -+ cp_portable "$hdrdir/include/asm/setup_data.h" \ - "$output/standard-headers/asm-x86" - fi - if [ $arch = riscv ]; then -- cp "$tmpdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" -+ cp "$hdrdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" - fi - done - arch= -@@ -170,13 +172,13 @@ mkdir -p "$output/linux-headers/linux" - for header in const.h stddef.h kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \ - psci.h psp-sev.h userfaultfd.h memfd.h mman.h nvme_ioctl.h \ - vduse.h iommufd.h bits.h; do -- cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux" -+ cp "$hdrdir/include/linux/$header" "$output/linux-headers/linux" - done - - rm -rf "$output/linux-headers/asm-generic" - mkdir -p "$output/linux-headers/asm-generic" - for header in unistd.h bitsperlong.h mman-common.h mman.h hugetlb_encode.h; do -- cp "$tmpdir/include/asm-generic/$header" "$output/linux-headers/asm-generic" -+ cp "$hdrdir/include/asm-generic/$header" "$output/linux-headers/asm-generic" - done - - if [ -L "$linux/source" ]; then -@@ -211,23 +213,23 @@ EOF - - rm -rf "$output/include/standard-headers/linux" - mkdir -p "$output/include/standard-headers/linux" --for i in "$tmpdir"/include/linux/*virtio*.h \ -- "$tmpdir/include/linux/qemu_fw_cfg.h" \ -- "$tmpdir/include/linux/fuse.h" \ -- "$tmpdir/include/linux/input.h" \ -- "$tmpdir/include/linux/input-event-codes.h" \ -- "$tmpdir/include/linux/udmabuf.h" \ -- "$tmpdir/include/linux/pci_regs.h" \ -- "$tmpdir/include/linux/ethtool.h" \ -- "$tmpdir/include/linux/const.h" \ -- "$tmpdir/include/linux/kernel.h" \ -- "$tmpdir/include/linux/vhost_types.h" \ -- "$tmpdir/include/linux/sysinfo.h" \ -- "$tmpdir/include/misc/pvpanic.h"; do -+for i in "$hdrdir"/include/linux/*virtio*.h \ -+ "$hdrdir/include/linux/qemu_fw_cfg.h" \ -+ "$hdrdir/include/linux/fuse.h" \ -+ "$hdrdir/include/linux/input.h" \ -+ "$hdrdir/include/linux/input-event-codes.h" \ -+ "$hdrdir/include/linux/udmabuf.h" \ -+ "$hdrdir/include/linux/pci_regs.h" \ -+ "$hdrdir/include/linux/ethtool.h" \ -+ "$hdrdir/include/linux/const.h" \ -+ "$hdrdir/include/linux/kernel.h" \ -+ "$hdrdir/include/linux/vhost_types.h" \ -+ "$hdrdir/include/linux/sysinfo.h" \ -+ "$hdrdir/include/misc/pvpanic.h"; do - cp_portable "$i" "$output/include/standard-headers/linux" - done - mkdir -p "$output/include/standard-headers/drm" --cp_portable "$tmpdir/include/drm/drm_fourcc.h" \ -+cp_portable "$hdrdir/include/drm/drm_fourcc.h" \ - "$output/include/standard-headers/drm" - - rm -rf "$output/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma" --- -2.39.3 - diff --git a/SOURCES/kvm-scripts-update-linux-headers-Add-bits.h-to-file-impo.patch b/SOURCES/kvm-scripts-update-linux-headers-Add-bits.h-to-file-impo.patch deleted file mode 100644 index eea324e..0000000 --- a/SOURCES/kvm-scripts-update-linux-headers-Add-bits.h-to-file-impo.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 5db9faee4d6efc9dbe010d2b745aba59d943d2ac Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Wed, 21 Feb 2024 10:51:38 -0600 -Subject: [PATCH 016/100] scripts/update-linux-headers: Add bits.h to file - imports - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [16/91] 150ee6376982bd5f471cb561f6760bf80d1211db (bonzini/rhel-qemu-kvm) - -Signed-off-by: Michael Roth -Signed-off-by: Paolo Bonzini -(cherry picked from commit b40b8eb609d3549ac14aab43849b20f5cba951c9) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index d48856f9e2..5f20434d5c 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -169,7 +169,7 @@ rm -rf "$output/linux-headers/linux" - mkdir -p "$output/linux-headers/linux" - for header in const.h stddef.h kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \ - psci.h psp-sev.h userfaultfd.h memfd.h mman.h nvme_ioctl.h \ -- vduse.h iommufd.h; do -+ vduse.h iommufd.h bits.h; do - cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux" - done - --- -2.39.3 - diff --git a/SOURCES/kvm-scripts-update-linux-headers-Add-setup_data.h-to-imp.patch b/SOURCES/kvm-scripts-update-linux-headers-Add-setup_data.h-to-imp.patch deleted file mode 100644 index 86c1f9c..0000000 --- a/SOURCES/kvm-scripts-update-linux-headers-Add-setup_data.h-to-imp.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 2d0989fe09703ef46ba9c5d14770dbf8a6fd2f80 Mon Sep 17 00:00:00 2001 -From: Michael Roth -Date: Sun, 18 Feb 2024 23:35:02 -0600 -Subject: [PATCH 015/100] scripts/update-linux-headers: Add setup_data.h to - import list - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [15/91] 9d46c8787259317710a84e7a6aa36731e9f55a17 (bonzini/rhel-qemu-kvm) - -Data structures like struct setup_data have been moved to a separate -setup_data.h header which bootparam.h relies on. Add setup_data.h to -the cp_portable() list and sync it along with the other header files. - -Note that currently struct setup_data is stripped away as part of -generating bootparam.h, but that handling is no currently needed for -setup_data.h since it doesn't pull in many external -headers/dependencies. However, QEMU currently redefines struct -setup_data in hw/i386/x86.c, so that will need to be removed as part of -any header update that pulls in the new setup_data.h to avoid build -bisect breakage. - -Because is the first architecture specific #include -in include/standard-headers/, add a new sed substitution to rewrite -asm/ include to the standard-headers/asm-* subdirectory for the current -architecture. - -And while at it, remove asm-generic/kvm_para.h from the list of -allowed includes: it does not have a matching substitution, and therefore -it would not be possible to use it on non-Linux systems where there is -no /usr/include/asm-generic/ directory. - -Signed-off-by: Michael Roth -Signed-off-by: Paolo Bonzini -(cherry picked from commit 66210a1a30f2384bb59f9dad8d769dba56dd30f1) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index a0006eec6f..d48856f9e2 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -61,7 +61,7 @@ cp_portable() { - -e 'linux/const' \ - -e 'linux/kernel' \ - -e 'linux/sysinfo' \ -- -e 'asm-generic/kvm_para' \ -+ -e 'asm/setup_data.h' \ - > /dev/null - then - echo "Unexpected #include in input file $f". -@@ -77,6 +77,7 @@ cp_portable() { - -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/"\(input-event-codes\.h\)"/"standard-headers\/linux\/\1"/' \ - -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ -+ -e 's/]*\)>/"standard-headers\/asm-'$arch'\/\1"/' \ - -e 's/__bitwise//' \ - -e 's/__attribute__((packed))/QEMU_PACKED/' \ - -e 's/__inline__/inline/' \ -@@ -155,11 +156,14 @@ for arch in $ARCHLIST; do - "$tmpdir/include/asm/bootparam.h" > "$tmpdir/bootparam.h" - cp_portable "$tmpdir/bootparam.h" \ - "$output/include/standard-headers/asm-$arch" -+ cp_portable "$tmpdir/include/asm/setup_data.h" \ -+ "$output/standard-headers/asm-x86" - fi - if [ $arch = riscv ]; then - cp "$tmpdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" - fi - done -+arch= - - rm -rf "$output/linux-headers/linux" - mkdir -p "$output/linux-headers/linux" --- -2.39.3 - diff --git a/SOURCES/kvm-scripts-update-linux-headers.sh-Fix-the-path-of-setu.patch b/SOURCES/kvm-scripts-update-linux-headers.sh-Fix-the-path-of-setu.patch deleted file mode 100644 index ecd631a..0000000 --- a/SOURCES/kvm-scripts-update-linux-headers.sh-Fix-the-path-of-setu.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 09acdbc49a4dd85d82ad30ec2859edfcdba8431e Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Mon, 27 May 2024 08:01:26 +0200 -Subject: [PATCH 049/100] scripts/update-linux-headers.sh: Fix the path of - setup_data.h - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [49/91] f3008bc07796687c9440f5720fbc72a12d0a1278 (bonzini/rhel-qemu-kvm) - -When running the update-linx-headers.sh script, it currently fails with: - -scripts/update-linux-headers.sh: line 73: .../qemu/standard-headers/asm-x86/setup_data.h: No such file or directory - -The "include" folder is obviously missing here - no clue how this could -have worked before? - -Fixes: 66210a1a30 ("scripts/update-linux-headers: Add setup_data.h to import list") -Message-ID: <20240527060126.12578-1-thuth@redhat.com> -Reviewed-by: Cornelia Huck -Signed-off-by: Thomas Huth -(cherry picked from commit bde26d90ae9f7551cac90e117fc7216c807a3bfe) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index 0f404d5317..f084bee72e 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -160,7 +160,7 @@ for arch in $ARCHLIST; do - cp_portable "$hdrdir/bootparam.h" \ - "$output/include/standard-headers/asm-$arch" - cp_portable "$hdrdir/include/asm/setup_data.h" \ -- "$output/standard-headers/asm-x86" -+ "$output/include/standard-headers/asm-x86" - fi - if [ $arch = riscv ]; then - cp "$hdrdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" --- -2.39.3 - diff --git a/SOURCES/kvm-scripts-update-linux-headers.sh-Remove-temporary-dir.patch b/SOURCES/kvm-scripts-update-linux-headers.sh-Remove-temporary-dir.patch deleted file mode 100644 index c7dbd3a..0000000 --- a/SOURCES/kvm-scripts-update-linux-headers.sh-Remove-temporary-dir.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 8e63d742015bf69a00fd44e88eb1198f594b2de2 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Mon, 27 May 2024 08:02:43 +0200 -Subject: [PATCH 048/100] scripts/update-linux-headers.sh: Remove temporary - directory inbetween - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [48/91] 879554dc7e722c4e20b302a00ca745ddeefdc0fb (bonzini/rhel-qemu-kvm) - -We are reusing the same temporary directory for installing the headers -of all targets, so there could be stale files here when switching from -one target to another. Make sure to delete the folder before installing -a new set of target headers into it. - -Message-ID: <20240527060243.12647-1-thuth@redhat.com> -Reviewed-by: Michael S. Tsirkin -Acked-by: Cornelia Huck -Signed-off-by: Thomas Huth -(cherry picked from commit 3efc75ad9d9317e5709861bbebb2c29390f8e7a2) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index 4431ba4d54..0f404d5317 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -113,6 +113,7 @@ for arch in $ARCHLIST; do - arch_var=ARCH - fi - -+ rm -rf "$hdrdir" - make -C "$linux" O="$blddir" INSTALL_HDR_PATH="$hdrdir" $arch_var=$arch headers_install - - rm -rf "$output/linux-headers/asm-$arch" --- -2.39.3 - diff --git a/SOURCES/kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch b/SOURCES/kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch deleted file mode 100644 index a7eebbc..0000000 --- a/SOURCES/kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d580b83d9eda7802ffa3890ea8641793fe78937c Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 31 Jul 2024 14:32:05 +0200 -Subject: [PATCH 094/100] scsi-block: Don't skip callback for sgio error - status/driver_status - -RH-Author: Kevin Wolf -RH-MergeRequest: 261: scsi-block: Fix error handling with r/werror=stop -RH-Jira: RHEL-50000 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [2/4] 1fee1b21dae314f4f34c88f2d2fabd7af011404a (kmwolf/centos-qemu-kvm) - -Instead of calling into scsi_handle_rw_error() directly from -scsi_block_sgio_complete() and skipping the normal callback, go through -the normal cleanup path by calling the callback with a positive error -value. - -The important difference here is not only that the code path is cleaner, -but that the callbacks set r->req.aiocb = NULL. If we skip setting this -and the error action is BLOCK_ERROR_ACTION_STOP, resuming the VM runs -into an assertion failure in scsi_read_data() or scsi_write_data() -because the dangling aiocb pointer is unexpected. - -Fixes: a108557bbf ("scsi: inline sg_io_sense_from_errno() into the callers.") -Buglink: https://issues.redhat.com/browse/RHEL-50000 -Signed-off-by: Kevin Wolf -Acked-by: Paolo Bonzini -Message-ID: <20240731123207.27636-3-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 622a70161ac258e4a166a7dca4b5be267e0652d9) -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index bed2c8746c..e7f57f3230 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -2804,16 +2804,6 @@ static void scsi_block_sgio_complete(void *opaque, int ret) - } else { - ret = io_hdr->status; - } -- -- if (ret > 0) { -- if (scsi_handle_rw_error(r, ret, true)) { -- scsi_req_unref(&r->req); -- return; -- } -- -- /* Ignore error. */ -- ret = 0; -- } - } - - req->cb(req->cb_opaque, ret); --- -2.39.3 - diff --git a/SOURCES/kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch b/SOURCES/kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch deleted file mode 100644 index 20aa88a..0000000 --- a/SOURCES/kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch +++ /dev/null @@ -1,79 +0,0 @@ -From eebe5fe8cbc854a6365e7c1adbb701079b137bcb Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 31 Jul 2024 14:32:06 +0200 -Subject: [PATCH 095/100] scsi-disk: Add warning comments that host_status - errors take a shortcut - -RH-Author: Kevin Wolf -RH-MergeRequest: 261: scsi-block: Fix error handling with r/werror=stop -RH-Jira: RHEL-50000 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [3/4] 6fcd603fc78fda65a425a1acd9a8710d81c6ed7f (kmwolf/centos-qemu-kvm) - -scsi_block_sgio_complete() has surprising behaviour in that there are -error cases in which it directly completes the request and never calls -the passed callback. In the current state of the code, this doesn't seem -to result in bugs, but with future code changes, we must be careful to -never rely on the callback doing some cleanup until this code smell is -fixed. For now, just add warnings to make people aware of the trap. - -Signed-off-by: Kevin Wolf -Acked-by: Paolo Bonzini -Message-ID: <20240731123207.27636-4-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 8a0495624f23f8f01dfb1484f367174f3b3572e8) -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index e7f57f3230..b4062ac2ff 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -65,6 +65,9 @@ struct SCSIDiskClass { - /* - * Callbacks receive ret == 0 for success. Errors are represented either as - * negative errno values, or as positive SAM status codes. -+ * -+ * Beware: For errors returned in host_status, the function may directly -+ * complete the request and never call the callback. - */ - DMAIOFunc *dma_readv; - DMAIOFunc *dma_writev; -@@ -359,6 +362,7 @@ done: - scsi_req_unref(&r->req); - } - -+/* May not be called in all error cases, don't rely on cleanup here */ - static void scsi_dma_complete(void *opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; -@@ -399,6 +403,7 @@ done: - scsi_req_unref(&r->req); - } - -+/* May not be called in all error cases, don't rely on cleanup here */ - static void scsi_read_complete(void *opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; -@@ -538,6 +543,7 @@ done: - scsi_req_unref(&r->req); - } - -+/* May not be called in all error cases, don't rely on cleanup here */ - static void scsi_write_complete(void * opaque, int ret) - { - SCSIDiskReq *r = (SCSIDiskReq *)opaque; -@@ -2793,6 +2799,7 @@ static void scsi_block_sgio_complete(void *opaque, int ret) - sg_io_hdr_t *io_hdr = &req->io_header; - - if (ret == 0) { -+ /* FIXME This skips calling req->cb() and any cleanup in it */ - if (io_hdr->host_status != SCSI_HOST_OK) { - scsi_req_complete_failed(&r->req, io_hdr->host_status); - scsi_req_unref(&r->req); --- -2.39.3 - diff --git a/SOURCES/kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch b/SOURCES/kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch deleted file mode 100644 index 0e2aeaf..0000000 --- a/SOURCES/kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch +++ /dev/null @@ -1,106 +0,0 @@ -From bd5cace452183053e356a27317c759ecfe0391aa Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 31 Jul 2024 14:32:07 +0200 -Subject: [PATCH 096/100] scsi-disk: Always report RESERVATION_CONFLICT to - guest - -RH-Author: Kevin Wolf -RH-MergeRequest: 261: scsi-block: Fix error handling with r/werror=stop -RH-Jira: RHEL-50000 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [4/4] eb4142071e5cbe385a949a6c48b0c8f8c6086918 (kmwolf/centos-qemu-kvm) - -In the case of scsi-block, RESERVATION_CONFLICT is not a backend error, -but indicates that the guest tried to make a request that it isn't -allowed to execute. Pass the error to the guest so that it can decide -what to do with it. - -Without this, if we stop the VM in response to a RESERVATION_CONFLICT -(as is the default policy in management software such as oVirt or -KubeVirt), it can happen that the VM cannot be resumed any more because -every attempt to resume it immediately runs into the same error and -stops the VM again. - -One case that expects RESERVATION_CONFLICT errors to be visible in the -guest is running the validation tests in Windows 2019's Failover Cluster -Manager, which intentionally tries to execute invalid requests to see if -they are properly rejected. - -Buglink: https://issues.redhat.com/browse/RHEL-50000 -Signed-off-by: Kevin Wolf -Acked-by: Paolo Bonzini -Message-ID: <20240731123207.27636-5-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit 9da6bd39f92434f55573acd017841b195c60188f) -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 35 ++++++++++++++++++++++++++++++----- - 1 file changed, 30 insertions(+), 5 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index b4062ac2ff..91ccf37fef 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -202,7 +202,7 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); - SCSISense sense = SENSE_CODE(NO_SENSE); -- int error = 0; -+ int error; - bool req_has_sense = false; - BlockErrorAction action; - int status; -@@ -213,11 +213,35 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - } else { - /* A passthrough command has completed with nonzero status. */ - status = ret; -- if (status == CHECK_CONDITION) { -+ switch (status) { -+ case CHECK_CONDITION: - req_has_sense = true; - error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense)); -- } else { -+ break; -+ case RESERVATION_CONFLICT: -+ /* -+ * Don't apply the error policy, always report to the guest. -+ * -+ * This is a passthrough code path, so it's not a backend error, but -+ * a response to an invalid guest request. -+ * -+ * Windows Failover Cluster validation intentionally sends invalid -+ * requests to verify that reservations work as intended. It is -+ * crucial that it sees the resulting errors. -+ * -+ * Treating a reservation conflict as a guest-side error is obvious -+ * when a pr-manager is in use. Without one, the situation is less -+ * clear, but there might be nothing that can be fixed on the host -+ * (like in the above example), and we don't want to be stuck in a -+ * loop where resuming the VM and retrying the request immediately -+ * stops it again. So always reporting is still the safer option in -+ * this case, too. -+ */ -+ error = 0; -+ break; -+ default: - error = EINVAL; -+ break; - } - } - -@@ -227,8 +251,9 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - * are usually retried immediately, so do not post them to QMP and - * do not account them as failed I/O. - */ -- if (req_has_sense && -- scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) { -+ if (!error || (req_has_sense && -+ scsi_sense_buf_is_guest_recoverable(r->req.sense, -+ sizeof(r->req.sense)))) { - action = BLOCK_ERROR_ACTION_REPORT; - acct_failed = false; - } else { --- -2.39.3 - diff --git a/SOURCES/kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch b/SOURCES/kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch deleted file mode 100644 index 409028a..0000000 --- a/SOURCES/kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 1a0aa9bbdad63d72628002740410b8a28282a96e Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 31 Jul 2024 14:32:04 +0200 -Subject: [PATCH 093/100] scsi-disk: Use positive return value for status in - dma_readv/writev - -RH-Author: Kevin Wolf -RH-MergeRequest: 261: scsi-block: Fix error handling with r/werror=stop -RH-Jira: RHEL-50000 -RH-Acked-by: Hanna Czenczek -RH-Acked-by: Stefan Hajnoczi -RH-Commit: [1/4] a0b3e7bfd7b7059c0ec3706f2eb1698c1d430b08 (kmwolf/centos-qemu-kvm) - -In some error cases, scsi_block_sgio_complete() never calls the passed -callback, but directly completes the request. This leads to bugs because -its error paths are not exact copies of what the callback would normally -do. - -In preparation to fix this, allow passing positive return values to the -callbacks that represent the status code that should be used to complete -the request. - -scsi_handle_rw_error() already handles positive values for its ret -parameter because scsi_block_sgio_complete() calls directly into it. - -Signed-off-by: Kevin Wolf -Acked-by: Paolo Bonzini -Message-ID: <20240731123207.27636-2-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit cfe0880835cd364b590ffd27ef8dbd2ad8838bc5) -Signed-off-by: Kevin Wolf ---- - hw/scsi/scsi-disk.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 4bd7af9d0c..bed2c8746c 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -62,6 +62,10 @@ OBJECT_DECLARE_TYPE(SCSIDiskState, SCSIDiskClass, SCSI_DISK_BASE) - - struct SCSIDiskClass { - SCSIDeviceClass parent_class; -+ /* -+ * Callbacks receive ret == 0 for success. Errors are represented either as -+ * negative errno values, or as positive SAM status codes. -+ */ - DMAIOFunc *dma_readv; - DMAIOFunc *dma_writev; - bool (*need_fua_emulation)(SCSICommand *cmd); -@@ -261,7 +265,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) - return true; - } - -- if (ret < 0) { -+ if (ret != 0) { - return scsi_handle_rw_error(r, ret, acct_failed); - } - -@@ -338,7 +342,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r) - static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret) - { - assert(r->req.aiocb == NULL); -- if (scsi_disk_req_check_error(r, ret, false)) { -+ if (scsi_disk_req_check_error(r, ret, ret > 0)) { - goto done; - } - -@@ -363,9 +367,10 @@ static void scsi_dma_complete(void *opaque, int ret) - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */ - if (ret < 0) { - block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); -- } else { -+ } else if (ret == 0) { - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - } - scsi_dma_complete_noio(r, ret); -@@ -381,7 +386,7 @@ static void scsi_read_complete_noio(SCSIDiskReq *r, int ret) - qemu_get_current_aio_context()); - - assert(r->req.aiocb == NULL); -- if (scsi_disk_req_check_error(r, ret, false)) { -+ if (scsi_disk_req_check_error(r, ret, ret > 0)) { - goto done; - } - -@@ -402,9 +407,10 @@ static void scsi_read_complete(void *opaque, int ret) - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - -+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */ - if (ret < 0) { - block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); -- } else { -+ } else if (ret == 0) { - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - trace_scsi_disk_read_complete(r->req.tag, r->qiov.size); - } -@@ -512,7 +518,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret) - qemu_get_current_aio_context()); - - assert (r->req.aiocb == NULL); -- if (scsi_disk_req_check_error(r, ret, false)) { -+ if (scsi_disk_req_check_error(r, ret, ret > 0)) { - goto done; - } - -@@ -540,9 +546,10 @@ static void scsi_write_complete(void * opaque, int ret) - assert (r->req.aiocb != NULL); - r->req.aiocb = NULL; - -+ /* ret > 0 is accounted for in scsi_disk_req_check_error() */ - if (ret < 0) { - block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); -- } else { -+ } else if (ret == 0) { - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - } - scsi_write_complete_noio(r, ret); --- -2.39.3 - diff --git a/SOURCES/kvm-scsi-fix-allocation-for-s390x-loadparm.patch b/SOURCES/kvm-scsi-fix-allocation-for-s390x-loadparm.patch new file mode 100644 index 0000000..d2a9833 --- /dev/null +++ b/SOURCES/kvm-scsi-fix-allocation-for-s390x-loadparm.patch @@ -0,0 +1,48 @@ +From 15f5e84210537514394b18e9dc6c710ad1218ecd Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 19 Nov 2024 22:31:22 +0100 +Subject: [PATCH 06/10] scsi: fix allocation for s390x loadparm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 298: [c9s] Fixes for the new s390x "boot order" feature +RH-Jira: RHEL-68440 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/8] 6a0e420261eb0521d4f979d2a6c250ee4aae7606 (thuth/qemu-kvm-cs9) + +Coverity reports a possible buffer overrun due to a non-NUL-terminated +string in scsi_property_set_loadparm(). While things are not so easy, +because qdev_prop_sanitize_s390x_loadparm is designed to operate on a +buffer that is not NUL-terminated, in this case the string *does* have +to be NUL-terminated because it is read by scsi_property_get_loadparm +and s390_build_iplb. + +Reviewed-by: jrossi@linux.ibm.com +Cc: thuth@redhat.com +Fixes: 429442e52d9 ("hw: Add "loadparm" property to scsi disk devices for booting on s390x", 2024-11-18) +Signed-off-by: Paolo Bonzini +(cherry picked from commit b73d7eff1eedb2399cd594bc872d5db13506d951) +Signed-off-by: Thomas Huth +--- + hw/scsi/scsi-disk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index 7566a5f531..de0c295173 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -3152,7 +3152,7 @@ static void scsi_property_set_loadparm(Object *obj, const char *value, + return; + } + +- lp_str = g_malloc0(strlen(value)); ++ lp_str = g_malloc0(strlen(value) + 1); + if (!qdev_prop_sanitize_s390x_loadparm(lp_str, value, errp)) { + g_free(lp_str); + return; +-- +2.39.3 + diff --git a/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch b/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch new file mode 100644 index 0000000..668cefa --- /dev/null +++ b/SOURCES/kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch @@ -0,0 +1,56 @@ +From bc3752c831177ce5a57121b6a7f6753e024b211c Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:32 +0800 +Subject: [PATCH 07/11] target/i386: Add AVX512 state when AVX10 is supported + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [7/9] 6c1875f13c0d3224e8afe7d03ef3681285f85c98 (bonzini/rhel-qemu-kvm) + +AVX10 state enumeration in CPUID leaf D and enabling in XCR0 register +are identical to AVX512 state regardless of the supported vector lengths. + +Given that some E-cores will support AVX10 but not support AVX512, add +AVX512 state components to guest when AVX10 is enabled. + +Based on a patch by Tao Su + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Tested-by: Xuelian Guo +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241031085233.425388-8-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 0d7475be3b402c25d74c5a4573cbeb733c8f3559) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 71d1f362e2..5042cbaa0e 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -7142,7 +7142,15 @@ static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa) + return false; + } + +- return (env->features[esa->feature] & esa->bits); ++ if (env->features[esa->feature] & esa->bits) { ++ return true; ++ } ++ if (esa->feature == FEAT_7_0_EBX && esa->bits == CPUID_7_0_EBX_AVX512F ++ && (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10)) { ++ return true; ++ } ++ ++ return false; + } + + static void x86_cpu_reset_hold(Object *obj, ResetType type) +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch b/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch new file mode 100644 index 0000000..b6a87af --- /dev/null +++ b/SOURCES/kvm-target-i386-Add-feature-dependencies-for-AVX10.patch @@ -0,0 +1,89 @@ +From eaa0a5dae408cb2848fcd2a8fe3999cba992ddef Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:31 +0800 +Subject: [PATCH 06/11] target/i386: Add feature dependencies for AVX10 + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [6/9] cbe290c488128b5b5a8f11b29d90399fb6172c57 (bonzini/rhel-qemu-kvm) + +Since the highest supported vector length for a processor implies that +all lesser vector lengths are also supported, add the dependencies of +the supported vector lengths. If all vector lengths aren't supported, +clear AVX10 enable bit as well. + +Note that the order of AVX10 related dependencies should be kept as: + CPUID_24_0_EBX_AVX10_128 -> CPUID_24_0_EBX_AVX10_256, + CPUID_24_0_EBX_AVX10_256 -> CPUID_24_0_EBX_AVX10_512, + CPUID_24_0_EBX_AVX10_VL_MASK -> CPUID_7_1_EDX_AVX10, + CPUID_7_1_EDX_AVX10 -> CPUID_24_0_EBX, +so that prevent user from setting weird CPUID combinations, e.g. 256-bits +and 512-bits are supported but 128-bits is not, no vector lengths are +supported but AVX10 enable bit is still set. + +Since AVX10_128 will be reserved as 1, adding these dependencies has the +bonus that when user sets -cpu host,-avx10-128, CPUID_7_1_EDX_AVX10 and +CPUID_24_0_EBX will be disabled automatically. + +Tested-by: Xuelian Guo +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-5-tao1.su@linux.intel.com +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +Link: https://lore.kernel.org/r/20241031085233.425388-7-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 150ab84b2d0083e6af344cca70290614d4fe568d) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 16 ++++++++++++++++ + target/i386/cpu.h | 4 ++++ + 2 files changed, 20 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index b6021be50d..71d1f362e2 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1766,6 +1766,22 @@ static FeatureDep feature_dependencies[] = { + .from = { FEAT_7_0_EBX, CPUID_7_0_EBX_SGX }, + .to = { FEAT_SGX_12_1_EAX, ~0ull }, + }, ++ { ++ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_128 }, ++ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 }, ++ }, ++ { ++ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_256 }, ++ .to = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_512 }, ++ }, ++ { ++ .from = { FEAT_24_0_EBX, CPUID_24_0_EBX_AVX10_VL_MASK }, ++ .to = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 }, ++ }, ++ { ++ .from = { FEAT_7_1_EDX, CPUID_7_1_EDX_AVX10 }, ++ .to = { FEAT_24_0_EBX, ~0ull }, ++ }, + }; + + typedef struct X86RegisterInfo32 { +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index c60290b8d5..4da9ed5930 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -997,6 +997,10 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_24_0_EBX_AVX10_256 (1U << 17) + /* AVX10 512-bit vector support is present */ + #define CPUID_24_0_EBX_AVX10_512 (1U << 18) ++/* AVX10 vector length support mask */ ++#define CPUID_24_0_EBX_AVX10_VL_MASK (CPUID_24_0_EBX_AVX10_128 | \ ++ CPUID_24_0_EBX_AVX10_256 | \ ++ CPUID_24_0_EBX_AVX10_512) + + /* RAS Features */ + #define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0) +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-Add-new-CPU-model-SierraForest.patch b/SOURCES/kvm-target-i386-Add-new-CPU-model-SierraForest.patch deleted file mode 100644 index c72f290..0000000 --- a/SOURCES/kvm-target-i386-Add-new-CPU-model-SierraForest.patch +++ /dev/null @@ -1,215 +0,0 @@ -From d9595fecd03c9a69ac562e3f240d50b2fa8d14a4 Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Wed, 20 Mar 2024 10:10:44 +0800 -Subject: [PATCH 006/100] target/i386: Add new CPU model SierraForest -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [6/91] 4bc71f82c258db46569a7e08965d1d358b19416c (bonzini/rhel-qemu-kvm) - -According to table 1-2 in Intel Architecture Instruction Set Extensions and -Future Features (rev 051) [1], SierraForest has the following new features -which have already been virtualized: - -- CMPCCXADD CPUID.(EAX=7,ECX=1):EAX[bit 7] -- AVX-IFMA CPUID.(EAX=7,ECX=1):EAX[bit 23] -- AVX-VNNI-INT8 CPUID.(EAX=7,ECX=1):EDX[bit 4] -- AVX-NE-CONVERT CPUID.(EAX=7,ECX=1):EDX[bit 5] - -Add above features to new CPU model SierraForest. Comparing with GraniteRapids -CPU model, SierraForest bare-metal removes the following features: - -- HLE CPUID.(EAX=7,ECX=0):EBX[bit 4] -- RTM CPUID.(EAX=7,ECX=0):EBX[bit 11] -- AVX512F CPUID.(EAX=7,ECX=0):EBX[bit 16] -- AVX512DQ CPUID.(EAX=7,ECX=0):EBX[bit 17] -- AVX512_IFMA CPUID.(EAX=7,ECX=0):EBX[bit 21] -- AVX512CD CPUID.(EAX=7,ECX=0):EBX[bit 28] -- AVX512BW CPUID.(EAX=7,ECX=0):EBX[bit 30] -- AVX512VL CPUID.(EAX=7,ECX=0):EBX[bit 31] -- AVX512_VBMI CPUID.(EAX=7,ECX=0):ECX[bit 1] -- AVX512_VBMI2 CPUID.(EAX=7,ECX=0):ECX[bit 6] -- AVX512_VNNI CPUID.(EAX=7,ECX=0):ECX[bit 11] -- AVX512_BITALG CPUID.(EAX=7,ECX=0):ECX[bit 12] -- AVX512_VPOPCNTDQ CPUID.(EAX=7,ECX=0):ECX[bit 14] -- LA57 CPUID.(EAX=7,ECX=0):ECX[bit 16] -- TSXLDTRK CPUID.(EAX=7,ECX=0):EDX[bit 16] -- AMX-BF16 CPUID.(EAX=7,ECX=0):EDX[bit 22] -- AVX512_FP16 CPUID.(EAX=7,ECX=0):EDX[bit 23] -- AMX-TILE CPUID.(EAX=7,ECX=0):EDX[bit 24] -- AMX-INT8 CPUID.(EAX=7,ECX=0):EDX[bit 25] -- AVX512_BF16 CPUID.(EAX=7,ECX=1):EAX[bit 5] -- fast zero-length MOVSB CPUID.(EAX=7,ECX=1):EAX[bit 10] -- fast short CMPSB, SCASB CPUID.(EAX=7,ECX=1):EAX[bit 12] -- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] -- PREFETCHI CPUID.(EAX=7,ECX=1):EDX[bit 14] -- XFD CPUID.(EAX=0xD,ECX=1):EAX[bit 4] -- EPT_PAGE_WALK_LENGTH_5 VMX_EPT_VPID_CAP(0x48c)[bit 7] - -Add all features of GraniteRapids CPU model except above features to -SierraForest CPU model. - -SierraForest doesn’t support TSX and RTM but supports TAA_NO. When RTM is -not enabled in host, KVM will not report TAA_NO. So, just don't include -TAA_NO in SierraForest CPU model. - -[1] https://cdrdv2.intel.com/v1/dl/getContent/671368 - -Reviewed-by: Zhao Liu -Reviewed-by: Xiaoyao Li -Signed-off-by: Tao Su -Message-ID: <20240320021044.508263-1-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 6e82d3b6220777667968a04c87e1667f164ebe88) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 126 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 0aa88d9b48..efbadc3ed7 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4127,6 +4127,132 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ }, - }, - }, -+ { -+ .name = "SierraForest", -+ .level = 0x23, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 175, -+ .stepping = 0, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | -+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | -+ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | -+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB | -+ CPUID_7_0_EBX_SHA_NI, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES | -+ CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_SBDR_SSDP_NO | -+ MSR_ARCH_CAP_FBSDP_NO | MSR_ARCH_CAP_PSDP_NO | -+ MSR_ARCH_CAP_PBRSB_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_CMPCCXADD | -+ CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_AVX_IFMA, -+ .features[FEAT_7_1_EDX] = -+ CPUID_7_1_EDX_AVX_VNNI_INT8 | CPUID_7_1_EDX_AVX_NE_CONVERT, -+ .features[FEAT_7_2_EDX] = -+ CPUID_7_2_EDX_MCDT_NO, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (SierraForest)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "Denverton", - .level = 21, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-Export-RFDS-bit-to-guests.patch b/SOURCES/kvm-target-i386-Export-RFDS-bit-to-guests.patch deleted file mode 100644 index 74de391..0000000 --- a/SOURCES/kvm-target-i386-Export-RFDS-bit-to-guests.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ae6229a3e45318b1101291b99a0e894399dcb1db Mon Sep 17 00:00:00 2001 -From: Pawan Gupta -Date: Wed, 13 Mar 2024 07:53:23 -0700 -Subject: [PATCH 007/100] target/i386: Export RFDS bit to guests - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [7/91] 7eb6cae8821a2e953d3ff2033fa2e973011ad771 (bonzini/rhel-qemu-kvm) - -Register File Data Sampling (RFDS) is a CPU side-channel vulnerability -that may expose stale register value. CPUs that set RFDS_NO bit in MSR -IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS. -Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has -the microcode to help mitigate RFDS. - -Make RFDS_CLEAR and RFDS_NO bits available to guests. - -Signed-off-by: Pawan Gupta -Reviewed-by: Xiaoyao Li -Reviewed-by: Zhao Liu -Message-ID: <9a38877857392b5c2deae7e7db1b170d15510314.1710341348.git.pawan.kumar.gupta@linux.intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 41bdd9812863c150284a9339a048ed88c40f4df7) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index efbadc3ed7..489c853b42 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1158,8 +1158,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", - NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, -- "pbrsb-no", NULL, "gds-no", NULL, -- NULL, NULL, NULL, NULL, -+ "pbrsb-no", NULL, "gds-no", "rfds-no", -+ "rfds-clear", NULL, NULL, NULL, - }, - .msr = { - .index = MSR_IA32_ARCH_CAPABILITIES, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-Implement-mc-kvm_type-to-get-VM-type.patch b/SOURCES/kvm-target-i386-Implement-mc-kvm_type-to-get-VM-type.patch deleted file mode 100644 index f37dbc2..0000000 --- a/SOURCES/kvm-target-i386-Implement-mc-kvm_type-to-get-VM-type.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 4a811f54cdb3c9329f193ea43c76ed4eb1b14c19 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 19 Mar 2024 15:29:33 +0100 -Subject: [PATCH 022/100] target/i386: Implement mc->kvm_type() to get VM type - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [22/91] d58cf6ead2de37852adc15c7642166904403453f (bonzini/rhel-qemu-kvm) - -KVM is introducing a new API to create confidential guests, which -will be used by TDX and SEV-SNP but is also available for SEV and -SEV-ES. The API uses the VM type argument to KVM_CREATE_VM to -identify which confidential computing technology to use. - -Since there are no other expected uses of VM types, delegate -mc->kvm_type() for x86 boards to the confidential-guest-support -object pointed to by ms->cgs. - -For example, if a sev-guest object is specified to confidential-guest-support, -like, - - qemu -machine ...,confidential-guest-support=sev0 \ - -object sev-guest,id=sev0,... - -it will check if a VM type KVM_X86_SEV_VM or KVM_X86_SEV_ES_VM -is supported, and if so use them together with the KVM_SEV_INIT2 -function of the KVM_MEMORY_ENCRYPT_OP ioctl. If not, it will fall back to -KVM_SEV_INIT and KVM_SEV_ES_INIT. - -This is a preparatory work towards TDX and SEV-SNP support, but it -will also enable support for VMSA features such as DebugSwap, which -are only available via KVM_SEV_INIT2. - -Co-developed-by: Xiaoyao Li -Signed-off-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -(cherry picked from commit ee88612df1e8d6c2bfec75bff3f9482ea44acec1) -Signed-off-by: Paolo Bonzini ---- - hw/i386/x86.c | 11 ++++++++ - target/i386/confidential-guest.h | 19 ++++++++++++++ - target/i386/kvm/kvm.c | 44 ++++++++++++++++++++++++++++++++ - target/i386/kvm/kvm_i386.h | 2 ++ - 4 files changed, 76 insertions(+) - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index 84a4801977..3d5b51e92d 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -1381,6 +1381,16 @@ static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name, - qapi_free_SgxEPCList(list); - } - -+static int x86_kvm_type(MachineState *ms, const char *vm_type) -+{ -+ /* -+ * No x86 machine has a kvm-type property. If one is added that has -+ * it, it should call kvm_get_vm_type() directly or not use it at all. -+ */ -+ assert(vm_type == NULL); -+ return kvm_enabled() ? kvm_get_vm_type(ms) : 0; -+} -+ - static void x86_machine_initfn(Object *obj) - { - X86MachineState *x86ms = X86_MACHINE(obj); -@@ -1405,6 +1415,7 @@ static void x86_machine_class_init(ObjectClass *oc, void *data) - mc->cpu_index_to_instance_props = x86_cpu_index_to_props; - mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; - mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; -+ mc->kvm_type = x86_kvm_type; - x86mc->save_tsc_khz = true; - x86mc->fwcfg_dma_enabled = true; - nc->nmi_monitor_handler = x86_nmi; -diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h -index ca12d5a8fb..532e172a60 100644 ---- a/target/i386/confidential-guest.h -+++ b/target/i386/confidential-guest.h -@@ -36,5 +36,24 @@ struct X86ConfidentialGuest { - struct X86ConfidentialGuestClass { - /* */ - ConfidentialGuestSupportClass parent; -+ -+ /* */ -+ int (*kvm_type)(X86ConfidentialGuest *cg); - }; -+ -+/** -+ * x86_confidential_guest_kvm_type: -+ * -+ * Calls #X86ConfidentialGuestClass.unplug callback of @plug_handler. -+ */ -+static inline int x86_confidential_guest_kvm_type(X86ConfidentialGuest *cg) -+{ -+ X86ConfidentialGuestClass *klass = X86_CONFIDENTIAL_GUEST_GET_CLASS(cg); -+ -+ if (klass->kvm_type) { -+ return klass->kvm_type(cg); -+ } else { -+ return 0; -+ } -+} - #endif -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index a12207a8ee..1f0ab12c2e 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -31,6 +31,7 @@ - #include "sysemu/kvm_int.h" - #include "sysemu/runstate.h" - #include "kvm_i386.h" -+#include "../confidential-guest.h" - #include "sev.h" - #include "xen-emu.h" - #include "hyperv.h" -@@ -161,6 +162,49 @@ static KVMMSRHandlers msr_handlers[KVM_MSR_FILTER_MAX_RANGES]; - static RateLimit bus_lock_ratelimit_ctrl; - static int kvm_get_one_msr(X86CPU *cpu, int index, uint64_t *value); - -+static const char *vm_type_name[] = { -+ [KVM_X86_DEFAULT_VM] = "default", -+}; -+ -+bool kvm_is_vm_type_supported(int type) -+{ -+ uint32_t machine_types; -+ -+ /* -+ * old KVM doesn't support KVM_CAP_VM_TYPES but KVM_X86_DEFAULT_VM -+ * is always supported -+ */ -+ if (type == KVM_X86_DEFAULT_VM) { -+ return true; -+ } -+ -+ machine_types = kvm_check_extension(KVM_STATE(current_machine->accelerator), -+ KVM_CAP_VM_TYPES); -+ return !!(machine_types & BIT(type)); -+} -+ -+int kvm_get_vm_type(MachineState *ms) -+{ -+ int kvm_type = KVM_X86_DEFAULT_VM; -+ -+ if (ms->cgs) { -+ if (!object_dynamic_cast(OBJECT(ms->cgs), TYPE_X86_CONFIDENTIAL_GUEST)) { -+ error_report("configuration type %s not supported for x86 guests", -+ object_get_typename(OBJECT(ms->cgs))); -+ exit(1); -+ } -+ kvm_type = x86_confidential_guest_kvm_type( -+ X86_CONFIDENTIAL_GUEST(ms->cgs)); -+ } -+ -+ if (!kvm_is_vm_type_supported(kvm_type)) { -+ error_report("vm-type %s not supported by KVM", vm_type_name[kvm_type]); -+ exit(1); -+ } -+ -+ return kvm_type; -+} -+ - bool kvm_has_smm(void) - { - return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM); -diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h -index 30fedcffea..6b44844d95 100644 ---- a/target/i386/kvm/kvm_i386.h -+++ b/target/i386/kvm/kvm_i386.h -@@ -37,6 +37,7 @@ bool kvm_hv_vpindex_settable(void); - bool kvm_enable_sgx_provisioning(KVMState *s); - bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); - -+int kvm_get_vm_type(MachineState *ms); - void kvm_arch_reset_vcpu(X86CPU *cs); - void kvm_arch_after_reset_vcpu(X86CPU *cpu); - void kvm_arch_do_init_vcpu(X86CPU *cs); -@@ -49,6 +50,7 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); - - #ifdef CONFIG_KVM - -+bool kvm_is_vm_type_supported(int type); - bool kvm_has_adjust_clock_stable(void); - bool kvm_has_exception_payload(void); - void kvm_synchronize_all_tsc(void); --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch b/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch new file mode 100644 index 0000000..a86f820 --- /dev/null +++ b/SOURCES/kvm-target-i386-Introduce-GraniteRapids-v2-model.patch @@ -0,0 +1,59 @@ +From 1895c3aa9eb0037eb06745ef499eb7476bebd554 Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:33 +0800 +Subject: [PATCH 08/11] target/i386: Introduce GraniteRapids-v2 model + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [8/9] 5b684731a1d2c2687515eb984398c9dc5bc3fc23 (bonzini/rhel-qemu-kvm) + +Update GraniteRapids CPU model to add AVX10 and the missing features(ss, +tsc-adjust, cldemote, movdiri, movdir64b). + +Tested-by: Xuelian Guo +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-7-tao1.su@linux.intel.com +Reviewed-by: Zhao Liu +Signed-off-by: Paolo Bonzini +Link: https://lore.kernel.org/r/20241031085233.425388-9-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1a519388a882fbb352e49cbebb0ed8f62d05842d) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 5042cbaa0e..ad368252d8 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -4393,6 +4393,23 @@ static const X86CPUDefinition builtin_x86_defs[] = { + .model_id = "Intel Xeon Processor (GraniteRapids)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, ++ { ++ .version = 2, ++ .props = (PropValue[]) { ++ { "ss", "on" }, ++ { "tsc-adjust", "on" }, ++ { "cldemote", "on" }, ++ { "movdiri", "on" }, ++ { "movdir64b", "on" }, ++ { "avx10", "on" }, ++ { "avx10-128", "on" }, ++ { "avx10-256", "on" }, ++ { "avx10-512", "on" }, ++ { "avx10-version", "1" }, ++ { "stepping", "1" }, ++ { /* end of list */ } ++ } ++ }, + { /* end of list */ }, + }, + }, +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch b/SOURCES/kvm-target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch deleted file mode 100644 index 9844da7..0000000 --- a/SOURCES/kvm-target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch +++ /dev/null @@ -1,68 +0,0 @@ -From fe60f8d47b6e14f17dd6c06b03bd00e6bcdbeefb Mon Sep 17 00:00:00 2001 -From: Zhenzhong Duan -Date: Wed, 20 Mar 2024 17:31:38 +0800 -Subject: [PATCH 005/100] target/i386: Introduce Icelake-Server-v7 to enable - TSX - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [5/91] 66d865899e0d510b6c86763422d6b28b904b208a (bonzini/rhel-qemu-kvm) - -When start L2 guest with both L1/L2 using Icelake-Server-v3 or above, -QEMU reports below warning: - -"warning: host doesn't support requested feature: MSR(10AH).taa-no [bit 8]" - -Reason is QEMU Icelake-Server-v3 has TSX feature disabled but enables taa-no -bit. It's meaningless that TSX isn't supported but still claim TSX is secure. -So L1 KVM doesn't expose taa-no to L2 if TSX is unsupported, then starting L2 -triggers the warning. - -Fix it by introducing a new version Icelake-Server-v7 which has both TSX -and taa-no features. Then guest can use TSX securely when it see taa-no. - -This matches the production Icelake which supports TSX and isn't susceptible -to TSX Async Abort (TAA) vulnerabilities, a.k.a, taa-no. - -Ideally, TSX should have being enabled together with taa-no since v3, but for -compatibility, we'd better to add v7 to enable it. - -Fixes: d965dc35592d ("target/i386: Add ARCH_CAPABILITIES related bits into Icelake-Server CPU model") -Tested-by: Xiangfei Ma -Signed-off-by: Zhenzhong Duan -Message-ID: <20240320093138.80267-2-zhenzhong.duan@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit c895fa54e3060c5ac6f3888dce96c9b78626072b) -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a7f71422ea..0aa88d9b48 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3840,6 +3840,16 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - }, - }, -+ { -+ .version = 7, -+ .note = "TSX, taa-no", -+ .props = (PropValue[]) { -+ /* Restore TSX features removed by -v2 above */ -+ { "hle", "on" }, -+ { "rtm", "on" }, -+ { /* end of list */ } -+ }, -+ }, - { /* end of list */ } - } - }, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch b/SOURCES/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch new file mode 100644 index 0000000..1d10634 --- /dev/null +++ b/SOURCES/kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch @@ -0,0 +1,64 @@ +From a079f758233f53fbdcfbae78bb6c6ee7a610b374 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Tue, 7 Jan 2025 13:40:43 +0100 +Subject: [PATCH 1/4] target/i386: Make sure SynIC state is really updated + before KVM_RUN + +RH-Author: Vitaly Kuznetsov +RH-MergeRequest: 315: target/i386: Make sure SynIC state is really updated before KVM_RUN +RH-Jira: RHEL-53073 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Maxim Levitsky +RH-Commit: [1/1] 24eb10f4c32a8dc348eaf32b7f19de19c30a9fca (vkuznets/qemu-kvm) + +'hyperv_synic' test from KVM unittests was observed to be flaky on certain +hardware (hangs sometimes). Debugging shows that the problem happens in +hyperv_sint_route_new() when the test tries to set up a new SynIC +route. The function bails out on: + + if (!synic->sctl_enabled) { + goto cleanup; + } + +but the test writes to HV_X64_MSR_SCONTROL just before it starts +establishing SINT routes. Further investigation shows that +synic_update() (called from async_synic_update()) happens after the SINT +setup attempt and not before. Apparently, the comment before +async_safe_run_on_cpu() in kvm_hv_handle_exit() does not correctly describe +the guarantees async_safe_run_on_cpu() gives. In particular, async worked +added to a CPU is actually processed from qemu_wait_io_event() which is not +always called before KVM_RUN, i.e. kvm_cpu_exec() checks whether an exit +request is pending for a CPU and if not, keeps running the vCPU until it +meets an exit it can't handle internally. Hyper-V specific MSR writes are +not automatically trigger an exit. + +Fix the issue by simply raising an exit request for the vCPU where SynIC +update was queued. This is not a performance critical path as SynIC state +does not get updated so often (and async_safe_run_on_cpu() is a big hammer +anyways). + +Reported-by: Jan Richter +Signed-off-by: Vitaly Kuznetsov +Link: https://lore.kernel.org/r/20240917160051.2637594-4-vkuznets@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit d3177e2e4353824a650434c57471615d43507500) +Signed-off-by: Vitaly Kuznetsov +--- + target/i386/kvm/hyperv.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/i386/kvm/hyperv.c b/target/i386/kvm/hyperv.c +index b94f12acc2..70b89cacf9 100644 +--- a/target/i386/kvm/hyperv.c ++++ b/target/i386/kvm/hyperv.c +@@ -80,6 +80,7 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) + * necessary because memory hierarchy is being changed + */ + async_safe_run_on_cpu(CPU(cpu), async_synic_update, RUN_ON_CPU_NULL); ++ cpu_exit(CPU(cpu)); + + return EXCP_INTERRUPT; + case KVM_EXIT_HYPERV_HCALL: { +-- +2.39.3 + diff --git a/SOURCES/kvm-target-i386-SEV-fix-formatting-of-CPUID-mismatch-mes.patch b/SOURCES/kvm-target-i386-SEV-fix-formatting-of-CPUID-mismatch-mes.patch deleted file mode 100644 index ace0367..0000000 --- a/SOURCES/kvm-target-i386-SEV-fix-formatting-of-CPUID-mismatch-mes.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 070dda07559a7488c62fc80a8c79e8baaee125eb Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Wed, 3 Jul 2024 10:37:23 +0200 -Subject: [PATCH 087/100] target/i386: SEV: fix formatting of CPUID mismatch - message - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [87/91] 36bc2cc80d5ffc1ceeb1836540660ff45885a818 (bonzini/rhel-qemu-kvm) - -Fixes: 70943ad8e4d ("i386/sev: Add support for SNP CPUID validation", 2024-06-05) -Signed-off-by: Paolo Bonzini -(cherry picked from commit f45ef010e19fe86314bffd5d5c9d5d77f4ce8103) -Signed-off-by: Paolo Bonzini ---- - target/i386/sev.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index c40562dce3..37de80adc7 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -839,7 +839,7 @@ sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old, - size_t i; - - if (old->count != new->count) { -- error_report("SEV-SNP: CPUID validation failed due to count mismatch," -+ error_report("SEV-SNP: CPUID validation failed due to count mismatch, " - "provided: %d, expected: %d", old->count, new->count); - return; - } -@@ -851,8 +851,8 @@ sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old, - new_func = &new->entries[i]; - - if (memcmp(old_func, new_func, sizeof(SnpCpuidFunc))) { -- error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x" -- "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x" -+ error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x, " -+ "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x, " - "expected: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x", - old_func->eax_in, old_func->ecx_in, - old_func->eax, old_func->ebx, old_func->ecx, old_func->edx, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-SEV-fix-mismatch-in-vcek-disabled-proper.patch b/SOURCES/kvm-target-i386-SEV-fix-mismatch-in-vcek-disabled-proper.patch deleted file mode 100644 index 3030d59..0000000 --- a/SOURCES/kvm-target-i386-SEV-fix-mismatch-in-vcek-disabled-proper.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 37b7e2185f1d23dd5f5a95b545b8d760492915ed Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 2 Aug 2024 01:43:37 +0200 -Subject: [PATCH 091/100] target/i386: SEV: fix mismatch in vcek-disabled - property name - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [91/91] 3a8abc4a0547b985cb79cef29bd3e8350d3d4b48 (bonzini/rhel-qemu-kvm) - -The vcek-disabled property of the sev-snp-guest object is misspelled -vcek-required (which I suppose would use the opposite polarity) in -the call to object_class_property_add_bool(). Fix it. - -Reported-by: Zixi Chen -Reviewed-by: Pankaj Gupta -Signed-off-by: Paolo Bonzini -(cherry picked from commit d4392415c328f83b2e30517a3561be523874f441) ---- - target/i386/sev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b921defb63..aed565dbe8 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -2378,7 +2378,7 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data) - object_class_property_add_bool(oc, "author-key-enabled", - sev_snp_guest_get_author_key_enabled, - sev_snp_guest_set_author_key_enabled); -- object_class_property_add_bool(oc, "vcek-required", -+ object_class_property_add_bool(oc, "vcek-disabled", - sev_snp_guest_get_vcek_disabled, - sev_snp_guest_set_vcek_disabled); - object_class_property_add_str(oc, "host-data", --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-SEV-use-KVM_SEV_INIT2-if-possible.patch b/SOURCES/kvm-target-i386-SEV-use-KVM_SEV_INIT2-if-possible.patch deleted file mode 100644 index 7c17e53..0000000 --- a/SOURCES/kvm-target-i386-SEV-use-KVM_SEV_INIT2-if-possible.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 6bb738fb90a3a1221ae35596b3d03a17e0b1c34d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 19 Mar 2024 15:30:25 +0100 -Subject: [PATCH 023/100] target/i386: SEV: use KVM_SEV_INIT2 if possible - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [23/91] 9579d772ae5124a94c6b1e3a4566bf3470d2bc8f (bonzini/rhel-qemu-kvm) - -Implement support for the KVM_X86_SEV_VM and KVM_X86_SEV_ES_VM virtual -machine types, and the KVM_SEV_INIT2 function of KVM_MEMORY_ENCRYPT_OP. - -These replace the KVM_SEV_INIT and KVM_SEV_ES_INIT functions, and have -several advantages: - -- sharing the initialization sequence with SEV-SNP and TDX - -- allowing arguments including the set of desired VMSA features - -- protection against invalid use of KVM_GET/SET_* ioctls for guests - with encrypted state - -If the KVM_X86_SEV_VM and KVM_X86_SEV_ES_VM types are not supported, -fall back to KVM_SEV_INIT and KVM_SEV_ES_INIT (which use the -default x86 VM type). - -Signed-off-by: Paolo Bonzini -(cherry picked from commit 663e2f443e5722370708ce2f4c27d94a2087d2d3) -Signed-off-by: Paolo Bonzini ---- - target/i386/kvm/kvm.c | 2 ++ - target/i386/sev.c | 41 +++++++++++++++++++++++++++++++++++++---- - 2 files changed, 39 insertions(+), 4 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 1f0ab12c2e..408568d053 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -164,6 +164,8 @@ static int kvm_get_one_msr(X86CPU *cpu, int index, uint64_t *value); - - static const char *vm_type_name[] = { - [KVM_X86_DEFAULT_VM] = "default", -+ [KVM_X86_SEV_VM] = "SEV", -+ [KVM_X86_SEV_ES_VM] = "SEV-ES", - }; - - bool kvm_is_vm_type_supported(int type) -diff --git a/target/i386/sev.c b/target/i386/sev.c -index ebe36d4c10..9dab4060b8 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -26,6 +26,7 @@ - #include "qemu/error-report.h" - #include "crypto/hash.h" - #include "sysemu/kvm.h" -+#include "kvm/kvm_i386.h" - #include "sev.h" - #include "sysemu/sysemu.h" - #include "sysemu/runstate.h" -@@ -56,6 +57,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) - struct SevGuestState { - X86ConfidentialGuest parent_obj; - -+ int kvm_type; -+ - /* configuration parameters */ - char *sev_device; - uint32_t policy; -@@ -850,6 +853,26 @@ sev_vm_state_change(void *opaque, bool running, RunState state) - } - } - -+static int sev_kvm_type(X86ConfidentialGuest *cg) -+{ -+ SevGuestState *sev = SEV_GUEST(cg); -+ int kvm_type; -+ -+ if (sev->kvm_type != -1) { -+ goto out; -+ } -+ -+ kvm_type = (sev->policy & SEV_POLICY_ES) ? KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM; -+ if (kvm_is_vm_type_supported(kvm_type)) { -+ sev->kvm_type = kvm_type; -+ } else { -+ sev->kvm_type = KVM_X86_DEFAULT_VM; -+ } -+ -+out: -+ return sev->kvm_type; -+} -+ - static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevGuestState *sev = SEV_GUEST(cgs); -@@ -929,13 +952,19 @@ static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - __func__); - goto err; - } -- cmd = KVM_SEV_ES_INIT; -- } else { -- cmd = KVM_SEV_INIT; - } - - trace_kvm_sev_init(); -- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ if (sev_kvm_type(X86_CONFIDENTIAL_GUEST(sev)) == KVM_X86_DEFAULT_VM) { -+ cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT; -+ -+ ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ } else { -+ struct kvm_sev_init args = { 0 }; -+ -+ ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT2, &args, &fw_error); -+ } -+ - if (ret) { - error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); -@@ -1327,8 +1356,10 @@ static void - sev_guest_class_init(ObjectClass *oc, void *data) - { - ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); -+ X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc); - - klass->kvm_init = sev_kvm_init; -+ x86_klass->kvm_type = sev_kvm_type; - - object_class_property_add_str(oc, "sev-device", - sev_guest_get_sev_device, -@@ -1357,6 +1388,8 @@ sev_guest_instance_init(Object *obj) - { - SevGuestState *sev = SEV_GUEST(obj); - -+ sev->kvm_type = -1; -+ - sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); - sev->policy = DEFAULT_GUEST_POLICY; - object_property_add_uint32_ptr(obj, "policy", &sev->policy, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch b/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch new file mode 100644 index 0000000..b8492c0 --- /dev/null +++ b/SOURCES/kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch @@ -0,0 +1,224 @@ +From 887a4929ea393510d6867c160ced628798e17163 Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:29 +0800 +Subject: [PATCH 04/11] target/i386: add AVX10 feature and AVX10 version + property + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [4/9] c71d05d79d1a228c01ab5fc5f486ae5db9e98a1b (bonzini/rhel-qemu-kvm) + +When AVX10 enable bit is set, the 0x24 leaf will be present as "AVX10 +Converged Vector ISA leaf" containing fields for the version number and +the supported vector bit lengths. + +Introduce avx10-version property so that avx10 version can be controlled +by user and cpu model. Per spec, avx10 version can never be 0, the default +value of avx10-version is set to 0 to determine whether it is specified by +user. The default can come from the device model or, for the max model, +from KVM's reported value. + +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com +Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +Tested-by: Xuelian Guo +Link: https://lore.kernel.org/r/20241031085233.425388-5-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit bccfb846fd52d6f20704ecfa4d01b60b43c6f640) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 64 ++++++++++++++++++++++++++++++++++++++----- + target/i386/cpu.h | 4 +++ + target/i386/kvm/kvm.c | 3 +- + 3 files changed, 63 insertions(+), 8 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 982d9bd7f6..6c041ec5af 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -47,6 +47,9 @@ + #include "cpu-internal.h" + + static void x86_cpu_realizefn(DeviceState *dev, Error **errp); ++static void x86_cpu_get_supported_cpuid(uint32_t func, uint32_t index, ++ uint32_t *eax, uint32_t *ebx, ++ uint32_t *ecx, uint32_t *edx); + + /* Helpers for building CPUID[2] descriptors: */ + +@@ -1133,7 +1136,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + "avx-vnni-int8", "avx-ne-convert", NULL, NULL, + "amx-complex", NULL, "avx-vnni-int16", NULL, + NULL, NULL, "prefetchiti", NULL, +- NULL, NULL, NULL, NULL, ++ NULL, NULL, NULL, "avx10", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +@@ -1961,6 +1964,7 @@ typedef struct X86CPUDefinition { + int family; + int model; + int stepping; ++ uint8_t avx10_version; + FeatureWordArray features; + const char *model_id; + const CPUCaches *const cache_info; +@@ -6328,6 +6332,9 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model) + */ + object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort); + ++ object_property_set_uint(OBJECT(cpu), "avx10-version", def->avx10_version, ++ &error_abort); ++ + x86_cpu_apply_version_props(cpu, model); + + /* +@@ -6856,6 +6863,16 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, + } + break; + } ++ case 0x24: { ++ *eax = 0; ++ *ebx = 0; ++ *ecx = 0; ++ *edx = 0; ++ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && count == 0) { ++ *ebx = env->features[FEAT_24_0_EBX] | env->avx10_version; ++ } ++ break; ++ } + case 0x40000000: + /* + * CPUID code in kvm_arch_init_vcpu() ignores stuff +@@ -7436,6 +7453,12 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + ~env->user_features[w] & + ~feature_word_info[w].no_autoenable_flags; + } ++ ++ if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) && !env->avx10_version) { ++ uint32_t eax, ebx, ecx, edx; ++ x86_cpu_get_supported_cpuid(0x24, 0, &eax, &ebx, &ecx, &edx); ++ env->avx10_version = ebx & 0xff; ++ } + } + + for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) { +@@ -7499,6 +7522,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x1F); + } + ++ /* Advanced Vector Extensions 10 (AVX10) requires CPUID[0x24] */ ++ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) { ++ x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x24); ++ } ++ + /* SVM requires CPUID[0x8000000A] */ + if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { + x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A); +@@ -7549,6 +7577,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) + CPUX86State *env = &cpu->env; + FeatureWord w; + const char *prefix = NULL; ++ bool have_filtered_features; ++ ++ uint32_t eax_0, ebx_0, ecx_0, edx_0; ++ uint32_t eax_1, ebx_1, ecx_1, edx_1; + + if (verbose) { + prefix = accel_uses_host_cpuid() +@@ -7570,13 +7602,10 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) + */ + if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) && + kvm_enabled()) { +- uint32_t eax_0, ebx_0, ecx_0, edx_0_unused; +- uint32_t eax_1, ebx_1, ecx_1_unused, edx_1_unused; +- + x86_cpu_get_supported_cpuid(0x14, 0, +- &eax_0, &ebx_0, &ecx_0, &edx_0_unused); ++ &eax_0, &ebx_0, &ecx_0, &edx_0); + x86_cpu_get_supported_cpuid(0x14, 1, +- &eax_1, &ebx_1, &ecx_1_unused, &edx_1_unused); ++ &eax_1, &ebx_1, &ecx_1, &edx_1); + + if (!eax_0 || + ((ebx_0 & INTEL_PT_MINIMAL_EBX) != INTEL_PT_MINIMAL_EBX) || +@@ -7597,7 +7626,27 @@ static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) + } + } + +- return x86_cpu_have_filtered_features(cpu); ++ have_filtered_features = x86_cpu_have_filtered_features(cpu); ++ ++ if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_AVX10) { ++ x86_cpu_get_supported_cpuid(0x24, 0, ++ &eax_0, &ebx_0, &ecx_0, &edx_0); ++ uint8_t version = ebx_0 & 0xff; ++ ++ if (version < env->avx10_version) { ++ if (prefix) { ++ warn_report("%s: avx10.%d. Adjust to avx10.%d", ++ prefix, env->avx10_version, version); ++ } ++ env->avx10_version = version; ++ have_filtered_features = true; ++ } ++ } else if (env->avx10_version && prefix) { ++ warn_report("%s: avx10.%d.", prefix, env->avx10_version); ++ have_filtered_features = true; ++ } ++ ++ return have_filtered_features; + } + + static void x86_cpu_hyperv_realize(X86CPU *cpu) +@@ -8378,6 +8427,7 @@ static Property x86_cpu_properties[] = { + DEFINE_PROP_UINT32("min-level", X86CPU, env.cpuid_min_level, 0), + DEFINE_PROP_UINT32("min-xlevel", X86CPU, env.cpuid_min_xlevel, 0), + DEFINE_PROP_UINT32("min-xlevel2", X86CPU, env.cpuid_min_xlevel2, 0), ++ DEFINE_PROP_UINT8("avx10-version", X86CPU, env.avx10_version, 0), + DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0), + DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true), + DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor), +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 14edd57a37..591113349d 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -972,6 +972,8 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + #define CPUID_7_1_EDX_AMX_COMPLEX (1U << 8) + /* PREFETCHIT0/1 Instructions */ + #define CPUID_7_1_EDX_PREFETCHITI (1U << 14) ++/* Support for Advanced Vector Extensions 10 */ ++#define CPUID_7_1_EDX_AVX10 (1U << 19) + /* Flexible return and event delivery (FRED) */ + #define CPUID_7_1_EAX_FRED (1U << 17) + /* Load into IA32_KERNEL_GS_BASE (LKGS) */ +@@ -1914,6 +1916,8 @@ typedef struct CPUArchState { + uint32_t cpuid_vendor3; + uint32_t cpuid_version; + FeatureWordArray features; ++ /* AVX10 version */ ++ uint8_t avx10_version; + /* Features that were explicitly enabled/disabled */ + FeatureWordArray user_features; + uint32_t cpuid_model[12]; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 814f93da19..d0329a4ed7 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1891,7 +1891,8 @@ static uint32_t kvm_x86_build_cpuid(CPUX86State *env, + case 0x7: + case 0x14: + case 0x1d: +- case 0x1e: { ++ case 0x1e: ++ case 0x24: { + uint32_t times; + + c->function = i; +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch b/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch new file mode 100644 index 0000000..0424c79 --- /dev/null +++ b/SOURCES/kvm-target-i386-add-CPUID.24-features-for-AVX10.patch @@ -0,0 +1,91 @@ +From 4d68991ce4c1bbc6acf74d249c8cea504560780f Mon Sep 17 00:00:00 2001 +From: Tao Su +Date: Thu, 31 Oct 2024 16:52:30 +0800 +Subject: [PATCH 05/11] target/i386: add CPUID.24 features for AVX10 + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [5/9] e70e79b79037c77df17a028b7451b92bde042c0e (bonzini/rhel-qemu-kvm) + +Introduce features for the supported vector bit lengths. + +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241028024512.156724-3-tao1.su@linux.intel.com +Link: https://lore.kernel.org/r/20241028024512.156724-4-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Tested-by: Xuelian Guo +Link: https://lore.kernel.org/r/20241031085233.425388-6-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2d055b8fe11ee567c2ae8047311fd83697e494b6) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 15 +++++++++++++++ + target/i386/cpu.h | 8 ++++++++ + 2 files changed, 23 insertions(+) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 6c041ec5af..b6021be50d 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -902,6 +902,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + #define TCG_SGX_12_0_EAX_FEATURES 0 + #define TCG_SGX_12_0_EBX_FEATURES 0 + #define TCG_SGX_12_1_EAX_FEATURES 0 ++#define TCG_24_0_EBX_FEATURES 0 + + #if defined CONFIG_USER_ONLY + #define CPUID_8000_0008_EBX_KERNEL_FEATURES (CPUID_8000_0008_EBX_IBPB | \ +@@ -1167,6 +1168,20 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + }, + .tcg_features = TCG_7_2_EDX_FEATURES, + }, ++ [FEAT_24_0_EBX] = { ++ .type = CPUID_FEATURE_WORD, ++ .feat_names = { ++ [16] = "avx10-128", ++ [17] = "avx10-256", ++ [18] = "avx10-512", ++ }, ++ .cpuid = { ++ .eax = 0x24, ++ .needs_ecx = true, .ecx = 0, ++ .reg = R_EBX, ++ }, ++ .tcg_features = TCG_24_0_EBX_FEATURES, ++ }, + [FEAT_8000_0007_EDX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 591113349d..c60290b8d5 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -666,6 +666,7 @@ typedef enum FeatureWord { + FEAT_XSAVE_XSS_HI, /* CPUID[EAX=0xd,ECX=1].EDX */ + FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ + FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ ++ FEAT_24_0_EBX, /* CPUID[EAX=0x24,ECX=0].EBX */ + FEATURE_WORDS, + } FeatureWord; + +@@ -990,6 +991,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w); + /* Packets which contain IP payload have LIP values */ + #define CPUID_14_0_ECX_LIP (1U << 31) + ++/* AVX10 128-bit vector support is present */ ++#define CPUID_24_0_EBX_AVX10_128 (1U << 16) ++/* AVX10 256-bit vector support is present */ ++#define CPUID_24_0_EBX_AVX10_256 (1U << 17) ++/* AVX10 512-bit vector support is present */ ++#define CPUID_24_0_EBX_AVX10_512 (1U << 18) ++ + /* RAS Features */ + #define CPUID_8000_0007_EBX_OVERFLOW_RECOV (1U << 0) + #define CPUID_8000_0007_EBX_SUCCOR (1U << 1) +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-add-guest-phys-bits-cpu-property.patch b/SOURCES/kvm-target-i386-add-guest-phys-bits-cpu-property.patch deleted file mode 100644 index cd41279..0000000 --- a/SOURCES/kvm-target-i386-add-guest-phys-bits-cpu-property.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 090c64ea622534ff2ae6c9b66cdf0b1ddb58bf26 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Mon, 18 Mar 2024 16:53:36 +0100 -Subject: [PATCH 002/100] target/i386: add guest-phys-bits cpu property - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [2/91] 6603e842012dc484e1f571ea0a77b59095f37003 (bonzini/rhel-qemu-kvm) - -Allows to set guest-phys-bits (cpuid leaf 80000008, eax[23:16]) -via -cpu $model,guest-phys-bits=$nr. - -Signed-off-by: Gerd Hoffmann -Message-ID: <20240318155336.156197-3-kraxel@redhat.com> -Reviewed-by: Zhao Liu -Signed-off-by: Paolo Bonzini -(cherry picked from commit 513ba32dccc659c80722b3a43233b26eaa50309a) -Signed-off-by: Paolo Bonzini ---- - hw/i386/pc.c | 2 ++ - target/i386/cpu.c | 22 ++++++++++++++++++++++ - target/i386/cpu.h | 8 ++++++++ - 3 files changed, 32 insertions(+) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 648762d908..b9fde3cec1 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -349,6 +349,8 @@ GlobalProperty pc_rhel_compat[] = { - const size_t pc_rhel_compat_len = G_N_ELEMENTS(pc_rhel_compat); - - GlobalProperty pc_rhel_9_5_compat[] = { -+ /* pc_rhel_9_5_compat from pc_compat_pc_9_0 (backported from 9.1) */ -+ { TYPE_X86_CPU, "guest-phys-bits", "0" }, - }; - const size_t pc_rhel_9_5_compat_len = G_N_ELEMENTS(pc_rhel_9_5_compat); - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index be7b0663cd..a7f71422ea 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6591,6 +6591,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { - /* 64 bit processor */ - *eax |= (cpu_x86_virtual_addr_width(env) << 8); -+ *eax |= (cpu->guest_phys_bits << 16); - } - *ebx = env->features[FEAT_8000_0008_EBX]; - if (cs->nr_cores * cs->nr_threads > 1) { -@@ -7350,6 +7351,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) - goto out; - } - -+ if (cpu->guest_phys_bits == -1) { -+ /* -+ * If it was not set by the user, or by the accelerator via -+ * cpu_exec_realizefn, clear. -+ */ -+ cpu->guest_phys_bits = 0; -+ } -+ - if (cpu->ucode_rev == 0) { - /* - * The default is the same as KVM's. Note that this check -@@ -7400,6 +7409,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) - if (cpu->phys_bits == 0) { - cpu->phys_bits = TCG_PHYS_ADDR_BITS; - } -+ if (cpu->guest_phys_bits && -+ (cpu->guest_phys_bits > cpu->phys_bits || -+ cpu->guest_phys_bits < 32)) { -+ error_setg(errp, "guest-phys-bits should be between 32 and %u " -+ " (but is %u)", -+ cpu->phys_bits, cpu->guest_phys_bits); -+ return; -+ } - } else { - /* For 32 bit systems don't use the user set value, but keep - * phys_bits consistent with what we tell the guest. -@@ -7408,6 +7425,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) - error_setg(errp, "phys-bits is not user-configurable in 32 bit"); - return; - } -+ if (cpu->guest_phys_bits != 0) { -+ error_setg(errp, "guest-phys-bits is not user-configurable in 32 bit"); -+ return; -+ } - - if (env->features[FEAT_1_EDX] & (CPUID_PSE36 | CPUID_PAE)) { - cpu->phys_bits = 36; -@@ -7908,6 +7929,7 @@ static Property x86_cpu_properties[] = { - DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false), - DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), - DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), -+ DEFINE_PROP_UINT32("guest-phys-bits", X86CPU, guest_phys_bits, -1), - DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false), - DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0), - DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true), -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 6b05738079..6112e27bfd 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -2027,6 +2027,14 @@ struct ArchCPU { - /* Number of physical address bits supported */ - uint32_t phys_bits; - -+ /* -+ * Number of guest physical address bits available. Usually this is -+ * identical to host physical address bits. With NPT or EPT 4-level -+ * paging, guest physical address space might be restricted to 48 bits -+ * even if the host cpu supports more physical address bits. -+ */ -+ uint32_t guest_phys_bits; -+ - /* in order to simplify APIC support, we leave this pointer to the - user */ - struct DeviceState *apic_state; --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch b/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch new file mode 100644 index 0000000..8bf0c7e --- /dev/null +++ b/SOURCES/kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch @@ -0,0 +1,43 @@ +From 3edc5689dd2b5a55655ab99e0153ad85ab50d773 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 3 Jul 2024 13:42:49 +0200 +Subject: [PATCH 09/11] target/i386: add sha512, sm3, sm4 feature bits + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [9/9] ec773b43841f1a38f0e5829c1d66cd5b517c5267 (bonzini/rhel-qemu-kvm) + +Status: queued for QEMU 10.0 + +SHA512, SM3, SM4 (CPUID[EAX=7,ECX=1).EAX bits 0 to 2) is supported by +Clearwater Forest processor, add it to QEMU as it does not need any +specific enablement. + +See https://lore.kernel.org/kvm/20241105054825.870939-1-tao1.su@linux.intel.com/ +for reference. + +Reviewed-by: Tao Su +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index ad368252d8..a70a3aa670 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1114,7 +1114,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + [FEAT_7_1_EAX] = { + .type = CPUID_FEATURE_WORD, + .feat_names = { +- NULL, NULL, NULL, NULL, ++ "sha512", "sm3", "sm4", NULL, + "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", + NULL, NULL, "fzrm", "fsrs", + "fsrc", NULL, NULL, NULL, +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch b/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch new file mode 100644 index 0000000..070616a --- /dev/null +++ b/SOURCES/kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch @@ -0,0 +1,50 @@ +From 9ed7a4e63c88a9b2afe51ffad36c12b174ad6e7a Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 31 Oct 2024 16:52:26 +0800 +Subject: [PATCH 01/11] target/i386: cpu: set correct supported XCR0 features + for TCG + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/9] a27738f95f7c00915cd16288e469276a879f6bdf (bonzini/rhel-qemu-kvm) + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20241031085233.425388-2-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 33098002a838a0450f243f5e17463aca700e923d) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index ed278dd4a1..cff7ae1c54 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1297,7 +1297,9 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .needs_ecx = true, .ecx = 0, + .reg = R_EAX, + }, +- .tcg_features = ~0U, ++ .tcg_features = XSTATE_FP_MASK | XSTATE_SSE_MASK | ++ XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK | ++ XSTATE_PKRU_MASK, + .migratable_flags = XSTATE_FP_MASK | XSTATE_SSE_MASK | + XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK | + XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK | +@@ -1310,7 +1312,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { + .needs_ecx = true, .ecx = 0, + .reg = R_EDX, + }, +- .tcg_features = ~0U, ++ .tcg_features = 0U, + }, + /*Below are MSR exposed features*/ + [FEAT_ARCH_CAPABILITIES] = { +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch b/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch new file mode 100644 index 0000000..b9799fa --- /dev/null +++ b/SOURCES/kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch @@ -0,0 +1,117 @@ +From a6d31ad703d50bce0c0fb054356f50e480cf5a4d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 31 Oct 2024 16:52:27 +0800 +Subject: [PATCH 02/11] target/i386: do not rely on ExtSaveArea for + accelerator-supported XCR0 bits + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [2/9] e53b5e7a58018c0635012382d93819dbe7cb6201 (bonzini/rhel-qemu-kvm) + +Right now, QEMU is using the "feature" and "bits" fields of ExtSaveArea +to query the accelerator for the support status of extended save areas. +This is a problem for AVX10, which attaches two feature bits (AVX512F +and AVX10) to the same extended save states. + +To keep the AVX10 hacks to the minimum, limit usage of esa->features +and esa->bits. Instead, just query the accelerator for the 0xD leaf. +Do it in common code and clear esa->size if an extended save state is +unsupported. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Link: https://lore.kernel.org/r/20241031085233.425388-3-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit b888c7807049cc044d10d70139cb945202fb7cd2) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 33 +++++++++++++++++++++++++++++++-- + target/i386/kvm/kvm-cpu.c | 4 ---- + 2 files changed, 31 insertions(+), 6 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index cff7ae1c54..4e240ab181 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -7088,6 +7088,15 @@ static void x86_cpu_set_sgxlepubkeyhash(CPUX86State *env) + #endif + } + ++static bool cpuid_has_xsave_feature(CPUX86State *env, const ExtSaveArea *esa) ++{ ++ if (!esa->size) { ++ return false; ++ } ++ ++ return (env->features[esa->feature] & esa->bits); ++} ++ + static void x86_cpu_reset_hold(Object *obj, ResetType type) + { + CPUState *cs = CPU(obj); +@@ -7196,7 +7205,7 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type) + if (!((1 << i) & CPUID_XSTATE_XCR0_MASK)) { + continue; + } +- if (env->features[esa->feature] & esa->bits) { ++ if (cpuid_has_xsave_feature(env, esa)) { + xcr0 |= 1ull << i; + } + } +@@ -7334,7 +7343,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) + mask = 0; + for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) { + const ExtSaveArea *esa = &x86_ext_save_areas[i]; +- if (env->features[esa->feature] & esa->bits) { ++ if (cpuid_has_xsave_feature(env, esa)) { + mask |= (1ULL << i); + } + } +@@ -8005,6 +8014,26 @@ static void x86_cpu_register_feature_bit_props(X86CPUClass *xcc, + + static void x86_cpu_post_initfn(Object *obj) + { ++ static bool first = true; ++ uint64_t supported_xcr0; ++ int i; ++ ++ if (first) { ++ first = false; ++ ++ supported_xcr0 = ++ ((uint64_t) x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_HI) << 32) | ++ x86_cpu_get_supported_feature_word(NULL, FEAT_XSAVE_XCR0_LO); ++ ++ for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { ++ ExtSaveArea *esa = &x86_ext_save_areas[i]; ++ ++ if (!(supported_xcr0 & (1 << i))) { ++ esa->size = 0; ++ } ++ } ++ } ++ + accel_cpu_instance_init(CPU(obj)); + } + +diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c +index 684e731cbc..961b87e98e 100644 +--- a/target/i386/kvm/kvm-cpu.c ++++ b/target/i386/kvm/kvm-cpu.c +@@ -143,10 +143,6 @@ static void kvm_cpu_xsave_init(void) + if (!esa->size) { + continue; + } +- if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits) +- != esa->bits) { +- continue; +- } + host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); + if (eax != 0) { + assert(esa->size == eax); +-- +2.48.0 + diff --git a/SOURCES/kvm-target-i386-introduce-x86-confidential-guest.patch b/SOURCES/kvm-target-i386-introduce-x86-confidential-guest.patch deleted file mode 100644 index dec3220..0000000 --- a/SOURCES/kvm-target-i386-introduce-x86-confidential-guest.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0573fcd1775b6613127b1906d59d02e65f7519f3 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 18 Mar 2024 11:07:43 -0400 -Subject: [PATCH 021/100] target/i386: introduce x86-confidential-guest - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [21/91] e86d3bcde7e1c2fa1ba8c9bc83e02033644f1ac0 (bonzini/rhel-qemu-kvm) - -Introduce a common superclass for x86 confidential guest implementations. -It will extend ConfidentialGuestSupportClass with a method that provides -the VM type to be passed to KVM_CREATE_VM. - -Signed-off-by: Paolo Bonzini -(cherry picked from commit d82e9c843d662f13821026618aba936eda31a6c0) -Signed-off-by: Paolo Bonzini ---- - target/i386/confidential-guest.c | 33 ++++++++++++++++++++++++++ - target/i386/confidential-guest.h | 40 ++++++++++++++++++++++++++++++++ - target/i386/meson.build | 2 +- - target/i386/sev.c | 6 ++--- - 4 files changed, 77 insertions(+), 4 deletions(-) - create mode 100644 target/i386/confidential-guest.c - create mode 100644 target/i386/confidential-guest.h - -diff --git a/target/i386/confidential-guest.c b/target/i386/confidential-guest.c -new file mode 100644 -index 0000000000..b3727845ad ---- /dev/null -+++ b/target/i386/confidential-guest.c -@@ -0,0 +1,33 @@ -+/* -+ * QEMU Confidential Guest support -+ * -+ * Copyright (C) 2024 Red Hat, Inc. -+ * -+ * Authors: -+ * Paolo Bonzini -+ * -+ * 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 "confidential-guest.h" -+ -+OBJECT_DEFINE_ABSTRACT_TYPE(X86ConfidentialGuest, -+ x86_confidential_guest, -+ X86_CONFIDENTIAL_GUEST, -+ CONFIDENTIAL_GUEST_SUPPORT) -+ -+static void x86_confidential_guest_class_init(ObjectClass *oc, void *data) -+{ -+} -+ -+static void x86_confidential_guest_init(Object *obj) -+{ -+} -+ -+static void x86_confidential_guest_finalize(Object *obj) -+{ -+} -diff --git a/target/i386/confidential-guest.h b/target/i386/confidential-guest.h -new file mode 100644 -index 0000000000..ca12d5a8fb ---- /dev/null -+++ b/target/i386/confidential-guest.h -@@ -0,0 +1,40 @@ -+/* -+ * x86-specific confidential guest methods. -+ * -+ * Copyright (c) 2024 Red Hat Inc. -+ * -+ * Authors: -+ * Paolo Bonzini -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+#ifndef TARGET_I386_CG_H -+#define TARGET_I386_CG_H -+ -+#include "qom/object.h" -+ -+#include "exec/confidential-guest-support.h" -+ -+#define TYPE_X86_CONFIDENTIAL_GUEST "x86-confidential-guest" -+ -+OBJECT_DECLARE_TYPE(X86ConfidentialGuest, -+ X86ConfidentialGuestClass, -+ X86_CONFIDENTIAL_GUEST) -+ -+struct X86ConfidentialGuest { -+ /* */ -+ ConfidentialGuestSupport parent_obj; -+}; -+ -+/** -+ * X86ConfidentialGuestClass: -+ * -+ * Class to be implemented by confidential-guest-support concrete objects -+ * for the x86 target. -+ */ -+struct X86ConfidentialGuestClass { -+ /* */ -+ ConfidentialGuestSupportClass parent; -+}; -+#endif -diff --git a/target/i386/meson.build b/target/i386/meson.build -index 7c74bfa859..8abce725f8 100644 ---- a/target/i386/meson.build -+++ b/target/i386/meson.build -@@ -6,7 +6,7 @@ i386_ss.add(files( - 'xsave_helper.c', - 'cpu-dump.c', - )) --i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c')) -+i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c', 'confidential-guest.c')) - - # x86 cpu type - i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c')) -diff --git a/target/i386/sev.c b/target/i386/sev.c -index c49a8fd55e..ebe36d4c10 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -35,7 +35,7 @@ - #include "monitor/monitor.h" - #include "monitor/hmp-target.h" - #include "qapi/qapi-commands-misc-target.h" --#include "exec/confidential-guest-support.h" -+#include "confidential-guest.h" - #include "hw/i386/pc.h" - #include "exec/address-spaces.h" - -@@ -54,7 +54,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) - * -machine ...,memory-encryption=sev0 - */ - struct SevGuestState { -- ConfidentialGuestSupport parent_obj; -+ X86ConfidentialGuest parent_obj; - - /* configuration parameters */ - char *sev_device; -@@ -1372,7 +1372,7 @@ sev_guest_instance_init(Object *obj) - - /* sev guest info */ - static const TypeInfo sev_guest_info = { -- .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT, -+ .parent = TYPE_X86_CONFIDENTIAL_GUEST, - .name = TYPE_SEV_GUEST, - .instance_size = sizeof(SevGuestState), - .instance_finalize = sev_guest_finalize, --- -2.39.3 - diff --git a/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch b/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch new file mode 100644 index 0000000..d67b6f2 --- /dev/null +++ b/SOURCES/kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch @@ -0,0 +1,176 @@ +From 1ed2fd718be2161f5ad6156dd2311a65b7f3a5e4 Mon Sep 17 00:00:00 2001 +From: Julia Suvorova +Date: Fri, 27 Sep 2024 12:47:41 +0200 +Subject: [PATCH 27/27] target/i386/kvm: Report which action failed in + kvm_arch_put/get_registers + +RH-Author: Julia Suvorova +RH-MergeRequest: 286: kvm: Allow kvm_arch_get/put_registers to accept Error** +RH-Jira: RHEL-60914 +RH-Acked-by: Juraj Marcin +RH-Acked-by: Peter Xu +RH-Commit: [2/2] b5d003dc2ccf869d7a810425baf21c783a96dcd1 + +To help debug and triage future failure reports (akin to [1,2]) that +may occur during kvm_arch_put/get_registers, the error path of each +action is accompanied by unique error message. + +[1] https://issues.redhat.com/browse/RHEL-7558 +[2] https://issues.redhat.com/browse/RHEL-21761 + +Signed-off-by: Julia Suvorova +Reviewed-by: Peter Xu +Link: https://lore.kernel.org/r/20240927104743.218468-3-jusual@redhat.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit fc058618d1596d29e89016750a1aaf64c9fe8832) +--- + target/i386/kvm/kvm.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 423e6922d8..814f93da19 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -5136,6 +5136,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) + if (level >= KVM_PUT_RESET_STATE) { + ret = kvm_put_msr_feature_control(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set feature control MSR"); + return ret; + } + } +@@ -5143,12 +5144,14 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) + /* must be before kvm_put_nested_state so that EFER.SVME is set */ + ret = has_sregs2 ? kvm_put_sregs2(x86_cpu) : kvm_put_sregs(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set special registers"); + return ret; + } + + if (level >= KVM_PUT_RESET_STATE) { + ret = kvm_put_nested_state(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set nested state"); + return ret; + } + } +@@ -5166,6 +5169,7 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) + if (xen_mode == XEN_EMULATE && level == KVM_PUT_FULL_STATE) { + ret = kvm_put_xen_state(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set Xen state"); + return ret; + } + } +@@ -5173,37 +5177,45 @@ int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp) + + ret = kvm_getput_regs(x86_cpu, 1); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set general purpose registers"); + return ret; + } + ret = kvm_put_xsave(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set XSAVE"); + return ret; + } + ret = kvm_put_xcrs(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set XCRs"); + return ret; + } + ret = kvm_put_msrs(x86_cpu, level); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set MSRs"); + return ret; + } + ret = kvm_put_vcpu_events(x86_cpu, level); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set vCPU events"); + return ret; + } + if (level >= KVM_PUT_RESET_STATE) { + ret = kvm_put_mp_state(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set MP state"); + return ret; + } + } + + ret = kvm_put_tscdeadline_msr(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set TSC deadline MSR"); + return ret; + } + ret = kvm_put_debugregs(x86_cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to set debug registers"); + return ret; + } + return 0; +@@ -5218,6 +5230,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) + + ret = kvm_get_vcpu_events(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get vCPU events"); + goto out; + } + /* +@@ -5226,44 +5239,54 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) + */ + ret = kvm_get_mp_state(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get MP state"); + goto out; + } + ret = kvm_getput_regs(cpu, 0); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get general purpose registers"); + goto out; + } + ret = kvm_get_xsave(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get XSAVE"); + goto out; + } + ret = kvm_get_xcrs(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get XCRs"); + goto out; + } + ret = has_sregs2 ? kvm_get_sregs2(cpu) : kvm_get_sregs(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get special registers"); + goto out; + } + ret = kvm_get_msrs(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get MSRs"); + goto out; + } + ret = kvm_get_apic(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get APIC"); + goto out; + } + ret = kvm_get_debugregs(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get debug registers"); + goto out; + } + ret = kvm_get_nested_state(cpu); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get nested state"); + goto out; + } + #ifdef CONFIG_XEN_EMU + if (xen_mode == XEN_EMULATE) { + ret = kvm_get_xen_state(cs); + if (ret < 0) { ++ error_setg_errno(errp, -ret, "Failed to get Xen state"); + goto out; + } + } +-- +2.39.3 + diff --git a/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch b/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch new file mode 100644 index 0000000..2e776fb --- /dev/null +++ b/SOURCES/kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch @@ -0,0 +1,83 @@ +From 6fd15c104cb9475311f68156ebf3603d406b90fa Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 31 Oct 2024 16:52:28 +0800 +Subject: [PATCH 03/11] target/i386: return bool from x86_cpu_filter_features + +RH-Author: Paolo Bonzini +RH-MergeRequest: 281: Add support for the AVX10.1, SHA512, SM3 and SM4 instruction sets. +RH-Jira: RHEL-30316 RHEL-45111 +RH-Acked-by: Vitaly Kuznetsov +RH-Acked-by: Miroslav Rezanina +RH-Commit: [3/9] a5cd846d3ade44b289d99b2742323f421fe30f8b (bonzini/rhel-qemu-kvm) + +Prepare for filtering non-boolean features such as AVX10 version. + +Signed-off-by: Paolo Bonzini +Reviewed-by: Zhao Liu +Signed-off-by: Tao Su +Link: https://lore.kernel.org/r/20241031085233.425388-4-tao1.su@linux.intel.com +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3507c6f04606593711408a6d26141bdbceff9377) +Signed-off-by: Paolo Bonzini +--- + target/i386/cpu.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 4e240ab181..982d9bd7f6 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -5837,7 +5837,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features, + } + } + +-static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); ++static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose); + + /* Build a list with the name of all features on a feature word array */ + static void x86_cpu_list_feature_names(FeatureWordArray features, +@@ -7542,9 +7542,9 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) + * Finishes initialization of CPUID data, filters CPU feature + * words based on host availability of each feature. + * +- * Returns: 0 if all flags are supported by the host, non-zero otherwise. ++ * Returns: true if any flag is not supported by the host, false otherwise. + */ +-static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) ++static bool x86_cpu_filter_features(X86CPU *cpu, bool verbose) + { + CPUX86State *env = &cpu->env; + FeatureWord w; +@@ -7596,6 +7596,8 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose) + mark_unavailable_features(cpu, FEAT_7_0_EBX, CPUID_7_0_EBX_INTEL_PT, prefix); + } + } ++ ++ return x86_cpu_have_filtered_features(cpu); + } + + static void x86_cpu_hyperv_realize(X86CPU *cpu) +@@ -7693,14 +7695,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) + } + } + +- x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid); +- +- if (cpu->enforce_cpuid && x86_cpu_have_filtered_features(cpu)) { +- error_setg(&local_err, +- accel_uses_host_cpuid() ? ++ if (x86_cpu_filter_features(cpu, cpu->check_cpuid || cpu->enforce_cpuid)) { ++ if (cpu->enforce_cpuid) { ++ error_setg(&local_err, ++ accel_uses_host_cpuid() ? + "Host doesn't support requested features" : + "TCG doesn't support requested features"); +- goto out; ++ goto out; ++ } + } + + /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on +-- +2.48.0 + diff --git a/SOURCES/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch b/SOURCES/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch new file mode 100644 index 0000000..232d6a5 --- /dev/null +++ b/SOURCES/kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch @@ -0,0 +1,51 @@ +From 6b2d9104632c948f37e640d471765f049cf01d57 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 22 Nov 2024 23:40:42 +0100 +Subject: [PATCH 2/4] tests/avocado/hotplug_blk: Fix addr in device_add command + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 316: qdev-monitor: avoid QemuOpts in QMP device_add +RH-Jira: RHEL-39948 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Czenczek +RH-Commit: [2/4] 5848a0ec61904674659ef5f1f19e29065c5c8271 (stefanha/centos-stream-qemu-kvm) + +pci_devfn properties accept both integer and string values, but +integer 1 and string '1' have different meanings: The integer value +means device 0, function 1 whereas the string value '1' is short for +'1.0' and means device 1, function 0. + +This test wants the string version so that the device actually becomes +visible for the guest. device_add hides the problem because it goes +through QemuOpts, which turns all properties into strings - this is a +QEMU bug that we want to fix, but that cancelled out the bug in this +test. + +Fix the test first so that device_add can be fixed afterwards. + +Signed-off-by: Kevin Wolf +Message-ID: <20241122224042.149258-1-kwolf@redhat.com> +Reviewed-by: Markus Armbruster +Signed-off-by: Kevin Wolf +(cherry picked from commit 770de685353e8c495ad4773fbd4bc0db997e4dfd) +Signed-off-by: Stefan Hajnoczi +--- + tests/avocado/hotplug_blk.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/avocado/hotplug_blk.py b/tests/avocado/hotplug_blk.py +index d55ded1c1d..b36bca02ec 100644 +--- a/tests/avocado/hotplug_blk.py ++++ b/tests/avocado/hotplug_blk.py +@@ -33,7 +33,7 @@ def plug(self) -> None: + 'drive': 'disk', + 'id': 'virtio-disk0', + 'bus': 'pci.1', +- 'addr': 1 ++ 'addr': '1', + } + + self.assert_no_vda() +-- +2.39.3 + diff --git a/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch b/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch new file mode 100644 index 0000000..4596afc --- /dev/null +++ b/SOURCES/kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch @@ -0,0 +1,74 @@ +From 0e5a728c1d46641bbf5c83289df56422efd374c8 Mon Sep 17 00:00:00 2001 +From: Jared Rossi +Date: Sat, 19 Oct 2024 21:29:53 -0400 +Subject: [PATCH 20/27] tests/qtest: Add s390x boot order tests to cdrom-test.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Thomas Huth +RH-MergeRequest: 277: Full boot order support for s390x [CentOS 9] +RH-Jira: RHEL-11424 +RH-Acked-by: Cédric Le Goater +RH-Acked-by: Miroslav Rezanina +RH-Commit: [20/23] 6b8769f2fc5f8c8a6345a5961f54e52be62aae49 (thuth/qemu-kvm-cs9) + +Add two new qtests to verify that a valid IPL device can successfully boot after +failed IPL attempts from one or more invalid devices. + +cdrom-test/as-fallback-device: Defines the primary boot target as a device that +is invalid for IPL and a second boot target that is valid for IPL. Ensures that +the valid device will be selected after the initial failed IPL. + +cdrom-test/as-last-option: Defines the maximum number of boot devices (8) +where only the final entry in the boot order is valid. Ensures that a valid +device will be selected even after multiple failed IPL attempts from both +virtio-blk and virtio-scsi device types. + +Signed-off-by: Jared Rossi +Reviewed-by: Thomas Huth +Message-ID: <20241020012953.1380075-20-jrossi@linux.ibm.com> +Signed-off-by: Thomas Huth +(cherry picked from commit f5aa2d9d4c6480fa73b89c935050afe57e5d8bd9) +--- + tests/qtest/cdrom-test.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c +index 5d89e62515..ecba648144 100644 +--- a/tests/qtest/cdrom-test.c ++++ b/tests/qtest/cdrom-test.c +@@ -206,6 +206,30 @@ static void add_s390x_tests(void) + "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " + "-device virtio-blk,drive=d2,bootindex=1 " + "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); ++ qtest_add_data_func("cdrom/boot/as-fallback-device", ++ "-device virtio-serial -device virtio-scsi " ++ "-device virtio-blk,drive=d1,bootindex=1 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " ++ "-device virtio-blk,drive=d2,bootindex=2 " ++ "-drive if=none,id=d2,media=cdrom,file=", test_cdboot); ++ qtest_add_data_func("cdrom/boot/as-last-option", ++ "-device virtio-serial -device virtio-scsi " ++ "-device virtio-blk,drive=d1,bootindex=1 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d1 " ++ "-device virtio-blk,drive=d2,bootindex=2 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d2 " ++ "-device virtio-blk,drive=d3,bootindex=3 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d3 " ++ "-device scsi-hd,drive=d4,bootindex=4 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d4 " ++ "-device scsi-hd,drive=d5,bootindex=5 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d5 " ++ "-device virtio-blk,drive=d6,bootindex=6 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d6 " ++ "-device scsi-hd,drive=d7,bootindex=7 " ++ "-drive driver=null-co,read-zeroes=on,if=none,id=d7 " ++ "-device scsi-cd,drive=d8,bootindex=8 " ++ "-drive if=none,id=d8,media=cdrom,file=", test_cdboot); + if (qtest_has_device("x-terminal3270")) { + qtest_add_data_func("cdrom/boot/without-bootindex", + "-device virtio-scsi -device virtio-serial " +-- +2.39.3 + diff --git a/SOURCES/kvm-tests-qtest-disable-most-pauth-tests.patch b/SOURCES/kvm-tests-qtest-disable-most-pauth-tests.patch new file mode 100644 index 0000000..74069e5 --- /dev/null +++ b/SOURCES/kvm-tests-qtest-disable-most-pauth-tests.patch @@ -0,0 +1,48 @@ +From 2cd838efaf2345497efab21fee689ff43d511f1c Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Thu, 23 Jan 2025 08:12:35 -0500 +Subject: [PATCH 11/11] tests/qtest: disable most pauth tests + +RH-Author: Sebastian Ott +RH-MergeRequest: 330: arm: disable pauth for virt-rhel9* +RH-Jira: RHEL-75782 +RH-Acked-by: Eric Auger +RH-Acked-by: Kashyap Chamarthy +RH-Acked-by: Gavin Shan +RH-Commit: [2/2] 373738aec33bf2dcaa47563b3c06595b21dca5be (seott1/cos-qemu-kvm) + +Since pauth is disabled for virt-rhel9* machine types (aliased via virt) +the following assertions will trigger and need to be disabled as well: + assert_has_feature_enabled(qts, cpu_type, "pauth"); + assert_set_feature(qts, cpu_type, "pauth-impdef", true); + assert_set_feature(qts, cpu_type, "pauth-qarma3", true); + +Signed-off-by: Sebastian Ott +JIRA: https://issues.redhat.com/browse/RHEL-75782 +--- + tests/qtest/arm-cpu-features.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c +index 3016e6233c..6b680578a6 100644 +--- a/tests/qtest/arm-cpu-features.c ++++ b/tests/qtest/arm-cpu-features.c +@@ -416,6 +416,7 @@ static void sve_tests_sve_off_kvm(const void *data) + + static void pauth_tests_default(QTestState *qts, const char *cpu_type) + { ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + assert_has_feature_enabled(qts, cpu_type, "pauth"); + assert_has_feature_disabled(qts, cpu_type, "pauth-impdef"); + assert_has_feature_disabled(qts, cpu_type, "pauth-qarma3"); +@@ -425,6 +426,7 @@ static void pauth_tests_default(QTestState *qts, const char *cpu_type) + assert_set_feature(qts, cpu_type, "pauth-impdef", false); + assert_set_feature(qts, cpu_type, "pauth-qarma3", true); + assert_set_feature(qts, cpu_type, "pauth-qarma3", false); ++#endif /* disabled for RHEL */ + assert_error(qts, cpu_type, + "cannot enable pauth-impdef or pauth-qarma3 without pauth", + "{ 'pauth': false, 'pauth-impdef': true }"); +-- +2.48.0 + diff --git a/SOURCES/kvm-trace-kvm-Split-address-space-and-slot-id-in-trace_k.patch b/SOURCES/kvm-trace-kvm-Split-address-space-and-slot-id-in-trace_k.patch deleted file mode 100644 index d21d298..0000000 --- a/SOURCES/kvm-trace-kvm-Split-address-space-and-slot-id-in-trace_k.patch +++ /dev/null @@ -1,59 +0,0 @@ -From b02dc1e5c0f01228053e784f9ec7ac3a47e91d7c Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Thu, 29 Feb 2024 01:36:25 -0500 -Subject: [PATCH 026/100] trace/kvm: Split address space and slot id in - trace_kvm_set_user_memory() - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [26/91] 640511c4ab0ba76bb4483f6c3fb73e060d914f0a (bonzini/rhel-qemu-kvm) - -The upper 16 bits of kvm_userspace_memory_region::slot are -address space id. Parse it separately in trace_kvm_set_user_memory(). - -Signed-off-by: Xiaoyao Li -Message-ID: <20240229063726.610065-5-xiaoyao.li@intel.com> -Signed-off-by: Paolo Bonzini -(cherry picked from commit 72853afc638b3e28779c86dd05da2f3bb149fe2c) -Signed-off-by: Paolo Bonzini ---- - accel/kvm/kvm-all.c | 5 +++-- - accel/kvm/trace-events | 2 +- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index b51e09a583..9bd235c969 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -303,8 +303,9 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo - ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); - slot->old_flags = mem.flags; - err: -- trace_kvm_set_user_memory(mem.slot, mem.flags, mem.guest_phys_addr, -- mem.memory_size, mem.userspace_addr, ret); -+ trace_kvm_set_user_memory(mem.slot >> 16, (uint16_t)mem.slot, mem.flags, -+ mem.guest_phys_addr, mem.memory_size, -+ mem.userspace_addr, ret); - if (ret < 0) { - error_report("%s: KVM_SET_USER_MEMORY_REGION failed, slot=%d," - " start=0x%" PRIx64 ", size=0x%" PRIx64 ": %s", -diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events -index a25902597b..9f599abc17 100644 ---- a/accel/kvm/trace-events -+++ b/accel/kvm/trace-events -@@ -15,7 +15,7 @@ kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d" - kvm_irqchip_release_virq(int virq) "virq %d" - kvm_set_ioeventfd_mmio(int fd, uint64_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%" PRIx64 " val=0x%x assign: %d size: %d match: %d" - kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint32_t val, bool assign, uint32_t size, bool datamatch) "fd: %d @0x%x val=0x%x assign: %d size: %d match: %d" --kvm_set_user_memory(uint32_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) "Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d" -+kvm_set_user_memory(uint16_t as, uint16_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) "AddrSpace#%d Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d" - kvm_clear_dirty_log(uint32_t slot, uint64_t start, uint32_t size) "slot#%"PRId32" start 0x%"PRIx64" size 0x%"PRIx32 - kvm_resample_fd_notify(int gsi) "gsi %d" - kvm_dirty_ring_full(int id) "vcpu %d" --- -2.39.3 - diff --git a/SOURCES/kvm-update-linux-headers-fix-forwarding-to-asm-generic-h.patch b/SOURCES/kvm-update-linux-headers-fix-forwarding-to-asm-generic-h.patch deleted file mode 100644 index f141bf1..0000000 --- a/SOURCES/kvm-update-linux-headers-fix-forwarding-to-asm-generic-h.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e185104a10a37174d13d981fa1febafbb7e651aa Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 3 Jun 2024 13:49:49 +0200 -Subject: [PATCH 050/100] update-linux-headers: fix forwarding to asm-generic - headers - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [50/91] 3c98a7fe790d943bb5ff8dca1da83f5944ec3e2e (bonzini/rhel-qemu-kvm) - -Afer commit 3efc75ad9d9 ("scripts/update-linux-headers.sh: Remove -temporary directory inbetween", 2024-05-29), updating linux-headers/ -results in errors such as - - cp: cannot stat '/tmp/tmp.1A1Eejh1UE/headers/include/asm/bitsperlong.h': No such file or directory - -because Loongarch does not have an asm/bitsperlong.h file and uses the -generic version. Before commit 3efc75ad9d9, the missing file would -incorrectly cause stale files to be included in linux-headers/. The files -were never committed to qemu.git, but were wrong nevertheless. The build -would just use the system version of the files, which is opposite to -the idea of importing Linux header files into QEMU's tree. - -Create forwarding headers, resembling the ones that are generated during a -kernel build by scripts/Makefile.asm-generic, if a file is only installed -under include/asm-generic/. - -Reviewed-by: Thomas Huth -Signed-off-by: Paolo Bonzini -(cherry picked from commit ef7c70f020ca1fe9e7c98ea2cd9d6ba3c5714716) -Signed-off-by: Paolo Bonzini ---- - scripts/update-linux-headers.sh | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index f084bee72e..78c0f2c43e 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -119,7 +119,14 @@ for arch in $ARCHLIST; do - rm -rf "$output/linux-headers/asm-$arch" - mkdir -p "$output/linux-headers/asm-$arch" - for header in kvm.h unistd.h bitsperlong.h mman.h; do -- cp "$hdrdir/include/asm/$header" "$output/linux-headers/asm-$arch" -+ if test -f "$hdrdir/include/asm/$header"; then -+ cp "$hdrdir/include/asm/$header" "$output/linux-headers/asm-$arch" -+ elif test -f "$hdrdir/include/asm-generic/$header"; then -+ # not installed as , but used as such in kernel sources -+ cat <$output/linux-headers/asm-$arch/$header -+#include -+EOF -+ fi - done - - if [ $arch = mips ]; then --- -2.39.3 - diff --git a/SOURCES/kvm-update-linux-headers-import-linux-kvm_para.h-header.patch b/SOURCES/kvm-update-linux-headers-import-linux-kvm_para.h-header.patch deleted file mode 100644 index a75a2aa..0000000 --- a/SOURCES/kvm-update-linux-headers-import-linux-kvm_para.h-header.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 8d6c37ddc253f63202cc9519670c258e9d81b98e Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 3 Jun 2024 14:25:06 +0200 -Subject: [PATCH 053/100] update-linux-headers: import linux/kvm_para.h header - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [53/91] 27d4db0ecec7d0b8adeba1ec85fca32eacee1009 (bonzini/rhel-qemu-kvm) - -Right now QEMU is importing arch/x86/include/uapi/asm/kvm_para.h -because it includes definitions for kvmclock and for KVM CPUID -bits. However, other definitions for KVM hypercall values and return -codes are included in include/uapi/linux/kvm_para.h and they will be -used by SEV-SNP. - -To ensure that it is possible to include both and -"standard-headers/asm-x86/kvm_para.h" without conflicts, provide -linux/kvm_para.h as a portable header too, and forward linux-headers/ -files to those in include/standard-headers. Note that -will include architecture-specific definitions as well, but -"standard-headers/linux/kvm_para.h" will not because it can be used in -architecture-independent files. - -This could easily be extended to other architectures, but right now -they do not need any symbol in their specific kvm_para.h files. - -Reviewed-by: Thomas Huth -Signed-off-by: Paolo Bonzini -(cherry picked from commit aa274c33c39e7de981dc195abe60e1a246c9d248) -Signed-off-by: Paolo Bonzini ---- - include/standard-headers/linux/kvm_para.h | 38 +++++++++++++++++++++++ - linux-headers/asm-x86/kvm_para.h | 1 + - linux-headers/linux/kvm_para.h | 2 ++ - scripts/update-linux-headers.sh | 22 ++++++++++++- - 4 files changed, 62 insertions(+), 1 deletion(-) - create mode 100644 include/standard-headers/linux/kvm_para.h - create mode 100644 linux-headers/asm-x86/kvm_para.h - create mode 100644 linux-headers/linux/kvm_para.h - -diff --git a/include/standard-headers/linux/kvm_para.h b/include/standard-headers/linux/kvm_para.h -new file mode 100644 -index 0000000000..015c166302 ---- /dev/null -+++ b/include/standard-headers/linux/kvm_para.h -@@ -0,0 +1,38 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef __LINUX_KVM_PARA_H -+#define __LINUX_KVM_PARA_H -+ -+/* -+ * This header file provides a method for making a hypercall to the host -+ * Architectures should define: -+ * - kvm_hypercall0, kvm_hypercall1... -+ * - kvm_arch_para_features -+ * - kvm_para_available -+ */ -+ -+/* Return values for hypercalls */ -+#define KVM_ENOSYS 1000 -+#define KVM_EFAULT EFAULT -+#define KVM_EINVAL EINVAL -+#define KVM_E2BIG E2BIG -+#define KVM_EPERM EPERM -+#define KVM_EOPNOTSUPP 95 -+ -+#define KVM_HC_VAPIC_POLL_IRQ 1 -+#define KVM_HC_MMU_OP 2 -+#define KVM_HC_FEATURES 3 -+#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 -+#define KVM_HC_KICK_CPU 5 -+#define KVM_HC_MIPS_GET_CLOCK_FREQ 6 -+#define KVM_HC_MIPS_EXIT_VM 7 -+#define KVM_HC_MIPS_CONSOLE_OUTPUT 8 -+#define KVM_HC_CLOCK_PAIRING 9 -+#define KVM_HC_SEND_IPI 10 -+#define KVM_HC_SCHED_YIELD 11 -+#define KVM_HC_MAP_GPA_RANGE 12 -+ -+/* -+ * hypercalls use architecture specific -+ */ -+ -+#endif /* __LINUX_KVM_PARA_H */ -diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h -new file mode 100644 -index 0000000000..1d3e0e0b07 ---- /dev/null -+++ b/linux-headers/asm-x86/kvm_para.h -@@ -0,0 +1 @@ -+#include "standard-headers/asm-x86/kvm_para.h" -diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h -new file mode 100644 -index 0000000000..6a1e672259 ---- /dev/null -+++ b/linux-headers/linux/kvm_para.h -@@ -0,0 +1,2 @@ -+#include "standard-headers/linux/kvm_para.h" -+#include -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index 90759dcfe0..64d1989961 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -64,6 +64,7 @@ cp_portable() { - -e 'linux/kernel' \ - -e 'linux/sysinfo' \ - -e 'asm/setup_data.h' \ -+ -e 'asm/kvm_para.h' \ - > /dev/null - then - echo "Unexpected #include in input file $f". -@@ -71,6 +72,15 @@ cp_portable() { - fi - - header=$(basename "$f"); -+ -+ if test -z "$arch"; then -+ # Let users of include/standard-headers/linux/ headers pick the -+ # asm-* header that they care about -+ arch_cmd='/]*\)>/d' -+ else -+ arch_cmd='s/]*\)>/"standard-headers\/asm-'$arch'\/\1"/' -+ fi -+ - sed -e 's/__aligned_u64/__u64 __attribute__((aligned(8)))/g' \ - -e 's/__u\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/u\([0-9][0-9]*\)/uint\1_t/g' \ -@@ -79,7 +89,7 @@ cp_portable() { - -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/"\(input-event-codes\.h\)"/"standard-headers\/linux\/\1"/' \ - -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ -- -e 's/]*\)>/"standard-headers\/asm-'$arch'\/\1"/' \ -+ -e "$arch_cmd" \ - -e 's/__bitwise//' \ - -e 's/__attribute__((packed))/QEMU_PACKED/' \ - -e 's/__inline__/inline/' \ -@@ -159,7 +169,12 @@ EOF - cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" - cp "$hdrdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" - cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" -+ - cp_portable "$hdrdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch" -+ cat <$output/linux-headers/asm-$arch/kvm_para.h -+#include "standard-headers/asm-$arch/kvm_para.h" -+EOF -+ - # Remove everything except the macros from bootparam.h avoiding the - # unnecessary import of several video/ist/etc headers - sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' \ -@@ -209,6 +224,10 @@ if [ -d "$linux/LICENSES" ]; then - done - fi - -+cat <$output/linux-headers/linux/kvm_para.h -+#include "standard-headers/linux/kvm_para.h" -+#include -+EOF - cat <$output/linux-headers/linux/virtio_config.h - #include "standard-headers/linux/virtio_config.h" - EOF -@@ -231,6 +250,7 @@ for i in "$hdrdir"/include/linux/*virtio*.h \ - "$hdrdir/include/linux/ethtool.h" \ - "$hdrdir/include/linux/const.h" \ - "$hdrdir/include/linux/kernel.h" \ -+ "$hdrdir/include/linux/kvm_para.h" \ - "$hdrdir/include/linux/vhost_types.h" \ - "$hdrdir/include/linux/sysinfo.h"; do - cp_portable "$i" "$output/include/standard-headers/linux" --- -2.39.3 - diff --git a/SOURCES/kvm-update-linux-headers-move-pvpanic.h-to-correct-direc.patch b/SOURCES/kvm-update-linux-headers-move-pvpanic.h-to-correct-direc.patch deleted file mode 100644 index cb0a4d4..0000000 --- a/SOURCES/kvm-update-linux-headers-move-pvpanic.h-to-correct-direc.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 00e250d9df1949d363758a34e3f46d8c71be054f Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 3 Jun 2024 14:16:55 +0200 -Subject: [PATCH 051/100] update-linux-headers: move pvpanic.h to correct - directory - -RH-Author: Paolo Bonzini -RH-MergeRequest: 245: SEV-SNP support -RH-Jira: RHEL-39544 -RH-Acked-by: Thomas Huth -RH-Acked-by: Bandan Das -RH-Acked-by: Vitaly Kuznetsov -RH-Commit: [51/91] 10efff5bbcb867ba34f3f9ff8045381ea96f94c7 (bonzini/rhel-qemu-kvm) - -Linux has , not . Use the same -directory for QEMU's include/standard-headers/ copy. - -Reviewed-by: Thomas Huth -Signed-off-by: Paolo Bonzini -(cherry picked from commit b8116f4cbaa0f64bb07564f20b3b5219e23c8bff) -Signed-off-by: Paolo Bonzini ---- - hw/misc/pvpanic-isa.c | 2 +- - hw/misc/pvpanic-pci.c | 2 +- - hw/misc/pvpanic.c | 2 +- - include/standard-headers/{linux => misc}/pvpanic.h | 0 - scripts/update-linux-headers.sh | 6 ++++-- - 5 files changed, 7 insertions(+), 5 deletions(-) - rename include/standard-headers/{linux => misc}/pvpanic.h (100%) - -diff --git a/hw/misc/pvpanic-isa.c b/hw/misc/pvpanic-isa.c -index ccec50f61b..b4f84c4110 100644 ---- a/hw/misc/pvpanic-isa.c -+++ b/hw/misc/pvpanic-isa.c -@@ -21,7 +21,7 @@ - #include "hw/misc/pvpanic.h" - #include "qom/object.h" - #include "hw/isa/isa.h" --#include "standard-headers/linux/pvpanic.h" -+#include "standard-headers/misc/pvpanic.h" - #include "hw/acpi/acpi_aml_interface.h" - - OBJECT_DECLARE_SIMPLE_TYPE(PVPanicISAState, PVPANIC_ISA_DEVICE) -diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c -index 83be95d0d2..4d44a881da 100644 ---- a/hw/misc/pvpanic-pci.c -+++ b/hw/misc/pvpanic-pci.c -@@ -21,7 +21,7 @@ - #include "hw/misc/pvpanic.h" - #include "qom/object.h" - #include "hw/pci/pci_device.h" --#include "standard-headers/linux/pvpanic.h" -+#include "standard-headers/misc/pvpanic.h" - - OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE) - -diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c -index 1540e9091a..80289ecf5f 100644 ---- a/hw/misc/pvpanic.c -+++ b/hw/misc/pvpanic.c -@@ -21,7 +21,7 @@ - #include "hw/qdev-properties.h" - #include "hw/misc/pvpanic.h" - #include "qom/object.h" --#include "standard-headers/linux/pvpanic.h" -+#include "standard-headers/misc/pvpanic.h" - - static void handle_event(int event) - { -diff --git a/include/standard-headers/linux/pvpanic.h b/include/standard-headers/misc/pvpanic.h -similarity index 100% -rename from include/standard-headers/linux/pvpanic.h -rename to include/standard-headers/misc/pvpanic.h -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index 78c0f2c43e..90759dcfe0 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -232,10 +232,12 @@ for i in "$hdrdir"/include/linux/*virtio*.h \ - "$hdrdir/include/linux/const.h" \ - "$hdrdir/include/linux/kernel.h" \ - "$hdrdir/include/linux/vhost_types.h" \ -- "$hdrdir/include/linux/sysinfo.h" \ -- "$hdrdir/include/misc/pvpanic.h"; do -+ "$hdrdir/include/linux/sysinfo.h"; do - cp_portable "$i" "$output/include/standard-headers/linux" - done -+mkdir -p "$output/include/standard-headers/misc" -+cp_portable "$hdrdir/include/misc/pvpanic.h" \ -+ "$output/include/standard-headers/misc" - mkdir -p "$output/include/standard-headers/drm" - cp_portable "$hdrdir/include/drm/drm_fourcc.h" \ - "$output/include/standard-headers/drm" --- -2.39.3 - diff --git a/SOURCES/kvm-vfio-container-Fix-container-object-destruction.patch b/SOURCES/kvm-vfio-container-Fix-container-object-destruction.patch new file mode 100644 index 0000000..f82a592 --- /dev/null +++ b/SOURCES/kvm-vfio-container-Fix-container-object-destruction.patch @@ -0,0 +1,61 @@ +From 18d64190c2bb43d42e02ea250ffe40b8ba4970f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Mon, 18 Nov 2024 16:34:30 +0100 +Subject: [PATCH 1/2] vfio/container: Fix container object destruction +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Cédric Le Goater +RH-MergeRequest: 293: vfio/container: Fix container object destruction +RH-Jira: RHEL-67935 +RH-Acked-by: Eric Auger +RH-Acked-by: Alex Williamson +RH-Commit: [1/1] cddda9554b1a858a7265d4ed9b81fdac46772a2c (clegoate/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-67935 + +commit ebbf7c60bbd1ceedf9faf962e428ceda2388c248 +Author: Cédric Le Goater +Date: Fri Nov 15 09:34:40 2024 +0100 + + vfio/container: Fix container object destruction + + When commit 96b7af4388b3 intoduced a .instance_finalize() handler, + it did not take into account that the container was not necessarily + inserted into the container list of the address space. Hence, if + the container object is destroyed, by calling object_unref() for + example, before vfio_address_space_insert() is called, QEMU may + crash when removing the container from the list as done in + vfio_container_instance_finalize(). This was seen with an SEV-SNP + guest for which discarding of RAM fails. + + To resolve this issue, use the safe version of QLIST_REMOVE(). + + Cc: Zhenzhong Duan + Cc: Eric Auger + Fixes: 96b7af4388b3 ("vfio/container: Move vfio_container_destroy() to an instance_finalize() handler") + Reviewed-by: Zhenzhong Duan + Signed-off-by: Cédric Le Goater + +Signed-off-by: Cédric Le Goater +--- + hw/vfio/container-base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c +index 809b157674..6f86c37d97 100644 +--- a/hw/vfio/container-base.c ++++ b/hw/vfio/container-base.c +@@ -103,7 +103,7 @@ static void vfio_container_instance_finalize(Object *obj) + VFIOContainerBase *bcontainer = VFIO_IOMMU(obj); + VFIOGuestIOMMU *giommu, *tmp; + +- QLIST_REMOVE(bcontainer, next); ++ QLIST_SAFE_REMOVE(bcontainer, next); + + QLIST_FOREACH_SAFE(giommu, &bcontainer->giommu_list, giommu_next, tmp) { + memory_region_unregister_iommu_notifier( +-- +2.45.1 + diff --git a/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch b/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch new file mode 100644 index 0000000..3dc09cc --- /dev/null +++ b/SOURCES/kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch @@ -0,0 +1,70 @@ +From 619ad79630f5ff2c634fa2785acdaa8dc2f66f62 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Wed, 6 Nov 2024 17:28:32 +0100 +Subject: [PATCH 25/27] vfio/migration: Change trace formats from hex to + decimal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Cédric Le Goater +RH-MergeRequest: 282: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() +RH-Jira: RHEL-64307 +RH-Acked-by: Peter Xu +RH-Acked-by: Alex Williamson +RH-Commit: [2/2] 04c78dea168c6b4edbbf0cbddadb0d760e7afeb5 (clegoate/qemu-kvm-c9s) + +JIRA: https://issues.redhat.com/browse/RHEL-64307 + +commit fa4e20defe239e42af0a1b5c030dec114f799f56 +Author: Avihai Horon +Date: Sun Oct 20 16:01:08 2024 +0300 + + vfio/migration: Change trace formats from hex to decimal + + Data sizes in VFIO migration trace events are printed in hex format + while in migration core trace events they are printed in decimal format. + + This inconsistency makes it less readable when using both trace event + types. Hence, change the data sizes print format to decimal in VFIO + migration trace events. + + Signed-off-by: Avihai Horon + Reviewed-by: Cédric Le Goater + +Signed-off-by: Cédric Le Goater +--- + hw/vfio/trace-events | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events +index 98bd4dccea..3756ff660e 100644 +--- a/hw/vfio/trace-events ++++ b/hw/vfio/trace-events +@@ -151,7 +151,7 @@ vfio_display_edid_write_error(void) "" + vfio_load_cleanup(const char *name) " (%s)" + vfio_load_device_config_state(const char *name) " (%s)" + vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64 +-vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size 0x%"PRIx64" ret %d" ++vfio_load_state_device_data(const char *name, uint64_t data_size, int ret) " (%s) size %"PRIu64" ret %d" + vfio_migration_realize(const char *name) " (%s)" + vfio_migration_set_device_state(const char *name, const char *state) " (%s) state %s" + vfio_migration_set_state(const char *name, const char *new_state, const char *recover_state) " (%s) new state %s, recover state %s" +@@ -160,10 +160,10 @@ vfio_save_block(const char *name, int data_size) " (%s) data_size %d" + vfio_save_cleanup(const char *name) " (%s)" + vfio_save_complete_precopy(const char *name, int ret) " (%s) ret %d" + vfio_save_device_config_state(const char *name) " (%s)" +-vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 +-vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size 0x%"PRIx64 +-vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 +-vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy 0x%"PRIx64" postcopy 0x%"PRIx64" stopcopy size 0x%"PRIx64" precopy initial size 0x%"PRIx64" precopy dirty size 0x%"PRIx64 ++vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size %"PRIu64" precopy dirty size %"PRIu64 ++vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size %"PRIu64 ++vfio_state_pending_estimate(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64 ++vfio_state_pending_exact(const char *name, uint64_t precopy, uint64_t postcopy, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy %"PRIu64" postcopy %"PRIu64" stopcopy size %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64 + vfio_vmstate_change(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" + vfio_vmstate_change_prepare(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s" + +-- +2.39.3 + diff --git a/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch b/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch new file mode 100644 index 0000000..2a2204c --- /dev/null +++ b/SOURCES/kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch @@ -0,0 +1,66 @@ +From 4d37b5f77a60ea951c33ac715584bb6f5897006a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= +Date: Wed, 6 Nov 2024 17:28:32 +0100 +Subject: [PATCH 24/27] vfio/migration: Report only stop-copy size in + vfio_state_pending_exact() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Cédric Le Goater +RH-MergeRequest: 282: vfio/migration: Report only stop-copy size in vfio_state_pending_exact() +RH-Jira: RHEL-64307 +RH-Acked-by: Peter Xu +RH-Acked-by: Alex Williamson +RH-Commit: [1/2] 5330acbef6f8a8ada56bd4c7f616138df1a94112 (clegoate/qemu-kvm-c9s) + +JIRA: https://issues.redhat.com/browse/RHEL-64307 + +commit 3b5948f808e3b99aedfa0aff45cffbe8b7ec07ed +Author: Avihai Horon +Date: Sun Oct 20 16:01:06 2024 +0300 + + vfio/migration: Report only stop-copy size in vfio_state_pending_exact() + + vfio_state_pending_exact() is used to update migration core how much + device data is left for the device migration. Currently, the sum of + pre-copy and stop-copy sizes of the VFIO device are reported. + + The pre-copy size is obtained via the VFIO_MIG_GET_PRECOPY_INFO ioctl, + which returns the amount of device data available to be transferred + while the device is in the PRE_COPY states. + + The stop-copy size is obtained via the VFIO_DEVICE_FEATURE_MIG_DATA_SIZE + ioctl, which returns the total amount of device data left to be + transferred in order to complete the device migration. + + According to the above, current implementation is wrong -- it reports + extra overlapping data because pre-copy size is already contained in + stop-copy size. Fix it by reporting only stop-copy size. + + Fixes: eda7362af959 ("vfio/migration: Add VFIO migration pre-copy support") + Signed-off-by: Avihai Horon + Reviewed-by: Cédric Le Goater + +Signed-off-by: Cédric Le Goater +--- + hw/vfio/migration.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c +index 262d42a46e..dd717e8d6c 100644 +--- a/hw/vfio/migration.c ++++ b/hw/vfio/migration.c +@@ -576,9 +576,6 @@ static void vfio_state_pending_exact(void *opaque, uint64_t *must_precopy, + + if (vfio_device_state_is_precopy(vbasedev)) { + vfio_query_precopy_size(migration); +- +- *must_precopy += +- migration->precopy_init_size + migration->precopy_dirty_size; + } + + trace_vfio_state_pending_exact(vbasedev->name, *must_precopy, *can_postcopy, +-- +2.39.3 + diff --git a/SOURCES/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch b/SOURCES/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch new file mode 100644 index 0000000..e3bac53 --- /dev/null +++ b/SOURCES/kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch @@ -0,0 +1,87 @@ +From 592361992b26d7f357d45de2e9ee68c1cdb15ab0 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 15 Jan 2025 14:50:43 +0100 +Subject: [PATCH 2/3] vhost: Add stubs for the migration state transfer + interface + +RH-Author: Laurent Vivier +RH-MergeRequest: 337: virtio-net: vhost-user: Implement internal migration +RH-Jira: RHEL-78372 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [1/2] f9a24e45e618a22f867de0fd14e1000a9a38ba91 (lvivier/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-78372 + +Migration state transfer interface is only used by vhost-user-fs, +so the interface needs to be defined only when vhost is built. + +But I need to use this interface with virtio-net and vhost is not always +enabled, and to avoid undefined reference error during build, define stub +functions for vhost_supports_device_state(), vhost_save_backend_state() and +vhost_load_backend_state(). + +Cc: Hanna Czenczek +Signed-off-by: Laurent Vivier +Message-Id: <20250115135044.799698-2-lvivier@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 3f65357313e0f928e0bd3ff868b705855d0405bc) +Signed-off-by: Laurent Vivier +--- + include/hw/virtio/vhost.h | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h +index d75faf46e9..1d524f85b9 100644 +--- a/include/hw/virtio/vhost.h ++++ b/include/hw/virtio/vhost.h +@@ -363,7 +363,14 @@ static inline int vhost_reset_device(struct vhost_dev *hdev) + * Returns true if the device supports these commands, and false if it + * does not. + */ ++#ifdef CONFIG_VHOST + bool vhost_supports_device_state(struct vhost_dev *dev); ++#else ++static inline bool vhost_supports_device_state(struct vhost_dev *dev) ++{ ++ return false; ++} ++#endif + + /** + * vhost_set_device_state_fd(): Begin transfer of internal state from/to +@@ -446,7 +453,15 @@ int vhost_check_device_state(struct vhost_dev *dev, Error **errp); + * + * Returns 0 on success, and -errno otherwise. + */ ++#ifdef CONFIG_VHOST + int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); ++#else ++static inline int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, ++ Error **errp) ++{ ++ return -ENOSYS; ++} ++#endif + + /** + * vhost_load_backend_state(): High-level function to load a vhost +@@ -463,6 +478,14 @@ int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); + * + * Returns 0 on success, and -errno otherwise. + */ ++#ifdef CONFIG_VHOST + int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); ++#else ++static inline int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, ++ Error **errp) ++{ ++ return -ENOSYS; ++} ++#endif + + #endif +-- +2.48.1 + diff --git a/SOURCES/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch b/SOURCES/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch new file mode 100644 index 0000000..0b3fed1 --- /dev/null +++ b/SOURCES/kvm-vhost-fail-device-start-if-iotlb-update-fails.patch @@ -0,0 +1,62 @@ +From f9b6f2440117eaa4c57a3b924ba935580ef2ecf1 Mon Sep 17 00:00:00 2001 +From: Prasad Pandit +Date: Thu, 7 Nov 2024 17:02:47 +0530 +Subject: [PATCH 18/19] vhost: fail device start if iotlb update fails + +RH-Author: Prasad Pandit +RH-MergeRequest: 309: vhost: fail device start if iotlb update fails +RH-Jira: RHEL-27832 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] c10d1b2d3414285c2feec8760eb8e63e186fd564 (pjp/cs-qemu-kvm) + +While starting a vhost device, updating iotlb entries +via 'vhost_device_iotlb_miss' may return an error. + + qemu-kvm: vhost_device_iotlb_miss: + 700871,700871: Fail to update device iotlb + +Fail device start when such an error occurs. + +Jira: https://issues.redhat.com/browse/RHEL-27832 +Signed-off-by: Prasad Pandit +Message-Id: <20241107113247.46532-1-ppandit@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Stefano Garzarella +(cherry picked from commit 571bdc97b83646dfd3746ec56fb2f70bca55b9a2) +Signed-off-by: Prasad Pandit +--- + hw/virtio/vhost.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index 06fc71746e..e25fdce3dd 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -2151,11 +2151,22 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) + * vhost-kernel code requires for this.*/ + for (i = 0; i < hdev->nvqs; ++i) { + struct vhost_virtqueue *vq = hdev->vqs + i; +- vhost_device_iotlb_miss(hdev, vq->used_phys, true); ++ r = vhost_device_iotlb_miss(hdev, vq->used_phys, true); ++ if (r) { ++ goto fail_iotlb; ++ } + } + } + vhost_start_config_intr(hdev); + return 0; ++fail_iotlb: ++ if (vhost_dev_has_iommu(hdev) && ++ hdev->vhost_ops->vhost_set_iotlb_callback) { ++ hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false); ++ } ++ if (hdev->vhost_ops->vhost_dev_start) { ++ hdev->vhost_ops->vhost_dev_start(hdev, false); ++ } + fail_start: + if (vrings) { + vhost_dev_set_vring_enable(hdev, false); +-- +2.39.3 + diff --git a/SOURCES/kvm-virtio-gpu-fix-v2-migration.patch b/SOURCES/kvm-virtio-gpu-fix-v2-migration.patch deleted file mode 100644 index 7183a65..0000000 --- a/SOURCES/kvm-virtio-gpu-fix-v2-migration.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 97d039841728570b54d11ee7e5322743f519d861 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= -Date: Thu, 16 May 2024 12:40:22 +0400 -Subject: [PATCH 3/4] virtio-gpu: fix v2 migration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Marc-André Lureau -RH-MergeRequest: 246: virtio-gpu: fix v2 migration -RH-Jira: RHEL-34621 -RH-Acked-by: Peter Xu -RH-Acked-by: Thomas Huth -RH-Commit: [1/2] 187370bc6198a4ed0e4763314f8113ffcd21eb36 (marcandre.lureau-rh/qemu-kvm-centos) - -Commit dfcf74fa ("virtio-gpu: fix scanout migration post-load") broke -forward/backward version migration. Versioning of nested VMSD structures -is not straightforward, as the wire format doesn't have nested -structures versions. Introduce x-scanout-vmstate-version and a field -test to save/load appropriately according to the machine version. - -Fixes: dfcf74fa ("virtio-gpu: fix scanout migration post-load") -Signed-off-by: Marc-André Lureau -Signed-off-by: Peter Xu -Reviewed-by: Fiona Ebner -Tested-by: Fiona Ebner -[fixed long lines] -Signed-off-by: Fabiano Rosas - -Jira: https://issues.redhat.com/browse/RHEL-34621 -Signed-off-by: Marc-André Lureau -(cherry picked from commit 40a23ef643664b5c1021a9789f9d680b6294fb50) ---- - hw/core/machine.c | 1 + - hw/display/virtio-gpu.c | 30 ++++++++++++++++++++++-------- - include/hw/virtio/virtio-gpu.h | 1 + - 3 files changed, 24 insertions(+), 8 deletions(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 0f256d9633..cf1d7faaaf 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -37,6 +37,7 @@ GlobalProperty hw_compat_8_2[] = { - { "migration", "zero-page-detection", "legacy"}, - { TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" }, - { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" }, -+ { "virtio-gpu-device", "x-scanout-vmstate-version", "1" }, - }; - const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2); - -diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c -index ae831b6b3e..d60b1b2973 100644 ---- a/hw/display/virtio-gpu.c -+++ b/hw/display/virtio-gpu.c -@@ -1166,10 +1166,17 @@ static void virtio_gpu_cursor_bh(void *opaque) - virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq); - } - -+static bool scanout_vmstate_after_v2(void *opaque, int version) -+{ -+ struct VirtIOGPUBase *base = container_of(opaque, VirtIOGPUBase, scanout); -+ struct VirtIOGPU *gpu = container_of(base, VirtIOGPU, parent_obj); -+ -+ return gpu->scanout_vmstate_version >= 2; -+} -+ - static const VMStateDescription vmstate_virtio_gpu_scanout = { - .name = "virtio-gpu-one-scanout", -- .version_id = 2, -- .minimum_version_id = 1, -+ .version_id = 1, - .fields = (const VMStateField[]) { - VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout), - VMSTATE_UINT32(width, struct virtio_gpu_scanout), -@@ -1181,12 +1188,18 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = { - VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout), - VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout), - VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout), -- VMSTATE_UINT32_V(fb.format, struct virtio_gpu_scanout, 2), -- VMSTATE_UINT32_V(fb.bytes_pp, struct virtio_gpu_scanout, 2), -- VMSTATE_UINT32_V(fb.width, struct virtio_gpu_scanout, 2), -- VMSTATE_UINT32_V(fb.height, struct virtio_gpu_scanout, 2), -- VMSTATE_UINT32_V(fb.stride, struct virtio_gpu_scanout, 2), -- VMSTATE_UINT32_V(fb.offset, struct virtio_gpu_scanout, 2), -+ VMSTATE_UINT32_TEST(fb.format, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), -+ VMSTATE_UINT32_TEST(fb.bytes_pp, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), -+ VMSTATE_UINT32_TEST(fb.width, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), -+ VMSTATE_UINT32_TEST(fb.height, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), -+ VMSTATE_UINT32_TEST(fb.stride, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), -+ VMSTATE_UINT32_TEST(fb.offset, struct virtio_gpu_scanout, -+ scanout_vmstate_after_v2), - VMSTATE_END_OF_LIST() - }, - }; -@@ -1659,6 +1672,7 @@ static Property virtio_gpu_properties[] = { - DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags, - VIRTIO_GPU_FLAG_BLOB_ENABLED, false), - DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0), -+ DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h -index ed44cdad6b..842315d51d 100644 ---- a/include/hw/virtio/virtio-gpu.h -+++ b/include/hw/virtio/virtio-gpu.h -@@ -177,6 +177,7 @@ typedef struct VGPUDMABuf { - struct VirtIOGPU { - VirtIOGPUBase parent_obj; - -+ uint8_t scanout_vmstate_version; - uint64_t conf_max_hostmem; - - VirtQueue *ctrl_vq; --- -2.39.3 - diff --git a/SOURCES/kvm-virtio-net-Add-queues-before-loading-them.patch b/SOURCES/kvm-virtio-net-Add-queues-before-loading-them.patch new file mode 100644 index 0000000..0474c68 --- /dev/null +++ b/SOURCES/kvm-virtio-net-Add-queues-before-loading-them.patch @@ -0,0 +1,94 @@ +From 873e57548d92eb916656b6304a780f63958aa9fe Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +Date: Tue, 22 Oct 2024 15:49:01 +0900 +Subject: [PATCH 01/10] virtio-net: Add queues before loading them +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: 小田喜陽彦 +RH-MergeRequest: 299: virtio-net: Add queues before loading them +RH-Jira: RHEL-69477 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Jason Wang +RH-Commit: [1/1] 7bd06d5f9c0f0ce3d211204c404451d7002bb7fb (akihiko.odaki/qemu-kvm) + +Call virtio_net_set_multiqueue() to add queues before loading their +states. Otherwise the loaded queues will not have handlers and elements +in them will not be processed. + +Cc: qemu-stable@nongnu.org +Fixes: 8c49756825da ("virtio-net: Add only one queue pair when realizing") +Reported-by: Laurent Vivier +Signed-off-by: Akihiko Odaki +Acked-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +(cherry picked from commit 9379ea9db3c0064fa2787db0794a23a30f7b2d2d) +--- + hw/net/virtio-net.c | 10 ++++++++++ + hw/virtio/virtio.c | 7 +++++++ + include/hw/virtio/virtio.h | 2 ++ + 3 files changed, 19 insertions(+) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index ed33a32877..90d05f94d4 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -3032,6 +3032,15 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue) + virtio_net_set_queue_pairs(n); + } + ++static int virtio_net_pre_load_queues(VirtIODevice *vdev) ++{ ++ virtio_net_set_multiqueue(VIRTIO_NET(vdev), ++ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_RSS) || ++ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MQ)); ++ ++ return 0; ++} ++ + static int virtio_net_post_load_device(void *opaque, int version_id) + { + VirtIONet *n = opaque; +@@ -4010,6 +4019,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) + vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; + vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; + vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO); ++ vdc->pre_load_queues = virtio_net_pre_load_queues; + vdc->post_load = virtio_net_post_load_virtio; + vdc->vmsd = &vmstate_virtio_net_device; + vdc->primary_unplug_pending = primary_unplug_pending; +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 9e10cbc058..10f24a58dd 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -3251,6 +3251,13 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) + config_len--; + } + ++ if (vdc->pre_load_queues) { ++ ret = vdc->pre_load_queues(vdev); ++ if (ret) { ++ return ret; ++ } ++ } ++ + num = qemu_get_be32(f); + + if (num > VIRTIO_QUEUE_MAX) { +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 0fcbc5c0c6..953dfca27c 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -210,6 +210,8 @@ struct VirtioDeviceClass { + void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask); + int (*start_ioeventfd)(VirtIODevice *vdev); + void (*stop_ioeventfd)(VirtIODevice *vdev); ++ /* Called before loading queues. Useful to add queues before loading. */ ++ int (*pre_load_queues)(VirtIODevice *vdev); + /* Saving and loading of a device; trying to deprecate save/load + * use vmsd for new devices. + */ +-- +2.39.3 + diff --git a/SOURCES/kvm-virtio-net-vhost-user-Implement-internal-migration.patch b/SOURCES/kvm-virtio-net-vhost-user-Implement-internal-migration.patch new file mode 100644 index 0000000..50fdaca --- /dev/null +++ b/SOURCES/kvm-virtio-net-vhost-user-Implement-internal-migration.patch @@ -0,0 +1,161 @@ +From f73b4e686c289ef6409c945d16582af16d2c28fc Mon Sep 17 00:00:00 2001 +From: Laurent Vivier +Date: Wed, 15 Jan 2025 14:50:44 +0100 +Subject: [PATCH 3/3] virtio-net: vhost-user: Implement internal migration + +RH-Author: Laurent Vivier +RH-MergeRequest: 337: virtio-net: vhost-user: Implement internal migration +RH-Jira: RHEL-78372 +RH-Acked-by: Hanna Czenczek +RH-Acked-by: Stefan Hajnoczi +RH-Commit: [2/2] 5832e25e230407a36022318a2a1e0d4f6f54bb92 (lvivier/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-78372 + +Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net +with vhost-user backend. + +Cc: Hanna Czenczek +Signed-off-by: Laurent Vivier +Message-Id: <20250115135044.799698-3-lvivier@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 60f543ad917fad731e39ff8ce2ca83b9a9cc9d90) +Signed-off-by: Laurent Vivier +--- + hw/net/virtio-net.c | 105 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 97 insertions(+), 8 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 90d05f94d4..3d2b2460ad 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -3305,6 +3305,102 @@ static const VMStateDescription vmstate_virtio_net_rss = { + }, + }; + ++static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) ++{ ++ VirtIONet *n = VIRTIO_NET(vdev); ++ NetClientState *nc = qemu_get_queue(n->nic); ++ struct vhost_net *net = get_vhost_net(nc->peer); ++ return &net->dev; ++} ++ ++static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field, ++ JSONWriter *vmdesc) ++{ ++ VirtIONet *n = pv; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ Error *local_error = NULL; ++ int ret; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ error_reportf_err(local_error, ++ "Error getting vhost back-end of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return -1; ++ } ++ ++ ret = vhost_save_backend_state(vhdev, f, &local_error); ++ if (ret < 0) { ++ error_reportf_err(local_error, ++ "Error saving back-end state of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, ++ const VMStateField *field) ++{ ++ VirtIONet *n = pv; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ Error *local_error = NULL; ++ int ret; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ error_reportf_err(local_error, ++ "Error getting vhost back-end of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return -1; ++ } ++ ++ ret = vhost_load_backend_state(vhdev, f, &local_error); ++ if (ret < 0) { ++ error_reportf_err(local_error, ++ "Error loading back-end state of %s device %s: ", ++ vdev->name, vdev->parent_obj.canonical_path); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static bool vhost_user_net_is_internal_migration(void *opaque) ++{ ++ VirtIONet *n = opaque; ++ VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ struct vhost_dev *vhdev; ++ ++ vhdev = virtio_net_get_vhost(vdev); ++ if (vhdev == NULL) { ++ return false; ++ } ++ ++ return vhost_supports_device_state(vhdev); ++} ++ ++static const VMStateDescription vhost_user_net_backend_state = { ++ .name = "virtio-net-device/backend", ++ .version_id = 0, ++ .needed = vhost_user_net_is_internal_migration, ++ .fields = (const VMStateField[]) { ++ { ++ .name = "backend", ++ .info = &(const VMStateInfo) { ++ .name = "virtio-net vhost-user backend state", ++ .get = vhost_user_net_load_state, ++ .put = vhost_user_net_save_state, ++ }, ++ }, ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static const VMStateDescription vmstate_virtio_net_device = { + .name = "virtio-net-device", + .version_id = VIRTIO_NET_VM_VERSION, +@@ -3357,6 +3453,7 @@ static const VMStateDescription vmstate_virtio_net_device = { + }, + .subsections = (const VMStateDescription * const []) { + &vmstate_virtio_net_rss, ++ &vhost_user_net_backend_state, + NULL + } + }; +@@ -3902,14 +3999,6 @@ static bool dev_unplug_pending(void *opaque) + return vdc->primary_unplug_pending(dev); + } + +-static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) +-{ +- VirtIONet *n = VIRTIO_NET(vdev); +- NetClientState *nc = qemu_get_queue(n->nic); +- struct vhost_net *net = get_vhost_net(nc->peer); +- return &net->dev; +-} +- + static const VMStateDescription vmstate_virtio_net = { + .name = "virtio-net", + .minimum_version_id = VIRTIO_NET_VM_VERSION, +-- +2.48.1 + diff --git a/SOURCES/kvm-virtio-rng-block-max-bytes-0.patch b/SOURCES/kvm-virtio-rng-block-max-bytes-0.patch deleted file mode 100644 index 2fba53d..0000000 --- a/SOURCES/kvm-virtio-rng-block-max-bytes-0.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3dd1412176a8ee6c06b5d41aa00ca49b535d99b7 Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Wed, 24 Jul 2024 06:48:59 -0400 -Subject: [PATCH 092/100] virtio-rng: block max-bytes=0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Laurent Vivier -RH-MergeRequest: 259: virtio-rng: block max-bytes=0 -RH-Jira: RHEL-50336 -RH-Acked-by: Eugenio Pérez -RH-Acked-by: Thomas Huth -RH-Acked-by: Eric Auger -RH-Commit: [1/1] 6d9852cc7cf7fdf49521b6301ceda26e11b1291f (lvivier/qemu-kvm-centos) - -JIRA: https://issues.redhat.com/browse/RHEL-50336 - -with max-bytes set to 0, quota is 0 and so device does not work. -block this to avoid user confusion - -Message-Id: <73a89a42d82ec8b47358f25119b87063e4a6ea57.1721818306.git.mst@redhat.com> -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Philippe Mathieu-Daudé -(cherry picked from commit 024d046bf41b5256adec671085bcee767a6da125) -Signed-off-by: Laurent Vivier ---- - hw/virtio/virtio-rng.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c -index f74efffef7..7cf31da071 100644 ---- a/hw/virtio/virtio-rng.c -+++ b/hw/virtio/virtio-rng.c -@@ -184,8 +184,9 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) - - /* Workaround: Property parsing does not enforce unsigned integers, - * So this is a hack to reject such numbers. */ -- if (vrng->conf.max_bytes > INT64_MAX) { -- error_setg(errp, "'max-bytes' parameter must be non-negative, " -+ if (vrng->conf.max_bytes == 0 || -+ vrng->conf.max_bytes > INT64_MAX) { -+ error_setg(errp, "'max-bytes' parameter must be positive, " - "and less than 2^63"); - return; - } --- -2.39.3 - diff --git a/SOURCES/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch b/SOURCES/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch new file mode 100644 index 0000000..c0fc2c4 --- /dev/null +++ b/SOURCES/kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch @@ -0,0 +1,65 @@ +From 621bad5cbfd7585f7bcef8bb4fcb17ab7ba52baa Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 27 Aug 2024 15:27:51 -0400 +Subject: [PATCH 4/4] vl: use qmp_device_add() in qemu_create_cli_devices() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 316: qdev-monitor: avoid QemuOpts in QMP device_add +RH-Jira: RHEL-39948 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Czenczek +RH-Commit: [4/4] e653aca40742b262e36e4d8dc554a54235e40e99 (stefanha/centos-stream-qemu-kvm) + +qemu_create_cli_devices() should use qmp_device_add() to match the +behavior of the QMP monitor. A comment explained that libvirt changes +implementing strict CLI syntax were needed. + +Peter Krempa has confirmed that modern libvirt uses +the same JSON for -device (CLI) and device_add (QMP). Go ahead and use +qmp_device_add(). + +Cc: Peter Krempa +Reviewed-by: Markus Armbruster +Signed-off-by: Stefan Hajnoczi +Message-ID: <20240827192751.948633-3-stefanha@redhat.com> +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit 11bf1d6aa06138e93b274e942d6992af63ffc510) +Signed-off-by: Stefan Hajnoczi +--- + system/vl.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/system/vl.c b/system/vl.c +index 5359231bf5..900d471f5e 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -2661,17 +2661,11 @@ static void qemu_create_cli_devices(void) + qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, NULL, &error_fatal); + QTAILQ_FOREACH(opt, &device_opts, next) { +- DeviceState *dev; ++ QObject *ret_data = NULL; ++ + loc_push_restore(&opt->loc); +- /* +- * TODO Eventually we should call qmp_device_add() here to make sure it +- * behaves the same, but QMP still has to accept incorrectly typed +- * options until libvirt is fixed and we want to be strict on the CLI +- * from the start, so call qdev_device_add_from_qdict() directly for +- * now. +- */ +- dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal); +- object_unref(OBJECT(dev)); ++ qmp_device_add(opt->opts, &ret_data, &error_fatal); ++ assert(ret_data == NULL); /* error_fatal aborts */ + loc_pop(&opt->loc); + } + rom_reset_order_override(); +-- +2.39.3 + diff --git a/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch b/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch new file mode 100644 index 0000000..39d808a --- /dev/null +++ b/SOURCES/kvm-vnc-fix-crash-when-no-console-attached.patch @@ -0,0 +1,61 @@ +From b38e94f0f0d45f8edd30828d4bb620430e604048 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 20 Aug 2024 17:11:12 +0400 +Subject: [PATCH 10/10] vnc: fix crash when no console attached +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +RH-MergeRequest: 300: vnc: fix crash when no console attached +RH-Jira: RHEL-61633 +RH-Acked-by: Miroslav Rezanina +RH-Commit: [1/1] 91fc70408701fa1e20ed8fefb8cdf424451dcc20 (marcandre.lureau-rh/qemu-kvm-centos) + +JIRA: https://issues.redhat.com/browse/RHEL-61633 + +Since commit e99441a3793b5 ("ui/curses: Do not use console_select()") +qemu_text_console_put_keysym() no longer checks for NULL console +argument, which leads to a later crash: + +Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. +0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332 +332 } else if (s->echo && (keysym == '\r' || keysym == '\n')) { +(gdb) bt + #0 0x00005555559ee186 in qemu_text_console_handle_keysym (s=0x0, keysym=31) at ../ui/console-vc.c:332 + #1 0x00005555559e18e5 in qemu_text_console_put_keysym (s=, keysym=) at ../ui/console.c:303 + #2 0x00005555559f2e88 in do_key_event (vs=vs@entry=0x5555579045c0, down=down@entry=1, keycode=keycode@entry=60, sym=sym@entry=65471) at ../ui/vnc.c:2034 + #3 0x00005555559f845c in ext_key_event (vs=0x5555579045c0, down=1, sym=65471, keycode=) at ../ui/vnc.c:2070 + #4 protocol_client_msg (vs=0x5555579045c0, data=, len=) at ../ui/vnc.c:2514 + #5 0x00005555559f515c in vnc_client_read (vs=0x5555579045c0) at ../ui/vnc.c:1607 + +Fixes: e99441a3793b5 ("ui/curses: Do not use console_select()") +Fixes: https://issues.redhat.com/browse/RHEL-50529 +Cc: qemu-stable@nongnu.org +Signed-off-by: Marc-André Lureau +Reviewed-by: Akihiko Odaki +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev + +(cherry picked from commit 0e60fc80938d9ce84274a36ddfaaa640bdef2be8) +Signed-off-by: Marc-André Lureau +--- + ui/vnc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ui/vnc.c b/ui/vnc.c +index dae5d51210..5057ec8680 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -1935,7 +1935,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) + } + + qkbd_state_key_event(vs->vd->kbd, qcode, down); +- if (!qemu_console_is_graphic(vs->vd->dcl.con)) { ++ if (QEMU_IS_TEXT_CONSOLE(vs->vd->dcl.con)) { + QemuTextConsole *con = QEMU_TEXT_CONSOLE(vs->vd->dcl.con); + bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK); + bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL); +-- +2.39.3 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index cc7b200..5422e1f 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -148,8 +148,8 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm -Version: 9.0.0 -Release: 10%{?rcrel}%{?dist}%{?cc_suffix} +Version: 9.1.0 +Release: 15%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -177,261 +177,294 @@ Source36: README.tests Patch0004: 0004-Initial-redhat-build.patch Patch0005: 0005-Enable-disable-devices-for-RHEL.patch Patch0006: 0006-Machine-type-related-general-changes.patch -Patch0007: 0007-Add-aarch64-machine-types.patch -Patch0008: 0008-Add-ppc64-machine-types.patch -Patch0009: 0009-Add-s390x-machine-types.patch -Patch0010: 0010-Add-x86_64-machine-types.patch -Patch0011: 0011-Enable-make-check.patch -Patch0012: 0012-vfio-cap-number-of-devices-that-can-be-assigned.patch -Patch0013: 0013-Add-support-statement-to-help-output.patch -Patch0014: 0014-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch -Patch0015: 0015-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch -Patch0016: 0016-Add-upstream-compatibility-bits.patch -Patch0017: 0017-x86-rhel-9.4.0-machine-type-compat-fix.patch -# For RHEL-34945 - [aarch64, kvm-unit-tests] all tests tagged as FAIL [qemu-kvm: GLib: g_ptr_array_add: assertion 'rarray' failed] -Patch18: kvm-hw-arm-virt-Fix-spurious-call-to-arm_virt_compat_set.patch -# For RHEL-30362 - Check/fix machine type compatibility for QEMU 9.0.0 [x86_64][rhel-9.5.0] -Patch19: kvm-Revert-x86-rhel-9.4.0-machine-type-compat-fix.patch -# For RHEL-33440 - Qemu hang when quit dst vm after storage migration(nbd+tls) -Patch20: kvm-nbd-server-do-not-poll-within-a-coroutine-context.patch -# For RHEL-33440 - Qemu hang when quit dst vm after storage migration(nbd+tls) -Patch21: kvm-nbd-server-Mark-negotiation-functions-as-coroutine_f.patch -# For RHEL-33440 - Qemu hang when quit dst vm after storage migration(nbd+tls) -Patch22: kvm-qio-Inherit-follow_coroutine_ctx-across-TLS.patch -# For RHEL-33440 - Qemu hang when quit dst vm after storage migration(nbd+tls) -Patch23: kvm-iotests-test-NBD-TLS-iothread.patch -# For RHEL-34621 - [RHEL9.5.0][stable_guest_abi]Failed to migrate VM with (qemu) qemu-kvm: Missing section footer for 0000:00:01.0/virtio-gpu qemu-kvm: load of migration failed: Invalid argument -Patch24: kvm-virtio-gpu-fix-v2-migration.patch -# For RHEL-34621 - [RHEL9.5.0][stable_guest_abi]Failed to migrate VM with (qemu) qemu-kvm: Missing section footer for 0000:00:01.0/virtio-gpu qemu-kvm: load of migration failed: Invalid argument -Patch25: kvm-rhel-9.4.0-machine-type-compat-for-virtio-gpu-migrat.patch -# For RHEL-42411 - qemu-kvm: linux-aio: add support for IO_CMD_FDSYNC command -Patch26: kvm-linux-aio-add-IO_CMD_FDSYNC-command-support.patch -# For RHEL-34618 - aio=io_uring: Assertion failure `luringcb->co->ctx == s->aio_context' with block_resize -# For RHEL-38697 - aio=native: Assertion failure `laiocb->co->ctx == laiocb->ctx->aio_context' with block_resize -Patch27: kvm-Revert-monitor-use-aio_co_reschedule_self.patch -# For RHEL-34618 - aio=io_uring: Assertion failure `luringcb->co->ctx == s->aio_context' with block_resize -# For RHEL-38697 - aio=native: Assertion failure `laiocb->co->ctx == laiocb->ctx->aio_context' with block_resize -Patch28: kvm-aio-warn-about-iohandler_ctx-special-casing.patch -# For RHEL-36159 - qemu crash on Assertion `block->n_free_ciphers > 0' failed in guest installation with luks and iothread-vq-mapping -Patch29: kvm-block-crypto-create-ciphers-on-demand.patch -# For RHEL-36159 - qemu crash on Assertion `block->n_free_ciphers > 0' failed in guest installation with luks and iothread-vq-mapping -Patch30: kvm-crypto-block-drop-qcrypto_block_open-n_threads-argum.patch -# For RHEL-35611 - CVE-2024-4467 qemu-kvm: QEMU: 'qemu-img info' leads to host file read/write [rhel-9.5] -Patch31: kvm-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch -# For RHEL-35611 - CVE-2024-4467 qemu-kvm: QEMU: 'qemu-img info' leads to host file read/write [rhel-9.5] -Patch32: kvm-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch -# For RHEL-35611 - CVE-2024-4467 qemu-kvm: QEMU: 'qemu-img info' leads to host file read/write [rhel-9.5] -Patch33: kvm-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch -# For RHEL-35611 - CVE-2024-4467 qemu-kvm: QEMU: 'qemu-img info' leads to host file read/write [rhel-9.5] -Patch34: kvm-block-Parse-filenames-only-when-explicitly-requested.patch -# For RHEL-40708 - [RHEL9.5.0][virtio_fs][s390x] after hot-unplug the vhost-user-fs-ccw device, the device is failed to hot-plug again -Patch35: kvm-hw-virtio-Fix-the-de-initialization-of-vhost-user-de.patch -# For RHEL-39936 - ARCH_DMA_MINALIGN smaller than CTR_EL0.CWG (128 < 256) on FUJITSU -Patch36: kvm-hw-arm-virt-Avoid-unexpected-warning-from-Linux-gues.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch37: kvm-introduce-pc_rhel_9_5_compat.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch38: kvm-target-i386-add-guest-phys-bits-cpu-property.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch39: kvm-kvm-add-support-for-guest-physical-bits.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch40: kvm-i386-kvm-Move-architectural-CPUID-leaf-generation-to.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch41: kvm-target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch42: kvm-target-i386-Add-new-CPU-model-SierraForest.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch43: kvm-target-i386-Export-RFDS-bit-to-guests.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch44: kvm-pci-host-q35-Move-PAM-initialization-above-SMRAM-ini.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch45: kvm-q35-Introduce-smm_ranges-property-for-q35-pci-host.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch46: kvm-hw-i386-acpi-Set-PCAT_COMPAT-bit-only-when-pic-is-no.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch47: kvm-confidential-guest-support-Add-kvm_init-and-kvm_rese.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch48: kvm-i386-sev-Switch-to-use-confidential_guest_kvm_init.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch49: kvm-ppc-pef-switch-to-use-confidential_guest_kvm_init-re.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch50: kvm-s390-Switch-to-use-confidential_guest_kvm_init.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch51: kvm-scripts-update-linux-headers-Add-setup_data.h-to-imp.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch52: kvm-scripts-update-linux-headers-Add-bits.h-to-file-impo.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch53: kvm-linux-headers-update-to-current-kvm-next.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch54: kvm-runstate-skip-initial-CPU-reset-if-reset-is-not-actu.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch55: kvm-KVM-track-whether-guest-state-is-encrypted.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch56: kvm-KVM-remove-kvm_arch_cpu_check_are_resettable.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch57: kvm-target-i386-introduce-x86-confidential-guest.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch58: kvm-target-i386-Implement-mc-kvm_type-to-get-VM-type.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch59: kvm-target-i386-SEV-use-KVM_SEV_INIT2-if-possible.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch60: kvm-i386-sev-Add-legacy-vm-type-parameter-for-SEV-guest-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch61: kvm-hw-i386-sev-Use-legacy-SEV-VM-types-for-older-machin.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch62: kvm-trace-kvm-Split-address-space-and-slot-id-in-trace_k.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch63: kvm-kvm-Introduce-support-for-memory_attributes.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch64: kvm-RAMBlock-Add-support-of-KVM-private-guest-memfd.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch65: kvm-kvm-Enable-KVM_SET_USER_MEMORY_REGION2-for-memslot.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch66: kvm-kvm-memory-Make-memory-type-private-by-default-if-it.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch67: kvm-HostMem-Add-mechanism-to-opt-in-kvm-guest-memfd-via-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch68: kvm-RAMBlock-make-guest_memfd-require-uncoordinated-disc.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch69: kvm-physmem-Introduce-ram_block_discard_guest_memfd_rang.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch70: kvm-kvm-handle-KVM_EXIT_MEMORY_FAULT.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch71: kvm-kvm-tdx-Don-t-complain-when-converting-vMMIO-region-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch72: kvm-kvm-tdx-Ignore-memory-conversion-to-shared-of-unassi.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch73: kvm-hw-i386-x86-Eliminate-two-if-statements-in-x86_bios_.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch74: kvm-hw-i386-Have-x86_bios_rom_init-take-X86MachineState-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch75: kvm-hw-i386-pc_sysfw-Remove-unused-parameter-from-pc_isa.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch76: kvm-hw-i386-x86-Don-t-leak-isa-bios-memory-regions.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch77: kvm-hw-i386-x86-Don-t-leak-pc.bios-memory-region.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch78: kvm-hw-i386-x86-Extract-x86_isa_bios_init-from-x86_bios_.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch79: kvm-hw-i386-pc_sysfw-Alias-rather-than-copy-isa-bios-reg.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch80: kvm-i386-correctly-select-code-in-hw-i386-that-depends-o.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch81: kvm-i386-pc-remove-unnecessary-MachineClass-overrides.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch82: kvm-hw-i386-split-x86.c-in-multiple-parts.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch83: kvm-scripts-update-linux-header.sh-be-more-src-tree-frie.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch84: kvm-scripts-update-linux-headers.sh-Remove-temporary-dir.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch85: kvm-scripts-update-linux-headers.sh-Fix-the-path-of-setu.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch86: kvm-update-linux-headers-fix-forwarding-to-asm-generic-h.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch87: kvm-update-linux-headers-move-pvpanic.h-to-correct-direc.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch88: kvm-linux-headers-Update-to-current-kvm-next.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch89: kvm-update-linux-headers-import-linux-kvm_para.h-header.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch90: kvm-machine-allow-early-use-of-machine_require_guest_mem.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch91: kvm-i386-sev-Replace-error_report-with-error_setg.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch92: kvm-i386-sev-Introduce-sev-common-type-to-encapsulate-co.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch93: kvm-i386-sev-Move-sev_launch_update-to-separate-class-me.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch94: kvm-i386-sev-Move-sev_launch_finish-to-separate-class-me.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch95: kvm-i386-sev-Introduce-sev-snp-guest-object.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch96: kvm-i386-sev-Add-a-sev_snp_enabled-helper.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch97: kvm-i386-sev-Add-sev_kvm_init-override-for-SEV-class.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch98: kvm-i386-sev-Add-snp_kvm_init-override-for-SNP-class.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch99: kvm-i386-cpu-Set-SEV-SNP-CPUID-bit-when-SNP-enabled.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch100: kvm-i386-sev-Don-t-return-launch-measurements-for-SEV-SN.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch101: kvm-i386-sev-Add-a-class-method-to-determine-KVM-VM-type.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch102: kvm-i386-sev-Update-query-sev-QAPI-format-to-handle-SEV-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch103: kvm-i386-sev-Add-the-SNP-launch-start-context.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch104: kvm-i386-sev-Add-handling-to-encrypt-finalize-guest-laun.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch105: kvm-i386-sev-Set-CPU-state-to-protected-once-SNP-guest-p.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch106: kvm-hw-i386-sev-Add-function-to-get-SEV-metadata-from-OV.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch107: kvm-i386-sev-Add-support-for-populating-OVMF-metadata-pa.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch108: kvm-i386-sev-Add-support-for-SNP-CPUID-validation.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch109: kvm-hw-i386-sev-Add-support-to-encrypt-BIOS-when-SEV-SNP.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch110: kvm-i386-sev-Invoke-launch_updata_data-for-SEV-class.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch111: kvm-i386-sev-Invoke-launch_updata_data-for-SNP-class.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch112: kvm-i386-kvm-Add-KVM_EXIT_HYPERCALL-handling-for-KVM_HC_.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch113: kvm-i386-sev-Enable-KVM_HC_MAP_GPA_RANGE-hcall-for-SNP-g.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch114: kvm-i386-sev-Extract-build_kernel_loader_hashes.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch115: kvm-i386-sev-Reorder-struct-declarations.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch116: kvm-i386-sev-Allow-measured-direct-kernel-boot-on-SNP.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch117: kvm-memory-Introduce-memory_region_init_ram_guest_memfd.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch118: kvm-hw-i386-sev-Use-guest_memfd-for-legacy-ROMs.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch119: kvm-hw-i386-Add-support-for-loading-BIOS-using-guest_mem.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch120: kvm-i386-sev-fix-unreachable-code-coverity-issue.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch121: kvm-i386-sev-Move-SEV_COMMON-null-check-before-dereferen.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch122: kvm-i386-sev-Return-when-sev_common-is-null.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch123: kvm-target-i386-SEV-fix-formatting-of-CPUID-mismatch-mes.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch124: kvm-i386-sev-Fix-error-message-in-sev_get_capabilities.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch125: kvm-i386-sev-Fallback-to-the-default-SEV-device-if-none-.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch126: kvm-i386-sev-Don-t-allow-automatic-fallback-to-legacy-KV.patch -# For RHEL-39544 - [QEMU] Add support for AMD SEV-SNP to Qemu -Patch127: kvm-target-i386-SEV-fix-mismatch-in-vcek-disabled-proper.patch -# For RHEL-50336 - Fail to boot up the guest including vtpm and virtio-rng (max-bytes=0) devices -Patch128: kvm-virtio-rng-block-max-bytes-0.patch -# For RHEL-50000 - scsi-block: Cannot setup Windows Failover Cluster, qemu crashes on assert -Patch129: kvm-scsi-disk-Use-positive-return-value-for-status-in-dm.patch -# For RHEL-50000 - scsi-block: Cannot setup Windows Failover Cluster, qemu crashes on assert -Patch130: kvm-scsi-block-Don-t-skip-callback-for-sgio-error-status.patch -# For RHEL-50000 - scsi-block: Cannot setup Windows Failover Cluster, qemu crashes on assert -Patch131: kvm-scsi-disk-Add-warning-comments-that-host_status-erro.patch -# For RHEL-50000 - scsi-block: Cannot setup Windows Failover Cluster, qemu crashes on assert -Patch132: kvm-scsi-disk-Always-report-RESERVATION_CONFLICT-to-gues.patch -# For RHEL-52617 - CVE-2024-7409 qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-9.5] -Patch133: kvm-nbd-server-Plumb-in-new-args-to-nbd_client_add.patch -# For RHEL-52617 - CVE-2024-7409 qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-9.5] -Patch134: kvm-nbd-server-CVE-2024-7409-Cap-default-max-connections.patch -# For RHEL-52617 - CVE-2024-7409 qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-9.5] -Patch135: kvm-nbd-server-CVE-2024-7409-Drop-non-negotiating-client.patch -# For RHEL-52617 - CVE-2024-7409 qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-9.5] -Patch136: kvm-nbd-server-CVE-2024-7409-Close-stray-clients-at-serv.patch -# For RHEL-52250 - fsfreeze hooks break on the systems first restorecon -Patch137: kvm-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch -# For RHEL-52617 - CVE-2024-7409 qemu-kvm: Denial of Service via Improper Synchronization in QEMU NBD Server During Socket Closure [rhel-9.5] -Patch138: kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch +Patch0007: 0007-meson-temporarily-disable-Wunused-function.patch +Patch0008: 0008-Remove-upstream-machine-type-versions-for-aarch64-s3.patch +Patch0009: 0009-Adapt-versioned-machine-type-macros-for-RHEL.patch +Patch0010: 0010-Increase-deletion-schedule-to-3-releases.patch +Patch0011: 0011-Add-downstream-aarch64-versioned-virt-machine-types.patch +Patch0012: 0012-Add-downstream-ppc64-versioned-spapr-machine-types.patch +Patch0013: 0013-Add-downstream-s390x-versioned-s390-ccw-virtio-machi.patch +Patch0014: 0014-Add-downstream-x86_64-versioned-pc-q35-machine-types.patch +Patch0015: 0015-Revert-meson-temporarily-disable-Wunused-function.patch +Patch0016: 0016-Enable-make-check.patch +Patch0017: 0017-vfio-cap-number-of-devices-that-can-be-assigned.patch +Patch0018: 0018-Add-support-statement-to-help-output.patch +Patch0019: 0019-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +Patch0020: 0020-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch +Patch0021: 0021-qemu-guest-agent-Update-the-logfile-path-of-qga-fsfr.patch +Patch0023: 0023-Add-upstream-compatibility-bits.patch +Patch0024: 0024-redhat-Add-QEMU-9.1-compat-handling-to-the-s390x-mac.patch +Patch0025: 0025-redhat-Add-rhel9.6.0-machine-type.patch +Patch0026: 0026-x86-ensure-compatibility-of-pc-q35-rhel9-and-pc-i440.patch +Patch0027: 0027-arm-ensure-compatibility-of-virt-rhel9.patch +Patch0028: 0028-arm-create-new-virt-machine-type-for-rhel-9.6.patch +Patch0029: 0029-x86-create-new-pc-q35-machine-type-for-rhel-9.6.patch +Patch0030: 0030-hw-arm-virt-Fix-Manufacturer-and-Product-Name-in-emu.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch31: kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch32: kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch33: kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch35: kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch36: kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch37: kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch38: kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch39: kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch40: kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch41: kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch42: kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch43: kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch44: kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch45: kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch46: kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch47: kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch48: kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch49: kvm-docs-system-Update-documentation-for-s390x-IPL.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch50: kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch51: kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch52: kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch +# For RHEL-11424 - [IBM 9.6 FEAT] KVM: Full boot order support - qemu part +Patch53: kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch +# For RHEL-64307 - High threshold value observed in vGPU live migration +Patch54: kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch +# For RHEL-64307 - High threshold value observed in vGPU live migration +Patch55: kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch +# For RHEL-60914 - Fail migration properly when put cpu register fails +Patch56: kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch +# For RHEL-60914 - Fail migration properly when put cpu register fails +Patch57: kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch +# For RHEL-11043 - [RFE] [HPEMC] [RHEL-9.6] qemu-kvm: support up to 4096 VCPUs +Patch58: kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch59: kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch60: kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch61: kvm-accel-kvm-refactor-dirty-ring-setup.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch62: kvm-KVM-Dynamic-sized-kvm-memslots-array.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch63: kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch64: kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch +# For RHEL-57682 - Bad migration performance when performing vGPU VM live migration +Patch65: kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch +# For RHEL-67844 - qemu crashed after killed virtiofsd during migration +Patch66: kvm-migration-Ensure-vmstate_save-sets-errp.patch +# For RHEL-67935 - QEMU should fail gracefully with passthrough devices in SEV-SNP guests +Patch67: kvm-vfio-container-Fix-container-object-destruction.patch +# For RHEL-68289 - [RHEL-9.6] QEMU core dump on applying merge property to memory backend +Patch68: kvm-hostmem-Apply-merge-property-after-the-memory-region.patch +# For RHEL-69477 - qemu crashed when migrate vm with multiqueue from rhel9.4 to rhel9.6 +Patch69: kvm-virtio-net-Add-queues-before-loading-them.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch70: kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch71: kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch72: kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch73: kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch74: kvm-scsi-fix-allocation-for-s390x-loadparm.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch75: kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch76: kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch +# For RHEL-68440 - The new "boot order" feature is sometimes not working as expected [RHEL 9] +Patch77: kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch +# For RHEL-61633 - Qemu-kvm crashed if no display device setting and switching display by remote-viewer [rhel-9] +Patch78: kvm-vnc-fix-crash-when-no-console-attached.patch +# For RHEL-66089 - warning: fd: migration to a file is deprecated when create or revert a snapshot +Patch79: kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch80: kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch81: kvm-s390x-cpumodel-add-msa10-subfunctions.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch82: kvm-s390x-cpumodel-add-msa11-subfunctions.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch83: kvm-s390x-cpumodel-add-msa12-changes.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch84: kvm-s390x-cpumodel-add-msa13-subfunctions.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch85: kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch86: kvm-linux-headers-Update-to-Linux-6.13-rc1.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch87: kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch88: kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch89: kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch90: kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch91: kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch92: kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch93: kvm-s390x-cpumodel-correct-PLO-feature-wording.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch94: kvm-s390x-cpumodel-Add-PLO-extension-facility.patch +# For RHEL-50212 - [IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part +Patch95: kvm-s390x-cpumodel-gen17-model.patch +# For RHEL-71940 - qemu-ga cannot freeze filesystems with sentinelone +Patch96: kvm-qga-skip-bind-mounts-in-fs-list.patch +# For RHEL-27832 - The post-copy migration of RT-VM leads to race while accessing vhost-user device and hung/stalled target VM +Patch97: kvm-vhost-fail-device-start-if-iotlb-update-fails.patch +# For RHEL-67107 - [aarch64] [rhel-9.6] Backport some important post 9.1 qemu fixes +Patch98: kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch +# For RHEL-39948 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-9.5] +Patch99: kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch +# For RHEL-39948 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-9.5] +Patch100: kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch +# For RHEL-39948 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-9.5] +Patch101: kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch +# For RHEL-39948 - qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-9.5] +Patch102: kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch +# For RHEL-53073 - kvm-unti kvm-hyperv_synic test is stuck on AMD with COS9 +Patch103: kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch +# For RHEL-73688 - VM crashes when requesting domstats +Patch104: kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch +# For RHEL-52278 - fsfreeze hooks doesn't log error on system logs when running hook fails +Patch105: kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch +# For RHEL-56340 - qemu-ga logs only "guest-fsfreeze called" (but not "guest-fsthaw called") +Patch106: kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch +# For RHEL-65616 - Failed to hot add PCIe device behind xio3130 downstream port +Patch107: kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch108: kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch109: kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch110: kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch111: kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch112: kvm-target-i386-add-CPUID.24-features-for-AVX10.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch113: kvm-target-i386-Add-feature-dependencies-for-AVX10.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch114: kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch115: kvm-target-i386-Introduce-GraniteRapids-v2-model.patch +# For RHEL-30316 - [Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support +# For RHEL-45111 - [Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4 +Patch116: kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch +# For RHEL-75782 - [Nvidia "Grace"] Lack of "PAuth" CPU feature results in live migration failure from RHEL 9.6 to 10 +Patch117: kvm-arm-disable-pauth-for-virt-rhel9.patch +# For RHEL-75782 - [Nvidia "Grace"] Lack of "PAuth" CPU feature results in live migration failure from RHEL 9.6 to 10 +Patch118: kvm-tests-qtest-disable-most-pauth-tests.patch +# For RHEL-72716 - Boot fall back to cdrom from network not always working +Patch119: kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch +# For RHEL-72716 - Boot fall back to cdrom from network not always working +Patch120: kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch +# For RHEL-72716 - Boot fall back to cdrom from network not always working +Patch121: kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch +# For RHEL-72716 - Boot fall back to cdrom from network not always working +Patch122: kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch +# For RHEL-67863 - Ensure qemu as NBD server does not flood logs [rhel 9.6] +Patch123: kvm-nbd-server-Silence-server-warnings-on-port-probes.patch +# For RHEL-78372 - Add vhost-user internal migration for passt [rhel-9] +Patch124: kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch +# For RHEL-78372 - Add vhost-user internal migration for passt [rhel-9] +Patch125: kvm-virtio-net-vhost-user-Implement-internal-migration.patch +# For RHEL-73891 - No RARP packets on the destination after migration [rhel-9.6] +Patch126: kvm-net-Fix-announce_self.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch127: kvm-migration-Add-helper-to-get-target-runstate.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch128: kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch129: kvm-migration-block-Make-late-block-active-the-default.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch130: kvm-migration-block-Apply-late-block-active-behavior-to-.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch131: kvm-migration-block-Fix-possible-race-with-block_inactiv.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch132: kvm-migration-block-Rewrite-disk-activation.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch133: kvm-block-Add-active-field-to-BlockDeviceInfo.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch134: kvm-block-Allow-inactivating-already-inactive-nodes.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch135: kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch136: kvm-migration-block-active-Remove-global-active-flag.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch137: kvm-block-Don-t-attach-inactive-child-to-active-node.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch138: kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch139: kvm-block-Add-option-to-create-inactive-nodes.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch140: kvm-block-Add-blockdev-set-active-QMP-command.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch141: kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch142: kvm-block-export-Don-t-ignore-image-activation-error-in-.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch143: kvm-block-Drain-nodes-before-inactivating-them.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch144: kvm-block-export-Add-option-to-allow-export-of-inactive-.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch145: kvm-nbd-server-Support-inactive-nodes.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch146: kvm-iotests-Add-filter_qtest.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch147: kvm-iotests-Add-qsd-migrate-case.patch +# For RHEL-54296 - Provide QMP command for block device reactivation after migration [rhel-9.5] +# For RHEL-78397 - backport fix for double migration of a paused VM (disk activation rewrite) +Patch148: kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch %if %{have_clang} BuildRequires: clang @@ -469,6 +502,8 @@ BuildRequires: librbd-devel # We need both because the 'stap' binary is probed for by configure BuildRequires: systemtap BuildRequires: systemtap-sdt-devel +# Required as we use dtrace for trace backend +BuildRequires: /usr/bin/dtrace # For VNC PNG support BuildRequires: libpng-devel # For virtiofs @@ -506,6 +541,7 @@ BuildRequires: libslirp-devel BuildRequires: pulseaudio-libs-devel BuildRequires: spice-protocol BuildRequires: capstone-devel +BuildRequires: python3-tomli # Requires for qemu-kvm package Requires: %{name}-core = %{epoch}:%{version}-%{release} @@ -776,7 +812,6 @@ ulimit -n 10240 --disable-attr \\\ --disable-auth-pam \\\ --disable-avx2 \\\ - --disable-avx512f \\\ --disable-avx512bw \\\ --disable-blkio \\\ --disable-block-drv-whitelist-in-tools \\\ @@ -832,7 +867,6 @@ ulimit -n 10240 --disable-linux-aio \\\ --disable-linux-io-uring \\\ --disable-linux-user \\\ - --disable-live-block-migration \\\ --disable-lto \\\ --disable-lzfse \\\ --disable-lzo \\\ @@ -852,7 +886,6 @@ ulimit -n 10240 --disable-parallels \\\ --disable-pie \\\ --disable-plugins \\\ - --disable-pvrdma \\\ --disable-qcow1 \\\ --disable-qed \\\ --disable-qga-vss \\\ @@ -931,6 +964,7 @@ run_configure() { --tls-priority=@QEMU,SYSTEM \ %{disable_everything} \ --with-devices-%{kvm_target}=%{kvm_target}-rh-devices \ + --rhel-version=9 \ "$@" echo "config-host.mak contents:" @@ -1060,7 +1094,7 @@ cp -a qemu-system-%{kvm_target} qemu-kvm %ifarch s390x # Copy the built new images into place for "make check": - cp pc-bios/s390-ccw/s390-ccw.img pc-bios/s390-ccw/s390-netboot.img pc-bios/ + cp pc-bios/s390-ccw/s390-ccw.img pc-bios/ %endif popd @@ -1199,7 +1233,6 @@ rm -rf %{buildroot}%{_datadir}/%{name}/skiboot.lid rm -rf %{buildroot}%{_datadir}/%{name}/qboot.rom rm -rf %{buildroot}%{_datadir}/%{name}/s390-ccw.img -rm -rf %{buildroot}%{_datadir}/%{name}/s390-netboot.img rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware.img rm -rf %{buildroot}%{_datadir}/%{name}/hppa-firmware64.img rm -rf %{buildroot}%{_datadir}/%{name}/canyonlands.dtb @@ -1223,9 +1256,8 @@ rm -rf %{buildroot}%{_libexecdir}/virtfs-proxy-helper rm -rf %{buildroot}%{_mandir}/man1/virtfs-proxy-helper* %ifarch s390x - # Use the s390-*.img that we've just built, not the pre-built ones + # Use the s390-ccw.img that we've just built, not the pre-built one install -m 0644 %{qemu_kvm_build}/pc-bios/s390-ccw/s390-ccw.img %{buildroot}%{_datadir}/%{name}/ - install -m 0644 %{qemu_kvm_build}/pc-bios/s390-ccw/s390-netboot.img %{buildroot}%{_datadir}/%{name}/ %else rm -rf %{buildroot}%{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so %endif @@ -1236,6 +1268,8 @@ rm -rf %{buildroot}%{_mandir}/man1/virtfs-proxy-helper* rm -rf %{buildroot}%{_datadir}/%{name}/multiboot.bin rm -rf %{buildroot}%{_datadir}/%{name}/multiboot_dma.bin rm -rf %{buildroot}%{_datadir}/%{name}/pvh.bin +%else + rm -rf %{buildroot}%{_bindir}/qemu-vmsr-helper %endif # Remove sparc files @@ -1414,7 +1448,6 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %ifarch s390x %{_datadir}/%{name}/s390-ccw.img - %{_datadir}/%{name}/s390-netboot.img %endif %{_datadir}/icons/* %{_datadir}/%{name}/linuxboot_dma.bin @@ -1498,6 +1531,222 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Mon Feb 17 2025 Jon Maloy - 9.1.0-15 +- kvm-net-Fix-announce_self.patch [RHEL-73891] +- kvm-migration-Add-helper-to-get-target-runstate.patch [RHEL-54296 RHEL-78397] +- kvm-qmp-cont-Only-activate-disks-if-migration-completed.patch [RHEL-54296 RHEL-78397] +- kvm-migration-block-Make-late-block-active-the-default.patch [RHEL-54296 RHEL-78397] +- kvm-migration-block-Apply-late-block-active-behavior-to-.patch [RHEL-54296 RHEL-78397] +- kvm-migration-block-Fix-possible-race-with-block_inactiv.patch [RHEL-54296 RHEL-78397] +- kvm-migration-block-Rewrite-disk-activation.patch [RHEL-54296 RHEL-78397] +- kvm-block-Add-active-field-to-BlockDeviceInfo.patch [RHEL-54296 RHEL-78397] +- kvm-block-Allow-inactivating-already-inactive-nodes.patch [RHEL-54296 RHEL-78397] +- kvm-block-Inactivate-external-snapshot-overlays-when-nec.patch [RHEL-54296 RHEL-78397] +- kvm-migration-block-active-Remove-global-active-flag.patch [RHEL-54296 RHEL-78397] +- kvm-block-Don-t-attach-inactive-child-to-active-node.patch [RHEL-54296 RHEL-78397] +- kvm-block-Fix-crash-on-block_resize-on-inactive-node.patch [RHEL-54296 RHEL-78397] +- kvm-block-Add-option-to-create-inactive-nodes.patch [RHEL-54296 RHEL-78397] +- kvm-block-Add-blockdev-set-active-QMP-command.patch [RHEL-54296 RHEL-78397] +- kvm-block-Support-inactive-nodes-in-blk_insert_bs.patch [RHEL-54296 RHEL-78397] +- kvm-block-export-Don-t-ignore-image-activation-error-in-.patch [RHEL-54296 RHEL-78397] +- kvm-block-Drain-nodes-before-inactivating-them.patch [RHEL-54296 RHEL-78397] +- kvm-block-export-Add-option-to-allow-export-of-inactive-.patch [RHEL-54296 RHEL-78397] +- kvm-nbd-server-Support-inactive-nodes.patch [RHEL-54296 RHEL-78397] +- kvm-iotests-Add-filter_qtest.patch [RHEL-54296 RHEL-78397] +- kvm-iotests-Add-qsd-migrate-case.patch [RHEL-54296 RHEL-78397] +- kvm-iotests-Add-NBD-based-tests-for-inactive-nodes.patch [RHEL-54296 RHEL-78397] +- Resolves: RHEL-73891 + (No RARP packets on the destination after migration [rhel-9.6]) +- Resolves: RHEL-54296 + (Provide QMP command for block device reactivation after migration [rhel-9.5]) +- Resolves: RHEL-78397 + (backport fix for double migration of a paused VM (disk activation rewrite)) + +* Mon Feb 10 2025 Jon Maloy - 9.1.0-14 +- kvm-nbd-server-Silence-server-warnings-on-port-probes.patch [RHEL-67863] +- kvm-vhost-Add-stubs-for-the-migration-state-transfer-int.patch [RHEL-78372] +- kvm-virtio-net-vhost-user-Implement-internal-migration.patch [RHEL-78372] +- Resolves: RHEL-67863 + (Ensure qemu as NBD server does not flood logs [rhel 9.6]) +- Resolves: RHEL-78372 + (Add vhost-user internal migration for passt [rhel-9]) + +* Thu Jan 30 2025 Jon Maloy - 9.1.0-13 +- kvm-pc-bios-s390-ccw-Abort-IPL-on-invalid-loadparm.patch [RHEL-72716] +- kvm-pc-bios-s390-ccw-virtio-Add-a-function-to-reset-a-vi.patch [RHEL-72716] +- kvm-pc-bios-s390-ccw-Fix-boot-problem-with-virtio-net-de.patch [RHEL-72716] +- kvm-pc-bios-s390-ccw-netmain-Fix-error-messages-with-reg.patch [RHEL-72716] +- Resolves: RHEL-72716 + (Boot fall back to cdrom from network not always working) + +* Mon Jan 27 2025 Jon Maloy - 9.1.0-12 +- kvm-target-i386-cpu-set-correct-supported-XCR0-features-.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-do-not-rely-on-ExtSaveArea-for-accelerat.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-return-bool-from-x86_cpu_filter_features.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-add-AVX10-feature-and-AVX10-version-prop.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-add-CPUID.24-features-for-AVX10.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-Add-feature-dependencies-for-AVX10.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-Add-AVX512-state-when-AVX10-is-supported.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-Introduce-GraniteRapids-v2-model.patch [RHEL-30316 RHEL-45111] +- kvm-target-i386-add-sha512-sm3-sm4-feature-bits.patch [RHEL-30316 RHEL-45111] +- kvm-arm-disable-pauth-for-virt-rhel9.patch [RHEL-75782] +- kvm-tests-qtest-disable-most-pauth-tests.patch [RHEL-75782] +- Resolves: RHEL-30316 + ([Intel 9.6 FEAT] [GNR] Virt-QEMU: Add AVX10.1 instruction support) +- Resolves: RHEL-45111 + ([Intel 9.6 FEAT] [CWF][DMR] Virt-QEMU: Advertise new instructions SHA2-512NI, SM3, and SM4) +- Resolves: RHEL-75782 + ([Nvidia "Grace"] Lack of "PAuth" CPU feature results in live migration failure from RHEL 9.6 to 10) + +* Tue Jan 21 2025 Jon Maloy - 9.1.0-11 +- kvm-pci-ensure-valid-link-status-bits-for-downstream-por.patch [RHEL-65616] +- Resolves: RHEL-65616 + (Failed to hot add PCIe device behind xio3130 downstream port) + +* Mon Jan 20 2025 Miroslav Rezanina - 9.1.0-10 +- kvm-target-i386-Make-sure-SynIC-state-is-really-updated-.patch [RHEL-53073] +- kvm-hw-virtio-fix-crash-in-processing-balloon-stats.patch [RHEL-73688] +- kvm-qemu-ga-Optimize-freeze-hook-script-logic-of-logging.patch [RHEL-52278] +- kvm-qga-Add-log-to-guest-fsfreeze-thaw-command.patch [RHEL-56340] +- Resolves: RHEL-53073 + (kvm-unti kvm-hyperv_synic test is stuck on AMD with COS9) +- Resolves: RHEL-73688 + (VM crashes when requesting domstats) +- Resolves: RHEL-52278 + (fsfreeze hooks doesn't log error on system logs when running hook fails) +- Resolves: RHEL-56340 + (qemu-ga logs only "guest-fsfreeze called" (but not "guest-fsthaw called")) + +* Mon Jan 13 2025 Miroslav Rezanina - 9.1.0-9 +- kvm-qdev-Fix-set_pci_devfn-to-visit-option-only-once.patch [RHEL-39948] +- kvm-tests-avocado-hotplug_blk-Fix-addr-in-device_add-com.patch [RHEL-39948] +- kvm-qdev-monitor-avoid-QemuOpts-in-QMP-device_add.patch [RHEL-39948] +- kvm-vl-use-qmp_device_add-in-qemu_create_cli_devices.patch [RHEL-39948] +- Resolves: RHEL-39948 + (qom-get iothread-vq-mapping is empty on new hotplug disk [rhel-9.5]) + +* Mon Jan 06 2025 Miroslav Rezanina - 9.1.0-8 +- kvm-linux-headers-Update-to-Linux-v6.12-rc5.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-msa10-subfunctions.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-msa11-subfunctions.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-msa12-changes.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-msa13-subfunctions.patch [RHEL-50212] +- kvm-s390x-cpumodel-Add-ptff-Query-Time-Stamp-Event-QTSE-.patch [RHEL-50212] +- kvm-linux-headers-Update-to-Linux-6.13-rc1.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-Concurrent-functions-facility-sup.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-Vector-Enhancements-facility-3.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-Miscellaneous-Instruction-Extensi.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-Vector-Packed-Decimal-Enhancement.patch [RHEL-50212] +- kvm-s390x-cpumodel-add-Ineffective-nonconstrained-transa.patch [RHEL-50212] +- kvm-s390x-cpumodel-Add-Sequential-Instruction-Fetching-f.patch [RHEL-50212] +- kvm-s390x-cpumodel-correct-PLO-feature-wording.patch [RHEL-50212] +- kvm-s390x-cpumodel-Add-PLO-extension-facility.patch [RHEL-50212] +- kvm-s390x-cpumodel-gen17-model.patch [RHEL-50212] +- kvm-qga-skip-bind-mounts-in-fs-list.patch [RHEL-71940] +- kvm-vhost-fail-device-start-if-iotlb-update-fails.patch [RHEL-27832] +- kvm-hw-char-pl011-Use-correct-masks-for-IBRD-and-FBRD.patch [RHEL-67107] +- Resolves: RHEL-50212 + ([IBM 9.6 FEAT] KVM: CPU model for new IBM Z HW - qemu part) +- Resolves: RHEL-71940 + (qemu-ga cannot freeze filesystems with sentinelone) +- Resolves: RHEL-27832 + (The post-copy migration of RT-VM leads to race while accessing vhost-user device and hung/stalled target VM) +- Resolves: RHEL-67107 + ([aarch64] [rhel-9.6] Backport some important post 9.1 qemu fixes) + +* Fri Dec 13 2024 Miroslav Rezanina - 9.1.0-7 +- kvm-migration-Allow-pipes-to-keep-working-for-fd-migrati.patch [RHEL-66089] +- Resolves: RHEL-66089 + (warning: fd: migration to a file is deprecated when create or revert a snapshot) + +* Thu Dec 05 2024 Miroslav Rezanina - 9.1.0-6 +- kvm-virtio-net-Add-queues-before-loading-them.patch [RHEL-69477] +- kvm-docs-system-s390x-bootdevices-Update-loadparm-docume.patch [RHEL-68440] +- kvm-docs-system-bootindex-Make-it-clear-that-s390x-can-a.patch [RHEL-68440] +- kvm-hw-s390x-Restrict-loadparm-property-to-devices-that-.patch [RHEL-68440] +- kvm-hw-Add-loadparm-property-to-scsi-disk-devices-for-bo.patch [RHEL-68440] +- kvm-scsi-fix-allocation-for-s390x-loadparm.patch [RHEL-68440] +- kvm-pc-bios-s390x-Initialize-cdrom-type-to-false-for-eac.patch [RHEL-68440] +- kvm-pc-bios-s390x-Initialize-machine-loadparm-before-pro.patch [RHEL-68440] +- kvm-pc-bios-s390-ccw-Re-initialize-receive-queue-index-b.patch [RHEL-68440] +- kvm-vnc-fix-crash-when-no-console-attached.patch [RHEL-61633] +- Resolves: RHEL-69477 + (qemu crashed when migrate vm with multiqueue from rhel9.4 to rhel9.6) +- Resolves: RHEL-68440 + (The new "boot order" feature is sometimes not working as expected [RHEL 9]) +- Resolves: RHEL-61633 + (Qemu-kvm crashed if no display device setting and switching display by remote-viewer [rhel-9]) + +* Mon Nov 25 2024 Jon Maloy - 9.1.0-5 +- kvm-vfio-container-Fix-container-object-destruction.patch [RHEL-67935] +- kvm-hostmem-Apply-merge-property-after-the-memory-region.patch [RHEL-68289] +- Resolves: RHEL-67935 + (QEMU should fail gracefully with passthrough devices in SEV-SNP guests) +- Resolves: RHEL-68289 + ([RHEL-9.6] QEMU core dump on applying merge property to memory backend) + +* Sun Nov 24 2024 Jon Maloy - 9.1.0-4 +- kvm-migration-Ensure-vmstate_save-sets-errp.patch [RHEL-67844] +- Resolves: RHEL-67844 + (qemu crashed after killed virtiofsd during migration) + +* Tue Nov 19 2024 Miroslav Rezanina - 9.1.0-3 +- kvm-pc-q35-Bump-max_cpus-to-4096-vcpus.patch [RHEL-11043] +- kvm-kvm-replace-fprintf-with-error_report-printf-in-kvm_.patch [RHEL-57682] +- kvm-kvm-refactor-core-virtual-machine-creation-into-its-.patch [RHEL-57682] +- kvm-accel-kvm-refactor-dirty-ring-setup.patch [RHEL-57682] +- kvm-KVM-Dynamic-sized-kvm-memslots-array.patch [RHEL-57682] +- kvm-KVM-Define-KVM_MEMSLOTS_NUM_MAX_DEFAULT.patch [RHEL-57682] +- kvm-KVM-Rename-KVMMemoryListener.nr_used_slots-to-nr_slo.patch [RHEL-57682] +- kvm-KVM-Rename-KVMState-nr_slots-to-nr_slots_max.patch [RHEL-57682] +- kvm-Require-new-dtrace-package.patch [RHEL-67900] +- Resolves: RHEL-11043 + ([RFE] [HPEMC] [RHEL-9.6] qemu-kvm: support up to 4096 VCPUs) +- Resolves: RHEL-57682 + (Bad migration performance when performing vGPU VM live migration ) +- Resolves: RHEL-67900 + (Failed to build qemu-kvm due to missing dtrace [rhel-9.6]) + +* Mon Nov 11 2024 Miroslav Rezanina - 9.1.0-2 +- kvm-hw-s390x-ipl-Provide-more-memory-to-the-s390-ccw.img.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Use-the-libc-from-SLOF-and-remove-s.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Link-the-netboot-code-into-the-main.patch [RHEL-11424] +- kvm-redhat-Remove-the-s390-netboot.img-from-the-spec-fil.patch [RHEL-11424] +- kvm-hw-s390x-Remove-the-possibility-to-load-the-s390-net.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Merge-netboot.mak-into-the-main-Mak.patch [RHEL-11424] +- kvm-docs-system-s390x-bootdevices-Update-the-documentati.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Remove-panics-from-ISO-IPL-path.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Remove-panics-from-ECKD-IPL-path.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Remove-panics-from-SCSI-IPL-path.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Remove-panics-from-DASD-IPL-path.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Remove-panics-from-Netboot-IPL-path.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Enable-failed-IPL-to-return-after-e.patch [RHEL-11424] +- kvm-include-hw-s390x-Add-include-files-for-common-IPL-st.patch [RHEL-11424] +- kvm-s390x-Add-individual-loadparm-assignment-to-CCW-devi.patch [RHEL-11424] +- kvm-hw-s390x-Build-an-IPLB-for-each-boot-device.patch [RHEL-11424] +- kvm-s390x-Rebuild-IPLB-for-SCSI-device-directly-from-DIA.patch [RHEL-11424] +- kvm-pc-bios-s390x-Enable-multi-device-boot-loop.patch [RHEL-11424] +- kvm-docs-system-Update-documentation-for-s390x-IPL.patch [RHEL-11424] +- kvm-tests-qtest-Add-s390x-boot-order-tests-to-cdrom-test.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Clarify-alignment-is-in-bytes.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Don-t-generate-TEXTRELs.patch [RHEL-11424] +- kvm-pc-bios-s390-ccw-Introduce-EXTRA_LDFLAGS.patch [RHEL-11424] +- kvm-vfio-migration-Report-only-stop-copy-size-in-vfio_st.patch [RHEL-64307] +- kvm-vfio-migration-Change-trace-formats-from-hex-to-deci.patch [RHEL-64307] +- kvm-kvm-Allow-kvm_arch_get-put_registers-to-accept-Error.patch [RHEL-60914] +- kvm-target-i386-kvm-Report-which-action-failed-in-kvm_ar.patch [RHEL-60914] +- Resolves: RHEL-11424 + ([IBM 9.6 FEAT] KVM: Full boot order support - qemu part) +- Resolves: RHEL-64307 + (High threshold value observed in vGPU live migration) +- Resolves: RHEL-60914 + (Fail migration properly when put cpu register fails) + +* Thu Sep 26 2024 Miroslav Rezanina - 9.1.0-1 +- Rebase to QEMU 9.1 [RHEL-41247] +- Resolves: RHEL-41247 + (Rebase qemu-9.1 for RHEL 9.6) +- * Mon Sep 02 2024 Miroslav Rezanina - 9.0.0-10 - kvm-nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch [RHEL-52617] - Resolves: RHEL-52617 @@ -1673,6 +1922,7 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ - Resolves: RHEL-30362 (Check/fix machine type compatibility for QEMU 9.0.0 [x86_64][rhel-9.5.0]) + * Wed Apr 24 2024 Miroslav Rezanina - 9.0.0-1 - Rebase to QEMU 9.0.0 [RHEL-28073] - Resolves: RHEL-28073