hw/s390x/ipl: Remove TCG dependency in handle_diag_308()
Rather than calling a TCG specific method in s390_ipl_reset_request(), have handle_diag_308() return whether a vCPU reset is pending, and use that in the TCG DIAG helper to return to the main loop. Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Jared Rossi <jrossi@linux.ibm.com> Message-Id: <20260617164035.70788-4-philmd@oss.qualcomm.com>
Philippe Mathieu-Daudé committed
Jun 12, 2026 at 15:51 UTC
d51fcd7fb81ca188f32a0aa9f418a33a49608f75
4 files changed
+22
-23
hw/s390x/ipl.c
-5
@@ -18,7 +18,6 @@
18
#include "system/physmem.h"
19
#include "system/reset.h"
20
#include "system/runstate.h"
21
-#include "system/tcg.h"
21
#include "elf.h"
22
#include "hw/core/loader.h"
23
#include "hw/core/qdev-properties.h"
@@ -690,10 +689,6 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
689
} else {
690
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
691
}
693
- /* as this is triggered by a CPU, make sure to exit the loop */
694
- if (tcg_enabled()) {
695
- cpu_loop_exit(cs);
696
- }
692
}
693
694
void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type)
target/s390x/diag.c
+16
-16
@@ -95,7 +95,7 @@ static void s390_ipl_write(CPUS390XState *env, uint64_t addr,
95
}
96
}
97
98
-void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
98
+bool handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
99
{
100
bool valid;
101
CPUState *cs = env_cpu(env);
@@ -105,34 +105,34 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
105
106
if (env->psw.mask & PSW_MASK_PSTATE) {
107
s390_program_interrupt(env, PGM_PRIVILEGED, ra);
108
- return;
108
+ return false;
109
}
110
111
if (subcode & ~0x0ffffULL) {
112
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
113
- return;
113
+ return false;
114
}
115
116
if (subcode >= DIAG308_PV_SET && !s390_has_feat(S390_FEAT_UNPACK)) {
117
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
118
- return;
118
+ return false;
119
}
120
121
switch (subcode) {
122
case DIAG308_RESET_MOD_CLR:
123
s390_ipl_reset_request(cs, S390_RESET_MODIFIED_CLEAR);
124
- break;
124
+ return true;
125
case DIAG308_RESET_LOAD_NORM:
126
s390_ipl_reset_request(cs, S390_RESET_LOAD_NORMAL);
127
- break;
127
+ return true;
128
case DIAG308_LOAD_CLEAR:
129
/* Well we still lack the clearing bit... */
130
s390_ipl_reset_request(cs, S390_RESET_REIPL);
131
- break;
131
+ return true;
132
case DIAG308_SET:
133
case DIAG308_PV_SET:
134
if (diag308_parm_check(env, r1, addr, ra, false)) {
135
- return;
135
+ return false;
136
}
137
iplb = g_new0(IplParameterBlock, 1);
138
s390_ipl_read(env, addr, iplb, sizeof(iplb->len));
@@ -159,11 +159,11 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
159
env->regs[r1 + 1] = DIAG_308_RC_OK;
160
out:
161
g_free(iplb);
162
- return;
162
+ return false;
163
case DIAG308_STORE:
164
case DIAG308_PV_STORE:
165
if (diag308_parm_check(env, r1, addr, ra, true)) {
166
- return;
166
+ return false;
167
}
168
if (subcode == DIAG308_PV_STORE) {
169
iplb = s390_ipl_get_iplb_pv();
@@ -172,30 +172,30 @@ out:
172
}
173
if (!iplb) {
174
env->regs[r1 + 1] = DIAG_308_RC_NO_CONF;
175
- return;
175
+ return false;
176
}
177
178
s390_ipl_write(env, addr, iplb, be32_to_cpu(iplb->len));
179
env->regs[r1 + 1] = DIAG_308_RC_OK;
180
- return;
180
+ return false;
181
case DIAG308_PV_START:
182
iplb = s390_ipl_get_iplb_pv();
183
if (!iplb) {
184
env->regs[r1 + 1] = DIAG_308_RC_NO_PV_CONF;
185
- return;
185
+ return false;
186
}
187
188
if (kvm_enabled() && kvm_s390_get_hpage_1m()) {
189
error_report("Protected VMs can currently not be backed with "
190
"huge pages");
191
env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
192
- return;
192
+ return false;
193
}
194
195
s390_ipl_reset_request(cs, S390_RESET_PV);
196
- break;
196
+ return true;
197
default:
198
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
199
- break;
199
+ return false;
200
}
201
}
target/s390x/s390x-internal.h
+2
-1
@@ -385,7 +385,8 @@ int mmu_translate_real(CPUS390XState *env, hwaddr raddr, int rw,
385
386
/* misc_helper.c */
387
int handle_diag_288(CPUS390XState *env, uint64_t r1, uint64_t r3);
388
-void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
388
+/* Return whether a CPU reset is pending */
389
+bool handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3,
390
uintptr_t ra);
391
392
target/s390x/tcg/misc_helper.c
+4
-1
@@ -135,7 +135,10 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)
135
case 0x308:
136
/* ipl */
137
bql_lock();
138
- handle_diag_308(env, r1, r3, GETPC());
138
+ if (handle_diag_308(env, r1, r3, GETPC())) {
139
+ /* As reset is triggered by the CPU, make sure to exit the loop */
140
+ cpu_loop_exit(CPU(env_archcpu(env)));
141
+ }
142
bql_unlock();
143
r = 0;
144
break;