From: Sourabh Jain <sourabhjain@linux.ibm.com>
To: Shivang Upadhyay <shivangu@linux.ibm.com>,
qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: hbathini@linux.ibm.com, adityag@linux.ibm.com,
harshpb@linux.ibm.com, rathc@linux.ibm.com, npiggin@gmail.com,
mahesh@linux.ibm.com, Shivang Upadhyay <shivanug@linux.ibm.com>
Subject: Re: [PATCH 1/3] hw/ppc: move RAS-specific RTAS handlers to spapr_rtas_ras.c
Date: Thu, 16 Jul 2026 10:14:57 +0530 [thread overview]
Message-ID: <0afdda10-c446-4fe9-aff5-5131701fe75c@linux.ibm.com> (raw)
In-Reply-To: <20260714164745.573141-2-shivangu@linux.ibm.com>
On 14/07/26 22:17, Shivang Upadhyay wrote:
> Following RTAS calls are moved to spapr_rtas_ras.c file
> - ibm,os-term
> - ibm,nmi-register
> - ibm,nmi-interlock
> - ibm,configure-kernel-dump
>
> The rtas calls are initialized with a new rtas_register_types
> constructor.
>
> No functional changes.
>
> Signed-off-by: Shivang Upadhyay <shivanug@linux.ibm.com>
> ---
> hw/ppc/meson.build | 1 +
> hw/ppc/spapr_rtas.c | 189 --------------------------------
> hw/ppc/spapr_rtas_ras.c | 232 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 233 insertions(+), 189 deletions(-)
> create mode 100644 hw/ppc/spapr_rtas_ras.c
>
> diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
> index 37aa535db2..83edb3d852 100644
> --- a/hw/ppc/meson.build
> +++ b/hw/ppc/meson.build
> @@ -14,6 +14,7 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files(
> 'spapr_events.c',
> 'spapr_hcall.c',
> 'spapr_nested.c',
> + 'spapr_rtas_ras.c',
> 'spapr_iommu.c',
> 'spapr_rtas.c',
> 'spapr_pci.c',
> diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
> index 328fc27c40..f8538735a4 100644
> --- a/hw/ppc/spapr_rtas.c
> +++ b/hw/ppc/spapr_rtas.c
> @@ -361,96 +361,6 @@ 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 called with nret != 1.\n");
> - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> - return;
> - }
> -
> - /* Number of inputs has to be 3 */
> - if (nargs != 3) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "FADump: ibm,configure-kernel-dump called with nargs != 3.\n");
> - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> - return;
> - }
> -
> - switch (cmd) {
> - case FADUMP_CMD_REGISTER:
> - ret_val = do_fadump_register(spapr, args);
> - if (ret_val != RTAS_OUT_SUCCESS) {
> - rtas_st(rets, 0, ret_val);
> - return;
> - }
> - break;
> - case FADUMP_CMD_UNREGISTER:
> - if (spapr->fadump_dump_active) {
> - 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) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "FADump: Nothing to invalidate, no dump active\n");
> -
> - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> - }
> -
> - spapr->fadump_registered = false;
> - spapr->fadump_dump_active = false;
> - memset(&spapr->registered_fdm, 0, sizeof(spapr->registered_fdm));
> - break;
> - default:
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "FADump: Unknown command: " TARGET_FMT_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,
> - target_ulong args,
> - uint32_t nret, target_ulong rets)
> -{
> - target_ulong msgaddr = rtas_ld(args, 0);
> - char msg[512];
> -
> - if (spapr->fadump_registered) {
> - /* If fadump boot works, control won't come back here */
> - return trigger_fadump_boot(spapr, rets);
> - }
> -
> - physical_memory_read(msgaddr, msg, sizeof(msg) - 1);
> - msg[sizeof(msg) - 1] = 0;
> -
> - error_report("OS terminated: %s", msg);
> - qemu_system_guest_panicked(NULL);
> -
> - rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> -}
> -
> static void rtas_set_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
> uint32_t token, uint32_t nargs,
> target_ulong args, uint32_t nret,
> @@ -501,95 +411,6 @@ static void rtas_get_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
> rtas_st(rets, 1, 100);
> }
>
> -static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> - SpaprMachineState *spapr,
> - uint32_t token, uint32_t nargs,
> - target_ulong args,
> - uint32_t nret, target_ulong rets)
> -{
> - hwaddr rtas_addr;
> - target_ulong sreset_addr, mce_addr;
> -
> - if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
> - rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> - return;
> - }
> -
> - rtas_addr = spapr_get_rtas_addr();
> - if (!rtas_addr) {
> - rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> - return;
> - }
> -
> - sreset_addr = rtas_ld(args, 0);
> - mce_addr = rtas_ld(args, 1);
> -
> - /* PAPR requires these are in the first 32M of memory and within RMA */
> - if (sreset_addr >= 32 * MiB || sreset_addr >= spapr->rma_size ||
> - mce_addr >= 32 * MiB || mce_addr >= spapr->rma_size) {
> - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> - return;
> - }
> -
> - if (kvm_enabled()) {
> - if (kvmppc_set_fwnmi(cpu) < 0) {
> - rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> - return;
> - }
> - }
> -
> - spapr->fwnmi_system_reset_addr = sreset_addr;
> - spapr->fwnmi_machine_check_addr = mce_addr;
> -
> - rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> -}
> -
> -static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> - SpaprMachineState *spapr,
> - uint32_t token, uint32_t nargs,
> - target_ulong args,
> - uint32_t nret, target_ulong rets)
> -{
> - if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
> - rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> - return;
> - }
> -
> - if (spapr->fwnmi_machine_check_addr == -1) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> -"FWNMI: ibm,nmi-interlock RTAS called with FWNMI not registered.\n");
> -
> - /* NMI register not called */
> - rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> - return;
> - }
> -
> - if (spapr->fwnmi_machine_check_interlock != cpu->vcpu_id) {
> - /*
> - * The vCPU that hit the NMI should invoke "ibm,nmi-interlock"
> - * This should be PARAM_ERROR, but Linux calls "ibm,nmi-interlock"
> - * for system reset interrupts, despite them not being interlocked.
> - * PowerVM silently ignores this and returns success here. Returning
> - * failure causes Linux to print the error "FWNMI: nmi-interlock
> - * failed: -3", although no other apparent ill effects, this is a
> - * regression for the user when enabling FWNMI. So for now, match
> - * PowerVM. When most Linux clients are fixed, this could be
> - * changed.
> - */
> - rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> - return;
> - }
> -
> - /*
> - * vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
> - * hence unset fwnmi_machine_check_interlock.
> - */
> - spapr->fwnmi_machine_check_interlock = -1;
> - qemu_cond_signal(&spapr->fwnmi_machine_check_interlock_cond);
> - rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> - migrate_del_blocker(&spapr->fwnmi_migration_blocker);
Nit: since |migrate_del_blocker| is being moved out of this file, we can
remove
|#include "migration/blocker.h"| from here.
> -}
> -
> static struct rtas_call {
> const char *name;
> spapr_rtas_fn fn;
> @@ -737,20 +558,10 @@ static void core_rtas_register_types(void)
> spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,
> "ibm,set-system-parameter",
> rtas_ibm_set_system_parameter);
> - spapr_rtas_register(RTAS_IBM_OS_TERM, "ibm,os-term",
> - rtas_ibm_os_term);
> spapr_rtas_register(RTAS_SET_POWER_LEVEL, "set-power-level",
> rtas_set_power_level);
> spapr_rtas_register(RTAS_GET_POWER_LEVEL, "get-power-level",
> rtas_get_power_level);
> - spapr_rtas_register(RTAS_IBM_NMI_REGISTER, "ibm,nmi-register",
> - rtas_ibm_nmi_register);
> - 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);
> }
> diff --git a/hw/ppc/spapr_rtas_ras.c b/hw/ppc/spapr_rtas_ras.c
> new file mode 100644
> index 0000000000..2f7ee3bb24
> --- /dev/null
> +++ b/hw/ppc/spapr_rtas_ras.c
> @@ -0,0 +1,232 @@
> +/*
> + * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
> + *
> + * RAS (Reliability, Availability and Serviceability) RTAS call handlers:
> + * - ibm,configure-kernel-dump (FADump)
> + * - ibm,os-term (FADump-aware OS termination)
> + *
> + * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qemu/error-report.h"
> +#include "qemu/units.h"
> +#include "system/physmem.h"
> +#include "system/runstate.h"
> +#include "kvm_ppc.h"
> +#include "migration/blocker.h"
> +
> +#include "hw/ppc/spapr.h"
> +#include "hw/ppc/spapr_fadump.h"
> +
> +/* 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 called with nret != 1.\n");
> + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> + return;
> + }
> +
> + /* Number of inputs has to be 3 */
> + if (nargs != 3) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "FADump: ibm,configure-kernel-dump called with nargs != 3.\n");
> + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> + return;
> + }
> +
> + switch (cmd) {
> + case FADUMP_CMD_REGISTER:
> + ret_val = do_fadump_register(spapr, args);
> + if (ret_val != RTAS_OUT_SUCCESS) {
> + rtas_st(rets, 0, ret_val);
> + return;
> + }
> + break;
> + case FADUMP_CMD_UNREGISTER:
> + if (spapr->fadump_dump_active) {
> + 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) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "FADump: Nothing to invalidate, no dump active\n");
> +
> + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> + }
> +
> + spapr->fadump_registered = false;
> + spapr->fadump_dump_active = false;
> + memset(&spapr->registered_fdm, 0, sizeof(spapr->registered_fdm));
> + break;
> + default:
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "FADump: Unknown command: " TARGET_FMT_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,
> + target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + target_ulong msgaddr = rtas_ld(args, 0);
> + char msg[512];
> +
> + if (spapr->fadump_registered) {
> + /* If fadump boot works, control won't come back here */
> + return trigger_fadump_boot(spapr, rets);
> + }
> +
> + physical_memory_read(msgaddr, msg, sizeof(msg) - 1);
> + msg[sizeof(msg) - 1] = 0;
> +
> + error_report("OS terminated: %s", msg);
> + qemu_system_guest_panicked(NULL);
> +
> + rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_register(PowerPCCPU *cpu,
> + SpaprMachineState *spapr,
> + uint32_t token, uint32_t nargs,
> + target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + hwaddr rtas_addr;
> + target_ulong sreset_addr, mce_addr;
> +
> + if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
> + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> + return;
> + }
> +
> + rtas_addr = spapr_get_rtas_addr();
> + if (!rtas_addr) {
> + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> + return;
> + }
> +
> + sreset_addr = rtas_ld(args, 0);
> + mce_addr = rtas_ld(args, 1);
> +
> + /* PAPR requires these are in the first 32M of memory and within RMA */
> + if (sreset_addr >= 32 * MiB || sreset_addr >= spapr->rma_size ||
> + mce_addr >= 32 * MiB || mce_addr >= spapr->rma_size) {
> + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> + return;
> + }
> +
> + if (kvm_enabled()) {
> + if (kvmppc_set_fwnmi(cpu) < 0) {
> + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> + return;
> + }
> + }
> +
> + spapr->fwnmi_system_reset_addr = sreset_addr;
> + spapr->fwnmi_machine_check_addr = mce_addr;
> +
> + rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> +}
> +
> +static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
> + SpaprMachineState *spapr,
> + uint32_t token, uint32_t nargs,
> + target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + if (spapr_get_cap(spapr, SPAPR_CAP_FWNMI) == SPAPR_CAP_OFF) {
> + rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
> + return;
> + }
> +
> + if (spapr->fwnmi_machine_check_addr == -1) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> +"FWNMI: ibm,nmi-interlock RTAS called with FWNMI not registered.\n");
> +
> + /* NMI register not called */
> + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
> + return;
> + }
> +
> + if (spapr->fwnmi_machine_check_interlock != cpu->vcpu_id) {
> + /*
> + * The vCPU that hit the NMI should invoke "ibm,nmi-interlock"
> + * This should be PARAM_ERROR, but Linux calls "ibm,nmi-interlock"
> + * for system reset interrupts, despite them not being interlocked.
> + * PowerVM silently ignores this and returns success here. Returning
> + * failure causes Linux to print the error "FWNMI: nmi-interlock
> + * failed: -3", although no other apparent ill effects, this is a
> + * regression for the user when enabling FWNMI. So for now, match
> + * PowerVM. When most Linux clients are fixed, this could be
> + * changed.
> + */
> + rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> + return;
> + }
> +
> + /*
> + * vCPU issuing "ibm,nmi-interlock" is done with NMI handling,
> + * hence unset fwnmi_machine_check_interlock.
> + */
> + spapr->fwnmi_machine_check_interlock = -1;
> + qemu_cond_signal(&spapr->fwnmi_machine_check_interlock_cond);
> + rtas_st(rets, 0, RTAS_OUT_SUCCESS);
> + migrate_del_blocker(&spapr->fwnmi_migration_blocker);
> +}
> +
> +static void ras_rtas_register_types(void)
> +{
> + spapr_rtas_register(RTAS_IBM_OS_TERM, "ibm,os-term",
> + rtas_ibm_os_term);
> + spapr_rtas_register(RTAS_IBM_NMI_REGISTER, "ibm,nmi-register",
> + rtas_ibm_nmi_register);
> + spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
> + rtas_ibm_nmi_interlock);
> + spapr_rtas_register(RTAS_CONFIGURE_KERNEL_DUMP, "ibm,configure-kernel-dump",
> + rtas_configure_kernel_dump);
> +}
> +
> +type_init(ras_rtas_register_types)
next prev parent reply other threads:[~2026-07-16 4:46 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 16:47 [PATCH 0/3] hw/ppc: reorg PowerPC RAS code for better maintainability Shivang Upadhyay
2026-07-14 16:47 ` [PATCH 1/3] hw/ppc: move RAS-specific RTAS handlers to spapr_rtas_ras.c Shivang Upadhyay
2026-07-16 4:44 ` Sourabh Jain [this message]
2026-07-14 16:47 ` [PATCH 2/3] MAINTAINERS: add dedicated PowerPC RAS section Shivang Upadhyay
2026-08-18 5:48 ` Aditya Gupta
2026-08-18 8:33 ` Sourabh Jain
2026-07-14 16:47 ` [PATCH 3/3] MAINTAINERS: add self as reviewer for PowerPC RAS Shivang Upadhyay
2026-08-18 5:49 ` Aditya Gupta
2026-07-15 14:39 ` [PATCH 0/3] hw/ppc: reorg PowerPC RAS code for better maintainability Vaibhav Jain
2026-07-15 14:52 ` Harsh Prateek Bora
2026-08-18 8:27 ` Sourabh Jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0afdda10-c446-4fe9-aff5-5131701fe75c@linux.ibm.com \
--to=sourabhjain@linux.ibm.com \
--cc=adityag@linux.ibm.com \
--cc=harshpb@linux.ibm.com \
--cc=hbathini@linux.ibm.com \
--cc=mahesh@linux.ibm.com \
--cc=npiggin@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=rathc@linux.ibm.com \
--cc=shivangu@linux.ibm.com \
--cc=shivanug@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox