* Thu Sep 26 2024 Miroslav Rezanina <mrezanin@redhat.com> - 9.1.0-1

- Rebase to QEMU 9.1 [RHEL-41247]
- Resolves: RHEL-41247
  (Rebase qemu-9.1 for RHEL 9.6)
This commit is contained in:
Miroslav Rezanina 2024-09-26 03:25:53 -04:00
parent 72caf15fff
commit c89d528a45
153 changed files with 1814 additions and 22051 deletions

1
.gitignore vendored
View File

@ -29,3 +29,4 @@
/qemu-8.1.0.tar.xz
/qemu-8.2.0.tar.xz
/qemu-9.0.0.tar.xz
/qemu-9.1.0.tar.xz

View File

@ -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 <mrezanin@redhat.com>
Date: Wed, 26 May 2021 10:56:02 +0200
Subject: Initial redhat build
@ -13,7 +13,7 @@ several issues are fixed in QEMU tree:
We disable make check due to issues with some of the tests.
This rebase is based on qemu-kvm-8.2.0-11.el9
This rebase is based on qemu-kvm-9.0.0-10.el9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
--
@ -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 <mrezanin@redhat.com>
.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

View File

@ -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 <mrezanin@redhat.com>
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)

View File

@ -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 <mrezanin@redhat.com>
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;

View File

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

View File

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

View File

@ -0,0 +1,139 @@
From c5e6c533f498a698ef6797f58f3f8aced62476fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:25: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é <berrange@redhat.com>
Signed-off-by: Mirslav Rezanina <mrezanin@redhat.com>
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

View File

@ -0,0 +1,195 @@
From 3cb90f2fec9096ddde4038e037e82a9c44614791 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 15:27:03 +0100
Subject: Adapt versioned machine type macros for RHEL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The versioned machine type macros are changed thus:
* All symbol names get 'rhel' inserted eg 'virt_rhel_macine_9_4_0_<blah>'
* All machine type names get 'rhel' inserted eg 'virt-rhel9.4.0-machine'
* Lifecycle is changed to deprecate after 1 major RHEL release,
force non-registration (effectively deletion) after 2 major releases
* Custom message to explain RHEL deprecation/deletion policy
* Remove upstream logic that temporarily disabled deletion since
the upstream constraints in this area don't apply to RHEL
* For automatic deprecation/deletion, RHEL_VERSION is defined
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
.distro/Makefile.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

View File

@ -0,0 +1,33 @@
From f25d2c0298d8d6328cb0071926d477f647a512fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 18:45:58 +0100
Subject: Increase deletion schedule to 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é <berrange@redhat.com>
---
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

View File

@ -0,0 +1,368 @@
From a2e5218bbe2e39712e06c5d8a51f836807c1cae9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:25:47 +0100
Subject: Add downstream aarch64 versioned 'virt' machine types
Adding changes to add RHEL machine types for aarch64 architecture.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
Rebase notes (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

View File

@ -1,7 +1,7 @@
From fb905dbe5b51ed899062ef99a2dd7f238d3e3384 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:27:13 +0200
Subject: Add ppc64 machine types
From 676f3da2fc29ae71ed4189483b86e3c6496b8905 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44: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)
+{

View File

@ -1,7 +1,7 @@
From 04178c77cfe188b4eed9c08a0bf66842e61fe5dc Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:47:32 +0200
Subject: Add s390x machine types
From 450ae6631771593689f7f9c3eb2081e93d3e75c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44:36 +0100
Subject: Add downstream s390x versioned 's390-ccw-virtio' machine types
Adding changes to add RHEL machine types for s390x architecture.
@ -11,6 +11,9 @@ Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Rebase changes (7.1.0):
- Moved adding rhel_old_machine_deprecation variable to general machine types commit
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)

View File

@ -1,7 +1,7 @@
From 3c88acb005806ad2386ab6c94a8831151f624738 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Fri, 19 Oct 2018 13:10:31 +0200
Subject: Add x86_64 machine types
From a7d5687a80eca95a1c39b73bebb9d478f3adfb0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Wed, 3 Jul 2024 13:44:41 +0100
Subject: 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 <xen/hvm/hvm_info_table.h>
#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

View File

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

