- 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)
285 lines
10 KiB
Diff
285 lines
10 KiB
Diff
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
|
|
|