master
c 482 lines 16.4 KB
Raw
1 /*
2 * Emulation of MPIPL (Memory Preserving Initial Program Load), aka fadump
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "qemu/osdep.h"
8 #include "qemu/log.h"
9 #include "qemu/units.h"
10 #include "system/address-spaces.h"
11 #include "system/cpus.h"
12 #include "system/hw_accel.h"
13 #include "system/memory.h"
14 #include "system/runstate.h"
15 #include "hw/ppc/pnv.h"
16 #include "hw/ppc/pnv_mpipl.h"
17 #include <math.h>
18
19 #define MDST_TABLE_RELOCATED \
20 (pnv->mpipl_state.skiboot_base + MDST_TABLE_OFF)
21 #define MDDT_TABLE_RELOCATED \
22 (pnv->mpipl_state.skiboot_base + MDDT_TABLE_OFF)
23 #define MDRT_TABLE_RELOCATED \
24 (pnv->mpipl_state.skiboot_base + MDRT_TABLE_OFF)
25 #define PROC_DUMP_RELOCATED \
26 (pnv->mpipl_state.skiboot_base + PROC_DUMP_AREA_OFF)
27
28 /*
29 * Preserve the memory regions as pointed by MDST table
30 *
31 * During this, the memory region pointed by entries in MDST, are 'copied'
32 * as it is to the memory region pointed by corresponding entry in MDDT
33 *
34 * Notes: All reads should consider data coming from skiboot as big-endian,
35 * and data written should also be in big-endian
36 */
37 static bool pnv_mpipl_preserve_mem(PnvMachineState *pnv)
38 {
39 g_autofree MdstTableEntry *mdst = g_malloc(MDST_TABLE_SIZE);
40 g_autofree MddtTableEntry *mddt = g_malloc(MDDT_TABLE_SIZE);
41 g_autofree MdrtTableEntry *mdrt = g_malloc0(MDRT_TABLE_SIZE);
42 AddressSpace *default_as = &address_space_memory;
43 MemTxResult io_result;
44 MemTxAttrs attrs;
45 uint64_t src_addr, dest_addr;
46 uint32_t data_len;
47 uint64_t num_chunks, chunk_id = 0;
48 int mdrt_idx = 0;
49
50 /* Mark the memory transactions as privileged memory access */
51 attrs.user = 0;
52 attrs.memory = 1;
53
54 if (pnv->mpipl_state.mdrt_table) {
55 /*
56 * MDRT table allocated from some past crash, free the memory to
57 * prevent memory leak
58 */
59 g_free(pnv->mpipl_state.mdrt_table);
60 pnv->mpipl_state.num_mdrt_entries = 0;
61 }
62
63 io_result = address_space_read(default_as, MDST_TABLE_RELOCATED, attrs,
64 mdst, MDST_TABLE_SIZE);
65 if (io_result != MEMTX_OK) {
66 qemu_log_mask(LOG_GUEST_ERROR,
67 "MPIPL: Failed to read MDST table at: 0x" TARGET_FMT_lx "\n",
68 MDST_TABLE_RELOCATED);
69
70 return false;
71 }
72
73 io_result = address_space_read(default_as, MDDT_TABLE_RELOCATED, attrs,
74 mddt, MDDT_TABLE_SIZE);
75 if (io_result != MEMTX_OK) {
76 qemu_log_mask(LOG_GUEST_ERROR,
77 "MPIPL: Failed to read MDDT table at: 0x" TARGET_FMT_lx "\n",
78 MDDT_TABLE_RELOCATED);
79
80 return false;
81 }
82
83 /* Try to read all entries */
84 for (int i = 0; i < MDST_MAX_ENTRIES; ++i) {
85 g_autofree uint8_t *copy_buffer = NULL;
86 bool is_copy_failed = false;
87
88 /* Considering entry with address and size as 0, as end of table */
89 if ((mdst[i].addr == 0) && (mdst[i].size == 0)) {
90 break;
91 }
92
93 if (mdst[i].size != mddt[i].size) {
94 qemu_log_mask(LOG_TRACE,
95 "Warning: Invalid entry, size mismatch in MDST & MDDT\n");
96 continue;
97 }
98
99 if (mdst[i].data_region != mddt[i].data_region) {
100 qemu_log_mask(LOG_TRACE,
101 "Warning: Invalid entry, region mismatch in MDST & MDDT\n");
102 continue;
103 }
104
105 src_addr = be64_to_cpu(mdst[i].addr) & ~HRMOR_BIT;
106 dest_addr = be64_to_cpu(mddt[i].addr) & ~HRMOR_BIT;
107 data_len = be32_to_cpu(mddt[i].size);
108
109 #define COPY_CHUNK_SIZE ((size_t)(32 * MiB))
110 copy_buffer = g_try_malloc(COPY_CHUNK_SIZE);
111 if (copy_buffer == NULL) {
112 qemu_log_mask(LOG_GUEST_ERROR,
113 "MPIPL: Failed allocating memory (size: %zu) for copying"
114 " reserved memory regions\n", COPY_CHUNK_SIZE);
115 is_copy_failed = true;
116 continue;
117 }
118
119 chunk_id = 0;
120 num_chunks = ceil((data_len * 1.0f) / COPY_CHUNK_SIZE);
121 while (chunk_id < num_chunks) {
122 /* Take minimum of bytes left to copy, and chunk size */
123 uint64_t copy_len = MIN(
124 data_len - (chunk_id * COPY_CHUNK_SIZE),
125 COPY_CHUNK_SIZE
126 );
127
128 /* Copy the source region to destination */
129 io_result = address_space_read(default_as, src_addr, attrs,
130 copy_buffer, copy_len);
131 if (io_result != MEMTX_OK) {
132 qemu_log_mask(LOG_GUEST_ERROR,
133 "MPIPL: Failed to read region at: 0x%" PRIx64 "\n",
134 src_addr);
135 is_copy_failed = true;
136 break;
137 }
138
139 io_result = address_space_write(default_as, dest_addr, attrs,
140 copy_buffer, copy_len);
141 if (io_result != MEMTX_OK) {
142 qemu_log_mask(LOG_GUEST_ERROR,
143 "MPIPL: Failed to write region at: 0x%" PRIx64 "\n",
144 dest_addr);
145 is_copy_failed = true;
146 break;
147 }
148
149 src_addr += COPY_CHUNK_SIZE;
150 dest_addr += COPY_CHUNK_SIZE;
151 ++chunk_id;
152 }
153 #undef COPY_CHUNK_SIZE
154
155 if (is_copy_failed) {
156 /*
157 * HDAT doesn't specify an error code in MDRT for failed copy,
158 * and doesn't specify how this is to be handled
159 * Hence just skip adding an entry in MDRT, as done for size
160 * mismatch or other inconsistency between MDST/MDDT
161 */
162 continue;
163 }
164
165 /* Populate entry in MDRT table if preserving successful */
166 mdrt[mdrt_idx].src_addr = cpu_to_be64(src_addr);
167 mdrt[mdrt_idx].dest_addr = cpu_to_be64(dest_addr);
168 mdrt[mdrt_idx].size = cpu_to_be32(data_len);
169 mdrt[mdrt_idx].data_region = mdst[i].data_region;
170 ++mdrt_idx;
171 }
172
173 pnv->mpipl_state.mdrt_table = g_steal_pointer(&mdrt);
174 pnv->mpipl_state.num_mdrt_entries = mdrt_idx;
175
176 return true;
177 }
178
179 static void do_store_cpu_regs(CPUState *cpu, MpiplPreservedCPUState *state)
180 {
181 CPUPPCState *env = cpu_env(cpu);
182 MpiplRegDataHdr *regs_hdr = &state->hdr;
183 MpiplRegEntry *reg_entries = state->reg_entries;
184 MpiplRegEntry *curr_reg_entry;
185 uint32_t num_saved_regs = 0;
186
187 cpu_synchronize_state(cpu);
188
189 regs_hdr->pir = cpu_to_be32(env->spr[SPR_PIR]);
190
191 /* QEMU CPUs are not in Power Saving Mode */
192 regs_hdr->core_state = 0xff;
193
194 regs_hdr->off_regentries = 0;
195 regs_hdr->num_regentries = cpu_to_be32(NUM_REGS_PER_CPU);
196
197 regs_hdr->alloc_size = cpu_to_be32(sizeof(MpiplRegEntry));
198 regs_hdr->act_size = cpu_to_be32(sizeof(MpiplRegEntry));
199
200 #define REG_TYPE_GPR 0x1
201 #define REG_TYPE_SPR 0x2
202 #define REG_TYPE_TIMA 0x3
203
204 /*
205 * ID numbers used by f/w while populating certain registers
206 *
207 * Copied these defines from the linux kernel
208 */
209 #define REG_ID_NIP 0x7D0
210 #define REG_ID_MSR 0x7D1
211 #define REG_ID_CCR 0x7D2
212
213 curr_reg_entry = reg_entries;
214
215 #define REG_ENTRY(type, num, val) \
216 do { \
217 curr_reg_entry->reg_type = cpu_to_be32(type); \
218 curr_reg_entry->reg_num = cpu_to_be32(num); \
219 curr_reg_entry->reg_val = cpu_to_be64(val); \
220 ++curr_reg_entry; \
221 ++num_saved_regs; \
222 } while (0)
223
224 /* Save the GPRs */
225 for (int gpr_id = 0; gpr_id < 32; ++gpr_id) {
226 REG_ENTRY(REG_TYPE_GPR, gpr_id, env->gpr[gpr_id]);
227 }
228
229 REG_ENTRY(REG_TYPE_SPR, SPR_ACOP, env->spr[SPR_ACOP]);
230 REG_ENTRY(REG_TYPE_SPR, SPR_AMR, env->spr[SPR_AMR]);
231 REG_ENTRY(REG_TYPE_SPR, SPR_BESCR, env->spr[SPR_BESCR]);
232 REG_ENTRY(REG_TYPE_SPR, SPR_CFAR, env->spr[SPR_CFAR]);
233 REG_ENTRY(REG_TYPE_SPR, SPR_CIABR, env->spr[SPR_CIABR]);
234
235 REG_ENTRY(REG_TYPE_SPR, SPR_CTR, env->spr[SPR_CTR]);
236 REG_ENTRY(REG_TYPE_SPR, SPR_CTRL, env->spr[SPR_CTRL]);
237 REG_ENTRY(REG_TYPE_SPR, SPR_DABR, env->spr[SPR_DABR]);
238 REG_ENTRY(REG_TYPE_SPR, SPR_DABRX, env->spr[SPR_DABRX]);
239 REG_ENTRY(REG_TYPE_SPR, SPR_DAR, env->spr[SPR_DAR]);
240 REG_ENTRY(REG_TYPE_SPR, SPR_DAWR0, env->spr[SPR_DAWR0]);
241 REG_ENTRY(REG_TYPE_SPR, SPR_DAWR1, env->spr[SPR_DAWR1]);
242 REG_ENTRY(REG_TYPE_SPR, SPR_DAWRX0, env->spr[SPR_DAWRX0]);
243 REG_ENTRY(REG_TYPE_SPR, SPR_DAWRX1, env->spr[SPR_DAWRX1]);
244 REG_ENTRY(REG_TYPE_SPR, SPR_DPDES, env->spr[SPR_DPDES]);
245 REG_ENTRY(REG_TYPE_SPR, SPR_DSCR, env->spr[SPR_DSCR]);
246 REG_ENTRY(REG_TYPE_SPR, SPR_DSISR, env->spr[SPR_DSISR]);
247 REG_ENTRY(REG_TYPE_SPR, SPR_EBBHR, env->spr[SPR_EBBHR]);
248 REG_ENTRY(REG_TYPE_SPR, SPR_EBBRR, env->spr[SPR_EBBRR]);
249
250 REG_ENTRY(REG_TYPE_SPR, SPR_FSCR, env->spr[SPR_FSCR]);
251
252 REG_ENTRY(REG_TYPE_SPR, SPR_CTR, env->ctr);
253 REG_ENTRY(REG_TYPE_SPR, SPR_DAR, env->spr[SPR_DAR]);
254 REG_ENTRY(REG_TYPE_SPR, SPR_DSISR, env->spr[SPR_DSISR]);
255 REG_ENTRY(REG_TYPE_SPR, SPR_LR, env->lr);
256 REG_ENTRY(REG_TYPE_SPR, REG_ID_MSR, env->msr);
257 REG_ENTRY(REG_TYPE_SPR, REG_ID_NIP, env->nip);
258 REG_ENTRY(REG_TYPE_SPR, SPR_XER, env->xer);
259 REG_ENTRY(REG_TYPE_SPR, SPR_SRR0, env->spr[SPR_SRR0]);
260 REG_ENTRY(REG_TYPE_SPR, SPR_SRR1, env->spr[SPR_SRR1]);
261 REG_ENTRY(REG_TYPE_SPR, SPR_HSRR0, env->spr[SPR_HSRR0]);
262 REG_ENTRY(REG_TYPE_SPR, SPR_HSRR1, env->spr[SPR_HSRR1]);
263 REG_ENTRY(REG_TYPE_SPR, SPR_CFAR, env->spr[SPR_CFAR]);
264 REG_ENTRY(REG_TYPE_SPR, SPR_HMER, env->spr[SPR_HMER]);
265 REG_ENTRY(REG_TYPE_SPR, SPR_HMEER, env->spr[SPR_HMEER]);
266
267 /*
268 * Ensure the number of registers saved match the number of
269 * registers per cpu
270 *
271 * This will help catch an error if in future a new register entry
272 * is added/removed while not modifying NUM_PER_CPU_REGS
273 */
274 assert(num_saved_regs == NUM_REGS_PER_CPU);
275 }
276
277 static bool pnv_mpipl_preserve_cpu_state(PnvMachineState *pnv)
278 {
279 MachineState *machine = MACHINE(pnv);
280 uint32_t num_cpus = machine->smp.cpus;
281 MpiplPreservedCPUState *state;
282 CPUState *cpu;
283 AddressSpace *default_as = &address_space_memory;
284 MemTxResult io_result;
285 MemTxAttrs attrs;
286
287 /* Mark the memory transactions as privileged memory access */
288 attrs.user = 0;
289 attrs.memory = 1;
290
291 if (pnv->mpipl_state.cpu_states) {
292 /*
293 * CPU States might have been allocated from some past crash, free the
294 * memory to preven memory leak
295 */
296 g_free(pnv->mpipl_state.cpu_states);
297 pnv->mpipl_state.num_cpu_states = 0;
298 }
299
300 pnv->mpipl_state.cpu_states = g_malloc_n(num_cpus,
301 sizeof(MpiplPreservedCPUState));
302 pnv->mpipl_state.num_cpu_states = num_cpus;
303
304 state = pnv->mpipl_state.cpu_states;
305
306 /* Preserve the Processor Dump Area */
307 io_result = address_space_read(default_as, PROC_DUMP_RELOCATED, attrs,
308 &pnv->mpipl_state.proc_area, sizeof(MpiplProcDumpArea));
309 if (io_result != MEMTX_OK) {
310 qemu_log_mask(LOG_GUEST_ERROR,
311 "MPIPL: Failed to read Proc Dump Area at: 0x" TARGET_FMT_lx "\n",
312 PROC_DUMP_RELOCATED);
313
314 return false;
315 }
316
317 CPU_FOREACH(cpu) {
318 do_store_cpu_regs(cpu, state);
319 ++state;
320 }
321
322 return true;
323 }
324
325 /*
326 * Write the preserved CPU state data in Processor Dump Area (PROC_DUMP_AREA)
327 *
328 * Returns true if everything went fine, else false for any error
329 */
330 static bool pnv_mpipl_write_cpu_state(PnvMachineState *pnv)
331 {
332 MpiplProcDumpArea *proc_area = &pnv->mpipl_state.proc_area;
333 MpiplPreservedCPUState *cpu_state = pnv->mpipl_state.cpu_states;
334 const uint32_t num_cpu_states = pnv->mpipl_state.num_cpu_states;
335 hwaddr next_regentries_hdr;
336 AddressSpace *default_as = &address_space_memory;
337 MemTxResult io_result;
338 MemTxAttrs attrs;
339
340 /* Mark the memory transactions as privileged memory access */
341 attrs.user = 0;
342 attrs.memory = 1;
343
344 if (be32_to_cpu(proc_area->alloc_size) <
345 (num_cpu_states * sizeof(MpiplPreservedCPUState))) {
346 qemu_log_mask(LOG_GUEST_ERROR,
347 "MPIPL: Size of buffer allocate by skiboot (%u bytes) is not"
348 "enough to save all CPUs registers needed (%zu bytes)",
349 be32_to_cpu(proc_area->alloc_size),
350 num_cpu_states * sizeof(MpiplPreservedCPUState));
351
352 return false;
353 }
354
355 proc_area->version = PROC_DUMP_AREA_VERSION_P9;
356
357 /*
358 * This is the stride kernel/firmware should use to jump from a
359 * register entries header to next CPU's header
360 */
361 proc_area->thread_size = cpu_to_be32(sizeof(MpiplPreservedCPUState));
362
363 /* Write the header and register entries for each CPU */
364 next_regentries_hdr = be64_to_cpu(proc_area->alloc_addr) & (~HRMOR_BIT);
365 for (int i = 0; i < num_cpu_states; ++i) {
366 io_result = address_space_write(default_as, next_regentries_hdr, attrs,
367 &cpu_state->hdr, sizeof(MpiplRegDataHdr));
368 if (io_result != MEMTX_OK) {
369 qemu_log_mask(LOG_GUEST_ERROR,
370 "MPIPL: Failed to write RegEntries Header\n");
371 return false;
372 }
373
374 io_result = address_space_write(default_as,
375 next_regentries_hdr + sizeof(MpiplRegDataHdr), attrs,
376 &cpu_state->reg_entries,
377 NUM_REGS_PER_CPU * (sizeof(MpiplRegEntry)));
378 if (io_result != MEMTX_OK) {
379 qemu_log_mask(LOG_GUEST_ERROR,
380 "MPIPL: Failed to write Register Entries\n");
381 return false;
382 }
383
384 /*
385 * According to HDAT section:
386 * "15.3.1.5 Architected Register Data content":
387 *
388 * The next register entries header will be at current header +
389 * "Thread Register State Entry size"
390 *
391 * Note: proc_area.thread_size == sizeof(MpiplPreservedCPUState)
392 */
393 next_regentries_hdr += sizeof(MpiplPreservedCPUState);
394 ++cpu_state;
395 }
396
397 /* Point the destination address to the preserved memory region */
398 proc_area->dest_addr = proc_area->alloc_addr;
399 proc_area->act_size = cpu_to_be32(num_cpu_states *
400 sizeof(MpiplPreservedCPUState));
401
402 io_result = address_space_write(default_as, PROC_DUMP_AREA_OFF, attrs,
403 proc_area, sizeof(MpiplProcDumpArea));
404 if (io_result != MEMTX_OK) {
405 qemu_log_mask(LOG_GUEST_ERROR,
406 "MPIPL: Failed to write Register Entries\n");
407 return false;
408 }
409
410 return true;
411 }
412
413 /*
414 * Write the preserved MDRT table, representing preserved memory regions
415 *
416 * Returns true if everything went fine, else false for any error
417 */
418 static bool pnv_mpipl_write_mdrt(PnvMachineState *pnv)
419 {
420 MpiplPreservedState *state = &pnv->mpipl_state;
421 AddressSpace *default_as = &address_space_memory;
422 MemTxResult io_result;
423 MemTxAttrs attrs;
424
425 /* Mark the memory transactions as privileged memory access */
426 attrs.user = 0;
427 attrs.memory = 1;
428
429 /*
430 * Generally writes from platform during MPIPL don't go to a relocated
431 * skiboot address
432 *
433 * Though for MDRT we are doing so, as this is the address skiboot
434 * considers by default for MDRT
435 *
436 * MDRT/MDST/MDDT base addresses are actually meant to be shared by
437 * platform in SPIRA structures.
438 *
439 * Not implementing SPIRA as it increases complexity for no gains.
440 * Using the default address skiboot expects for MDRT, which is the
441 * relocated MDRT, hence writing to it
442 *
443 * Other tables like MDST/MDDT should not be written to relocated
444 * addresses, as skiboot will overwrite anything from SKIBOOT_BASE till
445 * SKIBOOT_BASE+SKIBOOT_SIZE (which is 0x30000000-0x31c00000 by default)
446 */
447 io_result = address_space_write(default_as, MDRT_TABLE_RELOCATED, attrs,
448 state->mdrt_table,
449 state->num_mdrt_entries * sizeof(MdrtTableEntry));
450 if (io_result != MEMTX_OK) {
451 qemu_log_mask(LOG_GUEST_ERROR, "MPIPL: Failed to write MDRT table\n");
452 return false;
453 }
454
455 return true;
456 }
457
458 void do_mpipl_preserve(PnvMachineState *pnv)
459 {
460 pause_all_vcpus();
461
462 pnv_mpipl_preserve_mem(pnv);
463 pnv_mpipl_preserve_cpu_state(pnv);
464
465 /* Mark next boot as Memory-preserving boot */
466 pnv->mpipl_state.is_next_boot_mpipl = true;
467
468 /*
469 * Do a guest reset.
470 * Next reset will see 'is_next_boot_mpipl' as true, and trigger MPIPL
471 *
472 * Requirement:
473 * GUEST_RESET is expected to NOT clear the memory, as is the case when
474 * this is merged
475 */
476 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
477 }
478
479 bool do_mpipl_write(PnvMachineState *pnv)
480 {
481 return pnv_mpipl_write_mdrt(pnv) && pnv_mpipl_write_cpu_state(pnv);
482 }