View File

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

View File

@ -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 <mrezanin@redhat.com>
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

View File

@ -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 <bsd@redhat.com>
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 {

View File

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

View File

@ -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 <ehabkost@redhat.com>
Date: Wed, 4 Dec 2013 18:53:17 +0100
Subject: Add support statement to -help output
@ -21,10 +21,10 @@ Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1 file changed, 9 insertions(+)
diff --git a/system/vl.c b/system/vl.c
index 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");

View File

@ -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 <mrezanin@redhat.com>
Date: Wed, 8 Jul 2020 08:35:50 +0200
Subject: Use qemu-kvm in documentation instead of qemu-system-<arch>
@ -36,10 +36,10 @@ index 52d6454b93..d74dbdeca9 100644
.. |I2C| replace:: I\ :sup:`2`\ C
.. |I2S| replace:: I\ :sup:`2`\ S
diff --git a/qemu-options.hx b/qemu-options.hx
index 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
::

View File

@ -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 <kwolf@redhat.com>
Date: Fri, 20 Aug 2021 18:25:12 +0200
Subject: qcow2: Deprecation warning when opening v2 images rw
@ -44,7 +44,7 @@ Rebase notes (6.1.0):
2 files changed, 7 insertions(+)
diff --git a/block/qcow2.c b/block/qcow2.c
index 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()

View File

@ -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 <demeng@redhat.com>
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 <None>
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 <demeng@redhat.com>
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(-)

View File

@ -0,0 +1,109 @@
From 2b6f52a948d4ee1bbaadec56151a6c30782693a2 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Wed, 15 May 2024 01:41:13 -0400
Subject: Add upstream compatibility bits
---
hw/arm/virt.c | 1 +
hw/core/machine.c | 17 +++++++++++++++++
hw/i386/pc_piix.c | 2 ++
hw/i386/pc_q35.c | 2 ++
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/boards.h | 3 +++
6 files changed, 26 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 903c0f2e9f..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

View File

@ -0,0 +1,37 @@
From 492900c0b6a99f157249c2706c2f2ef5f67d20df Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:27:49 +0200
Subject: redhat: Add QEMU 9.1 compat handling to the s390x machine types
JIRA: https://issues.redhat.com/browse/RHEL-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 <thuth@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 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

View File

@ -0,0 +1,55 @@
From 1ceaf6413ec7cb19ea2b6147ec91c776c7c5df40 Mon Sep 17 00:00:00 2001
From: Thomas Huth <thuth@redhat.com>
Date: Mon, 26 Aug 2024 14:42:24 +0200
Subject: redhat: Add rhel9.6.0 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 <thuth@redhat.com>
---
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

View File

@ -0,0 +1,43 @@
From f35f400c9255be5fbb0158c6885a96ef23e7fb86 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
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 <sebott@redhat.com>
---
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

View File

@ -0,0 +1,27 @@
From 9c65a3e2e15c96b3b74d7c7846dbd60b13474370 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
Date: Thu, 5 Sep 2024 13:02:32 +0200
Subject: arm: ensure compatibility of virt-rhel9*
Signed-off-by: Sebastian Ott <sebott@redhat.com>
---
hw/arm/virt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 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

View File

@ -0,0 +1,41 @@
From 005be8f390c038ab9674103e1644dc1549c434a9 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
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 <sebott@redhat.com>
---
hw/arm/virt.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 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

View File

@ -0,0 +1,42 @@
From 826f14b90a0ad2427e4e80232c0fbaea80600650 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <sebott@redhat.com>
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 <sebott@redhat.com>
---
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

View File

@ -0,0 +1,90 @@
From d6a415e7a62ca1bc21f1833f4251f512b2072a93 Mon Sep 17 00:00:00 2001
From: Shaoqin Huang <shahuang@redhat.com>
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 <shahuang@redhat.com>
---
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

View File

@ -1,19 +0,0 @@
===================
qemu-kvm development
===================
qemu-kvm is maintained in a `source tree`_ rather than directly in dist-git.
This provides way to develope using regular source code structure and provides
way to generate SRPM and build using koji service. In addition, local build using
CentOS 9 Stream specific configuration.
Developers deliver all changes to source-git using merge request. Only maintainers
will be pushing changes sent to source-git to dist-git.
Each release in dist-git is tagged in the source repository so you can easily
check out the source tree for a build. The tags are in the format
name-version-release, but note release doesn't contain the dist tag since the
source can be built in different build roots (Fedora, CentOS, etc.)
.. _source tree: https://gitlab.com/redhat/centos-stream/src/qemu-kvm

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,65 +0,0 @@
From a9530c89225fce9e381929c4cd8e372068827acf Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 24 Jun 2024 10:52:49 +0200
Subject: [PATCH 089/100] i386/sev: Fallback to the default SEV device if none
provided in sev_get_capabilities()
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [89/91] 22318c20d7102815f754cec0efaf383e05ef79c1 (bonzini/rhel-qemu-kvm)
When management tools (e.g. libvirt) query QEMU capabilities,
they start QEMU with a minimalistic configuration and issue
various commands on monitor. One of the command issued is/might
be "query-sev-capabilities" to learn values like cbitpos or
reduced-phys-bits. But as of v9.0.0-1145-g16dcf200dc the monitor
command returns an error instead.
This creates a chicken-egg problem because in order to query
those aforementioned values QEMU needs to be started with a
'sev-guest' object. But to start QEMU with the values must be
known.
I think it's safe to assume that the default path ("/dev/sev")
provides the same data as user provided one. So fall back to it.
Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Link: https://lore.kernel.org/r/157f93712c23818be193ce785f648f0060b33dee.1719218926.git.mprivozn@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3fb24530b2bb1346a44e17becefc9865b40a2257)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 53b7f7315b..491fab74fd 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -585,13 +585,13 @@ static SevCapability *sev_get_capabilities(Error **errp)
}
sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
- if (!sev_common) {
- error_setg(errp, "SEV is not configured");
- return NULL;
+ if (sev_common) {
+ sev_device = object_property_get_str(OBJECT(sev_common), "sev-device",
+ &error_abort);
+ } else {
+ sev_device = g_strdup(DEFAULT_SEV_DEVICE);
}
- sev_device = object_property_get_str(OBJECT(sev_common), "sev-device",
- &error_abort);
fd = open(sev_device, O_RDWR);
if (fd < 0) {
error_setg_errno(errp, errno, "SEV: Failed to open %s",
--
2.39.3

View File

@ -1,48 +0,0 @@
From b672cdf8c10a530b5bcf6dd4489632891eb2c731 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 24 Jun 2024 10:52:48 +0200
Subject: [PATCH 088/100] i386/sev: Fix error message in sev_get_capabilities()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [88/91] ff8a8b27af02e565172ffe39d0571c234317713d (bonzini/rhel-qemu-kvm)
When a custom path is provided to sev-guest object and opening
the path fails an error message is reported. But the error
message still mentions DEFAULT_SEV_DEVICE ("/dev/sev") instead of
the custom path.
Fixes: 16dcf200dc951c1cde3e5b442457db5f690b8cf0
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/r/b4648905d399780063dc70851d3d6a3cd28719a5.1719218926.git.mprivozn@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e306ae87e0ef04bc7a5dec6db693f6ea09d64d45)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 37de80adc7..53b7f7315b 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -595,7 +595,7 @@ static SevCapability *sev_get_capabilities(Error **errp)
fd = open(sev_device, O_RDWR);
if (fd < 0) {
error_setg_errno(errp, errno, "SEV: Failed to open %s",
- DEFAULT_SEV_DEVICE);
+ sev_device);
g_free(sev_device);
return NULL;
}
--
2.39.3

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,134 +0,0 @@
From d009fa2cebebd1da80f4f2f5d0c4fffb87e02afc Mon Sep 17 00:00:00 2001
From: Dov Murik <dovmurik@linux.ibm.com>
Date: Thu, 30 May 2024 06:16:34 -0500
Subject: [PATCH 079/100] i386/sev: Reorder struct declarations
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <dovmurik@linux.ibm.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-23-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cc483bf911931f405dea682c74a3d8b9b6c54369)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,46 +0,0 @@
From 80c1d78e31b2567d1c610c8939b75d159ff6ea27 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [55/91] 1e15fc2458687e564af9fa5022c29e79ddc8edfd (bonzini/rhel-qemu-kvm)
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-2-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 18c453409a3a84cf7b2c764c5a03fb429a73bbeb)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,40 +0,0 @@
From 88da6d01b1de2b92adb5c47c6d482876a054705f Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <pankaj.gupta@amd.com>
Message-ID: <20240607183611.1111100-4-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cd7093a7a168a823d07671348996f049d45e8f67)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,47 +0,0 @@
From c7649ac1b958dc48de50f32b1ad80d84b17945a8 Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <michael.roth@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-18-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3d44fdff60ea66fbd7a33f5d32b50843cd80f48a)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,268 +0,0 @@
From 5540bb5ca052531563df1ade68995e268ae65224 Mon Sep 17 00:00:00 2001
From: Xiaoyao Li <xiaoyao.li@intel.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <xiaoyao.li@intel.com>
Message-Id: <20240229060038.606591-1-xiaoyao.li@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 637c95b37b106c2eeba313e0abb38ec12e918a59)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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 <brijesh.singh@amd.com>
- *
- * 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

