* Re: [PATCH v3 03/16] pseries/fadump: move out platform specific support from generic code
From: Oliver O'Halloran @ 2019-07-03 4:04 UTC (permalink / raw)
To: Hari Bathini, linuxppc-dev
Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Vasant Hegde,
Nicholas Piggin, Stewart Smith, Daniel Axtens
In-Reply-To: <156149556436.9094.15834897273683011518.stgit@hbathini.in.ibm.com>
On Wed, 2019-06-26 at 02:16 +0530, Hari Bathini wrote:
> Introduce callbacks for platform specific operations like register,
> unregister, invalidate & such, and move pseries specific code into
> platform code.
Please don't move around large blocks of code *and* change the code in
a single patch. It makes reviewing the changes extremely tedious since
the changes are mixed in with hundreds of lines of nothing.
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
> arch/powerpc/include/asm/fadump.h | 75 ----
> arch/powerpc/kernel/fadump-common.h | 38 ++
> arch/powerpc/kernel/fadump.c | 500 ++-----------------------
> arch/powerpc/platforms/pseries/Makefile | 1
> arch/powerpc/platforms/pseries/rtas-fadump.c | 529 ++++++++++++++++++++++++++
> arch/powerpc/platforms/pseries/rtas-fadump.h | 96 +++++
> 6 files changed, 700 insertions(+), 539 deletions(-)
> create mode 100644 arch/powerpc/platforms/pseries/rtas-fadump.c
> create mode 100644 arch/powerpc/platforms/pseries/rtas-fadump.h
>
> +static struct fadump_ops pseries_fadump_ops = {
> + .init_fadump_mem_struct = pseries_init_fadump_mem_struct,
> + .register_fadump = pseries_register_fadump,
I realise you are just translating the existing interface, but why is
init_fadump_mem_struct() done as a seperate step and not as a part of
the registration function? The struct doesn't seem to be necessary
until the actual registration happens.
> + .unregister_fadump = pseries_unregister_fadump,
> + .invalidate_fadump = pseries_invalidate_fadump,
> + .process_fadump = pseries_process_fadump,
> + .fadump_region_show = pseries_fadump_region_show,
> + .crash_fadump = pseries_crash_fadump,
Rename this to fadump_trigger or something, it's not clear what it
does.
^ permalink raw reply
* Re: [PATCH] powerpc/hw_breakpoint: move instruction stepping out of hw_breakpoint_handler()
From: Ravi Bangoria @ 2019-07-03 6:20 UTC (permalink / raw)
To: Christophe Leroy
Cc: Ravi Bangoria, linux-kernel, Paul Mackerras, linuxppc-dev
In-Reply-To: <f8cdc3f1c66ad3c43ebc568abcc6c39ed4676284.1561737231.git.christophe.leroy@c-s.fr>
On 6/28/19 9:25 PM, Christophe Leroy wrote:
> On 8xx, breakpoints stop after executing the instruction, so
> stepping/emulation is not needed. Move it into a sub-function and
> remove the #ifdefs.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Just one neat below...
[...]
> -#ifndef CONFIG_PPC_8xx
> - /* Do not emulate user-space instructions, instead single-step them */
> - if (user_mode(regs)) {
> - current->thread.last_hit_ubp = bp;
> - regs->msr |= MSR_SE;
> + if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, info->address))
May be split this line. It's 86 chars long and checkpatch.pl is warning
about this:
WARNING: line over 80 characters
#257: FILE: arch/powerpc/kernel/hw_breakpoint.c:282:
+ if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, info->address))
^ permalink raw reply
* Re: [PATCH] i2c: remove casting dma_alloc
From: Jochen Friedrich @ 2019-07-03 6:24 UTC (permalink / raw)
To: Vasyl Gomonovych, linuxppc-dev, linux-i2c, linux-kernel
In-Reply-To: <20190623211354.24181-1-gomonovych@gmail.com>
> From: Vasyl <gomonovych@gmail.com>
>
> Generated by: alloc_cast.cocci
>
> Signed-off-by: Vasyl <gomonovych@gmail.com>
Acked-by: Jochen Friedrich <jochen@scram.de>
> ---
> drivers/i2c/busses/i2c-cpm.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
> index 187900594e3d..1213e1932ccb 100644
> --- a/drivers/i2c/busses/i2c-cpm.c
> +++ b/drivers/i2c/busses/i2c-cpm.c
> @@ -531,7 +531,9 @@ static int cpm_i2c_setup(struct cpm_i2c *cpm)
> }
> out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
>
> - cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
> + cpm->txbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev,
> + CPM_MAX_READ + 1,
> + &cpm->txdma[i], GFP_KERNEL);
> if (!cpm->txbuf[i]) {
> ret = -ENOMEM;
> goto out_muram;
^ permalink raw reply
* Re: [RFC PATCH v2 00/12] Reduce ifdef mess in ptrace
From: Ravi Bangoria @ 2019-07-03 6:29 UTC (permalink / raw)
To: Christophe Leroy
Cc: Ravi Bangoria, mikey, linux-kernel, Paul Mackerras, linuxppc-dev
In-Reply-To: <cover.1561735587.git.christophe.leroy@c-s.fr>
On 6/28/19 9:17 PM, Christophe Leroy wrote:
> The purpose of this series is to reduce the amount of #ifdefs
> in ptrace.c
>
> This is a first try. Most of it is done, there are still some #ifdefs that
> could go away.
>
> Please comment and tell whether it is worth continuing in that direction.
Hi Christopher,
I'm seeing this warning with all the patches.
WARNING: Improper SPDX comment style for 'arch/powerpc/kernel/ptrace/ptrace-view.c', please use '//' instead
#100: FILE: arch/powerpc/kernel/ptrace/ptrace-view.c:1:
+/* SPDX-License-Identifier: GPL-2.0-or-later */
^ permalink raw reply
* [PATCH V2 0/2] recover the channel swap after xrun
From: shengjiu.wang @ 2019-07-03 6:42 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, alsa-devel
Cc: linuxppc-dev, linux-kernel
From: Shengjiu Wang <shengjiu.wang@nxp.com>
recover the channel swap after xrun
Shengjiu Wang (2):
ASoC: fsl_esai: Wrap some operations to be functions
ASoC: fsl_esai: recover the channel swap after xrun
sound/soc/fsl/fsl_esai.c | 267 ++++++++++++++++++++++++++++-----------
1 file changed, 194 insertions(+), 73 deletions(-)
Changes in v2
- add one patch for wrap operations to functions.
- fix some coding style issue
--
2.21.0
^ permalink raw reply
* [PATCH V2 1/2] ASoC: fsl_esai: Wrap some operations to be functions
From: shengjiu.wang @ 2019-07-03 6:42 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, alsa-devel
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <cover.1562136119.git.shengjiu.wang@nxp.com>
From: Shengjiu Wang <shengjiu.wang@nxp.com>
Extract the operation to be functions, to improve the
readability.
In this patch, fsl_esai_init, fsl_esai_register_restore,
fsl_esai_trigger_start and fsl_esai_trigger_stop are
extracted.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_esai.c | 191 ++++++++++++++++++++++++---------------
1 file changed, 118 insertions(+), 73 deletions(-)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 10d2210c91ef..20039ae9893b 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -35,6 +35,7 @@
* @fifo_depth: depth of tx/rx FIFO
* @slot_width: width of each DAI slot
* @slots: number of slots
+ * @channels: channel num for tx or rx
* @hck_rate: clock rate of desired HCKx clock
* @sck_rate: clock rate of desired SCKx clock
* @hck_dir: the direction of HCKx pads
@@ -57,6 +58,7 @@ struct fsl_esai {
u32 slots;
u32 tx_mask;
u32 rx_mask;
+ u32 channels[2];
u32 hck_rate[2];
u32 sck_rate[2];
bool hck_dir[2];
@@ -543,64 +545,131 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
+static int fsl_esai_init(struct fsl_esai *esai_priv)
{
- struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
- bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
- u8 i, channels = substream->runtime->channels;
+ struct platform_device *pdev = esai_priv->pdev;
+ int ret;
+
+ /* Reset ESAI unit */
+ ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
+ ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
+ ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * We need to enable ESAI so as to access some of its registers.
+ * Otherwise, we would fail to dump regmap from user space.
+ */
+ ret = regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
+ ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
+ ESAI_ECR_ESAIEN);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
+ return ret;
+ }
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
+ ESAI_PRRC_PDC_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
+ ESAI_PCRC_PC_MASK, 0);
+
+ return 0;
+}
+
+static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
+{
+ int ret;
+ /* FIFO reset for safety */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
+ ESAI_xFCR_xFR, ESAI_xFCR_xFR);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR,
+ ESAI_xFCR_xFR, ESAI_xFCR_xFR);
+
+ regcache_mark_dirty(esai_priv->regmap);
+ ret = regcache_sync(esai_priv->regmap);
+ if (ret)
+ return ret;
+
+ /* FIFO reset done */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
+
+ return 0;
+}
+
+static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
+{
+ u8 i, channels = esai_priv->channels[tx];
u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
u32 mask;
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
+ ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
+
+ /* Write initial words reqiured by ESAI as normal procedure */
+ for (i = 0; tx && i < channels; i++)
+ regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
+
+ /*
+ * When set the TE/RE in the end of enablement flow, there
+ * will be channel swap issue for multi data line case.
+ * In order to workaround this issue, we switch the bit
+ * enablement sequence to below sequence
+ * 1) clear the xSMB & xSMA: which is done in probe and
+ * stop state.
+ * 2) set TE/RE
+ * 3) set xSMB
+ * 4) set xSMA: xSMA is the last one in this flow, which
+ * will trigger esai to start.
+ */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
+ tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
+ tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
+ mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
+ ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
+ ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
+}
+
+static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
+{
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
+ tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
+ ESAI_xSMA_xS_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
+ ESAI_xSMB_xS_MASK, 0);
+
+ /* Disable and reset FIFO */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
+ ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
+ ESAI_xFCR_xFR, 0);
+}
+
+static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ esai_priv->channels[tx] = substream->runtime->channels;
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
- ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
-
- /* Write initial words reqiured by ESAI as normal procedure */
- for (i = 0; tx && i < channels; i++)
- regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
-
- /*
- * When set the TE/RE in the end of enablement flow, there
- * will be channel swap issue for multi data line case.
- * In order to workaround this issue, we switch the bit
- * enablement sequence to below sequence
- * 1) clear the xSMB & xSMA: which is done in probe and
- * stop state.
- * 2) set TE/RE
- * 3) set xSMB
- * 4) set xSMA: xSMA is the last one in this flow, which
- * will trigger esai to start.
- */
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
- tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
- tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
- mask = tx ? esai_priv->tx_mask : esai_priv->rx_mask;
-
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
- ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
- ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
-
+ fsl_esai_trigger_start(esai_priv, tx);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
- tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
- ESAI_xSMA_xS_MASK, 0);
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMB(tx),
- ESAI_xSMB_xS_MASK, 0);
-
- /* Disable and reset FIFO */
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
- ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
- regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
- ESAI_xFCR_xFR, 0);
+ fsl_esai_trigger_stop(esai_priv, tx);
break;
default:
return -EINVAL;
@@ -866,22 +935,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, esai_priv);
- /* Reset ESAI unit */
- ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
- if (ret) {
- dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
+ ret = fsl_esai_init(esai_priv);
+ if (ret)
return ret;
- }
-
- /*
- * We need to enable ESAI so as to access some of its registers.
- * Otherwise, we would fail to dump regmap from user space.
- */
- ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
- if (ret) {
- dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
- return ret;
- }
esai_priv->tx_mask = 0xFFFFFFFF;
esai_priv->rx_mask = 0xFFFFFFFF;
@@ -955,20 +1011,10 @@ static int fsl_esai_runtime_resume(struct device *dev)
regcache_cache_only(esai->regmap, false);
- /* FIFO reset for safety */
- regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
- ESAI_xFCR_xFR, ESAI_xFCR_xFR);
- regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
- ESAI_xFCR_xFR, ESAI_xFCR_xFR);
-
- ret = regcache_sync(esai->regmap);
+ ret = fsl_esai_register_restore(esai);
if (ret)
goto err_regcache_sync;
- /* FIFO reset done */
- regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
- regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
-
return 0;
err_regcache_sync:
@@ -991,7 +1037,6 @@ static int fsl_esai_runtime_suspend(struct device *dev)
struct fsl_esai *esai = dev_get_drvdata(dev);
regcache_cache_only(esai->regmap, true);
- regcache_mark_dirty(esai->regmap);
if (!IS_ERR(esai->fsysclk))
clk_disable_unprepare(esai->fsysclk);
--
2.21.0
^ permalink raw reply related
* [PATCH V2 2/2] ASoC: fsl_esai: recover the channel swap after xrun
From: shengjiu.wang @ 2019-07-03 6:42 UTC (permalink / raw)
To: timur, nicoleotsuka, Xiubo.Lee, festevam, broonie, alsa-devel
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <cover.1562136119.git.shengjiu.wang@nxp.com>
From: Shengjiu Wang <shengjiu.wang@nxp.com>
There is chip errata ERR008000, the reference doc is
(https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf),
The issue is "While using ESAI transmit or receive and
an underrun/overrun happens, channel swap may occur.
The only recovery mechanism is to reset the ESAI."
This issue exist in imx3/imx5/imx6(partial) series.
In this commit add a tasklet to handle reset of ESAI
after xrun happens to recover the channel swap.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_esai.c | 76 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 20039ae9893b..8c92e49ad6d8 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -32,6 +32,7 @@
* @extalclk: esai clock source to derive HCK, SCK and FS
* @fsysclk: system clock source to derive HCK, SCK and FS
* @spbaclk: SPBA clock (optional, depending on SoC design)
+ * @task: tasklet to handle the reset operation
* @fifo_depth: depth of tx/rx FIFO
* @slot_width: width of each DAI slot
* @slots: number of slots
@@ -42,6 +43,7 @@
* @sck_div: if using PSR/PM dividers for SCKx clock
* @slave_mode: if fully using DAI slave mode
* @synchronous: if using tx/rx synchronous mode
+ * @reset_at_xrun: flags for enable reset operaton
* @name: driver name
*/
struct fsl_esai {
@@ -53,6 +55,7 @@ struct fsl_esai {
struct clk *extalclk;
struct clk *fsysclk;
struct clk *spbaclk;
+ struct tasklet_struct task;
u32 fifo_depth;
u32 slot_width;
u32 slots;
@@ -65,6 +68,7 @@ struct fsl_esai {
bool sck_div[2];
bool slave_mode;
bool synchronous;
+ bool reset_at_xrun;
char name[32];
};
@@ -73,8 +77,16 @@ static irqreturn_t esai_isr(int irq, void *devid)
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
struct platform_device *pdev = esai_priv->pdev;
u32 esr;
+ u32 saisr;
regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
+ regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
+
+ if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
+ esai_priv->reset_at_xrun) {
+ dev_dbg(&pdev->dev, "reset module for xrun\n");
+ tasklet_schedule(&esai_priv->task);
+ }
if (esr & ESAI_ESR_TINIT_MASK)
dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
@@ -634,10 +646,17 @@ static void fsl_esai_trigger_start(struct fsl_esai *esai_priv, bool tx)
ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(mask));
regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(mask));
+
+ /* Enable Exception interrupt */
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
+ ESAI_xCR_xEIE_MASK, ESAI_xCR_xEIE);
}
static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
{
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
+ ESAI_xCR_xEIE_MASK, 0);
+
regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
regmap_update_bits(esai_priv->regmap, REG_ESAI_xSMA(tx),
@@ -652,6 +671,53 @@ static void fsl_esai_trigger_stop(struct fsl_esai *esai_priv, bool tx)
ESAI_xFCR_xFR, 0);
}
+static void fsl_esai_reset(unsigned long arg)
+{
+ struct fsl_esai *esai_priv = (struct fsl_esai *)arg;
+ u32 saisr, tfcr, rfcr;
+
+ /* save the registers */
+ regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
+ regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
+
+ /* stop the tx & rx */
+ fsl_esai_trigger_stop(esai_priv, 1);
+ fsl_esai_trigger_stop(esai_priv, 0);
+
+ /* reset the esai, and restore the registers */
+ fsl_esai_init(esai_priv);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
+ ESAI_xCR_xPR_MASK,
+ ESAI_xCR_xPR);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
+ ESAI_xCR_xPR_MASK,
+ ESAI_xCR_xPR);
+
+ /* restore registers by regcache_sync */
+ fsl_esai_register_restore(esai_priv);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
+ ESAI_xCR_xPR_MASK, 0);
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
+ ESAI_xCR_xPR_MASK, 0);
+
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
+ ESAI_PRRC_PDC_MASK,
+ ESAI_PRRC_PDC(ESAI_GPIO));
+ regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
+ ESAI_PCRC_PC_MASK,
+ ESAI_PCRC_PC(ESAI_GPIO));
+
+ regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
+
+ /* restart tx / rx, if they already enabled */
+ if (tfcr & ESAI_xFCR_xFEN)
+ fsl_esai_trigger_start(esai_priv, 1);
+ if (rfcr & ESAI_xFCR_xFEN)
+ fsl_esai_trigger_start(esai_priv, 0);
+}
+
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
@@ -856,6 +922,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
esai_priv->pdev = pdev;
snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
+ if (of_device_is_compatible(np, "fsl,vf610-esai") ||
+ of_device_is_compatible(np, "fsl,imx35-esai"))
+ esai_priv->reset_at_xrun = true;
+
/* Get the addresses and IRQ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
regs = devm_ioremap_resource(&pdev->dev, res);
@@ -955,6 +1025,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
+ tasklet_init(&esai_priv->task, fsl_esai_reset,
+ (unsigned long)esai_priv);
+
pm_runtime_enable(&pdev->dev);
regcache_cache_only(esai_priv->regmap, true);
@@ -968,7 +1041,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
static int fsl_esai_remove(struct platform_device *pdev)
{
+ struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
+
pm_runtime_disable(&pdev->dev);
+ tasklet_kill(&esai_priv->task);
return 0;
}
--
2.21.0
^ permalink raw reply related
* [PATCH 00/14] powerpc/64s/exception: machine check cleanup series
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
This ended up blowing out a bit because of some fixes and changes
to the way pseries works, and machine check is the trickiest and most
custom handler.
After this series it's almost understandable, and uses more of the
standard interrupt handler macros, which will make it more amenable
to consolidation in the next round of changes (which won't be in this
merge window).
Thanks,
Nick
Nicholas Piggin (14):
powerpc/64s/exception: machine check fwnmi remove HV case
powerpc/64s/exception: machine check remove bitrotted comment
powerpc/64s/exception: machine check fix KVM guest test
powerpc/64s/exception: machine check adjust RFI target
powerpc/64s/exception: machine check pseries should always run the
early handler
powerpc/64s/exception: machine check remove machine_check_pSeries_0
branch
powerpc/64s/exception: machine check use correct cfar for late handler
powerpc/64s/exception: machine check pseries should skip the late
handler for host kernel MCEs
powerpc/64s/exception: machine check restructure to reuse common
macros
powerpc/64s/exception: machine check move tramp code
powerpc/64s/exception: simplify machine check early path
powerpc/64s/exception: machine check move unrecoverable handling out
of line
powerpc/64s/exception: untangle early machine check handler branch
powerpc/64s/exception: machine check improve labels and comments
arch/powerpc/kernel/exceptions-64s.S | 367 +++++++++++++--------------
1 file changed, 172 insertions(+), 195 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH 01/14] powerpc/64s/exception: machine check fwnmi remove HV case
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
fwnmi does not trigger in HV mode, so remove always-true feature test.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 53c1b0a2ebce..db7ef8c8566f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1026,9 +1026,8 @@ TRAMP_REAL_BEGIN(machine_check_pSeries)
.globl machine_check_fwnmi
machine_check_fwnmi:
EXCEPTION_PROLOG_0 PACA_EXMC
-BEGIN_FTR_SECTION
b machine_check_common_early
-END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
+
machine_check_pSeries_0:
EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
/*
--
2.20.1
^ permalink raw reply related
* [PATCH 02/14] powerpc/64s/exception: machine check remove bitrotted comment
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 4 ----
1 file changed, 4 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index db7ef8c8566f..e8734a1dfdb9 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -933,10 +933,6 @@ EXC_COMMON_BEGIN(system_reset_common)
EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
- /* This is moved out of line as it can be patched by FW, but
- * some code path might still want to branch into the original
- * vector
- */
EXCEPTION_PROLOG_0 PACA_EXMC
BEGIN_FTR_SECTION
b machine_check_common_early
--
2.20.1
^ permalink raw reply related
* [PATCH 03/14] powerpc/64s/exception: machine check fix KVM guest test
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
The machine_check_handle_early hypervisor guest test is skipped if
!HVMODE or MSR[HV]=0, which is wrong for PR or nested hypervisors
that could be running a guest in this state.
Test HSTATE_IN_GUEST up front and use that to branch out to the KVM
handler, then MSR[PR] alone can test for this kernel's userspace.
This matches all other interrupt handling.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 33 +++++++++++-----------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e8734a1dfdb9..5789a00691f9 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1108,11 +1108,8 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
bl machine_check_early
std r3,RESULT(r1) /* Save result */
ld r12,_MSR(r1)
-BEGIN_FTR_SECTION
- b 4f
-END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
-#ifdef CONFIG_PPC_P7_NAP
+#ifdef CONFIG_PPC_P7_NAP
/*
* Check if thread was in power saving mode. We come here when any
* of the following is true:
@@ -1128,30 +1125,26 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
#endif
- /*
- * Check if we are coming from hypervisor userspace. If yes then we
- * continue in host kernel in V mode to deliver the MC event.
- */
- rldicl. r11,r12,4,63 /* See if MC hit while in HV mode. */
- beq 5f
-4: andi. r11,r12,MSR_PR /* See if coming from user. */
- bne 9f /* continue in V mode if we are. */
-
-5:
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-BEGIN_FTR_SECTION
/*
- * We are coming from kernel context. Check if we are coming from
- * guest. if yes, then we can continue. We will fall through
- * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
+ * Check if we are coming from guest. If yes, then run the normal
+ * exception handler which will take the do_kvm_200->kvmppc_interrupt
+ * branch to deliver the MC event to guest.
*/
lbz r11,HSTATE_IN_GUEST(r13)
cmpwi r11,0 /* Check if coming from guest */
bne 9f /* continue if we are. */
-END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
#endif
+
+ /*
+ * Check if we are coming from userspace. If yes, then run the normal
+ * exception handler which will deliver the MC event to this kernel.
+ */
+ andi. r11,r12,MSR_PR /* See if coming from user. */
+ bne 9f /* continue in V mode if we are. */
+
/*
- * At this point we are not sure about what context we come from.
+ * At this point we are coming from kernel context.
* Queue up the MCE event and return from the interrupt.
* But before that, check if this is an un-recoverable exception.
* If yes, then stay on emergency stack and panic.
--
2.20.1
^ permalink raw reply related
* [PATCH 04/14] powerpc/64s/exception: machine check adjust RFI target
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
The host kernel delivery case for powernv does RFI_TO_USER_OR_KERNEL,
but should just use RFI_TO_KERNEL which makes it clear this is not a
user case.
This is not a bug because RFI_TO_USER_OR_KERNEL deals with kernel
returns just fine.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 5789a00691f9..0186a44bb981 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1184,7 +1184,7 @@ BEGIN_FTR_SECTION
*/
bl machine_check_queue_event
MACHINE_CHECK_HANDLER_WINDUP
- RFI_TO_USER_OR_KERNEL
+ RFI_TO_KERNEL
FTR_SECTION_ELSE
/*
* pSeries: Return from MC interrupt. Before that stay on emergency
--
2.20.1
^ permalink raw reply related
* [PATCH 05/14] powerpc/64s/exception: machine check pseries should always run the early handler
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Now that pseries with fwnmi registered runs the early machine check
handler, there is no good reason to special case the non-fwnmi case
and skip the early handler. Reducing the code and number of paths is
a top priority for asm code, it's better to handle this in C where
possible (and the pseries early handler is a no-op if fwnmi is not
registered).
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 4 ----
1 file changed, 4 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 0186a44bb981..a69ceb28cf4c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -934,11 +934,7 @@ EXC_COMMON_BEGIN(system_reset_common)
EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
EXCEPTION_PROLOG_0 PACA_EXMC
-BEGIN_FTR_SECTION
b machine_check_common_early
-FTR_SECTION_ELSE
- b machine_check_pSeries_0
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
EXC_REAL_END(machine_check, 0x200, 0x100)
EXC_VIRT_NONE(0x4200, 0x100)
TRAMP_REAL_BEGIN(machine_check_common_early)
--
2.20.1
^ permalink raw reply related
* [PATCH 06/14] powerpc/64s/exception: machine check remove machine_check_pSeries_0 branch
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
This label has only one caller, so unwind the branch and move it
inline. The location of the comment is adjusted to match similar
one in system reset.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a69ceb28cf4c..54ca2b189d43 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1014,20 +1014,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
b 1b
b . /* prevent speculative execution */
-TRAMP_REAL_BEGIN(machine_check_pSeries)
- .globl machine_check_fwnmi
-machine_check_fwnmi:
+#ifdef CONFIG_PPC_PSERIES
+TRAMP_REAL_BEGIN(machine_check_fwnmi)
EXCEPTION_PROLOG_0 PACA_EXMC
b machine_check_common_early
-
-machine_check_pSeries_0:
- EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
- /*
- * MSR_RI is not enabled, because PACA_EXMC is being used, so a
- * nested machine check corrupts it. machine_check_common enables
- * MSR_RI.
- */
- EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0
+#endif
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
@@ -1197,7 +1188,13 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
/* Deliver the machine check to host kernel in V mode. */
MACHINE_CHECK_HANDLER_WINDUP
EXCEPTION_PROLOG_0 PACA_EXMC
- b machine_check_pSeries_0
+ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
+ EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0
+ /*
+ * MSR_RI is not enabled, because PACA_EXMC is being used, so a
+ * nested machine check corrupts it. machine_check_common enables
+ * MSR_RI.
+ */
EXC_COMMON_BEGIN(unrecover_mce)
/* Invoke machine_check_exception to print MCE event and panic. */
--
2.20.1
^ permalink raw reply related
* [PATCH 07/14] powerpc/64s/exception: machine check use correct cfar for late handler
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Bare metal machine checks run an "early" handler in real mode before
running the main handler which reports the event.
The main handler runs exactly as a normal interrupt handler, after the
"windup" which sets registers back as they were at interrupt entry.
CFAR does not get restored by the windup code, so that will be wrong
when the handler is run.
Restore the CFAR to the saved value before running the late handler.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 54ca2b189d43..f2c24a4ae723 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1186,6 +1186,10 @@ FTR_SECTION_ELSE
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
9:
/* Deliver the machine check to host kernel in V mode. */
+BEGIN_FTR_SECTION
+ ld r10,ORIG_GPR3(r1)
+ mtspr SPRN_CFAR,r10
+END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
MACHINE_CHECK_HANDLER_WINDUP
EXCEPTION_PROLOG_0 PACA_EXMC
EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
--
2.20.1
^ permalink raw reply related
* [PATCH 08/14] powerpc/64s/exception: machine check pseries should skip the late handler for host kernel MCEs
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
The powernv machine check handler copes with taking a MCE from one of
three contexts, guest, host kernel, and host user. In each case the
early handler runs first on a special stack. Then:
- The guest case branches to the KVM interrupt handler (via standard
interrupt macros).
- The host user case will run the "late" handler which is like a
normal interrupt that runs in virtual mode and uses the regular
kernel stack.
- The host kernel case queues the event and schedules it for
processing with irq work.
The last case is important, it must not enable virtual memory because
the MMU state may not be set up to deal with that (e.g., SLB might be
clear), it must not use the regular kernel stack for similar reasons
(e.g., might be in OPAL with OPAL stack in r1), and the kernel does
not expect anything to touch its stack if interrupts are disabled.
The pseries handler does not do this queueing, but instead it always
runs the late handler for host MCEs, which has some of the same
problems.
Rather than special casing pseries, just have it follow what powernv
is doing and queue up these events.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 22 ++--------------------
1 file changed, 2 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index f2c24a4ae723..ac7b5bb614d9 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1163,7 +1163,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
cmpdi r3,0 /* see if we handled MCE successfully */
beq 1b /* if !handled then panic */
-BEGIN_FTR_SECTION
+
/*
* Return from MC interrupt.
* Queue up the MCE event so that we can log it later, while
@@ -1172,18 +1172,7 @@ BEGIN_FTR_SECTION
bl machine_check_queue_event
MACHINE_CHECK_HANDLER_WINDUP
RFI_TO_KERNEL
-FTR_SECTION_ELSE
- /*
- * pSeries: Return from MC interrupt. Before that stay on emergency
- * stack and call machine_check_exception to log the MCE event.
- */
- LOAD_HANDLER(r10,mce_return)
- mtspr SPRN_SRR0,r10
- ld r10,PACAKMSR(r13)
- mtspr SPRN_SRR1,r10
- RFI_TO_KERNEL
- b .
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+
9:
/* Deliver the machine check to host kernel in V mode. */
BEGIN_FTR_SECTION
@@ -1212,13 +1201,6 @@ EXC_COMMON_BEGIN(unrecover_mce)
bl unrecoverable_exception
b 1b
-EXC_COMMON_BEGIN(mce_return)
- /* Invoke machine_check_exception to print MCE event and return. */
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl machine_check_exception
- MACHINE_CHECK_HANDLER_WINDUP
- RFI_TO_KERNEL
- b .
EXC_REAL_BEGIN(data_access, 0x300, 0x80)
EXCEPTION_PROLOG_0 PACA_EXGEN
--
2.20.1
^ permalink raw reply related
* [PATCH 09/14] powerpc/64s/exception: machine check restructure to reuse common macros
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Follow the pattern of sreset and HMI handlers more closely: use
EXCEPTION_PROLOG_COMMON_1 rather than open-coding it, and run the
handler at the relocated location.
This helps later simplification and code sharing.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 71 ++++++++++++++--------------
1 file changed, 36 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index ac7b5bb614d9..3cc5ee6e4b56 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -934,17 +934,23 @@ EXC_COMMON_BEGIN(system_reset_common)
EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
EXCEPTION_PROLOG_0 PACA_EXMC
- b machine_check_common_early
+ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 1, 1, 0
+ mfctr r10 /* save ctr, even for !RELOCATABLE */
+ BRANCH_TO_C000(r11, machine_check_early_common)
+ /*
+ * MSR_RI is not enabled, because PACA_EXMC is being used, so a
+ * nested machine check corrupts it. machine_check_common enables
+ * MSR_RI.
+ */
EXC_REAL_END(machine_check, 0x200, 0x100)
EXC_VIRT_NONE(0x4200, 0x100)
-TRAMP_REAL_BEGIN(machine_check_common_early)
- EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0, 0, 0
+
+EXC_COMMON_BEGIN(machine_check_early_common)
+ mtctr r10 /* Restore ctr */
+ mfspr r11,SPRN_SRR0
+ mfspr r12,SPRN_SRR1
+
/*
- * Register contents:
- * R13 = PACA
- * R9 = CR
- * Original R9 to R13 is saved on PACA_EXMC
- *
* Switch to mc_emergency stack and handle re-entrancy (we limit
* the nested MCE upto level 4 to avoid stack overflow).
* Save MCE registers srr1, srr0, dar and dsisr and then set ME=1
@@ -965,32 +971,30 @@ TRAMP_REAL_BEGIN(machine_check_common_early)
* the machine check is handled then the idle wakeup code is called
* to restore state.
*/
- mr r11,r1 /* Save r1 */
lhz r10,PACA_IN_MCE(r13)
cmpwi r10,0 /* Are we in nested machine check */
- bne 0f /* Yes, we are. */
- /* First machine check entry */
- ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */
-0: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
+ cmpwi cr1,r10,MAX_MCE_DEPTH /* Are we at maximum nesting */
addi r10,r10,1 /* increment paca->in_mce */
sth r10,PACA_IN_MCE(r13)
+
+ mr r10,r1 /* Save r1 */
+ bne 1f
+ /* First machine check entry */
+ ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */
+1: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
/* Limit nested MCE to level 4 to avoid stack overflow */
- cmpwi r10,MAX_MCE_DEPTH
- bgt 2f /* Check if we hit limit of 4 */
- std r11,GPR1(r1) /* Save r1 on the stack. */
- std r11,0(r1) /* make stack chain pointer */
- mfspr r11,SPRN_SRR0 /* Save SRR0 */
- std r11,_NIP(r1)
- mfspr r11,SPRN_SRR1 /* Save SRR1 */
- std r11,_MSR(r1)
- mfspr r11,SPRN_DAR /* Save DAR */
- std r11,_DAR(r1)
- mfspr r11,SPRN_DSISR /* Save DSISR */
- std r11,_DSISR(r1)
- std r9,_CCR(r1) /* Save CR in stackframe */
+ bge cr1,2f /* Check if we hit limit of 4 */
+
+ EXCEPTION_PROLOG_COMMON_1()
/* We don't touch AMR here, we never go to virtual mode */
- /* Save r9 through r13 from EXMC save area to stack frame. */
EXCEPTION_PROLOG_COMMON_2(PACA_EXMC)
+ EXCEPTION_PROLOG_COMMON_3(0x200)
+
+ ld r3,PACA_EXMC+EX_DAR(r13)
+ lwz r4,PACA_EXMC+EX_DSISR(r13)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+
mfmsr r11 /* get MSR value */
BEGIN_FTR_SECTION
ori r11,r11,MSR_ME /* turn on ME bit */
@@ -1016,8 +1020,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
#ifdef CONFIG_PPC_PSERIES
TRAMP_REAL_BEGIN(machine_check_fwnmi)
+ /* See comment at machine_check exception, don't turn on RI */
EXCEPTION_PROLOG_0 PACA_EXMC
- b machine_check_common_early
+ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 1, 1, 0
+ mfctr r10 /* save ctr */
+ BRANCH_TO_C000(r11, machine_check_early_common)
#endif
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
@@ -1088,8 +1095,6 @@ EXC_COMMON_BEGIN(machine_check_idle_common)
* ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack.
*/
EXC_COMMON_BEGIN(machine_check_handle_early)
- std r0,GPR0(r1) /* Save r0 */
- EXCEPTION_PROLOG_COMMON_3(0x200)
bl save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
bl machine_check_early
@@ -1180,14 +1185,10 @@ BEGIN_FTR_SECTION
mtspr SPRN_CFAR,r10
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
MACHINE_CHECK_HANDLER_WINDUP
+ /* See comment at machine_check exception, don't turn on RI */
EXCEPTION_PROLOG_0 PACA_EXMC
EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0
- /*
- * MSR_RI is not enabled, because PACA_EXMC is being used, so a
- * nested machine check corrupts it. machine_check_common enables
- * MSR_RI.
- */
EXC_COMMON_BEGIN(unrecover_mce)
/* Invoke machine_check_exception to print MCE event and panic. */
--
2.20.1
^ permalink raw reply related
* [PATCH 10/14] powerpc/64s/exception: machine check move tramp code
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Following convention, move the tramp code (unrelocated) above the
common handlers (relocated).
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3cc5ee6e4b56..9bb8c89e9e77 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -945,6 +945,17 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
EXC_REAL_END(machine_check, 0x200, 0x100)
EXC_VIRT_NONE(0x4200, 0x100)
+#ifdef CONFIG_PPC_PSERIES
+TRAMP_REAL_BEGIN(machine_check_fwnmi)
+ /* See comment at machine_check exception, don't turn on RI */
+ EXCEPTION_PROLOG_0 PACA_EXMC
+ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 1, 1, 0
+ mfctr r10 /* save ctr */
+ BRANCH_TO_C000(r11, machine_check_early_common)
+#endif
+
+TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
+
EXC_COMMON_BEGIN(machine_check_early_common)
mtctr r10 /* Restore ctr */
mfspr r11,SPRN_SRR0
@@ -1018,17 +1029,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
b 1b
b . /* prevent speculative execution */
-#ifdef CONFIG_PPC_PSERIES
-TRAMP_REAL_BEGIN(machine_check_fwnmi)
- /* See comment at machine_check exception, don't turn on RI */
- EXCEPTION_PROLOG_0 PACA_EXMC
- EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 1, 1, 0
- mfctr r10 /* save ctr */
- BRANCH_TO_C000(r11, machine_check_early_common)
-#endif
-
-TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
-
EXC_COMMON_BEGIN(machine_check_common)
/*
* Machine check is different because we use a different
--
2.20.1
^ permalink raw reply related
* [PATCH 11/14] powerpc/64s/exception: simplify machine check early path
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
machine_check_handle_early_common can reach machine_check_handle_early
directly now that it runs at the relocated address, so just branch
directly.
The rfi sequence is required to enable MSR[ME] but that step is moved
into a helper function, making the code easier to follow.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 30 +++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 9bb8c89e9e77..fcc3e6d5807f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1006,16 +1006,13 @@ EXC_COMMON_BEGIN(machine_check_early_common)
std r3,_DAR(r1)
std r4,_DSISR(r1)
- mfmsr r11 /* get MSR value */
+ li r10,MSR_RI
+ mtmsrd r10,1
BEGIN_FTR_SECTION
- ori r11,r11,MSR_ME /* turn on ME bit */
+ bl enable_machine_check
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
- ori r11,r11,MSR_RI /* turn on RI bit */
- LOAD_HANDLER(r12, machine_check_handle_early)
-1: mtspr SPRN_SRR0,r12
- mtspr SPRN_SRR1,r11
- RFI_TO_KERNEL
- b . /* prevent speculative execution */
+ b machine_check_handle_early
+
2:
/* Stack overflow. Stay on emergency stack and panic.
* Keep the ME bit off while panic-ing, so that if we hit
@@ -1026,7 +1023,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
LOAD_HANDLER(r12, unrecover_mce)
li r10,MSR_ME
andc r11,r11,r10 /* Turn off MSR_ME */
- b 1b
+ mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r11
+ RFI_TO_KERNEL
b . /* prevent speculative execution */
EXC_COMMON_BEGIN(machine_check_common)
@@ -2270,6 +2269,19 @@ CLOSE_FIXED_SECTION(virt_trampolines);
USE_TEXT_SECTION()
+enable_machine_check:
+ mflr r0
+ bcl 20,31,$+4
+0: mflr r3
+ addi r3,r3,(1f - 0b)
+ mtspr SPRN_SRR0,r3
+ mfmsr r3
+ ori r3,r3,MSR_ME
+ mtspr SPRN_SRR1,r3
+ RFI_TO_KERNEL
+1: mtlr r0
+ blr
+
/*
* Hash table stuff
*/
--
2.20.1
^ permalink raw reply related
* [PATCH 12/14] powerpc/64s/exception: machine check move unrecoverable handling out of line
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Similarly to the previous change, all callers of the unrecoverable
handler run relocated so can reach it with a direct branch. This makes
it easy to move out of line, which makes the "normal" path less
cluttered and easier to follow.
MSR[ME] manipulation still requires the rfi, so that is moved out of
line to its own function.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 82 +++++++++++++---------------
1 file changed, 39 insertions(+), 43 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index fcc3e6d5807f..88bcdd5b2dc7 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -992,9 +992,9 @@ EXC_COMMON_BEGIN(machine_check_early_common)
bne 1f
/* First machine check entry */
ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */
-1: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
- /* Limit nested MCE to level 4 to avoid stack overflow */
- bge cr1,2f /* Check if we hit limit of 4 */
+1: /* Limit nested MCE to level 4 to avoid stack overflow */
+ bgt cr1,unrecoverable_mce /* Check if we hit limit of 4 */
+ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
EXCEPTION_PROLOG_COMMON_1()
/* We don't touch AMR here, we never go to virtual mode */
@@ -1013,21 +1013,6 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
b machine_check_handle_early
-2:
- /* Stack overflow. Stay on emergency stack and panic.
- * Keep the ME bit off while panic-ing, so that if we hit
- * another machine check we checkstop.
- */
- addi r1,r1,INT_FRAME_SIZE /* go back to previous stack frame */
- ld r11,PACAKMSR(r13)
- LOAD_HANDLER(r12, unrecover_mce)
- li r10,MSR_ME
- andc r11,r11,r10 /* Turn off MSR_ME */
- mtspr SPRN_SRR0,r12
- mtspr SPRN_SRR1,r11
- RFI_TO_KERNEL
- b . /* prevent speculative execution */
-
EXC_COMMON_BEGIN(machine_check_common)
/*
* Machine check is different because we use a different
@@ -1141,32 +1126,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
* If yes, then stay on emergency stack and panic.
*/
andi. r11,r12,MSR_RI
- bne 2f
-1: mfspr r11,SPRN_SRR0
- LOAD_HANDLER(r10,unrecover_mce)
- mtspr SPRN_SRR0,r10
- ld r10,PACAKMSR(r13)
- /*
- * We are going down. But there are chances that we might get hit by
- * another MCE during panic path and we may run into unstable state
- * with no way out. Hence, turn ME bit off while going down, so that
- * when another MCE is hit during panic path, system will checkstop
- * and hypervisor will get restarted cleanly by SP.
- */
- li r3,MSR_ME
- andc r10,r10,r3 /* Turn off MSR_ME */
- mtspr SPRN_SRR1,r10
- RFI_TO_KERNEL
- b .
-2:
+ beq unrecoverable_mce
+
/*
* Check if we have successfully handled/recovered from error, if not
* then stay on emergency stack and panic.
*/
ld r3,RESULT(r1) /* Load result */
cmpdi r3,0 /* see if we handled MCE successfully */
-
- beq 1b /* if !handled then panic */
+ beq unrecoverable_mce /* if !handled then panic */
/*
* Return from MC interrupt.
@@ -1189,17 +1157,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0
-EXC_COMMON_BEGIN(unrecover_mce)
+EXC_COMMON_BEGIN(unrecoverable_mce)
+ /*
+ * We are going down. But there are chances that we might get hit by
+ * another MCE during panic path and we may run into unstable state
+ * with no way out. Hence, turn ME bit off while going down, so that
+ * when another MCE is hit during panic path, system will checkstop
+ * and hypervisor will get restarted cleanly by SP.
+ */
+ bl disable_machine_check
+ ld r10,PACAKMSR(r13)
+ li r3,MSR_ME
+ andc r10,r10,r3
+ mtmsrd r10
+
/* Invoke machine_check_exception to print MCE event and panic. */
addi r3,r1,STACK_FRAME_OVERHEAD
bl machine_check_exception
+
/*
- * We will not reach here. Even if we did, there is no way out. Call
- * unrecoverable_exception and die.
+ * We will not reach here. Even if we did, there is no way out.
+ * Call unrecoverable_exception and die.
*/
-1: addi r3,r1,STACK_FRAME_OVERHEAD
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl unrecoverable_exception
- b 1b
+ b .
EXC_REAL_BEGIN(data_access, 0x300, 0x80)
@@ -2282,6 +2264,20 @@ enable_machine_check:
1: mtlr r0
blr
+disable_machine_check:
+ mflr r0
+ bcl 20,31,$+4
+0: mflr r3
+ addi r3,r3,(1f - 0b)
+ mtspr SPRN_SRR0,r3
+ mfmsr r3
+ li r4,MSR_ME
+ andc r3,r3,r4
+ mtspr SPRN_SRR1,r3
+ RFI_TO_KERNEL
+1: mtlr r0
+ blr
+
/*
* Hash table stuff
*/
--
2.20.1
^ permalink raw reply related
* [PATCH 13/14] powerpc/64s/exception: untangle early machine check handler branch
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
machine_check_early_common now branches to machine_check_handle_early
which is its only caller.
Move interleaving code out of the way, and remove the branch.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 129 +++++++++++++--------------
1 file changed, 62 insertions(+), 67 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 88bcdd5b2dc7..8e16578cf932 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -956,6 +956,16 @@ TRAMP_REAL_BEGIN(machine_check_fwnmi)
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
+#define MACHINE_CHECK_HANDLER_WINDUP \
+ /* Clear MSR_RI before setting SRR0 and SRR1. */\
+ li r9,0; \
+ mtmsrd r9,1; /* Clear MSR_RI */ \
+ /* Decrement paca->in_mce now RI is clear. */ \
+ lhz r12,PACA_IN_MCE(r13); \
+ subi r12,r12,1; \
+ sth r12,PACA_IN_MCE(r13); \
+ EXCEPTION_RESTORE_REGS EXC_STD
+
EXC_COMMON_BEGIN(machine_check_early_common)
mtctr r10 /* Restore ctr */
mfspr r11,SPRN_SRR0
@@ -1011,74 +1021,7 @@ EXC_COMMON_BEGIN(machine_check_early_common)
BEGIN_FTR_SECTION
bl enable_machine_check
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
- b machine_check_handle_early
-EXC_COMMON_BEGIN(machine_check_common)
- /*
- * Machine check is different because we use a different
- * save area: PACA_EXMC instead of PACA_EXGEN.
- */
- EXCEPTION_COMMON(PACA_EXMC, 0x200)
- FINISH_NAP
- RECONCILE_IRQ_STATE(r10, r11)
- ld r3,PACA_EXMC+EX_DAR(r13)
- lwz r4,PACA_EXMC+EX_DSISR(r13)
- /* Enable MSR_RI when finished with PACA_EXMC */
- li r10,MSR_RI
- mtmsrd r10,1
- std r3,_DAR(r1)
- std r4,_DSISR(r1)
- bl save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl machine_check_exception
- b ret_from_except
-
-#define MACHINE_CHECK_HANDLER_WINDUP \
- /* Clear MSR_RI before setting SRR0 and SRR1. */\
- li r9,0; \
- mtmsrd r9,1; /* Clear MSR_RI */ \
- /* Decrement paca->in_mce now RI is clear. */ \
- lhz r12,PACA_IN_MCE(r13); \
- subi r12,r12,1; \
- sth r12,PACA_IN_MCE(r13); \
- EXCEPTION_RESTORE_REGS EXC_STD
-
-#ifdef CONFIG_PPC_P7_NAP
-/*
- * This is an idle wakeup. Low level machine check has already been
- * done. Queue the event then call the idle code to do the wake up.
- */
-EXC_COMMON_BEGIN(machine_check_idle_common)
- bl machine_check_queue_event
-
- /*
- * We have not used any non-volatile GPRs here, and as a rule
- * most exception code including machine check does not.
- * Therefore PACA_NAPSTATELOST does not need to be set. Idle
- * wakeup will restore volatile registers.
- *
- * Load the original SRR1 into r3 for pnv_powersave_wakeup_mce.
- *
- * Then decrement MCE nesting after finishing with the stack.
- */
- ld r3,_MSR(r1)
- ld r4,_LINK(r1)
-
- lhz r11,PACA_IN_MCE(r13)
- subi r11,r11,1
- sth r11,PACA_IN_MCE(r13)
-
- mtlr r4
- rlwinm r10,r3,47-31,30,31
- cmpwi cr1,r10,2
- bltlr cr1 /* no state loss, return to idle caller */
- b idle_return_gpr_loss
-#endif
- /*
- * Handle machine check early in real mode. We come here with
- * ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack.
- */
-EXC_COMMON_BEGIN(machine_check_handle_early)
bl save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
bl machine_check_early
@@ -1157,6 +1100,58 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0
+EXC_COMMON_BEGIN(machine_check_common)
+ /*
+ * Machine check is different because we use a different
+ * save area: PACA_EXMC instead of PACA_EXGEN.
+ */
+ EXCEPTION_COMMON(PACA_EXMC, 0x200)
+ FINISH_NAP
+ RECONCILE_IRQ_STATE(r10, r11)
+ ld r3,PACA_EXMC+EX_DAR(r13)
+ lwz r4,PACA_EXMC+EX_DSISR(r13)
+ /* Enable MSR_RI when finished with PACA_EXMC */
+ li r10,MSR_RI
+ mtmsrd r10,1
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+ bl save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl machine_check_exception
+ b ret_from_except
+
+#ifdef CONFIG_PPC_P7_NAP
+/*
+ * This is an idle wakeup. Low level machine check has already been
+ * done. Queue the event then call the idle code to do the wake up.
+ */
+EXC_COMMON_BEGIN(machine_check_idle_common)
+ bl machine_check_queue_event
+
+ /*
+ * We have not used any non-volatile GPRs here, and as a rule
+ * most exception code including machine check does not.
+ * Therefore PACA_NAPSTATELOST does not need to be set. Idle
+ * wakeup will restore volatile registers.
+ *
+ * Load the original SRR1 into r3 for pnv_powersave_wakeup_mce.
+ *
+ * Then decrement MCE nesting after finishing with the stack.
+ */
+ ld r3,_MSR(r1)
+ ld r4,_LINK(r1)
+
+ lhz r11,PACA_IN_MCE(r13)
+ subi r11,r11,1
+ sth r11,PACA_IN_MCE(r13)
+
+ mtlr r4
+ rlwinm r10,r3,47-31,30,31
+ cmpwi cr1,r10,2
+ bltlr cr1 /* no state loss, return to idle caller */
+ b idle_return_gpr_loss
+#endif
+
EXC_COMMON_BEGIN(unrecoverable_mce)
/*
* We are going down. But there are chances that we might get hit by
--
2.20.1
^ permalink raw reply related
* [PATCH 14/14] powerpc/64s/exception: machine check improve labels and comments
From: Nicholas Piggin @ 2019-07-03 7:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Mahesh Salgaonkar, Nicholas Piggin
In-Reply-To: <20190703075444.19005-1-npiggin@gmail.com>
Short forward and backward branches can be given number labels,
but larger significant divergences in code path a more readable
if they're given descriptive names.
Also adjusts a comment to account for guest delivery.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 8e16578cf932..0676a0f4c2d5 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1052,7 +1052,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
*/
lbz r11,HSTATE_IN_GUEST(r13)
cmpwi r11,0 /* Check if coming from guest */
- bne 9f /* continue if we are. */
+ bne mce_deliver /* continue if we are. */
#endif
/*
@@ -1060,7 +1060,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
* exception handler which will deliver the MC event to this kernel.
*/
andi. r11,r12,MSR_PR /* See if coming from user. */
- bne 9f /* continue in V mode if we are. */
+ bne mce_deliver /* continue in V mode if we are. */
/*
* At this point we are coming from kernel context.
@@ -1088,8 +1088,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
MACHINE_CHECK_HANDLER_WINDUP
RFI_TO_KERNEL
-9:
- /* Deliver the machine check to host kernel in V mode. */
+mce_deliver:
+ /*
+ * This is a host user or guest MCE. Restore all registers, then
+ * run the "late" handler. For host user, this will run the
+ * machine_check_exception handler in virtual mode like a normal
+ * interrupt handler. For guest, this will trigger the KVM test
+ * and branch to the KVM interrupt similarly to other interrupts.
+ */
BEGIN_FTR_SECTION
ld r10,ORIG_GPR3(r1)
mtspr SPRN_CFAR,r10
--
2.20.1
^ permalink raw reply related
* Re: [PATCH V2 1/2] ASoC: fsl_esai: Wrap some operations to be functions
From: Nicolin Chen @ 2019-07-03 9:10 UTC (permalink / raw)
To: shengjiu.wang
Cc: alsa-devel, timur, Xiubo.Lee, festevam, linux-kernel, broonie,
linuxppc-dev
In-Reply-To: <f57c5a045c6e5491b1bc9831388eab2c88773176.1562136119.git.shengjiu.wang@nxp.com>
Looks good to me, yet two small comments inline.
Please add this to this patch in the next version:
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
On Wed, Jul 03, 2019 at 02:42:04PM +0800, shengjiu.wang@nxp.com wrote:
> +static int fsl_esai_register_restore(struct fsl_esai *esai_priv)
> +{
> + int ret;
> + /* FIFO reset for safety */
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR,
Checkpatch script would probably warn this. Usually we add a blank
line after variable declarations.
> @@ -866,22 +935,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
>
> dev_set_drvdata(&pdev->dev, esai_priv);
>
> - /* Reset ESAI unit */
> - ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
> - if (ret) {
> - dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
> + ret = fsl_esai_init(esai_priv);
Could we rename this function to fsl_easi_hw_init() or something
clear like fsl_esai_register_init? fsl_easi_init() feels like a
driver init() function to me.
Thank you
Nicolin
^ permalink raw reply
* Re: [PATCH V2 2/2] ASoC: fsl_esai: recover the channel swap after xrun
From: Nicolin Chen @ 2019-07-03 9:32 UTC (permalink / raw)
To: shengjiu.wang
Cc: alsa-devel, timur, Xiubo.Lee, festevam, linux-kernel, broonie,
linuxppc-dev
In-Reply-To: <c29639336b6b32fa781bdddad30287f8b76d5e0b.1562136119.git.shengjiu.wang@nxp.com>
On Wed, Jul 03, 2019 at 02:42:05PM +0800, shengjiu.wang@nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> There is chip errata ERR008000, the reference doc is
> (https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf),
>
> The issue is "While using ESAI transmit or receive and
> an underrun/overrun happens, channel swap may occur.
> The only recovery mechanism is to reset the ESAI."
>
> This issue exist in imx3/imx5/imx6(partial) series.
>
> In this commit add a tasklet to handle reset of ESAI
> after xrun happens to recover the channel swap.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
> sound/soc/fsl/fsl_esai.c | 76 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 76 insertions(+)
>
> diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
> index 20039ae9893b..8c92e49ad6d8 100644
> --- a/sound/soc/fsl/fsl_esai.c
> +++ b/sound/soc/fsl/fsl_esai.c
> +static void fsl_esai_reset(unsigned long arg)
Similarly fsl_esai_hw_reset? This one isn't really that bad though,
yet it feels better to have function naming in a similar style.
> +{
> + struct fsl_esai *esai_priv = (struct fsl_esai *)arg;
> + u32 saisr, tfcr, rfcr;
> +
> + /* save the registers */
> + regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
> + regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
Instead of having this implicit comments, we could have:
+ bool tx = true, rx = false, enabled[2];
+
+ regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &tfcr);
+ regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &rfcr);
+ enabled[tx] = tfcr & ESAI_xFCR_xFEN;
+ enabled[rx] = rfcr & ESAI_xFCR_xFEN;
> +
> + /* stop the tx & rx */
> + fsl_esai_trigger_stop(esai_priv, 1);
> + fsl_esai_trigger_stop(esai_priv, 0);
And we could reuse the boolean 'tx' and 'rx' here.
> +
> + /* reset the esai, and restore the registers */
> + fsl_esai_init(esai_priv);
> +
[...]
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
> + ESAI_xCR_xPR_MASK,
> + ESAI_xCR_xPR);
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
> + ESAI_xCR_xPR_MASK,
> + ESAI_xCR_xPR);
Mask and value might fit into one line?
> +
> + /* restore registers by regcache_sync */
> + fsl_esai_register_restore(esai_priv);
> +
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
> + ESAI_xCR_xPR_MASK, 0);
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR,
> + ESAI_xCR_xPR_MASK, 0);
And just for curious, can (or shall) we stuff this personal reset
to the reset() function? I found this one is a part of the reset
routine being mentioned in the RM -- it was done after ESAI reset
is done via ECR register.
[...]
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
> + ESAI_PRRC_PDC_MASK,
> + ESAI_PRRC_PDC(ESAI_GPIO));
> + regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
> + ESAI_PCRC_PC_MASK,
> + ESAI_PCRC_PC(ESAI_GPIO));
Mask and value might fit into one line?
^ permalink raw reply
* Kernel Bug/oops during boot (PowerVM LPAR w/vTPM)
From: Sachin Sant @ 2019-07-03 10:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nayna, gcwilson
Booting mainline kernel on PowerVM LPAR with vTPM enabled results
into a kernel crash.
[ 0.365989] BUG: Kernel NULL pointer dereference at 0x00000012
[ 0.365995] Faulting instruction address: 0xc00000000073dd80
[ 0.366000] Oops: Kernel access of bad area, sig: 11 [#1]
[ 0.366005] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
[ 0.366010] Modules linked in:
[ 0.366015] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.2.0-rc7-autotest-autotest #1
[ 0.366020] NIP: c00000000073dd80 LR: c00000000073dcd0 CTR: 0000000000000000
[ 0.366026] REGS: c0000018ed8e7550 TRAP: 0380 Not tainted (5.2.0-rc7-autotest-autotest)
[ 0.366031] MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 28002448 XER: 20040001
[ 0.366038] CFAR: c000000000b6d1c4 IRQMASK: 0
[ 0.366038] GPR00: c00000000073dcd0 c0000018ed8e77e0 c000000001524a00 0000000000000000
[ 0.366038] GPR04: 0000000000000003 0000000000000000 0000000000010000 000000000000000e
[ 0.366038] GPR08: 0000000000000022 0000000000010000 c0000018e5510000 00000000883bfecd
[ 0.366038] GPR12: 0000000048002448 c00000001ec6ee00 c0000000000107a8 0000000000000000
[ 0.366038] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 0.366038] GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 0.366038] GPR24: c0000018eb9eaaa0 0000000000000000 c000000000bce810 c000000000e2ed28
[ 0.366038] GPR28: c0000018e70a4000 000000000000000a 0000000000000012 c0000018e5510000
[ 0.366085] NIP [c00000000073dd80] tpm1_pcr_extend+0x130/0x230
[ 0.366090] LR [c00000000073dcd0] tpm1_pcr_extend+0x80/0x230
[ 0.366094] Call Trace:
[ 0.366098] [c0000018ed8e77e0] [c00000000073dcd0] tpm1_pcr_extend+0x80/0x230 (unreliable)
[ 0.366105] [c0000018ed8e7890] [c00000000073c8c4] tpm_pcr_extend+0xd4/0x180
[ 0.366111] [c0000018ed8e78d0] [c0000000005745f8] ima_add_template_entry+0x198/0x320
[ 0.366117] [c0000018ed8e79b0] [c000000000577058] ima_store_template+0xc8/0x160
[ 0.366124] [c0000018ed8e7a30] [c000000000f6081c] ima_add_boot_aggregate+0xf8/0x184
[ 0.366130] [c0000018ed8e7b30] [c000000000f6093c] ima_init+0x94/0xbc
[ 0.366135] [c0000018ed8e7b90] [c000000000f60aac] init_ima+0x44/0xe8
[ 0.366140] [c0000018ed8e7c10] [c000000000010448] do_one_initcall+0x68/0x2c0
[ 0.366146] [c0000018ed8e7ce0] [c000000000f14738] kernel_init_freeable+0x318/0x47c
[ 0.366152] [c0000018ed8e7db0] [c0000000000107c4] kernel_init+0x24/0x150
[ 0.366158] [c0000018ed8e7e20] [c00000000000ba54] ret_from_kernel_thread+0x5c/0x68
[ 0.366163] Instruction dump:
[ 0.366167] 7d404d2c 81210068 792a07e1 e9410070 392a0002 7d004c2c 79070020 40c20048
[ 0.366174] 39080014 3d200001 7f884840 419d00a4 <807e0000> 809e0004 80be0008 80de000c
[ 0.366182] ---[ end trace ec40127c4fe87b2c ]—
Thanks
-Sachin
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox