@samitouri / QOSamiQemu / commits / d51fcd7fb8

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;