Re: [PATCH v4 2/2] powerpc/rtas: Implement reentrant rtas call

2020-05-15 Thread Nicholas Piggin
Excerpts from Leonardo Bras's message of May 15, 2020 9:51 am:
> Implement rtas_call_reentrant() for reentrant rtas-calls:
> "ibm,int-on", "ibm,int-off",ibm,get-xive" and  "ibm,set-xive".
> 
> On LoPAPR Version 1.1 (March 24, 2016), from 7.3.10.1 to 7.3.10.4,
> items 2 and 3 say:
> 
> 2 - For the PowerPC External Interrupt option: The * call must be
> reentrant to the number of processors on the platform.
> 3 - For the PowerPC External Interrupt option: The * argument call
> buffer for each simultaneous call must be physically unique.
> 
> So, these rtas-calls can be called in a lockless way, if using
> a different buffer for each cpu doing such rtas call.

What about rtas_call_unlocked? Do the callers need to take the rtas 
lock?

Machine checks must call ibm,nmi-interlock too, which we really don't 
want to take a lock for either. Hopefully that's in a class of its own
and we can essentially ignore with respect to other rtas calls.

The spec is pretty vague too :(

"The ibm,get-xive call must be reentrant to the number of processors on 
the platform."

This suggests ibm,get-xive can be called concurrently by multiple
processors. It doesn't say anything about being re-entrant against any 
of the other re-entrant calls. Maybe that could be reasonably assumed,
but I don't know if it's reasonable to assume it can be called 
concurrently with a *non-reentrant* call, is it?

> For this, it was suggested to add the buffer (struct rtas_args)
> in the PACA struct, so each cpu can have it's own buffer.

You can't do this, paca is not limited to RTAS_INSTANTIATE_MAX.
Which is good, because I didn't want you to add another 88 bytes to the 
paca :) Can you make it a pointer and allocate it separately? Check
the slb_shadow allocation, you could use a similar pattern.

The other option would be to have just one more rtas args, and have the 
crashing CPU always that. That would skirt the re-entrancy issue -- the
concurrency is only ever a last resort. Would be a bit tricker though.

Thanks,
Nick


Re: [PATCH] tty: hvc: Fix data abort due to race in hvc_open

