From: Laurent Dufour <ldufour@linux.ibm.com>
To: Nathan Lynch <nathanl@linux.ibm.com>, linuxppc-dev@lists.ozlabs.org
Cc: leobras.c@gmail.com, haren@linux.ibm.com, tyreld@linux.ibm.com
Subject: Re: [PATCH] Revert "powerpc/rtas: Implement reentrant rtas call"
Date: Thu, 8 Sep 2022 09:56:13 +0200 [thread overview]
Message-ID: <429708cd-7ae9-10e7-cbb9-3261ac339c8f@linux.ibm.com> (raw)
In-Reply-To: <20220907220111.223267-1-nathanl@linux.ibm.com>
Le 08/09/2022 à 00:01, Nathan Lynch a écrit :
> At the time this was submitted by Leonardo, I confirmed -- or thought
> I had confirmed -- with PowerVM partition firmware development that
> the following RTAS functions:
>
> - ibm,get-xive
> - ibm,int-off
> - ibm,int-on
> - ibm,set-xive
>
> were safe to call on multiple CPUs simultaneously, not only with
> respect to themselves as indicated by PAPR, but with arbitrary other
> RTAS calls:
>
> https://lore.kernel.org/linuxppc-dev/875zcy2v8o.fsf@linux.ibm.com/
>
> Recent discussion with firmware development makes it clear that this
> is not true, and that the code in commit b664db8e3f97 ("powerpc/rtas:
> Implement reentrant rtas call") is unsafe, likely explaining several
> strange bugs we've seen in internal testing involving DLPAR and
> LPM. These scenarios use ibm,configure-connector, whose internal state
> can be corrupted by the concurrent use of the "reentrant" functions,
> leading to symptoms like endless busy statuses from RTAS.
Thanks, Nathan,
T
his is fixing LPAR hangs I was facing when doing some migration tests.
Reviewed-by: Laurent Dufour <laurent.dufour@fr.ibm.com>
> Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
> Fixes: b664db8e3f97 ("powerpc/rtas: Implement reentrant rtas call")
> Cc: stable@vger.kernel.org
> ---
> arch/powerpc/include/asm/paca.h | 1 -
> arch/powerpc/include/asm/rtas.h | 1 -
> arch/powerpc/kernel/paca.c | 32 -----------------
> arch/powerpc/kernel/rtas.c | 54 -----------------------------
> arch/powerpc/sysdev/xics/ics-rtas.c | 22 ++++++------
> 5 files changed, 11 insertions(+), 99 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
> index 4d7aaab82702..3537b0500f4d 100644
> --- a/arch/powerpc/include/asm/paca.h
> +++ b/arch/powerpc/include/asm/paca.h
> @@ -263,7 +263,6 @@ struct paca_struct {
> u64 l1d_flush_size;
> #endif
> #ifdef CONFIG_PPC_PSERIES
> - struct rtas_args *rtas_args_reentrant;
> u8 *mce_data_buf; /* buffer to hold per cpu rtas errlog */
> #endif /* CONFIG_PPC_PSERIES */
>
> diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> index 00531af17ce0..56319aea646e 100644
> --- a/arch/powerpc/include/asm/rtas.h
> +++ b/arch/powerpc/include/asm/rtas.h
> @@ -240,7 +240,6 @@ extern struct rtas_t rtas;
> extern int rtas_token(const char *service);
> extern int rtas_service_present(const char *service);
> extern int rtas_call(int token, int, int, int *, ...);
> -int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...);
> void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
> int nret, ...);
> extern void __noreturn rtas_restart(char *cmd);
> diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
> index ba593fd60124..dfd097b79160 100644
> --- a/arch/powerpc/kernel/paca.c
> +++ b/arch/powerpc/kernel/paca.c
> @@ -16,7 +16,6 @@
> #include <asm/kexec.h>
> #include <asm/svm.h>
> #include <asm/ultravisor.h>
> -#include <asm/rtas.h>
>
> #include "setup.h"
>
> @@ -170,30 +169,6 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
> }
> #endif /* CONFIG_PPC_64S_HASH_MMU */
>
> -#ifdef CONFIG_PPC_PSERIES
> -/**
> - * new_rtas_args() - Allocates rtas args
> - * @cpu: CPU number
> - * @limit: Memory limit for this allocation
> - *
> - * Allocates a struct rtas_args and return it's pointer,
> - * if not in Hypervisor mode
> - *
> - * Return: Pointer to allocated rtas_args
> - * NULL if CPU in Hypervisor Mode
> - */
> -static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
> -{
> - limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX);
> -
> - if (early_cpu_has_feature(CPU_FTR_HVMODE))
> - return NULL;
> -
> - return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES,
> - limit, cpu);
> -}
> -#endif /* CONFIG_PPC_PSERIES */
> -
> /* The Paca is an array with one entry per processor. Each contains an
> * lppaca, which contains the information shared between the
> * hypervisor and Linux.
> @@ -232,10 +207,6 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
> /* For now -- if we have threads this will be adjusted later */
> new_paca->tcd_ptr = &new_paca->tcd;
> #endif
> -
> -#ifdef CONFIG_PPC_PSERIES
> - new_paca->rtas_args_reentrant = NULL;
> -#endif
> }
>
> /* Put the paca pointer into r13 and SPRG_PACA */
> @@ -307,9 +278,6 @@ void __init allocate_paca(int cpu)
> #endif
> #ifdef CONFIG_PPC_64S_HASH_MMU
> paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
> -#endif
> -#ifdef CONFIG_PPC_PSERIES
> - paca->rtas_args_reentrant = new_rtas_args(cpu, limit);
> #endif
> paca_struct_size += sizeof(struct paca_struct);
> }
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 693133972294..0b8a858aa847 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -43,7 +43,6 @@
> #include <asm/time.h>
> #include <asm/mmu.h>
> #include <asm/topology.h>
> -#include <asm/paca.h>
>
> /* This is here deliberately so it's only used in this file */
> void enter_rtas(unsigned long);
> @@ -932,59 +931,6 @@ void rtas_activate_firmware(void)
> pr_err("ibm,activate-firmware failed (%i)\n", fwrc);
> }
>
> -#ifdef CONFIG_PPC_PSERIES
> -/**
> - * rtas_call_reentrant() - Used for reentrant rtas calls
> - * @token: Token for desired reentrant RTAS call
> - * @nargs: Number of Input Parameters
> - * @nret: Number of Output Parameters
> - * @outputs: Array of outputs
> - * @...: Inputs for desired RTAS call
> - *
> - * According to LoPAR documentation, only "ibm,int-on", "ibm,int-off",
> - * "ibm,get-xive" and "ibm,set-xive" are currently reentrant.
> - * Reentrant calls need their own rtas_args buffer, so not using rtas.args, but
> - * PACA one instead.
> - *
> - * Return: -1 on error,
> - * First output value of RTAS call if (nret > 0),
> - * 0 otherwise,
> - */
> -int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...)
> -{
> - va_list list;
> - struct rtas_args *args;
> - unsigned long flags;
> - int i, ret = 0;
> -
> - if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
> - return -1;
> -
> - local_irq_save(flags);
> - preempt_disable();
> -
> - /* We use the per-cpu (PACA) rtas args buffer */
> - args = local_paca->rtas_args_reentrant;
> -
> - va_start(list, outputs);
> - va_rtas_call_unlocked(args, token, nargs, nret, list);
> - va_end(list);
> -
> - if (nret > 1 && outputs)
> - for (i = 0; i < nret - 1; ++i)
> - outputs[i] = be32_to_cpu(args->rets[i + 1]);
> -
> - if (nret > 0)
> - ret = be32_to_cpu(args->rets[0]);
> -
> - local_irq_restore(flags);
> - preempt_enable();
> -
> - return ret;
> -}
> -
> -#endif /* CONFIG_PPC_PSERIES */
> -
> /**
> * get_pseries_errorlog() - Find a specific pseries error log in an RTAS
> * extended event log.
> diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
> index 9e7007f9aca5..f8320f8e5bc7 100644
> --- a/arch/powerpc/sysdev/xics/ics-rtas.c
> +++ b/arch/powerpc/sysdev/xics/ics-rtas.c
> @@ -36,8 +36,8 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
>
> server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
>
> - call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
> - server, DEFAULT_PRIORITY);
> + call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
> + DEFAULT_PRIORITY);
> if (call_status != 0) {
> printk(KERN_ERR
> "%s: ibm_set_xive irq %u server %x returned %d\n",
> @@ -46,7 +46,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
> }
>
> /* Now unmask the interrupt (often a no-op) */
> - call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
> + call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq);
> if (call_status != 0) {
> printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
> __func__, hw_irq, call_status);
> @@ -68,7 +68,7 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
> if (hw_irq == XICS_IPI)
> return;
>
> - call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
> + call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq);
> if (call_status != 0) {
> printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
> __func__, hw_irq, call_status);
> @@ -76,8 +76,8 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
> }
>
> /* Have to set XIVE to 0xff to be able to remove a slot */
> - call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
> - xics_default_server, 0xff);
> + call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq,
> + xics_default_server, 0xff);
> if (call_status != 0) {
> printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
> __func__, hw_irq, call_status);
> @@ -108,7 +108,7 @@ static int ics_rtas_set_affinity(struct irq_data *d,
> if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
> return -1;
>
> - status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);
> + status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq);
>
> if (status) {
> printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
> @@ -126,8 +126,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
> pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq,
> hw_irq, irq_server);
>
> - status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
> - hw_irq, irq_server, xics_status[1]);
> + status = rtas_call(ibm_set_xive, 3, 1, NULL,
> + hw_irq, irq_server, xics_status[1]);
>
> if (status) {
> printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
> @@ -158,7 +158,7 @@ static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
> return -EINVAL;
>
> /* Check if RTAS knows about this interrupt */
> - rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
> + rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq);
> if (rc)
> return -ENXIO;
>
> @@ -174,7 +174,7 @@ static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
> {
> int rc, status[2];
>
> - rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
> + rc = rtas_call(ibm_get_xive, 1, 3, status, vec);
> if (rc)
> return -1;
> return status[0];
next prev parent reply other threads:[~2022-09-08 7:57 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-07 22:01 [PATCH] Revert "powerpc/rtas: Implement reentrant rtas call" Nathan Lynch
2022-09-08 7:56 ` Laurent Dufour [this message]
[not found] ` <1d76891ee052112ee1547a4027e358d5cbcac23d.camel@gmail.com>
2022-09-09 14:04 ` Nathan Lynch
2022-09-12 15:22 ` Leonardo Brás
2022-09-12 19:58 ` Nathan Lynch
2022-09-13 17:39 ` Leonardo Brás
2022-09-16 1:31 ` Nicholas Piggin
2022-09-16 21:56 ` Nathan Lynch
2022-09-19 13:51 ` Nathan Lynch
2022-09-19 23:45 ` Michael Ellerman
2022-09-20 3:54 ` Nicholas Piggin
2022-09-21 15:54 ` Nathan Lynch
2023-04-14 14:20 ` Michal Suchánek
2023-04-17 13:55 ` Nathan Lynch
2022-09-23 10:57 ` Michael Ellerman
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=429708cd-7ae9-10e7-cbb9-3261ac339c8f@linux.ibm.com \
--to=ldufour@linux.ibm.com \
--cc=haren@linux.ibm.com \
--cc=leobras.c@gmail.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=nathanl@linux.ibm.com \
--cc=tyreld@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;
as well as URLs for NNTP newsgroup(s).