From: Narayana Murty N <nnmlinux@linux.ibm.com>
To: Sourabh Jain <sourabhjain@linux.ibm.com>,
mahesh@linux.ibm.com, maddy@linux.ibm.com, mpe@ellerman.id.au,
christophe.leroy@csgroup.eu, oohall@gmail.com, npiggin@gmail.com,
tpearson@raptorengineering.com, alex@shazbot.org,
"Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
sbhat@linux.ibm.com, harshpb@linux.ibm.com
Subject: Re: [PATCH v4 1/5] powerpc/rtas: Handle ibm,open-errinjct return format
Date: Wed, 9 Sep 2026 11:15:56 +0530 [thread overview]
Message-ID: <880fbc4d-c068-4b43-826e-944f14632ce1@linux.ibm.com> (raw)
In-Reply-To: <1abcf248-0d93-4d2d-a3e2-867b0b3dea16@linux.ibm.com>
Hi Sourabh,
Thanks for the detailed review.
On 01/09/26 2:52 PM, Sourabh Jain wrote:
>
> On 31/08/26 12:24, Narayana Murty N wrote:
>> ibm,open-errinjct uses a non-standard RTAS return layout:
>>
>> rets[0] = session token (output parameter)
>> rets[1] = status code
>>
>> Unlike all other RTAS functions which use:
>>
>> rets[0] = status code
>> rets[1..] = output parameters
>>
>> Add rtas_token_is_open_errinjct() to identify this call, and
>> rtas_status_from_args() to extract status from the correct position.
>>
>> Add an early guard in rtas_call() that rejects ibm,open-errinjct
>> invocations where nret < 2, since reading rets[1] would be out of
>> bounds:
>>
>> if (rtas_token_is_open_errinjct(token) && nret < 2) {
>> WARN_ON_ONCE(1);
>> return RTAS_INVALID_PARAMETER;
>> }
>>
>> Adjust the output-copy loop so that for ibm,open-errinjct:
>>
>> return value = rets[1] (status)
>> outputs[0] = rets[0] (session token)
>>
>> For all other functions the existing convention is preserved:
>>
>> return value = rets[0] (status)
>> outputs[0..] = rets[1..] (non-status outputs)
>>
>> Move the "/* A -1 return code... */" comment immediately before the
>> ret == -1 check so it documents the check it guards.
>>
>> Also fix sys_rtas() last-error status detection: ibm,open-errinjct
>> places status at rets[1], so the -1 sentinel check must use rets[1]
>> for that function rather than always using rets[0].
>>
>> Reference: OpenPOWER PAPR documentation
>> https://files.openpower.foundation/s/XFgfMaqLMD5Bcm8
>> Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
>> ---
>> arch/powerpc/kernel/rtas.c | 78 +++++++++++++++++++++++++++++++++-----
>> 1 file changed, 68 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
>> index 8d81c1e7a8db..7131870655c6 100644
>> --- a/arch/powerpc/kernel/rtas.c
>> +++ b/arch/powerpc/kernel/rtas.c
>> @@ -1117,6 +1117,28 @@ static bool token_is_restricted_errinjct(s32
>> token)
>> token == rtas_function_token(RTAS_FN_IBM_ERRINJCT);
>> }
>> +/*
>> + * ibm,open-errinjct uses a non-standard return layout:
>> + * rets[0] = session token (output parameter)
>> + * rets[1] = status code
>> + *
>> + * All other RTAS functions use the standard layout:
>> + * rets[0] = status code
>> + * rets[1..] = output parameters
>> + */
>> +static inline bool rtas_token_is_open_errinjct(int token)
>> +{
>> + return token == rtas_function_token(RTAS_FN_IBM_OPEN_ERRINJCT);
>> +}
>> +
>> +static int rtas_status_from_args(int token, struct rtas_args *args,
>> int nret)
>> +{
>> + if (rtas_token_is_open_errinjct(token))
>> + return be32_to_cpu(args->rets[1]);
>> +
>> + return nret > 0 ? be32_to_cpu(args->rets[0]) : 0;
>> +}
>> +
>> /**
>> * rtas_call() - Invoke an RTAS firmware function.
>> * @token: Identifies the function being invoked.
>> @@ -1198,6 +1220,16 @@ int rtas_call(int token, int nargs, int nret,
>> int *outputs, ...)
>> return -1;
>> }
>> + /*
>> + * ibm,open-errinjct returns rets[0]=session_token, rets[1]=status.
>> + * We need nret >= 2 to read status from rets[1]. Reject early if
>> + * the caller forgot to account for the extra return cell.
>> + */
>> + if (rtas_token_is_open_errinjct(token) && nret < 2) {
>> + WARN_ON_ONCE(1);
>> + return RTAS_INVALID_PARAMETER;
>
> Nit: I would prefer -EINVAL instead. RTAS_INVALID_PARAMETER is RTAS
> error code but here kernel is validating the parameter so I think -
> EINVAL would be better.
I agree this is a kernel-side validation before entering RTAS, but for
rtas_call() I think keeping RTAS_INVALID_PARAMETER is safer.
The return value from rtas_call() is normally interpreted by callers as
an RTAS status code. If we return -EINVAL from rtas_call(), the caller
may still treat it as an RTAS return value. Since this is an invalid
RTAS call layout for ibm,open-errinjct, I would prefer to keep the
return value as RTAS_INVALID_PARAMETER in rtas_call().
>> + }
>> +
>> if ((mfmsr() & (MSR_IR|MSR_DR)) != (MSR_IR|MSR_DR)) {
>> WARN_ON_ONCE(1);
>> return -1;
>> @@ -1213,15 +1245,33 @@ int rtas_call(int token, int nargs, int nret,
>> int *outputs, ...)
>> va_rtas_call_unlocked(args, token, nargs, nret, list);
>> va_end(list);
>> + ret = rtas_status_from_args(token, args, nret);
>> +
>> /* A -1 return code indicates that the last command couldn't
>> - be completed due to a hardware error. */
>> - if (be32_to_cpu(args->rets[0]) == -1)
>> + * be completed due to a hardware error.
>> + */
>> + if (ret == -1)
>> buff_copy = __fetch_rtas_last_error(NULL);
>> - if (nret > 1 && outputs != NULL)
>> - for (i = 0; i < nret-1; ++i)
>> - outputs[i] = be32_to_cpu(args->rets[i + 1]);
>> - ret = (nret > 0) ? be32_to_cpu(args->rets[0]) : 0;
>> + /*
>> + * Copy non-status outputs to the caller's buffer.
>> + *
>> + * For ibm,open-errinjct the layout is:
>> + * rets[0] = session token -> outputs[0]
>> + * rets[1] = status (returned, not copied)
>> + *
>> + * For all other RTAS functions:
>> + * rets[0] = status (returned, not copied)
>> + * rets[1..nret-1] -> outputs[0..nret-2]
>> + */
>> + if (outputs != NULL) {
>> + if (rtas_token_is_open_errinjct(token)) {
>> + outputs[0] = be32_to_cpu(args->rets[0]);
>> + } else if (nret > 1) {
>> + for (i = 0; i < nret - 1; ++i)
>> + outputs[i] = be32_to_cpu(args->rets[i + 1]);
>> + }
>> + }
>> lockdep_unpin_lock(&rtas_lock, cookie);
>> raw_spin_unlock_irqrestore(&rtas_lock, flags);
>> @@ -1942,10 +1992,18 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user
>> *, uargs)
>> do_enter_rtas(&rtas_args);
>> args = rtas_args;
>> - /* A -1 return code indicates that the last command couldn't
>> - be completed due to a hardware error. */
>> - if (be32_to_cpu(args.rets[0]) == -1)
>> - errbuf = __fetch_rtas_last_error(buff_copy);
>> + /*
>> + * A -1 return code indicates that the last command couldn't
>> + * be completed due to a hardware error. ibm,open-errinjct
>> + * places status at rets[1] rather than rets[0]; check the
>> + * correct position for the -1 sentinel.
>> + */
>> + {
>> + __be32 status_cell = (token ==
>> rtas_function_token(RTAS_FN_IBM_OPEN_ERRINJCT) &&
>> + nret >= 2) ? args.rets[1] : args.rets[0];
>> + if (be32_to_cpu(status_cell) == -1)
>> + errbuf = __fetch_rtas_last_error(buff_copy);
>
> Do we know what happens when the ibm,open-errinjct RTAS call is made
> with nret < 2?
>
> The reason I’m asking is that, even with the above changes,
> args.rets[0] is used as the return code if the ibm,open-errinjct call
> is made with nret < 2.
>
> I like the approach you took in rtas_call() of pre-validating nret for
> the ibm,open-errinjct RTAS call and returning early if it is less than
> 2. I think we can use a similar approach here as well. If we do that,
> the above code changes will be much cleaner. In that case, we don't
> have to figure out how RTAS processes ibm,open-errinjct with nret < 2.
>
> The only concern I have is that this change would alter the system
> call behavior. Right now, the kernel accepts nret < 2 for
> ibm,open-errinjct and makes the RTAS call, but with the above suggested
> change, the kernel would return early if nret < 2.
>
> The prominent user of this system call is librtas, which passes
> nret = 2 for ibm,open-errinjct:
>
> https://github.com/ibm-power-utilities/librtas/blob/
> d321a1f5ae3d528ba027fc748d1cc1123dd4ae29/librtas_src/syscall_calls.c#L488
>
> Also, as per PAPR, users are supposed to pass nret = 2 for this RTAS
> call. So I think it should be fine to validate nret in sys_rtas for
> ibm,open-errinjct and return early if it is found to be less than 2.
>
> Since this is a change in system call behavior, I want to be a
> little cautious. So, I’d like to hear your thoughts and would also
> like to know what others think about making the above change.
>
Agreed.
For ibm,open-errinjct, rets[0] is the session token and rets[1] is the
status. So when nret < 2, we should not fall back to rets[0], because
that can interpret a session token as a status code.
I will add an early validation in sys_rtas() before entering RTAS for
this case and return -EINVAL there, since sys_rtas() is the userspace
syscall boundary.
So the split will be:
rtas_call(): return RTAS_INVALID_PARAMETER for invalid RTAS return layout
sys_rtas(): return -EINVAL for invalid userspace syscall arguments
This should not affect the valid librtas path, since librtas already
passes nret = 2 for ibm,open-errinjct, as required by PAPR.
Thanks,
Narayana
> Thanks, Sourabh Jain
>> + }
>> lockdep_unpin_lock(&rtas_lock, cookie);
>> raw_spin_unlock_irqrestore(&rtas_lock, flags);
>
next prev parent reply other threads:[~2026-09-09 5:46 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 6:54 [PATCH v4 0/5] powerpc/eeh: Add RTAS-based error injection support on pSeries Narayana Murty N
2026-08-31 6:54 ` [PATCH v4 1/5] powerpc/rtas: Handle ibm,open-errinjct return format Narayana Murty N
2026-09-01 9:22 ` Sourabh Jain
2026-09-09 5:45 ` Narayana Murty N [this message]
2026-08-31 6:54 ` [PATCH v4 2/5] vfio/spapr_tce: Normalize EEH IOA error injection addresses Narayana Murty N
2026-08-31 6:54 ` [PATCH v4 3/5] powerpc/pseries/eeh: Add RTAS error validation helpers Narayana Murty N
2026-08-31 6:54 ` [PATCH v4 4/5] powerpc/pseries/eeh: Implement RTAS-based EEH error injection Narayana Murty N
2026-09-02 5:16 ` Sourabh Jain
2026-09-09 6:07 ` Narayana Murty N
2026-08-31 6:54 ` [PATCH v4 5/5] powerpc/powernv/eeh: Map VFIO EEH error injection to OPAL Narayana Murty N
2026-09-01 18:08 ` [PATCH v4 0/5] powerpc/eeh: Add RTAS-based error injection support on pSeries Narayana Murty N
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=880fbc4d-c068-4b43-826e-944f14632ce1@linux.ibm.com \
--to=nnmlinux@linux.ibm.com \
--cc=alex@shazbot.org \
--cc=christophe.leroy@csgroup.eu \
--cc=harshpb@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mahesh@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=oohall@gmail.com \
--cc=ritesh.list@gmail.com \
--cc=sbhat@linux.ibm.com \
--cc=sourabhjain@linux.ibm.com \
--cc=tpearson@raptorengineering.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.