2020-05-15 Thread Greg KH
On Thu, May 14, 2020 at 04:22:10PM -0700, rana...@codeaurora.org wrote:
> On 2020-05-13 00:04, Greg KH wrote:
> > On Tue, May 12, 2020 at 02:39:50PM -0700, rana...@codeaurora.org wrote:
> > > On 2020-05-12 01:25, Greg KH wrote:
> > > > On Tue, May 12, 2020 at 09:22:15AM +0200, Jiri Slaby wrote:
> > > > > On 11. 05. 20, 9:39, Greg KH wrote:
> > > > > > On Mon, May 11, 2020 at 12:23:58AM -0700, rana...@codeaurora.org 
> > > > > > wrote:
> > > > > >> On 2020-05-09 23:48, Greg KH wrote:
> > > > > >>> On Sat, May 09, 2020 at 06:30:56PM -0700, rana...@codeaurora.org 
> > > > > >>> wrote:
> > > > >  On 2020-05-06 02:48, Greg KH wrote:
> > > > > > On Mon, Apr 27, 2020 at 08:26:01PM -0700, Raghavendra Rao 
> > > > > > Ananta wrote:
> > > > > >> Potentially, hvc_open() can be called in parallel when two 
> > > > > >> tasks calls
> > > > > >> open() on /dev/hvcX. In such a scenario, if the
> > > > > >> hp->ops->notifier_add()
> > > > > >> callback in the function fails, where it sets the 
> > > > > >> tty->driver_data to
> > > > > >> NULL, the parallel hvc_open() can see this NULL and cause a 
> > > > > >> memory
> > > > > >> abort.
> > > > > >> Hence, serialize hvc_open and check if tty->private_data is 
> > > > > >> NULL
> > > > > >> before
> > > > > >> proceeding ahead.
> > > > > >>
> > > > > >> The issue can be easily reproduced by launching two tasks
> > > > > >> simultaneously
> > > > > >> that does nothing but open() and close() on /dev/hvcX.
> > > > > >> For example:
> > > > > >> $ ./simple_open_close /dev/hvc0 & ./simple_open_close 
> > > > > >> /dev/hvc0 &
> > > > > >>
> > > > > >> Signed-off-by: Raghavendra Rao Ananta 
> > > > > >> ---
> > > > > >>  drivers/tty/hvc/hvc_console.c | 16 ++--
> > > > > >>  1 file changed, 14 insertions(+), 2 deletions(-)
> > > > > >>
> > > > > >> diff --git a/drivers/tty/hvc/hvc_console.c
> > > > > >> b/drivers/tty/hvc/hvc_console.c
> > > > > >> index 436cc51c92c3..ebe26fe5ac09 100644
> > > > > >> --- a/drivers/tty/hvc/hvc_console.c
> > > > > >> +++ b/drivers/tty/hvc/hvc_console.c
> > > > > >> @@ -75,6 +75,8 @@ static LIST_HEAD(hvc_structs);
> > > > > >>   */
> > > > > >>  static DEFINE_MUTEX(hvc_structs_mutex);
> > > > > >>
> > > > > >> +/* Mutex to serialize hvc_open */
> > > > > >> +static DEFINE_MUTEX(hvc_open_mutex);
> > > > > >>  /*
> > > > > >>   * This value is used to assign a tty->index value to a 
> > > > > >> hvc_struct
> > > > > >> based
> > > > > >>   * upon order of exposure via hvc_probe(), when we can not 
> > > > > >> match it
> > > > > >> to
> > > > > >> @@ -346,16 +348,24 @@ static int hvc_install(struct tty_driver
> > > > > >> *driver, struct tty_struct *tty)
> > > > > >>   */
> > > > > >>  static int hvc_open(struct tty_struct *tty, struct file * 
> > > > > >> filp)
> > > > > >>  {
> > > > > >> -  struct hvc_struct *hp = tty->driver_data;
> > > > > >> +  struct hvc_struct *hp;
> > > > > >>unsigned long flags;
> > > > > >>int rc = 0;
> > > > > >>
> > > > > >> +  mutex_lock(&hvc_open_mutex);
> > > > > >> +
> > > > > >> +  hp = tty->driver_data;
> > > > > >> +  if (!hp) {
> > > > > >> +  rc = -EIO;
> > > > > >> +  goto out;
> > > > > >> +  }
> > > > > >> +
> > > > > >>spin_lock_irqsave(&hp->port.lock, flags);
> > > > > >>/* Check and then increment for fast path open. */
> > > > > >>if (hp->port.count++ > 0) {
> > > > > >>spin_unlock_irqrestore(&hp->port.lock, flags);
> > > > > >>hvc_kick();
> > > > > >> -  return 0;
> > > > > >> +  goto out;
> > > > > >>} /* else count == 0 */
> > > > > >>spin_unlock_irqrestore(&hp->port.lock, flags);
> > > > > >
> > > > > > Wait, why isn't this driver just calling tty_port_open() 
> > > > > > instead of
> > > > > > trying to open-code all of this?
> > > > > >
> > > > > > Keeping a single mutext for open will not protect it from 
> > > > > > close, it will
> > > > > > just slow things down a bit.  There should already be a tty 
> > > > > > lock held by
> > > > > > the tty core for open() to keep it from racing things, right?
> > > > >  The tty lock should have been held, but not likely across
> > > > >  ->install() and
> > > > >  ->open() callbacks, thus resulting in a race between 
> > > > >  hvc_install() and
> > > > >  hvc_open(),
> > > > > >>>
> > > > > >>> How?  The tty lock is held in install, and should not conflict 
> > > > > >>> with
> > > > > >>> open(), otherwise, we would be seeing this happen in all tty 
> > > > > >>> drivers,
> > > > > >>> right?
> > > > > >>>
> > > > > >> Well, I was exp

Re: [PATCH v8 08/30] powerpc: Use a function for getting the instruction op code

2020-05-15 Thread Jordan Niethe
mpe, as suggested by Christophe could you please add this.
diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_INST_H
 #define _ASM_INST_H

+#include 
+
 /*
  * Instruction data type for POWER
  */
@@ -15,7 +17,7 @@ static inline u32 ppc_inst_val(u32 x)

 static inline int ppc_inst_primary_opcode(u32 x)
 {
-return ppc_inst_val(x) >> 26;
+return get_op(ppc_inst_val(x));
 }

 #endif /* _ASM_INST_H */
-- 
2.17.1


Re: [PATCH v8 23/30] powerpc: Add prefixed instructions to instruction data type

2020-05-15 Thread Jordan Niethe
Hey mpe, fixes for the issues highlighted by Christophe, except KUAP
as discussed. Will make the optprobe change as a preceding patch.

diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h
--- a/arch/powerpc/include/asm/inst.h
+++ b/arch/powerpc/include/asm/inst.h
@@ -11,9 +11,9 @@

 struct ppc_inst {
 u32 val;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 u32 suffix;
-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */
 } __packed;

 static inline u32 ppc_inst_val(struct ppc_inst x)
@@ -26,7 +26,7 @@ static inline int ppc_inst_primary_opcode(struct ppc_inst x)
 return get_op(ppc_inst_val(x));
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 #define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })

 #define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) })
@@ -52,7 +52,7 @@ static inline struct ppc_inst ppc_inst_read(const
struct ppc_inst *ptr)
 u32 val, suffix;

 val = *(u32 *)ptr;
-if ((val >> 26) == 1) {
+if ((get_op(val)) == OP_PREFIX) {
 suffix = *((u32 *)ptr + 1);
 return ppc_inst_prefix(val, suffix);
 } else {
@@ -94,7 +94,7 @@ static inline bool ppc_inst_equal(struct ppc_inst x,
struct ppc_inst y)
 return ppc_inst_val(x) == ppc_inst_val(y);
 }

-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */

 static inline int ppc_inst_len(struct ppc_inst x)
 {
diff --git a/arch/powerpc/include/asm/uaccess.h
b/arch/powerpc/include/asm/uaccess.h
index e9027b3c641a..ac36a82321d4 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -105,7 +105,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 #define __put_user_inatomic(x, ptr) \
 __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 #define __get_user_instr(x, ptr)\
 ({\
 long __gui_ret = 0;\
@@ -113,7 +113,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 struct ppc_inst __gui_inst;\
 unsigned int prefix, suffix;\
 __gui_ret = __get_user(prefix, (unsigned int __user *)__gui_ptr);\
-if (!__gui_ret && (prefix >> 26) == OP_PREFIX) {\
+if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) {\
 __gui_ret = __get_user(suffix,\
(unsigned int __user *)__gui_ptr + 1);\
 __gui_inst = ppc_inst_prefix(prefix, suffix);\
@@ -131,7 +131,7 @@ static inline int __access_ok(unsigned long addr,
unsigned long size,
 struct ppc_inst __gui_inst;\
 unsigned int prefix, suffix;\
 __gui_ret = __get_user_inatomic(prefix, (unsigned int __user
*)__gui_ptr);\
-if (!__gui_ret && (prefix >> 26) == OP_PREFIX) {\
+if (!__gui_ret && (get_op(prefix)) == OP_PREFIX) {\
 __gui_ret = __get_user_inatomic(suffix,\
 (unsigned int __user *)__gui_ptr + 1);\
 __gui_inst = ppc_inst_prefix(prefix, suffix);\
diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
index a8e66603d12b..3ac105e7faae 100644
--- a/arch/powerpc/kernel/optprobes.c
+++ b/arch/powerpc/kernel/optprobes.c
@@ -283,10 +283,8 @@ int arch_prepare_optimized_kprobe(struct
optimized_kprobe *op, struct kprobe *p)
  * 3. load instruction to be emulated into relevant register, and
  */
 temp = ppc_inst_read((struct ppc_inst *)p->ainsn.insn);
-patch_imm64_load_insns(ppc_inst_val(temp) |
-   ((u64)ppc_inst_suffix(temp) << 32),
-   4,
-   buff + TMPL_INSN_IDX);
+patch_imm64_load_insns(ppc_inst_val(temp) |
((u64)ppc_inst_suffix(temp) << 32),
+   4, buff + TMPL_INSN_IDX);

 /*
  * 4. branch back from trampoline
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 58b67b62d5d3..bfd4e1dae0fb 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -26,8 +26,6 @@ static int __patch_instruction(struct ppc_inst
*exec_addr, struct ppc_inst instr

 if (!ppc_inst_prefixed(instr)) {
 __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
-if (err)
-return err;
 } else {
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 __put_user_asm((u64)ppc_inst_suffix(instr) << 32 |
@@ -36,12 +34,13 @@ static int __patch_instruction(struct ppc_inst
*exec_addr, struct ppc_inst instr
 __put_user_asm((u64)ppc_inst_val(instr) << 32 |
ppc_inst_suffix(instr), patch_addr, err, "std");
 #endif /* CONFIG_CPU_LITTLE_ENDIAN */
-if (err)
-return err;
 }
+if (err)
+return err;

 asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr),
 "r" (exec_addr));
+
 return 0;
 }

diff --git a/arch/powerpc/lib/inst.c b/arch/powerpc/lib/inst.c

Re: [PATCH v8 24/30] powerpc: Test prefixed code patching

2020-05-15 Thread Jordan Niethe
Hey mpe could you add this please.
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -707,7 +707,7 @@ static void __init test_translate_branch(void)
 vfree(buf);
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 static void __init test_prefixed_patching(void)
 {
 extern unsigned int code_patching_test1[];
@@ -733,7 +733,7 @@ static int __init test_code_patching(void)
 test_branch_bform();
 test_create_function_call();
 test_translate_branch();
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 test_prefixed_patching();
 #endif

-- 
2.17.1


Re: [PATCH v8 25/30] powerpc: Test prefixed instructions in feature fixups

2020-05-15 Thread Jordan Niethe
Hey mpe, could you add this thanks.
diff --git a/arch/powerpc/lib/feature-fixups.c
b/arch/powerpc/lib/feature-fixups.c
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -689,7 +689,7 @@ static void test_lwsync_macros(void)
 }
 }

-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 static void __init test_prefix_patching(void)
 {
 extern unsigned int ftr_fixup_prefix1[];
@@ -755,7 +755,7 @@ static void __init test_prefix_word_alt_patching(void)
 patch_feature_section(0, &fixup);
 check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) != 0);
 }
-#endif /* __powerpc64__ */
+#endif /* CONFIG_PPC64 */

 static int __init test_feature_fixups(void)
 {
@@ -771,7 +771,7 @@ static int __init test_feature_fixups(void)
 test_cpu_macros();
 test_fw_macros();
 test_lwsync_macros();
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 test_prefix_patching();
 test_prefix_alt_patching();
 test_prefix_word_alt_patching();
--


Re: [PATCH v8 29/30] powerpc sstep: Add support for prefixed load/stores

2020-05-15 Thread Jordan Niethe
mpe, and this thanks.

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1204,7 +1204,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
   struct ppc_inst instr)
 {
 unsigned int opcode, ra, rb, rc, rd, spr, u;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
 unsigned int suffixopcode, prefixtype, prefix_r;
 #endif
 unsigned long int imm;
@@ -2701,7 +2701,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
 op->reg = rd;
 op->val = regs->gpr[rd];

-suffixopcode = suffix >> 26;
+suffixopcode = get_op(suffix);
 prefixtype = (word >> 24) & 0x3;
 switch (prefixtype) {
 case 0: /* Type 00  Eight-Byte Load/Store */
-- 
2.17.1


Re: [PATCH v8 30/30] powerpc sstep: Add support for prefixed fixed-point arithmetic

2020-05-15 Thread Jordan Niethe
mpe, and this thanks.
---
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1343,7 +1343,7 @@ int analyse_instr(struct instruction_op *op,
const struct pt_regs *regs,
 rd = (suffix >> 21) & 0x1f;
 op->reg = rd;
 op->val = regs->gpr[rd];
-suffixopcode = suffix >> 26;
+suffixopcode = get_op(suffix);
 prefixtype = (word >> 24) & 0x3;
 switch (prefixtype) {
 case 2:
-- 
2.17.1


Re: [PATCH 2/3] ASoC: fsl_esai: Add support for imx8qm

2020-05-15 Thread Shengjiu Wang
On Tue, May 12, 2020 at 8:38 PM Mark Brown  wrote:
>
> On Tue, May 12, 2020 at 10:48:41AM +0800, Shengjiu Wang wrote:
> > On Wed, May 6, 2020 at 10:33 AM Shengjiu Wang  
> > wrote:
> > > On Fri, May 1, 2020 at 6:23 PM Mark Brown  wrote:
>
> > > > > EDMA requires the period size to be multiple of maxburst. Otherwise
> > > > > the remaining bytes are not transferred and thus noise is produced.
>
> > > > If this constraint comes from the DMA controller then normally you'd
> > > > expect the DMA controller integration to be enforcing this - is there no
> > > > information in the DMA API that lets us know that this constraint is
> > > > there?
>
> > > No, I can't find one API for this.
> > > Do you have a recommendation?
>
> > could you please recommend which DMA API can I use?
>
> Not off-hand, you'd probably need to extend the API to export the
> information.

Thanks.  I will think about if I can find a better solution.
And I will drop this change and send v2 of this patch-set.


[PATCH v2 1/2] ASoC: fsl_esai: introduce SoC specific data

2020-05-15 Thread Shengjiu Wang
Introduce a SoC specific data structure which contains the
differences between the different SoCs.
This makes it easier to support more differences without having
to introduce a new if/else each time.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_esai.c | 46 
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 84290be778f0..bac65ba7fbad 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -21,6 +21,17 @@
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
 
+/**
+ * fsl_esai_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @reset_at_xrun: flags for enable reset operaton
+ */
+struct fsl_esai_soc_data {
+   bool imx;
+   bool reset_at_xrun;
+};
+
 /**
  * fsl_esai: ESAI private data
  *
@@ -33,6 +44,7 @@
  * @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
+ * @soc: soc specific data
  * @lock: spin lock between hw_reset() and trigger()
  * @fifo_depth: depth of tx/rx FIFO
  * @slot_width: width of each DAI slot
@@ -44,7 +56,6 @@
  * @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 {
@@ -57,6 +68,7 @@ struct fsl_esai {
struct clk *fsysclk;
struct clk *spbaclk;
struct tasklet_struct task;
+   const struct fsl_esai_soc_data *soc;
spinlock_t lock; /* Protect hw_reset and trigger */
u32 fifo_depth;
u32 slot_width;
@@ -70,10 +82,24 @@ struct fsl_esai {
bool sck_div[2];
bool slave_mode;
bool synchronous;
-   bool reset_at_xrun;
char name[32];
 };
 
+static struct fsl_esai_soc_data fsl_esai_vf610 = {
+   .imx = false,
+   .reset_at_xrun = true,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx35 = {
+   .imx = true,
+   .reset_at_xrun = true,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx6ull = {
+   .imx = true,
+   .reset_at_xrun = false,
+};
+
 static irqreturn_t esai_isr(int irq, void *devid)
 {
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
@@ -85,7 +111,7 @@ static irqreturn_t esai_isr(int irq, void *devid)
regmap_read(esai_priv->regmap, REG_ESAI_SAISR, &saisr);
 
if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
-   esai_priv->reset_at_xrun) {
+   esai_priv->soc->reset_at_xrun) {
dev_dbg(&pdev->dev, "reset module for xrun\n");
regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
   ESAI_xCR_xEIE_MASK, 0);
@@ -936,9 +962,11 @@ 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;
+   esai_priv->soc = of_device_get_match_data(&pdev->dev);
+   if (!esai_priv->soc) {
+   dev_err(&pdev->dev, "failed to get soc data\n");
+   return -ENODEV;
+   }
 
/* Get the addresses and IRQ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1063,9 +1091,9 @@ static int fsl_esai_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id fsl_esai_dt_ids[] = {
-   { .compatible = "fsl,imx35-esai", },
-   { .compatible = "fsl,vf610-esai", },
-   { .compatible = "fsl,imx6ull-esai", },
+   { .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
+   { .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
+   { .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
-- 
2.21.0



[PATCH v2 0/2] ASoC: fsl_esai: Add support for imx8qm

2020-05-15 Thread Shengjiu Wang
Add support for imx8qm.

Shengjiu Wang (2):
  ASoC: fsl_esai: introduce SoC specific data
  ASoC: fsl_esai: Add new compatible string for imx8qm

Changes in v2
- drop the 0002 patch in v1, the dma relate limitation should
  be done in dma driver, or define a new DMA API for it.


 .../devicetree/bindings/sound/fsl,esai.txt|  1 +
 sound/soc/fsl/fsl_esai.c  | 46 +++
 2 files changed, 38 insertions(+), 9 deletions(-)

-- 
2.21.0



[PATCH v2 2/2] ASoC: fsl_esai: Add new compatible string for imx8qm

2020-05-15 Thread Shengjiu Wang
Add new compatible string "fsl,imx8qm-esai" in the binding document.

Signed-off-by: Shengjiu Wang 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/sound/fsl,esai.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt 
b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index 0e6e2166f76c..0a2480aeecf0 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -12,6 +12,7 @@ Required properties:
  "fsl,imx35-esai",
  "fsl,vf610-esai",
  "fsl,imx6ull-esai",
+ "fsl,imx8qm-esai",
 
   - reg: Offset and length of the register set for the 
device.
 
-- 
2.21.0



Re: [PATCH v2 0/2] ASoC: fsl_esai: Add support for imx8qm

2020-05-15 Thread Mark Brown
On Fri, 15 May 2020 18:10:49 +0800, Shengjiu Wang wrote:
> Add support for imx8qm.
> 
> Shengjiu Wang (2):
>   ASoC: fsl_esai: introduce SoC specific data
>   ASoC: fsl_esai: Add new compatible string for imx8qm
> 
> Changes in v2
> - drop the 0002 patch in v1, the dma relate limitation should
>   be done in dma driver, or define a new DMA API for it.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.8

Thanks!

[1/2] ASoC: fsl_esai: introduce SoC specific data
  commit: 6878e75204e1d0420fd8130bad33f88053ba44de
[2/2] ASoC: fsl_esai: Add new compatible string for imx8qm
  commit: d59628b310a77e616ce2e5857e6ede5bf96c6784

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


[PATCH 01/29] arm: fix the flush_icache_range arguments in set_fiq_handler

2020-05-15 Thread Christoph Hellwig
The arguments passed look bogus, try to fix them to something that seems
to make sense.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/kernel/fiq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index cd1234c103fcd..98ca3e3fa8471 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -98,8 +98,8 @@ void set_fiq_handler(void *start, unsigned int length)
 
memcpy(base + offset, start, length);
if (!cache_is_vipt_nonaliasing())
-   flush_icache_range((unsigned long)base + offset, offset +
-  length);
+   flush_icache_range((unsigned long)base + offset,
+  (unsigned long)base + offset + length);
flush_icache_range(0x + offset, 0x + offset + length);
 }
 
-- 
2.26.2



sort out the flush_icache_range mess v2

2020-05-15 Thread Christoph Hellwig
Hi all,

flush_icache_range is mostly used for kernel address, except for the following
cases:

 - the nommu brk and mmap implementations,
 - the read_code helper that is only used for binfmt_flat, binfmt_elf_fdpic,
   and binfmt_aout including the broken ia32 compat version
 - binfmt_flat itself,

none of which really are used by a typical MMU enabled kernel, as a.out can
only be build for alpha and m68k to start with.

But strangely enough commit ae92ef8a4424 ("PATCH] flush icache in correct
context") added a "set_fs(KERNEL_DS)" around the flush_icache_range call
in the module loader, because apparently m68k assumed user pointers.

This series first cleans up the cacheflush implementations, largely by
switching as much as possible to the asm-generic version after a few
preparations, then moves the misnamed current flush_icache_user_range to
a new name, to finally introduce a real flush_icache_user_range to be used
for the above use cases to flush the instruction cache for a userspace
address range.  The last patch then drops the set_fs in the module code
and moves it into the m68k implementation.

A git tree is available here:

git://git.infradead.org/users/hch/misc.git flush_icache_range.2

Gitweb:


http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/flush_icache_range.2

Changes since v1:
 - fix pmem.c compilation on some s390 configs
 - drop two patches picked up by the arch maintainers


[PATCH 02/29] nds32: unexport flush_icache_page

2020-05-15 Thread Christoph Hellwig
flush_icache_page is only used by mm/memory.c.

Signed-off-by: Christoph Hellwig 
---
 arch/nds32/mm/cacheflush.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c
index 254703653b6f5..8f168b33065fa 100644
--- a/arch/nds32/mm/cacheflush.c
+++ b/arch/nds32/mm/cacheflush.c
@@ -35,7 +35,6 @@ void flush_icache_page(struct vm_area_struct *vma, struct 
page *page)
kunmap_atomic((void *)kaddr);
local_irq_restore(flags);
 }
-EXPORT_SYMBOL(flush_icache_page);
 
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
 unsigned long addr, int len)
-- 
2.26.2



[PATCH 03/29] powerpc: unexport flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
flush_icache_user_range is only used by copy_to_user_page, which is
only used by core VM code.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/mm/mem.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 041ed7cfd341a..f0d1bf0a8e14f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -587,7 +587,6 @@ void flush_icache_user_range(struct vm_area_struct *vma, 
struct page *page,
flush_icache_range(maddr, maddr + len);
kunmap(page);
 }
-EXPORT_SYMBOL(flush_icache_user_range);
 
 /*
  * System memory should not be in /proc/iomem but various tools expect it
-- 
2.26.2



[PATCH 04/29] unicore32: remove flush_cache_user_range

2020-05-15 Thread Christoph Hellwig
flush_cache_user_range is an ARMism not used by any generic or unicore32
specific code.

Signed-off-by: Christoph Hellwig 
---
 arch/unicore32/include/asm/cacheflush.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/arch/unicore32/include/asm/cacheflush.h 
b/arch/unicore32/include/asm/cacheflush.h
index dc8c0b41538f8..9393ca4047e93 100644
--- a/arch/unicore32/include/asm/cacheflush.h
+++ b/arch/unicore32/include/asm/cacheflush.h
@@ -132,14 +132,6 @@ extern void flush_cache_page(struct vm_area_struct *vma,
 
 #define flush_cache_dup_mm(mm) flush_cache_mm(mm)
 
-/*
- * flush_cache_user_range is used when we want to ensure that the
- * Harvard caches are synchronised for the user space address range.
- * This is used for the UniCore private sys_cacheflush system call.
- */
-#define flush_cache_user_range(vma, start, end) \
-   __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
-
 /*
  * Perform necessary cache operations to ensure that data previously
  * stored within this range of addresses can be executed by the CPU.
-- 
2.26.2



[PATCH 05/29] asm-generic: fix the inclusion guards for cacheflush.h

2020-05-15 Thread Christoph Hellwig
cacheflush.h uses a somewhat to generic include guard name that clashes
with various arch files.  Use a more specific one.

Signed-off-by: Christoph Hellwig 
---
 include/asm-generic/cacheflush.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h
index cac7404b2bdd2..906277492ec59 100644
--- a/include/asm-generic/cacheflush.h
+++ b/include/asm-generic/cacheflush.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_CACHEFLUSH_H
-#define __ASM_CACHEFLUSH_H
+#ifndef _ASM_GENERIC_CACHEFLUSH_H
+#define _ASM_GENERIC_CACHEFLUSH_H
 
 /* Keep includes the same across arches.  */
 #include 
@@ -109,4 +109,4 @@ static inline void flush_cache_vunmap(unsigned long start, 
unsigned long end)
memcpy(dst, src, len)
 #endif
 
-#endif /* __ASM_CACHEFLUSH_H */
+#endif /* _ASM_GENERIC_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 06/29] asm-generic: don't include in cacheflush.h

2020-05-15 Thread Christoph Hellwig
This seems to lead to some crazy include loops when using
asm-generic/cacheflush.h on more architectures, so leave it
to the arch header for now.

Signed-off-by: Christoph Hellwig 
---
 arch/um/include/asm/tlb.h | 2 ++
 arch/x86/include/asm/cacheflush.h | 2 ++
 drivers/nvdimm/pmem.c | 3 ++-
 include/asm-generic/cacheflush.h  | 3 ---
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h
index 70ee603839006..ff9c62828962c 100644
--- a/arch/um/include/asm/tlb.h
+++ b/arch/um/include/asm/tlb.h
@@ -2,6 +2,8 @@
 #ifndef __UM_TLB_H
 #define __UM_TLB_H
 
+#include 
+
 #include 
 #include 
 #include 
diff --git a/arch/x86/include/asm/cacheflush.h 
b/arch/x86/include/asm/cacheflush.h
index 63feaf2a5f93d..b192d917a6d0b 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_CACHEFLUSH_H
 #define _ASM_X86_CACHEFLUSH_H
 
+#include 
+
 /* Caches aren't brain-dead on the intel. */
 #include 
 #include 
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 2df6994acf836..55282a6217407 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -7,7 +7,6 @@
  * Copyright (c) 2015, Boaz Harrosh .
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -25,6 +24,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "pmem.h"
 #include "pfn.h"
 #include "nd.h"
diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h
index 906277492ec59..bf9bb83e9fc8d 100644
--- a/include/asm-generic/cacheflush.h
+++ b/include/asm-generic/cacheflush.h
@@ -2,9 +2,6 @@
 #ifndef _ASM_GENERIC_CACHEFLUSH_H
 #define _ASM_GENERIC_CACHEFLUSH_H
 
-/* Keep includes the same across arches.  */
-#include 
-
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 
 /*
-- 
2.26.2



[PATCH 07/29] asm-generic: improve the flush_dcache_page stub

2020-05-15 Thread Christoph Hellwig
There is a magic ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE cpp symbol that
guards non-stub availability of flush_dcache_pagge.  Use that to
check if flush_dcache_pagg is implemented.

Signed-off-by: Christoph Hellwig 
---
 include/asm-generic/cacheflush.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h
index bf9bb83e9fc8d..4d4ef6516 100644
--- a/include/asm-generic/cacheflush.h
+++ b/include/asm-generic/cacheflush.h
@@ -2,8 +2,6 @@
 #ifndef _ASM_GENERIC_CACHEFLUSH_H
 #define _ASM_GENERIC_CACHEFLUSH_H
 
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-
 /*
  * The cache doesn't need to be flushed when TLB entries change when
  * the cache is mapped to physical memory, not virtual memory
@@ -42,12 +40,14 @@ static inline void flush_cache_page(struct vm_area_struct 
*vma,
 }
 #endif
 
-#ifndef flush_dcache_page
+#ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE
 static inline void flush_dcache_page(struct page *page)
 {
 }
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
 #endif
 
+
 #ifndef flush_dcache_mmap_lock
 static inline void flush_dcache_mmap_lock(struct address_space *mapping)
 {
-- 
2.26.2



[PATCH 08/29] alpha: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
Alpha needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/alpha/include/asm/cacheflush.h | 28 ++--
 1 file changed, 6 insertions(+), 22 deletions(-)

diff --git a/arch/alpha/include/asm/cacheflush.h 
b/arch/alpha/include/asm/cacheflush.h
index 89128489cb598..636d7ca0d05f6 100644
--- a/arch/alpha/include/asm/cacheflush.h
+++ b/arch/alpha/include/asm/cacheflush.h
@@ -4,19 +4,6 @@
 
 #include 
 
-/* Caches aren't brain-dead on the Alpha. */
-#define flush_cache_all()  do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)do { } while (0)
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
 /* Note that the following two definitions are _highly_ dependent
on the contexts in which they are used in the kernel.  I personally
think it is criminal how loosely defined these macros are.  */
@@ -59,20 +46,17 @@ flush_icache_user_range(struct vm_area_struct *vma, struct 
page *page,
mm->context[smp_processor_id()] = 0;
}
 }
-#else
+#define flush_icache_user_range flush_icache_user_range
+#else /* CONFIG_SMP */
 extern void flush_icache_user_range(struct vm_area_struct *vma,
struct page *page, unsigned long addr, int len);
-#endif
+#define flush_icache_user_range flush_icache_user_range
+#endif /* CONFIG_SMP */
 
 /* This is used only in __do_fault and do_swap_page.  */
 #define flush_icache_page(vma, page) \
-  flush_icache_user_range((vma), (page), 0, 0)
+   flush_icache_user_range((vma), (page), 0, 0)
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
- flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
+#include 
 
 #endif /* _ALPHA_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 10/29] c6x: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
C6x needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/c6x/include/asm/cacheflush.h | 19 +--
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/arch/c6x/include/asm/cacheflush.h 
b/arch/c6x/include/asm/cacheflush.h
index 4540b40475e6c..10922d528de6d 100644
--- a/arch/c6x/include/asm/cacheflush.h
+++ b/arch/c6x/include/asm/cacheflush.h
@@ -16,21 +16,6 @@
 #include 
 #include 
 
-/*
- * virtually-indexed cache management (our cache is physically indexed)
- */
-#define flush_cache_all()  do {} while (0)
-#define flush_cache_mm(mm) do {} while (0)
-#define flush_cache_dup_mm(mm) do {} while (0)
-#define flush_cache_range(mm, start, end)  do {} while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
-#define flush_cache_vmap(start, end)   do {} while (0)
-#define flush_cache_vunmap(start, end) do {} while (0)
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)do {} while (0)
-#define flush_dcache_mmap_lock(mapping)do {} while (0)
-#define flush_dcache_mmap_unlock(mapping)  do {} while (0)
-
 /*
  * physically-indexed cache management
  */
@@ -49,14 +34,12 @@ do {
  \
(unsigned long) page_address(page) + PAGE_SIZE)); \
 } while (0)
 
-
 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \
 do {\
memcpy(dst, src, len);   \
flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
 } while (0)
 
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
+#include 
 
 #endif /* _ASM_C6X_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 11/29] hexagon: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
Hexagon needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/hexagon/include/asm/cacheflush.h | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/arch/hexagon/include/asm/cacheflush.h 
b/arch/hexagon/include/asm/cacheflush.h
index fb447de45d54c..6eff0730e6efd 100644
--- a/arch/hexagon/include/asm/cacheflush.h
+++ b/arch/hexagon/include/asm/cacheflush.h
@@ -25,29 +25,17 @@
 #define LINESIZE   32
 #define LINEBITS   5
 
-#define flush_cache_all()  do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)do { } while (0)
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-#define flush_icache_page(vma, pg) do { } while (0)
-#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
 /*
  * Flush Dcache range through current map.
  */
 extern void flush_dcache_range(unsigned long start, unsigned long end);
+#define flush_dcache_range flush_dcache_range
 
 /*
  * Flush Icache range through current map.
  */
 extern void flush_icache_range(unsigned long start, unsigned long end);
+#define flush_icache_range flush_icache_range
 
 /*
  * Memory-management related flushes are there to ensure in non-physically
@@ -78,6 +66,7 @@ static inline void update_mmu_cache(struct vm_area_struct 
*vma,
 
 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
   unsigned long vaddr, void *dst, void *src, int len);
+#define copy_to_user_page copy_to_user_page
 
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
@@ -85,4 +74,6 @@ void copy_to_user_page(struct vm_area_struct *vma, struct 
page *page,
 extern void hexagon_inv_dcache_range(unsigned long start, unsigned long end);
 extern void hexagon_clean_dcache_range(unsigned long start, unsigned long end);
 
+#include 
+
 #endif
-- 
2.26.2



[PATCH 09/29] arm64: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
ARM64 needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/arm64/include/asm/cacheflush.h | 46 -
 1 file changed, 5 insertions(+), 41 deletions(-)

diff --git a/arch/arm64/include/asm/cacheflush.h 
b/arch/arm64/include/asm/cacheflush.h
index e6cca3d4acf70..03a5a187163ab 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -94,20 +94,7 @@ static inline void flush_icache_range(unsigned long start, 
unsigned long end)
 #endif
kick_all_cpus_sync();
 }
-
-static inline void flush_cache_mm(struct mm_struct *mm)
-{
-}
-
-static inline void flush_cache_page(struct vm_area_struct *vma,
-   unsigned long user_addr, unsigned long pfn)
-{
-}
-
-static inline void flush_cache_range(struct vm_area_struct *vma,
-unsigned long start, unsigned long end)
-{
-}
+#define flush_icache_range flush_icache_range
 
 /*
  * Cache maintenance functions used by the DMA API. No to be used directly.
@@ -123,12 +110,7 @@ extern void __dma_flush_area(const void *, size_t);
  */
 extern void copy_to_user_page(struct vm_area_struct *, struct page *,
unsigned long, void *, const void *, unsigned long);
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   do {\
-   memcpy(dst, src, len);  \
-   } while (0)
-
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+#define copy_to_user_page copy_to_user_page
 
 /*
  * flush_dcache_page is used when the kernel has written to the page
@@ -154,29 +136,11 @@ static __always_inline void __flush_icache_all(void)
dsb(ish);
 }
 
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-
-/*
- * We don't appear to need to do anything here.  In fact, if we did, we'd
- * duplicate cache flushing elsewhere performed by flush_dcache_page().
- */
-#define flush_icache_page(vma,page)do { } while (0)
-
-/*
- * Not required on AArch64 (PIPT or VIPT non-aliasing D-cache).
- */
-static inline void flush_cache_vmap(unsigned long start, unsigned long end)
-{
-}
-
-static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
-{
-}
-
 int set_memory_valid(unsigned long addr, int numpages, int enable);
 
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
 
-#endif
+#include 
+
+#endif /* __ASM_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 15/29] openrisc: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
OpenRISC needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/openrisc/include/asm/cacheflush.h | 31 +-
 1 file changed, 6 insertions(+), 25 deletions(-)

diff --git a/arch/openrisc/include/asm/cacheflush.h 
b/arch/openrisc/include/asm/cacheflush.h
index 79d5d7753fe4b..74d1fce4e8839 100644
--- a/arch/openrisc/include/asm/cacheflush.h
+++ b/arch/openrisc/include/asm/cacheflush.h
@@ -62,31 +62,12 @@ static inline void flush_dcache_page(struct page *page)
clear_bit(PG_dc_clean, &page->flags);
 }
 
-/*
- * Other interfaces are not required since we do not have virtually
- * indexed or tagged caches. So we can use the default here.
- */
-#define flush_cache_all()  do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-#define flush_icache_range(start, end) do { } while (0)
-#define flush_icache_page(vma, pg) do { } while (0)
-#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)   \
-   do { \
-   memcpy(dst, src, len);   \
-   if (vma->vm_flags & VM_EXEC) \
-   sync_icache_dcache(page);\
-   } while (0)
+#define flush_icache_user_range(vma, page, addr, len)  \
+do {   \
+   if (vma->vm_flags & VM_EXEC)\
+   sync_icache_dcache(page);   \
+} while (0)
 
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
+#include 
 
 #endif /* __ASM_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 13/29] microblaze: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
Microblaze needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/microblaze/include/asm/cacheflush.h | 29 ++--
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/arch/microblaze/include/asm/cacheflush.h 
b/arch/microblaze/include/asm/cacheflush.h
index 11f56c85056bb..39f8fb6768d8b 100644
--- a/arch/microblaze/include/asm/cacheflush.h
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -57,9 +57,6 @@ void microblaze_cache_init(void);
 #define invalidate_icache()mbc->iin();
 #define invalidate_icache_range(start, end)mbc->iinr(start, end);
 
-#define flush_icache_user_range(vma, pg, adr, len) flush_icache();
-#define flush_icache_page(vma, pg) do { } while (0)
-
 #define enable_dcache()mbc->de();
 #define disable_dcache()   mbc->dd();
 /* FIXME for LL-temac driver */
@@ -77,27 +74,9 @@ do { \
flush_dcache_range((unsigned) (addr), (unsigned) (addr) + PAGE_SIZE); \
 } while (0);
 
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-
 #define flush_cache_page(vma, vmaddr, pfn) \
flush_dcache_range(pfn << PAGE_SHIFT, (pfn << PAGE_SHIFT) + PAGE_SIZE);
 
-/* MS: kgdb code use this macro, wrong len with FLASH */
-#if 0
-#define flush_cache_range(vma, start, len) {   \
-   flush_icache_range((unsigned) (start), (unsigned) (start) + (len)); \
-   flush_dcache_range((unsigned) (start), (unsigned) (start) + (len)); \
-}
-#endif
-
-#define flush_cache_range(vma, start, len) do { } while (0)
-
 static inline void copy_to_user_page(struct vm_area_struct *vma,
 struct page *page, unsigned long vaddr,
 void *dst, void *src, int len)
@@ -109,12 +88,8 @@ static inline void copy_to_user_page(struct vm_area_struct 
*vma,
flush_dcache_range(addr, addr + PAGE_SIZE);
}
 }
+#define copy_to_user_page copy_to_user_page
 
-static inline void copy_from_user_page(struct vm_area_struct *vma,
-  struct page *page, unsigned long vaddr,
-  void *dst, void *src, int len)
-{
-   memcpy(dst, src, len);
-}
+#include 
 
 #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 12/29] ia64: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
IA64 needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
---
 arch/ia64/include/asm/cacheflush.h | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/arch/ia64/include/asm/cacheflush.h 
b/arch/ia64/include/asm/cacheflush.h
index 6d3478f8abc89..a8f1c86ac242a 100644
--- a/arch/ia64/include/asm/cacheflush.h
+++ b/arch/ia64/include/asm/cacheflush.h
@@ -12,44 +12,22 @@
 
 #include 
 
-/*
- * Cache flushing routines.  This is the kind of stuff that can be very 
expensive, so try
- * to avoid them whenever possible.
- */
-
-#define flush_cache_all()  do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_icache_page(vma,page)do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 #define flush_dcache_page(page)\
 do {   \
clear_bit(PG_arch_1, &(page)->flags);   \
 } while (0)
 
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
-
-extern void flush_icache_range (unsigned long start, unsigned long end);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+#define flush_icache_range flush_icache_range
 extern void clflush_cache_range(void *addr, int size);
 
-
 #define flush_icache_user_range(vma, page, user_addr, len) 
\
 do {   
\
unsigned long _addr = (unsigned long) page_address(page) + ((user_addr) 
& ~PAGE_MASK);  \
flush_icache_range(_addr, _addr + (len));   
\
 } while (0)
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-do { memcpy(dst, src, len); \
- flush_icache_user_range(vma, page, vaddr, len); \
-} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
+#include 
 
 #endif /* _ASM_IA64_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 14/29] m68knommu: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
m68knommu needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Signed-off-by: Christoph Hellwig 
Acked-by: Greg Ungerer 
---
 arch/m68k/include/asm/cacheflush_no.h | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/m68k/include/asm/cacheflush_no.h 
b/arch/m68k/include/asm/cacheflush_no.h
index 11e9a9dcbfb24..2731f07e7be8c 100644
--- a/arch/m68k/include/asm/cacheflush_no.h
+++ b/arch/m68k/include/asm/cacheflush_no.h
@@ -9,25 +9,8 @@
 #include 
 
 #define flush_cache_all()  __flush_cache_all()
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr)  do { } while (0)
 #define flush_dcache_range(start, len) __flush_dcache_all()
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)do { } while (0)
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
 #define flush_icache_range(start, len) __flush_icache_all()
-#define flush_icache_page(vma,pg)  do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)do { } while (0)
-#define flush_cache_vmap(start, end)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
 
 void mcf_cache_push(void);
 
@@ -98,4 +81,6 @@ static inline void cache_clear(unsigned long paddr, int len)
__clear_cache_all();
 }
 
+#include 
+
 #endif /* _M68KNOMMU_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 16/29] powerpc: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
Power needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Also remove the pointless __KERNEL__ ifdef while we're at it.

Signed-off-by: Christoph Hellwig 
---
 arch/powerpc/include/asm/cacheflush.h | 42 +++
 1 file changed, 10 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/include/asm/cacheflush.h 
b/arch/powerpc/include/asm/cacheflush.h
index e92191b390f31..e682c8e10e903 100644
--- a/arch/powerpc/include/asm/cacheflush.h
+++ b/arch/powerpc/include/asm/cacheflush.h
@@ -4,23 +4,9 @@
 #ifndef _ASM_POWERPC_CACHEFLUSH_H
 #define _ASM_POWERPC_CACHEFLUSH_H
 
-#ifdef __KERNEL__
-
 #include 
 #include 
 
-/*
- * No cache flushing is required when address mappings are changed,
- * because the caches on PowerPCs are physically addressed.
- */
-#define flush_cache_all()  do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_icache_page(vma, page)   do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
 #ifdef CONFIG_PPC_BOOK3S_64
 /*
  * Book3s has no ptesync after setting a pte, so without this ptesync it's
@@ -33,20 +19,20 @@ static inline void flush_cache_vmap(unsigned long start, 
unsigned long end)
 {
asm volatile("ptesync" ::: "memory");
 }
-#else
-static inline void flush_cache_vmap(unsigned long start, unsigned long end) { }
-#endif
+#define flush_cache_vmap flush_cache_vmap
+#endif /* CONFIG_PPC_BOOK3S_64 */
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
-#define flush_dcache_mmap_lock(mapping)do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)  do { } while (0)
 
 void flush_icache_range(unsigned long start, unsigned long stop);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
-   struct page *page, unsigned long addr,
-   int len);
-extern void flush_dcache_icache_page(struct page *page);
+#define flush_icache_range flush_icache_range
+
+void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+   unsigned long addr, int len);
+#define flush_icache_user_range flush_icache_user_range
+
+void flush_dcache_icache_page(struct page *page);
 void __flush_dcache_icache(void *page);
 
 /**
@@ -111,14 +97,6 @@ static inline void invalidate_dcache_range(unsigned long 
start,
mb();   /* sync */
 }
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-   do { \
-   memcpy(dst, src, len); \
-   flush_icache_user_range(vma, page, vaddr, len); \
-   } while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
-
-#endif /* __KERNEL__ */
+#include 
 
 #endif /* _ASM_POWERPC_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 17/29] riscv: use asm-generic/cacheflush.h

2020-05-15 Thread Christoph Hellwig
RISC-V needs almost no cache flushing routines of its own.  Rely on
asm-generic/cacheflush.h for the defaults.

Also remove the pointless __KERNEL__ ifdef while we're at it.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
---
 arch/riscv/include/asm/cacheflush.h | 62 ++---
 1 file changed, 3 insertions(+), 59 deletions(-)

diff --git a/arch/riscv/include/asm/cacheflush.h 
b/arch/riscv/include/asm/cacheflush.h
index c8677c75f82cb..a167b4fbdf007 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -8,65 +8,6 @@
 
 #include 
 
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-
-/*
- * The cache doesn't need to be flushed when TLB entries change when
- * the cache is mapped to physical memory, not virtual memory
- */
-static inline void flush_cache_all(void)
-{
-}
-
-static inline void flush_cache_mm(struct mm_struct *mm)
-{
-}
-
-static inline void flush_cache_dup_mm(struct mm_struct *mm)
-{
-}
-
-static inline void flush_cache_range(struct vm_area_struct *vma,
-unsigned long start,
-unsigned long end)
-{
-}
-
-static inline void flush_cache_page(struct vm_area_struct *vma,
-   unsigned long vmaddr,
-   unsigned long pfn)
-{
-}
-
-static inline void flush_dcache_mmap_lock(struct address_space *mapping)
-{
-}
-
-static inline void flush_dcache_mmap_unlock(struct address_space *mapping)
-{
-}
-
-static inline void flush_icache_page(struct vm_area_struct *vma,
-struct page *page)
-{
-}
-
-static inline void flush_cache_vmap(unsigned long start, unsigned long end)
-{
-}
-
-static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
-{
-}
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-   do { \
-   memcpy(dst, src, len); \
-   flush_icache_user_range(vma, page, vaddr, len); \
-   } while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-   memcpy(dst, src, len)
-
 static inline void local_flush_icache_all(void)
 {
asm volatile ("fence.i" ::: "memory");
@@ -79,6 +20,7 @@ static inline void flush_dcache_page(struct page *page)
if (test_bit(PG_dcache_clean, &page->flags))
clear_bit(PG_dcache_clean, &page->flags);
 }
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 
 /*
  * RISC-V doesn't have an instruction to flush parts of the instruction cache,
@@ -105,4 +47,6 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
 #define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL
 #define SYS_RISCV_FLUSH_ICACHE_ALL   (SYS_RISCV_FLUSH_ICACHE_LOCAL)
 
+#include 
+
 #endif /* _ASM_RISCV_CACHEFLUSH_H */
