@@ -26,6 +26,7 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
'spapr_nvdimm.c',
'spapr_rtas_ddw.c',
'spapr_numa.c',
+ 'spapr_fadump.c',
'pef.c',
))
ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_TCG'], if_true: files(
new file mode 100644
@@ -0,0 +1,22 @@
+/*
+ * Firmware Assisted Dump in PSeries
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ppc/spapr.h"
+
+/*
+ * Handle the "FADUMP_CMD_REGISTER" command in 'ibm,configure-kernel-dump'
+ *
+ * Returns:
+ * * RTAS_OUT_HW_ERROR: Not implemented/Misc issue such as memory access
+ * failures
+ */
+uint32_t do_fadump_register(void)
+{
+ /* WIP: FADUMP_CMD_REGISTER implemented in future patch */
+
+ return RTAS_OUT_HW_ERROR;
+}
@@ -341,6 +341,68 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
rtas_st(rets, 0, ret);
}
+/* Papr Section 7.4.9 ibm,configure-kernel-dump RTAS call */
+static void rtas_configure_kernel_dump(PowerPCCPU *cpu,
+ SpaprMachineState *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+ target_ulong cmd = rtas_ld(args, 0);
+ uint32_t ret_val;
+
+ /* Number of outputs has to be 1 */
+ if (nret != 1) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "FADump: ibm,configure-kernel-dump RTAS called with nret != 1.\n");
+ return;
+ }
+
+ /* Number of inputs has to be 3 */
+ if (nargs != 3) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ switch (cmd) {
+ case FADUMP_CMD_REGISTER:
+ ret_val = do_fadump_register();
+ if (ret_val != RTAS_OUT_SUCCESS) {
+ rtas_st(rets, 0, ret_val);
+ return;
+ }
+ break;
+ case FADUMP_CMD_UNREGISTER:
+ if (spapr->fadump_dump_active == 1) {
+ rtas_st(rets, 0, RTAS_OUT_DUMP_ACTIVE);
+ return;
+ }
+
+ spapr->fadump_registered = false;
+ spapr->fadump_dump_active = false;
+ memset(&spapr->registered_fdm, 0, sizeof(spapr->registered_fdm));
+ break;
+ case FADUMP_CMD_INVALIDATE:
+ if (spapr->fadump_dump_active) {
+ spapr->fadump_registered = false;
+ spapr->fadump_dump_active = false;
+ memset(&spapr->registered_fdm, 0, sizeof(spapr->registered_fdm));
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "FADump: Nothing to invalidate, no dump active\n");
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "FADump: Unknown command: %lu\n", cmd);
+
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
static void rtas_ibm_os_term(PowerPCCPU *cpu,
SpaprMachineState *spapr,
uint32_t token, uint32_t nargs,
@@ -656,6 +718,10 @@ static void core_rtas_register_types(void)
spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
rtas_ibm_nmi_interlock);
+ /* Register fadump rtas call */
+ spapr_rtas_register(RTAS_CONFIGURE_KERNEL_DUMP, "ibm,configure-kernel-dump",
+ rtas_configure_kernel_dump);
+
qtest_set_command_cb(spapr_qtest_callback);
}
@@ -13,6 +13,7 @@
#include "hw/ppc/xics.h" /* For ICSState */
#include "hw/ppc/spapr_tpm_proxy.h"
#include "hw/ppc/spapr_nested.h" /* For SpaprMachineStateNested */
+#include "hw/ppc/spapr_fadump.h" /* For FadumpMemStruct */
struct SpaprVioBus;
struct SpaprPhbState;
@@ -283,6 +284,11 @@ struct SpaprMachineState {
Error *fwnmi_migration_blocker;
SpaprWatchdog wds[WDT_MAX_WATCHDOGS];
+
+ /* Fadump State */
+ bool fadump_registered;
+ bool fadump_dump_active;
+ FadumpMemStruct registered_fdm;
};
#define H_SUCCESS 0
@@ -708,6 +714,8 @@ void push_sregs_to_kvm_pr(SpaprMachineState *spapr);
#define RTAS_OUT_PARAM_ERROR -3
#define RTAS_OUT_NOT_SUPPORTED -3
#define RTAS_OUT_NO_SUCH_INDICATOR -3
+#define RTAS_OUT_DUMP_ALREADY_REGISTERED -9
+#define RTAS_OUT_DUMP_ACTIVE -10
#define RTAS_OUT_NOT_AUTHORIZED -9002
#define RTAS_OUT_SYSPARM_PARAM_ERROR -9999
@@ -770,8 +778,9 @@ void push_sregs_to_kvm_pr(SpaprMachineState *spapr);
#define RTAS_IBM_SUSPEND_ME (RTAS_TOKEN_BASE + 0x2A)
#define RTAS_IBM_NMI_REGISTER (RTAS_TOKEN_BASE + 0x2B)
#define RTAS_IBM_NMI_INTERLOCK (RTAS_TOKEN_BASE + 0x2C)
+#define RTAS_CONFIGURE_KERNEL_DUMP (RTAS_TOKEN_BASE + 0x2D)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2D)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2E)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
new file mode 100644
@@ -0,0 +1,69 @@
+/*
+ * Firmware Assisted Dump in PSeries
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef PPC_SPAPR_FADUMP_H
+#define PPC_SPAPR_FADUMP_H
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+/* Fadump commands */
+#define FADUMP_CMD_REGISTER 1
+#define FADUMP_CMD_UNREGISTER 2
+#define FADUMP_CMD_INVALIDATE 3
+
+#define FADUMP_VERSION 1
+
+/*
+ * The Firmware Assisted Dump Memory structure supports a maximum of 10 sections
+ * in the dump memory structure. Presently, three sections are used for
+ * CPU state data, HPTE & Parameters area, while the remaining seven sections
+ * can be used for boot memory regions.
+ */
+#define FADUMP_MAX_SECTIONS 10
+#define RTAS_FADUMP_MAX_BOOT_MEM_REGS 7
+
+typedef struct FadumpSection FadumpSection;
+typedef struct FadumpSectionHeader FadumpSectionHeader;
+typedef struct FadumpMemStruct FadumpMemStruct;
+
+struct SpaprMachineState;
+
+/* Kernel Dump section info */
+struct FadumpSection {
+ __be32 request_flag;
+ __be16 source_data_type;
+ __be16 error_flags;
+ __be64 source_address;
+ __be64 source_len;
+ __be64 bytes_dumped;
+ __be64 destination_address;
+};
+
+/* ibm,configure-kernel-dump header. */
+struct FadumpSectionHeader {
+ __be32 dump_format_version;
+ __be16 dump_num_sections;
+ __be16 dump_status_flag;
+ __be32 offset_first_dump_section;
+
+ /* Fields for disk dump option. */
+ __be32 dd_block_size;
+ __be64 dd_block_offset;
+ __be64 dd_num_blocks;
+ __be32 dd_offset_disk_path;
+
+ /* Maximum time allowed to prevent an automatic dump-reboot. */
+ __be32 max_time_auto;
+};
+
+/* Note: All the data in these structures is in big-endian */
+struct FadumpMemStruct {
+ FadumpSectionHeader header;
+ FadumpSection rgn[FADUMP_MAX_SECTIONS];
+};
+
+uint32_t do_fadump_register(void);
+#endif /* PPC_SPAPR_FADUMP_H */
Add skeleton for handle "ibm,configure-kernel-dump" rtas call in QEMU. Verify basic details mandated by the PAPR, such as number of inputs/output, and add handling for the three fadump commands: regiser/unregister/invalidate. Currently fadump register will always return HARDWARE ERROR, since it's not implemented yet. So if the kernel's attempt to register fadump will itself fail as the support is not there yet in QEMU. The checks are based on the table in following requirement in PAPR v2.13: "R1–7.3.30–1. For the Configure Platform Assisted Kernel Dump option ..." Signed-off-by: Aditya Gupta <adityag@linux.ibm.com> --- hw/ppc/meson.build | 1 + hw/ppc/spapr_fadump.c | 22 +++++++++++ hw/ppc/spapr_rtas.c | 66 +++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 11 +++++- include/hw/ppc/spapr_fadump.h | 69 +++++++++++++++++++++++++++++++++++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/spapr_fadump.c create mode 100644 include/hw/ppc/spapr_fadump.h