View File

@ -1,240 +0,0 @@
From a870e7c31d9605baea4741d82521612b6164c99b Mon Sep 17 00:00:00 2001
From: Michael Roth <michael.roth@amd.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <michael.roth@amd.com>
Co-developed-by:Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-15-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 59d3740cb4ac0f010ce35877572904f6297284b4)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,51 +0,0 @@
From 98057e3adafa052b21a4fe5ef22835d30df3e644 Mon Sep 17 00:00:00 2001
From: Pankaj Gupta <pankaj.gupta@amd.com>
Date: Fri, 7 Jun 2024 13:36:09 -0500
Subject: [PATCH 084/100] i386/sev: fix unreachable code coverity issue
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <pankaj.gupta@amd.com>
Message-ID: <20240607183611.1111100-2-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c94eb5db8e409c932da9eb187e68d4cdc14acc5b)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/sev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 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

View File

@ -1,81 +0,0 @@
From deae6c3b57c3919946a5ce1613e667a3240cf158 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Mon, 15 Apr 2024 12:45:09 +0200
Subject: [PATCH 001/100] introduce pc_rhel_9_5_compat
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [1/91] cfd402fa5080eddba7c954e81ed79f9a1dd654cf (bonzini/rhel-qemu-kvm)
Allow undoing backported changes that impact guest ABI.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