-- 
2.26.2



[PATCH 18/29] arm,sparc,unicore32: remove flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
flush_icache_user_range is only used by , so
remove it from the architectures that implement it, but don't use
.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/include/asm/cacheflush.h   | 3 ---
 arch/sparc/include/asm/cacheflush_32.h  | 2 --
 arch/sparc/include/asm/cacheflush_64.h  | 1 -
 arch/unicore32/include/asm/cacheflush.h | 3 ---
 4 files changed, 9 deletions(-)

diff --git a/arch/arm/include/asm/cacheflush.h 
b/arch/arm/include/asm/cacheflush.h
index 7114b9aa46b87..c78e14fcfb5df 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -318,9 +318,6 @@ extern void flush_kernel_dcache_page(struct page *);
 #define flush_dcache_mmap_lock(mapping)
xa_lock_irq(&mapping->i_pages)
 #define flush_dcache_mmap_unlock(mapping)  xa_unlock_irq(&mapping->i_pages)
 
-#define flush_icache_user_range(vma,page,addr,len) \
-   flush_dcache_page(page)
-
 /*
  * We don't appear to need to do anything here.  In fact, if we did, we'd
  * duplicate cache flushing elsewhere performed by flush_dcache_page().
diff --git a/arch/sparc/include/asm/cacheflush_32.h 
b/arch/sparc/include/asm/cacheflush_32.h
index fb66094a2c30c..41c6d734a4741 100644
--- a/arch/sparc/include/asm/cacheflush_32.h
+++ b/arch/sparc/include/asm/cacheflush_32.h
@@ -17,8 +17,6 @@
 #define flush_icache_range(start, end) do { } while (0)
 #define flush_icache_page(vma, pg) do { } while (0)
 
-#define flush_icache_user_range(vma,pg,adr,len)do { } while (0)
-
 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do {\
flush_cache_page(vma, vaddr, page_to_pfn(page));\
diff --git a/arch/sparc/include/asm/cacheflush_64.h 
b/arch/sparc/include/asm/cacheflush_64.h
index e7517434d1fa6..b9341836597ec 100644
--- a/arch/sparc/include/asm/cacheflush_64.h
+++ b/arch/sparc/include/asm/cacheflush_64.h
@@ -49,7 +49,6 @@ void __flush_dcache_range(unsigned long start, unsigned long 
end);
 void flush_dcache_page(struct page *page);
 
 #define flush_icache_page(vma, pg) do { } while(0)
-#define flush_icache_user_range(vma,pg,adr,len)do { } while (0)
 
 void flush_ptrace_access(struct vm_area_struct *, struct page *,
 unsigned long uaddr, void *kaddr,
diff --git a/arch/unicore32/include/asm/cacheflush.h 
b/arch/unicore32/include/asm/cacheflush.h
index 9393ca4047e93..ff0be92ebc320 100644
--- a/arch/unicore32/include/asm/cacheflush.h
+++ b/arch/unicore32/include/asm/cacheflush.h
@@ -162,9 +162,6 @@ extern void flush_dcache_page(struct page *);
 #define flush_dcache_mmap_lock(mapping)do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)  do { } while (0)
 
-#define flush_icache_user_range(vma, page, addr, len)  \
-   flush_dcache_page(page)
-
 /*
  * We don't appear to need to do anything here.  In fact, if we did, we'd
  * duplicate cache flushing elsewhere performed by flush_dcache_page().
-- 
2.26.2



[PATCH 20/29] asm-generic: add a flush_icache_user_range stub

2020-05-15 Thread Christoph Hellwig
Define flush_icache_user_range to flush_icache_range unless the
architecture provides its own implementation.

Signed-off-by: Christoph Hellwig 
---
 include/asm-generic/cacheflush.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h
index 2c9686fefb715..907fa5d164944 100644
--- a/include/asm-generic/cacheflush.h
+++ b/include/asm-generic/cacheflush.h
@@ -66,6 +66,10 @@ static inline void flush_icache_range(unsigned long start, 
unsigned long end)
 }
 #endif
 
+#ifndef flush_icache_user_range
+#define flush_icache_user_range flush_icache_range
+#endif
+
 #ifndef flush_icache_page
 static inline void flush_icache_page(struct vm_area_struct *vma,
 struct page *page)
-- 
2.26.2



[PATCH 19/29] mm: rename flush_icache_user_range to flush_icache_user_page

2020-05-15 Thread Christoph Hellwig
The function currently known as flush_icache_user_range only operates
on a single page.  Rename it to flush_icache_user_page as we'll need
the name flush_icache_user_range for something else soon.

Signed-off-by: Christoph Hellwig 
Acked-by: Geert Uytterhoeven 
---
 arch/alpha/include/asm/cacheflush.h| 10 +-
 arch/alpha/kernel/smp.c|  2 +-
 arch/ia64/include/asm/cacheflush.h |  2 +-
 arch/m68k/include/asm/cacheflush_mm.h  |  4 ++--
 arch/m68k/mm/cache.c   |  2 +-
 arch/nds32/include/asm/cacheflush.h|  4 ++--
 arch/nds32/mm/cacheflush.c |  2 +-
 arch/openrisc/include/asm/cacheflush.h |  2 +-
 arch/powerpc/include/asm/cacheflush.h  |  4 ++--
 arch/powerpc/mm/mem.c  |  2 +-
 arch/riscv/include/asm/cacheflush.h|  3 ++-
 include/asm-generic/cacheflush.h   |  6 +++---
 kernel/events/uprobes.c|  2 +-
 13 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/arch/alpha/include/asm/cacheflush.h 
b/arch/alpha/include/asm/cacheflush.h
index 636d7ca0d05f6..9945ff483eaf7 100644
--- a/arch/alpha/include/asm/cacheflush.h
+++ b/arch/alpha/include/asm/cacheflush.h
@@ -35,7 +35,7 @@ extern void smp_imb(void);
 
 extern void __load_new_mm_context(struct mm_struct *);
 static inline void
-flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long addr, int len)
 {
if (vma->vm_flags & VM_EXEC) {
@@ -46,16 +46,16 @@ flush_icache_user_range(struct vm_area_struct *vma, struct 
page *page,
mm->context[smp_processor_id()] = 0;
}
 }
-#define flush_icache_user_range flush_icache_user_range
+#define flush_icache_user_page flush_icache_user_page
 #else /* CONFIG_SMP */
-extern void flush_icache_user_range(struct vm_area_struct *vma,
+extern void flush_icache_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long addr, int len);
-#define flush_icache_user_range flush_icache_user_range
+#define flush_icache_user_page flush_icache_user_page
 #endif /* CONFIG_SMP */
 
 /* This is used only in __do_fault and do_swap_page.  */
 #define flush_icache_page(vma, page) \
-   flush_icache_user_range((vma), (page), 0, 0)
+   flush_icache_user_page((vma), (page), 0, 0)
 
 #include 
 
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 5f90df30be20a..52995bf413fea 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -740,7 +740,7 @@ ipi_flush_icache_page(void *x)
 }
 
 void
-flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long addr, int len)
 {
struct mm_struct *mm = vma->vm_mm;
diff --git a/arch/ia64/include/asm/cacheflush.h 
b/arch/ia64/include/asm/cacheflush.h
index a8f1c86ac242a..708c0fa5d975e 100644
--- a/arch/ia64/include/asm/cacheflush.h
+++ b/arch/ia64/include/asm/cacheflush.h
@@ -22,7 +22,7 @@ extern void flush_icache_range(unsigned long start, unsigned 
long end);
 #define flush_icache_range flush_icache_range
 extern void clflush_cache_range(void *addr, int size);
 
-#define flush_icache_user_range(vma, page, user_addr, len) 
\
+#define flush_icache_user_page(vma, page, user_addr, len)  
\
 do {   
\
unsigned long _addr = (unsigned long) page_address(page) + ((user_addr) 
& ~PAGE_MASK);  \
flush_icache_range(_addr, _addr + (len));   
\
diff --git a/arch/m68k/include/asm/cacheflush_mm.h 
b/arch/m68k/include/asm/cacheflush_mm.h
index 1e2544ecaf88c..95376bf84faa5 100644
--- a/arch/m68k/include/asm/cacheflush_mm.h
+++ b/arch/m68k/include/asm/cacheflush_mm.h
@@ -254,7 +254,7 @@ static inline void __flush_page_to_ram(void *vaddr)
 #define flush_dcache_mmap_unlock(mapping)  do { } while (0)
 #define flush_icache_page(vma, page)   __flush_page_to_ram(page_address(page))
 
-extern void flush_icache_user_range(struct vm_area_struct *vma, struct page 
*page,
+extern void flush_icache_user_page(struct vm_area_struct *vma, struct page 
*page,
unsigned long addr, int len);
 extern void flush_icache_range(unsigned long address, unsigned long endaddr);
 
@@ -264,7 +264,7 @@ static inline void copy_to_user_page(struct vm_area_struct 
*vma,
 {
flush_cache_page(vma, vaddr, page_to_pfn(page));
memcpy(dst, src, len);
-   flush_icache_user_range(vma, page, vaddr, len);
+   flush_icache_user_page(vma, page, vaddr, len);
 }
 static inline void copy_from_user_page(struct vm_area_struct *vma,
   struct page *page, unsigned long vaddr,
diff --git a/arch/m68k/mm/cache.c b/arch/m6

[PATCH 21/29] sh: implement flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
The SuperH implementation of flush_icache_range seems to be able to
cope with user addresses.  Just define flush_icache_user_range to
flush_icache_range.

Signed-off-by: Christoph Hellwig 
---
 arch/sh/include/asm/cacheflush.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index b932e42ef0284..fe7400079b97b 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -46,6 +46,7 @@ extern void flush_cache_range(struct vm_area_struct *vma,
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 extern void flush_dcache_page(struct page *page);
 extern void flush_icache_range(unsigned long start, unsigned long end);
+#define flush_icache_user_range flush_icache_range
 extern void flush_icache_page(struct vm_area_struct *vma,
 struct page *page);
 extern void flush_cache_sigtramp(unsigned long address);
-- 
2.26.2



[PATCH 22/29] xtensa: implement flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
The Xtensa implementation of flush_icache_range seems to be able to
cope with user addresses.  Just define flush_icache_user_range to
flush_icache_range.

Signed-off-by: Christoph Hellwig 
---
 arch/xtensa/include/asm/cacheflush.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/xtensa/include/asm/cacheflush.h 
b/arch/xtensa/include/asm/cacheflush.h
index a0d50be5a8cb1..460e666ad0761 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -107,6 +107,8 @@ void flush_cache_page(struct vm_area_struct*,
 #define flush_cache_page  local_flush_cache_page
 #endif
 
+#define flush_icache_user_range flush_icache_range
+
 #define local_flush_cache_all()
\
do {\
__flush_invalidate_dcache_all();\
-- 
2.26.2



[PATCH 23/29] arm: rename flush_cache_user_range to flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
flush_icache_user_range will be the name for a generic primitive.
Move the arm name so that arm already has an implementation.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/include/asm/cacheflush.h | 4 ++--
 arch/arm/kernel/traps.c   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/cacheflush.h 
b/arch/arm/include/asm/cacheflush.h
index c78e14fcfb5df..2e24e765e6d3a 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -258,11 +258,11 @@ extern void flush_cache_page(struct vm_area_struct *vma, 
unsigned long user_addr
 #define flush_cache_dup_mm(mm) flush_cache_mm(mm)
 
 /*
- * flush_cache_user_range is used when we want to ensure that the
+ * flush_icache_user_range is used when we want to ensure that the
  * Harvard caches are synchronised for the user space address range.
  * This is used for the ARM private sys_cacheflush system call.
  */
-#define flush_cache_user_range(s,e)__cpuc_coherent_user_range(s,e)
+#define flush_icache_user_range(s,e)   __cpuc_coherent_user_range(s,e)
 
 /*
  * Perform necessary cache operations to ensure that data previously
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1e70e7227f0ff..316a7687f8133 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -566,7 +566,7 @@ __do_cache_op(unsigned long start, unsigned long end)
if (fatal_signal_pending(current))
return 0;
 
-   ret = flush_cache_user_range(start, start + chunk);
+   ret = flush_icache_user_range(start, start + chunk);
if (ret)
return ret;
 
-- 
2.26.2



[PATCH 25/29] exec: only build read_code when needed

2020-05-15 Thread Christoph Hellwig
Only build read_code when binary formats that use it are built into the
kernel.

Signed-off-by: Christoph Hellwig 
---
 fs/exec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 06b4c550af5d9..a4f766f296f8f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1027,6 +1027,8 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t 
*size, loff_t max_size,
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
 
+#if defined(CONFIG_HAVE_AOUT) || defined(CONFIG_BINFMT_FLAT) || \
+defined(CONFIG_BINFMT_ELF_FDPIC)
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t 
len)
 {
ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
@@ -1035,6 +1037,7 @@ ssize_t read_code(struct file *file, unsigned long addr, 
loff_t pos, size_t len)
return res;
 }
 EXPORT_SYMBOL(read_code);
+#endif
 
 /*
  * Maps the mm_struct mm into the current task struct.
-- 
2.26.2



[PATCH 24/29] m68k: implement flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
Rename the current flush_icache_range to flush_icache_user_range as
per commit ae92ef8a4424 ("PATCH] flush icache in correct context") there
seems to be an assumption that it operates on user addresses.  Add a
flush_icache_range around it that for now is a no-op.

Signed-off-by: Christoph Hellwig 
Acked-by: Geert Uytterhoeven 
---
 arch/m68k/include/asm/cacheflush_mm.h | 2 ++
 arch/m68k/mm/cache.c  | 7 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/include/asm/cacheflush_mm.h 
b/arch/m68k/include/asm/cacheflush_mm.h
index 95376bf84faa5..1ac55e7b47f01 100644
--- a/arch/m68k/include/asm/cacheflush_mm.h
+++ b/arch/m68k/include/asm/cacheflush_mm.h
@@ -257,6 +257,8 @@ static inline void __flush_page_to_ram(void *vaddr)
 extern void flush_icache_user_page(struct vm_area_struct *vma, struct page 
*page,
unsigned long addr, int len);
 extern void flush_icache_range(unsigned long address, unsigned long endaddr);
+extern void flush_icache_user_range(unsigned long address,
+   unsigned long endaddr);
 
 static inline void copy_to_user_page(struct vm_area_struct *vma,
 struct page *page, unsigned long vaddr,
diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c
index 99057cd5ff7f1..7915be3a09712 100644
--- a/arch/m68k/mm/cache.c
+++ b/arch/m68k/mm/cache.c
@@ -73,7 +73,7 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr)
 
 /* Push n pages at kernel virtual address and clear the icache */
 /* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
-void flush_icache_range(unsigned long address, unsigned long endaddr)
+void flush_icache_user_range(unsigned long address, unsigned long endaddr)
 {
if (CPU_IS_COLDFIRE) {
unsigned long start, end;
@@ -104,6 +104,11 @@ void flush_icache_range(unsigned long address, unsigned 
long endaddr)
  : "di" (FLUSH_I));
}
 }
+
+void flush_icache_range(unsigned long address, unsigned long endaddr)
+{
+   flush_icache_user_range(address, endaddr);
+}
 EXPORT_SYMBOL(flush_icache_range);
 
 void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
-- 
2.26.2



[PATCH 26/29] exec: use flush_icache_user_range in read_code

2020-05-15 Thread Christoph Hellwig
read_code operates on user addresses.

Signed-off-by: Christoph Hellwig 
---
 fs/exec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/exec.c b/fs/exec.c
index a4f766f296f8f..c541867316a63 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1033,7 +1033,7 @@ ssize_t read_code(struct file *file, unsigned long addr, 
loff_t pos, size_t len)
 {
ssize_t res = vfs_read(file, (void __user *)addr, len, &pos);
if (res > 0)
-   flush_icache_range(addr, addr + len);
+   flush_icache_user_range(addr, addr + len);
return res;
 }
 EXPORT_SYMBOL(read_code);
-- 
2.26.2



[PATCH 29/29] module: move the set_fs hack for flush_icache_range to m68k

2020-05-15 Thread Christoph Hellwig
flush_icache_range generally operates on kernel addresses, but for some
reason m68k needed a set_fs override.  Move that into the m68k code
insted of keeping it in the module loader.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Geert Uytterhoeven 
Acked-by: Geert Uytterhoeven 
---
 arch/m68k/mm/cache.c | 4 
 kernel/module.c  | 8 
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c
index 7915be3a09712..5ecb3310e8745 100644
--- a/arch/m68k/mm/cache.c
+++ b/arch/m68k/mm/cache.c
@@ -107,7 +107,11 @@ void flush_icache_user_range(unsigned long address, 
unsigned long endaddr)
 
 void flush_icache_range(unsigned long address, unsigned long endaddr)
 {
+   mm_segment_t old_fs = get_fs();
+
+   set_fs(KERNEL_DS);
flush_icache_user_range(address, endaddr);
+   set_fs(old_fs);
 }
 EXPORT_SYMBOL(flush_icache_range);
 
diff --git a/kernel/module.c b/kernel/module.c
index 646f1e2330d2b..b1673ed49594f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3312,12 +3312,6 @@ static int check_module_license_and_versions(struct 
module *mod)
 
 static void flush_module_icache(const struct module *mod)
 {
-   mm_segment_t old_fs;
-
-   /* flush the icache in correct context */
-   old_fs = get_fs();
-   set_fs(KERNEL_DS);
-
/*
 * Flush the instruction cache, since we've played with text.
 * Do it before processing of module parameters, so the module
@@ -3329,8 +3323,6 @@ static void flush_module_icache(const struct module *mod)
   + mod->init_layout.size);
flush_icache_range((unsigned long)mod->core_layout.base,
   (unsigned long)mod->core_layout.base + 
mod->core_layout.size);
-
-   set_fs(old_fs);
 }
 
 int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
-- 
2.26.2



[PATCH 28/29] nommu: use flush_icache_user_range in brk and mmap

2020-05-15 Thread Christoph Hellwig
These obviously operate on user addresses.

Signed-off-by: Christoph Hellwig 
---
 mm/nommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/nommu.c b/mm/nommu.c
index 318df4e236c99..aed7acaed2383 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -443,7 +443,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
/*
 * Ok, looks good - let it rip.
 */
-   flush_icache_range(mm->brk, brk);
+   flush_icache_user_range(mm->brk, brk);
return mm->brk = brk;
 }
 
@@ -1287,7 +1287,7 @@ unsigned long do_mmap(struct file *file,
/* we flush the region from the icache only when the first executable
 * mapping of it is made  */
if (vma->vm_flags & VM_EXEC && !region->vm_icache_flushed) {
-   flush_icache_range(region->vm_start, region->vm_end);
+   flush_icache_user_range(region->vm_start, region->vm_end);
region->vm_icache_flushed = true;
}
 
-- 
2.26.2



[PATCH 27/29] binfmt_flat: use flush_icache_user_range

2020-05-15 Thread Christoph Hellwig
load_flat_file works on user addresses.

Signed-off-by: Christoph Hellwig 
Acked-by: Greg Ungerer 
---
 fs/binfmt_flat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 831a2b25ba79f..6f0aca5379da2 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -854,7 +854,7 @@ static int load_flat_file(struct linux_binprm *bprm,
 #endif /* CONFIG_BINFMT_FLAT_OLD */
}
 
-   flush_icache_range(start_code, end_code);
+   flush_icache_user_range(start_code, end_code);
 
/* zero the BSS,  BRK and stack areas */
if (clear_user((void __user *)(datapos + data_len), bss_len +
-- 
2.26.2



Re: [PATCH v4 03/14] arm64: add support for folded p4d page tables

2020-05-15 Thread Andrew Morton
On Tue, 14 Apr 2020 18:34:44 +0300 Mike Rapoport  wrote:

> Implement primitives necessary for the 4th level folding, add walks of p4d
> level where appropriate, replace 5level-fixup.h with pgtable-nop4d.h and
> remove __ARCH_USE_5LEVEL_HACK.

This needed some rework due to arm changes in linux-next.  Please check
my handiwork and test it once I've merged this into linux-next?

Rejects were

--- 
arch/arm64/include/asm/pgtable.h~arm64-add-support-for-folded-p4d-page-tables
+++ arch/arm64/include/asm/pgtable.h
@@ -596,49 +604,50 @@ static inline phys_addr_t pud_page_paddr
 
 #define pud_ERROR(pud) __pud_error(__FILE__, __LINE__, pud_val(pud))
 
-#define pgd_none(pgd)  (!pgd_val(pgd))
-#define pgd_bad(pgd)   (!(pgd_val(pgd) & 2))
-#define pgd_present(pgd)   (pgd_val(pgd))
+#define p4d_none(p4d)  (!p4d_val(p4d))
+#define p4d_bad(p4d)   (!(p4d_val(p4d) & 2))
+#define p4d_present(p4d)   (p4d_val(p4d))
 
-static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
+static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 {
-   if (in_swapper_pgdir(pgdp)) {
-   set_swapper_pgd(pgdp, pgd);
+   if (in_swapper_pgdir(p4dp)) {
+   set_swapper_pgd((pgd_t *)p4dp, __pgd(p4d_val(p4d)));
return;
}
 
-   WRITE_ONCE(*pgdp, pgd);
+   WRITE_ONCE(*p4dp, p4d);
dsb(ishst);
isb();
 }
 
-static inline void pgd_clear(pgd_t *pgdp)
+static inline void p4d_clear(p4d_t *p4dp)
 {
-   set_pgd(pgdp, __pgd(0));
+   set_p4d(p4dp, __p4d(0));
 }
 
-static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
+static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
 {
-   return __pgd_to_phys(pgd);
+   return __p4d_to_phys(p4d);
 }
 
 /* Find an entry in the frst-level page table. */
 #define pud_index(addr)(((addr) >> PUD_SHIFT) & (PTRS_PER_PUD 
- 1))
 
-#define pud_offset_phys(dir, addr) (pgd_page_paddr(READ_ONCE(*(dir))) + 
pud_index(addr) * sizeof(pud_t))
+#define pud_offset_phys(dir, addr) (p4d_page_paddr(READ_ONCE(*(dir))) + 
pud_index(addr) * sizeof(pud_t))
 #define pud_offset(dir, addr)  ((pud_t *)__va(pud_offset_phys((dir), 
(addr
 
 #define pud_set_fixmap(addr)   ((pud_t *)set_fixmap_offset(FIX_PUD, 
addr))
-#define pud_set_fixmap_offset(pgd, addr)   
pud_set_fixmap(pud_offset_phys(pgd, addr))
+#define pud_set_fixmap_offset(p4d, addr)   
pud_set_fixmap(pud_offset_phys(p4d, addr))
 #define pud_clear_fixmap() clear_fixmap(FIX_PUD)
 
-#define pgd_page(pgd)  pfn_to_page(__phys_to_pfn(__pgd_to_phys(pgd)))
+#define p4d_page(p4d)  pfn_to_page(__phys_to_pfn(__p4d_to_phys(p4d)))
 
 /* use ONLY for statically allocated translation tables */
 #define pud_offset_kimg(dir,addr)  ((pud_t 
*)__phys_to_kimg(pud_offset_phys((dir), (addr
 
 #else
 
+#define p4d_page_paddr(p4d)({ BUILD_BUG(); 0;})
 #define pgd_page_paddr(pgd)({ BUILD_BUG(); 0;})
 
 /* Match pud_offset folding in  */



and

--- arch/arm64/kvm/mmu.c~arm64-add-support-for-folded-p4d-page-tables
+++ arch/arm64/kvm/mmu.c
@@ -469,7 +517,7 @@ static void stage2_flush_memslot(struct
do {
next = stage2_pgd_addr_end(kvm, addr, end);
if (!stage2_pgd_none(kvm, *pgd))
-   stage2_flush_puds(kvm, pgd, addr, next);
+   stage2_flush_p4ds(kvm, pgd, addr, next);
} while (pgd++, addr = next, addr != end);
 }
 


Result:

From: Mike Rapoport 
Subject: arm64: add support for folded p4d page tables

Implement primitives necessary for the 4th level folding, add walks of p4d
level where appropriate, replace 5level-fixup.h with pgtable-nop4d.h and
remove __ARCH_USE_5LEVEL_HACK.

Link: http://lkml.kernel.org/r/20200414153455.21744-4-r...@kernel.org
Signed-off-by: Mike Rapoport 
Cc: Arnd Bergmann 
Cc: Benjamin Herrenschmidt 
Cc: Brian Cain 
Cc: Catalin Marinas 
Cc: Christophe Leroy 
Cc: Fenghua Yu 
Cc: Geert Uytterhoeven 
Cc: Guan Xuetao 
Cc: James Morse 
Cc: Jonas Bonn 
Cc: Julien Thierry 
Cc: Ley Foon Tan 
Cc: Marc Zyngier 
Cc: Michael Ellerman 
Cc: Paul Mackerras 
Cc: Rich Felker 
Cc: Russell King 
Cc: Stafford Horne 
Cc: Stefan Kristiansson 
Cc: Suzuki K Poulose 
Cc: Tony Luck 
Cc: Will Deacon 
Cc: Yoshinori Sato 
Signed-off-by: Andrew Morton 
---

 arch/arm64/include/asm/kvm_mmu.h|   10 -
 arch/arm64/include/asm/pgalloc.h|   10 -
 arch/arm64/include/asm/pgtable-types.h  |5 
 arch/arm64/include/asm/pgtable.h|   37 ++-
 arch/arm64/include/asm/stage2_pgtable.h |   48 +++--
 arch/arm64/kernel/hibernate.c   |   44 +++-
 arch/arm64/kvm/mmu.c|  209 ++
 arch/arm64/mm/fault.c   |9 
 arch/arm64/mm/hugetlbpage.c |   15 +
 arch/arm64/mm/kasan_init.c  |   26 ++
 arch/arm64/mm/mmu.c |   52 +++--
 arch/arm64/mm/pageattr.c|7 
 12 files changed, 368 insertions(+), 104 dele

[PATCH v4 3/6] printk: Introduce kmsg_dump_reason_str()

2020-05-15 Thread Kees Cook
The pstore subsystem already had a private version of this function.
With the coming addition of the pstore/zone driver, this needs to be
shared. As it really should live with printk, move it there instead.

Link: https://lore.kernel.org/lkml/20200510202436.63222-8-keesc...@chromium.org/
Acked-by: Petr Mladek 
Acked-by: Sergey Senozhatsky 
Signed-off-by: Kees Cook 
---
 fs/pstore/platform.c  | 18 +-
 include/linux/kmsg_dump.h |  7 +++
 kernel/printk/printk.c| 17 +
 3 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 90d74ebaa70a..5e6c6022deb9 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -135,22 +135,6 @@ enum pstore_type_id pstore_name_to_type(const char *name)
 }
 EXPORT_SYMBOL_GPL(pstore_name_to_type);
 
-static const char *get_reason_str(enum kmsg_dump_reason reason)
-{
-   switch (reason) {
-   case KMSG_DUMP_PANIC:
-   return "Panic";
-   case KMSG_DUMP_OOPS:
-   return "Oops";
-   case KMSG_DUMP_EMERG:
-   return "Emergency";
-   case KMSG_DUMP_SHUTDOWN:
-   return "Shutdown";
-   default:
-   return "Unknown";
-   }
-}
-
 static void pstore_timer_kick(void)
 {
if (pstore_update_ms < 0)
@@ -403,7 +387,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
unsigned intpart = 1;
int ret;
 
-   why = get_reason_str(reason);
+   why = kmsg_dump_reason_str(reason);
 
if (down_trylock(&psinfo->buf_lock)) {
/* Failed to acquire lock: give up if we cannot wait. */
diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index 9826014771ab..3378bcbe585e 100644
--- a/include/linux/kmsg_dump.h
+++ b/include/linux/kmsg_dump.h
@@ -70,6 +70,8 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper);
 int kmsg_dump_register(struct kmsg_dumper *dumper);
 
 int kmsg_dump_unregister(struct kmsg_dumper *dumper);
+
+const char *kmsg_dump_reason_str(enum kmsg_dump_reason reason);
 #else
 static inline void kmsg_dump(enum kmsg_dump_reason reason)
 {
@@ -111,6 +113,11 @@ static inline int kmsg_dump_unregister(struct kmsg_dumper 
*dumper)
 {
return -EINVAL;
 }
+
+static inline const char *kmsg_dump_reason_str(enum kmsg_dump_reason reason)
+{
+   return "Disabled";
+}
 #endif
 
 #endif /* _LINUX_KMSG_DUMP_H */
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index a121c2255737..14ca4d05d902 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3144,6 +3144,23 @@ EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
 static bool always_kmsg_dump;
 module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | 
S_IWUSR);
 
+const char *kmsg_dump_reason_str(enum kmsg_dump_reason reason)
+{
+   switch (reason) {
+   case KMSG_DUMP_PANIC:
+   return "Panic";
+   case KMSG_DUMP_OOPS:
+   return "Oops";
+   case KMSG_DUMP_EMERG:
+   return "Emergency";
+   case KMSG_DUMP_SHUTDOWN:
+   return "Shutdown";
+   default:
+   return "Unknown";
+   }
+}
+EXPORT_SYMBOL_GPL(kmsg_dump_reason_str);
+
 /**
  * kmsg_dump - dump kernel log to kernel message dumpers.
  * @reason: the reason (oops, panic etc) for dumping
-- 
2.20.1



[PATCH v4 5/6] pstore/ram: Introduce max_reason and convert dump_oops

2020-05-15 Thread Kees Cook
Now that pstore_register() can correctly pass max_reason to the kmesg
dump facility, introduce a new "max_reason" module parameter and
"max-reason" Device Tree field.

The "dump_oops" module parameter and "dump-oops" Device
Tree field are now considered deprecated, but are now automatically
converted to their corresponding max_reason values when present, though
the new max_reason setting has precedence.

For struct ramoops_platform_data, the "dump_oops" member is entirely
replaced by a new "max_reason" member, with the only existing user
updated in place.

Additionally remove the "reason" filter logic from ramoops_pstore_write(),
as that is not specifically needed anymore, though technically
this is a change in behavior for any ramoops users also setting the
printk.always_kmsg_dump boot param, which will cause ramoops to behave as
if max_reason was set to KMSG_DUMP_MAX.

Co-developed-by: Pavel Tatashin 
Signed-off-by: Pavel Tatashin 
Link: https://lore.kernel.org/lkml/20200506211523.15077-5-keesc...@chromium.org/
Signed-off-by: Kees Cook 
---
 Documentation/admin-guide/ramoops.rst | 14 --
 drivers/platform/chrome/chromeos_pstore.c |  2 +-
 fs/pstore/ram.c   | 58 +++
 include/linux/pstore_ram.h|  2 +-
 4 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/Documentation/admin-guide/ramoops.rst 
b/Documentation/admin-guide/ramoops.rst
index 6dbcc5481000..a60a96218ba9 100644
--- a/Documentation/admin-guide/ramoops.rst
+++ b/Documentation/admin-guide/ramoops.rst
@@ -32,11 +32,17 @@ memory to be mapped strongly ordered, and atomic operations 
on strongly ordered
 memory are implementation defined, and won't work on many ARMs such as omaps.
 
 The memory area is divided into ``record_size`` chunks (also rounded down to
-power of two) and each oops/panic writes a ``record_size`` chunk of
+power of two) and each kmesg dump writes a ``record_size`` chunk of
 information.
 
-Dumping both oopses and panics can be done by setting 1 in the ``dump_oops``
-variable while setting 0 in that variable dumps only the panics.
+Limiting which kinds of kmsg dumps are stored can be controlled via
+the ``max_reason`` value, as defined in include/linux/kmsg_dump.h's
+``enum kmsg_dump_reason``. For example, to store both Oopses and Panics,
+``max_reason`` should be set to 2 (KMSG_DUMP_OOPS), to store only Panics
+``max_reason`` should be set to 1 (KMSG_DUMP_PANIC). Setting this to 0
+(KMSG_DUMP_UNDEF), means the reason filtering will be controlled by the
+``printk.always_kmsg_dump`` boot param: if unset, it'll be KMSG_DUMP_OOPS,
+otherwise KMSG_DUMP_MAX.
 
 The module uses a counter to record multiple dumps but the counter gets reset
 on restart (i.e. new dumps after the restart will overwrite old ones).
@@ -90,7 +96,7 @@ Setting the ramoops parameters can be done in several 
different manners:
 .mem_address= <...>,
 .mem_type   = <...>,
 .record_size= <...>,
-.dump_oops  = <...>,
+.max_reason = <...>,
 .ecc= <...>,
   };
 
diff --git a/drivers/platform/chrome/chromeos_pstore.c 
b/drivers/platform/chrome/chromeos_pstore.c
index d13770785fb5..fa51153688b4 100644
--- a/drivers/platform/chrome/chromeos_pstore.c
+++ b/drivers/platform/chrome/chromeos_pstore.c
@@ -57,7 +57,7 @@ static struct ramoops_platform_data chromeos_ramoops_data = {
.record_size= 0x4,
.console_size   = 0x2,
.ftrace_size= 0x2,
-   .dump_oops  = 1,
+   .max_reason = KMSG_DUMP_OOPS,
 };
 
 static struct platform_device chromeos_ramoops = {
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 31f277633beb..f6eace1dbf7e 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -58,10 +58,10 @@ module_param(mem_type, uint, 0400);
 MODULE_PARM_DESC(mem_type,
"set to 1 to try to use unbuffered memory (default 0)");
 
-static int dump_oops = 1;
-module_param(dump_oops, int, 0400);
-MODULE_PARM_DESC(dump_oops,
-   "set to 1 to dump oopses, 0 to only dump panics (default 1)");
+static int ramoops_max_reason = -1;
+module_param_named(max_reason, ramoops_max_reason, int, 0400);
+MODULE_PARM_DESC(max_reason,
+"maximum reason for kmsg dump (default 2: Oops and Panic) ");
 
 static int ramoops_ecc;
 module_param_named(ecc, ramoops_ecc, int, 0400);
@@ -70,6 +70,11 @@ MODULE_PARM_DESC(ramoops_ecc,
"ECC buffer size in bytes (1 is a special value, means 16 "
"bytes ECC)");
 
+static int ramoops_dump_oops = -1;
+module_param_named(dump_oops, ramoops_dump_oops, int, 0400);
+MODULE_PARM_DESC(dump_oops,
+"(deprecated: use max_reason instead) set to 1 to dump oopses 
& panics, 0 to only dump panics");
+
 struct ramoops_context {
struct persistent_ram_zone **dprzs; /* Oops dump zones */
struct persistent_ram_zone *cprz;

[PATCH v4 4/6] pstore/platform: Pass max_reason to kmesg dump

2020-05-15 Thread Kees Cook
From: Pavel Tatashin 

Add a new member to struct pstore_info for passing information about
kmesg dump maximum reason. This allows a finer control of what kmesg
dumps are sent to pstore storage backends.

Those backends that do not explicitly set this field (keeping it equal to
0), get the default behavior: store only Oopses and Panics, or everything
if the printk.always_kmsg_dump boot param is set.

Signed-off-by: Pavel Tatashin 
Link: https://lore.kernel.org/lkml/20200506211523.15077-3-keesc...@chromium.org/
Co-developed-by: Kees Cook 
Signed-off-by: Kees Cook 
---
 fs/pstore/platform.c   | 4 +++-
 include/linux/pstore.h | 7 +++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 5e6c6022deb9..a9e297eefdff 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -595,8 +595,10 @@ int pstore_register(struct pstore_info *psi)
 
pstore_get_records(0);
 
-   if (psi->flags & PSTORE_FLAGS_DMESG)
+   if (psi->flags & PSTORE_FLAGS_DMESG) {
+   pstore_dumper.max_reason = psinfo->max_reason;
pstore_register_kmsg();
+   }
if (psi->flags & PSTORE_FLAGS_CONSOLE)
pstore_register_console();
if (psi->flags & PSTORE_FLAGS_FTRACE)
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index f6f22b13e04f..eb93a54cff31 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -96,6 +96,12 @@ struct pstore_record {
  *
  * @read_mutex:serializes @open, @read, @close, and @erase callbacks
  * @flags: bitfield of frontends the backend can accept writes for
+ * @max_reason:Used when PSTORE_FLAGS_DMESG is set. Contains the
+ * kmsg_dump_reason enum value. KMSG_DUMP_UNDEF means
+ * "use existing kmsg_dump() filtering, based on the
+ * printk.always_kmsg_dump boot param" (which is either
+ * KMSG_DUMP_OOPS when false, or KMSG_DUMP_MAX when
+ * true); see printk.always_kmsg_dump for more details.
  * @data:  backend-private pointer passed back during callbacks
  *
  * Callbacks:
@@ -179,6 +185,7 @@ struct pstore_info {
struct mutexread_mutex;
 
int flags;
+   int max_reason;
void*data;
 
int (*open)(struct pstore_info *psi);
-- 
2.20.1



[PATCH v4 1/6] printk: Collapse shutdown types into a single dump reason

2020-05-15 Thread Kees Cook
To turn the KMSG_DUMP_* reasons into a more ordered list, collapse
the redundant KMSG_DUMP_(RESTART|HALT|POWEROFF) reasons into
KMSG_DUMP_SHUTDOWN. The current users already don't meaningfully
distinguish between them, so there's no need to, as discussed here:
https://lore.kernel.org/lkml/ca+ck2bapv5u1ih5y9t5funtyximtfctdyxjcpuyjoyhnokr...@mail.gmail.com/

Signed-off-by: Kees Cook 
---
 arch/powerpc/kernel/nvram_64.c | 4 +---
 fs/pstore/platform.c   | 8 ++--
 include/linux/kmsg_dump.h  | 4 +---
 kernel/reboot.c| 6 +++---
 4 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index fb4f61096613..0cd1c88bfc8b 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -655,9 +655,7 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
int rc = -1;
 
switch (reason) {
-   case KMSG_DUMP_RESTART:
-   case KMSG_DUMP_HALT:
-   case KMSG_DUMP_POWEROFF:
+   case KMSG_DUMP_SHUTDOWN:
/* These are almost always orderly shutdowns. */
return;
case KMSG_DUMP_OOPS:
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 072440457c08..90d74ebaa70a 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -144,12 +144,8 @@ static const char *get_reason_str(enum kmsg_dump_reason 
reason)
return "Oops";
case KMSG_DUMP_EMERG:
return "Emergency";
-   case KMSG_DUMP_RESTART:
-   return "Restart";
-   case KMSG_DUMP_HALT:
-   return "Halt";
-   case KMSG_DUMP_POWEROFF:
-   return "Poweroff";
+   case KMSG_DUMP_SHUTDOWN:
+   return "Shutdown";
default:
return "Unknown";
}
diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index 2e7a1e032c71..3f82b5cb2d82 100644
--- a/include/linux/kmsg_dump.h
+++ b/include/linux/kmsg_dump.h
@@ -25,9 +25,7 @@ enum kmsg_dump_reason {
KMSG_DUMP_PANIC,
KMSG_DUMP_OOPS,
KMSG_DUMP_EMERG,
-   KMSG_DUMP_RESTART,
-   KMSG_DUMP_HALT,
-   KMSG_DUMP_POWEROFF,
+   KMSG_DUMP_SHUTDOWN,
 };
 
 /**
diff --git a/kernel/reboot.c b/kernel/reboot.c
index c4d472b7f1b4..491f1347bf43 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -250,7 +250,7 @@ void kernel_restart(char *cmd)
pr_emerg("Restarting system\n");
else
pr_emerg("Restarting system with command '%s'\n", cmd);
-   kmsg_dump(KMSG_DUMP_RESTART);
+   kmsg_dump(KMSG_DUMP_SHUTDOWN);
machine_restart(cmd);
 }
 EXPORT_SYMBOL_GPL(kernel_restart);
@@ -274,7 +274,7 @@ void kernel_halt(void)
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emerg("System halted\n");
-   kmsg_dump(KMSG_DUMP_HALT);
+   kmsg_dump(KMSG_DUMP_SHUTDOWN);
machine_halt();
 }
 EXPORT_SYMBOL_GPL(kernel_halt);
@@ -292,7 +292,7 @@ void kernel_power_off(void)
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emerg("Power down\n");
-   kmsg_dump(KMSG_DUMP_POWEROFF);
+   kmsg_dump(KMSG_DUMP_SHUTDOWN);
machine_power_off();
 }
 EXPORT_SYMBOL_GPL(kernel_power_off);
-- 
2.20.1



[PATCH v4 2/6] printk: honor the max_reason field in kmsg_dumper

2020-05-15 Thread Kees Cook
From: Pavel Tatashin 

kmsg_dump() allows to dump kmesg buffer for various system events: oops,
panic, reboot, etc. It provides an interface to register a callback call
for clients, and in that callback interface there is a field "max_reason"
which gets ignored unless always_kmsg_dump is passed as kernel parameter.

Allow clients to decide max_reason, and keep the current behavior when
max_reason is not set.

Signed-off-by: Pavel Tatashin 
Link: https://lore.kernel.org/lkml/20200506211523.15077-2-keesc...@chromium.org/
Signed-off-by: Kees Cook 
---
 include/linux/kmsg_dump.h |  1 +
 kernel/printk/printk.c| 15 +++
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index 3f82b5cb2d82..9826014771ab 100644
--- a/include/linux/kmsg_dump.h
+++ b/include/linux/kmsg_dump.h
@@ -26,6 +26,7 @@ enum kmsg_dump_reason {
KMSG_DUMP_OOPS,
KMSG_DUMP_EMERG,
KMSG_DUMP_SHUTDOWN,
+   KMSG_DUMP_MAX
 };
 
 /**
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9a9b6156270b..a121c2255737 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3157,12 +3157,19 @@ void kmsg_dump(enum kmsg_dump_reason reason)
struct kmsg_dumper *dumper;
unsigned long flags;
 
-   if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
-   return;
-
rcu_read_lock();
list_for_each_entry_rcu(dumper, &dump_list, list) {
-   if (dumper->max_reason && reason > dumper->max_reason)
+   enum kmsg_dump_reason max_reason = dumper->max_reason;
+
+   /*
+* If client has not provided a specific max_reason, default
+* to KMSG_DUMP_OOPS, unless always_kmsg_dump was set.
+*/
+   if (max_reason == KMSG_DUMP_UNDEF) {
+   max_reason = always_kmsg_dump ? KMSG_DUMP_MAX :
+   KMSG_DUMP_OOPS;
+   }
+   if (reason > max_reason)
continue;
 
/* initialize iterator with data about the stored records */
-- 
2.20.1



[PATCH v4 0/6] allow ramoops to collect all kmesg_dump events

2020-05-15 Thread Kees Cook
Hello!

I wanted to get the pstore tree nailed down, so here's the v4 of
Pavel's series, tweaked for the feedback during v3 review.

-Kees

v4:
- rebase on pstore tree
- collapse shutdown types into a single dump reason
  
https://lore.kernel.org/lkml/ca+ck2bapv5u1ih5y9t5funtyximtfctdyxjcpuyjoyhnokr...@mail.gmail.com/
- fix dump_oops vs max_reason module params
  https://lore.kernel.org/lkml/20200512233504.GA118720@sequoia/
- typos
  
https://lore.kernel.org/lkml/4cdeaa2af2fe0d6cc2ca8ce3a37608340799df8a.ca...@perches.com/
- rename DT parsing routines ..._size -> ..._u32
  
https://lore.kernel.org/lkml/ca+ck2bcu8efomiu+nebjvn-o2dbuecxwrfssnjb3ys3cacb...@mail.gmail.com/
v3: https://lore.kernel.org/lkml/20200506211523.15077-1-keesc...@chromium.org/
v2: 
https://lore.kernel.org/lkml/20200505154510.93506-1-pasha.tatas...@soleen.com
v1: 
https://lore.kernel.org/lkml/20200502143555.543636-1-pasha.tatas...@soleen.com

Kees Cook (3):
  printk: Collapse shutdown types into a single dump reason
  printk: Introduce kmsg_dump_reason_str()
  pstore/ram: Introduce max_reason and convert dump_oops

Pavel Tatashin (3):
  printk: honor the max_reason field in kmsg_dumper
  pstore/platform: Pass max_reason to kmesg dump
  ramoops: Add max_reason optional field to ramoops DT node

 Documentation/admin-guide/ramoops.rst | 14 +++--
 .../bindings/reserved-memory/ramoops.txt  | 13 -
 arch/powerpc/kernel/nvram_64.c|  4 +-
 drivers/platform/chrome/chromeos_pstore.c |  2 +-
 fs/pstore/platform.c  | 26 ++---
 fs/pstore/ram.c   | 58 +--
 include/linux/kmsg_dump.h | 12 +++-
 include/linux/pstore.h|  7 +++
 include/linux/pstore_ram.h|  2 +-
 kernel/printk/printk.c| 32 --
 kernel/reboot.c   |  6 +-
 11 files changed, 114 insertions(+), 62 deletions(-)

-- 
2.20.1



[PATCH v4 6/6] ramoops: Add max_reason optional field to ramoops DT node

2020-05-15 Thread Kees Cook
From: Pavel Tatashin 

Currently, it is possible to dump kmsges for panic, or oops.
With max_reason it is possible to dump messages for other
kmesg_dump events, for example reboot, halt, shutdown, kexec.

Signed-off-by: Pavel Tatashin 
Link: https://lore.kernel.org/lkml/20200506211523.15077-6-keesc...@chromium.org/
Signed-off-by: Kees Cook 
---
 .../devicetree/bindings/reserved-memory/ramoops.txt | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt 
b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
index 0eba562fe5c6..b7886fea368c 100644
--- a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
+++ b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
@@ -30,7 +30,7 @@ Optional properties:
 - ecc-size: enables ECC support and specifies ECC buffer size in bytes
   (defaults to 0: no ECC)
 
-- record-size: maximum size in bytes of each dump done on oops/panic
+- record-size: maximum size in bytes of each kmsg dump.
   (defaults to 0: disabled)
 
 - console-size: size in bytes of log buffer reserved for kernel messages
@@ -45,7 +45,16 @@ Optional properties:
 - unbuffered: if present, use unbuffered mappings to map the reserved region
   (defaults to buffered mappings)
 
-- no-dump-oops: if present, only dump panics (defaults to panics and oops)
+- max-reason: if present, sets maximum type of kmsg dump reasons to store
+  (defaults to 2: log Oopses and Panics). This can be set to INT_MAX to
+  store all kmsg dumps. See include/linux/kmsg_dump.h KMSG_DUMP_* for other
+  kmsg dump reason values. Setting this to 0 (KMSG_DUMP_UNDEF), means the
+  reason filtering will be controlled by the printk.always_kmsg_dump boot
+  param: if unset, it will be KMSG_DUMP_OOPS, otherwise KMSG_DUMP_MAX.
+
+- no-dump-oops: deprecated, use max_reason instead. If present, and
+  max_reason is not specified, it is equivalent to max_reason = 1
+  (KMSG_DUMP_PANIC).
 
 - flags: if present, pass ramoops behavioral flags (defaults to 0,
   see include/linux/pstore_ram.h RAMOOPS_FLAG_* for flag values).
-- 
2.20.1



Re: [PATCH v4 0/6] allow ramoops to collect all kmesg_dump events

2020-05-15 Thread Pavel Tatashin
On Fri, May 15, 2020 at 2:44 PM Kees Cook  wrote:
>
> Hello!
>
> I wanted to get the pstore tree nailed down, so here's the v4 of
> Pavel's series, tweaked for the feedback during v3 review.

Hi Kees,

Thank you, I was planning to send a new version of this series later
today. Let me quickly review it.

Pasha

>
> -Kees
>
> v4:
> - rebase on pstore tree
> - collapse shutdown types into a single dump reason
>   
> https://lore.kernel.org/lkml/ca+ck2bapv5u1ih5y9t5funtyximtfctdyxjcpuyjoyhnokr...@mail.gmail.com/
> - fix dump_oops vs max_reason module params
>   https://lore.kernel.org/lkml/20200512233504.GA118720@sequoia/
> - typos
>   
> https://lore.kernel.org/lkml/4cdeaa2af2fe0d6cc2ca8ce3a37608340799df8a.ca...@perches.com/
> - rename DT parsing routines ..._size -> ..._u32
>   
> https://lore.kernel.org/lkml/ca+ck2bcu8efomiu+nebjvn-o2dbuecxwrfssnjb3ys3cacb...@mail.gmail.com/
> v3: https://lore.kernel.org/lkml/20200506211523.15077-1-keesc...@chromium.org/
> v2: 
> https://lore.kernel.org/lkml/20200505154510.93506-1-pasha.tatas...@soleen.com
> v1: 
> https://lore.kernel.org/lkml/20200502143555.543636-1-pasha.tatas...@soleen.com
>
> Kees Cook (3):
>   printk: Collapse shutdown types into a single dump reason
>   printk: Introduce kmsg_dump_reason_str()
>   pstore/ram: Introduce max_reason and convert dump_oops
>
> Pavel Tatashin (3):
>   printk: honor the max_reason field in kmsg_dumper
>   pstore/platform: Pass max_reason to kmesg dump
>   ramoops: Add max_reason optional field to ramoops DT node
>
>  Documentation/admin-guide/ramoops.rst | 14 +++--
>  .../bindings/reserved-memory/ramoops.txt  | 13 -
>  arch/powerpc/kernel/nvram_64.c|  4 +-
>  drivers/platform/chrome/chromeos_pstore.c |  2 +-
>  fs/pstore/platform.c  | 26 ++---
>  fs/pstore/ram.c   | 58 +--
>  include/linux/kmsg_dump.h | 12 +++-
>  include/linux/pstore.h|  7 +++
>  include/linux/pstore_ram.h|  2 +-
>  kernel/printk/printk.c| 32 --
>  kernel/reboot.c   |  6 +-
>  11 files changed, 114 insertions(+), 62 deletions(-)
>
> --
> 2.20.1
>


Re: [PATCH v4 1/6] printk: Collapse shutdown types into a single dump reason

2020-05-15 Thread Pavel Tatashin
On Fri, May 15, 2020 at 2:44 PM Kees Cook  wrote:
>
> To turn the KMSG_DUMP_* reasons into a more ordered list, collapse
> the redundant KMSG_DUMP_(RESTART|HALT|POWEROFF) reasons into
> KMSG_DUMP_SHUTDOWN. The current users already don't meaningfully
> distinguish between them, so there's no need to, as discussed here:
> https://lore.kernel.org/lkml/ca+ck2bapv5u1ih5y9t5funtyximtfctdyxjcpuyjoyhnokr...@mail.gmail.com/
>
> Signed-off-by: Kees Cook 

Maybe it makes sense to mention in the commit log that for all three
merged cases there is a pr_emerg() message logged right before the
kmsg_dump(), thus the reason is distinguishable from the dmesg log
itself.

Reviewed-by: Pavel Tatashin 


Re: [PATCH] tty: hvc: Fix data abort due to race in hvc_open

2020-05-15 Thread rananta

On 2020-05-15 00:30, Greg KH wrote:

On Thu, May 14, 2020 at 04:22:10PM -0700, rana...@codeaurora.org wrote:

On 2020-05-13 00:04, Greg KH wrote:
> On Tue, May 12, 2020 at 02:39:50PM -0700, rana...@codeaurora.org wrote:
> > On 2020-05-12 01:25, Greg KH wrote:
> > > On Tue, May 12, 2020 at 09:22:15AM +0200, Jiri Slaby wrote:
> > > > On 11. 05. 20, 9:39, Greg KH wrote:
> > > > > On Mon, May 11, 2020 at 12:23:58AM -0700, rana...@codeaurora.org 
wrote:
> > > > >> On 2020-05-09 23:48, Greg KH wrote:
> > > > >>> On Sat, May 09, 2020 at 06:30:56PM -0700, rana...@codeaurora.org 
wrote:
> > > >  On 2020-05-06 02:48, Greg KH wrote:
> > > > > On Mon, Apr 27, 2020 at 08:26:01PM -0700, Raghavendra Rao Ananta 
wrote:
> > > > >> Potentially, hvc_open() can be called in parallel when two tasks 
calls
> > > > >> open() on /dev/hvcX. In such a scenario, if the
> > > > >> hp->ops->notifier_add()
> > > > >> callback in the function fails, where it sets the 
tty->driver_data to
> > > > >> NULL, the parallel hvc_open() can see this NULL and cause a 
memory
> > > > >> abort.
> > > > >> Hence, serialize hvc_open and check if tty->private_data is NULL
> > > > >> before
> > > > >> proceeding ahead.
> > > > >>
> > > > >> The issue can be easily reproduced by launching two tasks
> > > > >> simultaneously
> > > > >> that does nothing but open() and close() on /dev/hvcX.
> > > > >> For example:
> > > > >> $ ./simple_open_close /dev/hvc0 & ./simple_open_close /dev/hvc0 &
> > > > >>
> > > > >> Signed-off-by: Raghavendra Rao Ananta 
> > > > >> ---
> > > > >>  drivers/tty/hvc/hvc_console.c | 16 ++--
> > > > >>  1 file changed, 14 insertions(+), 2 deletions(-)
> > > > >>
> > > > >> diff --git a/drivers/tty/hvc/hvc_console.c
> > > > >> b/drivers/tty/hvc/hvc_console.c
> > > > >> index 436cc51c92c3..ebe26fe5ac09 100644
> > > > >> --- a/drivers/tty/hvc/hvc_console.c
> > > > >> +++ b/drivers/tty/hvc/hvc_console.c
> > > > >> @@ -75,6 +75,8 @@ static LIST_HEAD(hvc_structs);
> > > > >>   */
> > > > >>  static DEFINE_MUTEX(hvc_structs_mutex);
> > > > >>
> > > > >> +/* Mutex to serialize hvc_open */
> > > > >> +static DEFINE_MUTEX(hvc_open_mutex);
> > > > >>  /*
> > > > >>   * This value is used to assign a tty->index value to a 
hvc_struct
> > > > >> based
> > > > >>   * upon order of exposure via hvc_probe(), when we can not 
match it
> > > > >> to
> > > > >> @@ -346,16 +348,24 @@ static int hvc_install(struct tty_driver
> > > > >> *driver, struct tty_struct *tty)
> > > > >>   */
> > > > >>  static int hvc_open(struct tty_struct *tty, struct file * filp)
> > > > >>  {
> > > > >> -  struct hvc_struct *hp = tty->driver_data;
> > > > >> +  struct hvc_struct *hp;
> > > > >>unsigned long flags;
> > > > >>int rc = 0;
> > > > >>
> > > > >> +  mutex_lock(&hvc_open_mutex);
> > > > >> +
> > > > >> +  hp = tty->driver_data;
> > > > >> +  if (!hp) {
> > > > >> +  rc = -EIO;
> > > > >> +  goto out;
> > > > >> +  }
> > > > >> +
> > > > >>spin_lock_irqsave(&hp->port.lock, flags);
> > > > >>/* Check and then increment for fast path open. */
> > > > >>if (hp->port.count++ > 0) {
> > > > >>spin_unlock_irqrestore(&hp->port.lock, flags);
> > > > >>hvc_kick();
> > > > >> -  return 0;
> > > > >> +  goto out;
> > > > >>} /* else count == 0 */
> > > > >>spin_unlock_irqrestore(&hp->port.lock, flags);
> > > > >
> > > > > Wait, why isn't this driver just calling tty_port_open() instead 
of
> > > > > trying to open-code all of this?
> > > > >
> > > > > Keeping a single mutext for open will not protect it from close, 
it will
> > > > > just slow things down a bit.  There should already be a tty lock 
held by
> > > > > the tty core for open() to keep it from racing things, right?
> > > >  The tty lock should have been held, but not likely across
> > > >  ->install() and
> > > >  ->open() callbacks, thus resulting in a race between hvc_install() 
and
> > > >  hvc_open(),
> > > > >>>
> > > > >>> How?  The tty lock is held in install, and should not conflict with
> > > > >>> open(), otherwise, we would be seeing this happen in all tty 
drivers,
> > > > >>> right?
> > > > >>>
> > > > >> Well, I was expecting the same, but IIRC, I see that the open() was 
being
> > > > >> called in parallel for the same device node.
> > > > >
> > > > > So open and install are happening at the same time?  And the 
tty_lock()
> > > > > does not protect the needed fields from being protected properly?  If
> > > > > not, what fields are being touched without the lock?
> > > > >
> > > > >> Is it expected that the tty core would allow only one thread to
> > > > >> access the dev-node, while blocking the othe

Re: [PATCH v4 3/6] printk: Introduce kmsg_dump_reason_str()

2020-05-15 Thread Pavel Tatashin
On Fri, May 15, 2020 at 2:44 PM Kees Cook  wrote:
>
> The pstore subsystem already had a private version of this function.
> With the coming addition of the pstore/zone driver, this needs to be
> shared. As it really should live with printk, move it there instead.
>
> Link: 
> https://lore.kernel.org/lkml/20200510202436.63222-8-keesc...@chromium.org/
> Acked-by: Petr Mladek 
> Acked-by: Sergey Senozhatsky 
> Signed-off-by: Kees Cook 

Reviewed-by: Pavel Tatashin 


Re: [PATCH v4 5/6] pstore/ram: Introduce max_reason and convert dump_oops

2020-05-15 Thread Pavel Tatashin
>  #define parse_u32(name, field, default_value) {  
>   \
> ret = ramoops_parse_dt_u32(pdev, name, default_value,   \

The series seems to be missing the patch where ramoops_parse_dt_size
-> ramoops_parse_dt_u32 get renamed, and updated to handle default
value.


Re: [PATCH v4 5/6] pstore/ram: Introduce max_reason and convert dump_oops

2020-05-15 Thread Pavel Tatashin
 pdata.dump_oops = dump_oops;
> +   /* If "max_reason" is set, its value has priority over "dump_oops". */
> +   if (ramoops_max_reason != -1)
> +   pdata.max_reason = ramoops_max_reason;

 (ramoops_max_reason >= 0) might make more sense here, we do not want
negative max_reason even if it was provided by the user.

Otherwise the series looks good.

Thank you,
Pasha


Re: [PATCH v4 5/6] pstore/ram: Introduce max_reason and convert dump_oops

2020-05-15 Thread Kees Cook
On Fri, May 15, 2020 at 03:30:27PM -0400, Pavel Tatashin wrote:
> >  #define parse_u32(name, field, default_value) {
> > \
> > ret = ramoops_parse_dt_u32(pdev, name, default_value,   \
> 
> The series seems to be missing the patch where ramoops_parse_dt_size
> -> ramoops_parse_dt_u32 get renamed, and updated to handle default
> value.

Oops! Sorry, I cut the line in the wrong place for sending out the delta
on top of the pstore tree. :)

It's unchanged from:
https://lore.kernel.org/lkml/20200506211523.15077-4-keesc...@chromium.org/

-- 
Kees Cook


Re: [PATCH v4 5/6] pstore/ram: Introduce max_reason and convert dump_oops

2020-05-15 Thread Kees Cook
On Fri, May 15, 2020 at 03:40:14PM -0400, Pavel Tatashin wrote:
>  pdata.dump_oops = dump_oops;
> > +   /* If "max_reason" is set, its value has priority over "dump_oops". 
> > */
> > +   if (ramoops_max_reason != -1)
> > +   pdata.max_reason = ramoops_max_reason;
> 
>  (ramoops_max_reason >= 0) might make more sense here, we do not want
> negative max_reason even if it was provided by the user.

Yeah, that's a good point. I'll tweak that. Thanks!

-- 
Kees Cook


Re: [PATCH v2 00/12] mm: consolidate definitions of page table accessors

2020-05-15 Thread Andrew Morton
On Thu, 14 May 2020 20:03:15 +0300 Mike Rapoport  wrote:

> The low level page table accessors (pXY_index(), pXY_offset()) are
> duplicated across all architectures and sometimes more than once. For
> instance, we have 31 definition of pgd_offset() for 25 supported
> architectures.
> 
> Most of these definitions are actually identical and typically it boils
> down to, e.g. 
> 
> static inline unsigned long pmd_index(unsigned long address)
> {
> return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
> }
> 
> static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
> {
> return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
> }
> 
> These definitions can be shared among 90% of the arches provided XYZ_SHIFT,
> PTRS_PER_XYZ and xyz_page_vaddr() are defined.
> 
> For architectures that really need a custom version there is always
> possibility to override the generic version with the usual ifdefs magic.
> 
> These patches introduce include/linux/pgtable.h that replaces
> include/asm-generic/pgtable.h and add the definitions of the page table
> accessors to the new header.

hm,

>  712 files changed, 684 insertions(+), 2021 deletions(-)

big!

There's a lot of stuff going on at present (I suspect everyone is
sitting at home coding up a storm).  However this all merged up fairly
cleanly, haven't tried compiling it yet.


powerpc/pci: [PATCH 1/1 V2] PCIE PHB reset

2020-05-15 Thread wenxiong
From: Wen Xiong 

Several device drivers hit EEH(Extended Error handling) when triggering
kdump on Pseries PowerVM. This patch implemented a reset of the PHBs
in pci general code. PHB reset stop all PCI transactions from previous
kernel. We have tested the patch in several enviroments:
- direct slot adapters
- adapters under the switch
- a VF adapter in PowerVM
- a VF adapter/adapter in KVM guest.

Signed-off-by: Wen Xiong 

---
 arch/powerpc/platforms/pseries/pci.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/pci.c 
b/arch/powerpc/platforms/pseries/pci.c
index 911534b89c85..cb7e4276cf04 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -11,6 +11,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -354,3 +356,153 @@ int pseries_root_bridge_prepare(struct pci_host_bridge 
*bridge)
 
return 0;
 }
+
+/**
+ * pseries_get_pdn_addr - Retrieve PHB address
+ * @pe: EEH PE
+ *
+ * Retrieve the assocated PHB address. Actually, there're 2 RTAS
+ * function calls dedicated for the purpose. We need implement
+ * it through the new function and then the old one. Besides,
+ * you should make sure the config address is figured out from
+ * FDT node before calling the function.
+ *
+ */
+static int pseries_get_pdn_addr(struct pci_controller *phb)
+{
+   int ret = -1;
+   int rets[3];
+   int ibm_get_config_addr_info;
+   int ibm_get_config_addr_info2;
+   int config_addr = 0;
+   struct pci_dn *root_pdn, *pdn;
+
+   ibm_get_config_addr_info2   = rtas_token("ibm,get-config-addr-info2");
+   ibm_get_config_addr_info= rtas_token("ibm,get-config-addr-info");
+
+   root_pdn = PCI_DN(phb->dn);
+   pdn = list_first_entry(&root_pdn->child_list, struct pci_dn, list);
+   config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
+
+   if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
+   /*
+* First of all, we need to make sure there has one PE
+* associated with the device. If option is 1, it
+* queries if config address is supported in a PE or not.
+* If option is 0, it returns PE config address or config
+* address for the PE primary bus.
+*/
+   ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
+   config_addr, BUID_HI(pdn->phb->buid),
+   BUID_LO(pdn->phb->buid), 1);
+   if (ret || (rets[0] == 0)) {
+   pr_warn("%s: Failed to get address for PHB#%x-PE# 
option=%d config_addr=%x\n",
+   __func__, pdn->phb->global_number, 1, rets[0]);
+   return -1;
+   }
+
+   /* Retrieve the associated PE config address */
+   ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
+   config_addr, BUID_HI(pdn->phb->buid),
+   BUID_LO(pdn->phb->buid), 0);
+   if (ret) {
+   pr_warn("%s: Failed to get address for PHB#%x-PE# 
option=%d config_addr=%x\n",
+   __func__, pdn->phb->global_number, 0, rets[0]);
+   return -1;
+   }
+   return rets[0];
+   }
+
+   if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
+   ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets,
+   config_addr, BUID_HI(pdn->phb->buid),
+   BUID_LO(pdn->phb->buid), 0);
+   if (ret || rets[0]) {
+   pr_warn("%s: Failed to get address for PHB#%x-PE# 
config_addr=%x\n",
+   __func__, pdn->phb->global_number, rets[0]);
+   return -1;
+   }
+   return rets[0];
+   }
+
+   return ret;
+}
+
+static int __init pseries_phb_reset(void)
+{
+   struct pci_controller *phb;
+   int config_addr;
+   int ibm_set_slot_reset;
+   int ibm_configure_pe;
+   int ret;
+
+   if (is_kdump_kernel() || reset_devices) {
+   pr_info("Issue PHB reset ...\n");
+   ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
+   ibm_configure_pe = rtas_token("ibm,configure-pe");
+
+   if (ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE ||
+   ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
+   pr_info("%s: EEH functionality not supported\n",
+   __func__);
+   }
+
+   list_for_each_entry(phb, &hose_list, list_node) {
+   config_addr = pseries_get_pdn_addr(phb);
+   if (config_addr == -1)
+   continue;
+
+   ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
+  

Re: powerpc/pci: [PATCH 1/1 V2] PCIE PHB reset

2020-05-15 Thread Gustavo Romero

Hi Xiong,

On 5/15/20 5:04 PM, wenxi...@linux.vnet.ibm.com wrote:

From: Wen Xiong 

Several device drivers hit EEH(Extended Error handling) when triggering
kdump on Pseries PowerVM. This patch implemented a reset of the PHBs
in pci general code. PHB reset stop all PCI transactions from previous
kernel. We have tested the patch in several enviroments:


What do you mean exactly by "previous kernel" in here? Is there a way to
enhance that comment a bit further?


Thanks,
Gustavo


Re: [PATCH v4 2/2] powerpc/rtas: Implement reentrant rtas call

2020-05-15 Thread Leonardo Bras
Hello Nick,

On Fri, 2020-05-15 at 17:30 +1000, Nicholas Piggin wrote:
> Excerpts from Leonardo Bras's message of May 15, 2020 9:51 am:
> > Implement rtas_call_reentrant() for reentrant rtas-calls:
> > "ibm,int-on", "ibm,int-off",ibm,get-xive" and  "ibm,set-xive".
> > 
> > On LoPAPR Version 1.1 (March 24, 2016), from 7.3.10.1 to 7.3.10.4,
> > items 2 and 3 say:
> > 
> > 2 - For the PowerPC External Interrupt option: The * call must be
> > reentrant to the number of processors on the platform.
> > 3 - For the PowerPC External Interrupt option: The * argument call
> > buffer for each simultaneous call must be physically unique.
> > 
> > So, these rtas-calls can be called in a lockless way, if using
> > a different buffer for each cpu doing such rtas call.
> 
> What about rtas_call_unlocked? Do the callers need to take the rtas 
> lock?
> 
> Machine checks must call ibm,nmi-interlock too, which we really don't 
> want to take a lock for either. Hopefully that's in a class of its own
> and we can essentially ignore with respect to other rtas calls.
> 
> The spec is pretty vague too :(
> 
> "The ibm,get-xive call must be reentrant to the number of processors on 
> the platform."
> 
> This suggests ibm,get-xive can be called concurrently by multiple
> processors. It doesn't say anything about being re-entrant against any 
> of the other re-entrant calls. Maybe that could be reasonably assumed,
> but I don't know if it's reasonable to assume it can be called 
> concurrently with a *non-reentrant* call, is it?

This was discussed on a previous version of the patchset:

https://lore.kernel.org/linuxppc-dev/875zcy2v8o@linux.ibm.com/

He checked with partition firmware development and these calls can be
used concurrently with arbitrary other RTAS calls.

> 
> > For this, it was suggested to add the buffer (struct rtas_args)
> > in the PACA struct, so each cpu can have it's own buffer.
> 
> You can't do this, paca is not limited to RTAS_INSTANTIATE_MAX.
> Which is good, because I didn't want you to add another 88 bytes to the 
> paca :) Can you make it a pointer and allocate it separately? Check
> the slb_shadow allocation, you could use a similar pattern.

Sure, I will send the next version with this change.

> 
> The other option would be to have just one more rtas args, and have the 
> crashing CPU always that. That would skirt the re-entrancy issue -- the
> concurrency is only ever a last resort. Would be a bit tricker though.

It seems a good idea, but I would like to try the previous alternative
first.

> Thanks,
> Nick

Thank you Nick! 



[PATCH v5 0/2] Implement reentrant rtas call

2020-05-15 Thread Leonardo Bras
Patch 2 implement rtas_call_reentrant() for reentrant rtas-calls:
"ibm,int-on", "ibm,int-off",ibm,get-xive" and  "ibm,set-xive",
according to LoPAPR Version 1.1 (March 24, 2016).

For that, it's necessary that every call uses a different
rtas buffer (rtas_args). Paul Mackerras suggested using the PACA
structure for creating a per-cpu buffer for these calls.

Patch 1 was necessary to make PACA have a 'struct rtas_args' member.

Reentrant rtas calls can be useful to avoid deadlocks in crashing,
where rtas-calls are needed, but some other thread crashed holding
the rtas.lock.

This is a backtrace of a deadlock from a kdump testing environment:

  #0 arch_spin_lock
  #1  lock_rtas () 
  #2  rtas_call (token=8204, nargs=1, nret=1, outputs=0x0)
  #3  ics_rtas_mask_real_irq (hw_irq=4100) 
  #4  machine_kexec_mask_interrupts
  #5  default_machine_crash_shutdown
  #6  machine_crash_shutdown 
  #7  __crash_kexec
  #8  crash_kexec
  #9  oops_end

Signed-off-by: Leonardo Bras 

---
Changes since v4:
- Insted of having the full buffer on PACA, adds only a pointer and
  allocate it during allocate_paca(), making sure it's in a memory
  range available for RTAS (32-bit). (Thanks Nick Piggin!)

Changes since v3:
- Adds protection from preemption and interruption

Changes since v2:
- Fixed build failure from ppc64e, by including spinlock_types.h on 
  rtas-types.h
- Improved commit messages

Changes since v1:
- Moved buffer from stack to PACA (as suggested by Paul Mackerras)
- Added missing output bits
- Improve documentation following kernel-doc format (as suggested by
  Nathan Lynch)


Leonardo Bras (2):
  powerpc/rtas: Move type/struct definitions from rtas.h into
rtas-types.h
  powerpc/rtas: Implement reentrant rtas call

 arch/powerpc/include/asm/paca.h   |   2 +
 arch/powerpc/include/asm/rtas-types.h | 126 ++
 arch/powerpc/include/asm/rtas.h   | 119 +---
 arch/powerpc/kernel/rtas.c|  42 +
 arch/powerpc/sysdev/xics/ics-rtas.c   |  22 ++---
 5 files changed, 183 insertions(+), 128 deletions(-)
 create mode 100644 arch/powerpc/include/asm/rtas-types.h

-- 
2.25.4



[PATCH v5 1/2] powerpc/rtas: Move type/struct definitions from rtas.h into rtas-types.h

2020-05-15 Thread Leonardo Bras
In order to get any rtas* struct into other headers, including rtas.h
may cause a lot of errors, regarding include dependency needed for
inline functions.

Create rtas-types.h and move there all type/struct definitions
from rtas.h, then include rtas-types.h into rtas.h.

Also, as suggested by checkpath.pl, replace uint8_t for u8, and keep
the same type pattern for the whole file, as they are the same
according to powerpc/boot/types.h.

Signed-off-by: Leonardo Bras 
---
 arch/powerpc/include/asm/rtas-types.h | 126 ++
 arch/powerpc/include/asm/rtas.h   | 118 +---
 2 files changed, 127 insertions(+), 117 deletions(-)
 create mode 100644 arch/powerpc/include/asm/rtas-types.h

diff --git a/arch/powerpc/include/asm/rtas-types.h 
b/arch/powerpc/include/asm/rtas-types.h
new file mode 100644
index ..87354e28f160
--- /dev/null
+++ b/arch/powerpc/include/asm/rtas-types.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _POWERPC_RTAS_TYPES_H
+#define _POWERPC_RTAS_TYPES_H
+#ifdef __KERNEL__
+
+#include 
+
+typedef __be32 rtas_arg_t;
+
+struct rtas_args {
+   __be32 token;
+   __be32 nargs;
+   __be32 nret;
+   rtas_arg_t args[16];
+   rtas_arg_t *rets; /* Pointer to return values in args[]. */
+};
+
+struct rtas_t {
+   unsigned long entry;/* physical address pointer */
+   unsigned long base; /* physical address pointer */
+   unsigned long size;
+   arch_spinlock_t lock;
+   struct rtas_args args;
+   struct device_node *dev;/* virtual address pointer */
+};
+
+struct rtas_suspend_me_data {
+   atomic_t working; /* number of cpus accessing this struct */
+   atomic_t done;
+   int token; /* ibm,suspend-me */
+   atomic_t error;
+   struct completion *complete; /* wait on this until working == 0 */
+};
+
+struct rtas_error_log {
+   /* Byte 0 */
+   u8  byte0;  /* Architectural version */
+
+   /* Byte 1 */
+   u8  byte1;
+   /* 
+* XXX  3: Severity level of error
+*XX2: Degree of recovery
+*  X   1: Extended log present?
+*   XX 2: Reserved
+*/
+
+   /* Byte 2 */
+   u8  byte2;
+   /* 
+*  4: Initiator of event
+*  4: Target of failed operation
+*/
+   u8  byte3;  /* General event or error*/
+   __be32  extended_log_length;/* length in bytes */
+   unsigned char   buffer[1];  /* Start of extended log */
+   /* Variable length.  */
+};
+
+/* RTAS general extended event log, Version 6. The extended log starts
+ * from "buffer" field of struct rtas_error_log defined above.
+ */
+struct rtas_ext_event_log_v6 {
+   /* Byte 0 */
+   u8 byte0;
+   /* 
+* X1: Log valid
+*  X   1: Unrecoverable error
+*   X  1: Recoverable (correctable or successfully retried)
+*X 1: Bypassed unrecoverable error (degraded operation)
+* X1: Predictive error
+*  X   1: "New" log (always 1 for data returned from RTAS)
+*   X  1: Big Endian
+*X 1: Reserved
+*/
+
+   /* Byte 1 */
+   u8 byte1;   /* reserved */
+
+   /* Byte 2 */
+   u8 byte2;
+   /* 
+* X1: Set to 1 (indicating log is in PowerPC format)
+*  XXX 3: Reserved
+*  4: Log format used for bytes 12-2047
+*/
+
+   /* Byte 3 */
+   u8 byte3;   /* reserved */
+   /* Byte 4-11 */
+   u8 reserved[8]; /* reserved */
+   /* Byte 12-15 */
+   __be32  company_id; /* Company ID of the company*/
+   /* that defines the format for  */
+   /* the vendor specific log type */
+   /* Byte 16-end of log */
+   u8 vendor_log[1];   /* Start of vendor specific log */
+   /* Variable length. */
+};
+
+/* Vendor specific Platform Event Log Format, Version 6, section header */
+struct pseries_errorlog {
+   __be16 id;  /* 0x00 2-byte ASCII section ID */
+   __be16 length;  /* 0x02 Section length in bytes */
+   u8 version; /* 0x04 Section version */
+   u8 subtype; /* 0x05 Section subtype */
+   __be16 creator_component;   /* 0x06 Creator component ID*/
+   u8 data[];  /* 0x08 Start of section data   */
+};
+
+/* RTAS pseries hotplug errorlog section */
+struct pse

[PATCH v5 2/2] powerpc/rtas: Implement reentrant rtas call

2020-05-15 Thread Leonardo Bras
Implement rtas_call_reentrant() for reentrant rtas-calls:
"ibm,int-on", "ibm,int-off",ibm,get-xive" and  "ibm,set-xive".

On LoPAPR Version 1.1 (March 24, 2016), from 7.3.10.1 to 7.3.10.4,
items 2 and 3 say:

2 - For the PowerPC External Interrupt option: The * call must be
reentrant to the number of processors on the platform.
3 - For the PowerPC External Interrupt option: The * argument call
buffer for each simultaneous call must be physically unique.

So, these rtas-calls can be called in a lockless way, if using
a different buffer for each cpu doing such rtas call.

For this, it was suggested to add the buffer (struct rtas_args)
in the PACA struct, so each cpu can have it's own buffer.
The PACA struct received a pointer to rtas buffer, which is
allocated in the memory range available to rtas 32-bit.

Reentrant rtas calls are useful to avoid deadlocks in crashing,
where rtas-calls are needed, but some other thread crashed holding
the rtas.lock.

This is a backtrace of a deadlock from a kdump testing environment:

  #0 arch_spin_lock
  #1  lock_rtas ()
  #2  rtas_call (token=8204, nargs=1, nret=1, outputs=0x0)
  #3  ics_rtas_mask_real_irq (hw_irq=4100)
  #4  machine_kexec_mask_interrupts
  #5  default_machine_crash_shutdown
  #6  machine_crash_shutdown
  #7  __crash_kexec
  #8  crash_kexec
  #9  oops_end

Signed-off-by: Leonardo Bras 
---
 arch/powerpc/include/asm/paca.h |  2 ++
 arch/powerpc/include/asm/rtas.h |  1 +
 arch/powerpc/kernel/paca.c  | 20 +++
 arch/powerpc/kernel/rtas.c  | 52 +
 arch/powerpc/sysdev/xics/ics-rtas.c | 22 ++--
 5 files changed, 86 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index e3cc9eb9204d..87cd9c2220cc 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -270,6 +271,7 @@ struct paca_struct {
 #ifdef CONFIG_MMIOWB
struct mmiowb_state mmiowb_state;
 #endif
+   struct rtas_args *reentrant_args;
 } cacheline_aligned;
 
 extern void copy_mm_to_paca(struct mm_struct *mm);
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index c35c5350b7e4..fa7509c85881 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -236,6 +236,7 @@ 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 3f91ccaa9c74..88c9b61489fc 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "setup.h"
 
@@ -164,6 +165,23 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, 
unsigned long limit)
 
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
+/**
+ * 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.
+ *
+ * Return: Pointer to allocated rtas_args
+ */
+static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
+{
+   limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX);
+
+   return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES,
+  limit, cpu);
+}
+
 /* The Paca is an array with one entry per processor.  Each contains an
  * lppaca, which contains the information shared between the
  * hypervisor and Linux.
@@ -202,6 +220,7 @@ void __init __nostackprotector initialise_paca(struct 
paca_struct *new_paca, int
/* For now -- if we have threads this will be adjusted later */
new_paca->tcd_ptr = &new_paca->tcd;
 #endif
+   new_paca->reentrant_args = NULL;
 }
 
 /* Put the paca pointer into r13 and SPRG_PACA */
@@ -274,6 +293,7 @@ void __init allocate_paca(int cpu)
 #ifdef CONFIG_PPC_BOOK3S_64
paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
 #endif
+   paca->reentrant_args = new_rtas_args(cpu, limit);
paca_struct_size += sizeof(struct paca_struct);
 }
 
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index c5fa251b8950..6e22eb4fc0e7 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* This is here deliberately so it's only used in this file */
 void enter_rtas(unsigned long);
@@ -483,6 +484,57 @@ int rtas_call(int token, int nargs, int nret, int 
*outputs, ...)
 }
 EXPORT_SYMBOL(rtas_call);
 
+/**
+ * rtas_call_reentrant() - Used for reentr