* Mon Apr 14 2025 Jon Maloy <jmaloy@redhat.com> - 9.1.0-18
- kvm-virtio-kconfig-memory-devices-are-PCI-only.patch [RHEL-72977] - kvm-hw-s390-ccw-device-Convert-to-three-phase-reset.patch [RHEL-72977] - kvm-hw-s390-virtio-ccw-Convert-to-three-phase-reset.patch [RHEL-72977] - kvm-target-s390-Convert-CPU-to-Resettable-interface.patch [RHEL-72977] - kvm-reset-Use-ResetType-for-qemu_devices_reset-and-Machi.patch [RHEL-72977] - kvm-reset-Add-RESET_TYPE_WAKEUP.patch [RHEL-72977] - kvm-virtio-mem-Use-new-Resettable-framework-instead-of-L.patch [RHEL-72977] - kvm-virtio-mem-Add-support-for-suspend-wake-up-with-plug.patch [RHEL-72977] - kvm-virtio-mem-unplug-memory-only-during-system-resets-n.patch [RHEL-72977] - kvm-s390x-s390-virtio-ccw-don-t-crash-on-weird-RAM-sizes.patch [RHEL-72977] - kvm-s390x-s390-virtio-hcall-remove-hypercall-registratio.patch [RHEL-72977] - kvm-s390x-s390-virtio-hcall-prepare-for-more-diag500-hyp.patch [RHEL-72977] - kvm-s390x-rename-s390-virtio-hcall-to-s390-hypercall.patch [RHEL-72977] - kvm-s390x-s390-virtio-ccw-move-setting-the-maximum-guest.patch [RHEL-72977] - kvm-s390x-introduce-s390_get_memory_limit.patch [RHEL-72977] - kvm-s390x-s390-hypercall-introduce-DIAG500-STORAGE_LIMIT.patch [RHEL-72977] - kvm-s390x-s390-stattrib-kvm-prepare-for-memory-devices-a.patch [RHEL-72977] - kvm-s390x-s390-skeys-prepare-for-memory-devices.patch [RHEL-72977] - kvm-s390x-s390-virtio-ccw-prepare-for-memory-devices.patch [RHEL-72977] - kvm-s390x-pv-prepare-for-memory-devices.patch [RHEL-72977] - kvm-s390x-remember-the-maximum-page-size.patch [RHEL-72977] - kvm-s390x-virtio-ccw-add-support-for-virtio-based-memory.patch [RHEL-72977] - kvm-s390x-virtio-mem-support.patch [RHEL-72977] - kvm-hw-virtio-Also-include-md-stubs-in-case-CONFIG_VIRTI.patch [RHEL-72977] - kvm-virtio-mem-don-t-warn-about-THP-sizes-on-a-kernel-wi.patch [RHEL-72977] - kvm-redhat-Enable-virtio-mem-on-s390x.patch [RHEL-72977] - Resolves: RHEL-72977 ([IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part)
This commit is contained in:
parent
5b6159d787
commit
eace179c9a
63
kvm-hw-s390-ccw-device-Convert-to-three-phase-reset.patch
Normal file
63
kvm-hw-s390-ccw-device-Convert-to-three-phase-reset.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 5126609c0714c66a0ec41328017e7e8388c78bf4 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Fri, 13 Sep 2024 15:31:43 +0100
|
||||
Subject: [PATCH 02/26] hw/s390/ccw-device: Convert to three-phase reset
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [2/26] 58f6fc2e65a101e069feac399859464d31e43045 (thuth/qemu-kvm-cs)
|
||||
|
||||
Convert the TYPE_CCW_DEVICE to three-phase reset. This is a
|
||||
device class which is subclassed, so it needs to be three-phase
|
||||
before we can convert the subclass.
|
||||
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-id: 20240830145812.1967042-2-peter.maydell@linaro.org
|
||||
(cherry picked from commit 6a0e10b76b68e2f412746a1d5ed7d6efee804864)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/ccw-device.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
|
||||
index d7bb364579..30f2fb486f 100644
|
||||
--- a/hw/s390x/ccw-device.c
|
||||
+++ b/hw/s390x/ccw-device.c
|
||||
@@ -88,9 +88,9 @@ static Property ccw_device_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
-static void ccw_device_reset(DeviceState *d)
|
||||
+static void ccw_device_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
- CcwDevice *ccw_dev = CCW_DEVICE(d);
|
||||
+ CcwDevice *ccw_dev = CCW_DEVICE(obj);
|
||||
|
||||
css_reset_sch(ccw_dev->sch);
|
||||
}
|
||||
@@ -99,11 +99,12 @@ static void ccw_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCWDeviceClass *k = CCW_DEVICE_CLASS(klass);
|
||||
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
k->realize = ccw_device_realize;
|
||||
k->refill_ids = ccw_device_refill_ids;
|
||||
device_class_set_props(dc, ccw_device_properties);
|
||||
- dc->reset = ccw_device_reset;
|
||||
+ rc->phases.hold = ccw_device_reset_hold;
|
||||
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
|
||||
}
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
92
kvm-hw-s390-virtio-ccw-Convert-to-three-phase-reset.patch
Normal file
92
kvm-hw-s390-virtio-ccw-Convert-to-three-phase-reset.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From 7cbf9be09907407a64d739a2d0862af2ad08eaf5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Fri, 13 Sep 2024 15:31:43 +0100
|
||||
Subject: [PATCH 03/26] hw/s390/virtio-ccw: Convert to three-phase reset
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [3/26] e06ee194fa289a387433b905eb0999a048681a92 (thuth/qemu-kvm-cs)
|
||||
|
||||
Convert the virtio-ccw code to three-phase reset. This allows us to
|
||||
remove a call to device_class_set_parent_reset(), replacing it with
|
||||
the three-phase equivalent resettable_class_set_parent_phases().
|
||||
Removing all the device_class_set_parent_reset() uses will allow us
|
||||
to remove some of the glue code that interworks between three-phase
|
||||
and legacy reset.
|
||||
|
||||
This is a simple conversion, with no behavioural changes.
|
||||
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
|
||||
Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-id: 20240830145812.1967042-3-peter.maydell@linaro.org
|
||||
(cherry picked from commit 6affa00d6ebebf24485667fe146470b0d6feb90d)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/virtio-ccw.c | 13 ++++++++-----
|
||||
hw/s390x/virtio-ccw.h | 2 +-
|
||||
2 files changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
|
||||
index b4676909dd..96747318d2 100644
|
||||
--- a/hw/s390x/virtio-ccw.c
|
||||
+++ b/hw/s390x/virtio-ccw.c
|
||||
@@ -913,14 +913,15 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
|
||||
}
|
||||
}
|
||||
|
||||
-static void virtio_ccw_reset(DeviceState *d)
|
||||
+static void virtio_ccw_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
- VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||
+ VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(obj);
|
||||
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
|
||||
|
||||
virtio_ccw_reset_virtio(dev);
|
||||
- if (vdc->parent_reset) {
|
||||
- vdc->parent_reset(d);
|
||||
+
|
||||
+ if (vdc->parent_phases.hold) {
|
||||
+ vdc->parent_phases.hold(obj, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,11 +1234,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
|
||||
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
|
||||
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
k->unplug = virtio_ccw_busdev_unplug;
|
||||
dc->realize = virtio_ccw_busdev_realize;
|
||||
dc->unrealize = virtio_ccw_busdev_unrealize;
|
||||
- device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset);
|
||||
+ resettable_class_set_parent_phases(rc, NULL, virtio_ccw_reset_hold, NULL,
|
||||
+ &vdc->parent_phases);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_ccw_device_info = {
|
||||
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
|
||||
index fac186c8f6..c7a830a194 100644
|
||||
--- a/hw/s390x/virtio-ccw.h
|
||||
+++ b/hw/s390x/virtio-ccw.h
|
||||
@@ -57,7 +57,7 @@ struct VirtIOCCWDeviceClass {
|
||||
CCWDeviceClass parent_class;
|
||||
void (*realize)(VirtioCcwDevice *dev, Error **errp);
|
||||
void (*unrealize)(VirtioCcwDevice *dev);
|
||||
- void (*parent_reset)(DeviceState *dev);
|
||||
+ ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||
--
|
||||
2.48.1
|
||||
|
@ -0,0 +1,59 @@
|
||||
From afa3a488f3ca52a5455987e4cd643882c4b15d8a Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Thu, 13 Mar 2025 07:35:22 +0100
|
||||
Subject: [PATCH 24/26] hw/virtio: Also include md stubs in case
|
||||
CONFIG_VIRTIO_PCI is not set
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [24/26] ae6307b26d01d2a317f7e5d1d3b3a16b6d5f56de (thuth/qemu-kvm-cs)
|
||||
|
||||
For the s390x target, it's possible to build the QEMU binary without
|
||||
CONFIG_VIRTIO_PCI and only have the virtio-mem device via the ccw
|
||||
transport. In that case, QEMU currently fails to link correctly:
|
||||
|
||||
/usr/bin/ld: libqemu-s390x-softmmu.a.p/hw_s390x_s390-virtio-ccw.c.o: in function `s390_machine_device_pre_plug':
|
||||
../hw/s390x/s390-virtio-ccw.c:579:(.text+0x1e96): undefined reference to `virtio_md_pci_pre_plug'
|
||||
/usr/bin/ld: libqemu-s390x-softmmu.a.p/hw_s390x_s390-virtio-ccw.c.o: in function `s390_machine_device_plug':
|
||||
../hw/s390x/s390-virtio-ccw.c:608:(.text+0x21a4): undefined reference to `virtio_md_pci_plug'
|
||||
/usr/bin/ld: libqemu-s390x-softmmu.a.p/hw_s390x_s390-virtio-ccw.c.o: in function `s390_machine_device_unplug_request':
|
||||
../hw/s390x/s390-virtio-ccw.c:622:(.text+0x2334): undefined reference to `virtio_md_pci_unplug_request'
|
||||
/usr/bin/ld: libqemu-s390x-softmmu.a.p/hw_s390x_s390-virtio-ccw.c.o: in function `s390_machine_device_unplug':
|
||||
../hw/s390x/s390-virtio-ccw.c:633:(.text+0x2436): undefined reference to `virtio_md_pci_unplug'
|
||||
clang: error: linker command failed with exit code 1 (use -v to see invocation)
|
||||
|
||||
We also need to include the stubs when CONFIG_VIRTIO_PCI is missing.
|
||||
|
||||
Fixes: aa910c20ec5 ("s390x: virtio-mem support")
|
||||
Message-ID: <20250313063522.1348288-1-thuth@redhat.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
(cherry picked from commit c1a6bff276ca52ffde472532d92bb5bb122dab3f)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/meson.build | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
|
||||
index c38bdd6fa4..e2f9c75625 100644
|
||||
--- a/hw/virtio/meson.build
|
||||
+++ b/hw/virtio/meson.build
|
||||
@@ -89,7 +89,8 @@ specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
|
||||
system_ss.add_all(when: 'CONFIG_VIRTIO', if_true: system_virtio_ss)
|
||||
system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c'))
|
||||
system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c'))
|
||||
-system_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio-md-stubs.c'))
|
||||
+system_ss.add(when: ['CONFIG_VIRTIO_MD', 'CONFIG_VIRTIO_PCI'],
|
||||
+ if_false: files('virtio-md-stubs.c'))
|
||||
|
||||
system_ss.add(files('virtio-hmp-cmds.c'))
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
36
kvm-redhat-Enable-virtio-mem-on-s390x.patch
Normal file
36
kvm-redhat-Enable-virtio-mem-on-s390x.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 7300a435547b7e999227648fd1451db00e9c4867 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Mon, 24 Mar 2025 18:09:26 +0100
|
||||
Subject: [PATCH 26/26] redhat: Enable virtio-mem on s390x
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [26/26] 076b44c8f0262e903c5e17eda676614aec6f5c98 (thuth/qemu-kvm-cs)
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-72977
|
||||
|
||||
Enable virtio-mem on s390x now, too.
|
||||
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
configs/devices/s390x-softmmu/s390x-rh-devices.mak | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/configs/devices/s390x-softmmu/s390x-rh-devices.mak b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
index 24cf6dbd03..834281d872 100644
|
||||
--- a/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
+++ b/configs/devices/s390x-softmmu/s390x-rh-devices.mak
|
||||
@@ -12,6 +12,7 @@ CONFIG_VFIO_CCW=y
|
||||
CONFIG_VFIO_PCI=y
|
||||
CONFIG_VHOST_USER=y
|
||||
CONFIG_VIRTIO_CCW=y
|
||||
+CONFIG_VIRTIO_MEM=y
|
||||
CONFIG_WDT_DIAG288=y
|
||||
CONFIG_VHOST_VSOCK=y
|
||||
CONFIG_VHOST_USER_VSOCK=y
|
||||
--
|
||||
2.48.1
|
||||
|
94
kvm-reset-Add-RESET_TYPE_WAKEUP.patch
Normal file
94
kvm-reset-Add-RESET_TYPE_WAKEUP.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From 2de79d978c2cd29ad686dd91e74a86dbf2121f1f Mon Sep 17 00:00:00 2001
|
||||
From: Juraj Marcin <jmarcin@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 12:37:13 +0200
|
||||
Subject: [PATCH 06/26] reset: Add RESET_TYPE_WAKEUP
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [6/26] 6169fe25bfa5715340c180ee8711d0ad61832106 (thuth/qemu-kvm-cs)
|
||||
|
||||
Some devices need to distinguish cold start reset from waking up from a
|
||||
suspended state. This patch adds new value to the enum, and updates the
|
||||
i386 wakeup method to use this new reset type.
|
||||
|
||||
Message-ID: <20240904103722.946194-3-jmarcin@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 759cbb4ee971da13ddfa8ad73befc2351d542044)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
docs/devel/reset.rst | 12 +++++++++++-
|
||||
hw/i386/pc.c | 2 +-
|
||||
include/hw/resettable.h | 2 ++
|
||||
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
|
||||
index d2799eba7a..44bd51b42e 100644
|
||||
--- a/docs/devel/reset.rst
|
||||
+++ b/docs/devel/reset.rst
|
||||
@@ -44,6 +44,17 @@ The Resettable interface handles reset types with an enum ``ResetType``:
|
||||
value on each cold reset, such as RNG seed information, and which they
|
||||
must not reinitialize on a snapshot-load reset.
|
||||
|
||||
+``RESET_TYPE_WAKEUP``
|
||||
+ If the machine supports waking up from a suspended state and needs to reset
|
||||
+ its devices during wake-up (from the ``MachineClass::wakeup()`` method), this
|
||||
+ reset type should be used for such a request. Devices can utilize this reset
|
||||
+ type to differentiate the reset requested during machine wake-up from other
|
||||
+ reset requests. For example, RAM content must not be lost during wake-up, and
|
||||
+ memory devices like virtio-mem that provide additional RAM must not reset
|
||||
+ such state during wake-ups, but might do so during cold resets. However, this
|
||||
+ reset type should not be used for wake-up detection, as not every machine
|
||||
+ type issues a device reset request during wake-up.
|
||||
+
|
||||
``RESET_TYPE_S390_CPU_NORMAL``
|
||||
This is only used for S390 CPU objects; it clears interrupts, stops
|
||||
processing, and clears the TLB, but does not touch register contents.
|
||||
@@ -53,7 +64,6 @@ The Resettable interface handles reset types with an enum ``ResetType``:
|
||||
``RESET_TYPE_S390_CPU_NORMAL`` does and also clears the PSW, prefix,
|
||||
FPC, timer and control registers. It does not touch gprs, fprs or acrs.
|
||||
|
||||
-
|
||||
Devices which implement reset methods must treat any unknown ``ResetType``
|
||||
as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of
|
||||
existing code we need to change if we add more types in future.
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index fedcf2a65f..fa9f16cbaf 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -1889,7 +1889,7 @@ static void pc_machine_reset(MachineState *machine, ResetType type)
|
||||
static void pc_machine_wakeup(MachineState *machine)
|
||||
{
|
||||
cpu_synchronize_all_states();
|
||||
- pc_machine_reset(machine, RESET_TYPE_COLD);
|
||||
+ pc_machine_reset(machine, RESET_TYPE_WAKEUP);
|
||||
cpu_synchronize_all_post_reset();
|
||||
}
|
||||
|
||||
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
|
||||
index 83b561fc83..cf37cd5ead 100644
|
||||
--- a/include/hw/resettable.h
|
||||
+++ b/include/hw/resettable.h
|
||||
@@ -29,6 +29,7 @@ typedef struct ResettableState ResettableState;
|
||||
* Types of reset.
|
||||
*
|
||||
* + Cold: reset resulting from a power cycle of the object.
|
||||
+ * + Wakeup: reset resulting from a wake-up from a suspended state.
|
||||
*
|
||||
* TODO: Support has to be added to handle more types. In particular,
|
||||
* ResettableState structure needs to be expanded.
|
||||
@@ -36,6 +37,7 @@ typedef struct ResettableState ResettableState;
|
||||
typedef enum ResetType {
|
||||
RESET_TYPE_COLD,
|
||||
RESET_TYPE_SNAPSHOT_LOAD,
|
||||
+ RESET_TYPE_WAKEUP,
|
||||
RESET_TYPE_S390_CPU_INITIAL,
|
||||
RESET_TYPE_S390_CPU_NORMAL,
|
||||
} ResetType;
|
||||
--
|
||||
2.48.1
|
||||
|
360
kvm-reset-Use-ResetType-for-qemu_devices_reset-and-Machi.patch
Normal file
360
kvm-reset-Use-ResetType-for-qemu_devices_reset-and-Machi.patch
Normal file
@ -0,0 +1,360 @@
|
||||
From 8d48193b5a661f31c1c1db068d241b31ae379339 Mon Sep 17 00:00:00 2001
|
||||
From: Juraj Marcin <jmarcin@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 12:37:12 +0200
|
||||
Subject: [PATCH 05/26] reset: Use ResetType for qemu_devices_reset() and
|
||||
MachineClass::reset()
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [5/26] ea1324b27885d979bcc54cc355dbdf940686776c (thuth/qemu-kvm-cs)
|
||||
|
||||
Currently, both qemu_devices_reset() and MachineClass::reset() use
|
||||
ShutdownCause for the reason of the reset. However, the Resettable
|
||||
interface uses ResetState, so ShutdownCause needs to be translated to
|
||||
ResetType somewhere. Translating it qemu_devices_reset() makes adding
|
||||
new reset types harder, as they cannot always be matched to a single
|
||||
ShutdownCause here, and devices may need to check the ResetType to
|
||||
determine what to reset and if to reset at all.
|
||||
|
||||
This patch moves this translation up in the call stack to
|
||||
qemu_system_reset() and updates all MachineClass children to use the
|
||||
ResetType instead.
|
||||
|
||||
Message-ID: <20240904103722.946194-2-jmarcin@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 1b063fe2df002052cc2d10799764979b8c583480)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/arm/aspeed.c | 4 ++--
|
||||
hw/arm/mps2-tz.c | 4 ++--
|
||||
hw/core/reset.c | 5 +----
|
||||
hw/hppa/machine.c | 4 ++--
|
||||
hw/i386/microvm.c | 4 ++--
|
||||
hw/i386/pc.c | 6 +++---
|
||||
hw/ppc/pegasos2.c | 4 ++--
|
||||
hw/ppc/pnv.c | 4 ++--
|
||||
hw/ppc/spapr.c | 6 +++---
|
||||
hw/s390x/s390-virtio-ccw.c | 4 ++--
|
||||
include/hw/boards.h | 3 ++-
|
||||
include/sysemu/reset.h | 5 +++--
|
||||
system/runstate.c | 13 +++++++++++--
|
||||
13 files changed, 37 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
|
||||
index fd5603f7aa..cbca7685da 100644
|
||||
--- a/hw/arm/aspeed.c
|
||||
+++ b/hw/arm/aspeed.c
|
||||
@@ -1529,12 +1529,12 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
|
||||
aspeed_machine_class_init_cpus_defaults(mc);
|
||||
}
|
||||
|
||||
-static void fby35_reset(MachineState *state, ShutdownCause reason)
|
||||
+static void fby35_reset(MachineState *state, ResetType type)
|
||||
{
|
||||
AspeedMachineState *bmc = ASPEED_MACHINE(state);
|
||||
AspeedGPIOState *gpio = &bmc->soc->gpio;
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
/* Board ID: 7 (Class-1, 4 slots) */
|
||||
object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
|
||||
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
|
||||
index aec57c0d68..8edf57a66d 100644
|
||||
--- a/hw/arm/mps2-tz.c
|
||||
+++ b/hw/arm/mps2-tz.c
|
||||
@@ -1254,7 +1254,7 @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
-static void mps2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void mps2_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
|
||||
|
||||
@@ -1264,7 +1264,7 @@ static void mps2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
* reset see the correct mapping.
|
||||
*/
|
||||
remap_memory(mms, mms->remap);
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
}
|
||||
|
||||
static void mps2tz_class_init(ObjectClass *oc, void *data)
|
||||
diff --git a/hw/core/reset.c b/hw/core/reset.c
|
||||
index 58dfc8db3d..14a2639fbf 100644
|
||||
--- a/hw/core/reset.c
|
||||
+++ b/hw/core/reset.c
|
||||
@@ -170,11 +170,8 @@ void qemu_unregister_resettable(Object *obj)
|
||||
resettable_container_remove(get_root_reset_container(), obj);
|
||||
}
|
||||
|
||||
-void qemu_devices_reset(ShutdownCause reason)
|
||||
+void qemu_devices_reset(ResetType type)
|
||||
{
|
||||
- ResetType type = (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD) ?
|
||||
- RESET_TYPE_SNAPSHOT_LOAD : RESET_TYPE_COLD;
|
||||
-
|
||||
/* Reset the simulation */
|
||||
resettable_reset(OBJECT(get_root_reset_container()), type);
|
||||
}
|
||||
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
|
||||
index 5d0a8739de..8259fe2e38 100644
|
||||
--- a/hw/hppa/machine.c
|
||||
+++ b/hw/hppa/machine.c
|
||||
@@ -642,12 +642,12 @@ static void machine_HP_C3700_init(MachineState *machine)
|
||||
machine_HP_common_init_tail(machine, pci_bus, translate);
|
||||
}
|
||||
|
||||
-static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
|
||||
+static void hppa_machine_reset(MachineState *ms, ResetType type)
|
||||
{
|
||||
unsigned int smp_cpus = ms->smp.cpus;
|
||||
int i;
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
/* Start all CPUs at the firmware entry point.
|
||||
* Monarch CPU will initialize firmware, secondary CPUs
|
||||
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
|
||||
index 40edcee7af..8ae4dff7f2 100644
|
||||
--- a/hw/i386/microvm.c
|
||||
+++ b/hw/i386/microvm.c
|
||||
@@ -462,7 +462,7 @@ static void microvm_machine_state_init(MachineState *machine)
|
||||
microvm_devices_init(mms);
|
||||
}
|
||||
|
||||
-static void microvm_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void microvm_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
|
||||
CPUState *cs;
|
||||
@@ -475,7 +475,7 @@ static void microvm_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
mms->kernel_cmdline_fixed = true;
|
||||
}
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
CPU_FOREACH(cs) {
|
||||
cpu = X86_CPU(cs);
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index fa0e42d072..fedcf2a65f 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -1869,12 +1869,12 @@ static void pc_machine_initfn(Object *obj)
|
||||
qemu_add_machine_init_done_notifier(&pcms->machine_done);
|
||||
}
|
||||
|
||||
-static void pc_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void pc_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
CPUState *cs;
|
||||
X86CPU *cpu;
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
/* Reset APIC after devices have been reset to cancel
|
||||
* any changes that qemu_devices_reset() might have done.
|
||||
@@ -1889,7 +1889,7 @@ static void pc_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
static void pc_machine_wakeup(MachineState *machine)
|
||||
{
|
||||
cpu_synchronize_all_states();
|
||||
- pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE);
|
||||
+ pc_machine_reset(machine, RESET_TYPE_COLD);
|
||||
cpu_synchronize_all_post_reset();
|
||||
}
|
||||
|
||||
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
|
||||
index 9b0a6b70ab..8ff4a00c34 100644
|
||||
--- a/hw/ppc/pegasos2.c
|
||||
+++ b/hw/ppc/pegasos2.c
|
||||
@@ -291,14 +291,14 @@ static void pegasos2_superio_write(uint8_t addr, uint8_t val)
|
||||
cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
|
||||
}
|
||||
|
||||
-static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void pegasos2_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
|
||||
void *fdt;
|
||||
uint64_t d[2];
|
||||
int sz;
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
if (!pm->vof) {
|
||||
return; /* Firmware should set up machine so nothing to do */
|
||||
}
|
||||
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
|
||||
index 3526852685..988fd55d88 100644
|
||||
--- a/hw/ppc/pnv.c
|
||||
+++ b/hw/ppc/pnv.c
|
||||
@@ -709,13 +709,13 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
-static void pnv_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void pnv_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
PnvMachineState *pnv = PNV_MACHINE(machine);
|
||||
IPMIBmc *bmc;
|
||||
void *fdt;
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
/*
|
||||
* The machine should provide by default an internal BMC simulator.
|
||||
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
|
||||
index 29e66f1b3f..11c953669a 100644
|
||||
--- a/hw/ppc/spapr.c
|
||||
+++ b/hw/ppc/spapr.c
|
||||
@@ -1725,7 +1725,7 @@ void spapr_check_mmu_mode(bool guest_radix)
|
||||
}
|
||||
}
|
||||
|
||||
-static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void spapr_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(machine);
|
||||
PowerPCCPU *first_ppc_cpu;
|
||||
@@ -1733,7 +1733,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
void *fdt;
|
||||
int rc;
|
||||
|
||||
- if (reason != SHUTDOWN_CAUSE_SNAPSHOT_LOAD) {
|
||||
+ if (type != RESET_TYPE_SNAPSHOT_LOAD) {
|
||||
/*
|
||||
* Record-replay snapshot load must not consume random, this was
|
||||
* already replayed from initial machine reset.
|
||||
@@ -1769,7 +1769,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
spapr_setup_hpt(spapr);
|
||||
}
|
||||
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
|
||||
spapr_ovec_cleanup(spapr->ov5_cas);
|
||||
spapr->ov5_cas = spapr_ovec_new();
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index ef2a9687c7..94cad1705b 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -434,7 +434,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms)
|
||||
s390_pv_prep_reset();
|
||||
}
|
||||
|
||||
-static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
+static void s390_machine_reset(MachineState *machine, ResetType type)
|
||||
{
|
||||
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
|
||||
enum s390_reset reset_type;
|
||||
@@ -466,7 +466,7 @@ static void s390_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||
* Device reset includes CPU clear resets so this has to be
|
||||
* done AFTER the unprotect call above.
|
||||
*/
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
s390_crypto_reset();
|
||||
|
||||
/* configure and start the ipl CPU only */
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index ffefc0a625..fe011b1e86 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
#include "hw/core/cpu.h"
|
||||
+#include "hw/resettable.h"
|
||||
|
||||
#define TYPE_MACHINE_SUFFIX "-machine"
|
||||
|
||||
@@ -253,7 +254,7 @@ struct MachineClass {
|
||||
const char *deprecation_reason;
|
||||
|
||||
void (*init)(MachineState *state);
|
||||
- void (*reset)(MachineState *state, ShutdownCause reason);
|
||||
+ void (*reset)(MachineState *state, ResetType type);
|
||||
void (*wakeup)(MachineState *state);
|
||||
int (*kvm_type)(MachineState *machine, const char *arg);
|
||||
|
||||
diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h
|
||||
index ae436044a9..0e297c0e02 100644
|
||||
--- a/include/sysemu/reset.h
|
||||
+++ b/include/sysemu/reset.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#ifndef QEMU_SYSEMU_RESET_H
|
||||
#define QEMU_SYSEMU_RESET_H
|
||||
|
||||
+#include "hw/resettable.h"
|
||||
#include "qapi/qapi-events-run-state.h"
|
||||
|
||||
typedef void QEMUResetHandler(void *opaque);
|
||||
@@ -110,7 +111,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
||||
|
||||
/**
|
||||
* qemu_devices_reset: Perform a complete system reset
|
||||
- * @reason: reason for the reset
|
||||
+ * @reason: type of the reset
|
||||
*
|
||||
* This function performs the low-level work needed to do a complete reset
|
||||
* of the system (calling all the callbacks registered with
|
||||
@@ -121,6 +122,6 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
|
||||
* If you want to trigger a system reset from, for instance, a device
|
||||
* model, don't use this function. Use qemu_system_reset_request().
|
||||
*/
|
||||
-void qemu_devices_reset(ShutdownCause reason);
|
||||
+void qemu_devices_reset(ResetType type);
|
||||
|
||||
#endif
|
||||
diff --git a/system/runstate.c b/system/runstate.c
|
||||
index a0e2a5fd22..c2c9afa905 100644
|
||||
--- a/system/runstate.c
|
||||
+++ b/system/runstate.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "exec/cpu-common.h"
|
||||
#include "gdbstub/syscalls.h"
|
||||
#include "hw/boards.h"
|
||||
+#include "hw/resettable.h"
|
||||
#include "migration/misc.h"
|
||||
#include "migration/postcopy-ram.h"
|
||||
#include "monitor/monitor.h"
|
||||
@@ -507,15 +508,23 @@ static int qemu_debug_requested(void)
|
||||
void qemu_system_reset(ShutdownCause reason)
|
||||
{
|
||||
MachineClass *mc;
|
||||
+ ResetType type;
|
||||
|
||||
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
|
||||
|
||||
cpu_synchronize_all_states();
|
||||
|
||||
+ switch (reason) {
|
||||
+ case SHUTDOWN_CAUSE_SNAPSHOT_LOAD:
|
||||
+ type = RESET_TYPE_SNAPSHOT_LOAD;
|
||||
+ break;
|
||||
+ default:
|
||||
+ type = RESET_TYPE_COLD;
|
||||
+ }
|
||||
if (mc && mc->reset) {
|
||||
- mc->reset(current_machine, reason);
|
||||
+ mc->reset(current_machine, type);
|
||||
} else {
|
||||
- qemu_devices_reset(reason);
|
||||
+ qemu_devices_reset(type);
|
||||
}
|
||||
switch (reason) {
|
||||
case SHUTDOWN_CAUSE_NONE:
|
||||
--
|
||||
2.48.1
|
||||
|
144
kvm-s390x-introduce-s390_get_memory_limit.patch
Normal file
144
kvm-s390x-introduce-s390_get_memory_limit.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 1dd38383832fc27f2980f33bb5e10ec1af7e3fc3 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:07 +0100
|
||||
Subject: [PATCH 15/26] s390x: introduce s390_get_memory_limit()
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [15/26] 5ae6a624a6541283cb15e90ebeb8fef3940c823b (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's add s390_get_memory_limit(), to query what has been successfully
|
||||
set via s390_set_memory_limit(). Allow setting the limit only once.
|
||||
|
||||
We'll remember the limit in the machine state. Move
|
||||
s390_set_memory_limit() to machine code, merging it into
|
||||
set_memory_limit(), because this really is a machine property.
|
||||
|
||||
Message-ID: <20241219144115.2820241-7-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 27221b69a3ea49339a1f82b9622126f3928e0915)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 17 ++++++++++++-----
|
||||
include/hw/s390x/s390-virtio-ccw.h | 8 ++++++++
|
||||
target/s390x/cpu-sysemu.c | 8 --------
|
||||
target/s390x/cpu.h | 1 -
|
||||
4 files changed, 20 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 248ac28d20..f5f147eb92 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "migration/blocker.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/s390x/cpu-topology.h"
|
||||
+#include "kvm/kvm_s390x.h"
|
||||
#include CONFIG_DEVICES
|
||||
|
||||
static Error *pv_mig_blocker;
|
||||
@@ -121,12 +122,16 @@ static void subsystem_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static void set_memory_limit(uint64_t new_limit)
|
||||
+static void s390_set_memory_limit(S390CcwMachineState *s390ms,
|
||||
+ uint64_t new_limit)
|
||||
{
|
||||
- uint64_t hw_limit;
|
||||
- int ret;
|
||||
+ uint64_t hw_limit = 0;
|
||||
+ int ret = 0;
|
||||
|
||||
- ret = s390_set_memory_limit(new_limit, &hw_limit);
|
||||
+ assert(!s390ms->memory_limit && new_limit);
|
||||
+ if (kvm_enabled()) {
|
||||
+ ret = kvm_s390_set_mem_limit(new_limit, &hw_limit);
|
||||
+ }
|
||||
if (ret == -E2BIG) {
|
||||
error_report("host supports a maximum of %" PRIu64 " GB",
|
||||
hw_limit / GiB);
|
||||
@@ -135,10 +140,12 @@ static void set_memory_limit(uint64_t new_limit)
|
||||
error_report("setting the guest size failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
+ s390ms->memory_limit = new_limit;
|
||||
}
|
||||
|
||||
static void s390_memory_init(MachineState *machine)
|
||||
{
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(machine);
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = machine->ram;
|
||||
uint64_t ram_size = memory_region_size(ram);
|
||||
@@ -154,7 +161,7 @@ static void s390_memory_init(MachineState *machine)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
- set_memory_limit(ram_size);
|
||||
+ s390_set_memory_limit(s390ms, ram_size);
|
||||
|
||||
/* Map the initial memory. Must happen after setting the memory limit. */
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
|
||||
index 996864a34e..de04336c5a 100644
|
||||
--- a/include/hw/s390x/s390-virtio-ccw.h
|
||||
+++ b/include/hw/s390x/s390-virtio-ccw.h
|
||||
@@ -29,10 +29,18 @@ struct S390CcwMachineState {
|
||||
bool dea_key_wrap;
|
||||
bool pv;
|
||||
uint8_t loadparm[8];
|
||||
+ uint64_t memory_limit;
|
||||
|
||||
SCLPDevice *sclp;
|
||||
};
|
||||
|
||||
+static inline uint64_t s390_get_memory_limit(S390CcwMachineState *s390ms)
|
||||
+{
|
||||
+ /* We expect to be called only after the limit was set. */
|
||||
+ assert(s390ms->memory_limit);
|
||||
+ return s390ms->memory_limit;
|
||||
+}
|
||||
+
|
||||
#define S390_PTF_REASON_NONE (0x00 << 8)
|
||||
#define S390_PTF_REASON_DONE (0x01 << 8)
|
||||
#define S390_PTF_REASON_BUSY (0x02 << 8)
|
||||
diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
|
||||
index 1cd30c1d84..3118a25fee 100644
|
||||
--- a/target/s390x/cpu-sysemu.c
|
||||
+++ b/target/s390x/cpu-sysemu.c
|
||||
@@ -255,14 +255,6 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
|
||||
return s390_count_running_cpus();
|
||||
}
|
||||
|
||||
-int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
|
||||
-{
|
||||
- if (kvm_enabled()) {
|
||||
- return kvm_s390_set_mem_limit(new_limit, hw_limit);
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
void s390_set_max_pagesize(uint64_t pagesize, Error **errp)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
|
||||
index 6a64472403..ecaf3191d2 100644
|
||||
--- a/target/s390x/cpu.h
|
||||
+++ b/target/s390x/cpu.h
|
||||
@@ -881,7 +881,6 @@ static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
|
||||
|
||||
/* cpu.c */
|
||||
void s390_crypto_reset(void);
|
||||
-int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit);
|
||||
void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
|
||||
void s390_cmma_reset(void);
|
||||
void s390_enable_css_support(S390CPU *cpu);
|
||||
--
|
||||
2.48.1
|
||||
|
46
kvm-s390x-pv-prepare-for-memory-devices.patch
Normal file
46
kvm-s390x-pv-prepare-for-memory-devices.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 9d5420c4370b74d60f082f2aa1225b19150ee629 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:12 +0100
|
||||
Subject: [PATCH 20/26] s390x/pv: prepare for memory devices
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [20/26] cdbe71168b9afa9657b94f1e7500568314c707a8 (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's avoid checking for the maxram_size, and instead rely on the memory
|
||||
limit determined in s390_memory_init(), that might be larger than
|
||||
maxram_size, for example due to alignment purposes.
|
||||
|
||||
This check now correctly mimics what the kernel will check in
|
||||
kvm_s390_pv_set_aside(), whereby a VM <= 2 GiB VM would end up using
|
||||
a segment type ASCE.
|
||||
|
||||
Message-ID: <20241219144115.2820241-12-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit a056332e732110c8ef0d40ffd49bd03afc2f04ca)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
target/s390x/kvm/pv.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c
|
||||
index 424cce75ca..fa66607e7b 100644
|
||||
--- a/target/s390x/kvm/pv.c
|
||||
+++ b/target/s390x/kvm/pv.c
|
||||
@@ -133,7 +133,7 @@ bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms)
|
||||
* If the feature is not present or if the VM is not larger than 2 GiB,
|
||||
* KVM_PV_ASYNC_CLEANUP_PREPARE fill fail; no point in attempting it.
|
||||
*/
|
||||
- if ((MACHINE(ms)->ram_size <= 2 * GiB) ||
|
||||
+ if (s390_get_memory_limit(ms) <= 2 * GiB ||
|
||||
!kvm_check_extension(kvm_state, KVM_CAP_S390_PROTECTED_ASYNC_DISABLE)) {
|
||||
return false;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
107
kvm-s390x-remember-the-maximum-page-size.patch
Normal file
107
kvm-s390x-remember-the-maximum-page-size.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 5a311d410bca4a5530a51c0b789ce8525d2d0653 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:13 +0100
|
||||
Subject: [PATCH 21/26] s390x: remember the maximum page size
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [21/26] 3b97c555b153d42e4fcb27dbb65fbf3edac622a4 (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's remember the value (successfully) set via s390_set_max_pagesize().
|
||||
This will be helpful to reject hotplugged memory devices that would exceed
|
||||
this initially set page size.
|
||||
|
||||
Handle it just like how we handle s390_get_memory_limit(), storing it in
|
||||
the machine, and moving the handling to machine code.
|
||||
|
||||
Message-ID: <20241219144115.2820241-13-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit df2ac211a62e6ced7f1495b634fa6f78962f2321)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 12 +++++++++++-
|
||||
include/hw/s390x/s390-virtio-ccw.h | 1 +
|
||||
target/s390x/cpu-sysemu.c | 7 -------
|
||||
target/s390x/cpu.h | 1 -
|
||||
4 files changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 824c73536a..bd05a22b4e 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -143,6 +143,16 @@ static void s390_set_memory_limit(S390CcwMachineState *s390ms,
|
||||
s390ms->memory_limit = new_limit;
|
||||
}
|
||||
|
||||
+static void s390_set_max_pagesize(S390CcwMachineState *s390ms,
|
||||
+ uint64_t pagesize)
|
||||
+{
|
||||
+ assert(!s390ms->max_pagesize && pagesize);
|
||||
+ if (kvm_enabled()) {
|
||||
+ kvm_s390_set_max_pagesize(pagesize, &error_fatal);
|
||||
+ }
|
||||
+ s390ms->max_pagesize = pagesize;
|
||||
+}
|
||||
+
|
||||
static void s390_memory_init(MachineState *machine)
|
||||
{
|
||||
S390CcwMachineState *s390ms = S390_CCW_MACHINE(machine);
|
||||
@@ -191,7 +201,7 @@ static void s390_memory_init(MachineState *machine)
|
||||
* Configure the maximum page size. As no memory devices were created
|
||||
* yet, this is the page size of initial memory only.
|
||||
*/
|
||||
- s390_set_max_pagesize(qemu_maxrampagesize(), &error_fatal);
|
||||
+ s390_set_max_pagesize(s390ms, qemu_maxrampagesize());
|
||||
/* Initialize storage key device */
|
||||
s390_skeys_init();
|
||||
/* Initialize storage attributes device */
|
||||
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
|
||||
index de04336c5a..599740a998 100644
|
||||
--- a/include/hw/s390x/s390-virtio-ccw.h
|
||||
+++ b/include/hw/s390x/s390-virtio-ccw.h
|
||||
@@ -30,6 +30,7 @@ struct S390CcwMachineState {
|
||||
bool pv;
|
||||
uint8_t loadparm[8];
|
||||
uint64_t memory_limit;
|
||||
+ uint64_t max_pagesize;
|
||||
|
||||
SCLPDevice *sclp;
|
||||
};
|
||||
diff --git a/target/s390x/cpu-sysemu.c b/target/s390x/cpu-sysemu.c
|
||||
index 3118a25fee..706a5c53e2 100644
|
||||
--- a/target/s390x/cpu-sysemu.c
|
||||
+++ b/target/s390x/cpu-sysemu.c
|
||||
@@ -255,13 +255,6 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
|
||||
return s390_count_running_cpus();
|
||||
}
|
||||
|
||||
-void s390_set_max_pagesize(uint64_t pagesize, Error **errp)
|
||||
-{
|
||||
- if (kvm_enabled()) {
|
||||
- kvm_s390_set_max_pagesize(pagesize, errp);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void s390_cmma_reset(void)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
|
||||
index ecaf3191d2..9770a62ac9 100644
|
||||
--- a/target/s390x/cpu.h
|
||||
+++ b/target/s390x/cpu.h
|
||||
@@ -881,7 +881,6 @@ static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
|
||||
|
||||
/* cpu.c */
|
||||
void s390_crypto_reset(void);
|
||||
-void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
|
||||
void s390_cmma_reset(void);
|
||||
void s390_enable_css_support(S390CPU *cpu);
|
||||
void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
|
||||
--
|
||||
2.48.1
|
||||
|
113
kvm-s390x-rename-s390-virtio-hcall-to-s390-hypercall.patch
Normal file
113
kvm-s390x-rename-s390-virtio-hcall-to-s390-hypercall.patch
Normal file
@ -0,0 +1,113 @@
|
||||
From 2fbdf7e3cf23daea470aaa4a29e16641feb76f3c Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:05 +0100
|
||||
Subject: [PATCH 13/26] s390x: rename s390-virtio-hcall* to s390-hypercall*
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [13/26] 3c1ef3cbb137517b306871f0a88a61a59740af5a (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's make it clearer that we are talking about general
|
||||
QEMU/KVM-specific hypercalls.
|
||||
|
||||
Message-ID: <20241219144115.2820241-5-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 85489fc3652d0c4433c940f1a80a952e8cb5d3cb)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/meson.build | 2 +-
|
||||
hw/s390x/{s390-virtio-hcall.c => s390-hypercall.c} | 2 +-
|
||||
hw/s390x/{s390-virtio-hcall.h => s390-hypercall.h} | 6 +++---
|
||||
target/s390x/kvm/kvm.c | 2 +-
|
||||
target/s390x/tcg/misc_helper.c | 2 +-
|
||||
5 files changed, 7 insertions(+), 7 deletions(-)
|
||||
rename hw/s390x/{s390-virtio-hcall.c => s390-hypercall.c} (97%)
|
||||
rename hw/s390x/{s390-virtio-hcall.h => s390-hypercall.h} (86%)
|
||||
|
||||
diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build
|
||||
index d6c8c33915..e344a3bd8c 100644
|
||||
--- a/hw/s390x/meson.build
|
||||
+++ b/hw/s390x/meson.build
|
||||
@@ -29,7 +29,7 @@ s390x_ss.add(when: 'CONFIG_TCG', if_true: files(
|
||||
))
|
||||
s390x_ss.add(when: 'CONFIG_S390_CCW_VIRTIO', if_true: files(
|
||||
's390-virtio-ccw.c',
|
||||
- 's390-virtio-hcall.c',
|
||||
+ 's390-hypercall.c',
|
||||
))
|
||||
s390x_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('3270-ccw.c'))
|
||||
s390x_ss.add(when: 'CONFIG_VFIO', if_true: files('s390-pci-vfio.c'))
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-hypercall.c
|
||||
similarity index 97%
|
||||
rename from hw/s390x/s390-virtio-hcall.c
|
||||
rename to hw/s390x/s390-hypercall.c
|
||||
index 5fb78a719e..f816c2b1ef 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.c
|
||||
+++ b/hw/s390x/s390-hypercall.c
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "hw/boards.h"
|
||||
-#include "hw/s390x/s390-virtio-hcall.h"
|
||||
+#include "hw/s390x/s390-hypercall.h"
|
||||
#include "hw/s390x/ioinst.h"
|
||||
#include "hw/s390x/css.h"
|
||||
#include "virtio-ccw.h"
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.h b/hw/s390x/s390-hypercall.h
|
||||
similarity index 86%
|
||||
rename from hw/s390x/s390-virtio-hcall.h
|
||||
rename to hw/s390x/s390-hypercall.h
|
||||
index dca456b926..2fa81dbfdd 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.h
|
||||
+++ b/hw/s390x/s390-hypercall.h
|
||||
@@ -9,8 +9,8 @@
|
||||
* directory.
|
||||
*/
|
||||
|
||||
-#ifndef HW_S390_VIRTIO_HCALL_H
|
||||
-#define HW_S390_VIRTIO_HCALL_H
|
||||
+#ifndef HW_S390_HYPERCALL_H
|
||||
+#define HW_S390_HYPERCALL_H
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
@@ -21,4 +21,4 @@
|
||||
|
||||
void handle_diag_500(S390CPU *cpu, uintptr_t ra);
|
||||
|
||||
-#endif /* HW_S390_VIRTIO_HCALL_H */
|
||||
+#endif /* HW_S390_HYPERCALL_H */
|
||||
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
|
||||
index 42d6a54126..afc8d570c9 100644
|
||||
--- a/target/s390x/kvm/kvm.c
|
||||
+++ b/target/s390x/kvm/kvm.c
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "hw/s390x/ebcdic.h"
|
||||
#include "exec/memattrs.h"
|
||||
#include "hw/s390x/s390-virtio-ccw.h"
|
||||
-#include "hw/s390x/s390-virtio-hcall.h"
|
||||
+#include "hw/s390x/s390-hypercall.h"
|
||||
#include "target/s390x/kvm/pv.h"
|
||||
#include CONFIG_DEVICES
|
||||
|
||||
diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c
|
||||
index 2b4310003b..b726a95352 100644
|
||||
--- a/target/s390x/tcg/misc_helper.c
|
||||
+++ b/target/s390x/tcg/misc_helper.c
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/s390x/ebcdic.h"
|
||||
-#include "hw/s390x/s390-virtio-hcall.h"
|
||||
+#include "hw/s390x/s390-hypercall.h"
|
||||
#include "hw/s390x/sclp.h"
|
||||
#include "hw/s390x/s390_flic.h"
|
||||
#include "hw/s390x/ioinst.h"
|
||||
--
|
||||
2.48.1
|
||||
|
@ -0,0 +1,99 @@
|
||||
From 86417a068f24964422d4fd5ea301d70a0f8142d2 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:08 +0100
|
||||
Subject: [PATCH 16/26] s390x/s390-hypercall: introduce DIAG500 STORAGE_LIMIT
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [16/26] c1c341227388735450ddbba0201e7523e0658c07 (thuth/qemu-kvm-cs)
|
||||
|
||||
A guest OS that supports memory hotplug / memory devices must during
|
||||
boot be aware of the maximum possible physical memory address that it might
|
||||
have to handle at a later stage during its runtime.
|
||||
|
||||
For example, the maximum possible memory address might be required to
|
||||
prepare the kernel virtual address space accordingly (e.g., select page
|
||||
table hierarchy depth).
|
||||
|
||||
On s390x there is currently no such mechanism that is compatible with
|
||||
paravirtualized memory devices, because the whole SCLP interface was
|
||||
designed around the idea of "storage increments" and "standby memory".
|
||||
Paravirtualized memory devices we want to support, such as virtio-mem, have
|
||||
no intersection with any of that, but could co-exist with them in the
|
||||
future if ever needed.
|
||||
|
||||
In particular, a guest OS must never detect and use device memory
|
||||
without the help of a proper device driver. Device memory must not be
|
||||
exposed in any firmware-provided memory map (SCLP or diag260 on s390x).
|
||||
For this reason, these memory devices will be places in memory *above*
|
||||
the "maximum storage increment" exposed via SCLP.
|
||||
|
||||
Let's provide a new diag500 subcode to query the memory limit determined in
|
||||
s390_memory_init().
|
||||
|
||||
Message-ID: <20241219144115.2820241-8-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit f7c168657816486527727d860b73747d41f0c5f6)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-hypercall.c | 12 +++++++++++-
|
||||
hw/s390x/s390-hypercall.h | 1 +
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-hypercall.c b/hw/s390x/s390-hypercall.c
|
||||
index f816c2b1ef..ac1b08b2cd 100644
|
||||
--- a/hw/s390x/s390-hypercall.c
|
||||
+++ b/hw/s390x/s390-hypercall.c
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
-#include "hw/boards.h"
|
||||
+#include "hw/s390x/s390-virtio-ccw.h"
|
||||
#include "hw/s390x/s390-hypercall.h"
|
||||
#include "hw/s390x/ioinst.h"
|
||||
#include "hw/s390x/css.h"
|
||||
@@ -57,6 +57,13 @@ static int handle_virtio_ccw_notify(uint64_t subch_id, uint64_t data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static uint64_t handle_storage_limit(void)
|
||||
+{
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(qdev_get_machine());
|
||||
+
|
||||
+ return s390_get_memory_limit(s390ms) - 1;
|
||||
+}
|
||||
+
|
||||
void handle_diag_500(S390CPU *cpu, uintptr_t ra)
|
||||
{
|
||||
CPUS390XState *env = &cpu->env;
|
||||
@@ -69,6 +76,9 @@ void handle_diag_500(S390CPU *cpu, uintptr_t ra)
|
||||
case DIAG500_VIRTIO_CCW_NOTIFY:
|
||||
env->regs[2] = handle_virtio_ccw_notify(env->regs[2], env->regs[3]);
|
||||
break;
|
||||
+ case DIAG500_STORAGE_LIMIT:
|
||||
+ env->regs[2] = handle_storage_limit();
|
||||
+ break;
|
||||
default:
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
}
|
||||
diff --git a/hw/s390x/s390-hypercall.h b/hw/s390x/s390-hypercall.h
|
||||
index 2fa81dbfdd..4f07209128 100644
|
||||
--- a/hw/s390x/s390-hypercall.h
|
||||
+++ b/hw/s390x/s390-hypercall.h
|
||||
@@ -18,6 +18,7 @@
|
||||
#define DIAG500_VIRTIO_RESET 1 /* legacy */
|
||||
#define DIAG500_VIRTIO_SET_STATUS 2 /* legacy */
|
||||
#define DIAG500_VIRTIO_CCW_NOTIFY 3 /* KVM_S390_VIRTIO_CCW_NOTIFY */
|
||||
+#define DIAG500_STORAGE_LIMIT 4
|
||||
|
||||
void handle_diag_500(S390CPU *cpu, uintptr_t ra);
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
56
kvm-s390x-s390-skeys-prepare-for-memory-devices.patch
Normal file
56
kvm-s390x-s390-skeys-prepare-for-memory-devices.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 53d1b43699c6b30583f41a18a33c28893718aeac Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:10 +0100
|
||||
Subject: [PATCH 18/26] s390x/s390-skeys: prepare for memory devices
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [18/26] 47edda0eeb6d5932f81633f2d9d294b1ca5f413c (thuth/qemu-kvm-cs)
|
||||
|
||||
With memory devices, we will have storage keys for memory that
|
||||
exceeds the initial ram size.
|
||||
|
||||
The TODO already states that current handling is subopimal,
|
||||
but we won't worry about improving that (TCG-only) thing for now.
|
||||
|
||||
Message-ID: <20241219144115.2820241-10-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit d1e3c2ac41b3f73708682e4e8212c32ad35013b9)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-skeys.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
|
||||
index bf22d6863e..e4297b3b8a 100644
|
||||
--- a/hw/s390x/s390-skeys.c
|
||||
+++ b/hw/s390x/s390-skeys.c
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/units.h"
|
||||
-#include "hw/boards.h"
|
||||
+#include "hw/s390x/s390-virtio-ccw.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/s390x/storage-keys.h"
|
||||
#include "qapi/error.h"
|
||||
@@ -251,9 +251,9 @@ static bool qemu_s390_enable_skeys(S390SKeysState *ss)
|
||||
* g_once_init_enter() is good enough.
|
||||
*/
|
||||
if (g_once_init_enter(&initialized)) {
|
||||
- MachineState *machine = MACHINE(qdev_get_machine());
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(qdev_get_machine());
|
||||
|
||||
- skeys->key_count = machine->ram_size / TARGET_PAGE_SIZE;
|
||||
+ skeys->key_count = s390_get_memory_limit(s390ms) / TARGET_PAGE_SIZE;
|
||||
skeys->keydata = g_malloc0(skeys->key_count);
|
||||
g_once_init_leave(&initialized, 1);
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
155
kvm-s390x-s390-stattrib-kvm-prepare-for-memory-devices-a.patch
Normal file
155
kvm-s390x-s390-stattrib-kvm-prepare-for-memory-devices-a.patch
Normal file
@ -0,0 +1,155 @@
|
||||
From 1195c91d10892a888870248fd881612955b9e1eb Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:09 +0100
|
||||
Subject: [PATCH 17/26] s390x/s390-stattrib-kvm: prepare for memory devices and
|
||||
sparse memory layouts
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [17/26] 799aa7b2b9cc2a948e9f391bc0ecf739254c78b1 (thuth/qemu-kvm-cs)
|
||||
|
||||
With memory devices, we will have storage attributes for memory that
|
||||
exceeds the initial ram size. Further, we can easily have memory holes,
|
||||
for which there (currently) are no storage attributes.
|
||||
|
||||
In particular, with memory holes, KVM_S390_SET_CMMA_BITS will fail to set
|
||||
some storage attributes.
|
||||
|
||||
So let's do it like we handle storage keys migration, relying on
|
||||
guest_phys_blocks_append(). However, in contrast to storage key
|
||||
migration, we will handle it on the migration destination.
|
||||
|
||||
This is a preparation for virtio-mem support. Note that ever since the
|
||||
"early migration" feature was added (x-early-migration), the state
|
||||
of device blocks (plugged/unplugged) is migrated early such that
|
||||
guest_phys_blocks_append() will properly consider all currently plugged
|
||||
memory blocks and skip any unplugged ones.
|
||||
|
||||
In the future, we should try getting rid of the large temporary buffer
|
||||
and also not send any attributes for any memory holes, just so they
|
||||
get ignored on the destination.
|
||||
|
||||
Message-ID: <20241219144115.2820241-9-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 241e6b2d27b090b17cda5b011b2064544b0c458b)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-stattrib-kvm.c | 67 +++++++++++++++++++++++-------------
|
||||
1 file changed, 43 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c
|
||||
index eeaa811098..33ec91422a 100644
|
||||
--- a/hw/s390x/s390-stattrib-kvm.c
|
||||
+++ b/hw/s390x/s390-stattrib-kvm.c
|
||||
@@ -10,11 +10,12 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
-#include "hw/boards.h"
|
||||
+#include "hw/s390x/s390-virtio-ccw.h"
|
||||
#include "migration/qemu-file.h"
|
||||
#include "hw/s390x/storage-attributes.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/kvm.h"
|
||||
+#include "sysemu/memory_mapping.h"
|
||||
#include "exec/ram_addr.h"
|
||||
#include "kvm/kvm_s390x.h"
|
||||
#include "qapi/error.h"
|
||||
@@ -84,8 +85,8 @@ static int kvm_s390_stattrib_set_stattr(S390StAttribState *sa,
|
||||
uint8_t *values)
|
||||
{
|
||||
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
|
||||
- MachineState *machine = MACHINE(qdev_get_machine());
|
||||
- unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(qdev_get_machine());
|
||||
+ unsigned long max = s390_get_memory_limit(s390ms) / TARGET_PAGE_SIZE;
|
||||
|
||||
if (start_gfn + count > max) {
|
||||
error_report("Out of memory bounds when setting storage attributes");
|
||||
@@ -103,39 +104,57 @@ static int kvm_s390_stattrib_set_stattr(S390StAttribState *sa,
|
||||
static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
|
||||
{
|
||||
KVMS390StAttribState *sas = KVM_S390_STATTRIB(sa);
|
||||
- MachineState *machine = MACHINE(qdev_get_machine());
|
||||
- unsigned long max = machine->ram_size / TARGET_PAGE_SIZE;
|
||||
- /* We do not need to reach the maximum buffer size allowed */
|
||||
- unsigned long cx, len = KVM_S390_SKEYS_MAX / 2;
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(qdev_get_machine());
|
||||
+ unsigned long max = s390_get_memory_limit(s390ms) / TARGET_PAGE_SIZE;
|
||||
+ unsigned long start_gfn, end_gfn, pages;
|
||||
+ GuestPhysBlockList guest_phys_blocks;
|
||||
+ GuestPhysBlock *block;
|
||||
int r;
|
||||
struct kvm_s390_cmma_log clog = {
|
||||
.flags = 0,
|
||||
.mask = ~0ULL,
|
||||
};
|
||||
|
||||
- if (sas->incoming_buffer) {
|
||||
- for (cx = 0; cx + len <= max; cx += len) {
|
||||
- clog.start_gfn = cx;
|
||||
- clog.count = len;
|
||||
- clog.values = (uint64_t)(sas->incoming_buffer + cx);
|
||||
- r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
|
||||
- if (r) {
|
||||
- error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
- if (cx < max) {
|
||||
- clog.start_gfn = cx;
|
||||
- clog.count = max - cx;
|
||||
- clog.values = (uint64_t)(sas->incoming_buffer + cx);
|
||||
+ if (!sas->incoming_buffer) {
|
||||
+ return;
|
||||
+ }
|
||||
+ guest_phys_blocks_init(&guest_phys_blocks);
|
||||
+ guest_phys_blocks_append(&guest_phys_blocks);
|
||||
+
|
||||
+ QTAILQ_FOREACH(block, &guest_phys_blocks.head, next) {
|
||||
+ assert(QEMU_IS_ALIGNED(block->target_start, TARGET_PAGE_SIZE));
|
||||
+ assert(QEMU_IS_ALIGNED(block->target_end, TARGET_PAGE_SIZE));
|
||||
+
|
||||
+ start_gfn = block->target_start / TARGET_PAGE_SIZE;
|
||||
+ end_gfn = block->target_end / TARGET_PAGE_SIZE;
|
||||
+
|
||||
+ while (start_gfn < end_gfn) {
|
||||
+ /* Don't exceed the maximum buffer size. */
|
||||
+ pages = MIN(end_gfn - start_gfn, KVM_S390_SKEYS_MAX / 2);
|
||||
+
|
||||
+ /*
|
||||
+ * If we ever get guest physical memory beyond the configured
|
||||
+ * memory limit, something went very wrong.
|
||||
+ */
|
||||
+ assert(start_gfn + pages <= max);
|
||||
+
|
||||
+ clog.start_gfn = start_gfn;
|
||||
+ clog.count = pages;
|
||||
+ clog.values = (uint64_t)(sas->incoming_buffer + start_gfn);
|
||||
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
|
||||
if (r) {
|
||||
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
|
||||
+ goto out;
|
||||
}
|
||||
+
|
||||
+ start_gfn += pages;
|
||||
}
|
||||
- g_free(sas->incoming_buffer);
|
||||
- sas->incoming_buffer = NULL;
|
||||
}
|
||||
+
|
||||
+out:
|
||||
+ guest_phys_blocks_free(&guest_phys_blocks);
|
||||
+ g_free(sas->incoming_buffer);
|
||||
+ sas->incoming_buffer = NULL;
|
||||
}
|
||||
|
||||
static int kvm_s390_stattrib_set_migrationmode(S390StAttribState *sa, bool val,
|
||||
--
|
||||
2.48.1
|
||||
|
@ -0,0 +1,63 @@
|
||||
From 4ee3076ac566622929f9410636483c4f0b2da967 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:02 +0100
|
||||
Subject: [PATCH 10/26] s390x/s390-virtio-ccw: don't crash on weird RAM sizes
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [10/26] 55738da52f3cf4746bee2b17780a10720fa05863 (thuth/qemu-kvm-cs)
|
||||
|
||||
KVM is not happy when starting a VM with weird RAM sizes:
|
||||
|
||||
# qemu-system-s390x --enable-kvm --nographic -m 1234K
|
||||
qemu-system-s390x: kvm_set_user_memory_region: KVM_SET_USER_MEMORY_REGION
|
||||
failed, slot=0, start=0x0, size=0x244000: Invalid argument
|
||||
kvm_set_phys_mem: error registering slot: Invalid argument
|
||||
Aborted (core dumped)
|
||||
|
||||
Let's handle that in a better way by rejecting such weird RAM sizes
|
||||
right from the start:
|
||||
|
||||
# qemu-system-s390x --enable-kvm --nographic -m 1234K
|
||||
qemu-system-s390x: ram size must be multiples of 1 MiB
|
||||
|
||||
Message-ID: <20241219144115.2820241-2-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Eric Farman <farman@linux.ibm.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Acked-by: Janosch Frank <frankja@linux.ibm.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 14e568ab4836347481af2e334009c385f456a734)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 94cad1705b..82ded9666c 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -180,6 +180,17 @@ static void s390_memory_init(MemoryRegion *ram)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
|
||||
+ if (!QEMU_IS_ALIGNED(memory_region_size(ram), 1 * MiB)) {
|
||||
+ /*
|
||||
+ * SCLP cannot possibly expose smaller granularity right now and KVM
|
||||
+ * cannot handle smaller granularity. As we don't support NUMA, the
|
||||
+ * region size directly corresponds to machine->ram_size, and the region
|
||||
+ * is a single RAM memory region.
|
||||
+ */
|
||||
+ error_report("ram size must be multiples of 1 MiB");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
/* allocate RAM for core */
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
140
kvm-s390x-s390-virtio-ccw-move-setting-the-maximum-guest.patch
Normal file
140
kvm-s390x-s390-virtio-ccw-move-setting-the-maximum-guest.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 9ec2d356210f1e66f50519cc4d58633a13db9004 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:06 +0100
|
||||
Subject: [PATCH 14/26] s390x/s390-virtio-ccw: move setting the maximum guest
|
||||
size from sclp to machine code
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [14/26] a5970c1c6d8d09a473a25a7eee533ec3a6711ec8 (thuth/qemu-kvm-cs)
|
||||
|
||||
Nowadays, it feels more natural to have that code located in
|
||||
s390_memory_init(), where we also have direct access to the machine
|
||||
object.
|
||||
|
||||
While at it, use the actual RAM size, not the maximum RAM size which
|
||||
cannot currently be reached without support for any memory devices.
|
||||
Consequently update s390_pv_vm_try_disable_async() to rely on the RAM size
|
||||
as well, to avoid temporary issues while we further rework that
|
||||
handling.
|
||||
|
||||
set_memory_limit() is temporary, we'll merge it with
|
||||
s390_set_memory_limit() next.
|
||||
|
||||
Message-ID: <20241219144115.2820241-6-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 3c6fb557d295949bea291c3bf88ee9c83392e78c)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 28 ++++++++++++++++++++++++----
|
||||
hw/s390x/sclp.c | 11 -----------
|
||||
target/s390x/kvm/pv.c | 2 +-
|
||||
3 files changed, 25 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index d47e99028e..248ac28d20 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -121,11 +121,29 @@ static void subsystem_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static void s390_memory_init(MemoryRegion *ram)
|
||||
+static void set_memory_limit(uint64_t new_limit)
|
||||
+{
|
||||
+ uint64_t hw_limit;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = s390_set_memory_limit(new_limit, &hw_limit);
|
||||
+ if (ret == -E2BIG) {
|
||||
+ error_report("host supports a maximum of %" PRIu64 " GB",
|
||||
+ hw_limit / GiB);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ } else if (ret) {
|
||||
+ error_report("setting the guest size failed");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void s390_memory_init(MachineState *machine)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
+ MemoryRegion *ram = machine->ram;
|
||||
+ uint64_t ram_size = memory_region_size(ram);
|
||||
|
||||
- if (!QEMU_IS_ALIGNED(memory_region_size(ram), 1 * MiB)) {
|
||||
+ if (!QEMU_IS_ALIGNED(ram_size, 1 * MiB)) {
|
||||
/*
|
||||
* SCLP cannot possibly expose smaller granularity right now and KVM
|
||||
* cannot handle smaller granularity. As we don't support NUMA, the
|
||||
@@ -136,7 +154,9 @@ static void s390_memory_init(MemoryRegion *ram)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
- /* allocate RAM for core */
|
||||
+ set_memory_limit(ram_size);
|
||||
+
|
||||
+ /* Map the initial memory. Must happen after setting the memory limit. */
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
/*
|
||||
@@ -211,7 +231,7 @@ static void ccw_init(MachineState *machine)
|
||||
qdev_realize_and_unref(DEVICE(ms->sclp), NULL, &error_fatal);
|
||||
|
||||
/* init memory + setup max page size. Required for the CPU model */
|
||||
- s390_memory_init(machine->ram);
|
||||
+ s390_memory_init(machine);
|
||||
|
||||
/* init CPUs (incl. CPU model) early so s390_has_feature() works */
|
||||
s390_init_cpus(machine);
|
||||
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
|
||||
index 8757626b5c..73e88ab4eb 100644
|
||||
--- a/hw/s390x/sclp.c
|
||||
+++ b/hw/s390x/sclp.c
|
||||
@@ -376,10 +376,7 @@ void sclp_service_interrupt(uint32_t sccb)
|
||||
/* qemu object creation and initialization functions */
|
||||
static void sclp_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
- MachineState *machine = MACHINE(qdev_get_machine());
|
||||
SCLPDevice *sclp = SCLP(dev);
|
||||
- uint64_t hw_limit;
|
||||
- int ret;
|
||||
|
||||
/*
|
||||
* qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS. As long
|
||||
@@ -389,14 +386,6 @@ static void sclp_realize(DeviceState *dev, Error **errp)
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(sclp->event_facility), errp)) {
|
||||
return;
|
||||
}
|
||||
-
|
||||
- ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
|
||||
- if (ret == -E2BIG) {
|
||||
- error_setg(errp, "host supports a maximum of %" PRIu64 " GB",
|
||||
- hw_limit / GiB);
|
||||
- } else if (ret) {
|
||||
- error_setg(errp, "setting the guest size failed");
|
||||
- }
|
||||
}
|
||||
|
||||
static void sclp_memory_init(SCLPDevice *sclp)
|
||||
diff --git a/target/s390x/kvm/pv.c b/target/s390x/kvm/pv.c
|
||||
index dde836d21a..424cce75ca 100644
|
||||
--- a/target/s390x/kvm/pv.c
|
||||
+++ b/target/s390x/kvm/pv.c
|
||||
@@ -133,7 +133,7 @@ bool s390_pv_vm_try_disable_async(S390CcwMachineState *ms)
|
||||
* If the feature is not present or if the VM is not larger than 2 GiB,
|
||||
* KVM_PV_ASYNC_CLEANUP_PREPARE fill fail; no point in attempting it.
|
||||
*/
|
||||
- if ((MACHINE(ms)->maxram_size <= 2 * GiB) ||
|
||||
+ if ((MACHINE(ms)->ram_size <= 2 * GiB) ||
|
||||
!kvm_check_extension(kvm_state, KVM_CAP_S390_PROTECTED_ASYNC_DISABLE)) {
|
||||
return false;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
117
kvm-s390x-s390-virtio-ccw-prepare-for-memory-devices.patch
Normal file
117
kvm-s390x-s390-virtio-ccw-prepare-for-memory-devices.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 0e7d7bf86fb242c1ea90bf9648fb061626790eda Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:11 +0100
|
||||
Subject: [PATCH 19/26] s390x/s390-virtio-ccw: prepare for memory devices
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [19/26] 2441c8c5f5a06d5ca93188dd44e8a08f06d1722b (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's prepare our address space for memory devices if enabled via
|
||||
"maxmem" and if we have CONFIG_MEM_DEVICE enabled at all. Note that
|
||||
CONFIG_MEM_DEVICE will be selected automatically once we add support
|
||||
for devices.
|
||||
|
||||
Just like on other architectures, the region container for memory devices
|
||||
is placed directly above our initial memory. For now, we only align the
|
||||
start address of the region up to 1 GiB, but we won't add any additional
|
||||
space to the region for internal alignment purposes; this can be done in
|
||||
the future if really required.
|
||||
|
||||
The RAM size returned via SCLP is not modified, as this only
|
||||
covers initial RAM (and standby memory we don't implement) and not memory
|
||||
devices; clarify that in the docs of read_SCP_info(). Existing OSes without
|
||||
support for memory devices will keep working as is, even when memory
|
||||
devices would be attached the VM.
|
||||
|
||||
Guest OSs which support memory devices, such as virtio-mem, will
|
||||
consult diag500(), to find out the maximum possible pfn. Guest OSes that
|
||||
don't support memory devices, don't have to be changed and will continue
|
||||
relying on information provided by SCLP.
|
||||
|
||||
There are no remaining maxram_size users in s390x code, and the remaining
|
||||
ram_size users only care about initial RAM:
|
||||
* hw/s390x/ipl.c
|
||||
* hw/s390x/s390-hypercall.c
|
||||
* hw/s390x/sclp.c
|
||||
* target/s390x/kvm/pv.c
|
||||
|
||||
Message-ID: <20241219144115.2820241-11-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 1e86400298cf0fed5f7d49427db477775b859093)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-ccw.c | 23 ++++++++++++++++++++++-
|
||||
hw/s390x/sclp.c | 6 +++++-
|
||||
2 files changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index f5f147eb92..824c73536a 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -149,6 +149,7 @@ static void s390_memory_init(MachineState *machine)
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = machine->ram;
|
||||
uint64_t ram_size = memory_region_size(ram);
|
||||
+ uint64_t devmem_base, devmem_size;
|
||||
|
||||
if (!QEMU_IS_ALIGNED(ram_size, 1 * MiB)) {
|
||||
/*
|
||||
@@ -161,11 +162,31 @@ static void s390_memory_init(MachineState *machine)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
- s390_set_memory_limit(s390ms, ram_size);
|
||||
+ devmem_size = 0;
|
||||
+ devmem_base = ram_size;
|
||||
+#ifdef CONFIG_MEM_DEVICE
|
||||
+ if (machine->ram_size < machine->maxram_size) {
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure memory devices have a sane default alignment, even
|
||||
+ * when weird initial memory sizes are specified.
|
||||
+ */
|
||||
+ devmem_base = QEMU_ALIGN_UP(devmem_base, 1 * GiB);
|
||||
+ devmem_size = machine->maxram_size - machine->ram_size;
|
||||
+ }
|
||||
+#endif
|
||||
+ s390_set_memory_limit(s390ms, devmem_base + devmem_size);
|
||||
|
||||
/* Map the initial memory. Must happen after setting the memory limit. */
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
+ /* Initialize address space for memory devices. */
|
||||
+#ifdef CONFIG_MEM_DEVICE
|
||||
+ if (devmem_size) {
|
||||
+ machine_memory_devices_init(machine, devmem_base, devmem_size);
|
||||
+ }
|
||||
+#endif /* CONFIG_MEM_DEVICE */
|
||||
+
|
||||
/*
|
||||
* Configure the maximum page size. As no memory devices were created
|
||||
* yet, this is the page size of initial memory only.
|
||||
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
|
||||
index 73e88ab4eb..5945c9b1d8 100644
|
||||
--- a/hw/s390x/sclp.c
|
||||
+++ b/hw/s390x/sclp.c
|
||||
@@ -161,7 +161,11 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
|
||||
read_info->rnsize2 = cpu_to_be32(rnsize);
|
||||
}
|
||||
|
||||
- /* we don't support standby memory, maxram_size is never exposed */
|
||||
+ /*
|
||||
+ * We don't support standby memory. maxram_size is used for sizing the
|
||||
+ * memory device region, which is not exposed through SCLP but through
|
||||
+ * diag500.
|
||||
+ */
|
||||
rnmax = machine->ram_size >> sclp->increment_size;
|
||||
if (rnmax < 0x10000) {
|
||||
read_info->rnmax = cpu_to_be16(rnmax);
|
||||
--
|
||||
2.48.1
|
||||
|
163
kvm-s390x-s390-virtio-hcall-prepare-for-more-diag500-hyp.patch
Normal file
163
kvm-s390x-s390-virtio-hcall-prepare-for-more-diag500-hyp.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From d2764db41fc6edcead9ad27b8d31e7bff524c0c0 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:04 +0100
|
||||
Subject: [PATCH 12/26] s390x/s390-virtio-hcall: prepare for more diag500
|
||||
hypercalls
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [12/26] 6573602d71b9e70679a48315f913309be29d6239 (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's generalize, abstracting the virtio bits. diag500 is now a generic
|
||||
hypercall to handle QEMU/KVM specific things. Explicitly specify all
|
||||
already defined subcodes, including legacy ones (so we know what we can
|
||||
use for new hypercalls).
|
||||
|
||||
Move the PGM_SPECIFICATION injection into the renamed function
|
||||
handle_diag_500(), so we can turn it into a void function.
|
||||
|
||||
We'll rename the files separately, so git properly detects the rename.
|
||||
|
||||
Message-ID: <20241219144115.2820241-4-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 6e9cc2da4e8b997fd6ff3249034f436b84fc7974)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/s390-virtio-hcall.c | 15 ++++++++-------
|
||||
hw/s390x/s390-virtio-hcall.h | 11 ++++++-----
|
||||
target/s390x/kvm/kvm.c | 20 +++-----------------
|
||||
target/s390x/tcg/misc_helper.c | 5 +++--
|
||||
4 files changed, 20 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c
|
||||
index ca49e3cd22..5fb78a719e 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.c
|
||||
+++ b/hw/s390x/s390-virtio-hcall.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Support for virtio hypercalls on s390
|
||||
+ * Support for QEMU/KVM hypercalls on s390
|
||||
*
|
||||
* Copyright 2012 IBM Corp.
|
||||
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||
@@ -57,18 +57,19 @@ static int handle_virtio_ccw_notify(uint64_t subch_id, uint64_t data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int s390_virtio_hypercall(CPUS390XState *env)
|
||||
+void handle_diag_500(S390CPU *cpu, uintptr_t ra)
|
||||
{
|
||||
+ CPUS390XState *env = &cpu->env;
|
||||
const uint64_t subcode = env->regs[1];
|
||||
|
||||
switch (subcode) {
|
||||
- case KVM_S390_VIRTIO_NOTIFY:
|
||||
+ case DIAG500_VIRTIO_NOTIFY:
|
||||
env->regs[2] = handle_virtio_notify(env->regs[2]);
|
||||
- return 0;
|
||||
- case KVM_S390_VIRTIO_CCW_NOTIFY:
|
||||
+ break;
|
||||
+ case DIAG500_VIRTIO_CCW_NOTIFY:
|
||||
env->regs[2] = handle_virtio_ccw_notify(env->regs[2], env->regs[3]);
|
||||
- return 0;
|
||||
+ break;
|
||||
default:
|
||||
- return -EINVAL;
|
||||
+ s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
}
|
||||
}
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.h b/hw/s390x/s390-virtio-hcall.h
|
||||
index 3d9fe147d2..dca456b926 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.h
|
||||
+++ b/hw/s390x/s390-virtio-hcall.h
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Support for virtio hypercalls on s390x
|
||||
+ * Support for QEMU/KVM hypercalls on s390x
|
||||
*
|
||||
* Copyright IBM Corp. 2012, 2017
|
||||
* Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||
@@ -12,12 +12,13 @@
|
||||
#ifndef HW_S390_VIRTIO_HCALL_H
|
||||
#define HW_S390_VIRTIO_HCALL_H
|
||||
|
||||
-#include "standard-headers/asm-s390/virtio-ccw.h"
|
||||
#include "cpu.h"
|
||||
|
||||
-/* The only thing that we need from the old kvm_virtio.h file */
|
||||
-#define KVM_S390_VIRTIO_NOTIFY 0
|
||||
+#define DIAG500_VIRTIO_NOTIFY 0 /* legacy, implemented as a NOP */
|
||||
+#define DIAG500_VIRTIO_RESET 1 /* legacy */
|
||||
+#define DIAG500_VIRTIO_SET_STATUS 2 /* legacy */
|
||||
+#define DIAG500_VIRTIO_CCW_NOTIFY 3 /* KVM_S390_VIRTIO_CCW_NOTIFY */
|
||||
|
||||
-int s390_virtio_hypercall(CPUS390XState *env);
|
||||
+void handle_diag_500(S390CPU *cpu, uintptr_t ra);
|
||||
|
||||
#endif /* HW_S390_VIRTIO_HCALL_H */
|
||||
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
|
||||
index 5947dda829..42d6a54126 100644
|
||||
--- a/target/s390x/kvm/kvm.c
|
||||
+++ b/target/s390x/kvm/kvm.c
|
||||
@@ -1492,22 +1492,6 @@ static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
|
||||
return r;
|
||||
}
|
||||
|
||||
-static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
|
||||
-{
|
||||
- CPUS390XState *env = &cpu->env;
|
||||
- int ret = -EINVAL;
|
||||
-
|
||||
-#ifdef CONFIG_S390_CCW_VIRTIO
|
||||
- ret = s390_virtio_hypercall(env);
|
||||
-#endif /* CONFIG_S390_CCW_VIRTIO */
|
||||
- if (ret == -EINVAL) {
|
||||
- kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static void kvm_handle_diag_288(S390CPU *cpu, struct kvm_run *run)
|
||||
{
|
||||
uint64_t r1, r3;
|
||||
@@ -1603,9 +1587,11 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
|
||||
case DIAG_SET_CONTROL_PROGRAM_CODES:
|
||||
handle_diag_318(cpu, run);
|
||||
break;
|
||||
+#ifdef CONFIG_S390_CCW_VIRTIO
|
||||
case DIAG_KVM_HYPERCALL:
|
||||
- r = handle_hypercall(cpu, run);
|
||||
+ handle_diag_500(cpu, RA_IGNORED);
|
||||
break;
|
||||
+#endif /* CONFIG_S390_CCW_VIRTIO */
|
||||
case DIAG_KVM_BREAKPOINT:
|
||||
r = handle_sw_breakpoint(cpu, run);
|
||||
break;
|
||||
diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c
|
||||
index f44136a568..2b4310003b 100644
|
||||
--- a/target/s390x/tcg/misc_helper.c
|
||||
+++ b/target/s390x/tcg/misc_helper.c
|
||||
@@ -119,10 +119,11 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
|
||||
switch (num) {
|
||||
#ifdef CONFIG_S390_CCW_VIRTIO
|
||||
case 0x500:
|
||||
- /* KVM hypercall */
|
||||
+ /* QEMU/KVM hypercall */
|
||||
bql_lock();
|
||||
- r = s390_virtio_hypercall(env);
|
||||
+ handle_diag_500(env_archcpu(env), GETPC());
|
||||
bql_unlock();
|
||||
+ r = 0;
|
||||
break;
|
||||
#endif /* CONFIG_S390_CCW_VIRTIO */
|
||||
case 0x44:
|
||||
--
|
||||
2.48.1
|
||||
|
296
kvm-s390x-s390-virtio-hcall-remove-hypercall-registratio.patch
Normal file
296
kvm-s390x-s390-virtio-hcall-remove-hypercall-registratio.patch
Normal file
@ -0,0 +1,296 @@
|
||||
From 16ccb16d393a3e63936dc993c30c67fdecb1f120 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:03 +0100
|
||||
Subject: [PATCH 11/26] s390x/s390-virtio-hcall: remove hypercall registration
|
||||
mechanism
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [11/26] 5e8d2720fe9fd6e6e24487d71988821f1cf27f17 (thuth/qemu-kvm-cs)
|
||||
|
||||
Nowadays, we only have a single machine type in QEMU, everything is based
|
||||
on virtio-ccw and the traditional virtio machine does no longer exist. No
|
||||
need to dynamically register diag500 handlers. Move the two existing
|
||||
handlers into s390-virtio-hcall.c.
|
||||
|
||||
Message-ID: <20241219144115.2820241-3-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 4be0fce498d0a08f18b3a9accdb9ded79484d30a)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/s390x/meson.build | 6 ++--
|
||||
hw/s390x/s390-virtio-ccw.c | 58 ------------------------------
|
||||
hw/s390x/s390-virtio-hcall.c | 65 +++++++++++++++++++++++++---------
|
||||
hw/s390x/s390-virtio-hcall.h | 2 --
|
||||
target/s390x/kvm/kvm.c | 5 ++-
|
||||
target/s390x/tcg/misc_helper.c | 3 ++
|
||||
6 files changed, 60 insertions(+), 79 deletions(-)
|
||||
|
||||
diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build
|
||||
index 482fd13420..d6c8c33915 100644
|
||||
--- a/hw/s390x/meson.build
|
||||
+++ b/hw/s390x/meson.build
|
||||
@@ -12,7 +12,6 @@ s390x_ss.add(files(
|
||||
's390-pci-inst.c',
|
||||
's390-skeys.c',
|
||||
's390-stattrib.c',
|
||||
- 's390-virtio-hcall.c',
|
||||
'sclp.c',
|
||||
'sclpcpu.c',
|
||||
'sclpquiesce.c',
|
||||
@@ -28,7 +27,10 @@ s390x_ss.add(when: 'CONFIG_KVM', if_true: files(
|
||||
s390x_ss.add(when: 'CONFIG_TCG', if_true: files(
|
||||
'tod-tcg.c',
|
||||
))
|
||||
-s390x_ss.add(when: 'CONFIG_S390_CCW_VIRTIO', if_true: files('s390-virtio-ccw.c'))
|
||||
+s390x_ss.add(when: 'CONFIG_S390_CCW_VIRTIO', if_true: files(
|
||||
+ 's390-virtio-ccw.c',
|
||||
+ 's390-virtio-hcall.c',
|
||||
+))
|
||||
s390x_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('3270-ccw.c'))
|
||||
s390x_ss.add(when: 'CONFIG_VFIO', if_true: files('s390-pci-vfio.c'))
|
||||
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index 82ded9666c..d47e99028e 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -16,11 +16,8 @@
|
||||
#include "exec/ram_addr.h"
|
||||
#include "exec/confidential-guest-support.h"
|
||||
#include "hw/boards.h"
|
||||
-#include "hw/s390x/s390-virtio-hcall.h"
|
||||
#include "hw/s390x/sclp.h"
|
||||
#include "hw/s390x/s390_flic.h"
|
||||
-#include "hw/s390x/ioinst.h"
|
||||
-#include "hw/s390x/css.h"
|
||||
#include "virtio-ccw.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/ctype.h"
|
||||
@@ -124,58 +121,6 @@ static void subsystem_reset(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static int virtio_ccw_hcall_notify(const uint64_t *args)
|
||||
-{
|
||||
- uint64_t subch_id = args[0];
|
||||
- uint64_t data = args[1];
|
||||
- SubchDev *sch;
|
||||
- VirtIODevice *vdev;
|
||||
- int cssid, ssid, schid, m;
|
||||
- uint16_t vq_idx = data;
|
||||
-
|
||||
- if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- sch = css_find_subch(m, cssid, ssid, schid);
|
||||
- if (!sch || !css_subch_visible(sch)) {
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- vdev = virtio_ccw_get_vdev(sch);
|
||||
- if (vq_idx >= VIRTIO_QUEUE_MAX || !virtio_queue_get_num(vdev, vq_idx)) {
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
|
||||
- virtio_queue_set_shadow_avail_idx(virtio_get_queue(vdev, vq_idx),
|
||||
- (data >> 16) & 0xFFFF);
|
||||
- }
|
||||
-
|
||||
- virtio_queue_notify(vdev, vq_idx);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int virtio_ccw_hcall_early_printk(const uint64_t *args)
|
||||
-{
|
||||
- uint64_t mem = args[0];
|
||||
- MachineState *ms = MACHINE(qdev_get_machine());
|
||||
-
|
||||
- if (mem < ms->ram_size) {
|
||||
- /* Early printk */
|
||||
- return 0;
|
||||
- }
|
||||
- return -EINVAL;
|
||||
-}
|
||||
-
|
||||
-static void virtio_ccw_register_hcalls(void)
|
||||
-{
|
||||
- s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
|
||||
- virtio_ccw_hcall_notify);
|
||||
- /* Tolerate early printk. */
|
||||
- s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
|
||||
- virtio_ccw_hcall_early_printk);
|
||||
-}
|
||||
-
|
||||
static void s390_memory_init(MemoryRegion *ram)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
@@ -296,9 +241,6 @@ static void ccw_init(MachineState *machine)
|
||||
OBJECT(dev));
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
||||
|
||||
- /* register hypercalls */
|
||||
- virtio_ccw_register_hcalls();
|
||||
-
|
||||
s390_enable_css_support(s390_cpu_addr2state(0));
|
||||
|
||||
ret = css_create_css_image(VIRTUAL_CSSID, true);
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c
|
||||
index ec7cf8beb3..ca49e3cd22 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.c
|
||||
+++ b/hw/s390x/s390-virtio-hcall.c
|
||||
@@ -11,31 +11,64 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
+#include "hw/boards.h"
|
||||
#include "hw/s390x/s390-virtio-hcall.h"
|
||||
+#include "hw/s390x/ioinst.h"
|
||||
+#include "hw/s390x/css.h"
|
||||
+#include "virtio-ccw.h"
|
||||
|
||||
-#define MAX_DIAG_SUBCODES 255
|
||||
+static int handle_virtio_notify(uint64_t mem)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(qdev_get_machine());
|
||||
|
||||
-static s390_virtio_fn s390_diag500_table[MAX_DIAG_SUBCODES];
|
||||
+ if (mem < ms->ram_size) {
|
||||
+ /* Early printk */
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
|
||||
-void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn)
|
||||
+static int handle_virtio_ccw_notify(uint64_t subch_id, uint64_t data)
|
||||
{
|
||||
- assert(code < MAX_DIAG_SUBCODES);
|
||||
- assert(!s390_diag500_table[code]);
|
||||
+ SubchDev *sch;
|
||||
+ VirtIODevice *vdev;
|
||||
+ int cssid, ssid, schid, m;
|
||||
+ uint16_t vq_idx = data;
|
||||
+
|
||||
+ if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ sch = css_find_subch(m, cssid, ssid, schid);
|
||||
+ if (!sch || !css_subch_visible(sch)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- s390_diag500_table[code] = fn;
|
||||
+ vdev = virtio_ccw_get_vdev(sch);
|
||||
+ if (vq_idx >= VIRTIO_QUEUE_MAX || !virtio_queue_get_num(vdev, vq_idx)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (virtio_vdev_has_feature(vdev, VIRTIO_F_NOTIFICATION_DATA)) {
|
||||
+ virtio_queue_set_shadow_avail_idx(virtio_get_queue(vdev, vq_idx),
|
||||
+ (data >> 16) & 0xFFFF);
|
||||
+ }
|
||||
+
|
||||
+ virtio_queue_notify(vdev, vq_idx);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int s390_virtio_hypercall(CPUS390XState *env)
|
||||
{
|
||||
- s390_virtio_fn fn;
|
||||
-
|
||||
- if (env->regs[1] < MAX_DIAG_SUBCODES) {
|
||||
- fn = s390_diag500_table[env->regs[1]];
|
||||
- if (fn) {
|
||||
- env->regs[2] = fn(&env->regs[2]);
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
+ const uint64_t subcode = env->regs[1];
|
||||
|
||||
- return -EINVAL;
|
||||
+ switch (subcode) {
|
||||
+ case KVM_S390_VIRTIO_NOTIFY:
|
||||
+ env->regs[2] = handle_virtio_notify(env->regs[2]);
|
||||
+ return 0;
|
||||
+ case KVM_S390_VIRTIO_CCW_NOTIFY:
|
||||
+ env->regs[2] = handle_virtio_ccw_notify(env->regs[2], env->regs[3]);
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
diff --git a/hw/s390x/s390-virtio-hcall.h b/hw/s390x/s390-virtio-hcall.h
|
||||
index 3ae6d6ae3a..3d9fe147d2 100644
|
||||
--- a/hw/s390x/s390-virtio-hcall.h
|
||||
+++ b/hw/s390x/s390-virtio-hcall.h
|
||||
@@ -18,8 +18,6 @@
|
||||
/* The only thing that we need from the old kvm_virtio.h file */
|
||||
#define KVM_S390_VIRTIO_NOTIFY 0
|
||||
|
||||
-typedef int (*s390_virtio_fn)(const uint64_t *args);
|
||||
-void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
|
||||
int s390_virtio_hypercall(CPUS390XState *env);
|
||||
|
||||
#endif /* HW_S390_VIRTIO_HCALL_H */
|
||||
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
|
||||
index 7a0ca5570f..5947dda829 100644
|
||||
--- a/target/s390x/kvm/kvm.c
|
||||
+++ b/target/s390x/kvm/kvm.c
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "hw/s390x/s390-virtio-ccw.h"
|
||||
#include "hw/s390x/s390-virtio-hcall.h"
|
||||
#include "target/s390x/kvm/pv.h"
|
||||
+#include CONFIG_DEVICES
|
||||
|
||||
#define kvm_vm_check_mem_attr(s, attr) \
|
||||
kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr)
|
||||
@@ -1494,9 +1495,11 @@ static int handle_e3(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl)
|
||||
static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
|
||||
{
|
||||
CPUS390XState *env = &cpu->env;
|
||||
- int ret;
|
||||
+ int ret = -EINVAL;
|
||||
|
||||
+#ifdef CONFIG_S390_CCW_VIRTIO
|
||||
ret = s390_virtio_hypercall(env);
|
||||
+#endif /* CONFIG_S390_CCW_VIRTIO */
|
||||
if (ret == -EINVAL) {
|
||||
kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
|
||||
return 0;
|
||||
diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c
|
||||
index 303f86d363..f44136a568 100644
|
||||
--- a/target/s390x/tcg/misc_helper.c
|
||||
+++ b/target/s390x/tcg/misc_helper.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "hw/s390x/s390-pci-inst.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/s390x/tod.h"
|
||||
+#include CONFIG_DEVICES
|
||||
#endif
|
||||
|
||||
/* #define DEBUG_HELPER */
|
||||
@@ -116,12 +117,14 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
|
||||
uint64_t r;
|
||||
|
||||
switch (num) {
|
||||
+#ifdef CONFIG_S390_CCW_VIRTIO
|
||||
case 0x500:
|
||||
/* KVM hypercall */
|
||||
bql_lock();
|
||||
r = s390_virtio_hypercall(env);
|
||||
bql_unlock();
|
||||
break;
|
||||
+#endif /* CONFIG_S390_CCW_VIRTIO */
|
||||
case 0x44:
|
||||
/* yield */
|
||||
r = 0;
|
||||
--
|
||||
2.48.1
|
||||
|
423
kvm-s390x-virtio-ccw-add-support-for-virtio-based-memory.patch
Normal file
423
kvm-s390x-virtio-ccw-add-support-for-virtio-based-memory.patch
Normal file
@ -0,0 +1,423 @@
|
||||
From 6b82fca2ecac0c7b30780ebb71ce5bad0421b9b4 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:14 +0100
|
||||
Subject: [PATCH 22/26] s390x/virtio-ccw: add support for virtio based memory
|
||||
devices
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [22/26] 270a9fbe7e5bacfa6c9377815a01da26c4d26097 (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's implement support for abstract virtio based memory devices, using
|
||||
the virtio-pci implementation as an orientation. Wire them up in the
|
||||
machine hotplug handler, taking care of s390x page size limitations.
|
||||
|
||||
As we neither support virtio-mem or virtio-pmem yet, the code is
|
||||
effectively unused. We'll implement support for virtio-mem based on this
|
||||
next.
|
||||
|
||||
Note that we won't wire up the virtio-pci variant (should currently be
|
||||
impossible due to lack of support for MSI-X), but we'll add a safety net
|
||||
to reject plugging them in the pre-plug handler.
|
||||
|
||||
Message-ID: <20241219144115.2820241-14-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 88d86f6f1e36741ba9e1625da19a7ccf1a343d39)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
MAINTAINERS | 3 +
|
||||
hw/s390x/meson.build | 3 +
|
||||
hw/s390x/s390-virtio-ccw.c | 47 +++++++++-
|
||||
hw/s390x/virtio-ccw-md-stubs.c | 24 ++++++
|
||||
hw/s390x/virtio-ccw-md.c | 153 +++++++++++++++++++++++++++++++++
|
||||
hw/s390x/virtio-ccw-md.h | 44 ++++++++++
|
||||
hw/virtio/Kconfig | 1 +
|
||||
7 files changed, 274 insertions(+), 1 deletion(-)
|
||||
create mode 100644 hw/s390x/virtio-ccw-md-stubs.c
|
||||
create mode 100644 hw/s390x/virtio-ccw-md.c
|
||||
create mode 100644 hw/s390x/virtio-ccw-md.h
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 3584d6a6c6..f21dc3fa75 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -2387,6 +2387,9 @@ F: include/hw/virtio/virtio-crypto.h
|
||||
virtio based memory device
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
S: Supported
|
||||
+F: hw/s390x/virtio-ccw-md.c
|
||||
+F: hw/s390x/virtio-ccw-md.h
|
||||
+F: hw/s390x/virtio-ccw-md-stubs.c
|
||||
F: hw/virtio/virtio-md-pci.c
|
||||
F: include/hw/virtio/virtio-md-pci.h
|
||||
F: stubs/virtio-md-pci.c
|
||||
diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build
|
||||
index e344a3bd8c..4431868408 100644
|
||||
--- a/hw/s390x/meson.build
|
||||
+++ b/hw/s390x/meson.build
|
||||
@@ -50,8 +50,11 @@ endif
|
||||
virtio_ss.add(when: 'CONFIG_VHOST_SCSI', if_true: files('vhost-scsi-ccw.c'))
|
||||
virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-ccw.c'))
|
||||
virtio_ss.add(when: 'CONFIG_VHOST_USER_FS', if_true: files('vhost-user-fs-ccw.c'))
|
||||
+virtio_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-ccw-md.c'))
|
||||
s390x_ss.add_all(when: 'CONFIG_VIRTIO_CCW', if_true: virtio_ss)
|
||||
|
||||
+s390x_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio-ccw-md-stubs.c'))
|
||||
+
|
||||
hw_arch += {'s390x': s390x_ss}
|
||||
|
||||
hw_s390x_modules = {}
|
||||
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
|
||||
index bd05a22b4e..9f4ad01789 100644
|
||||
--- a/hw/s390x/s390-virtio-ccw.c
|
||||
+++ b/hw/s390x/s390-virtio-ccw.c
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/s390x/cpu-topology.h"
|
||||
#include "kvm/kvm_s390x.h"
|
||||
+#include "hw/virtio/virtio-md-pci.h"
|
||||
+#include "hw/s390x/virtio-ccw-md.h"
|
||||
#include CONFIG_DEVICES
|
||||
|
||||
static Error *pv_mig_blocker;
|
||||
@@ -546,11 +548,39 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
|
||||
s390_ipl_clear_reset_request();
|
||||
}
|
||||
|
||||
+static void s390_machine_device_pre_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
|
||||
+ virtio_ccw_md_pre_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
|
||||
+ error_setg(errp,
|
||||
+ "PCI-attached virtio based memory devices not supported");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
+ S390CcwMachineState *s390ms = S390_CCW_MACHINE(hotplug_dev);
|
||||
+
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
s390_cpu_plug(hotplug_dev, dev, errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
|
||||
+ /*
|
||||
+ * At this point, the device is realized and set all memdevs mapped, so
|
||||
+ * qemu_maxrampagesize() will pick up the page sizes of these memdevs
|
||||
+ * as well. Before we plug the device and expose any RAM memory regions
|
||||
+ * to the system, make sure we don't exceed the previously set max page
|
||||
+ * size. While only relevant for KVM, there is not really any use case
|
||||
+ * for this with TCG, so we'll unconditionally reject it.
|
||||
+ */
|
||||
+ if (qemu_maxrampagesize() != s390ms->max_pagesize) {
|
||||
+ error_setg(errp, "Memory device uses a bigger page size than"
|
||||
+ " initial memory");
|
||||
+ return;
|
||||
+ }
|
||||
+ virtio_ccw_md_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,9 +590,20 @@ static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
error_setg(errp, "CPU hot unplug not supported on this machine");
|
||||
return;
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
|
||||
+ virtio_ccw_md_unplug_request(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev),
|
||||
+ errp);
|
||||
}
|
||||
}
|
||||
|
||||
+static void s390_machine_device_unplug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
|
||||
+ virtio_ccw_md_unplug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
|
||||
unsigned cpu_index)
|
||||
{
|
||||
@@ -609,7 +650,9 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
|
||||
static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
|
||||
DeviceState *dev)
|
||||
{
|
||||
- if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
|
||||
+ if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) ||
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW) ||
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
}
|
||||
return NULL;
|
||||
@@ -769,8 +812,10 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
|
||||
/* it is overridden with 'host' cpu *in kvm_arch_init* */
|
||||
mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu");
|
||||
+ hc->pre_plug = s390_machine_device_pre_plug;
|
||||
hc->plug = s390_machine_device_plug;
|
||||
hc->unplug_request = s390_machine_device_unplug_request;
|
||||
+ hc->unplug = s390_machine_device_unplug;
|
||||
nc->nmi_monitor_handler = s390_nmi;
|
||||
mc->default_ram_id = "s390.ram";
|
||||
mc->default_nic = "virtio-net-ccw";
|
||||
diff --git a/hw/s390x/virtio-ccw-md-stubs.c b/hw/s390x/virtio-ccw-md-stubs.c
|
||||
new file mode 100644
|
||||
index 0000000000..e937865550
|
||||
--- /dev/null
|
||||
+++ b/hw/s390x/virtio-ccw-md-stubs.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "hw/s390x/virtio-ccw-md.h"
|
||||
+
|
||||
+void virtio_ccw_md_pre_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ error_setg(errp, "virtio based memory devices not supported");
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ error_setg(errp, "virtio based memory devices not supported");
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ error_setg(errp, "virtio based memory devices not supported");
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_unplug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ error_setg(errp, "virtio based memory devices not supported");
|
||||
+}
|
||||
diff --git a/hw/s390x/virtio-ccw-md.c b/hw/s390x/virtio-ccw-md.c
|
||||
new file mode 100644
|
||||
index 0000000000..de333282df
|
||||
--- /dev/null
|
||||
+++ b/hw/s390x/virtio-ccw-md.c
|
||||
@@ -0,0 +1,153 @@
|
||||
+/*
|
||||
+ * Virtio CCW support for abstract virtio based memory device
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * David Hildenbrand <david@redhat.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/s390x/virtio-ccw-md.h"
|
||||
+#include "hw/mem/memory-device.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+void virtio_ccw_md_pre_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ DeviceState *dev = DEVICE(vmd);
|
||||
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
|
||||
+ MemoryDeviceState *md = MEMORY_DEVICE(vmd);
|
||||
+ Error *local_err = NULL;
|
||||
+
|
||||
+ if (!bus_handler && dev->hotplugged) {
|
||||
+ /*
|
||||
+ * Without a bus hotplug handler, we cannot control the plug/unplug
|
||||
+ * order. We should never reach this point when hotplugging, but
|
||||
+ * better add a safety net.
|
||||
+ */
|
||||
+ error_setg(errp, "hotplug of virtio based memory devices not supported"
|
||||
+ " on this bus.");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * First, see if we can plug this memory device at all. If that
|
||||
+ * succeeds, branch of to the actual hotplug handler.
|
||||
+ */
|
||||
+ memory_device_pre_plug(md, ms, &local_err);
|
||||
+ if (!local_err && bus_handler) {
|
||||
+ hotplug_handler_pre_plug(bus_handler, dev, &local_err);
|
||||
+ }
|
||||
+ error_propagate(errp, local_err);
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ DeviceState *dev = DEVICE(vmd);
|
||||
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
|
||||
+ MemoryDeviceState *md = MEMORY_DEVICE(vmd);
|
||||
+ Error *local_err = NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * Plug the memory device first and then branch off to the actual
|
||||
+ * hotplug handler. If that one fails, we can easily undo the memory
|
||||
+ * device bits.
|
||||
+ */
|
||||
+ memory_device_plug(md, ms);
|
||||
+ if (bus_handler) {
|
||||
+ hotplug_handler_plug(bus_handler, dev, &local_err);
|
||||
+ if (local_err) {
|
||||
+ memory_device_unplug(md, ms);
|
||||
+ }
|
||||
+ }
|
||||
+ error_propagate(errp, local_err);
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ VirtIOMDCcwClass *vmdc = VIRTIO_MD_CCW_GET_CLASS(vmd);
|
||||
+ DeviceState *dev = DEVICE(vmd);
|
||||
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
|
||||
+ HotplugHandlerClass *hdc;
|
||||
+ Error *local_err = NULL;
|
||||
+
|
||||
+ if (!vmdc->unplug_request_check) {
|
||||
+ error_setg(errp,
|
||||
+ "this virtio based memory devices cannot be unplugged");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!bus_handler) {
|
||||
+ error_setg(errp, "hotunplug of virtio based memory devices not"
|
||||
+ "supported on this bus");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ vmdc->unplug_request_check(vmd, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Forward the async request or turn it into a sync request (handling it
|
||||
+ * like qdev_unplug()).
|
||||
+ */
|
||||
+ hdc = HOTPLUG_HANDLER_GET_CLASS(bus_handler);
|
||||
+ if (hdc->unplug_request) {
|
||||
+ hotplug_handler_unplug_request(bus_handler, dev, &local_err);
|
||||
+ } else {
|
||||
+ virtio_ccw_md_unplug(vmd, ms, &local_err);
|
||||
+ if (!local_err) {
|
||||
+ object_unparent(OBJECT(dev));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void virtio_ccw_md_unplug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)
|
||||
+{
|
||||
+ DeviceState *dev = DEVICE(vmd);
|
||||
+ HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
|
||||
+ MemoryDeviceState *md = MEMORY_DEVICE(vmd);
|
||||
+ Error *local_err = NULL;
|
||||
+
|
||||
+ /* Unplug the memory device while it is still realized. */
|
||||
+ memory_device_unplug(md, ms);
|
||||
+
|
||||
+ if (bus_handler) {
|
||||
+ hotplug_handler_unplug(bus_handler, dev, &local_err);
|
||||
+ if (local_err) {
|
||||
+ /* Not expected to fail ... but still try to recover. */
|
||||
+ memory_device_plug(md, ms);
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* Very unexpected, but let's just try to do the right thing. */
|
||||
+ warn_report("Unexpected unplug of virtio based memory device");
|
||||
+ qdev_unrealize(dev);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo virtio_ccw_md_info = {
|
||||
+ .name = TYPE_VIRTIO_MD_CCW,
|
||||
+ .parent = TYPE_VIRTIO_CCW_DEVICE,
|
||||
+ .instance_size = sizeof(VirtIOMDCcw),
|
||||
+ .class_size = sizeof(VirtIOMDCcwClass),
|
||||
+ .abstract = true,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_MEMORY_DEVICE },
|
||||
+ { }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static void virtio_ccw_md_register(void)
|
||||
+{
|
||||
+ type_register_static(&virtio_ccw_md_info);
|
||||
+}
|
||||
+type_init(virtio_ccw_md_register)
|
||||
diff --git a/hw/s390x/virtio-ccw-md.h b/hw/s390x/virtio-ccw-md.h
|
||||
new file mode 100644
|
||||
index 0000000000..39ba864c92
|
||||
--- /dev/null
|
||||
+++ b/hw/s390x/virtio-ccw-md.h
|
||||
@@ -0,0 +1,44 @@
|
||||
+/*
|
||||
+ * Virtio CCW support for abstract virtio based memory device
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * David Hildenbrand <david@redhat.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#ifndef HW_S390X_VIRTIO_CCW_MD_H
|
||||
+#define HW_S390X_VIRTIO_CCW_MD_H
|
||||
+
|
||||
+#include "virtio-ccw.h"
|
||||
+#include "qom/object.h"
|
||||
+
|
||||
+/*
|
||||
+ * virtio-md-ccw: This extends VirtioCcwDevice.
|
||||
+ */
|
||||
+#define TYPE_VIRTIO_MD_CCW "virtio-md-ccw"
|
||||
+
|
||||
+OBJECT_DECLARE_TYPE(VirtIOMDCcw, VirtIOMDCcwClass, VIRTIO_MD_CCW)
|
||||
+
|
||||
+struct VirtIOMDCcwClass {
|
||||
+ /* private */
|
||||
+ VirtIOCCWDeviceClass parent;
|
||||
+
|
||||
+ /* public */
|
||||
+ void (*unplug_request_check)(VirtIOMDCcw *vmd, Error **errp);
|
||||
+};
|
||||
+
|
||||
+struct VirtIOMDCcw {
|
||||
+ VirtioCcwDevice parent_obj;
|
||||
+};
|
||||
+
|
||||
+void virtio_ccw_md_pre_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp);
|
||||
+void virtio_ccw_md_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp);
|
||||
+void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms,
|
||||
+ Error **errp);
|
||||
+void virtio_ccw_md_unplug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp);
|
||||
+
|
||||
+#endif /* HW_S390X_VIRTIO_CCW_MD_H */
|
||||
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
|
||||
index 0afec2ae92..f4b14e1a44 100644
|
||||
--- a/hw/virtio/Kconfig
|
||||
+++ b/hw/virtio/Kconfig
|
||||
@@ -25,6 +25,7 @@ config VIRTIO_MMIO
|
||||
config VIRTIO_CCW
|
||||
bool
|
||||
select VIRTIO
|
||||
+ select VIRTIO_MD_SUPPORTED
|
||||
|
||||
config VIRTIO_BALLOON
|
||||
bool
|
||||
--
|
||||
2.48.1
|
||||
|
459
kvm-s390x-virtio-mem-support.patch
Normal file
459
kvm-s390x-virtio-mem-support.patch
Normal file
@ -0,0 +1,459 @@
|
||||
From fa68427f55bee8d18d846e03ebf9f1eeb80f274d Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Thu, 19 Dec 2024 15:41:15 +0100
|
||||
Subject: [PATCH 23/26] s390x: virtio-mem support
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [23/26] 4c59ba9025ce5ba7686a7f3e01bb70e8c580709f (thuth/qemu-kvm-cs)
|
||||
|
||||
Let's add our virtio-mem-ccw proxy device and wire it up. We should
|
||||
be supporting everything (e.g., device unplug, "dynamic-memslots") that
|
||||
we already support for the virtio-pci variant.
|
||||
|
||||
With a Linux guest that supports virtio-mem (and has automatic memory
|
||||
onlining properly configured) the following example will work:
|
||||
|
||||
1. Start a VM with 4G initial memory and a virtio-mem device with a maximum
|
||||
capacity of 16GB:
|
||||
|
||||
qemu/build/qemu-system-s390x \
|
||||
--enable-kvm \
|
||||
-m 4G,maxmem=20G \
|
||||
-nographic \
|
||||
-smp 8 \
|
||||
-hda Fedora-Server-KVM-40-1.14.s390x.qcow2 \
|
||||
-chardev socket,id=monitor,path=/var/tmp/monitor,server,nowait \
|
||||
-mon chardev=monitor,mode=readline \
|
||||
-object memory-backend-ram,id=mem0,size=16G,reserve=off \
|
||||
-device virtio-mem-ccw,id=vmem0,memdev=mem0,dynamic-memslots=on
|
||||
|
||||
2. Query the current size of virtio-mem device:
|
||||
|
||||
(qemu) info memory-devices
|
||||
Memory device [virtio-mem]: "vmem0"
|
||||
memaddr: 0x100000000
|
||||
node: 0
|
||||
requested-size: 0
|
||||
size: 0
|
||||
max-size: 17179869184
|
||||
block-size: 1048576
|
||||
memdev: /objects/mem0
|
||||
|
||||
3. Request to grow it to 8GB (hotplug 8GB):
|
||||
|
||||
(qemu) qom-set vmem0 requested-size 8G
|
||||
(qemu) info memory-devices
|
||||
Memory device [virtio-mem]: "vmem0"
|
||||
memaddr: 0x100000000
|
||||
node: 0
|
||||
requested-size: 8589934592
|
||||
size: 8589934592
|
||||
max-size: 17179869184
|
||||
block-size: 1048576
|
||||
memdev: /objects/mem0
|
||||
|
||||
4. Request to grow to 16GB (hotplug another 8GB):
|
||||
|
||||
(qemu) qom-set vmem0 requested-size 16G
|
||||
(qemu) info memory-devices
|
||||
Memory device [virtio-mem]: "vmem0"
|
||||
memaddr: 0x100000000
|
||||
node: 0
|
||||
requested-size: 17179869184
|
||||
size: 17179869184
|
||||
max-size: 17179869184
|
||||
block-size: 1048576
|
||||
memdev: /objects/mem0
|
||||
|
||||
5. Try to hotunplug all memory again, shrinking to 0GB:
|
||||
|
||||
(qemu) qom-set vmem0 requested-size 0G
|
||||
(qemu) info memory-devices
|
||||
Memory device [virtio-mem]: "vmem0"
|
||||
memaddr: 0x100000000
|
||||
node: 0
|
||||
requested-size: 0
|
||||
size: 0
|
||||
max-size: 17179869184
|
||||
block-size: 1048576
|
||||
memdev: /objects/mem0
|
||||
|
||||
6. If it worked, unplug the device
|
||||
|
||||
(qemu) device_del vmem0
|
||||
(qemu) info memory-devices
|
||||
(qemu) object_del mem0
|
||||
|
||||
7. Hotplug a new device with a smaller capacity and directly size it to 1GB
|
||||
|
||||
(qemu) object_add memory-backend-ram,id=mem0,size=8G,reserve=off
|
||||
(qemu) device_add virtio-mem-ccw,id=vmem0,memdev=mem0,\
|
||||
dynamic-memslots=on,requested-size=1G
|
||||
(qemu) info memory-devices
|
||||
Memory device [virtio-mem]: "vmem0"
|
||||
memaddr: 0x100000000
|
||||
node: 0
|
||||
requested-size: 1073741824
|
||||
size: 1073741824
|
||||
max-size: 8589934592
|
||||
block-size: 1048576
|
||||
memdev: /objects/mem0
|
||||
|
||||
Trying to use a virtio-mem device backed by hugetlb into a !hugetlb VM
|
||||
correctly results in the error:
|
||||
... Memory device uses a bigger page size than initial memory
|
||||
|
||||
Note that the virtio-mem driver in Linux will supports 1 MiB (pageblock)
|
||||
granularity.
|
||||
|
||||
Message-ID: <20241219144115.2820241-15-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit aa910c20ec5f3b10551da19e441b3e2b54406e25)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
MAINTAINERS | 2 +
|
||||
hw/s390x/Kconfig | 1 +
|
||||
hw/s390x/meson.build | 1 +
|
||||
hw/s390x/virtio-ccw-mem.c | 226 ++++++++++++++++++++++++++++++++++++++
|
||||
hw/s390x/virtio-ccw-mem.h | 34 ++++++
|
||||
hw/virtio/virtio-mem.c | 4 +-
|
||||
6 files changed, 267 insertions(+), 1 deletion(-)
|
||||
create mode 100644 hw/s390x/virtio-ccw-mem.c
|
||||
create mode 100644 hw/s390x/virtio-ccw-mem.h
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index f21dc3fa75..f7b7ceffc4 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -2401,6 +2401,8 @@ W: https://virtio-mem.gitlab.io/
|
||||
F: hw/virtio/virtio-mem.c
|
||||
F: hw/virtio/virtio-mem-pci.h
|
||||
F: hw/virtio/virtio-mem-pci.c
|
||||
+F: hw/s390x/virtio-ccw-mem.c
|
||||
+F: hw/s390x/virtio-ccw-mem.h
|
||||
F: include/hw/virtio/virtio-mem.h
|
||||
|
||||
virtio-snd
|
||||
diff --git a/hw/s390x/Kconfig b/hw/s390x/Kconfig
|
||||
index 3bbf4ae56e..5d57daff77 100644
|
||||
--- a/hw/s390x/Kconfig
|
||||
+++ b/hw/s390x/Kconfig
|
||||
@@ -15,3 +15,4 @@ config S390_CCW_VIRTIO
|
||||
select SCLPCONSOLE
|
||||
select VIRTIO_CCW
|
||||
select MSI_NONBROKEN
|
||||
+ select VIRTIO_MEM_SUPPORTED
|
||||
diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build
|
||||
index 4431868408..3bbebfd817 100644
|
||||
--- a/hw/s390x/meson.build
|
||||
+++ b/hw/s390x/meson.build
|
||||
@@ -51,6 +51,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_SCSI', if_true: files('vhost-scsi-ccw.c'))
|
||||
virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-ccw.c'))
|
||||
virtio_ss.add(when: 'CONFIG_VHOST_USER_FS', if_true: files('vhost-user-fs-ccw.c'))
|
||||
virtio_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-ccw-md.c'))
|
||||
+virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-ccw-mem.c'))
|
||||
s390x_ss.add_all(when: 'CONFIG_VIRTIO_CCW', if_true: virtio_ss)
|
||||
|
||||
s390x_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio-ccw-md-stubs.c'))
|
||||
diff --git a/hw/s390x/virtio-ccw-mem.c b/hw/s390x/virtio-ccw-mem.c
|
||||
new file mode 100644
|
||||
index 0000000000..bee0d560cb
|
||||
--- /dev/null
|
||||
+++ b/hw/s390x/virtio-ccw-mem.c
|
||||
@@ -0,0 +1,226 @@
|
||||
+/*
|
||||
+ * virtio-mem CCW implementation
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * David Hildenbrand <david@redhat.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "virtio-ccw-mem.h"
|
||||
+#include "hw/mem/memory-device.h"
|
||||
+#include "qapi/qapi-events-machine.h"
|
||||
+#include "qapi/qapi-events-misc.h"
|
||||
+
|
||||
+static void virtio_ccw_mem_realize(VirtioCcwDevice *ccw_dev, Error **errp)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(ccw_dev);
|
||||
+ DeviceState *vdev = DEVICE(&dev->vdev);
|
||||
+
|
||||
+ qdev_realize(vdev, BUS(&ccw_dev->bus), errp);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_set_addr(MemoryDeviceState *md, uint64_t addr,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ object_property_set_uint(OBJECT(md), VIRTIO_MEM_ADDR_PROP, addr, errp);
|
||||
+}
|
||||
+
|
||||
+static uint64_t virtio_ccw_mem_get_addr(const MemoryDeviceState *md)
|
||||
+{
|
||||
+ return object_property_get_uint(OBJECT(md), VIRTIO_MEM_ADDR_PROP,
|
||||
+ &error_abort);
|
||||
+}
|
||||
+
|
||||
+static MemoryRegion *virtio_ccw_mem_get_memory_region(MemoryDeviceState *md,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(md);
|
||||
+ VirtIOMEM *vmem = &dev->vdev;
|
||||
+ VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+
|
||||
+ return vmc->get_memory_region(vmem, errp);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_decide_memslots(MemoryDeviceState *md,
|
||||
+ unsigned int limit)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(md);
|
||||
+ VirtIOMEM *vmem = VIRTIO_MEM(&dev->vdev);
|
||||
+ VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+
|
||||
+ vmc->decide_memslots(vmem, limit);
|
||||
+}
|
||||
+
|
||||
+static unsigned int virtio_ccw_mem_get_memslots(MemoryDeviceState *md)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(md);
|
||||
+ VirtIOMEM *vmem = VIRTIO_MEM(&dev->vdev);
|
||||
+ VirtIOMEMClass *vmc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+
|
||||
+ return vmc->get_memslots(vmem);
|
||||
+}
|
||||
+
|
||||
+static uint64_t virtio_ccw_mem_get_plugged_size(const MemoryDeviceState *md,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ return object_property_get_uint(OBJECT(md), VIRTIO_MEM_SIZE_PROP,
|
||||
+ errp);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_fill_device_info(const MemoryDeviceState *md,
|
||||
+ MemoryDeviceInfo *info)
|
||||
+{
|
||||
+ VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1);
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(md);
|
||||
+ VirtIOMEM *vmem = &dev->vdev;
|
||||
+ VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+ DeviceState *vdev = DEVICE(md);
|
||||
+
|
||||
+ if (vdev->id) {
|
||||
+ vi->id = g_strdup(vdev->id);
|
||||
+ }
|
||||
+
|
||||
+ /* let the real device handle everything else */
|
||||
+ vpc->fill_device_info(vmem, vi);
|
||||
+
|
||||
+ info->u.virtio_mem.data = vi;
|
||||
+ info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM;
|
||||
+}
|
||||
+
|
||||
+static uint64_t virtio_ccw_mem_get_min_alignment(const MemoryDeviceState *md)
|
||||
+{
|
||||
+ return object_property_get_uint(OBJECT(md), VIRTIO_MEM_BLOCK_SIZE_PROP,
|
||||
+ &error_abort);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_size_change_notify(Notifier *notifier, void *data)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = container_of(notifier, VirtIOMEMCcw,
|
||||
+ size_change_notifier);
|
||||
+ DeviceState *vdev = DEVICE(dev);
|
||||
+ char *qom_path = object_get_canonical_path(OBJECT(dev));
|
||||
+ const uint64_t * const size_p = data;
|
||||
+
|
||||
+ qapi_event_send_memory_device_size_change(vdev->id, *size_p, qom_path);
|
||||
+ g_free(qom_path);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_unplug_request_check(VirtIOMDCcw *vmd, Error **errp)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(vmd);
|
||||
+ VirtIOMEM *vmem = &dev->vdev;
|
||||
+ VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+
|
||||
+ vpc->unplug_request_check(vmem, errp);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_get_requested_size(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(obj);
|
||||
+
|
||||
+ object_property_get(OBJECT(&dev->vdev), name, v, errp);
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_set_requested_size(Object *obj, Visitor *v,
|
||||
+ const char *name, void *opaque,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(obj);
|
||||
+ DeviceState *vdev = DEVICE(obj);
|
||||
+
|
||||
+ /*
|
||||
+ * If we passed virtio_ccw_mem_unplug_request_check(), making sure that
|
||||
+ * the requested size is 0, don't allow modifying the requested size
|
||||
+ * anymore, otherwise the VM might end up hotplugging memory before
|
||||
+ * handling the unplug request.
|
||||
+ */
|
||||
+ if (vdev->pending_deleted_event) {
|
||||
+ error_setg(errp, "'%s' cannot be changed if the device is in the"
|
||||
+ " process of unplug", name);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ object_property_set(OBJECT(&dev->vdev), name, v, errp);
|
||||
+}
|
||||
+
|
||||
+static Property virtio_ccw_mem_properties[] = {
|
||||
+ DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||
+ VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||
+ DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev,
|
||||
+ VIRTIO_CCW_MAX_REV),
|
||||
+ DEFINE_PROP_END_OF_LIST(),
|
||||
+};
|
||||
+
|
||||
+static void virtio_ccw_mem_class_init(ObjectClass *klass, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
+ VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
|
||||
+ MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(klass);
|
||||
+ VirtIOMDCcwClass *vmdc = VIRTIO_MD_CCW_CLASS(klass);
|
||||
+
|
||||
+ k->realize = virtio_ccw_mem_realize;
|
||||
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
+ device_class_set_props(dc, virtio_ccw_mem_properties);
|
||||
+
|
||||
+ mdc->get_addr = virtio_ccw_mem_get_addr;
|
||||
+ mdc->set_addr = virtio_ccw_mem_set_addr;
|
||||
+ mdc->get_plugged_size = virtio_ccw_mem_get_plugged_size;
|
||||
+ mdc->get_memory_region = virtio_ccw_mem_get_memory_region;
|
||||
+ mdc->decide_memslots = virtio_ccw_mem_decide_memslots;
|
||||
+ mdc->get_memslots = virtio_ccw_mem_get_memslots;
|
||||
+ mdc->fill_device_info = virtio_ccw_mem_fill_device_info;
|
||||
+ mdc->get_min_alignment = virtio_ccw_mem_get_min_alignment;
|
||||
+
|
||||
+ vmdc->unplug_request_check = virtio_ccw_mem_unplug_request_check;
|
||||
+}
|
||||
+
|
||||
+static void virtio_ccw_mem_instance_init(Object *obj)
|
||||
+{
|
||||
+ VirtIOMEMCcw *dev = VIRTIO_MEM_CCW(obj);
|
||||
+ VirtIOMEMClass *vmc;
|
||||
+ VirtIOMEM *vmem;
|
||||
+
|
||||
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||
+ TYPE_VIRTIO_MEM);
|
||||
+
|
||||
+ dev->size_change_notifier.notify = virtio_ccw_mem_size_change_notify;
|
||||
+ vmem = &dev->vdev;
|
||||
+ vmc = VIRTIO_MEM_GET_CLASS(vmem);
|
||||
+ /*
|
||||
+ * We never remove the notifier again, as we expect both devices to
|
||||
+ * disappear at the same time.
|
||||
+ */
|
||||
+ vmc->add_size_change_notifier(vmem, &dev->size_change_notifier);
|
||||
+
|
||||
+ object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP,
|
||||
+ OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
|
||||
+ object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),
|
||||
+ VIRTIO_MEM_SIZE_PROP);
|
||||
+ object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
|
||||
+ virtio_ccw_mem_get_requested_size,
|
||||
+ virtio_ccw_mem_set_requested_size, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo virtio_ccw_mem = {
|
||||
+ .name = TYPE_VIRTIO_MEM_CCW,
|
||||
+ .parent = TYPE_VIRTIO_MD_CCW,
|
||||
+ .instance_size = sizeof(VirtIOMEMCcw),
|
||||
+ .instance_init = virtio_ccw_mem_instance_init,
|
||||
+ .class_init = virtio_ccw_mem_class_init,
|
||||
+};
|
||||
+
|
||||
+static void virtio_ccw_mem_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&virtio_ccw_mem);
|
||||
+}
|
||||
+type_init(virtio_ccw_mem_register_types)
|
||||
diff --git a/hw/s390x/virtio-ccw-mem.h b/hw/s390x/virtio-ccw-mem.h
|
||||
new file mode 100644
|
||||
index 0000000000..738ab2c744
|
||||
--- /dev/null
|
||||
+++ b/hw/s390x/virtio-ccw-mem.h
|
||||
@@ -0,0 +1,34 @@
|
||||
+/*
|
||||
+ * Virtio MEM CCW device
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * David Hildenbrand <david@redhat.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ */
|
||||
+
|
||||
+#ifndef HW_S390X_VIRTIO_CCW_MEM_H
|
||||
+#define HW_S390X_VIRTIO_CCW_MEM_H
|
||||
+
|
||||
+#include "virtio-ccw-md.h"
|
||||
+#include "hw/virtio/virtio-mem.h"
|
||||
+#include "qom/object.h"
|
||||
+
|
||||
+typedef struct VirtIOMEMCcw VirtIOMEMCcw;
|
||||
+
|
||||
+/*
|
||||
+ * virtio-mem-ccw: This extends VirtIOMDCcw
|
||||
+ */
|
||||
+#define TYPE_VIRTIO_MEM_CCW "virtio-mem-ccw"
|
||||
+DECLARE_INSTANCE_CHECKER(VirtIOMEMCcw, VIRTIO_MEM_CCW, TYPE_VIRTIO_MEM_CCW)
|
||||
+
|
||||
+struct VirtIOMEMCcw {
|
||||
+ VirtIOMDCcw parent_obj;
|
||||
+ VirtIOMEM vdev;
|
||||
+ Notifier size_change_notifier;
|
||||
+};
|
||||
+
|
||||
+#endif /* HW_S390X_VIRTIO_CCW_MEM_H */
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index 00da98b6e1..c9f8a23bbc 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -61,6 +61,8 @@ static uint32_t virtio_mem_default_thp_size(void)
|
||||
} else if (qemu_real_host_page_size() == 64 * KiB) {
|
||||
default_thp_size = 512 * MiB;
|
||||
}
|
||||
+#elif defined(__s390x__)
|
||||
+ default_thp_size = 1 * MiB;
|
||||
#endif
|
||||
|
||||
return default_thp_size;
|
||||
@@ -161,7 +163,7 @@ static bool virtio_mem_has_shared_zeropage(RAMBlock *rb)
|
||||
* necessary (as the section size can change). But it's more likely that the
|
||||
* section size will rather get smaller and not bigger over time.
|
||||
*/
|
||||
-#if defined(TARGET_X86_64) || defined(TARGET_I386)
|
||||
+#if defined(TARGET_X86_64) || defined(TARGET_I386) || defined(TARGET_S390X)
|
||||
#define VIRTIO_MEM_USABLE_EXTENT (2 * (128 * MiB))
|
||||
#elif defined(TARGET_ARM)
|
||||
#define VIRTIO_MEM_USABLE_EXTENT (2 * (512 * MiB))
|
||||
--
|
||||
2.48.1
|
||||
|
284
kvm-target-s390-Convert-CPU-to-Resettable-interface.patch
Normal file
284
kvm-target-s390-Convert-CPU-to-Resettable-interface.patch
Normal file
@ -0,0 +1,284 @@
|
||||
From 50c4cbbe0a8849dd0c720c6e706498cb0d46f5b3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Fri, 13 Sep 2024 15:31:43 +0100
|
||||
Subject: [PATCH 04/26] target/s390: Convert CPU to Resettable interface
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [4/26] 157b29ced6b92ecec5e69f8bc60d0183a0c88fa0 (thuth/qemu-kvm-cs)
|
||||
|
||||
Convert the s390 CPU to the Resettable interface. This is slightly
|
||||
more involved than the other CPU types were (see commits
|
||||
9130cade5fc22..d66e64dd006df) because S390 has its own set of
|
||||
different kinds of reset with different behaviours that it needs to
|
||||
trigger.
|
||||
|
||||
We handle this by adding these reset types to the Resettable
|
||||
ResetType enum. Now instead of having an underlying implementation
|
||||
of reset that is s390-specific and which might be called either
|
||||
directly or via the DeviceClass::reset method, we can implement only
|
||||
the Resettable hold phase method, and have the places that need to
|
||||
trigger an s390-specific reset type do so by calling
|
||||
resettable_reset().
|
||||
|
||||
The other option would have been to smuggle in the s390 reset
|
||||
type via, for instance, a field in the CPU state that we set
|
||||
in s390_do_cpu_initial_reset() etc and then examined in the
|
||||
reset method, but doing it this way seems cleaner.
|
||||
|
||||
The motivation for this change is that this is the last caller
|
||||
of the legacy device_class_set_parent_reset() function, and
|
||||
removing that will let us clean up some glue code that we added
|
||||
for the transition to three-phase reset.
|
||||
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-id: 20240830145812.1967042-4-peter.maydell@linaro.org
|
||||
(cherry picked from commit cf7f61d13f28f32d0b14abb70ce1bd9e41623b2e)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
docs/devel/reset.rst | 10 ++++++++++
|
||||
include/hw/resettable.h | 2 ++
|
||||
target/s390x/cpu.c | 38 +++++++++++++++++---------------------
|
||||
target/s390x/cpu.h | 21 ++++-----------------
|
||||
target/s390x/sigp.c | 8 ++------
|
||||
5 files changed, 35 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst
|
||||
index 24ab630465..d2799eba7a 100644
|
||||
--- a/docs/devel/reset.rst
|
||||
+++ b/docs/devel/reset.rst
|
||||
@@ -44,6 +44,16 @@ The Resettable interface handles reset types with an enum ``ResetType``:
|
||||
value on each cold reset, such as RNG seed information, and which they
|
||||
must not reinitialize on a snapshot-load reset.
|
||||
|
||||
+``RESET_TYPE_S390_CPU_NORMAL``
|
||||
+ This is only used for S390 CPU objects; it clears interrupts, stops
|
||||
+ processing, and clears the TLB, but does not touch register contents.
|
||||
+
|
||||
+``RESET_TYPE_S390_CPU_INITIAL``
|
||||
+ This is only used for S390 CPU objects; it does everything
|
||||
+ ``RESET_TYPE_S390_CPU_NORMAL`` does and also clears the PSW, prefix,
|
||||
+ FPC, timer and control registers. It does not touch gprs, fprs or acrs.
|
||||
+
|
||||
+
|
||||
Devices which implement reset methods must treat any unknown ``ResetType``
|
||||
as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of
|
||||
existing code we need to change if we add more types in future.
|
||||
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
|
||||
index 7e249deb8b..83b561fc83 100644
|
||||
--- a/include/hw/resettable.h
|
||||
+++ b/include/hw/resettable.h
|
||||
@@ -36,6 +36,8 @@ typedef struct ResettableState ResettableState;
|
||||
typedef enum ResetType {
|
||||
RESET_TYPE_COLD,
|
||||
RESET_TYPE_SNAPSHOT_LOAD,
|
||||
+ RESET_TYPE_S390_CPU_INITIAL,
|
||||
+ RESET_TYPE_S390_CPU_NORMAL,
|
||||
} ResetType;
|
||||
|
||||
/*
|
||||
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
|
||||
index 0fbfcd35d8..4e41a3dff5 100644
|
||||
--- a/target/s390x/cpu.c
|
||||
+++ b/target/s390x/cpu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
+#include "hw/resettable.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
#include "disas/capstone.h"
|
||||
#include "sysemu/tcg.h"
|
||||
@@ -162,23 +163,25 @@ static void s390_query_cpu_fast(CPUState *cpu, CpuInfoFast *value)
|
||||
#endif
|
||||
}
|
||||
|
||||
-/* S390CPUClass::reset() */
|
||||
-static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
|
||||
+/* S390CPUClass Resettable reset_hold phase method */
|
||||
+static void s390_cpu_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
- S390CPU *cpu = S390_CPU(s);
|
||||
+ S390CPU *cpu = S390_CPU(obj);
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
- DeviceState *dev = DEVICE(s);
|
||||
|
||||
- scc->parent_reset(dev);
|
||||
+ if (scc->parent_phases.hold) {
|
||||
+ scc->parent_phases.hold(obj, type);
|
||||
+ }
|
||||
cpu->env.sigp_order = 0;
|
||||
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
|
||||
|
||||
switch (type) {
|
||||
- case S390_CPU_RESET_CLEAR:
|
||||
+ default:
|
||||
+ /* RESET_TYPE_COLD: power on or "clear" reset */
|
||||
memset(env, 0, offsetof(CPUS390XState, start_initial_reset_fields));
|
||||
/* fall through */
|
||||
- case S390_CPU_RESET_INITIAL:
|
||||
+ case RESET_TYPE_S390_CPU_INITIAL:
|
||||
/* initial reset does not clear everything! */
|
||||
memset(&env->start_initial_reset_fields, 0,
|
||||
offsetof(CPUS390XState, start_normal_reset_fields) -
|
||||
@@ -203,7 +206,7 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->fpu_status);
|
||||
/* fall through */
|
||||
- case S390_CPU_RESET_NORMAL:
|
||||
+ case RESET_TYPE_S390_CPU_NORMAL:
|
||||
env->psw.mask &= ~PSW_MASK_RI;
|
||||
memset(&env->start_normal_reset_fields, 0,
|
||||
offsetof(CPUS390XState, end_reset_fields) -
|
||||
@@ -212,20 +215,18 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
|
||||
env->pfault_token = -1UL;
|
||||
env->bpbc = false;
|
||||
break;
|
||||
- default:
|
||||
- g_assert_not_reached();
|
||||
}
|
||||
|
||||
/* Reset state inside the kernel that we cannot access yet from QEMU. */
|
||||
if (kvm_enabled()) {
|
||||
switch (type) {
|
||||
- case S390_CPU_RESET_CLEAR:
|
||||
+ default:
|
||||
kvm_s390_reset_vcpu_clear(cpu);
|
||||
break;
|
||||
- case S390_CPU_RESET_INITIAL:
|
||||
+ case RESET_TYPE_S390_CPU_INITIAL:
|
||||
kvm_s390_reset_vcpu_initial(cpu);
|
||||
break;
|
||||
- case S390_CPU_RESET_NORMAL:
|
||||
+ case RESET_TYPE_S390_CPU_NORMAL:
|
||||
kvm_s390_reset_vcpu_normal(cpu);
|
||||
break;
|
||||
}
|
||||
@@ -315,12 +316,6 @@ static Property s390x_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
-static void s390_cpu_reset_full(DeviceState *dev)
|
||||
-{
|
||||
- CPUState *s = CPU(dev);
|
||||
- return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
|
||||
-}
|
||||
-
|
||||
#ifdef CONFIG_TCG
|
||||
#include "hw/core/tcg-cpu-ops.h"
|
||||
|
||||
@@ -383,15 +378,16 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
||||
S390CPUClass *scc = S390_CPU_CLASS(oc);
|
||||
CPUClass *cc = CPU_CLASS(scc);
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
|
||||
|
||||
device_class_set_parent_realize(dc, s390_cpu_realizefn,
|
||||
&scc->parent_realize);
|
||||
device_class_set_props(dc, s390x_cpu_properties);
|
||||
dc->user_creatable = true;
|
||||
|
||||
- device_class_set_parent_reset(dc, s390_cpu_reset_full, &scc->parent_reset);
|
||||
+ resettable_class_set_parent_phases(rc, NULL, s390_cpu_reset_hold, NULL,
|
||||
+ &scc->parent_phases);
|
||||
|
||||
- scc->reset = s390_cpu_reset;
|
||||
cc->class_by_name = s390_cpu_class_by_name,
|
||||
cc->has_work = s390_cpu_has_work;
|
||||
cc->mmu_index = s390x_cpu_mmu_index;
|
||||
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
|
||||
index d6b75ad0e0..6a64472403 100644
|
||||
--- a/target/s390x/cpu.h
|
||||
+++ b/target/s390x/cpu.h
|
||||
@@ -177,19 +177,11 @@ struct ArchCPU {
|
||||
uint32_t irqstate_saved_size;
|
||||
};
|
||||
|
||||
-typedef enum cpu_reset_type {
|
||||
- S390_CPU_RESET_NORMAL,
|
||||
- S390_CPU_RESET_INITIAL,
|
||||
- S390_CPU_RESET_CLEAR,
|
||||
-} cpu_reset_type;
|
||||
-
|
||||
/**
|
||||
* S390CPUClass:
|
||||
* @parent_realize: The parent class' realize handler.
|
||||
- * @parent_reset: The parent class' reset handler.
|
||||
+ * @parent_phases: The parent class' reset phase handlers.
|
||||
* @load_normal: Performs a load normal.
|
||||
- * @cpu_reset: Performs a CPU reset.
|
||||
- * @initial_cpu_reset: Performs an initial CPU reset.
|
||||
*
|
||||
* An S/390 CPU model.
|
||||
*/
|
||||
@@ -203,9 +195,8 @@ struct S390CPUClass {
|
||||
const char *desc;
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
- DeviceReset parent_reset;
|
||||
+ ResettablePhases parent_phases;
|
||||
void (*load_normal)(CPUState *cpu);
|
||||
- void (*reset)(CPUState *cpu, cpu_reset_type type);
|
||||
};
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@@ -872,16 +863,12 @@ static inline void s390_do_cpu_full_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
|
||||
static inline void s390_do_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
- S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
|
||||
-
|
||||
- scc->reset(cs, S390_CPU_RESET_NORMAL);
|
||||
+ resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_NORMAL);
|
||||
}
|
||||
|
||||
static inline void s390_do_cpu_initial_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
- S390CPUClass *scc = S390_CPU_GET_CLASS(cs);
|
||||
-
|
||||
- scc->reset(cs, S390_CPU_RESET_INITIAL);
|
||||
+ resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_INITIAL);
|
||||
}
|
||||
|
||||
static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
|
||||
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
|
||||
index ad0ad61177..08aaecf12b 100644
|
||||
--- a/target/s390x/sigp.c
|
||||
+++ b/target/s390x/sigp.c
|
||||
@@ -251,24 +251,20 @@ static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
|
||||
|
||||
static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
- S390CPU *cpu = S390_CPU(cs);
|
||||
- S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
SigpInfo *si = arg.host_ptr;
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
- scc->reset(cs, S390_CPU_RESET_INITIAL);
|
||||
+ resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_INITIAL);
|
||||
cpu_synchronize_post_reset(cs);
|
||||
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
}
|
||||
|
||||
static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
- S390CPU *cpu = S390_CPU(cs);
|
||||
- S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
SigpInfo *si = arg.host_ptr;
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
- scc->reset(cs, S390_CPU_RESET_NORMAL);
|
||||
+ resettable_reset(OBJECT(cs), RESET_TYPE_S390_CPU_NORMAL);
|
||||
cpu_synchronize_post_reset(cs);
|
||||
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
}
|
||||
--
|
||||
2.48.1
|
||||
|
87
kvm-virtio-kconfig-memory-devices-are-PCI-only.patch
Normal file
87
kvm-virtio-kconfig-memory-devices-are-PCI-only.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From a582cf6f68febba05e20548f643c8be637eab7b8 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Fri, 6 Sep 2024 12:16:58 +0200
|
||||
Subject: [PATCH 01/26] virtio: kconfig: memory devices are PCI only
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [1/26] 0f0eab06b6f79f84c2e8d4fee28309b3c7c57414 (thuth/qemu-kvm-cs)
|
||||
|
||||
Virtio memory devices rely on PCI BARs to expose the contents of memory.
|
||||
Because of this they cannot be used (yet) with virtio-mmio or virtio-ccw.
|
||||
In fact the code that is common to virtio-mem and virtio-pmem, which
|
||||
is in hw/virtio/virtio-md-pci.c, is only included if CONFIG_VIRTIO_PCI
|
||||
is set. Reproduce the same condition in the Kconfig file, only allowing
|
||||
VIRTIO_MEM and VIRTIO_PMEM to be defined if the transport supports it.
|
||||
|
||||
Without this patch it is possible to create a configuration with
|
||||
CONFIG_VIRTIO_PCI=n and CONFIG_VIRTIO_MEM=y, but that causes a
|
||||
linking failure.
|
||||
|
||||
Message-ID: <20240906101658.514470-1-pbonzini@redhat.com>
|
||||
Reported-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 8d018fe59a0beff580ac6b3399d642c4277d9dd0)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/Kconfig | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
|
||||
index aa63ff7fd4..0afec2ae92 100644
|
||||
--- a/hw/virtio/Kconfig
|
||||
+++ b/hw/virtio/Kconfig
|
||||
@@ -16,6 +16,7 @@ config VIRTIO_PCI
|
||||
default y if PCI_DEVICES
|
||||
depends on PCI
|
||||
select VIRTIO
|
||||
+ select VIRTIO_MD_SUPPORTED
|
||||
|
||||
config VIRTIO_MMIO
|
||||
bool
|
||||
@@ -35,10 +36,17 @@ config VIRTIO_CRYPTO
|
||||
default y
|
||||
depends on VIRTIO
|
||||
|
||||
+# not all virtio transports support memory devices; if none does,
|
||||
+# no need to include the code
|
||||
+config VIRTIO_MD_SUPPORTED
|
||||
+ bool
|
||||
+
|
||||
config VIRTIO_MD
|
||||
bool
|
||||
+ depends on VIRTIO_MD_SUPPORTED
|
||||
select MEM_DEVICE
|
||||
|
||||
+# selected by the board if it has the required support code
|
||||
config VIRTIO_PMEM_SUPPORTED
|
||||
bool
|
||||
|
||||
@@ -46,9 +54,11 @@ config VIRTIO_PMEM
|
||||
bool
|
||||
default y
|
||||
depends on VIRTIO
|
||||
+ depends on VIRTIO_MD_SUPPORTED
|
||||
depends on VIRTIO_PMEM_SUPPORTED
|
||||
select VIRTIO_MD
|
||||
|
||||
+# selected by the board if it has the required support code
|
||||
config VIRTIO_MEM_SUPPORTED
|
||||
bool
|
||||
|
||||
@@ -57,6 +67,7 @@ config VIRTIO_MEM
|
||||
default y
|
||||
depends on VIRTIO
|
||||
depends on LINUX
|
||||
+ depends on VIRTIO_MD_SUPPORTED
|
||||
depends on VIRTIO_MEM_SUPPORTED
|
||||
select VIRTIO_MD
|
||||
|
||||
--
|
||||
2.48.1
|
||||
|
@ -0,0 +1,79 @@
|
||||
From 001200670ce9076a34419828e7e7ba92f19a80b7 Mon Sep 17 00:00:00 2001
|
||||
From: Juraj Marcin <jmarcin@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 12:37:15 +0200
|
||||
Subject: [PATCH 08/26] virtio-mem: Add support for suspend+wake-up with
|
||||
plugged memory
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [8/26] 08e25d41e32b3ac2bf5e0266f9c7e91739eda4d4 (thuth/qemu-kvm-cs)
|
||||
|
||||
Before, the virtio-mem device would unplug all the memory with any reset
|
||||
of the device, including during the wake-up of the guest from a
|
||||
suspended state. Due to this, the virtio-mem driver in the Linux kernel
|
||||
disallowed suspend-to-ram requests in the guest when the
|
||||
VIRTIO_MEM_F_PERSISTENT_SUSPEND feature is not exposed by QEMU.
|
||||
|
||||
This patch adds the code to skip the reset on wake-up and exposes
|
||||
theVIRTIO_MEM_F_PERSISTENT_SUSPEND feature to the guest kernel driver
|
||||
when suspending is possible in QEMU (currently only x86).
|
||||
|
||||
Message-ID: <20240904103722.946194-5-jmarcin@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 1f5f49056d0f140568805d66f33396ed5cd90369)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 10 ++++++++++
|
||||
hw/virtio/virtio-qmp.c | 3 +++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index 025ae4abac..51642a15ef 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -883,6 +883,9 @@ static uint64_t virtio_mem_get_features(VirtIODevice *vdev, uint64_t features,
|
||||
if (vmem->unplugged_inaccessible == ON_OFF_AUTO_ON) {
|
||||
virtio_add_feature(&features, VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE);
|
||||
}
|
||||
+ if (qemu_wakeup_suspend_enabled()) {
|
||||
+ virtio_add_feature(&features, VIRTIO_MEM_F_PERSISTENT_SUSPEND);
|
||||
+ }
|
||||
return features;
|
||||
}
|
||||
|
||||
@@ -1842,6 +1845,13 @@ static void virtio_mem_system_reset_hold(Object *obj, ResetType type)
|
||||
{
|
||||
VirtIOMEM *vmem = VIRTIO_MEM(obj);
|
||||
|
||||
+ /*
|
||||
+ * When waking up from standby/suspend-to-ram, do not unplug any memory.
|
||||
+ */
|
||||
+ if (type == RESET_TYPE_WAKEUP) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* During usual resets, we will unplug all memory and shrink the usable
|
||||
* region size. This is, however, not possible in all scenarios. Then,
|
||||
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
|
||||
index 1dd96ed20f..cccc6fe761 100644
|
||||
--- a/hw/virtio/virtio-qmp.c
|
||||
+++ b/hw/virtio/virtio-qmp.c
|
||||
@@ -450,6 +450,9 @@ static const qmp_virtio_feature_map_t virtio_mem_feature_map[] = {
|
||||
FEATURE_ENTRY(VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, \
|
||||
"VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE: Unplugged memory cannot be "
|
||||
"accessed"),
|
||||
+ FEATURE_ENTRY(VIRTIO_MEM_F_PERSISTENT_SUSPEND, \
|
||||
+ "VIRTIO_MEM_F_PERSISTENT_SUSPND: Plugged memory will remain "
|
||||
+ "plugged when suspending+resuming"),
|
||||
{ -1, "" }
|
||||
};
|
||||
#endif
|
||||
--
|
||||
2.48.1
|
||||
|
141
kvm-virtio-mem-Use-new-Resettable-framework-instead-of-L.patch
Normal file
141
kvm-virtio-mem-Use-new-Resettable-framework-instead-of-L.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 6bc0cdecdc736d642bb6c040e07d79a0a3e591ea Mon Sep 17 00:00:00 2001
|
||||
From: Juraj Marcin <jmarcin@redhat.com>
|
||||
Date: Wed, 4 Sep 2024 12:37:14 +0200
|
||||
Subject: [PATCH 07/26] virtio-mem: Use new Resettable framework instead of
|
||||
LegacyReset
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [7/26] 31fddbeb4aaf6794b83399a7e2996f01d918d748 (thuth/qemu-kvm-cs)
|
||||
|
||||
LegacyReset does not pass ResetType to the reset callback method, which
|
||||
the new Resettable framework uses. Due to this, virtio-mem cannot use
|
||||
the new RESET_TYPE_WAKEUP to skip the reset during wake-up from a
|
||||
suspended state.
|
||||
|
||||
This patch adds overrides Resettable interface methods in VirtIOMEMClass
|
||||
to use the new Resettable framework and replaces
|
||||
qemu_[un]register_reset() calls with qemu_[un]register_resettable().
|
||||
|
||||
Message-ID: <20240904103722.946194-4-jmarcin@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit c009a311e93963860cfba917605a4bf903a06bce)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 38 +++++++++++++++++++++-------------
|
||||
include/hw/virtio/virtio-mem.h | 4 ++++
|
||||
2 files changed, 28 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index ba11aa4646..025ae4abac 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -895,18 +895,6 @@ static int virtio_mem_validate_features(VirtIODevice *vdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void virtio_mem_system_reset(void *opaque)
|
||||
-{
|
||||
- VirtIOMEM *vmem = VIRTIO_MEM(opaque);
|
||||
-
|
||||
- /*
|
||||
- * During usual resets, we will unplug all memory and shrink the usable
|
||||
- * region size. This is, however, not possible in all scenarios. Then,
|
||||
- * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL).
|
||||
- */
|
||||
- virtio_mem_unplug_all(vmem);
|
||||
-}
|
||||
-
|
||||
static void virtio_mem_prepare_mr(VirtIOMEM *vmem)
|
||||
{
|
||||
const uint64_t region_size = memory_region_size(&vmem->memdev->mr);
|
||||
@@ -1123,7 +1111,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
||||
vmstate_register_any(VMSTATE_IF(vmem),
|
||||
&vmstate_virtio_mem_device_early, vmem);
|
||||
}
|
||||
- qemu_register_reset(virtio_mem_system_reset, vmem);
|
||||
+ qemu_register_resettable(OBJECT(vmem));
|
||||
|
||||
/*
|
||||
* Set ourselves as RamDiscardManager before the plug handler maps the
|
||||
@@ -1143,7 +1131,7 @@ static void virtio_mem_device_unrealize(DeviceState *dev)
|
||||
* found via an address space anymore. Unset ourselves.
|
||||
*/
|
||||
memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
|
||||
- qemu_unregister_reset(virtio_mem_system_reset, vmem);
|
||||
+ qemu_unregister_resettable(OBJECT(vmem));
|
||||
if (vmem->early_migration) {
|
||||
vmstate_unregister(VMSTATE_IF(vmem), &vmstate_virtio_mem_device_early,
|
||||
vmem);
|
||||
@@ -1844,12 +1832,31 @@ static void virtio_mem_unplug_request_check(VirtIOMEM *vmem, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
+static ResettableState *virtio_mem_get_reset_state(Object *obj)
|
||||
+{
|
||||
+ VirtIOMEM *vmem = VIRTIO_MEM(obj);
|
||||
+ return &vmem->reset_state;
|
||||
+}
|
||||
+
|
||||
+static void virtio_mem_system_reset_hold(Object *obj, ResetType type)
|
||||
+{
|
||||
+ VirtIOMEM *vmem = VIRTIO_MEM(obj);
|
||||
+
|
||||
+ /*
|
||||
+ * During usual resets, we will unplug all memory and shrink the usable
|
||||
+ * region size. This is, however, not possible in all scenarios. Then,
|
||||
+ * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL).
|
||||
+ */
|
||||
+ virtio_mem_unplug_all(vmem);
|
||||
+}
|
||||
+
|
||||
static void virtio_mem_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
||||
VirtIOMEMClass *vmc = VIRTIO_MEM_CLASS(klass);
|
||||
RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass);
|
||||
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
device_class_set_props(dc, virtio_mem_properties);
|
||||
dc->vmsd = &vmstate_virtio_mem;
|
||||
@@ -1876,6 +1883,9 @@ static void virtio_mem_class_init(ObjectClass *klass, void *data)
|
||||
rdmc->replay_discarded = virtio_mem_rdm_replay_discarded;
|
||||
rdmc->register_listener = virtio_mem_rdm_register_listener;
|
||||
rdmc->unregister_listener = virtio_mem_rdm_unregister_listener;
|
||||
+
|
||||
+ rc->get_state = virtio_mem_get_reset_state;
|
||||
+ rc->phases.hold = virtio_mem_system_reset_hold;
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_mem_info = {
|
||||
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
|
||||
index 5f5b02b8f9..a1af144c28 100644
|
||||
--- a/include/hw/virtio/virtio-mem.h
|
||||
+++ b/include/hw/virtio/virtio-mem.h
|
||||
@@ -14,6 +14,7 @@
|
||||
#define HW_VIRTIO_MEM_H
|
||||
|
||||
#include "standard-headers/linux/virtio_mem.h"
|
||||
+#include "hw/resettable.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "qapi/qapi-types-misc.h"
|
||||
#include "sysemu/hostmem.h"
|
||||
@@ -115,6 +116,9 @@ struct VirtIOMEM {
|
||||
|
||||
/* listeners to notify on plug/unplug activity. */
|
||||
QLIST_HEAD(, RamDiscardListener) rdl_list;
|
||||
+
|
||||
+ /* State of the resettable container */
|
||||
+ ResettableState reset_state;
|
||||
};
|
||||
|
||||
struct VirtIOMEMClass {
|
||||
--
|
||||
2.48.1
|
||||
|
@ -0,0 +1,59 @@
|
||||
From f4052d25199bfce8ce29a173934a805fe1cf7e3e Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Tue, 10 Sep 2024 18:34:33 +0200
|
||||
Subject: [PATCH 25/26] virtio-mem: don't warn about THP sizes on a kernel
|
||||
without THP support
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [25/26] 5dff17ef818722db8f1fa87cff5b7777afc3c814 (thuth/qemu-kvm-cs)
|
||||
|
||||
If the config directory in sysfs does not exist at all, we are dealing
|
||||
with a system that does not support THPs. Simply use 1 MiB block size
|
||||
then, instead of warning "Could not detect THP size, falling back to
|
||||
..." and falling back to the default THP size.
|
||||
|
||||
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Cc: Gavin Shan <gshan@redhat.com>
|
||||
Cc: Juraj Marcin <jmarcin@redhat.com>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
Message-Id: <20240910163433.2100295-1-david@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry picked from commit 95b717a8154b955de2782305f305b63f357b0576)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index c9f8a23bbc..4977658312 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -90,6 +90,7 @@ static uint32_t virtio_mem_default_thp_size(void)
|
||||
static uint32_t thp_size;
|
||||
|
||||
#define HPAGE_PMD_SIZE_PATH "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size"
|
||||
+#define HPAGE_PATH "/sys/kernel/mm/transparent_hugepage/"
|
||||
static uint32_t virtio_mem_thp_size(void)
|
||||
{
|
||||
gchar *content = NULL;
|
||||
@@ -100,6 +101,12 @@ static uint32_t virtio_mem_thp_size(void)
|
||||
return thp_size;
|
||||
}
|
||||
|
||||
+ /* No THP -> no restrictions. */
|
||||
+ if (!g_file_test(HPAGE_PATH, G_FILE_TEST_EXISTS)) {
|
||||
+ thp_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
|
||||
+ return thp_size;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Try to probe the actual THP size, fallback to (sane but eventually
|
||||
* incorrect) default sizes.
|
||||
--
|
||||
2.48.1
|
||||
|
258
kvm-virtio-mem-unplug-memory-only-during-system-resets-n.patch
Normal file
258
kvm-virtio-mem-unplug-memory-only-during-system-resets-n.patch
Normal file
@ -0,0 +1,258 @@
|
||||
From e5f2bb584154eef665211228f1ac3113e2acc269 Mon Sep 17 00:00:00 2001
|
||||
From: David Hildenbrand <david@redhat.com>
|
||||
Date: Fri, 25 Oct 2024 12:41:03 +0200
|
||||
Subject: [PATCH 09/26] virtio-mem: unplug memory only during system resets,
|
||||
not device resets
|
||||
|
||||
RH-Author: Thomas Huth <thuth@redhat.com>
|
||||
RH-MergeRequest: 351: Enable virtio-mem support on s390x
|
||||
RH-Jira: RHEL-72977
|
||||
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
||||
RH-Acked-by: Juraj Marcin <None>
|
||||
RH-Commit: [9/26] 7c5ddd4d3fd0d19caa946bcbe98cb5732404978b (thuth/qemu-kvm-cs)
|
||||
|
||||
We recently converted from the LegacyReset to the new reset framework
|
||||
in commit c009a311e939 ("virtio-mem: Use new Resettable framework instead
|
||||
of LegacyReset") to be able to use the ResetType to filter out wakeup
|
||||
resets.
|
||||
|
||||
However, this change had an undesired implications: as we override the
|
||||
Resettable interface methods in VirtIOMEMClass, the reset handler will
|
||||
not only get called during system resets (i.e., qemu_devices_reset())
|
||||
but also during any direct or indirect device rests (e.g.,
|
||||
device_cold_reset()).
|
||||
|
||||
Further, we might now receive two reset callbacks during
|
||||
qemu_devices_reset(), first when reset by a parent and later when reset
|
||||
directly.
|
||||
|
||||
The memory state of virtio-mem devices is rather special: it's supposed to
|
||||
be persistent/unchanged during most resets (similar to resetting a hard
|
||||
disk will not destroy the data), unless actually cold-resetting the whole
|
||||
system (different to a hard disk where a reboot will not destroy the data):
|
||||
ripping out system RAM is something guest OSes don't particularly enjoy,
|
||||
but we want to detect when rebooting to an OS that does not support
|
||||
virtio-mem and wouldn't be able to detect+use the memory -- and we want
|
||||
to force-defragment hotplugged memory to also shrink the usable device
|
||||
memory region. So we rally want to catch system resets to do that.
|
||||
|
||||
On supported targets (e.g., x86), getting a cold reset on the
|
||||
device/parent triggers is not that easy (but looks like PCI code
|
||||
might trigger it), so this implication went unnoticed.
|
||||
|
||||
However, with upcoming s390x support it is problematic: during
|
||||
kdump, s390x triggers a subsystem reset, ending up in
|
||||
s390_machine_reset() and calling only subsystem_reset() instead of
|
||||
qemu_devices_reset() -- because it's not a full system reset.
|
||||
|
||||
In subsystem_reset(), s390x performs a device_cold_reset() of any
|
||||
TYPE_VIRTUAL_CSS_BRIDGE device, which ends up resetting all children,
|
||||
including the virtio-mem device. Consequently, we wrongly detect a system
|
||||
reset and unplug all device memory, resulting in hotplugged memory not
|
||||
getting included in the crash dump -- undesired.
|
||||
|
||||
We really must not mess with hotplugged memory state during simple
|
||||
device resets. To fix, create+register a new reset object that will only
|
||||
get triggered during qemu_devices_reset() calls, but not during any other
|
||||
resets as it is logically not the child of any other object.
|
||||
|
||||
Message-ID: <20241025104103.342188-1-david@redhat.com>
|
||||
Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Cc: Juraj Marcin <jmarcin@redhat.com>
|
||||
Cc: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: David Hildenbrand <david@redhat.com>
|
||||
(cherry picked from commit 713484d0389c9d1cbb87eca060361281248b69f5)
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
---
|
||||
hw/virtio/virtio-mem.c | 103 +++++++++++++++++++++++----------
|
||||
include/hw/virtio/virtio-mem.h | 13 ++++-
|
||||
2 files changed, 84 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
|
||||
index 51642a15ef..00da98b6e1 100644
|
||||
--- a/hw/virtio/virtio-mem.c
|
||||
+++ b/hw/virtio/virtio-mem.c
|
||||
@@ -949,6 +949,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
||||
VirtIOMEM *vmem = VIRTIO_MEM(dev);
|
||||
uint64_t page_size;
|
||||
RAMBlock *rb;
|
||||
+ Object *obj;
|
||||
int ret;
|
||||
|
||||
if (!vmem->memdev) {
|
||||
@@ -1114,7 +1115,28 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
|
||||
vmstate_register_any(VMSTATE_IF(vmem),
|
||||
&vmstate_virtio_mem_device_early, vmem);
|
||||
}
|
||||
- qemu_register_resettable(OBJECT(vmem));
|
||||
+
|
||||
+ /*
|
||||
+ * We only want to unplug all memory to start with a clean slate when
|
||||
+ * it is safe for the guest -- during system resets that call
|
||||
+ * qemu_devices_reset().
|
||||
+ *
|
||||
+ * We'll filter out selected qemu_devices_reset() calls used for other
|
||||
+ * purposes, like resetting all devices during wakeup from suspend on
|
||||
+ * x86 based on the reset type passed to qemu_devices_reset().
|
||||
+ *
|
||||
+ * Unplugging all memory during simple device resets can result in the VM
|
||||
+ * unexpectedly losing RAM, corrupting VM state.
|
||||
+ *
|
||||
+ * Simple device resets (or resets triggered by getting a parent device
|
||||
+ * reset) must not change the state of plugged memory blocks. Therefore,
|
||||
+ * we need a dedicated reset object that only gets called during
|
||||
+ * qemu_devices_reset().
|
||||
+ */
|
||||
+ obj = object_new(TYPE_VIRTIO_MEM_SYSTEM_RESET);
|
||||
+ vmem->system_reset = VIRTIO_MEM_SYSTEM_RESET(obj);
|
||||
+ vmem->system_reset->vmem = vmem;
|
||||
+ qemu_register_resettable(obj);
|
||||
|
||||
/*
|
||||
* Set ourselves as RamDiscardManager before the plug handler maps the
|
||||
@@ -1134,7 +1156,10 @@ static void virtio_mem_device_unrealize(DeviceState *dev)
|
||||
* found via an address space anymore. Unset ourselves.
|
||||
*/
|
||||
memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL);
|
||||
- qemu_unregister_resettable(OBJECT(vmem));
|
||||
+
|
||||
+ qemu_unregister_resettable(OBJECT(vmem->system_reset));
|
||||
+ object_unref(OBJECT(vmem->system_reset));
|
||||
+
|
||||
if (vmem->early_migration) {
|
||||
vmstate_unregister(VMSTATE_IF(vmem), &vmstate_virtio_mem_device_early,
|
||||
vmem);
|
||||
@@ -1835,38 +1860,12 @@ static void virtio_mem_unplug_request_check(VirtIOMEM *vmem, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
-static ResettableState *virtio_mem_get_reset_state(Object *obj)
|
||||
-{
|
||||
- VirtIOMEM *vmem = VIRTIO_MEM(obj);
|
||||
- return &vmem->reset_state;
|
||||
-}
|
||||
-
|
||||
-static void virtio_mem_system_reset_hold(Object *obj, ResetType type)
|
||||
-{
|
||||
- VirtIOMEM *vmem = VIRTIO_MEM(obj);
|
||||
-
|
||||
- /*
|
||||
- * When waking up from standby/suspend-to-ram, do not unplug any memory.
|
||||
- */
|
||||
- if (type == RESET_TYPE_WAKEUP) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * During usual resets, we will unplug all memory and shrink the usable
|
||||
- * region size. This is, however, not possible in all scenarios. Then,
|
||||
- * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL).
|
||||
- */
|
||||
- virtio_mem_unplug_all(vmem);
|
||||
-}
|
||||
-
|
||||
static void virtio_mem_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
||||
VirtIOMEMClass *vmc = VIRTIO_MEM_CLASS(klass);
|
||||
RamDiscardManagerClass *rdmc = RAM_DISCARD_MANAGER_CLASS(klass);
|
||||
- ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
|
||||
device_class_set_props(dc, virtio_mem_properties);
|
||||
dc->vmsd = &vmstate_virtio_mem;
|
||||
@@ -1893,9 +1892,6 @@ static void virtio_mem_class_init(ObjectClass *klass, void *data)
|
||||
rdmc->replay_discarded = virtio_mem_rdm_replay_discarded;
|
||||
rdmc->register_listener = virtio_mem_rdm_register_listener;
|
||||
rdmc->unregister_listener = virtio_mem_rdm_unregister_listener;
|
||||
-
|
||||
- rc->get_state = virtio_mem_get_reset_state;
|
||||
- rc->phases.hold = virtio_mem_system_reset_hold;
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_mem_info = {
|
||||
@@ -1918,3 +1914,48 @@ static void virtio_register_types(void)
|
||||
}
|
||||
|
||||
type_init(virtio_register_types)
|
||||
+
|
||||
+OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(VirtioMemSystemReset, virtio_mem_system_reset, VIRTIO_MEM_SYSTEM_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })
|
||||
+
|
||||
+static void virtio_mem_system_reset_init(Object *obj)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void virtio_mem_system_reset_finalize(Object *obj)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static ResettableState *virtio_mem_system_reset_get_state(Object *obj)
|
||||
+{
|
||||
+ VirtioMemSystemReset *vmem_reset = VIRTIO_MEM_SYSTEM_RESET(obj);
|
||||
+
|
||||
+ return &vmem_reset->reset_state;
|
||||
+}
|
||||
+
|
||||
+static void virtio_mem_system_reset_hold(Object *obj, ResetType type)
|
||||
+{
|
||||
+ VirtioMemSystemReset *vmem_reset = VIRTIO_MEM_SYSTEM_RESET(obj);
|
||||
+ VirtIOMEM *vmem = vmem_reset->vmem;
|
||||
+
|
||||
+ /*
|
||||
+ * When waking up from standby/suspend-to-ram, do not unplug any memory.
|
||||
+ */
|
||||
+ if (type == RESET_TYPE_WAKEUP) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * During usual resets, we will unplug all memory and shrink the usable
|
||||
+ * region size. This is, however, not possible in all scenarios. Then,
|
||||
+ * the guest has to deal with this manually (VIRTIO_MEM_REQ_UNPLUG_ALL).
|
||||
+ */
|
||||
+ virtio_mem_unplug_all(vmem);
|
||||
+}
|
||||
+
|
||||
+static void virtio_mem_system_reset_class_init(ObjectClass *klass, void *data)
|
||||
+{
|
||||
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
+
|
||||
+ rc->get_state = virtio_mem_system_reset_get_state;
|
||||
+ rc->phases.hold = virtio_mem_system_reset_hold;
|
||||
+}
|
||||
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
|
||||
index a1af144c28..550ce585b2 100644
|
||||
--- a/include/hw/virtio/virtio-mem.h
|
||||
+++ b/include/hw/virtio/virtio-mem.h
|
||||
@@ -25,6 +25,10 @@
|
||||
OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass,
|
||||
VIRTIO_MEM)
|
||||
|
||||
+#define TYPE_VIRTIO_MEM_SYSTEM_RESET "virtio-mem-system-reset"
|
||||
+
|
||||
+OBJECT_DECLARE_SIMPLE_TYPE(VirtioMemSystemReset, VIRTIO_MEM_SYSTEM_RESET)
|
||||
+
|
||||
#define VIRTIO_MEM_MEMDEV_PROP "memdev"
|
||||
#define VIRTIO_MEM_NODE_PROP "node"
|
||||
#define VIRTIO_MEM_SIZE_PROP "size"
|
||||
@@ -117,8 +121,15 @@ struct VirtIOMEM {
|
||||
/* listeners to notify on plug/unplug activity. */
|
||||
QLIST_HEAD(, RamDiscardListener) rdl_list;
|
||||
|
||||
- /* State of the resettable container */
|
||||
+ /* Catch system resets -> qemu_devices_reset() only. */
|
||||
+ VirtioMemSystemReset *system_reset;
|
||||
+};
|
||||
+
|
||||
+struct VirtioMemSystemReset {
|
||||
+ Object parent;
|
||||
+
|
||||
ResettableState reset_state;
|
||||
+ VirtIOMEM *vmem;
|
||||
};
|
||||
|
||||
struct VirtIOMEMClass {
|
||||
--
|
||||
2.48.1
|
||||
|
@ -149,7 +149,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
|
||||
Summary: QEMU is a machine emulator and virtualizer
|
||||
Name: qemu-kvm
|
||||
Version: 9.1.0
|
||||
Release: 17%{?rcrel}%{?dist}%{?cc_suffix}
|
||||
Release: 18%{?rcrel}%{?dist}%{?cc_suffix}
|
||||
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
||||
# Epoch 15 used for RHEL 8
|
||||
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
||||
@ -493,6 +493,58 @@ Patch160: kvm-vfio-pci-Delete-local-pm_cap.patch
|
||||
Patch161: kvm-pcie-virtio-Remove-redundant-pm_cap.patch
|
||||
# For RHEL-7301 - [intel iommu] VFIO_MAP_DMA failed: Bad address on system_powerdown
|
||||
Patch162: kvm-hw-vfio-pci-Re-order-pre-reset.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch163: kvm-virtio-kconfig-memory-devices-are-PCI-only.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch164: kvm-hw-s390-ccw-device-Convert-to-three-phase-reset.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch165: kvm-hw-s390-virtio-ccw-Convert-to-three-phase-reset.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch166: kvm-target-s390-Convert-CPU-to-Resettable-interface.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch167: kvm-reset-Use-ResetType-for-qemu_devices_reset-and-Machi.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch168: kvm-reset-Add-RESET_TYPE_WAKEUP.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch169: kvm-virtio-mem-Use-new-Resettable-framework-instead-of-L.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch170: kvm-virtio-mem-Add-support-for-suspend-wake-up-with-plug.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch171: kvm-virtio-mem-unplug-memory-only-during-system-resets-n.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch172: kvm-s390x-s390-virtio-ccw-don-t-crash-on-weird-RAM-sizes.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch173: kvm-s390x-s390-virtio-hcall-remove-hypercall-registratio.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch174: kvm-s390x-s390-virtio-hcall-prepare-for-more-diag500-hyp.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch175: kvm-s390x-rename-s390-virtio-hcall-to-s390-hypercall.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch176: kvm-s390x-s390-virtio-ccw-move-setting-the-maximum-guest.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch177: kvm-s390x-introduce-s390_get_memory_limit.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch178: kvm-s390x-s390-hypercall-introduce-DIAG500-STORAGE_LIMIT.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch179: kvm-s390x-s390-stattrib-kvm-prepare-for-memory-devices-a.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch180: kvm-s390x-s390-skeys-prepare-for-memory-devices.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch181: kvm-s390x-s390-virtio-ccw-prepare-for-memory-devices.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch182: kvm-s390x-pv-prepare-for-memory-devices.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch183: kvm-s390x-remember-the-maximum-page-size.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch184: kvm-s390x-virtio-ccw-add-support-for-virtio-based-memory.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch185: kvm-s390x-virtio-mem-support.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch186: kvm-hw-virtio-Also-include-md-stubs-in-case-CONFIG_VIRTI.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch187: kvm-virtio-mem-don-t-warn-about-THP-sizes-on-a-kernel-wi.patch
|
||||
# For RHEL-72977 - [IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part
|
||||
Patch188: kvm-redhat-Enable-virtio-mem-on-s390x.patch
|
||||
|
||||
%if %{have_clang}
|
||||
BuildRequires: clang
|
||||
@ -1561,6 +1613,36 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Apr 14 2025 Jon Maloy <jmaloy@redhat.com> - 9.1.0-18
|
||||
- kvm-virtio-kconfig-memory-devices-are-PCI-only.patch [RHEL-72977]
|
||||
- kvm-hw-s390-ccw-device-Convert-to-three-phase-reset.patch [RHEL-72977]
|
||||
- kvm-hw-s390-virtio-ccw-Convert-to-three-phase-reset.patch [RHEL-72977]
|
||||
- kvm-target-s390-Convert-CPU-to-Resettable-interface.patch [RHEL-72977]
|
||||
- kvm-reset-Use-ResetType-for-qemu_devices_reset-and-Machi.patch [RHEL-72977]
|
||||
- kvm-reset-Add-RESET_TYPE_WAKEUP.patch [RHEL-72977]
|
||||
- kvm-virtio-mem-Use-new-Resettable-framework-instead-of-L.patch [RHEL-72977]
|
||||
- kvm-virtio-mem-Add-support-for-suspend-wake-up-with-plug.patch [RHEL-72977]
|
||||
- kvm-virtio-mem-unplug-memory-only-during-system-resets-n.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-virtio-ccw-don-t-crash-on-weird-RAM-sizes.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-virtio-hcall-remove-hypercall-registratio.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-virtio-hcall-prepare-for-more-diag500-hyp.patch [RHEL-72977]
|
||||
- kvm-s390x-rename-s390-virtio-hcall-to-s390-hypercall.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-virtio-ccw-move-setting-the-maximum-guest.patch [RHEL-72977]
|
||||
- kvm-s390x-introduce-s390_get_memory_limit.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-hypercall-introduce-DIAG500-STORAGE_LIMIT.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-stattrib-kvm-prepare-for-memory-devices-a.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-skeys-prepare-for-memory-devices.patch [RHEL-72977]
|
||||
- kvm-s390x-s390-virtio-ccw-prepare-for-memory-devices.patch [RHEL-72977]
|
||||
- kvm-s390x-pv-prepare-for-memory-devices.patch [RHEL-72977]
|
||||
- kvm-s390x-remember-the-maximum-page-size.patch [RHEL-72977]
|
||||
- kvm-s390x-virtio-ccw-add-support-for-virtio-based-memory.patch [RHEL-72977]
|
||||
- kvm-s390x-virtio-mem-support.patch [RHEL-72977]
|
||||
- kvm-hw-virtio-Also-include-md-stubs-in-case-CONFIG_VIRTI.patch [RHEL-72977]
|
||||
- kvm-virtio-mem-don-t-warn-about-THP-sizes-on-a-kernel-wi.patch [RHEL-72977]
|
||||
- kvm-redhat-Enable-virtio-mem-on-s390x.patch [RHEL-72977]
|
||||
- Resolves: RHEL-72977
|
||||
([IBM 9.7 FEAT] KVM: Enable virtio-mem support - qemu part)
|
||||
|
||||
* Mon Mar 31 2025 Jon Maloy <jmaloy@redhat.com> - 9.1.0-17
|
||||
- kvm-hw-pci-Rename-has_power-to-enabled.patch [RHEL-7301]
|
||||
- kvm-hw-pci-Basic-support-for-PCI-power-management.patch [RHEL-7301]
|
||||
|
Loading…
Reference in New Issue
Block a user