View File

@ -1,61 +0,0 @@
From 16c2e9e339a4c83055fd39e032fa16a0e732ed17 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
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 <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-35611
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [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 <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
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

View File

@ -1,64 +0,0 @@
From d70daa2eb5b670513ccd36c0baa5b36ec8cef666 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
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 <hczenczek@redhat.com>
RH-MergeRequest: 1: CVE 2024-4467 (PRDSC)
RH-Jira: RHEL-35611
RH-CVE: CVE-2024-4467
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Commit: [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 <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Upstream: N/A, embargoed
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
---
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

View File

@ -1,275 +0,0 @@
From 88adaeaecb1d7753aa8ac3da40f617d93eaf8bdc Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
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 <eblake@redhat.com>
RH-MergeRequest: 244: qio: Inherit follow_coroutine_ctx across TLS
RH-Jira: RHEL-33440
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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" <rjones@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-ID: <20240531180639.1392905-6-eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit a73c99378022ebb785481e84cfe1e81097546268)
Jira: https://issues.redhat.com/browse/RHEL-33440
Signed-off-by: Eric Blake <eblake@redhat.com>
---
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 <http://www.gnu.org/licenses/>.
+#
+
+# 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

View File

@ -1,153 +0,0 @@
From 120157257ac239050779fdddc9abb56bd39958b3 Mon Sep 17 00:00:00 2001
From: Chao Peng <chao.p.peng@linux.intel.com>
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 <pbonzini@redhat.com>
RH-MergeRequest: 245: SEV-SNP support
RH-Jira: RHEL-39544
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Bandan Das <bdas@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Commit: [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 <chao.p.peng@linux.intel.com>
Co-developed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Message-ID: <20240320083945.991426-10-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ce5a983233b4ca94ced88c9581014346509b5c71)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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

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