Re: [PATCH] vhost: do not enable VHOST_MENU by default

2020-04-13 Thread Michael Ellerman
Jason Wang  writes:
> We try to keep the defconfig untouched after decoupling CONFIG_VHOST
> out of CONFIG_VIRTUALIZATION in commit 20c384f1ea1a
> ("vhost: refine vhost and vringh kconfig") by enabling VHOST_MENU by
> default. Then the defconfigs can keep enabling CONFIG_VHOST_NET
> without the caring of CONFIG_VHOST.
>
> But this will leave a "CONFIG_VHOST_MENU=y" in all defconfigs and even
> for the ones that doesn't want vhost. So it actually shifts the
> burdens to the maintainers of all other to add "CONFIG_VHOST_MENU is
> not set". So this patch tries to enable CONFIG_VHOST explicitly in
> defconfigs that enables CONFIG_VHOST_NET and CONFIG_VHOST_VSOCK.
>
> Cc: Thomas Bogendoerfer 
> Cc: Benjamin Herrenschmidt 
> Cc: Paul Mackerras 
> Cc: Michael Ellerman 
> Cc: Heiko Carstens 
> Cc: Vasily Gorbik 
> Cc: Christian Borntraeger 
> Reported-by: Geert Uytterhoeven 
> Signed-off-by: Jason Wang 
> ---
>  arch/mips/configs/malta_kvm_defconfig  |  1 +
>  arch/powerpc/configs/powernv_defconfig |  1 +
>  arch/powerpc/configs/ppc64_defconfig   |  1 +
>  arch/powerpc/configs/pseries_defconfig |  1 +

Fine by me.

Acked-by: Michael Ellerman  (powerpc)

cheers

>  arch/s390/configs/debug_defconfig  |  1 +
>  arch/s390/configs/defconfig|  1 +
>  drivers/vhost/Kconfig  | 18 +-
>  7 files changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/arch/mips/configs/malta_kvm_defconfig 
> b/arch/mips/configs/malta_kvm_defconfig
> index 8ef612552a19..06f0c7a0ca87 100644
> --- a/arch/mips/configs/malta_kvm_defconfig
> +++ b/arch/mips/configs/malta_kvm_defconfig
> @@ -18,6 +18,7 @@ CONFIG_PCI=y
>  CONFIG_VIRTUALIZATION=y
>  CONFIG_KVM=m
>  CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS=y
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_MODULES=y
>  CONFIG_MODULE_UNLOAD=y
> diff --git a/arch/powerpc/configs/powernv_defconfig 
> b/arch/powerpc/configs/powernv_defconfig
> index 71749377d164..404245b4594d 100644
> --- a/arch/powerpc/configs/powernv_defconfig
> +++ b/arch/powerpc/configs/powernv_defconfig
> @@ -346,5 +346,6 @@ CONFIG_CRYPTO_DEV_VMX=y
>  CONFIG_VIRTUALIZATION=y
>  CONFIG_KVM_BOOK3S_64=m
>  CONFIG_KVM_BOOK3S_64_HV=m
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_PRINTK_TIME=y
> diff --git a/arch/powerpc/configs/ppc64_defconfig 
> b/arch/powerpc/configs/ppc64_defconfig
> index 7e68cb222c7b..4599fc7be285 100644
> --- a/arch/powerpc/configs/ppc64_defconfig
> +++ b/arch/powerpc/configs/ppc64_defconfig
> @@ -61,6 +61,7 @@ CONFIG_ELECTRA_CF=y
>  CONFIG_VIRTUALIZATION=y
>  CONFIG_KVM_BOOK3S_64=m
>  CONFIG_KVM_BOOK3S_64_HV=m
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_OPROFILE=m
>  CONFIG_KPROBES=y
> diff --git a/arch/powerpc/configs/pseries_defconfig 
> b/arch/powerpc/configs/pseries_defconfig
> index 6b68109e248f..4cad3901b5de 100644
> --- a/arch/powerpc/configs/pseries_defconfig
> +++ b/arch/powerpc/configs/pseries_defconfig
> @@ -321,5 +321,6 @@ CONFIG_CRYPTO_DEV_VMX=y
>  CONFIG_VIRTUALIZATION=y
>  CONFIG_KVM_BOOK3S_64=m
>  CONFIG_KVM_BOOK3S_64_HV=m
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_PRINTK_TIME=y
> diff --git a/arch/s390/configs/debug_defconfig 
> b/arch/s390/configs/debug_defconfig
> index 0c86ba19fa2b..6ec6e69630d1 100644
> --- a/arch/s390/configs/debug_defconfig
> +++ b/arch/s390/configs/debug_defconfig
> @@ -57,6 +57,7 @@ CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
>  CONFIG_CMM=m
>  CONFIG_APPLDATA_BASE=y
>  CONFIG_KVM=m
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_VHOST_VSOCK=m
>  CONFIG_OPROFILE=m
> diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
> index 6b27d861a9a3..d1b3bf83d687 100644
> --- a/arch/s390/configs/defconfig
> +++ b/arch/s390/configs/defconfig
> @@ -57,6 +57,7 @@ CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
>  CONFIG_CMM=m
>  CONFIG_APPLDATA_BASE=y
>  CONFIG_KVM=m
> +CONFIG_VHOST=m
>  CONFIG_VHOST_NET=m
>  CONFIG_VHOST_VSOCK=m
>  CONFIG_OPROFILE=m
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index e79cbbdfea45..14d296dc18cd 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -12,23 +12,18 @@ config VHOST_RING
> This option is selected by any driver which needs to access
> the host side of a virtio ring.
>  
> -config VHOST
> - tristate
> +menuconfig VHOST
> + tristate "Vhost Devices"
>   select VHOST_IOTLB
>   help
> -   This option is selected by any driver which needs to access
> -   the core of vhost.
> -
> -menuconfig VHOST_MENU
> - bool "VHOST drivers"
> - default y
> +   Enable option to support host kernel or hardware accelerator
> +   for virtio device.
>  
> -if VHOST_MENU
> +if VHOST
>  
>  config VHOST_NET
>   tristate "Host kernel accelerator for virtio net"
>   depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)
> - select VHOST
>   ---help---
> This kernel module can be loaded in host kernel to accelerate
> guest networking with virtio_net. Not to be confused with 

Re: [PATCH v3 13/16] powerpc/watchpoint: Prepare handler to handle more than one watcnhpoint

2020-04-13 Thread Christophe Leroy




Le 14/04/2020 à 05:16, Ravi Bangoria a écrit :

Currently we assume that we have only one watchpoint supported by hw.
Get rid of that assumption and use dynamic loop instead. This should
make supporting more watchpoints very easy.

With more than one watchpoint, exception handler need to know which
DAWR caused the exception, and hw currently does not provide it. So
we need sw logic for the same. To figure out which DAWR caused the
exception, check all different combinations of user specified range,
dawr address range, actual access range and dawrx constrains. For ex,
if user specified range and actual access range overlaps but dawrx is
configured for readonly watchpoint and the instruction is store, this
DAWR must not have caused exception.

Signed-off-by: Ravi Bangoria 
---
  arch/powerpc/include/asm/processor.h |   2 +-
  arch/powerpc/include/asm/sstep.h |   2 +
  arch/powerpc/kernel/hw_breakpoint.c  | 400 +--
  arch/powerpc/kernel/process.c|   3 -
  4 files changed, 315 insertions(+), 92 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 65b03162cd67..4bc4e4a99166 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -185,7 +185,7 @@ struct thread_struct {
 * Helps identify source of single-step exception and subsequent
 * hw-breakpoint enablement
 */
-   struct perf_event *last_hit_ubp;
+   struct perf_event *last_hit_ubp[HBP_NUM_MAX];
  #endif /* CONFIG_HAVE_HW_BREAKPOINT */
struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint 
info */
unsigned long   trap_nr;/* last trap # on this thread */
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..38919b27a6fa 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -48,6 +48,8 @@ enum instruction_type {
  
  #define INSTR_TYPE_MASK	0x1f
  
+#define OP_IS_LOAD(type)	((LOAD <= (type) && (type) <= LOAD_VSX) || (type) == LARX)

+#define OP_IS_STORE(type)  ((STORE <= (type) && (type) <= STORE_VSX) || 
(type) == STCX)
  #define OP_IS_LOAD_STORE(type)(LOAD <= (type) && (type) <= STCX)
  
  /* Compute flags, ORed in with type */

diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 02ffd14f4519..9b5812bca892 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -30,7 +30,7 @@
   * Stores the breakpoints currently in use on each breakpoint address
   * register for every cpu
   */
-static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM_MAX]);
  
  /*

   * Returns total number of data or instruction breakpoints available.
@@ -42,6 +42,17 @@ int hw_breakpoint_slots(int type)
return 0;   /* no instruction breakpoints available */
  }
  
+static bool single_step_pending(void)

+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (current->thread.last_hit_ubp[i])
+   return true;
+   }
+   return false;
+}
+
  /*
   * Install a perf counter breakpoint.
   *
@@ -54,16 +65,26 @@ int hw_breakpoint_slots(int type)
  int arch_install_hw_breakpoint(struct perf_event *bp)
  {
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-   struct perf_event **slot = this_cpu_ptr(_per_reg);
+   struct perf_event **slot;
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   slot = this_cpu_ptr(_per_reg[i]);
+   if (!*slot) {
+   *slot = bp;
+   break;
+   }
+   }
  
-	*slot = bp;

+   if (WARN_ONCE(i == nr_wp_slots(), "Can't find any breakpoint slot"))
+   return -EBUSY;
  
  	/*

 * Do not install DABR values if the instruction must be single-stepped.
 * If so, DABR will be populated in single_step_dabr_instruction().
 */
-   if (current->thread.last_hit_ubp != bp)
-   __set_breakpoint(0, info);
+   if (!single_step_pending())
+   __set_breakpoint(i, info);
  
  	return 0;

  }
@@ -79,15 +100,22 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
   */
  void arch_uninstall_hw_breakpoint(struct perf_event *bp)
  {
-   struct perf_event **slot = this_cpu_ptr(_per_reg);
+   struct arch_hw_breakpoint null_brk = {0};
+   struct perf_event **slot;
+   int i;
  
-	if (*slot != bp) {

-   WARN_ONCE(1, "Can't find the breakpoint");
-   return;
+   for (i = 0; i < nr_wp_slots(); i++) {
+   slot = this_cpu_ptr(_per_reg[i]);
+   if (*slot == bp) {
+   *slot = NULL;
+   break;
+   }
}
  
-	*slot = NULL;

-   hw_breakpoint_disable();
+   if (WARN_ONCE(i == 

Re: [PATCH v3 12/16] powerpc/watchpoint: Use builtin ALIGN*() macros

2020-04-13 Thread Christophe Leroy




Le 14/04/2020 à 05:16, Ravi Bangoria a écrit :

Currently we calculate hw aligned start and end addresses manually.
Replace them with builtin ALIGN_DOWN() and ALIGN() macros.

Suggested-by: Christophe Leroy 
Signed-off-by: Ravi Bangoria 
---
  arch/powerpc/include/asm/hw_breakpoint.h  |  5 +++--
  arch/powerpc/kernel/hw_breakpoint.c   | 12 ++--
  arch/powerpc/kernel/process.c |  8 
  arch/powerpc/kernel/ptrace/ptrace-noadv.c |  2 +-
  4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index d472b2eb757e..add5aa076919 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -34,10 +34,11 @@ struct arch_hw_breakpoint {
  #define HW_BRK_TYPE_PRIV_ALL  (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
 HW_BRK_TYPE_HYP)
  
+/* Minimum granularity */

  #ifdef CONFIG_PPC_8xx
-#define HW_BREAKPOINT_ALIGN 0x3
+#define HW_BREAKPOINT_SIZE  0x4
  #else
-#define HW_BREAKPOINT_ALIGN 0x7
+#define HW_BREAKPOINT_SIZE  0x8
  #endif
  
  #define DABR_MAX_LEN	8

diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 319a761b7412..02ffd14f4519 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -145,10 +145,10 @@ int arch_bp_generic_fields(int type, int *gen_bp_type)
   *<---8 bytes--->
   *
   * In this case, we should configure hw as:
- *   start_addr = address & ~HW_BREAKPOINT_ALIGN
+ *   start_addr = address & ~(HW_BREAKPOINT_SIZE - 1)
   *   len = 16 bytes
   *
- * @start_addr and @end_addr are inclusive.
+ * @start_addr is inclusive but @end_addr is exclusive.
   */
  static int hw_breakpoint_validate_len(struct arch_hw_breakpoint *hw)
  {
@@ -156,14 +156,14 @@ static int hw_breakpoint_validate_len(struct 
arch_hw_breakpoint *hw)
u16 hw_len;
unsigned long start_addr, end_addr;
  
-	start_addr = hw->address & ~HW_BREAKPOINT_ALIGN;

-   end_addr = (hw->address + hw->len - 1) | HW_BREAKPOINT_ALIGN;
-   hw_len = end_addr - start_addr + 1;
+   start_addr = ALIGN_DOWN(hw->address, HW_BREAKPOINT_SIZE);
+   end_addr = ALIGN(hw->address + hw->len, HW_BREAKPOINT_SIZE);
+   hw_len = end_addr - start_addr;
  
  	if (dawr_enabled()) {

max_len = DAWR_MAX_LEN;
/* DAWR region can't cross 512 bytes boundary */
-   if ((start_addr >> 9) != (end_addr >> 9))
+   if ((start_addr >> 9) != ((end_addr - 1) >> 9))


What about:
if (ALIGN(start_addr, SZ_512M) != ALIGN(end - 1, SZ_512M))


return -EINVAL;
} else if (IS_ENABLED(CONFIG_PPC_8xx)) {
/* 8xx can setup a range without limitation */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index aab82ab80dfa..06679adac447 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -800,12 +800,12 @@ static inline int set_breakpoint_8xx(struct 
arch_hw_breakpoint *brk)
unsigned long lctrl1 = LCTRL1_CTE_GT | LCTRL1_CTF_LT | LCTRL1_CRWE_RW |
   LCTRL1_CRWF_RW;
unsigned long lctrl2 = LCTRL2_LW0EN | LCTRL2_LW0LADC | LCTRL2_SLW0EN;
-   unsigned long start_addr = brk->address & ~HW_BREAKPOINT_ALIGN;
-   unsigned long end_addr = (brk->address + brk->len - 1) | 
HW_BREAKPOINT_ALIGN;
+   unsigned long start_addr = ALIGN_DOWN(brk->address, HW_BREAKPOINT_SIZE);
+   unsigned long end_addr = ALIGN(brk->address + brk->len, 
HW_BREAKPOINT_SIZE);
  
  	if (start_addr == 0)

lctrl2 |= LCTRL2_LW0LA_F;
-   else if (end_addr == ~0U)
+   else if (end_addr - 1 == ~0U)


What about:
else if (end_addr == 0)


lctrl2 |= LCTRL2_LW0LA_E;
else
lctrl2 |= LCTRL2_LW0LA_EandF;
@@ -821,7 +821,7 @@ static inline int set_breakpoint_8xx(struct 
arch_hw_breakpoint *brk)
lctrl1 |= LCTRL1_CRWE_WO | LCTRL1_CRWF_WO;
  
  	mtspr(SPRN_CMPE, start_addr - 1);

-   mtspr(SPRN_CMPF, end_addr + 1);
+   mtspr(SPRN_CMPF, end_addr);
mtspr(SPRN_LCTRL1, lctrl1);
mtspr(SPRN_LCTRL2, lctrl2);
  
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c

index 08cb8c1b504c..697c7e4b5877 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -216,7 +216,7 @@ long ppc_set_hwdebug(struct task_struct *child, struct 
ppc_hw_breakpoint *bp_inf
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
  
-	brk.address = bp_info->addr & ~HW_BREAKPOINT_ALIGN;

+   brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
brk.type = HW_BRK_TYPE_TRANSLATE;
brk.len = DABR_MAX_LEN;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)



Christophe


Re: Boot flakiness with QEMU 3.1.0 and Clang built kernels

2020-04-13 Thread Nathan Chancellor
On Tue, Apr 14, 2020 at 12:05:53PM +1000, David Gibson wrote:
> On Sat, Apr 11, 2020 at 11:57:23PM +1000, Nicholas Piggin wrote:
> > Nicholas Piggin's on April 11, 2020 7:32 pm:
> > > Nathan Chancellor's on April 11, 2020 10:53 am:
> > >> The tt.config values are needed to reproduce but I did not verify that
> > >> ONLY tt.config was needed. Other than that, no, we are just building
> > >> either pseries_defconfig or powernv_defconfig with those configs and
> > >> letting it boot up with a simple initramfs, which prints the version
> > >> string then shuts the machine down.
> > >> 
> > >> Let me know if you need any more information, cheers!
> > > 
> > > Okay I can reproduce it. Sometimes it eventually recovers after a long
> > > pause, and some keyboard input often helps it along. So that seems like 
> > > it might be a lost interrupt.
> > > 
> > > POWER8 vs POWER9 might just be a timing thing if P9 is still hanging
> > > sometimes. I wasn't able to reproduce it with defconfig+tt.config, I
> > > needed your other config with various other debug options.
> > > 
> > > Thanks for the very good report. I'll let you know what I find.
> > 
> > It looks like a qemu bug. Booting with '-d int' shows the decrementer 
> > simply stops firing at the point of the hang, even though MSR[EE]=1 and 
> > the DEC register is wrapping. Linux appears to be doing the right thing 
> > as far as I can tell (not losing interrupts).
> > 
> > This qemu patch fixes the boot hang for me. I don't know that qemu 
> > really has the right idea of "context synchronizing" as defined in the
> > powerpc architecture -- mtmsrd L=1 is not context synchronizing but that
> > does not mean it can avoid looking at exceptions until the next such
> > event. It looks like the decrementer exception goes high but the
> > execution of mtmsrd L=1 is ignoring it.
> > 
> > Prior to the Linux patch 3282a3da25b you bisected to, interrupt replay
> > code would return with an 'rfi' instruction as part of interrupt return,
> > which probably helped to get things moving along a bit. However it would
> > not be foolproof, and Cedric did say he encountered some mysterious
> > lockups under load with qemu powernv before that patch was merged, so
> > maybe it's the same issue?
> > 
> > Thanks,
> > Nick
> > 
> > The patch is a bit of a hack, but if you can run it and verify it fixes
> > your boot hang would be good.
> 
> So a bug in this handling wouldn't surprise me at all.  However a
> report against QEMU 3.1 isn't particularly useful.
> 
>  * Does the problem occur with current upstream master qemu?

Yes, I can reproduce the hang on 5.0.0-rc2.

>  * Does the problem occur with qemu-2.12 (a pretty widely deployed
>"stable" qemu, e.g. in RHEL)?

No idea but I would assume so. I might have time later this week to test
but I assume it is kind of irrelevant if it is reproducible at ToT.

> > ---
> > 
> > diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> > index b207fb5386..1d997f5c32 100644
> > --- a/target/ppc/translate.c
> > +++ b/target/ppc/translate.c
> > @@ -4364,12 +4364,21 @@ static void gen_mtmsrd(DisasContext *ctx)
> >  if (ctx->opcode & 0x0001) {
> >  /* Special form that does not need any synchronisation */
> >  TCGv t0 = tcg_temp_new();
> > +TCGv t1 = tcg_temp_new();
> >  tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
> >  (1 << MSR_RI) | (1 << MSR_EE));
> > -tcg_gen_andi_tl(cpu_msr, cpu_msr,
> > +tcg_gen_andi_tl(t1, cpu_msr,
> >  ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
> > -tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
> > +tcg_gen_or_tl(t1, t1, t0);
> > +
> > +gen_update_nip(ctx, ctx->base.pc_next);
> > +gen_helper_store_msr(cpu_env, t1);
> >  tcg_temp_free(t0);
> > +tcg_temp_free(t1);
> > +/* Must stop the translation as machine state (may have) changed */
> > +/* Note that mtmsr is not always defined as context-synchronizing 
> > */
> > +gen_stop_exception(ctx);
> > +
> >  } else {
> >  /*
> >   * XXX: we need to update nip before the store if we enter
> > 
> 
> -- 
> David Gibson  | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au| minimalist, thank you.  NOT _the_ 
> _other_
>   | _way_ _around_!
> http://www.ozlabs.org/~dgibson

Cheers,
Nathan


[PATCH v3 16/16] powerpc/watchpoint/xmon: Support 2nd dawr

2020-04-13 Thread Ravi Bangoria
Add support for 2nd DAWR in xmon. With this, we can have two
simultaneous breakpoints from xmon.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/xmon/xmon.c | 101 ++-
 1 file changed, 69 insertions(+), 32 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 99e9138661e4..01da49b666db 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -111,7 +111,7 @@ struct bpt {
 
 #define NBPTS  256
 static struct bpt bpts[NBPTS];
-static struct bpt dabr;
+static struct bpt dabr[HBP_NUM_MAX];
 static struct bpt *iabr;
 static unsigned bpinstr = 0x7fe8;  /* trap */
 
@@ -787,10 +787,17 @@ static int xmon_sstep(struct pt_regs *regs)
 
 static int xmon_break_match(struct pt_regs *regs)
 {
+   int i;
+
if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
return 0;
-   if (dabr.enabled == 0)
-   return 0;
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (dabr[i].enabled)
+   goto found;
+   }
+   return 0;
+
+found:
xmon_core(regs, 0);
return 1;
 }
@@ -929,13 +936,16 @@ static void insert_bpts(void)
 
 static void insert_cpu_bpts(void)
 {
+   int i;
struct arch_hw_breakpoint brk;
 
-   if (dabr.enabled) {
-   brk.address = dabr.address;
-   brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | 
HW_BRK_TYPE_PRIV_ALL;
-   brk.len = DABR_MAX_LEN;
-   __set_breakpoint(0, );
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (dabr[i].enabled) {
+   brk.address = dabr[i].address;
+   brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | 
HW_BRK_TYPE_PRIV_ALL;
+   brk.len = 8;
+   __set_breakpoint(i, );
+   }
}
 
if (iabr)
@@ -1349,6 +1359,35 @@ static long check_bp_loc(unsigned long addr)
return 1;
 }
 
+static int find_free_data_bpt(void)
+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (!dabr[i].enabled)
+   return i;
+   }
+   printf("Couldn't find free breakpoint register\n");
+   return -1;
+}
+
+static void print_data_bpts(void)
+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (!dabr[i].enabled)
+   continue;
+
+   printf("   data   "REG"  [", dabr[i].address);
+   if (dabr[i].enabled & 1)
+   printf("r");
+   if (dabr[i].enabled & 2)
+   printf("w");
+   printf("]\n");
+   }
+}
+
 static char *breakpoint_help_string =
 "Breakpoint command usage:\n"
 "bshow breakpoints\n"
@@ -1382,10 +1421,9 @@ bpt_cmds(void)
printf("Hardware data breakpoint not supported on this 
cpu\n");
break;
}
-   if (dabr.enabled) {
-   printf("Couldn't find free breakpoint register\n");
+   i = find_free_data_bpt();
+   if (i < 0)
break;
-   }
mode = 7;
cmd = inchar();
if (cmd == 'r')
@@ -1394,15 +1432,15 @@ bpt_cmds(void)
mode = 6;
else
termch = cmd;
-   dabr.address = 0;
-   dabr.enabled = 0;
-   if (scanhex()) {
-   if (!is_kernel_addr(dabr.address)) {
+   dabr[i].address = 0;
+   dabr[i].enabled = 0;
+   if (scanhex([i].address)) {
+   if (!is_kernel_addr(dabr[i].address)) {
printf(badaddr);
break;
}
-   dabr.address &= ~HW_BRK_TYPE_DABR;
-   dabr.enabled = mode | BP_DABR;
+   dabr[i].address &= ~HW_BRK_TYPE_DABR;
+   dabr[i].enabled = mode | BP_DABR;
}
 
force_enable_xmon();
@@ -1441,7 +1479,9 @@ bpt_cmds(void)
for (i = 0; i < NBPTS; ++i)
bpts[i].enabled = 0;
iabr = NULL;
-   dabr.enabled = 0;
+   for (i = 0; i < nr_wp_slots(); i++)
+   dabr[i].enabled = 0;
+
printf("All breakpoints cleared\n");
break;
}
@@ -1475,14 +1515,7 @@ bpt_cmds(void)
if (xmon_is_ro || !scanhex()) {
/* print all breakpoints */
printf("   typeaddress\n");
-   if (dabr.enabled) {
-   printf("   data   "REG"  [", dabr.address);
-   

[PATCH v3 15/16] powerpc/watchpoint/xmon: Don't allow breakpoint overwriting

2020-04-13 Thread Ravi Bangoria
Xmon allows overwriting breakpoints because it's supported by only
one dawr. But with multiple dawrs, overwriting becomes ambiguous
or unnecessary complicated. So let's not allow it.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/xmon/xmon.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d8c0f01e4b24..99e9138661e4 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1382,6 +1382,10 @@ bpt_cmds(void)
printf("Hardware data breakpoint not supported on this 
cpu\n");
break;
}
+   if (dabr.enabled) {
+   printf("Couldn't find free breakpoint register\n");
+   break;
+   }
mode = 7;
cmd = inchar();
if (cmd == 'r')
-- 
2.21.1



[PATCH v3 14/16] powerpc/watchpoint: Don't allow concurrent perf and ptrace events

2020-04-13 Thread Ravi Bangoria
With Book3s DAWR, ptrace and perf watchpoints on powerpc behaves
differently. Ptrace watchpoint works in one-shot mode and generates
signal before executing instruction. It's ptrace user's job to
single-step the instruction and re-enable the watchpoint. OTOH, in
case of perf watchpoint, kernel emulates/single-steps the instruction
and then generates event. If perf and ptrace creates two events with
same or overlapping address ranges, it's ambiguous to decide who
should single-step the instruction. Because of this issue, don't
allow perf and ptrace watchpoint at the same time if their address
range overlaps.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/hw_breakpoint.h |   2 +
 arch/powerpc/kernel/hw_breakpoint.c  | 222 +++
 kernel/events/hw_breakpoint.c|  16 ++
 3 files changed, 240 insertions(+)

diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index add5aa076919..f42a55eb77d2 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -70,6 +70,8 @@ extern int hw_breakpoint_exceptions_notify(struct 
notifier_block *unused,
unsigned long val, void *data);
 int arch_install_hw_breakpoint(struct perf_event *bp);
 void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+int arch_reserve_bp_slot(struct perf_event *bp);
+void arch_release_bp_slot(struct perf_event *bp);
 void arch_unregister_hw_breakpoint(struct perf_event *bp);
 void hw_breakpoint_pmu_read(struct perf_event *bp);
 extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 9b5812bca892..48c8b5edbc90 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -123,6 +123,228 @@ static bool is_ptrace_bp(struct perf_event *bp)
return bp->overflow_handler == ptrace_triggered;
 }
 
+struct breakpoint {
+   struct list_head list;
+   struct perf_event *bp;
+   bool ptrace_bp;
+};
+
+static DEFINE_PER_CPU(struct breakpoint *, cpu_bps[HBP_NUM_MAX]);
+static LIST_HEAD(task_bps);
+
+static struct breakpoint *alloc_breakpoint(struct perf_event *bp)
+{
+   struct breakpoint *tmp;
+
+   tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+   if (!tmp)
+   return ERR_PTR(-ENOMEM);
+   tmp->bp = bp;
+   tmp->ptrace_bp = is_ptrace_bp(bp);
+   return tmp;
+}
+
+static bool bp_addr_range_overlap(struct perf_event *bp1, struct perf_event 
*bp2)
+{
+   __u64 bp1_saddr, bp1_eaddr, bp2_saddr, bp2_eaddr;
+
+   bp1_saddr = ALIGN_DOWN(bp1->attr.bp_addr, HW_BREAKPOINT_SIZE);
+   bp1_eaddr = ALIGN(bp1->attr.bp_addr + bp1->attr.bp_len, 
HW_BREAKPOINT_SIZE);
+   bp2_saddr = ALIGN_DOWN(bp2->attr.bp_addr, HW_BREAKPOINT_SIZE);
+   bp2_eaddr = ALIGN(bp2->attr.bp_addr + bp2->attr.bp_len, 
HW_BREAKPOINT_SIZE);
+
+   return (bp1_saddr < bp2_eaddr && bp1_eaddr > bp2_saddr);
+}
+
+static bool alternate_infra_bp(struct breakpoint *b, struct perf_event *bp)
+{
+   return is_ptrace_bp(bp) ? !b->ptrace_bp : b->ptrace_bp;
+}
+
+static bool can_co_exist(struct breakpoint *b, struct perf_event *bp)
+{
+   return !(alternate_infra_bp(b, bp) && bp_addr_range_overlap(b->bp, bp));
+}
+
+static int task_bps_add(struct perf_event *bp)
+{
+   struct breakpoint *tmp;
+
+   tmp = alloc_breakpoint(bp);
+   if (IS_ERR(tmp))
+   return PTR_ERR(tmp);
+
+   list_add(>list, _bps);
+   return 0;
+}
+
+static void task_bps_remove(struct perf_event *bp)
+{
+   struct list_head *pos, *q;
+   struct breakpoint *tmp;
+
+   list_for_each_safe(pos, q, _bps) {
+   tmp = list_entry(pos, struct breakpoint, list);
+
+   if (tmp->bp == bp) {
+   list_del(>list);
+   kfree(tmp);
+   break;
+   }
+   }
+}
+
+/*
+ * If any task has breakpoint from alternate infrastructure,
+ * return true. Otherwise return false.
+ */
+static bool all_task_bps_check(struct perf_event *bp)
+{
+   struct breakpoint *tmp;
+
+   list_for_each_entry(tmp, _bps, list) {
+   if (!can_co_exist(tmp, bp))
+   return true;
+   }
+   return false;
+}
+
+/*
+ * If same task has breakpoint from alternate infrastructure,
+ * return true. Otherwise return false.
+ */
+static bool same_task_bps_check(struct perf_event *bp)
+{
+   struct breakpoint *tmp;
+
+   list_for_each_entry(tmp, _bps, list) {
+   if (tmp->bp->hw.target == bp->hw.target &&
+   !can_co_exist(tmp, bp))
+   return true;
+   }
+   return false;
+}
+
+static int cpu_bps_add(struct perf_event *bp)
+{
+   struct breakpoint **cpu_bp;
+   struct breakpoint *tmp;
+   int i = 0;
+
+   tmp = alloc_breakpoint(bp);
+   if 

[PATCH v3 13/16] powerpc/watchpoint: Prepare handler to handle more than one watcnhpoint

2020-04-13 Thread Ravi Bangoria
Currently we assume that we have only one watchpoint supported by hw.
Get rid of that assumption and use dynamic loop instead. This should
make supporting more watchpoints very easy.

With more than one watchpoint, exception handler need to know which
DAWR caused the exception, and hw currently does not provide it. So
we need sw logic for the same. To figure out which DAWR caused the
exception, check all different combinations of user specified range,
dawr address range, actual access range and dawrx constrains. For ex,
if user specified range and actual access range overlaps but dawrx is
configured for readonly watchpoint and the instruction is store, this
DAWR must not have caused exception.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/processor.h |   2 +-
 arch/powerpc/include/asm/sstep.h |   2 +
 arch/powerpc/kernel/hw_breakpoint.c  | 400 +--
 arch/powerpc/kernel/process.c|   3 -
 4 files changed, 315 insertions(+), 92 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 65b03162cd67..4bc4e4a99166 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -185,7 +185,7 @@ struct thread_struct {
 * Helps identify source of single-step exception and subsequent
 * hw-breakpoint enablement
 */
-   struct perf_event *last_hit_ubp;
+   struct perf_event *last_hit_ubp[HBP_NUM_MAX];
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint 
info */
unsigned long   trap_nr;/* last trap # on this thread */
diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h
index 769f055509c9..38919b27a6fa 100644
--- a/arch/powerpc/include/asm/sstep.h
+++ b/arch/powerpc/include/asm/sstep.h
@@ -48,6 +48,8 @@ enum instruction_type {
 
 #define INSTR_TYPE_MASK0x1f
 
+#define OP_IS_LOAD(type)   ((LOAD <= (type) && (type) <= LOAD_VSX) || 
(type) == LARX)
+#define OP_IS_STORE(type)  ((STORE <= (type) && (type) <= STORE_VSX) || 
(type) == STCX)
 #define OP_IS_LOAD_STORE(type) (LOAD <= (type) && (type) <= STCX)
 
 /* Compute flags, ORed in with type */
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 02ffd14f4519..9b5812bca892 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -30,7 +30,7 @@
  * Stores the breakpoints currently in use on each breakpoint address
  * register for every cpu
  */
-static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM_MAX]);
 
 /*
  * Returns total number of data or instruction breakpoints available.
@@ -42,6 +42,17 @@ int hw_breakpoint_slots(int type)
return 0;   /* no instruction breakpoints available */
 }
 
+static bool single_step_pending(void)
+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (current->thread.last_hit_ubp[i])
+   return true;
+   }
+   return false;
+}
+
 /*
  * Install a perf counter breakpoint.
  *
@@ -54,16 +65,26 @@ int hw_breakpoint_slots(int type)
 int arch_install_hw_breakpoint(struct perf_event *bp)
 {
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-   struct perf_event **slot = this_cpu_ptr(_per_reg);
+   struct perf_event **slot;
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   slot = this_cpu_ptr(_per_reg[i]);
+   if (!*slot) {
+   *slot = bp;
+   break;
+   }
+   }
 
-   *slot = bp;
+   if (WARN_ONCE(i == nr_wp_slots(), "Can't find any breakpoint slot"))
+   return -EBUSY;
 
/*
 * Do not install DABR values if the instruction must be single-stepped.
 * If so, DABR will be populated in single_step_dabr_instruction().
 */
-   if (current->thread.last_hit_ubp != bp)
-   __set_breakpoint(0, info);
+   if (!single_step_pending())
+   __set_breakpoint(i, info);
 
return 0;
 }
@@ -79,15 +100,22 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
  */
 void arch_uninstall_hw_breakpoint(struct perf_event *bp)
 {
-   struct perf_event **slot = this_cpu_ptr(_per_reg);
+   struct arch_hw_breakpoint null_brk = {0};
+   struct perf_event **slot;
+   int i;
 
-   if (*slot != bp) {
-   WARN_ONCE(1, "Can't find the breakpoint");
-   return;
+   for (i = 0; i < nr_wp_slots(); i++) {
+   slot = this_cpu_ptr(_per_reg[i]);
+   if (*slot == bp) {
+   *slot = NULL;
+   break;
+   }
}
 
-   *slot = NULL;
-   hw_breakpoint_disable();
+   if (WARN_ONCE(i == nr_wp_slots(), "Can't find any breakpoint slot"))
+  

[PATCH v3 12/16] powerpc/watchpoint: Use builtin ALIGN*() macros

2020-04-13 Thread Ravi Bangoria
Currently we calculate hw aligned start and end addresses manually.
Replace them with builtin ALIGN_DOWN() and ALIGN() macros.

Suggested-by: Christophe Leroy 
Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/hw_breakpoint.h  |  5 +++--
 arch/powerpc/kernel/hw_breakpoint.c   | 12 ++--
 arch/powerpc/kernel/process.c |  8 
 arch/powerpc/kernel/ptrace/ptrace-noadv.c |  2 +-
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index d472b2eb757e..add5aa076919 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -34,10 +34,11 @@ struct arch_hw_breakpoint {
 #define HW_BRK_TYPE_PRIV_ALL   (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
 HW_BRK_TYPE_HYP)
 
+/* Minimum granularity */
 #ifdef CONFIG_PPC_8xx
-#define HW_BREAKPOINT_ALIGN 0x3
+#define HW_BREAKPOINT_SIZE  0x4
 #else
-#define HW_BREAKPOINT_ALIGN 0x7
+#define HW_BREAKPOINT_SIZE  0x8
 #endif
 
 #define DABR_MAX_LEN   8
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 319a761b7412..02ffd14f4519 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -145,10 +145,10 @@ int arch_bp_generic_fields(int type, int *gen_bp_type)
  *<---8 bytes--->
  *
  * In this case, we should configure hw as:
- *   start_addr = address & ~HW_BREAKPOINT_ALIGN
+ *   start_addr = address & ~(HW_BREAKPOINT_SIZE - 1)
  *   len = 16 bytes
  *
- * @start_addr and @end_addr are inclusive.
+ * @start_addr is inclusive but @end_addr is exclusive.
  */
 static int hw_breakpoint_validate_len(struct arch_hw_breakpoint *hw)
 {
@@ -156,14 +156,14 @@ static int hw_breakpoint_validate_len(struct 
arch_hw_breakpoint *hw)
u16 hw_len;
unsigned long start_addr, end_addr;
 
-   start_addr = hw->address & ~HW_BREAKPOINT_ALIGN;
-   end_addr = (hw->address + hw->len - 1) | HW_BREAKPOINT_ALIGN;
-   hw_len = end_addr - start_addr + 1;
+   start_addr = ALIGN_DOWN(hw->address, HW_BREAKPOINT_SIZE);
+   end_addr = ALIGN(hw->address + hw->len, HW_BREAKPOINT_SIZE);
+   hw_len = end_addr - start_addr;
 
if (dawr_enabled()) {
max_len = DAWR_MAX_LEN;
/* DAWR region can't cross 512 bytes boundary */
-   if ((start_addr >> 9) != (end_addr >> 9))
+   if ((start_addr >> 9) != ((end_addr - 1) >> 9))
return -EINVAL;
} else if (IS_ENABLED(CONFIG_PPC_8xx)) {
/* 8xx can setup a range without limitation */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index aab82ab80dfa..06679adac447 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -800,12 +800,12 @@ static inline int set_breakpoint_8xx(struct 
arch_hw_breakpoint *brk)
unsigned long lctrl1 = LCTRL1_CTE_GT | LCTRL1_CTF_LT | LCTRL1_CRWE_RW |
   LCTRL1_CRWF_RW;
unsigned long lctrl2 = LCTRL2_LW0EN | LCTRL2_LW0LADC | LCTRL2_SLW0EN;
-   unsigned long start_addr = brk->address & ~HW_BREAKPOINT_ALIGN;
-   unsigned long end_addr = (brk->address + brk->len - 1) | 
HW_BREAKPOINT_ALIGN;
+   unsigned long start_addr = ALIGN_DOWN(brk->address, HW_BREAKPOINT_SIZE);
+   unsigned long end_addr = ALIGN(brk->address + brk->len, 
HW_BREAKPOINT_SIZE);
 
if (start_addr == 0)
lctrl2 |= LCTRL2_LW0LA_F;
-   else if (end_addr == ~0U)
+   else if (end_addr - 1 == ~0U)
lctrl2 |= LCTRL2_LW0LA_E;
else
lctrl2 |= LCTRL2_LW0LA_EandF;
@@ -821,7 +821,7 @@ static inline int set_breakpoint_8xx(struct 
arch_hw_breakpoint *brk)
lctrl1 |= LCTRL1_CRWE_WO | LCTRL1_CRWF_WO;
 
mtspr(SPRN_CMPE, start_addr - 1);
-   mtspr(SPRN_CMPF, end_addr + 1);
+   mtspr(SPRN_CMPF, end_addr);
mtspr(SPRN_LCTRL1, lctrl1);
mtspr(SPRN_LCTRL2, lctrl2);
 
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c 
b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 08cb8c1b504c..697c7e4b5877 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -216,7 +216,7 @@ long ppc_set_hwdebug(struct task_struct *child, struct 
ppc_hw_breakpoint *bp_inf
if ((unsigned long)bp_info->addr >= TASK_SIZE)
return -EIO;
 
-   brk.address = bp_info->addr & ~HW_BREAKPOINT_ALIGN;
+   brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
brk.type = HW_BRK_TYPE_TRANSLATE;
brk.len = DABR_MAX_LEN;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
-- 
2.21.1



[PATCH v3 11/16] powerpc/watchpoint: Introduce is_ptrace_bp() function

2020-04-13 Thread Ravi Bangoria
Introduce is_ptrace_bp() function and move the check inside the
function. We will utilize it more in later set of patches.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/kernel/hw_breakpoint.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 772b2c953220..319a761b7412 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -90,6 +90,11 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
hw_breakpoint_disable();
 }
 
+static bool is_ptrace_bp(struct perf_event *bp)
+{
+   return bp->overflow_handler == ptrace_triggered;
+}
+
 /*
  * Perform cleanup of arch-specific counters during unregistration
  * of the perf-event
@@ -324,7 +329,7 @@ int hw_breakpoint_handler(struct die_args *args)
 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
 * generated in do_dabr().
 */
-   if (bp->overflow_handler == ptrace_triggered) {
+   if (is_ptrace_bp(bp)) {
perf_bp_event(bp, regs);
rc = NOTIFY_DONE;
goto out;
-- 
2.21.1



[PATCH v3 10/16] powerpc/watchpoint: Use loop for thread_struct->ptrace_bps

2020-04-13 Thread Ravi Bangoria
ptrace_bps is already an array of size HBP_NUM_MAX. But we use
hardcoded index 0 while fetching/updating it. Convert such code
to loop over array.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/kernel/hw_breakpoint.c   |  7 --
 arch/powerpc/kernel/process.c |  6 -
 arch/powerpc/kernel/ptrace/ptrace-noadv.c | 28 +--
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 5826f1f2cab9..772b2c953220 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -419,10 +419,13 @@ NOKPROBE_SYMBOL(hw_breakpoint_exceptions_notify);
  */
 void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
 {
+   int i;
struct thread_struct *t = >thread;
 
-   unregister_hw_breakpoint(t->ptrace_bps[0]);
-   t->ptrace_bps[0] = NULL;
+   for (i = 0; i < nr_wp_slots(); i++) {
+   unregister_hw_breakpoint(t->ptrace_bps[i]);
+   t->ptrace_bps[i] = NULL;
+   }
 }
 
 void hw_breakpoint_pmu_read(struct perf_event *bp)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 5ad23ac2c9d9..aab82ab80dfa 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1624,6 +1624,9 @@ int copy_thread_tls(unsigned long clone_flags, unsigned 
long usp,
void (*f)(void);
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
struct thread_info *ti = task_thread_info(p);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+   int i;
+#endif
 
klp_init_thread_info(p);
 
@@ -1683,7 +1686,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned 
long usp,
p->thread.ksp_limit = (unsigned long)end_of_stack(p);
 #endif
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-   p->thread.ptrace_bps[0] = NULL;
+   for (i = 0; i < nr_wp_slots(); i++)
+   p->thread.ptrace_bps[i] = NULL;
 #endif
 
p->thread.fp_save_area = NULL;
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c 
b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 0dbb35392dd2..08cb8c1b504c 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -168,6 +168,19 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned 
long addr, unsigned l
return 0;
 }
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+static int find_empty_ptrace_bp(struct thread_struct *thread)
+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (!thread->ptrace_bps[i])
+   return i;
+   }
+   return -1;
+}
+#endif
+
 static int find_empty_hw_brk(struct thread_struct *thread)
 {
int i;
@@ -217,8 +230,9 @@ long ppc_set_hwdebug(struct task_struct *child, struct 
ppc_hw_breakpoint *bp_inf
len = 1;
else
return -EINVAL;
-   bp = thread->ptrace_bps[0];
-   if (bp)
+
+   i = find_empty_ptrace_bp(thread);
+   if (i < 0)
return -ENOSPC;
 
/* Create a new breakpoint request if one doesn't exist already */
@@ -228,13 +242,13 @@ long ppc_set_hwdebug(struct task_struct *child, struct 
ppc_hw_breakpoint *bp_inf
arch_bp_generic_fields(brk.type, _type);
 
bp = register_user_hw_breakpoint(, ptrace_triggered, NULL, child);
-   thread->ptrace_bps[0] = bp;
+   thread->ptrace_bps[i] = bp;
if (IS_ERR(bp)) {
-   thread->ptrace_bps[0] = NULL;
+   thread->ptrace_bps[i] = NULL;
return PTR_ERR(bp);
}
 
-   return 1;
+   return i + 1;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
@@ -263,10 +277,10 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
return -EINVAL;
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-   bp = thread->ptrace_bps[0];
+   bp = thread->ptrace_bps[data - 1];
if (bp) {
unregister_hw_breakpoint(bp);
-   thread->ptrace_bps[0] = NULL;
+   thread->ptrace_bps[data - 1] = NULL;
} else {
ret = -ENOENT;
}
-- 
2.21.1



[PATCH v3 09/16] powerpc/watchpoint: Convert thread_struct->hw_brk to an array

2020-04-13 Thread Ravi Bangoria
So far powerpc hw supported only one watchpoint. But Future Power
architecture is introducing 2nd DAWR. Convert thread_struct->hw_brk
into an array.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/processor.h  |  2 +-
 arch/powerpc/kernel/process.c | 60 ++-
 arch/powerpc/kernel/ptrace/ptrace-noadv.c | 40 ++-
 arch/powerpc/kernel/ptrace/ptrace32.c |  4 +-
 arch/powerpc/kernel/signal.c  | 12 +++--
 5 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 90f6dbc7ff00..65b03162cd67 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -187,7 +187,7 @@ struct thread_struct {
 */
struct perf_event *last_hit_ubp;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
-   struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
+   struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint 
info */
unsigned long   trap_nr;/* last trap # on this thread */
u8 load_slb;/* Ages out SLB preload cache entries */
u8 load_fp;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1d9d382517ae..5ad23ac2c9d9 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -711,21 +711,49 @@ void switch_booke_debug_regs(struct debug_reg *new_debug)
 EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
 #else  /* !CONFIG_PPC_ADV_DEBUG_REGS */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
-static void set_breakpoint(struct arch_hw_breakpoint *brk)
+static void set_breakpoint(int i, struct arch_hw_breakpoint *brk)
 {
preempt_disable();
-   __set_breakpoint(0, brk);
+   __set_breakpoint(i, brk);
preempt_enable();
 }
 
 static void set_debug_reg_defaults(struct thread_struct *thread)
 {
-   thread->hw_brk.address = 0;
-   thread->hw_brk.type = 0;
-   thread->hw_brk.len = 0;
-   thread->hw_brk.hw_len = 0;
-   if (ppc_breakpoint_available())
-   set_breakpoint(>hw_brk);
+   int i;
+   struct arch_hw_breakpoint null_brk = {0};
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   thread->hw_brk[i] = null_brk;
+   if (ppc_breakpoint_available())
+   set_breakpoint(i, >hw_brk[i]);
+   }
+}
+
+static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
+   struct arch_hw_breakpoint *b)
+{
+   if (a->address != b->address)
+   return false;
+   if (a->type != b->type)
+   return false;
+   if (a->len != b->len)
+   return false;
+   /* no need to check hw_len. it's calculated from address and len */
+   return true;
+}
+
+static void switch_hw_breakpoint(struct task_struct *new)
+{
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++) {
+   if (likely(hw_brk_match(this_cpu_ptr(_brk[i]),
+   >thread.hw_brk[i])))
+   continue;
+
+   __set_breakpoint(i, >thread.hw_brk[i]);
+   }
 }
 #endif /* !CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -829,19 +857,6 @@ bool ppc_breakpoint_available(void)
 }
 EXPORT_SYMBOL_GPL(ppc_breakpoint_available);
 
-static inline bool hw_brk_match(struct arch_hw_breakpoint *a,
- struct arch_hw_breakpoint *b)
-{
-   if (a->address != b->address)
-   return false;
-   if (a->type != b->type)
-   return false;
-   if (a->len != b->len)
-   return false;
-   /* no need to check hw_len. it's calculated from address and len */
-   return true;
-}
-
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 
 static inline bool tm_enabled(struct task_struct *tsk)
@@ -1174,8 +1189,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
  * schedule DABR
  */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
-   if (unlikely(!hw_brk_match(this_cpu_ptr(_brk[0]), 
>thread.hw_brk)))
-   __set_breakpoint(0, >thread.hw_brk);
+   switch_hw_breakpoint(new);
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c 
b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 12962302d6a4..0dbb35392dd2 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -67,11 +67,16 @@ int ptrace_get_debugreg(struct task_struct *child, unsigned 
long addr,
/* We only support one DABR and no IABRS at the moment */
if (addr > 0)
return -EINVAL;
-   dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
-(child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
+   dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
+(child->thread.hw_brk[0].type & 

[PATCH v3 08/16] powerpc/watchpoint: Disable all available watchpoints when !dawr_force_enable

2020-04-13 Thread Ravi Bangoria
Instead of disabling only first watchpoint, disable all available
watchpoints while clearing dawr_force_enable.

Callback function is used only for disabling watchpoint, rename it
to disable_dawrs_cb(). And null_brk parameter is not really required
while disabling watchpoint, remove it.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/kernel/dawr.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c
index 8114ad3a8574..7f8c69ab537a 100644
--- a/arch/powerpc/kernel/dawr.c
+++ b/arch/powerpc/kernel/dawr.c
@@ -50,9 +50,13 @@ int set_dawr(int nr, struct arch_hw_breakpoint *brk)
return 0;
 }
 
-static void set_dawr_cb(void *info)
+static void disable_dawrs_cb(void *info)
 {
-   set_dawr(0, info);
+   struct arch_hw_breakpoint null_brk = {0};
+   int i;
+
+   for (i = 0; i < nr_wp_slots(); i++)
+   set_dawr(i, _brk);
 }
 
 static ssize_t dawr_write_file_bool(struct file *file,
@@ -74,7 +78,7 @@ static ssize_t dawr_write_file_bool(struct file *file,
 
/* If we are clearing, make sure all CPUs have the DAWR cleared */
if (!dawr_force_enable)
-   smp_call_function(set_dawr_cb, _brk, 0);
+   smp_call_function(disable_dawrs_cb, NULL, 0);
 
return rc;
 }
-- 
2.21.1



[PATCH v3 07/16] powerpc/watchpoint: Get watchpoint count dynamically while disabling them

2020-04-13 Thread Ravi Bangoria
Instead of disabling only one watchpoint, get num of available
watchpoints dynamically and disable all of them.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/hw_breakpoint.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index 1120c7d9db58..d472b2eb757e 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -78,14 +78,14 @@ extern void ptrace_triggered(struct perf_event *bp,
struct perf_sample_data *data, struct pt_regs *regs);
 static inline void hw_breakpoint_disable(void)
 {
-   struct arch_hw_breakpoint brk;
-
-   brk.address = 0;
-   brk.type = 0;
-   brk.len = 0;
-   brk.hw_len = 0;
-   if (ppc_breakpoint_available())
-   __set_breakpoint(0, );
+   int i;
+   struct arch_hw_breakpoint null_brk = {0};
+
+   if (!ppc_breakpoint_available())
+   return;
+
+   for (i = 0; i < nr_wp_slots(); i++)
+   __set_breakpoint(i, _brk);
 }
 extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 int hw_breakpoint_handler(struct die_args *args);
-- 
2.21.1



[PATCH v3 06/16] powerpc/watchpoint: Provide DAWR number to __set_breakpoint

2020-04-13 Thread Ravi Bangoria
Introduce new parameter 'nr' to __set_breakpoint() which indicates
which DAWR should be programed. Also convert current_brk variable
to an array.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/debug.h |  2 +-
 arch/powerpc/include/asm/hw_breakpoint.h |  2 +-
 arch/powerpc/kernel/hw_breakpoint.c  |  8 
 arch/powerpc/kernel/process.c| 14 +++---
 arch/powerpc/kernel/signal.c |  2 +-
 arch/powerpc/xmon/xmon.c |  2 +-
 6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
index 7756026b95ca..ec57daf87f40 100644
--- a/arch/powerpc/include/asm/debug.h
+++ b/arch/powerpc/include/asm/debug.h
@@ -45,7 +45,7 @@ static inline int debugger_break_match(struct pt_regs *regs) 
{ return 0; }
 static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
 #endif
 
-void __set_breakpoint(struct arch_hw_breakpoint *brk);
+void __set_breakpoint(int nr, struct arch_hw_breakpoint *brk);
 bool ppc_breakpoint_available(void);
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 extern void do_send_trap(struct pt_regs *regs, unsigned long address,
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index 5b3b02834e0b..1120c7d9db58 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -85,7 +85,7 @@ static inline void hw_breakpoint_disable(void)
brk.len = 0;
brk.hw_len = 0;
if (ppc_breakpoint_available())
-   __set_breakpoint();
+   __set_breakpoint(0, );
 }
 extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
 int hw_breakpoint_handler(struct die_args *args);
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 4120349e2abe..5826f1f2cab9 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -63,7 +63,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
 * If so, DABR will be populated in single_step_dabr_instruction().
 */
if (current->thread.last_hit_ubp != bp)
-   __set_breakpoint(info);
+   __set_breakpoint(0, info);
 
return 0;
 }
@@ -221,7 +221,7 @@ void thread_change_pc(struct task_struct *tsk, struct 
pt_regs *regs)
 
info = counter_arch_bp(tsk->thread.last_hit_ubp);
regs->msr &= ~MSR_SE;
-   __set_breakpoint(info);
+   __set_breakpoint(0, info);
tsk->thread.last_hit_ubp = NULL;
 }
 
@@ -346,7 +346,7 @@ int hw_breakpoint_handler(struct die_args *args)
if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
perf_bp_event(bp, regs);
 
-   __set_breakpoint(info);
+   __set_breakpoint(0, info);
 out:
rcu_read_unlock();
return rc;
@@ -379,7 +379,7 @@ static int single_step_dabr_instruction(struct die_args 
*args)
if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
perf_bp_event(bp, regs);
 
-   __set_breakpoint(info);
+   __set_breakpoint(0, info);
current->thread.last_hit_ubp = NULL;
 
/*
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 14aba1295b10..1d9d382517ae 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -637,7 +637,7 @@ void do_break (struct pt_regs *regs, unsigned long address,
 }
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
-static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk);
+static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk[HBP_NUM_MAX]);
 
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 /*
@@ -714,7 +714,7 @@ EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
 static void set_breakpoint(struct arch_hw_breakpoint *brk)
 {
preempt_disable();
-   __set_breakpoint(brk);
+   __set_breakpoint(0, brk);
preempt_enable();
 }
 
@@ -800,13 +800,13 @@ static inline int set_breakpoint_8xx(struct 
arch_hw_breakpoint *brk)
return 0;
 }
 
-void __set_breakpoint(struct arch_hw_breakpoint *brk)
+void __set_breakpoint(int nr, struct arch_hw_breakpoint *brk)
 {
-   memcpy(this_cpu_ptr(_brk), brk, sizeof(*brk));
+   memcpy(this_cpu_ptr(_brk[nr]), brk, sizeof(*brk));
 
if (dawr_enabled())
// Power8 or later
-   set_dawr(0, brk);
+   set_dawr(nr, brk);
else if (IS_ENABLED(CONFIG_PPC_8xx))
set_breakpoint_8xx(brk);
else if (!cpu_has_feature(CPU_FTR_ARCH_207S))
@@ -1174,8 +1174,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
  * schedule DABR
  */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
-   if (unlikely(!hw_brk_match(this_cpu_ptr(_brk), 
>thread.hw_brk)))
-   __set_breakpoint(>thread.hw_brk);
+   if (unlikely(!hw_brk_match(this_cpu_ptr(_brk[0]), 
>thread.hw_brk)))
+   __set_breakpoint(0, >thread.hw_brk);
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 

[PATCH v3 05/16] powerpc/watchpoint: Provide DAWR number to set_dawr

2020-04-13 Thread Ravi Bangoria
Introduce new parameter 'nr' to set_dawr() which indicates which DAWR
should be programed.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/hw_breakpoint.h |  4 ++--
 arch/powerpc/kernel/dawr.c   | 15 ++-
 arch/powerpc/kernel/process.c|  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index 518b41eef924..5b3b02834e0b 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -104,10 +104,10 @@ static inline bool dawr_enabled(void)
 {
return dawr_force_enable;
 }
-int set_dawr(struct arch_hw_breakpoint *brk);
+int set_dawr(int nr, struct arch_hw_breakpoint *brk);
 #else
 static inline bool dawr_enabled(void) { return false; }
-static inline int set_dawr(struct arch_hw_breakpoint *brk) { return -1; }
+static inline int set_dawr(int nr, struct arch_hw_breakpoint *brk) { return 
-1; }
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c
index e91b613bf137..8114ad3a8574 100644
--- a/arch/powerpc/kernel/dawr.c
+++ b/arch/powerpc/kernel/dawr.c
@@ -16,7 +16,7 @@
 bool dawr_force_enable;
 EXPORT_SYMBOL_GPL(dawr_force_enable);
 
-int set_dawr(struct arch_hw_breakpoint *brk)
+int set_dawr(int nr, struct arch_hw_breakpoint *brk)
 {
unsigned long dawr, dawrx, mrd;
 
@@ -39,15 +39,20 @@ int set_dawr(struct arch_hw_breakpoint *brk)
if (ppc_md.set_dawr)
return ppc_md.set_dawr(dawr, dawrx);
 
-   mtspr(SPRN_DAWR0, dawr);
-   mtspr(SPRN_DAWRX0, dawrx);
+   if (nr == 0) {
+   mtspr(SPRN_DAWR0, dawr);
+   mtspr(SPRN_DAWRX0, dawrx);
+   } else {
+   mtspr(SPRN_DAWR1, dawr);
+   mtspr(SPRN_DAWRX1, dawrx);
+   }
 
return 0;
 }
 
 static void set_dawr_cb(void *info)
 {
-   set_dawr(info);
+   set_dawr(0, info);
 }
 
 static ssize_t dawr_write_file_bool(struct file *file,
@@ -60,7 +65,7 @@ static ssize_t dawr_write_file_bool(struct file *file,
/* Send error to user if they hypervisor won't allow us to write DAWR */
if (!dawr_force_enable &&
firmware_has_feature(FW_FEATURE_LPAR) &&
-   set_dawr(_brk) != H_SUCCESS)
+   set_dawr(0, _brk) != H_SUCCESS)
return -ENODEV;
 
rc = debugfs_write_file_bool(file, user_buf, count, ppos);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 9c21288f8645..14aba1295b10 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -806,7 +806,7 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk)
 
if (dawr_enabled())
// Power8 or later
-   set_dawr(brk);
+   set_dawr(0, brk);
else if (IS_ENABLED(CONFIG_PPC_8xx))
set_breakpoint_8xx(brk);
else if (!cpu_has_feature(CPU_FTR_ARCH_207S))
-- 
2.21.1



[PATCH v3 04/16] powerpc/watchpoint/ptrace: Return actual num of available watchpoints

2020-04-13 Thread Ravi Bangoria
User can ask for num of available watchpoints(dbginfo.num_data_bps)
using ptrace(PPC_PTRACE_GETHWDBGINFO). Return actual number of
available watchpoints on the machine rather than hardcoded 1.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/kernel/ptrace/ptrace-noadv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c 
b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index f87e7c5c3bf3..12962302d6a4 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -44,7 +44,7 @@ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo)
dbginfo->version = 1;
dbginfo->num_instruction_bps = 0;
if (ppc_breakpoint_available())
-   dbginfo->num_data_bps = 1;
+   dbginfo->num_data_bps = nr_wp_slots();
else
dbginfo->num_data_bps = 0;
dbginfo->num_condition_regs = 0;
-- 
2.21.1



[PATCH v3 03/16] powerpc/watchpoint: Introduce function to get nr watchpoints dynamically

2020-04-13 Thread Ravi Bangoria
So far we had only one watchpoint, so we have hardcoded HBP_NUM to 1.
But future Power architecture is introducing 2nd DAWR and thus kernel
should be able to dynamically find actual number of watchpoints
supported by hw it's running on. Introduce function for the same.
Also convert HBP_NUM macro to HBP_NUM_MAX, which will now represent
maximum number of watchpoints supported by Powerpc.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/cputable.h  | 6 +-
 arch/powerpc/include/asm/hw_breakpoint.h | 5 +
 arch/powerpc/include/asm/processor.h | 2 +-
 arch/powerpc/kernel/hw_breakpoint.c  | 2 +-
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index 40a4d3c6fd99..c67b94f3334c 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -614,7 +614,11 @@ enum {
 };
 #endif /* __powerpc64__ */
 
-#define HBP_NUM 1
+/*
+ * Maximum number of hw breakpoint supported on powerpc. Number of
+ * breakpoints supported by actual hw might be less than this.
+ */
+#define HBP_NUM_MAX1
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h 
b/arch/powerpc/include/asm/hw_breakpoint.h
index f2f8d8aa8e3b..518b41eef924 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -43,6 +43,11 @@ struct arch_hw_breakpoint {
 #define DABR_MAX_LEN   8
 #define DAWR_MAX_LEN   512
 
+static inline int nr_wp_slots(void)
+{
+   return HBP_NUM_MAX;
+}
+
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 #include 
 #include 
diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index eedcbfb9a6ff..90f6dbc7ff00 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -180,7 +180,7 @@ struct thread_struct {
int fpexc_mode; /* floating-point exception mode */
unsigned intalign_ctl;  /* alignment handling control */
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-   struct perf_event *ptrace_bps[HBP_NUM];
+   struct perf_event *ptrace_bps[HBP_NUM_MAX];
/*
 * Helps identify source of single-step exception and subsequent
 * hw-breakpoint enablement
diff --git a/arch/powerpc/kernel/hw_breakpoint.c 
b/arch/powerpc/kernel/hw_breakpoint.c
index 72f461bd70fb..4120349e2abe 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -38,7 +38,7 @@ static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
 int hw_breakpoint_slots(int type)
 {
if (type == TYPE_DATA)
-   return HBP_NUM;
+   return nr_wp_slots();
return 0;   /* no instruction breakpoints available */
 }
 
-- 
2.21.1



[PATCH v3 02/16] powerpc/watchpoint: Add SPRN macros for second DAWR

2020-04-13 Thread Ravi Bangoria
Future Power architecture is introducing second DAWR. Add SPRN_ macros
for the same.

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/reg.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 156ee89fa9be..062e74cf41fd 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -284,6 +284,7 @@
 #define   CTRL_TE  0x00c0  /* thread enable */
 #define   CTRL_RUNLATCH0x1
 #define SPRN_DAWR0 0xB4
+#define SPRN_DAWR1 0xB5
 #define SPRN_RPR   0xBA/* Relative Priority Register */
 #define SPRN_CIABR 0xBB
 #define   CIABR_PRIV   0x3
@@ -291,6 +292,7 @@
 #define   CIABR_PRIV_SUPER 2
 #define   CIABR_PRIV_HYPER 3
 #define SPRN_DAWRX00xBC
+#define SPRN_DAWRX10xBD
 #define   DAWRX_USER   __MASK(0)
 #define   DAWRX_KERNEL __MASK(1)
 #define   DAWRX_HYP__MASK(2)
-- 
2.21.1



[PATCH v3 01/16] powerpc/watchpoint: Rename current DAWR macros

2020-04-13 Thread Ravi Bangoria
Future Power architecture is introducing second DAWR. Use real
register names from ISA for current macros:
  s/SPRN_DAWR/SPRN_DAWR0/
  s/SPRN_DAWRX/SPRN_DAWRX0/

Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/include/asm/reg.h  |  4 ++--
 arch/powerpc/kernel/dawr.c  |  4 ++--
 arch/powerpc/kvm/book3s_hv.c| 12 ++--
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 18 +-
 arch/powerpc/xmon/xmon.c|  2 +-
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index da5cab038e25..156ee89fa9be 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -283,14 +283,14 @@
 #define   CTRL_CT1 0x4000  /* thread 1 */
 #define   CTRL_TE  0x00c0  /* thread enable */
 #define   CTRL_RUNLATCH0x1
-#define SPRN_DAWR  0xB4
+#define SPRN_DAWR0 0xB4
 #define SPRN_RPR   0xBA/* Relative Priority Register */
 #define SPRN_CIABR 0xBB
 #define   CIABR_PRIV   0x3
 #define   CIABR_PRIV_USER  1
 #define   CIABR_PRIV_SUPER 2
 #define   CIABR_PRIV_HYPER 3
-#define SPRN_DAWRX 0xBC
+#define SPRN_DAWRX00xBC
 #define   DAWRX_USER   __MASK(0)
 #define   DAWRX_KERNEL __MASK(1)
 #define   DAWRX_HYP__MASK(2)
diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c
index cc14aa6c4a1b..e91b613bf137 100644
--- a/arch/powerpc/kernel/dawr.c
+++ b/arch/powerpc/kernel/dawr.c
@@ -39,8 +39,8 @@ int set_dawr(struct arch_hw_breakpoint *brk)
if (ppc_md.set_dawr)
return ppc_md.set_dawr(dawr, dawrx);
 
-   mtspr(SPRN_DAWR, dawr);
-   mtspr(SPRN_DAWRX, dawrx);
+   mtspr(SPRN_DAWR0, dawr);
+   mtspr(SPRN_DAWRX0, dawrx);
 
return 0;
 }
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 33be4d93248a..498c57e1f5c9 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3383,8 +3383,8 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu 
*vcpu, u64 time_limit,
int trap;
unsigned long host_hfscr = mfspr(SPRN_HFSCR);
unsigned long host_ciabr = mfspr(SPRN_CIABR);
-   unsigned long host_dawr = mfspr(SPRN_DAWR);
-   unsigned long host_dawrx = mfspr(SPRN_DAWRX);
+   unsigned long host_dawr = mfspr(SPRN_DAWR0);
+   unsigned long host_dawrx = mfspr(SPRN_DAWRX0);
unsigned long host_psscr = mfspr(SPRN_PSSCR);
unsigned long host_pidr = mfspr(SPRN_PID);
 
@@ -3413,8 +3413,8 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu 
*vcpu, u64 time_limit,
mtspr(SPRN_SPURR, vcpu->arch.spurr);
 
if (dawr_enabled()) {
-   mtspr(SPRN_DAWR, vcpu->arch.dawr);
-   mtspr(SPRN_DAWRX, vcpu->arch.dawrx);
+   mtspr(SPRN_DAWR0, vcpu->arch.dawr);
+   mtspr(SPRN_DAWRX0, vcpu->arch.dawrx);
}
mtspr(SPRN_CIABR, vcpu->arch.ciabr);
mtspr(SPRN_IC, vcpu->arch.ic);
@@ -3466,8 +3466,8 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu 
*vcpu, u64 time_limit,
  (local_paca->kvm_hstate.fake_suspend << PSSCR_FAKE_SUSPEND_LG));
mtspr(SPRN_HFSCR, host_hfscr);
mtspr(SPRN_CIABR, host_ciabr);
-   mtspr(SPRN_DAWR, host_dawr);
-   mtspr(SPRN_DAWRX, host_dawrx);
+   mtspr(SPRN_DAWR0, host_dawr);
+   mtspr(SPRN_DAWRX0, host_dawrx);
mtspr(SPRN_PID, host_pidr);
 
/*
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 780a499c7114..70de3325d0e9 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -707,8 +707,8 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 BEGIN_FTR_SECTION
mfspr   r5, SPRN_CIABR
-   mfspr   r6, SPRN_DAWR
-   mfspr   r7, SPRN_DAWRX
+   mfspr   r6, SPRN_DAWR0
+   mfspr   r7, SPRN_DAWRX0
mfspr   r8, SPRN_IAMR
std r5, STACK_SLOT_CIABR(r1)
std r6, STACK_SLOT_DAWR(r1)
@@ -803,8 +803,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
beq 1f
ld  r5, VCPU_DAWR(r4)
ld  r6, VCPU_DAWRX(r4)
-   mtspr   SPRN_DAWR, r5
-   mtspr   SPRN_DAWRX, r6
+   mtspr   SPRN_DAWR0, r5
+   mtspr   SPRN_DAWRX0, r6
 1:
ld  r7, VCPU_CIABR(r4)
ld  r8, VCPU_TAR(r4)
@@ -1766,8 +1766,8 @@ BEGIN_FTR_SECTION
 * If the DAWR doesn't work, it's ok to write these here as
 * this value should always be zero
*/
-   mtspr   SPRN_DAWR, r6
-   mtspr   SPRN_DAWRX, r7
+   mtspr   SPRN_DAWR0, r6
+   mtspr   SPRN_DAWRX0, r7
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 BEGIN_FTR_SECTION
ld  r5, STACK_SLOT_TID(r1)
@@ -2577,8 +2577,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mfmsr   r6
andi.   r6, r6, MSR_DR  /* in real mode? */
bne 4f
-   mtspr   SPRN_DAWR, 

[PATCH v3 00/16] powerpc/watchpoint: Preparation for more than one watchpoint

2020-04-13 Thread Ravi Bangoria
So far, powerpc Book3S code has been written with an assumption of only
one watchpoint. But future power architecture is introducing second
watchpoint register (DAWR). Even though this patchset does not enable
2nd DAWR, it make the infrastructure ready so that enabling 2nd DAWR
should just be a matter of changing count.

Existing functionality works fine with the patchset. I've tested it with
perf, ptrace(gdb), xmon. All hw-breakpoint selftests are passing as well.
And I've build tested for 8xx and 'AMCC 44x, 46x or 47x'.

Note: kvm or PowerVM guest is not enabled yet.

v2:
  
https://lore.kernel.org/linuxppc-dev/20200401061309.92442-1-ravi.bango...@linux.ibm.com

v2->v3:
 - Few minor improvements as suggested by Christophe
 - Rebased to powerpc/next

Ravi Bangoria (16):
  powerpc/watchpoint: Rename current DAWR macros
  powerpc/watchpoint: Add SPRN macros for second DAWR
  powerpc/watchpoint: Introduce function to get nr watchpoints
dynamically
  powerpc/watchpoint/ptrace: Return actual num of available watchpoints
  powerpc/watchpoint: Provide DAWR number to set_dawr
  powerpc/watchpoint: Provide DAWR number to __set_breakpoint
  powerpc/watchpoint: Get watchpoint count dynamically while disabling
them
  powerpc/watchpoint: Disable all available watchpoints when
!dawr_force_enable
  powerpc/watchpoint: Convert thread_struct->hw_brk to an array
  powerpc/watchpoint: Use loop for thread_struct->ptrace_bps
  powerpc/watchpoint: Introduce is_ptrace_bp() function
  powerpc/watchpoint: Use builtin ALIGN*() macros
  powerpc/watchpoint: Prepare handler to handle more than one
watcnhpoint
  powerpc/watchpoint: Don't allow concurrent perf and ptrace events
  powerpc/watchpoint/xmon: Don't allow breakpoint overwriting
  powerpc/watchpoint/xmon: Support 2nd dawr

 arch/powerpc/include/asm/cputable.h   |   6 +-
 arch/powerpc/include/asm/debug.h  |   2 +-
 arch/powerpc/include/asm/hw_breakpoint.h  |  32 +-
 arch/powerpc/include/asm/processor.h  |   6 +-
 arch/powerpc/include/asm/reg.h|   6 +-
 arch/powerpc/include/asm/sstep.h  |   2 +
 arch/powerpc/kernel/dawr.c|  23 +-
 arch/powerpc/kernel/hw_breakpoint.c   | 646 ++
 arch/powerpc/kernel/process.c |  85 +--
 arch/powerpc/kernel/ptrace/ptrace-noadv.c |  72 ++-
 arch/powerpc/kernel/ptrace/ptrace32.c |   4 +-
 arch/powerpc/kernel/signal.c  |  12 +-
 arch/powerpc/kvm/book3s_hv.c  |  12 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  18 +-
 arch/powerpc/xmon/xmon.c  |  99 +++-
 kernel/events/hw_breakpoint.c |  16 +
 16 files changed, 814 insertions(+), 227 deletions(-)

-- 
2.21.1



Re: [PATCH v7 5/7] ASoC: fsl_asrc: Move common definition to fsl_asrc_common

2020-04-13 Thread Nicolin Chen
On Tue, Apr 14, 2020 at 08:43:07AM +0800, Shengjiu Wang wrote:
> There is a new ASRC included in i.MX serial platform, there
> are some common definition can be shared with each other.
> So move the common definition to a separate header file.
> 
> And add fsl_asrc_pair_priv and fsl_asrc_priv for
> the variable specific for the module, which can be used
> internally.
> 
> Signed-off-by: Shengjiu Wang 

> diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> +static size_t fsl_asrc_get_pair_priv_size(void)
> +{
> + return sizeof(struct fsl_asrc_pair_priv);
> +}

Perhaps we haven't understood completely each other's point.

Yet, would the following change work?

> diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
> new file mode 100644
> index ..b15244e027d0
> --- /dev/null
> +++ b/sound/soc/fsl/fsl_asrc_common.h
> +struct fsl_asrc {
> + size_t (*get_pair_priv_size)(void);

+   size_t pair_priv_size;

> diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> @@ -992,25 +1012,32 @@ static int fsl_asrc_probe(struct platform_device *pdev)
> + asrc->get_pair_priv_size = fsl_asrc_get_pair_priv_size;

+   asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv);

> diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
> @@ -311,11 +311,12 @@ static int fsl_asrc_dma_startup(struct 
> snd_soc_component *component,
>   return ret;
>   }
>  
> - pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL);
> + pair = kzalloc(sizeof(*pair) + asrc->get_pair_priv_size(), GFP_KERNEL);

+   pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL);


Re: [PATCH v7 5/7] ASoC: fsl_asrc: Move common definition to fsl_asrc_common

2020-04-13 Thread Nicolin Chen
On Tue, Apr 14, 2020 at 10:21:29AM +0800, Shengjiu Wang wrote:
> On Tue, Apr 14, 2020 at 10:09 AM Nicolin Chen  wrote:
> >
> > On Tue, Apr 14, 2020 at 08:43:07AM +0800, Shengjiu Wang wrote:
> > > There is a new ASRC included in i.MX serial platform, there
> > > are some common definition can be shared with each other.
> > > So move the common definition to a separate header file.
> > >
> > > And add fsl_asrc_pair_priv and fsl_asrc_priv for
> > > the variable specific for the module, which can be used
> > > internally.
> > >
> > > Signed-off-by: Shengjiu Wang 
> >
> > > diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> > > +static size_t fsl_asrc_get_pair_priv_size(void)
> > > +{
> > > + return sizeof(struct fsl_asrc_pair_priv);
> > > +}
> >
> > Perhaps we haven't understood completely each other's point.
> >
> > Yet, would the following change work?
> 
> Should work, almost same

Function call involving branch instruction may fail CPU's branch
prediction and hurt performance, depending on the CPU arch. If a
variable simply does the job, we should avoid doing that.

> or do you want me to use variable to replace function pointer?

Yes. And please add my ack once you change it as the reset LGTM:

Acked-by: Nicolin Chen 


[PATCH] vhost: do not enable VHOST_MENU by default

2020-04-13 Thread Jason Wang
We try to keep the defconfig untouched after decoupling CONFIG_VHOST
out of CONFIG_VIRTUALIZATION in commit 20c384f1ea1a
("vhost: refine vhost and vringh kconfig") by enabling VHOST_MENU by
default. Then the defconfigs can keep enabling CONFIG_VHOST_NET
without the caring of CONFIG_VHOST.

But this will leave a "CONFIG_VHOST_MENU=y" in all defconfigs and even
for the ones that doesn't want vhost. So it actually shifts the
burdens to the maintainers of all other to add "CONFIG_VHOST_MENU is
not set". So this patch tries to enable CONFIG_VHOST explicitly in
defconfigs that enables CONFIG_VHOST_NET and CONFIG_VHOST_VSOCK.

Cc: Thomas Bogendoerfer 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Heiko Carstens 
Cc: Vasily Gorbik 
Cc: Christian Borntraeger 
Reported-by: Geert Uytterhoeven 
Signed-off-by: Jason Wang 
---
 arch/mips/configs/malta_kvm_defconfig  |  1 +
 arch/powerpc/configs/powernv_defconfig |  1 +
 arch/powerpc/configs/ppc64_defconfig   |  1 +
 arch/powerpc/configs/pseries_defconfig |  1 +
 arch/s390/configs/debug_defconfig  |  1 +
 arch/s390/configs/defconfig|  1 +
 drivers/vhost/Kconfig  | 18 +-
 7 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/arch/mips/configs/malta_kvm_defconfig 
b/arch/mips/configs/malta_kvm_defconfig
index 8ef612552a19..06f0c7a0ca87 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -18,6 +18,7 @@ CONFIG_PCI=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
 CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS=y
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
diff --git a/arch/powerpc/configs/powernv_defconfig 
b/arch/powerpc/configs/powernv_defconfig
index 71749377d164..404245b4594d 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -346,5 +346,6 @@ CONFIG_CRYPTO_DEV_VMX=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_PRINTK_TIME=y
diff --git a/arch/powerpc/configs/ppc64_defconfig 
b/arch/powerpc/configs/ppc64_defconfig
index 7e68cb222c7b..4599fc7be285 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -61,6 +61,7 @@ CONFIG_ELECTRA_CF=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_OPROFILE=m
 CONFIG_KPROBES=y
diff --git a/arch/powerpc/configs/pseries_defconfig 
b/arch/powerpc/configs/pseries_defconfig
index 6b68109e248f..4cad3901b5de 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -321,5 +321,6 @@ CONFIG_CRYPTO_DEV_VMX=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=m
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_PRINTK_TIME=y
diff --git a/arch/s390/configs/debug_defconfig 
b/arch/s390/configs/debug_defconfig
index 0c86ba19fa2b..6ec6e69630d1 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -57,6 +57,7 @@ CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
 CONFIG_CMM=m
 CONFIG_APPLDATA_BASE=y
 CONFIG_KVM=m
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_VHOST_VSOCK=m
 CONFIG_OPROFILE=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 6b27d861a9a3..d1b3bf83d687 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -57,6 +57,7 @@ CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y
 CONFIG_CMM=m
 CONFIG_APPLDATA_BASE=y
 CONFIG_KVM=m
+CONFIG_VHOST=m
 CONFIG_VHOST_NET=m
 CONFIG_VHOST_VSOCK=m
 CONFIG_OPROFILE=m
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index e79cbbdfea45..14d296dc18cd 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -12,23 +12,18 @@ config VHOST_RING
  This option is selected by any driver which needs to access
  the host side of a virtio ring.
 
-config VHOST
-   tristate
+menuconfig VHOST
+   tristate "Vhost Devices"
select VHOST_IOTLB
help
- This option is selected by any driver which needs to access
- the core of vhost.
-
-menuconfig VHOST_MENU
-   bool "VHOST drivers"
-   default y
+ Enable option to support host kernel or hardware accelerator
+ for virtio device.
 
-if VHOST_MENU
+if VHOST
 
 config VHOST_NET
tristate "Host kernel accelerator for virtio net"
depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)
-   select VHOST
---help---
  This kernel module can be loaded in host kernel to accelerate
  guest networking with virtio_net. Not to be confused with virtio_net
@@ -40,7 +35,6 @@ config VHOST_NET
 config VHOST_SCSI
tristate "VHOST_SCSI TCM fabric driver"
depends on TARGET_CORE && EVENTFD
-   select VHOST
default n
---help---
Say M here to enable the vhost_scsi TCM fabric module
@@ -49,7 +43,6 @@ config VHOST_SCSI
 config 

Re: Boot flakiness with QEMU 3.1.0 and Clang built kernels

2020-04-13 Thread David Gibson
On Sat, Apr 11, 2020 at 11:57:23PM +1000, Nicholas Piggin wrote:
> Nicholas Piggin's on April 11, 2020 7:32 pm:
> > Nathan Chancellor's on April 11, 2020 10:53 am:
> >> The tt.config values are needed to reproduce but I did not verify that
> >> ONLY tt.config was needed. Other than that, no, we are just building
> >> either pseries_defconfig or powernv_defconfig with those configs and
> >> letting it boot up with a simple initramfs, which prints the version
> >> string then shuts the machine down.
> >> 
> >> Let me know if you need any more information, cheers!
> > 
> > Okay I can reproduce it. Sometimes it eventually recovers after a long
> > pause, and some keyboard input often helps it along. So that seems like 
> > it might be a lost interrupt.
> > 
> > POWER8 vs POWER9 might just be a timing thing if P9 is still hanging
> > sometimes. I wasn't able to reproduce it with defconfig+tt.config, I
> > needed your other config with various other debug options.
> > 
> > Thanks for the very good report. I'll let you know what I find.
> 
> It looks like a qemu bug. Booting with '-d int' shows the decrementer 
> simply stops firing at the point of the hang, even though MSR[EE]=1 and 
> the DEC register is wrapping. Linux appears to be doing the right thing 
> as far as I can tell (not losing interrupts).
> 
> This qemu patch fixes the boot hang for me. I don't know that qemu 
> really has the right idea of "context synchronizing" as defined in the
> powerpc architecture -- mtmsrd L=1 is not context synchronizing but that
> does not mean it can avoid looking at exceptions until the next such
> event. It looks like the decrementer exception goes high but the
> execution of mtmsrd L=1 is ignoring it.
> 
> Prior to the Linux patch 3282a3da25b you bisected to, interrupt replay
> code would return with an 'rfi' instruction as part of interrupt return,
> which probably helped to get things moving along a bit. However it would
> not be foolproof, and Cedric did say he encountered some mysterious
> lockups under load with qemu powernv before that patch was merged, so
> maybe it's the same issue?
> 
> Thanks,
> Nick
> 
> The patch is a bit of a hack, but if you can run it and verify it fixes
> your boot hang would be good.

So a bug in this handling wouldn't surprise me at all.  However a
report against QEMU 3.1 isn't particularly useful.

 * Does the problem occur with current upstream master qemu?
 * Does the problem occur with qemu-2.12 (a pretty widely deployed
   "stable" qemu, e.g. in RHEL)?

> ---
> 
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index b207fb5386..1d997f5c32 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -4364,12 +4364,21 @@ static void gen_mtmsrd(DisasContext *ctx)
>  if (ctx->opcode & 0x0001) {
>  /* Special form that does not need any synchronisation */
>  TCGv t0 = tcg_temp_new();
> +TCGv t1 = tcg_temp_new();
>  tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
>  (1 << MSR_RI) | (1 << MSR_EE));
> -tcg_gen_andi_tl(cpu_msr, cpu_msr,
> +tcg_gen_andi_tl(t1, cpu_msr,
>  ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
> -tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
> +tcg_gen_or_tl(t1, t1, t0);
> +
> +gen_update_nip(ctx, ctx->base.pc_next);
> +gen_helper_store_msr(cpu_env, t1);
>  tcg_temp_free(t0);
> +tcg_temp_free(t1);
> +/* Must stop the translation as machine state (may have) changed */
> +/* Note that mtmsr is not always defined as context-synchronizing */
> +gen_stop_exception(ctx);
> +
>  } else {
>  /*
>   * XXX: we need to update nip before the store if we enter
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [RFC/PATCH 2/3] pseries/kvm: Clear PSSCR[ESL|EC] bits before guest entry

2020-04-13 Thread David Gibson
On Mon, Apr 13, 2020 at 03:55:49PM +0530, Gautham R Shenoy wrote:
> Hello David,
> 
> On Wed, Apr 08, 2020 at 12:29:57PM +1000, David Gibson wrote:
> > On Tue, Apr 07, 2020 at 06:55:26PM +0530, Gautham R Shenoy wrote:
> > > Hello David,
> > > 
> > > On Mon, Apr 06, 2020 at 07:58:19PM +1000, David Gibson wrote:
> > > > On Fri, Apr 03, 2020 at 03:01:03PM +0530, Gautham R Shenoy wrote:
> > > > > On Fri, Apr 03, 2020 at 12:20:26PM +1000, Nicholas Piggin wrote:
> > > > > > Gautham R. Shenoy's on March 31, 2020 10:10 pm:
> > > > > > > From: "Gautham R. Shenoy" 
> > > > > > > 
> > > > > > > ISA v3.0 allows the guest to execute a stop instruction. For 
> > > > > > > this, the
> > > > > > > PSSCR[ESL|EC] bits need to be cleared by the hypervisor before
> > > > > > > scheduling in the guest vCPU.
> > > > > > > 
> > > > > > > Currently we always schedule in a vCPU with PSSCR[ESL|EC] bits
> > > > > > > set. This patch changes the behaviour to enter the guest with
> > > > > > > PSSCR[ESL|EC] bits cleared. This is a RFC patch where we
> > > > > > > unconditionally clear these bits. Ideally this should be done
> > > > > > > conditionally on platforms where the guest stop instruction has no
> > > > > > > Bugs (starting POWER9 DD2.3).
> > > > > > 
> > > > > > How will guests know that they can use this facility safely after 
> > > > > > your
> > > > > > series? You need both DD2.3 and a patched KVM.
> > > > > 
> > > > > 
> > > > > Yes, this is something that isn't addressed in this series (mentioned
> > > > > in the cover letter), which is a POC demonstrating that the stop0lite
> > > > > state in guest works.
> > > > > 
> > > > > However, to answer your question, this is the scheme that I had in
> > > > > mind :
> > > > > 
> > > > > OPAL:
> > > > >On Procs >= DD2.3 : we publish a dt-cpu-feature "idle-stop-guest"
> > > > > 
> > > > > Hypervisor Kernel:
> > > > > 1. If "idle-stop-guest" dt-cpu-feature is discovered, then
> > > > >we set bool enable_guest_stop = true;
> > > > > 
> > > > > 2. During KVM guest entry, clear PSSCR[ESL|EC] iff
> > > > >enable_guest_stop == true.
> > > > > 
> > > > > 3. In kvm_vm_ioctl_check_extension(), for a new capability
> > > > >KVM_CAP_STOP, return true iff enable_guest_top == true.
> > > > > 
> > > > > QEMU:
> > > > >Check with the hypervisor if KVM_CAP_STOP is present. If so,
> > > > >indicate the presence to the guest via device tree.
> > > > 
> > > > Nack.  Presenting different capabilities to the guest depending on
> > > > host capabilities (rather than explicit options) is never ok.  It
> > > > means that depending on the system you start on you may or may not be
> > > > able to migrate to other systems that you're supposed to be able to,
> > > 
> > > I agree that blocking migration for the unavailability of this feature
> > > is not desirable. Could you point me to some other capabilities in KVM
> > > which have been implemented via explicit options?
> > 
> > TBH, most of the options for the 'pseries' machine type are in this
> > category: cap-vsx, cap-dfp, cap-htm, a bunch related to various
> > Spectre mitigations, cap-hpt-max-page-size (maximum page size for hash
> > guests), cap-nested-hv, cap-large-decr, cap-fwnmi, resize-hpt (HPT
> > resizing extension), ic-mode (which irq controllers are available to
> > the guest).
> 
> 
> Thanks. I will follow this suit.
> 
> > 
> > > The ISA 3.0 allows the guest to execute the "stop" instruction.
> > 
> > So, this was a bug in DD2.2's implementation of the architecture?
> 
> Yes, the previous versions could miss wakeup events when stop was
> executed in HV=0,PR=0 mode. So, the hypervisor had to block that.
> 
> 
> > 
> > > If the
> > > Hypervisor hasn't cleared the PSSCR[ESL|EC] then, guest executing the
> > > "stop" instruction in the causes a Hypervisor Facility Unavailable
> > > Exception, thus giving the hypervisor a chance to emulate the
> > > instruction. However, in the current code, when the hypervisor
> > > receives this exception, it sends a PROGKILL to the guest which
> > > results in crashing the guest.
> > > 
> > > Patch 1 of this series emulates wakeup from the "stop"
> > > instruction. Would the following scheme be ok?
> > > 
> > > OPAL:
> > >   On Procs >= DD2.3 : we publish a dt-cpu-feature "idle-stop-guest"
> > > 
> > > Hypervisor Kernel:
> > > 
> > >  If "idle-stop-guest" dt feature is available, then, before
> > >  entering the guest, the hypervisor clears the PSSCR[EC|ESL]
> > >  bits allowing the guest to safely execute stop instruction.
> > > 
> > >  If "idle-stop-guest" dt feature is not available, then, the
> > >  Hypervisor sets the PSSCR[ESL|EC] bits, thereby causing a
> > >  guest "stop" instruction execution to trap back into the
> > >  hypervisor. We then emulate a wakeup from the stop
> > >  instruction (Patch 1 of this series).
> > > 
> > > Guest Kernel:
> > >   If (cpu_has_feature(CPU_FTR_ARCH_300)) only then use the
> > > 

Re: [PATCH v7 5/7] ASoC: fsl_asrc: Move common definition to fsl_asrc_common

2020-04-13 Thread Shengjiu Wang
On Tue, Apr 14, 2020 at 10:09 AM Nicolin Chen  wrote:
>
> On Tue, Apr 14, 2020 at 08:43:07AM +0800, Shengjiu Wang wrote:
> > There is a new ASRC included in i.MX serial platform, there
> > are some common definition can be shared with each other.
> > So move the common definition to a separate header file.
> >
> > And add fsl_asrc_pair_priv and fsl_asrc_priv for
> > the variable specific for the module, which can be used
> > internally.
> >
> > Signed-off-by: Shengjiu Wang 
>
> > diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> > +static size_t fsl_asrc_get_pair_priv_size(void)
> > +{
> > + return sizeof(struct fsl_asrc_pair_priv);
> > +}
>
> Perhaps we haven't understood completely each other's point.
>
> Yet, would the following change work?

Should work, almost same, or do you want me to use variable to
replace function pointer?

best regards
wang shengjiu


Re: [PATCH v7 4/7] ASoC: fsl_asrc: Support new property fsl,asrc-format

2020-04-13 Thread Nicolin Chen
On Tue, Apr 14, 2020 at 08:43:06AM +0800, Shengjiu Wang wrote:
> In order to align with new ESARC, we add new property fsl,asrc-format.
> The fsl,asrc-format can replace the fsl,asrc-width, driver
> can accept format from devicetree, don't need to convert it to
> format through width.
> 
> Signed-off-by: Shengjiu Wang 

Acked-by: Nicolin Chen 


[PATCH v7 7/7] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers

2020-04-13 Thread Shengjiu Wang
EASRC (Enhanced Asynchronous Sample Rate Converter) is a new IP module
found on i.MX8MN. It is different with old ASRC module.

The primary features for the EASRC are as follows:
- 4 Contexts - groups of channels with an independent time base
- Fully independent and concurrent context control
- Simultaneous processing of up to 32 audio channels
- Programmable filter charachteristics for each context
- 32, 24, 20, and 16-bit fixed point audio sample support
- 32-bit floating point audio sample support
- 8kHz to 384kHz sample rate
- 1/16 to 8x sample rate conversion ratio

Signed-off-by: Shengjiu Wang 
Signed-off-by: Cosmin-Gabriel Samoila 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/Kconfig |   11 +
 sound/soc/fsl/Makefile|2 +
 sound/soc/fsl/fsl_easrc.c | 2119 +
 sound/soc/fsl/fsl_easrc.h |  651 
 4 files changed, 2783 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_easrc.c
 create mode 100644 sound/soc/fsl/fsl_easrc.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 65e8cd4be930..ea7b4787a8af 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -84,6 +84,17 @@ config SND_SOC_FSL_MICFIL
  Say Y if you want to add Pulse Density Modulation microphone
  interface (MICFIL) support for NXP.
 
+config SND_SOC_FSL_EASRC
+   tristate "Enhanced Asynchronous Sample Rate Converter (EASRC) module 
support"
+   depends on SND_SOC_FSL_ASRC
+   select REGMAP_MMIO
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Enhanced ASRC support for NXP. The ASRC is
+ a digital module that converts audio from a source sample rate to a
+ destination sample rate. It is a new design module compare with the
+ old ASRC.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 8cde88c72d93..b835eebf8825 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -24,6 +24,7 @@ snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_dma.o
 snd-soc-fsl-mqs-objs := fsl_mqs.o
+snd-soc-fsl-easrc-objs := fsl_easrc.o
 
 obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
 obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o
 obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
 obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o
+obj-$(CONFIG_SND_SOC_FSL_EASRC) += snd-soc-fsl-easrc.o
 obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
 
 # MPC5200 Platform Support
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
new file mode 100644
index ..2e639ebcd15b
--- /dev/null
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -0,0 +1,2119 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_easrc.h"
+#include "imx-pcm.h"
+
+#define FSL_EASRC_FORMATS   (SNDRV_PCM_FMTBIT_S16_LE | \
+SNDRV_PCM_FMTBIT_U16_LE | \
+SNDRV_PCM_FMTBIT_S24_LE | \
+SNDRV_PCM_FMTBIT_S24_3LE | \
+SNDRV_PCM_FMTBIT_U24_LE | \
+SNDRV_PCM_FMTBIT_U24_3LE | \
+SNDRV_PCM_FMTBIT_S32_LE | \
+SNDRV_PCM_FMTBIT_U32_LE | \
+SNDRV_PCM_FMTBIT_S20_3LE | \
+SNDRV_PCM_FMTBIT_U20_3LE | \
+SNDRV_PCM_FMTBIT_FLOAT_LE)
+
+static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+   struct fsl_asrc *easrc = snd_soc_component_get_drvdata(comp);
+   struct fsl_easrc_priv *easrc_priv = easrc->private;
+   struct soc_mreg_control *mc =
+   (struct soc_mreg_control *)kcontrol->private_value;
+   unsigned int regval = ucontrol->value.integer.value[0];
+
+   easrc_priv->bps_iec958[mc->regbase] = regval;
+
+   return 0;
+}
+
+static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+   struct fsl_asrc *easrc = snd_soc_component_get_drvdata(comp);
+   struct fsl_easrc_priv *easrc_priv = easrc->private;
+   struct soc_mreg_control *mc =
+   (struct 

[PATCH v7 5/7] ASoC: fsl_asrc: Move common definition to fsl_asrc_common

2020-04-13 Thread Shengjiu Wang
There is a new ASRC included in i.MX serial platform, there
are some common definition can be shared with each other.
So move the common definition to a separate header file.

And add fsl_asrc_pair_priv and fsl_asrc_priv for
the variable specific for the module, which can be used
internally.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc.c|  87 +-
 sound/soc/fsl/fsl_asrc.h|  74 ++
 sound/soc/fsl/fsl_asrc_common.h | 106 
 sound/soc/fsl/fsl_asrc_dma.c|  25 
 4 files changed, 183 insertions(+), 109 deletions(-)
 create mode 100644 sound/soc/fsl/fsl_asrc_common.h

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index a9458fe268bc..ca9e766f7c69 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -308,8 +308,10 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair 
*pair,
  */
 static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool 
use_ideal_rate)
 {
-   struct asrc_config *config = pair->config;
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct asrc_config *config = pair_priv->config;
struct fsl_asrc *asrc = pair->asrc;
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
enum asrc_pair_index index = pair->index;
enum asrc_word_width input_word_width;
enum asrc_word_width output_word_width;
@@ -392,11 +394,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair 
*pair, bool use_ideal_rate)
}
 
/* Validate input and output clock sources */
-   clk_index[IN] = asrc->clk_map[IN][config->inclk];
-   clk_index[OUT] = asrc->clk_map[OUT][config->outclk];
+   clk_index[IN] = asrc_priv->clk_map[IN][config->inclk];
+   clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk];
 
/* We only have output clock for ideal ratio mode */
-   clk = asrc->asrck_clk[clk_index[ideal ? OUT : IN]];
+   clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
 
clk_rate = clk_get_rate(clk);
rem[IN] = do_div(clk_rate, inrate);
@@ -417,7 +419,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, 
bool use_ideal_rate)
 
div[IN] = min_t(u32, 1024, div[IN]);
 
-   clk = asrc->asrck_clk[clk_index[OUT]];
+   clk = asrc_priv->asrck_clk[clk_index[OUT]];
clk_rate = clk_get_rate(clk);
if (ideal && use_ideal_rate)
rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE);
@@ -437,13 +439,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair 
*pair, bool use_ideal_rate)
/* Set the channel number */
channels = config->channel_num;
 
-   if (asrc->soc->channel_bits < 4)
+   if (asrc_priv->soc->channel_bits < 4)
channels /= 2;
 
/* Update channels for current pair */
regmap_update_bits(asrc->regmap, REG_ASRCNCR,
-  ASRCNCR_ANCi_MASK(index, asrc->soc->channel_bits),
-  ASRCNCR_ANCi(index, channels, 
asrc->soc->channel_bits));
+  ASRCNCR_ANCi_MASK(index, 
asrc_priv->soc->channel_bits),
+  ASRCNCR_ANCi(index, channels, 
asrc_priv->soc->channel_bits));
 
/* Default setting: Automatic selection for processing mode */
regmap_update_bits(asrc->regmap, REG_ASRCTR,
@@ -568,9 +570,10 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream 
*substream,
struct snd_soc_dai *dai)
 {
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
 
/* Odd channel number is not valid for older ASRC (channel_bits==3) */
-   if (asrc->soc->channel_bits == 3)
+   if (asrc_priv->soc->channel_bits == 3)
snd_pcm_hw_constraint_step(substream->runtime, 0,
   SNDRV_PCM_HW_PARAM_CHANNELS, 2);
 
@@ -586,6 +589,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
unsigned int channels = params_channels(params);
unsigned int rate = params_rate(params);
struct asrc_config config;
@@ -597,7 +601,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
return ret;
}
 
-   pair->config = 
+   pair_priv->config = 
 
config.pair = pair->index;
config.channel_num = channels;
@@ -931,9 +935,20 @@ static irqreturn_t fsl_asrc_isr(int irq, void *dev_id)
return IRQ_HANDLED;
 }
 
+static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
+{
+   return REG_ASRDx(dir, index);
+}
+
+static size_t fsl_asrc_get_pair_priv_size(void)
+{
+   

[PATCH v7 6/7] ASoC: dt-bindings: fsl_easrc: Add document for EASRC

2020-04-13 Thread Shengjiu Wang
EASRC (Enhanced Asynchronous Sample Rate Converter) is a new
IP module found on i.MX8MN.

Signed-off-by: Shengjiu Wang 
---
 .../devicetree/bindings/sound/fsl,easrc.yaml  | 101 ++
 1 file changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,easrc.yaml 
b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml
new file mode 100644
index ..14ea60084420
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,easrc.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,easrc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Asynchronous Sample Rate Converter (ASRC) Controller
+
+maintainers:
+  - Shengjiu Wang 
+
+properties:
+  $nodename:
+pattern: "^easrc@.*"
+
+  compatible:
+const: fsl,imx8mn-easrc
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Peripheral clock
+
+  clock-names:
+items:
+  - const: mem
+
+  dmas:
+maxItems: 8
+
+  dma-names:
+items:
+  - const: ctx0_rx
+  - const: ctx0_tx
+  - const: ctx1_rx
+  - const: ctx1_tx
+  - const: ctx2_rx
+  - const: ctx2_tx
+  - const: ctx3_rx
+  - const: ctx3_tx
+
+  firmware-name:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/string
+  - const: imx/easrc/easrc-imx8mn.bin
+description: The coefficient table for the filters
+
+  fsl,asrc-rate:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - minimum: 8000
+  - maximum: 192000
+description: Defines a mutual sample rate used by DPCM Back Ends
+
+  fsl,asrc-format:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [2, 6, 10, 32, 36]
+default: 2
+description:
+  Defines a mutual sample format used by DPCM Back Ends
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - firmware-name
+  - fsl,asrc-rate
+  - fsl,asrc-format
+
+examples:
+  - |
+#include 
+
+easrc: easrc@300C {
+   compatible = "fsl,imx8mn-easrc";
+   reg = <0x0 0x300C 0x0 0x1>;
+   interrupts = <0x0 122 0x4>;
+   clocks = < IMX8MN_CLK_ASRC_ROOT>;
+   clock-names = "mem";
+   dmas = < 16 23 0> , < 17 23 0>,
+  < 18 23 0> , < 19 23 0>,
+  < 20 23 0> , < 21 23 0>,
+  < 22 23 0> , < 23 23 0>;
+   dma-names = "ctx0_rx", "ctx0_tx",
+   "ctx1_rx", "ctx1_tx",
+   "ctx2_rx", "ctx2_tx",
+   "ctx3_rx", "ctx3_tx";
+   firmware-name = "imx/easrc/easrc-imx8mn.bin";
+   fsl,asrc-rate  = <8000>;
+   fsl,asrc-format = <2>;
+};
-- 
2.21.0



[PATCH v7 4/7] ASoC: fsl_asrc: Support new property fsl,asrc-format

2020-04-13 Thread Shengjiu Wang
In order to align with new ESARC, we add new property fsl,asrc-format.
The fsl,asrc-format can replace the fsl,asrc-width, driver
can accept format from devicetree, don't need to convert it to
format through width.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc.c | 41 +++-
 sound/soc/fsl/fsl_asrc.h |  4 ++--
 sound/soc/fsl/fsl_asrc_dma.c | 15 ++---
 3 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 4d3e51bfa949..a9458fe268bc 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -589,7 +589,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
unsigned int channels = params_channels(params);
unsigned int rate = params_rate(params);
struct asrc_config config;
-   snd_pcm_format_t format;
int ret;
 
ret = fsl_asrc_request_pair(channels, pair);
@@ -600,11 +599,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
 
pair->config = 
 
-   if (asrc->asrc_width == 16)
-   format = SNDRV_PCM_FORMAT_S16_LE;
-   else
-   format = SNDRV_PCM_FORMAT_S24_LE;
-
config.pair = pair->index;
config.channel_num = channels;
config.inclk = INCLK_NONE;
@@ -612,11 +606,11 @@ static int fsl_asrc_dai_hw_params(struct 
snd_pcm_substream *substream,
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format   = params_format(params);
-   config.output_format  = format;
+   config.output_format  = asrc->asrc_format;
config.input_sample_rate  = rate;
config.output_sample_rate = asrc->asrc_rate;
} else {
-   config.input_format   = format;
+   config.input_format   = asrc->asrc_format;
config.output_format  = params_format(params);
config.input_sample_rate  = asrc->asrc_rate;
config.output_sample_rate = rate;
@@ -946,6 +940,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
int irq, ret, i;
u32 map_idx;
char tmp[16];
+   u32 width;
 
asrc = devm_kzalloc(>dev, sizeof(*asrc), GFP_KERNEL);
if (!asrc)
@@ -1052,16 +1047,32 @@ static int fsl_asrc_probe(struct platform_device *pdev)
return ret;
}
 
-   ret = of_property_read_u32(np, "fsl,asrc-width",
-  >asrc_width);
+   ret = of_property_read_u32(np, "fsl,asrc-format", >asrc_format);
if (ret) {
-   dev_err(>dev, "failed to get output width\n");
-   return ret;
+   ret = of_property_read_u32(np, "fsl,asrc-width", );
+   if (ret) {
+   dev_err(>dev, "failed to decide output format\n");
+   return ret;
+   }
+
+   switch (width) {
+   case 16:
+   asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+   break;
+   case 24:
+   asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+   break;
+   default:
+   dev_warn(>dev,
+"unsupported width, use default S24_LE\n");
+   asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+   break;
+   }
}
 
-   if (asrc->asrc_width != 16 && asrc->asrc_width != 24) {
-   dev_warn(>dev, "unsupported width, switching to 24bit\n");
-   asrc->asrc_width = 24;
+   if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
+   dev_warn(>dev, "unsupported width, use default S24_LE\n");
+   asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
}
 
platform_set_drvdata(pdev, asrc);
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 95d62c45afde..3b0f156af2c3 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -493,7 +493,7 @@ struct fsl_asrc_pair {
  * @channel_avail: non-occupied channel numbers
  * @clk_map: clock map for input/output clock
  * @asrc_rate: default sample rate for ASoC Back-Ends
- * @asrc_width: default sample width for ASoC Back-Ends
+ * @asrc_format: default sample format for ASoC Back-Ends
  * @regcache_cfg: store register value of REG_ASRCFG
  */
 struct fsl_asrc {
@@ -514,7 +514,7 @@ struct fsl_asrc {
unsigned char *clk_map[2];
 
int asrc_rate;
-   int asrc_width;
+   snd_pcm_format_t asrc_format;
 
u32 regcache_cfg;
 };
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index 5fe83aece25b..a9dd3155ff35 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -146,7 +146,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
struct device 

Re: [PATCH v2] qtpm2: Export tpm2_get_cc_attrs_tbl for ibmvtpm driver as module

2020-04-13 Thread Michael Ellerman
Jarkko Sakkinen  writes:
> On Wed, Apr 01, 2020 at 02:40:30PM +0530, Sachin Sant wrote:
>> > On 20-Mar-2020, at 1:27 AM, Jarkko Sakkinen 
>> >  wrote:
>> > 
>> > On Wed, Mar 18, 2020 at 09:00:17PM -0400, Stefan Berger wrote:
>> >> From: Stefan Berger 
>> >> 
>> >> This patch fixes the following problem when the ibmvtpm driver
>> >> is built as a module:
>> >> 
>> >> ERROR: modpost: "tpm2_get_cc_attrs_tbl" [drivers/char/tpm/tpm_ibmvtpm.ko] 
>> >> undefined!
>> >> make[1]: *** [scripts/Makefile.modpost:94: __modpost] Error 1
>> >> make: *** [Makefile:1298: modules] Error 2
>> >> 
>> >> Fixes: 18b3670d79ae ("tpm: ibmvtpm: Add support for TPM2")
>> >> Signed-off-by: Stefan Berger 
>> >> Reported-by: Sachin Sant 
>> >> Tested-by: Sachin Sant 
>> > 
>> 
>> Ping. This failure can now be seen in mainline (cad18da0af) as well.
>
> It is in my tree

Can you please send it to Linus?

cheers


[PATCH v7 1/7] ASoC: fsl_asrc: rename asrc_priv to asrc

2020-04-13 Thread Shengjiu Wang
In order to move common structure to fsl_asrc_common.h
we change the name of asrc_priv to asrc, the asrc_priv
will be used by new struct fsl_asrc_priv.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_asrc.c | 298 +--
 sound/soc/fsl/fsl_asrc.h |   4 +-
 sound/soc/fsl/fsl_asrc_dma.c |  24 +--
 3 files changed, 163 insertions(+), 163 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 0dcebc24c312..4d3e51bfa949 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -21,10 +21,10 @@
 #define IDEAL_RATIO_DECIMAL_DEPTH 26
 
 #define pair_err(fmt, ...) \
-   dev_err(_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, 
##__VA_ARGS__)
+   dev_err(>pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
 
 #define pair_dbg(fmt, ...) \
-   dev_dbg(_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, 
##__VA_ARGS__)
+   dev_dbg(>pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
 
 /* Corresponding to process_option */
 static unsigned int supported_asrc_rate[] = {
@@ -157,15 +157,15 @@ static void fsl_asrc_sel_proc(int inrate, int outrate,
 int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair)
 {
enum asrc_pair_index index = ASRC_INVALID_PAIR;
-   struct fsl_asrc *asrc_priv = pair->asrc_priv;
-   struct device *dev = _priv->pdev->dev;
+   struct fsl_asrc *asrc = pair->asrc;
+   struct device *dev = >pdev->dev;
unsigned long lock_flags;
int i, ret = 0;
 
-   spin_lock_irqsave(_priv->lock, lock_flags);
+   spin_lock_irqsave(>lock, lock_flags);
 
for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
-   if (asrc_priv->pair[i] != NULL)
+   if (asrc->pair[i] != NULL)
continue;
 
index = i;
@@ -177,17 +177,17 @@ int fsl_asrc_request_pair(int channels, struct 
fsl_asrc_pair *pair)
if (index == ASRC_INVALID_PAIR) {
dev_err(dev, "all pairs are busy now\n");
ret = -EBUSY;
-   } else if (asrc_priv->channel_avail < channels) {
+   } else if (asrc->channel_avail < channels) {
dev_err(dev, "can't afford required channels: %d\n", channels);
ret = -EINVAL;
} else {
-   asrc_priv->channel_avail -= channels;
-   asrc_priv->pair[index] = pair;
+   asrc->channel_avail -= channels;
+   asrc->pair[index] = pair;
pair->channels = channels;
pair->index = index;
}
 
-   spin_unlock_irqrestore(_priv->lock, lock_flags);
+   spin_unlock_irqrestore(>lock, lock_flags);
 
return ret;
 }
@@ -195,25 +195,25 @@ int fsl_asrc_request_pair(int channels, struct 
fsl_asrc_pair *pair)
 /**
  * Release ASRC pair
  *
- * It clears the resource from asrc_priv and releases the occupied channels.
+ * It clears the resource from asrc and releases the occupied channels.
  */
 void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
 {
-   struct fsl_asrc *asrc_priv = pair->asrc_priv;
+   struct fsl_asrc *asrc = pair->asrc;
enum asrc_pair_index index = pair->index;
unsigned long lock_flags;
 
/* Make sure the pair is disabled */
-   regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
+   regmap_update_bits(asrc->regmap, REG_ASRCTR,
   ASRCTR_ASRCEi_MASK(index), 0);
 
-   spin_lock_irqsave(_priv->lock, lock_flags);
+   spin_lock_irqsave(>lock, lock_flags);
 
-   asrc_priv->channel_avail += pair->channels;
-   asrc_priv->pair[index] = NULL;
+   asrc->channel_avail += pair->channels;
+   asrc->pair[index] = NULL;
pair->error = 0;
 
-   spin_unlock_irqrestore(_priv->lock, lock_flags);
+   spin_unlock_irqrestore(>lock, lock_flags);
 }
 
 /**
@@ -221,10 +221,10 @@ void fsl_asrc_release_pair(struct fsl_asrc_pair *pair)
  */
 static void fsl_asrc_set_watermarks(struct fsl_asrc_pair *pair, u32 in, u32 
out)
 {
-   struct fsl_asrc *asrc_priv = pair->asrc_priv;
+   struct fsl_asrc *asrc = pair->asrc;
enum asrc_pair_index index = pair->index;
 
-   regmap_update_bits(asrc_priv->regmap, REG_ASRMCR(index),
+   regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
   ASRMCRi_EXTTHRSHi_MASK |
   ASRMCRi_INFIFO_THRESHOLD_MASK |
   ASRMCRi_OUTFIFO_THRESHOLD_MASK,
@@ -257,7 +257,7 @@ static u32 fsl_asrc_cal_asrck_divisor(struct fsl_asrc_pair 
*pair, u32 div)
 static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair,
int inrate, int outrate)
 {
-   struct fsl_asrc *asrc_priv = pair->asrc_priv;
+   struct fsl_asrc *asrc = pair->asrc;
enum asrc_pair_index index = pair->index;
unsigned long ratio;
int i;
@@ -286,8 +286,8 @@ static int fsl_asrc_set_ideal_ratio(struct 

[PATCH v7 3/7] ASoC: fsl-asoc-card: Support new property fsl, asrc-format

2020-04-13 Thread Shengjiu Wang
In order to align with new ESARC, we add new property fsl,asrc-format.
The fsl,asrc-format can replace the fsl,asrc-width, driver
can accept format from devicetree, don't need to convert it to
format through width.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/fsl-asoc-card.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index bb33601fab84..cf4feb835743 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -680,17 +680,23 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
goto asrc_fail;
}
 
-   ret = of_property_read_u32(asrc_np, "fsl,asrc-width", );
+   ret = of_property_read_u32(asrc_np, "fsl,asrc-format",
+  >asrc_format);
if (ret) {
-   dev_err(>dev, "failed to get output rate\n");
-   ret = -EINVAL;
-   goto asrc_fail;
-   }
+   /* Fallback to old binding; translate to asrc_format */
+   ret = of_property_read_u32(asrc_np, "fsl,asrc-width",
+  );
+   if (ret) {
+   dev_err(>dev,
+   "failed to decide output format\n");
+   goto asrc_fail;
+   }
 
-   if (width == 24)
-   priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
-   else
-   priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+   if (width == 24)
+   priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+   else
+   priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
+   }
}
 
/* Finish card registering */
-- 
2.21.0



[PATCH v7 0/7] ASoC: Add new module driver for new ASRC

2020-04-13 Thread Shengjiu Wang
Add new module driver for new ASRC in i.MX8MN, several commits
are added for new property fsl,asrc-format

Shengjiu Wang (7):
  ASoC: fsl_asrc: rename asrc_priv to asrc
  ASoC: dt-bindings: fsl_asrc: Add new property fsl,asrc-format
  ASoC: fsl-asoc-card: Support new property fsl,asrc-format
  ASoC: fsl_asrc: Support new property fsl,asrc-format
  ASoC: fsl_asrc: Move common definition to fsl_asrc_common
  ASoC: dt-bindings: fsl_easrc: Add document for EASRC
  ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers

changes in v7
- updated according to Nicoin's comments.
- add get_pair_priv_size to replace PAIR_PRIVATE_SIZE

changes in v6
- updated according to Nicoin's and Rob's comments.

changes in v5
- Add new property fsl,asrc-format, rather than change fsl,asrc-width
  to fsl,asrc-formt.
- code change for above change.

changes in v4
- Add several commit for changing DT binding asrc-width to asrc-format
- rename asrc_priv to asrc

changes in v3
- add new commit "ASoC: fsl_asrc: Change asrc_width to asrc_format"
- modify binding doc to yaml format
- remove fsl_easrc_dma.c, make fsl_asrc_dma.c useable for easrc.

changes in v2
- change i.MX815 to i.MX8MN
- Add changes in Kconfig and Makefile

 .../devicetree/bindings/sound/fsl,asrc.txt|4 +
 .../devicetree/bindings/sound/fsl,easrc.yaml  |  101 +
 sound/soc/fsl/Kconfig |   11 +
 sound/soc/fsl/Makefile|2 +
 sound/soc/fsl/fsl-asoc-card.c |   24 +-
 sound/soc/fsl/fsl_asrc.c  |  310 +--
 sound/soc/fsl/fsl_asrc.h  |   74 +-
 sound/soc/fsl/fsl_asrc_common.h   |  106 +
 sound/soc/fsl/fsl_asrc_dma.c  |   54 +-
 sound/soc/fsl/fsl_easrc.c | 2119 +
 sound/soc/fsl/fsl_easrc.h |  651 +
 11 files changed, 3222 insertions(+), 234 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml
 create mode 100644 sound/soc/fsl/fsl_asrc_common.h
 create mode 100644 sound/soc/fsl/fsl_easrc.c
 create mode 100644 sound/soc/fsl/fsl_easrc.h

-- 
2.21.0



[PATCH v7 2/7] ASoC: dt-bindings: fsl_asrc: Add new property fsl, asrc-format

2020-04-13 Thread Shengjiu Wang
In order to support new EASRC and simplify the code structure,
We decide to share the common structure between them. This bring
a problem that EASRC accept format directly from devicetree, but
ASRC accept width from devicetree.

In order to align with new ESARC, we add new property fsl,asrc-format.
The fsl,asrc-format can replace the fsl,asrc-width, then driver
can accept format from devicetree, don't need to convert it to
format through width.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 Documentation/devicetree/bindings/sound/fsl,asrc.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt 
b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index cb9a25165503..998b4c8a7f78 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -51,6 +51,10 @@ Optional properties:
  will be in use as default. Otherwise, the big endian
  mode will be in use for all the device registers.
 
+   - fsl,asrc-format   : Defines a mutual sample format used by DPCM Back
+ Ends, which can replace the fsl,asrc-width.
+ The value is 2 (S16_LE), or 6 (S24_LE).
+
 Example:
 
 asrc: asrc@2034000 {
-- 
2.21.0



[PATCH v2 2/2] crypto: Remove unnecessary memzero_explicit()

2020-04-13 Thread Waiman Long
Since kfree_sensitive() will do an implicit memzero_explicit(), there
is no need to call memzero_explicit() before it. Eliminate those
memzero_explicit() and simplify the call sites. For better correctness,
the setting of keylen is also moved down after the key pointer check.

Signed-off-by: Waiman Long 
---
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c  | 19 +-
 .../allwinner/sun8i-ss/sun8i-ss-cipher.c  | 20 +--
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 12 +++
 drivers/crypto/inside-secure/safexcel_hash.c  |  3 +--
 4 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c 
b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index aa4e8fdc2b32..8358fac98719 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -366,10 +366,7 @@ void sun8i_ce_cipher_exit(struct crypto_tfm *tfm)
 {
struct sun8i_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
crypto_free_sync_skcipher(op->fallback_tfm);
pm_runtime_put_sync_suspend(op->ce->dev);
 }
@@ -391,14 +388,11 @@ int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
dev_dbg(ce->dev, "ERROR: Invalid keylen %u\n", keylen);
return -EINVAL;
}
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
-   op->keylen = keylen;
+   kfree_sensitive(op->key);
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
return -ENOMEM;
+   op->keylen = keylen;
 
crypto_sync_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
crypto_sync_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & 
CRYPTO_TFM_REQ_MASK);
@@ -416,14 +410,11 @@ int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
if (err)
return err;
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
-   op->keylen = keylen;
+   kfree_sensitive(op->key);
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
return -ENOMEM;
+   op->keylen = keylen;
 
crypto_sync_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
crypto_sync_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & 
CRYPTO_TFM_REQ_MASK);
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c 
b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
index 5246ef4f5430..0495fbc27fcc 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
@@ -249,7 +249,6 @@ static int sun8i_ss_cipher(struct skcipher_request *areq)
offset = areq->cryptlen - ivsize;
if (rctx->op_dir & SS_DECRYPTION) {
memcpy(areq->iv, backup_iv, ivsize);
-   memzero_explicit(backup_iv, ivsize);
kfree_sensitive(backup_iv);
} else {
scatterwalk_map_and_copy(areq->iv, areq->dst, 
offset,
@@ -367,10 +366,7 @@ void sun8i_ss_cipher_exit(struct crypto_tfm *tfm)
 {
struct sun8i_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
crypto_free_sync_skcipher(op->fallback_tfm);
pm_runtime_put_sync(op->ss->dev);
 }
@@ -392,14 +388,11 @@ int sun8i_ss_aes_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
dev_dbg(ss->dev, "ERROR: Invalid keylen %u\n", keylen);
return -EINVAL;
}
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
-   op->keylen = keylen;
+   kfree_sensitive(op->key);
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
return -ENOMEM;
+   op->keylen = keylen;
 
crypto_sync_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
crypto_sync_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & 
CRYPTO_TFM_REQ_MASK);
@@ -418,14 +411,11 @@ int sun8i_ss_des3_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
return -EINVAL;
}
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
-   op->keylen = keylen;
+   kfree_sensitive(op->key);
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
return 

Re: [PATCH 2/2] crypto: Remove unnecessary memzero_explicit()

2020-04-13 Thread Waiman Long
On 4/13/20 5:31 PM, Joe Perches wrote:
> On Mon, 2020-04-13 at 17:15 -0400, Waiman Long wrote:
>> Since kfree_sensitive() will do an implicit memzero_explicit(), there
>> is no need to call memzero_explicit() before it. Eliminate those
>> memzero_explicit() and simplify the call sites.
> 2 bits of trivia:
>
>> diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c 
>> b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
> []
>> @@ -391,10 +388,7 @@ int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, 
>> const u8 *key,
>>  dev_dbg(ce->dev, "ERROR: Invalid keylen %u\n", keylen);
>>  return -EINVAL;
>>  }
>> -if (op->key) {
>> -memzero_explicit(op->key, op->keylen);
>> -kfree(op->key);
>> -}
>> +kfree_sensitive(op->key);
>>  op->keylen = keylen;
>>  op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
>>  if (!op->key)
> It might be a defect to set op->keylen before the kmemdup succeeds.
It could be. I can move it down after the op->key check.
>> @@ -416,10 +410,7 @@ int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, 
>> const u8 *key,
>>  if (err)
>>  return err;
>>  
>> -if (op->key) {
>> -memzero_explicit(op->key, op->keylen);
>> -kfree(op->key);
>> -}
>> +free_sensitive(op->key, op->keylen);
> Why not kfree_sensitive(op->key) ?

Oh, it is a bug. I will send out v2 to fix that.

Thanks for spotting it.

Cheers,
Longman


>
>



Re: [PATCH] kvm_host: unify VM_STAT and VCPU_STAT definitions in a single place

2020-04-13 Thread Philippe Mathieu-Daudé
Hi Emanuele,

On 4/13/20 4:03 PM, Emanuele Giuseppe Esposito wrote:
> The macros VM_STAT and VCPU_STAT are redundantly implemented in multiple
> files, each used by a different architecure to initialize the debugfs
> entries for statistics. Since they all have the same purpose, they can be
> unified in a single common definition in include/linux/kvm_host.h
> 
> Signed-off-by: Emanuele Giuseppe Esposito 
> ---
>  arch/arm64/kvm/guest.c| 23 +++
>  arch/mips/kvm/mips.c  | 61 +++
>  arch/powerpc/kvm/book3s.c |  3 --
>  arch/powerpc/kvm/booke.c  |  3 --
>  arch/s390/kvm/kvm-s390.c  |  3 --
>  arch/x86/kvm/x86.c|  3 --
>  include/linux/kvm_host.h  |  3 ++
>  7 files changed, 43 insertions(+), 56 deletions(-)
> 
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 23ebe51410f0..3e3aee8b37c0 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -29,20 +29,17 @@
>  
>  #include "trace.h"
>  
> -#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM }
> -#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
> -
>  struct kvm_stats_debugfs_item debugfs_entries[] = {
> - VCPU_STAT(halt_successful_poll),
> - VCPU_STAT(halt_attempted_poll),
> - VCPU_STAT(halt_poll_invalid),
> - VCPU_STAT(halt_wakeup),
> - VCPU_STAT(hvc_exit_stat),
> - VCPU_STAT(wfe_exit_stat),
> - VCPU_STAT(wfi_exit_stat),
> - VCPU_STAT(mmio_exit_user),
> - VCPU_STAT(mmio_exit_kernel),
> - VCPU_STAT(exits),
> + { "halt_successful_poll", VCPU_STAT(halt_successful_poll) },
> + { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) },
> + { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
> + { "halt_wakeup", VCPU_STAT(halt_wakeup) },
> + { "hvc_exit_stat", VCPU_STAT(hvc_exit_stat) },
> + { "wfe_exit_stat", VCPU_STAT(wfe_exit_stat) },
> + { "wfi_exit_stat", VCPU_STAT(wfi_exit_stat) },
> + { "mmio_exit_user", VCPU_STAT(mmio_exit_user) },
> + { "mmio_exit_kernel", VCPU_STAT(mmio_exit_kernel) },
> + { "exits", VCPU_STAT(exits) },
>   { NULL }
>  };
>  
[...]
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 6d58beb65454..e02d38c7fff1 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -1130,6 +1130,9 @@ struct kvm_stats_debugfs_item {
>  #define KVM_DBGFS_GET_MODE(dbgfs_item)   
>   \
>   ((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)
>  
> +#define VM_STAT(x, ...) offsetof(struct kvm, stat.x), KVM_STAT_VM, ## 
> __VA_ARGS__
> +#define VCPU_STAT(x, ...) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, 
> ## __VA_ARGS__

I find this macro expanding into multiple fields odd... Maybe a matter
of taste. Sugggestion, have the macro define the full structure, as in
the arm64 arch:

#define VM_STAT(n, x, ...) { n, offsetof(struct kvm, stat.x),
KVM_STAT_VM, ## __VA_ARGS__ }

Ditto for VCPU_STAT().

> +
>  extern struct kvm_stats_debugfs_item debugfs_entries[];
>  extern struct dentry *kvm_debugfs_dir;
>  
> 


[PATCH] kvm_host: unify VM_STAT and VCPU_STAT definitions in a single place

2020-04-13 Thread Emanuele Giuseppe Esposito
The macros VM_STAT and VCPU_STAT are redundantly implemented in multiple
files, each used by a different architecure to initialize the debugfs
entries for statistics. Since they all have the same purpose, they can be
unified in a single common definition in include/linux/kvm_host.h

Signed-off-by: Emanuele Giuseppe Esposito 
---
 arch/arm64/kvm/guest.c| 23 +++
 arch/mips/kvm/mips.c  | 61 +++
 arch/powerpc/kvm/book3s.c |  3 --
 arch/powerpc/kvm/booke.c  |  3 --
 arch/s390/kvm/kvm-s390.c  |  3 --
 arch/x86/kvm/x86.c|  3 --
 include/linux/kvm_host.h  |  3 ++
 7 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 23ebe51410f0..3e3aee8b37c0 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -29,20 +29,17 @@
 
 #include "trace.h"
 
-#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM }
-#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
-
 struct kvm_stats_debugfs_item debugfs_entries[] = {
-   VCPU_STAT(halt_successful_poll),
-   VCPU_STAT(halt_attempted_poll),
-   VCPU_STAT(halt_poll_invalid),
-   VCPU_STAT(halt_wakeup),
-   VCPU_STAT(hvc_exit_stat),
-   VCPU_STAT(wfe_exit_stat),
-   VCPU_STAT(wfi_exit_stat),
-   VCPU_STAT(mmio_exit_user),
-   VCPU_STAT(mmio_exit_kernel),
-   VCPU_STAT(exits),
+   { "halt_successful_poll", VCPU_STAT(halt_successful_poll) },
+   { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) },
+   { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
+   { "halt_wakeup", VCPU_STAT(halt_wakeup) },
+   { "hvc_exit_stat", VCPU_STAT(hvc_exit_stat) },
+   { "wfe_exit_stat", VCPU_STAT(wfe_exit_stat) },
+   { "wfi_exit_stat", VCPU_STAT(wfi_exit_stat) },
+   { "mmio_exit_user", VCPU_STAT(mmio_exit_user) },
+   { "mmio_exit_kernel", VCPU_STAT(mmio_exit_kernel) },
+   { "exits", VCPU_STAT(exits) },
{ NULL }
 };
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 8f05dd0a0f4e..f14b93d02f02 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -39,40 +39,39 @@
 #define VECTORSPACING 0x100/* for EI/VI mode */
 #endif
 
-#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x)
 struct kvm_stats_debugfs_item debugfs_entries[] = {
-   { "wait", VCPU_STAT(wait_exits), KVM_STAT_VCPU },
-   { "cache",VCPU_STAT(cache_exits),KVM_STAT_VCPU },
-   { "signal",   VCPU_STAT(signal_exits),   KVM_STAT_VCPU },
-   { "interrupt",VCPU_STAT(int_exits),  KVM_STAT_VCPU },
-   { "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
-   { "tlbmod",   VCPU_STAT(tlbmod_exits),   KVM_STAT_VCPU },
-   { "tlbmiss_ld",   VCPU_STAT(tlbmiss_ld_exits),   KVM_STAT_VCPU },
-   { "tlbmiss_st",   VCPU_STAT(tlbmiss_st_exits),   KVM_STAT_VCPU },
-   { "addrerr_st",   VCPU_STAT(addrerr_st_exits),   KVM_STAT_VCPU },
-   { "addrerr_ld",   VCPU_STAT(addrerr_ld_exits),   KVM_STAT_VCPU },
-   { "syscall",  VCPU_STAT(syscall_exits),  KVM_STAT_VCPU },
-   { "resvd_inst",   VCPU_STAT(resvd_inst_exits),   KVM_STAT_VCPU },
-   { "break_inst",   VCPU_STAT(break_inst_exits),   KVM_STAT_VCPU },
-   { "trap_inst",VCPU_STAT(trap_inst_exits),KVM_STAT_VCPU },
-   { "msa_fpe",  VCPU_STAT(msa_fpe_exits),  KVM_STAT_VCPU },
-   { "fpe",  VCPU_STAT(fpe_exits),  KVM_STAT_VCPU },
-   { "msa_disabled", VCPU_STAT(msa_disabled_exits), KVM_STAT_VCPU },
-   { "flush_dcache", VCPU_STAT(flush_dcache_exits), KVM_STAT_VCPU },
+   { "wait", VCPU_STAT(wait_exits) },
+   { "cache",VCPU_STAT(cache_exits) },
+   { "signal",   VCPU_STAT(signal_exits) },
+   { "interrupt",VCPU_STAT(int_exits) },
+   { "cop_unusable", VCPU_STAT(cop_unusable_exits) },
+   { "tlbmod",   VCPU_STAT(tlbmod_exits) },
+   { "tlbmiss_ld",   VCPU_STAT(tlbmiss_ld_exits) },
+   { "tlbmiss_st",   VCPU_STAT(tlbmiss_st_exits) },
+   { "addrerr_st",   VCPU_STAT(addrerr_st_exits) },
+   { "addrerr_ld",   VCPU_STAT(addrerr_ld_exits) },
+   { "syscall",  VCPU_STAT(syscall_exits) },
+   { "resvd_inst",   VCPU_STAT(resvd_inst_exits) },
+   { "break_inst",   VCPU_STAT(break_inst_exits) },
+   { "trap_inst",VCPU_STAT(trap_inst_exits) },
+   { "msa_fpe",  VCPU_STAT(msa_fpe_exits) },
+   { "fpe",  VCPU_STAT(fpe_exits) },
+   { "msa_disabled", VCPU_STAT(msa_disabled_exits) },
+   { "flush_dcache", VCPU_STAT(flush_dcache_exits) },
 #ifdef CONFIG_KVM_MIPS_VZ
-   { "vz_gpsi",  VCPU_STAT(vz_gpsi_exits),  KVM_STAT_VCPU },
-   { "vz_gsfc",  VCPU_STAT(vz_gsfc_exits),  KVM_STAT_VCPU },
-   { "vz_hc",VCPU_STAT(vz_hc_exits),KVM_STAT_VCPU },
-   { "vz_grr",   VCPU_STAT(vz_grr_exits), 

Re: [PATCH 2/2] crypto: Remove unnecessary memzero_explicit()

2020-04-13 Thread Joe Perches
On Mon, 2020-04-13 at 17:15 -0400, Waiman Long wrote:
> Since kfree_sensitive() will do an implicit memzero_explicit(), there
> is no need to call memzero_explicit() before it. Eliminate those
> memzero_explicit() and simplify the call sites.

2 bits of trivia:

> diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c 
> b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
[]
> @@ -391,10 +388,7 @@ int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, 
> const u8 *key,
>   dev_dbg(ce->dev, "ERROR: Invalid keylen %u\n", keylen);
>   return -EINVAL;
>   }
> - if (op->key) {
> - memzero_explicit(op->key, op->keylen);
> - kfree(op->key);
> - }
> + kfree_sensitive(op->key);
>   op->keylen = keylen;
>   op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
>   if (!op->key)

It might be a defect to set op->keylen before the kmemdup succeeds.

> @@ -416,10 +410,7 @@ int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, 
> const u8 *key,
>   if (err)
>   return err;
>  
> - if (op->key) {
> - memzero_explicit(op->key, op->keylen);
> - kfree(op->key);
> - }
> + free_sensitive(op->key, op->keylen);

Why not kfree_sensitive(op->key) ?




[PATCH 2/2] crypto: Remove unnecessary memzero_explicit()

2020-04-13 Thread Waiman Long
Since kfree_sensitive() will do an implicit memzero_explicit(), there
is no need to call memzero_explicit() before it. Eliminate those
memzero_explicit() and simplify the call sites.

Signed-off-by: Waiman Long 
---
 .../crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c  | 15 +++
 .../crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c  | 16 +++-
 drivers/crypto/amlogic/amlogic-gxl-cipher.c  | 10 ++
 drivers/crypto/inside-secure/safexcel_hash.c |  3 +--
 4 files changed, 9 insertions(+), 35 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c 
b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index aa4e8fdc2b32..46c10c7ca6d0 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -366,10 +366,7 @@ void sun8i_ce_cipher_exit(struct crypto_tfm *tfm)
 {
struct sun8i_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
crypto_free_sync_skcipher(op->fallback_tfm);
pm_runtime_put_sync_suspend(op->ce->dev);
 }
@@ -391,10 +388,7 @@ int sun8i_ce_aes_setkey(struct crypto_skcipher *tfm, const 
u8 *key,
dev_dbg(ce->dev, "ERROR: Invalid keylen %u\n", keylen);
return -EINVAL;
}
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
op->keylen = keylen;
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
@@ -416,10 +410,7 @@ int sun8i_ce_des3_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
if (err)
return err;
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   free_sensitive(op->key, op->keylen);
op->keylen = keylen;
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c 
b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
index 5246ef4f5430..7e09a923cbaf 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
@@ -249,7 +249,6 @@ static int sun8i_ss_cipher(struct skcipher_request *areq)
offset = areq->cryptlen - ivsize;
if (rctx->op_dir & SS_DECRYPTION) {
memcpy(areq->iv, backup_iv, ivsize);
-   memzero_explicit(backup_iv, ivsize);
kfree_sensitive(backup_iv);
} else {
scatterwalk_map_and_copy(areq->iv, areq->dst, 
offset,
@@ -367,10 +366,7 @@ void sun8i_ss_cipher_exit(struct crypto_tfm *tfm)
 {
struct sun8i_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
crypto_free_sync_skcipher(op->fallback_tfm);
pm_runtime_put_sync(op->ss->dev);
 }
@@ -392,10 +388,7 @@ int sun8i_ss_aes_setkey(struct crypto_skcipher *tfm, const 
u8 *key,
dev_dbg(ss->dev, "ERROR: Invalid keylen %u\n", keylen);
return -EINVAL;
}
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
op->keylen = keylen;
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
@@ -418,10 +411,7 @@ int sun8i_ss_des3_setkey(struct crypto_skcipher *tfm, 
const u8 *key,
return -EINVAL;
}
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key);
op->keylen = keylen;
op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA);
if (!op->key)
diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c 
b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index fd1269900d67..f424397fbba4 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -341,10 +341,7 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
 {
struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
 
-   if (op->key) {
-   memzero_explicit(op->key, op->keylen);
-   kfree(op->key);
-   }
+   kfree_sensitive(op->key)
crypto_free_sync_skcipher(op->fallback_tfm);
 }
 
@@ -368,10 +365,7 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 
*key,
dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
return -EINVAL;
}
-   if (op->key) {
-   

[PATCH 1/2] mm, treewide: Rename kzfree() to kfree_sensitive()

2020-04-13 Thread Waiman Long
As said by Linus:

  A symmetric naming is only helpful if it implies symmetries in use.
  Otherwise it's actively misleading.

  In "kzalloc()", the z is meaningful and an important part of what the
  caller wants.

  In "kzfree()", the z is actively detrimental, because maybe in the
  future we really _might_ want to use that "memfill(0xdeadbeef)" or
  something. The "zero" part of the interface isn't even _relevant_.

The main reason that kzfree() exists is to clear sensitive information
that should not be leaked to other future users of the same memory
objects.

Rename kzfree() to kfree_sensitive() to follow the example of the
recently added kvfree_sensitive() and make the intention of the API
more explicit. In addition, memzero_explicit() is used to clear the
memory to make sure that it won't get optimized away by the compiler.

The renaming is done by using the command sequence:

  git grep -w --name-only kzfree |\
  xargs sed -i 's/\bkzfree\b/kfree_sensitive/'

followed by some editing of the kfree_sensitive() kerneldoc and the
use of memzero_explicit() instead of memset().

Suggested-by: Joe Perches 
Signed-off-by: Waiman Long 
---
 arch/s390/crypto/prng.c   |  4 +--
 arch/x86/power/hibernate.c|  2 +-
 crypto/adiantum.c |  2 +-
 crypto/ahash.c|  4 +--
 crypto/api.c  |  2 +-
 crypto/asymmetric_keys/verify_pefile.c|  4 +--
 crypto/deflate.c  |  2 +-
 crypto/drbg.c | 10 +++---
 crypto/ecc.c  |  8 ++---
 crypto/ecdh.c |  2 +-
 crypto/gcm.c  |  2 +-
 crypto/gf128mul.c |  4 +--
 crypto/jitterentropy-kcapi.c  |  2 +-
 crypto/rng.c  |  2 +-
 crypto/rsa-pkcs1pad.c |  6 ++--
 crypto/seqiv.c|  2 +-
 crypto/shash.c|  2 +-
 crypto/skcipher.c |  2 +-
 crypto/testmgr.c  |  6 ++--
 crypto/zstd.c |  2 +-
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c  |  2 +-
 .../allwinner/sun8i-ss/sun8i-ss-cipher.c  |  2 +-
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   |  4 +--
 drivers/crypto/atmel-ecc.c|  2 +-
 drivers/crypto/caam/caampkc.c | 28 +++
 drivers/crypto/cavium/cpt/cptvf_main.c|  6 ++--
 drivers/crypto/cavium/cpt/cptvf_reqmanager.c  | 12 +++
 drivers/crypto/cavium/nitrox/nitrox_lib.c |  4 +--
 drivers/crypto/cavium/zip/zip_crypto.c|  6 ++--
 drivers/crypto/ccp/ccp-crypto-rsa.c   |  6 ++--
 drivers/crypto/ccree/cc_aead.c|  4 +--
 drivers/crypto/ccree/cc_buffer_mgr.c  |  4 +--
 drivers/crypto/ccree/cc_cipher.c  |  6 ++--
 drivers/crypto/ccree/cc_hash.c|  8 ++---
 drivers/crypto/ccree/cc_request_mgr.c |  2 +-
 drivers/crypto/marvell/cesa/hash.c|  2 +-
 .../crypto/marvell/octeontx/otx_cptvf_main.c  |  6 ++--
 .../marvell/octeontx/otx_cptvf_reqmgr.h   |  2 +-
 drivers/crypto/mediatek/mtk-aes.c |  2 +-
 drivers/crypto/nx/nx.c|  4 +--
 drivers/crypto/virtio/virtio_crypto_algs.c| 12 +++
 drivers/crypto/virtio/virtio_crypto_core.c|  2 +-
 drivers/md/dm-crypt.c | 34 +--
 drivers/md/dm-integrity.c |  6 ++--
 drivers/misc/ibmvmc.c |  6 ++--
 .../hisilicon/hns3/hns3pf/hclge_mbx.c |  2 +-
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c|  6 ++--
 drivers/net/ppp/ppp_mppe.c|  6 ++--
 drivers/net/wireguard/noise.c |  4 +--
 drivers/net/wireguard/peer.c  |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c  |  2 +-
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  6 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  6 ++--
 drivers/net/wireless/intersil/orinoco/wext.c  |  4 +--
 drivers/s390/crypto/ap_bus.h  |  4 +--
 drivers/staging/ks7010/ks_hostif.c|  2 +-
 drivers/staging/rtl8723bs/core/rtw_security.c |  2 +-
 drivers/staging/wlan-ng/p80211netdev.c|  2 +-
 drivers/target/iscsi/iscsi_target_auth.c  |  2 +-
 fs/btrfs/ioctl.c  |  2 +-
 fs/cifs/cifsencrypt.c |  2 +-
 fs/cifs/connect.c | 10 +++---
 fs/cifs/dfs_cache.c   |  2 +-
 fs/cifs/misc.c|  8 ++---
 fs/crypto/keyring.c   |  6 ++--
 fs/crypto/keysetup_v1.c   |  4 +--
 fs/ecryptfs/keystore.c|  4 +--
 fs/ecryptfs/messaging.c   |  2 +-
 

[PATCH 0/2] mm, treewide: Rename kzfree() to kfree_sensitive()

2020-04-13 Thread Waiman Long
This patchset makes a global rename of the kzfree() to kfree_sensitive()
to highlight the fact buffer clearing is only needed if the data objects
contain sensitive information like encrpytion key. The fact that kzfree()
uses memset() to do the clearing isn't totally safe either as compiler
may compile out the clearing in their optimizer. Instead, the new
kfree_sensitive() uses memzero_explicit() which won't get compiled out.

Waiman Long (2):
  mm, treewide: Rename kzfree() to kfree_sensitive()
  crypto: Remove unnecessary memzero_explicit()

 arch/s390/crypto/prng.c   |  4 +--
 arch/x86/power/hibernate.c|  2 +-
 crypto/adiantum.c |  2 +-
 crypto/ahash.c|  4 +--
 crypto/api.c  |  2 +-
 crypto/asymmetric_keys/verify_pefile.c|  4 +--
 crypto/deflate.c  |  2 +-
 crypto/drbg.c | 10 +++---
 crypto/ecc.c  |  8 ++---
 crypto/ecdh.c |  2 +-
 crypto/gcm.c  |  2 +-
 crypto/gf128mul.c |  4 +--
 crypto/jitterentropy-kcapi.c  |  2 +-
 crypto/rng.c  |  2 +-
 crypto/rsa-pkcs1pad.c |  6 ++--
 crypto/seqiv.c|  2 +-
 crypto/shash.c|  2 +-
 crypto/skcipher.c |  2 +-
 crypto/testmgr.c  |  6 ++--
 crypto/zstd.c |  2 +-
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c  | 17 +++---
 .../allwinner/sun8i-ss/sun8i-ss-cipher.c  | 18 +++---
 drivers/crypto/amlogic/amlogic-gxl-cipher.c   | 14 +++-
 drivers/crypto/atmel-ecc.c|  2 +-
 drivers/crypto/caam/caampkc.c | 28 +++
 drivers/crypto/cavium/cpt/cptvf_main.c|  6 ++--
 drivers/crypto/cavium/cpt/cptvf_reqmanager.c  | 12 +++
 drivers/crypto/cavium/nitrox/nitrox_lib.c |  4 +--
 drivers/crypto/cavium/zip/zip_crypto.c|  6 ++--
 drivers/crypto/ccp/ccp-crypto-rsa.c   |  6 ++--
 drivers/crypto/ccree/cc_aead.c|  4 +--
 drivers/crypto/ccree/cc_buffer_mgr.c  |  4 +--
 drivers/crypto/ccree/cc_cipher.c  |  6 ++--
 drivers/crypto/ccree/cc_hash.c|  8 ++---
 drivers/crypto/ccree/cc_request_mgr.c |  2 +-
 drivers/crypto/inside-secure/safexcel_hash.c  |  3 +-
 drivers/crypto/marvell/cesa/hash.c|  2 +-
 .../crypto/marvell/octeontx/otx_cptvf_main.c  |  6 ++--
 .../marvell/octeontx/otx_cptvf_reqmgr.h   |  2 +-
 drivers/crypto/mediatek/mtk-aes.c |  2 +-
 drivers/crypto/nx/nx.c|  4 +--
 drivers/crypto/virtio/virtio_crypto_algs.c| 12 +++
 drivers/crypto/virtio/virtio_crypto_core.c|  2 +-
 drivers/md/dm-crypt.c | 34 +--
 drivers/md/dm-integrity.c |  6 ++--
 drivers/misc/ibmvmc.c |  6 ++--
 .../hisilicon/hns3/hns3pf/hclge_mbx.c |  2 +-
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c|  6 ++--
 drivers/net/ppp/ppp_mppe.c|  6 ++--
 drivers/net/wireguard/noise.c |  4 +--
 drivers/net/wireguard/peer.c  |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c  |  2 +-
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  6 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  6 ++--
 drivers/net/wireless/intersil/orinoco/wext.c  |  4 +--
 drivers/s390/crypto/ap_bus.h  |  4 +--
 drivers/staging/ks7010/ks_hostif.c|  2 +-
 drivers/staging/rtl8723bs/core/rtw_security.c |  2 +-
 drivers/staging/wlan-ng/p80211netdev.c|  2 +-
 drivers/target/iscsi/iscsi_target_auth.c  |  2 +-
 fs/btrfs/ioctl.c  |  2 +-
 fs/cifs/cifsencrypt.c |  2 +-
 fs/cifs/connect.c | 10 +++---
 fs/cifs/dfs_cache.c   |  2 +-
 fs/cifs/misc.c|  8 ++---
 fs/crypto/keyring.c   |  6 ++--
 fs/crypto/keysetup_v1.c   |  4 +--
 fs/ecryptfs/keystore.c|  4 +--
 fs/ecryptfs/messaging.c   |  2 +-
 include/crypto/aead.h |  2 +-
 include/crypto/akcipher.h |  2 +-
 include/crypto/gf128mul.h |  2 +-
 include/crypto/hash.h |  2 +-
 include/crypto/internal/acompress.h   |  2 +-
 include/crypto/kpp.h  |  2 +-
 include/crypto/skcipher.h |  2 +-
 include/linux/slab.h  |  2 +-
 lib/mpi/mpiutil.c |  6 ++--
 lib/test_kasan.c 

-Wincompatible-pointer-types in arch/powerpc/platforms/embedded6xx/mvme5100.c

2020-04-13 Thread Nathan Chancellor
Hi all,

0day reported a build error in arch/powerpc/platforms/embedded6xx/mvme5100.c
when building with clang [1]. This is not a clang specific issue since
it also happens with gcc:

$ curl -LSs 
https://lore.kernel.org/lkml/202004131704.6mh1jcq3%25...@intel.com/2-a.bin | 
gzip -d > .config
$ make -j$(nproc) -s ARCH=powerpc CROSS_COMPILE=powerpc-linux- olddefconfig 
arch/powerpc/platforms/embedded6xx/mvme5100.o
arch/powerpc/platforms/embedded6xx/mvme5100.c: In function 
'mvme5100_add_bridge':
arch/powerpc/platforms/embedded6xx/mvme5100.c:135:58: error: passing argument 5 
of 'early_read_config_dword' from incompatible pointer type 
[-Werror=incompatible-pointer-types]
  135 |  early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, _membase);
  |  ^~~~
  |  |
  |  phys_addr_t * 
{aka long long unsigned int *}
In file included from arch/powerpc/platforms/embedded6xx/mvme5100.c:18:
./arch/powerpc/include/asm/pci-bridge.h:139:32: note: expected 'u32 *' {aka 
'unsigned int *'} but argument is of type 'phys_addr_t *' {aka 'long long 
unsigned int *'}
  139 |int dev_fn, int where, u32 *val);
  |   ~^~~
In file included from ./include/linux/printk.h:7,
 from ./include/linux/kernel.h:15,
 from ./include/linux/list.h:9,
 from ./include/linux/rculist.h:10,
 from ./include/linux/pid.h:5,
 from ./include/linux/sched.h:14,
 from ./include/linux/ratelimit.h:6,
 from ./include/linux/dev_printk.h:16,
 from ./include/linux/device.h:15,
 from ./include/linux/of_platform.h:9,
 from arch/powerpc/platforms/embedded6xx/mvme5100.c:15:
./include/linux/kern_levels.h:5:18: error: format '%x' expects argument of type 
'unsigned int', but argument 2 has type 'phys_addr_t' {aka 'long long unsigned 
int'} [-Werror=format=]
5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
  |  ^~
./include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
   14 | #define KERN_INFO KERN_SOH "6" /* informational */
  |   ^~~~
./include/linux/printk.h:305:9: note: in expansion of macro 'KERN_INFO'
  305 |  printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
  | ^
arch/powerpc/platforms/embedded6xx/mvme5100.c:142:2: note: in expansion of 
macro 'pr_info'
  142 |  pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
  |  ^~~
arch/powerpc/platforms/embedded6xx/mvme5100.c:142:44: note: format string is 
defined here
  142 |  pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
  |   ~^
  ||
  |unsigned int
  |   %llx
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:267: 
arch/powerpc/platforms/embedded6xx/mvme5100.o] Error 1
make[3]: *** [scripts/Makefile.build:488: arch/powerpc/platforms/embedded6xx] 
Error 2
make[2]: *** [scripts/Makefile.build:488: arch/powerpc/platforms] Error 2
make[1]: *** [Makefile:1722: arch/powerpc] Error 2
make: *** [Makefile:328: __build_one_by_one] Error 2

I am not sure how exactly this should be fixed. Should this driver just
not be selectable when CONFIG_PHYS_ADDR_T_64BIT is selected or is there
something else that I am missing?

[1]: https://lore.kernel.org/lkml/202004131704.6mh1jcq3%25...@intel.com/

Cheers,
Nathan


Re: [PATCH 25/28] mm: remove vmalloc_user_node_flags

2020-04-13 Thread Johannes Weiner
On Thu, Apr 09, 2020 at 03:25:03PM -0700, Andrii Nakryiko wrote:
> cc Johannes who suggested this API call originally

I forgot why we did it this way - probably just cruft begetting more
cruft. Either way, Christoph's cleanup makes this look a lot better.

> On Wed, Apr 8, 2020 at 5:03 AM Christoph Hellwig  wrote:
> >
> > Open code it in __bpf_map_area_alloc, which is the only caller.  Also
> > clean up __bpf_map_area_alloc to have a single vmalloc call with
> > slightly different flags instead of the current two different calls.
> >
> > For this to compile for the nommu case add a __vmalloc_node_range stub
> > to nommu.c.
> >
> > Signed-off-by: Christoph Hellwig 

Acked-by: Johannes Weiner 


[PATCH] lib/mpi: Fix building for powerpc with clang

2020-04-13 Thread Nathan Chancellor
0day reports over and over on an powerpc randconfig with clang:

lib/mpi/generic_mpih-mul1.c:37:13: error: invalid use of a cast in a
inline asm context requiring an l-value: remove the cast or build with
-fheinous-gnu-extensions

Remove the superfluous casts, which have been done previously for x86
and arm32 in commit dea632cadd12 ("lib/mpi: fix build with clang") and
commit 7b7c1df2883d ("lib/mpi/longlong.h: fix building with 32-bit
x86").

Reported-by: kbuild test robot 
Link: https://github.com/ClangBuiltLinux/linux/issues/991
Signed-off-by: Nathan Chancellor 
---

Herbet seems to take lib/mpi patches but there does not seem to be a
formal maintainer so Michael could take it since it is just a powerpc
thing.

 lib/mpi/longlong.h | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index 2dceaca27489..891e1c3549c4 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -722,22 +722,22 @@ do {  
\
 do { \
if (__builtin_constant_p(bh) && (bh) == 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else \
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "%r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
@@ -747,36 +747,36 @@ do { \
 do { \
if (__builtin_constant_p(ah) && (ah) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p(ah) && (ah) == ~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p(bh) && (bh) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else \
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
-   : "=r" ((USItype)(sh)), \
-   "=" ((USItype)(sl)) \
+   : "=r" (sh), \
+   "=" (sl) \
: "r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
@@ -787,7 +787,7 @@ do { \
 do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mulhwu %0,%1,%2" \
-   : "=r" ((USItype) ph) \
+   : "=r" (ph) \
: "%r" (__m0), \
"r" (__m1)); \
(pl) = __m0 * __m1; \

base-commit: 8f3d9f354286745c751374f5f1fcafee6b3f3136
-- 
2.26.0



[PATCH] powerpc/wii: Fix declaration made after definition

2020-04-13 Thread Nathan Chancellor
A 0day randconfig uncovered an error with clang, trimmed for brevity:

arch/powerpc/platforms/embedded6xx/wii.c:195:7: error: attribute
declaration must precede definition [-Werror,-Wignored-attributes]
if (!machine_is(wii))
 ^

The macro machine_is declares mach_##name but define_machine actually
defines mach_##name, hence the warning.

To fix this, move define_machine after the is_machine usage.

Fixes: 5a7ee3198dfa ("powerpc: wii: platform support")
Reported-by: kbuild test robot 
Link: https://github.com/ClangBuiltLinux/linux/issues/989
Signed-off-by: Nathan Chancellor 
---
 arch/powerpc/platforms/embedded6xx/wii.c | 25 
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/embedded6xx/wii.c 
b/arch/powerpc/platforms/embedded6xx/wii.c
index 67e48b0a164e..a802ef957d63 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -172,19 +172,6 @@ static void wii_shutdown(void)
flipper_quiesce();
 }
 
-define_machine(wii) {
-   .name   = "wii",
-   .probe  = wii_probe,
-   .setup_arch = wii_setup_arch,
-   .restart= wii_restart,
-   .halt   = wii_halt,
-   .init_IRQ   = wii_pic_probe,
-   .get_irq= flipper_pic_get_irq,
-   .calibrate_decr = generic_calibrate_decr,
-   .progress   = udbg_progress,
-   .machine_shutdown   = wii_shutdown,
-};
-
 static const struct of_device_id wii_of_bus[] = {
{ .compatible = "nintendo,hollywood", },
{ },
@@ -200,3 +187,15 @@ static int __init wii_device_probe(void)
 }
 device_initcall(wii_device_probe);
 
+define_machine(wii) {
+   .name   = "wii",
+   .probe  = wii_probe,
+   .setup_arch = wii_setup_arch,
+   .restart= wii_restart,
+   .halt   = wii_halt,
+   .init_IRQ   = wii_pic_probe,
+   .get_irq= flipper_pic_get_irq,
+   .calibrate_decr = generic_calibrate_decr,
+   .progress   = udbg_progress,
+   .machine_shutdown   = wii_shutdown,
+};

base-commit: 8f3d9f354286745c751374f5f1fcafee6b3f3136
-- 
2.26.0



Re: [PATCH v2 4/4] hugetlbfs: clean up command line processing

2020-04-13 Thread Mike Kravetz
On 4/10/20 1:37 PM, Peter Xu wrote:
> On Wed, Apr 01, 2020 at 11:38:19AM -0700, Mike Kravetz wrote:
>> With all hugetlb page processing done in a single file clean up code.
>> - Make code match desired semantics
>>   - Update documentation with semantics
>> - Make all warnings and errors messages start with 'HugeTLB:'.
>> - Consistently name command line parsing routines.
>> - Check for hugepages_supported() before processing parameters.
>> - Add comments to code
>>   - Describe some of the subtle interactions
>>   - Describe semantics of command line arguments
>>
>> Signed-off-by: Mike Kravetz 
>> ---
>>  .../admin-guide/kernel-parameters.txt | 35 ---
>>  Documentation/admin-guide/mm/hugetlbpage.rst  | 44 +
>>  mm/hugetlb.c  | 96 +++
>>  3 files changed, 142 insertions(+), 33 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt 
>> b/Documentation/admin-guide/kernel-parameters.txt
>> index 1bd5454b5e5f..de653cfe1726 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -832,12 +832,15 @@
>>  See also Documentation/networking/decnet.txt.
>>  
>>  default_hugepagesz=
>> -[same as hugepagesz=] The size of the default
>> -HugeTLB page size. This is the size represented by
>> -the legacy /proc/ hugepages APIs, used for SHM, and
>> -default size when mounting hugetlbfs filesystems.
>> -Defaults to the default architecture's huge page size
>> -if not specified.
>> +[HW] The size of the default HugeTLB page size. This
> 
> Could I ask what's "HW"?  Sorry this is not a comment at all but
> really a pure question I wanted to ask... :)

kernel-parameters.rst includes kernel-parameters.txt and included the meaning
for these codes.

   HW  Appropriate hardware is enabled.

Previously, it listed an obsolete list of architectures.

>> +is the size represented by the legacy /proc/ hugepages
>> +APIs.  In addition, this is the default hugetlb size
>> +used for shmget(), mmap() and mounting hugetlbfs
>> +filesystems.  If not specified, defaults to the
>> +architecture's default huge page size.  Huge page
>> +sizes are architecture dependent.  See also
>> +Documentation/admin-guide/mm/hugetlbpage.rst.
>> +Format: size[KMG]
>>  
>>  deferred_probe_timeout=
>>  [KNL] Debugging option to set a timeout in seconds for
>> @@ -1480,13 +1483,19 @@
>>  If enabled, boot-time allocation of gigantic hugepages
>>  is skipped.
>>  
>> -hugepages=  [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
>> -hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
>> -On x86-64 and powerpc, this option can be specified
>> -multiple times interleaved with hugepages= to reserve
>> -huge pages of different sizes. Valid pages sizes on
>> -x86-64 are 2M (when the CPU supports "pse") and 1G
>> -(when the CPU supports the "pdpe1gb" cpuinfo flag).
>> +hugepages=  [HW] Number of HugeTLB pages to allocate at boot.
>> +If this follows hugepagesz (below), it specifies
>> +the number of pages of hugepagesz to be allocated.
> 
> "... Otherwise it specifies the number of pages to allocate for the
> default huge page size." ?

Yes, best to be specific.  I suspect this is the most common way this
parameter is used.

> 
>> +Format: 
> 
> How about add a new line here?

Sure

>> +hugepagesz=
>> +[HW] The size of the HugeTLB pages.  This is used in
>> +conjunction with hugepages (above) to allocate huge
>> +pages of a specific size at boot.  The pair
>> +hugepagesz=X hugepages=Y can be specified once for
>> +each supported huge page size. Huge page sizes are
>> +architecture dependent.  See also
>> +Documentation/admin-guide/mm/hugetlbpage.rst.
>> +Format: size[KMG]
>>  
>>  hung_task_panic=
>>  [KNL] Should the hung task detector generate panics.
>> diff --git a/Documentation/admin-guide/mm/hugetlbpage.rst 
>> b/Documentation/admin-guide/mm/hugetlbpage.rst
>> index 1cc0bc78d10e..de340c586995 100644
>> --- a/Documentation/admin-guide/mm/hugetlbpage.rst
>> +++ b/Documentation/admin-guide/mm/hugetlbpage.rst
>> @@ -100,6 +100,50 @@ with a huge page size selection parameter 
>> "hugepagesz=".   must
>>  be specified in bytes with optional 

Re: [PATCH v2 1/4] hugetlbfs: add arch_hugetlb_valid_size

2020-04-13 Thread Mike Kravetz
On 4/10/20 12:16 PM, Peter Xu wrote:
> On Wed, Apr 01, 2020 at 11:38:16AM -0700, Mike Kravetz wrote:
>> diff --git a/arch/arm64/include/asm/hugetlb.h 
>> b/arch/arm64/include/asm/hugetlb.h
>> index 2eb6c234d594..81606223494f 100644
>> --- a/arch/arm64/include/asm/hugetlb.h
>> +++ b/arch/arm64/include/asm/hugetlb.h
>> @@ -59,6 +59,8 @@ extern void huge_pte_clear(struct mm_struct *mm, unsigned 
>> long addr,
>>  extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
>>   pte_t *ptep, pte_t pte, unsigned long sz);
>>  #define set_huge_swap_pte_at set_huge_swap_pte_at
>> +bool __init arch_hugetlb_valid_size(unsigned long size);
>> +#define arch_hugetlb_valid_size arch_hugetlb_valid_size
> 
> Sorry for chimming in late.

Thank you for taking a look!

> Since we're working on removing arch-dependent codes after all.. I'm
> thinking whether we can define arch_hugetlb_valid_size() once in the
> common header (e.g. linux/hugetlb.h), then in mm/hugetlb.c:
> 
> bool __init __attribute((weak)) arch_hugetlb_valid_size(unsigned long size)
> {
>   return size == HPAGE_SIZE;
> }
> 
> We can simply redefine arch_hugetlb_valid_size() in arch specific C
> files where we want to override the default.  Would that be slightly
> cleaner?

I think both the #define X X and weak attribute methods are acceptable.
I went with the #define method only because it was most familiar to me.
Using the weak attribute method does appear to be cleaner.  I'll code it up.

Anyone else have a preference?
-- 
Mike Kravetz


[PATCH 25/26] perf metrictroup: Split the metricgroup__add_metric function

2020-04-13 Thread Arnaldo Carvalho de Melo
From: Kajol Jain 

This patch refactors metricgroup__add_metric function where some part of
it move to function metricgroup__add_metric_param.  No logic change.

Signed-off-by: Kajol Jain 
Acked-by: Jiri Olsa 
Cc: Alexander Shishkin 
Cc: Andi Kleen 
Cc: Anju T Sudhakar 
Cc: Benjamin Herrenschmidt 
Cc: Greg Kroah-Hartman 
Cc: Jin Yao 
Cc: Joe Mario 
Cc: Kan Liang 
Cc: Madhavan Srinivasan 
Cc: Mamatha Inamdar 
Cc: Mark Rutland 
Cc: Michael Ellerman 
Cc: Michael Petlan 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Ravi Bangoria 
Cc: Sukadev Bhattiprolu 
Cc: Thomas Gleixner 
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lore.kernel.org/lkml/20200401203340.31402-4-kj...@linux.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/metricgroup.c | 60 ---
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 926449a7cdbf..7ad81c8177ea 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -485,6 +485,39 @@ static bool metricgroup__has_constraint(struct pmu_event 
*pe)
return false;
 }
 
+static int __metricgroup__add_metric(struct strbuf *events,
+   struct list_head *group_list, struct pmu_event *pe)
+{
+
+   const char **ids;
+   int idnum;
+   struct egroup *eg;
+
+   if (expr__find_other(pe->metric_expr, NULL, , ) < 0)
+   return -EINVAL;
+
+   if (events->len > 0)
+   strbuf_addf(events, ",");
+
+   if (metricgroup__has_constraint(pe))
+   metricgroup__add_metric_non_group(events, ids, idnum);
+   else
+   metricgroup__add_metric_weak_group(events, ids, idnum);
+
+   eg = malloc(sizeof(*eg));
+   if (!eg)
+   return -ENOMEM;
+
+   eg->ids = ids;
+   eg->idnum = idnum;
+   eg->metric_name = pe->metric_name;
+   eg->metric_expr = pe->metric_expr;
+   eg->metric_unit = pe->unit;
+   list_add_tail(>nd, group_list);
+
+   return 0;
+}
+
 static int metricgroup__add_metric(const char *metric, struct strbuf *events,
   struct list_head *group_list)
 {
@@ -504,35 +537,12 @@ static int metricgroup__add_metric(const char *metric, 
struct strbuf *events,
continue;
if (match_metric(pe->metric_group, metric) ||
match_metric(pe->metric_name, metric)) {
-   const char **ids;
-   int idnum;
-   struct egroup *eg;
 
pr_debug("metric expr %s for %s\n", pe->metric_expr, 
pe->metric_name);
 
-   if (expr__find_other(pe->metric_expr,
-NULL, , ) < 0)
-   continue;
-   if (events->len > 0)
-   strbuf_addf(events, ",");
-
-   if (metricgroup__has_constraint(pe))
-   metricgroup__add_metric_non_group(events, ids, 
idnum);
-   else
-   metricgroup__add_metric_weak_group(events, ids, 
idnum);
-
-   eg = malloc(sizeof(struct egroup));
-   if (!eg) {
-   ret = -ENOMEM;
+   ret = __metricgroup__add_metric(events, group_list, pe);
+   if (ret == -ENOMEM)
break;
-   }
-   eg->ids = ids;
-   eg->idnum = idnum;
-   eg->metric_name = pe->metric_name;
-   eg->metric_expr = pe->metric_expr;
-   eg->metric_unit = pe->unit;
-   list_add_tail(>nd, group_list);
-   ret = 0;
}
}
return ret;
-- 
2.21.1



[PATCH 24/26] perf expr: Add expr_scanner_ctx object

2020-04-13 Thread Arnaldo Carvalho de Melo
From: Jiri Olsa 

Add the expr_scanner_ctx object to hold user data for the expr scanner.
Currently it holds only start_token, Kajol Jain will use it to hold 24x7
runtime param.

Signed-off-by: Jiri Olsa 
Cc: Alexander Shishkin 
Cc: Andi Kleen 
Cc: Anju T Sudhakar 
Cc: Benjamin Herrenschmidt 
Cc: Greg Kroah-Hartman 
Cc: Jin Yao 
Cc: Joe Mario 
Cc: Kajol Jain 
Cc: Kan Liang 
Cc: Madhavan Srinivasan 
Cc: Mamatha Inamdar 
Cc: Mark Rutland 
Cc: Michael Ellerman 
Cc: Michael Petlan 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Ravi Bangoria 
Cc: Sukadev Bhattiprolu 
Cc: Thomas Gleixner 
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lore.kernel.org/lkml/20200401203340.31402-3-kj...@linux.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/expr.c |  6 --
 tools/perf/util/expr.h |  4 
 tools/perf/util/expr.l | 10 +-
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index c8ccc548a585..c3382d58cf40 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -3,7 +3,6 @@
 #include 
 #include "expr.h"
 #include "expr-bison.h"
-#define YY_EXTRA_TYPE int
 #include "expr-flex.h"
 
 #ifdef PARSER_DEBUG
@@ -30,11 +29,14 @@ static int
 __expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
  int start)
 {
+   struct expr_scanner_ctx scanner_ctx = {
+   .start_token = start,
+   };
YY_BUFFER_STATE buffer;
void *scanner;
int ret;
 
-   ret = expr_lex_init_extra(start, );
+   ret = expr_lex_init_extra(_ctx, );
if (ret)
return ret;
 
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index b9e53f2b5844..0938ad166ece 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -15,6 +15,10 @@ struct expr_parse_ctx {
struct expr_parse_id ids[MAX_PARSE_ID];
 };
 
+struct expr_scanner_ctx {
+   int start_token;
+};
+
 void expr__ctx_init(struct expr_parse_ctx *ctx);
 void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char 
*expr);
diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l
index eaad29243c23..2582c2464938 100644
--- a/tools/perf/util/expr.l
+++ b/tools/perf/util/expr.l
@@ -76,13 +76,13 @@ sym [0-9a-zA-Z_\.:@]+
 symbol {spec}*{sym}*{spec}*{sym}*
 
 %%
-   {
-   int start_token;
+   struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
 
-   start_token = expr_get_extra(yyscanner);
+   {
+   int start_token = sctx->start_token;
 
-   if (start_token) {
-   expr_set_extra(NULL, yyscanner);
+   if (sctx->start_token) {
+   sctx->start_token = 0;
return start_token;
}
}
-- 
2.21.1



[PATCH 23/26] perf expr: Add expr_ prefix for parse_ctx and parse_id

2020-04-13 Thread Arnaldo Carvalho de Melo
From: Jiri Olsa 

Adding expr_ prefix for parse_ctx and parse_id, to straighten out the
expr* namespace.

There's no functional change.

Signed-off-by: Jiri Olsa 
Cc: Alexander Shishkin 
Cc: Andi Kleen 
Cc: Anju T Sudhakar 
Cc: Benjamin Herrenschmidt 
Cc: Greg Kroah-Hartman 
Cc: Jin Yao 
Cc: Joe Mario 
Cc: Kajol Jain 
Cc: Kan Liang 
Cc: Madhavan Srinivasan 
Cc: Mamatha Inamdar 
Cc: Mark Rutland 
Cc: Michael Ellerman 
Cc: Michael Petlan 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Ravi Bangoria 
Cc: Sukadev Bhattiprolu 
Cc: Thomas Gleixner 
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lore.kernel.org/lkml/20200401203340.31402-2-kj...@linux.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/tests/expr.c   |  4 ++--
 tools/perf/util/expr.c| 10 +-
 tools/perf/util/expr.h| 12 ++--
 tools/perf/util/expr.y|  6 +++---
 tools/perf/util/stat-shadow.c |  2 +-
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index 28313e59d6f6..ea10fc4412c4 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -6,7 +6,7 @@
 #include 
 #include 
 
-static int test(struct parse_ctx *ctx, const char *e, double val2)
+static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
 {
double val;
 
@@ -22,7 +22,7 @@ int test__expr(struct test *t __maybe_unused, int subtest 
__maybe_unused)
const char **other;
double val;
int i, ret;
-   struct parse_ctx ctx;
+   struct expr_parse_ctx ctx;
int num_other;
 
expr__ctx_init();
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index fd192ddf93c1..c8ccc548a585 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -11,7 +11,7 @@ extern int expr_debug;
 #endif
 
 /* Caller must make sure id is allocated */
-void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
+void expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val)
 {
int idx;
 
@@ -21,13 +21,13 @@ void expr__add_id(struct parse_ctx *ctx, const char *name, 
double val)
ctx->ids[idx].val = val;
 }
 
-void expr__ctx_init(struct parse_ctx *ctx)
+void expr__ctx_init(struct expr_parse_ctx *ctx)
 {
ctx->num_ids = 0;
 }
 
 static int
-__expr__parse(double *val, struct parse_ctx *ctx, const char *expr,
+__expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
  int start)
 {
YY_BUFFER_STATE buffer;
@@ -52,7 +52,7 @@ __expr__parse(double *val, struct parse_ctx *ctx, const char 
*expr,
return ret;
 }
 
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr)
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char 
*expr)
 {
return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0;
 }
@@ -75,7 +75,7 @@ int expr__find_other(const char *expr, const char *one, const 
char ***other,
 int *num_other)
 {
int err, i = 0, j = 0;
-   struct parse_ctx ctx;
+   struct expr_parse_ctx ctx;
 
expr__ctx_init();
err = __expr__parse(NULL, , expr, EXPR_OTHER);
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 9377538f4097..b9e53f2b5844 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -5,19 +5,19 @@
 #define EXPR_MAX_OTHER 20
 #define MAX_PARSE_ID EXPR_MAX_OTHER
 
-struct parse_id {
+struct expr_parse_id {
const char *name;
double val;
 };
 
-struct parse_ctx {
+struct expr_parse_ctx {
int num_ids;
-   struct parse_id ids[MAX_PARSE_ID];
+   struct expr_parse_id ids[MAX_PARSE_ID];
 };
 
-void expr__ctx_init(struct parse_ctx *ctx);
-void expr__add_id(struct parse_ctx *ctx, const char *id, double val);
-int expr__parse(double *final_val, struct parse_ctx *ctx, const char *expr);
+void expr__ctx_init(struct expr_parse_ctx *ctx);
+void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
+int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char 
*expr);
 int expr__find_other(const char *expr, const char *one, const char ***other,
int *num_other);
 
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 4720cbe79357..cd17486c1c5d 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -15,7 +15,7 @@
 %define api.pure full
 
 %parse-param { double *final_val }
-%parse-param { struct parse_ctx *ctx }
+%parse-param { struct expr_parse_ctx *ctx }
 %parse-param {void *scanner}
 %lex-param {void* scanner}
 
@@ -39,14 +39,14 @@
 
 %{
 static void expr_error(double *final_val __maybe_unused,
-  struct parse_ctx *ctx __maybe_unused,
+  struct expr_parse_ctx *ctx __maybe_unused,
   void *scanner,
   const char *s)
 {
pr_debug("%s\n", s);
 }
 
-static int lookup_id(struct parse_ctx *ctx, char *id, double *val)

Re: [PATCH vdsotest] Use vdso wrapper for gettimeofday()

2020-04-13 Thread Nathan Lynch
Christophe Leroy  writes:
> Hi Nathan,
>
> Le 16/01/2020 à 17:56, Nathan Lynch a écrit :
>> Hi Christophe,
>> 
>> Christophe Leroy  writes:
>>> To properly handle errors returned by gettimeofday(), the
>>> DO_VDSO_CALL() macro has to be used, otherwise vdsotest
>>> misinterpret VDSO function return on error.
>>>
>>> This has gone unnoticed until now because the powerpc VDSO
>>> gettimeofday() always succeed, but while porting powerpc to
>>> generic C VDSO, the following has been encountered:
>> 
>> Thanks for this, I'll review it soon.
>> 
>> Can you point me to patches for the powerpc generic vdso work?
>> 
>
> I have not seen any update on the vdsotest repository, have you been 
> able to have a look at the patch ?

Thanks for the reminder. I've applied this now.


[PATCH V3 5/5] selftests/powerpc: Add README for GZIP engine tests

2020-04-13 Thread Raphael Moreira Zinsly
Include a README file with the instructions to use the
testcases at selftests/powerpc/nx-gzip.

Signed-off-by: Bulent Abali 
Signed-off-by: Raphael Moreira Zinsly 
---
 .../powerpc/nx-gzip/99-nx-gzip.rules  |  1 +
 .../testing/selftests/powerpc/nx-gzip/README  | 46 +++
 2 files changed, 47 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/README

diff --git a/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules 
b/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
new file mode 100644
index ..5a7118495cb3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="nxgzip", KERNEL=="nx-gzip", MODE="0666"
diff --git a/tools/testing/selftests/powerpc/nx-gzip/README 
b/tools/testing/selftests/powerpc/nx-gzip/README
new file mode 100644
index ..9a491daaef4d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/README
@@ -0,0 +1,46 @@
+Test the nx-gzip function:
+=
+
+Verify that following device exists:
+  /dev/crypto/nx-gzip
+If you get a permission error run as sudo or set the device permissions:
+   sudo chmod go+rw /dev/crypto/nx-gzip
+However, chmod may not survive across boots. You may create a udev file such
+as:
+   /etc/udev/rules.d/99-nx-gzip.rules
+
+
+Then make and run:
+$ make
+gcc -O3 -I./inc -o gzfht_test gzfht_test.c gzip_vas.c
+gcc -O3 -I./inc -o gunz_test gunz_test.c gzip_vas.c
+
+
+Compress any file using Fixed Huffman mode. Output will have a .nx.gz suffix:
+$ ./gzfht_test gzip_vas.c
+file gzip_vas.c read, 6418 bytes
+compressed 6418 to 3131 bytes total, crc32 checksum = 96b9717d
+
+
+Uncompress the previous output. Output will have a .nx.gunzip suffix:
+./gunz_test gzip_vas.c.nx.gz
+gzHeader FLG 0
+00 00 00 00 04 03
+gzHeader MTIME, XFL, OS ignored
+computed checksum 96b9717d isize 1912
+stored   checksum 96b9717d isize 1912
+decomp is complete: fclose
+
+
+Compare two files:
+$ sha1sum gzip_vas.c.nx.gz.nx.gunzip gzip_vas.c
+4c0b494f657c0c89a7d9f87dd3da8597be9a887a  gzip_vas.c.nx.gz.nx.gunzip
+4c0b494f657c0c89a7d9f87dd3da8597be9a887a  gzip_vas.c
+
+
+Note that the code here are intended for testing the nx-gzip hardware function.
+They are not intended for demonstrating performance or compression ratio.
+By being simplistic these selftests expect to allocate the entire set of source
+and target pages in the memory so it needs enough memory to work.
+For more information and source code consider using:
+https://github.com/libnxz/power-gzip
-- 
2.21.0



[PATCH V3 4/5] selftests/powerpc: Add NX-GZIP engine decompress testcase

2020-04-13 Thread Raphael Moreira Zinsly
Include a decompression testcase for the powerpc NX-GZIP
engine.

Signed-off-by: Bulent Abali 
Signed-off-by: Raphael Moreira Zinsly 
---
 .../selftests/powerpc/nx-gzip/Makefile|7 +-
 .../selftests/powerpc/nx-gzip/gunz_test.c | 1026 +
 2 files changed, 1030 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gunz_test.c

diff --git a/tools/testing/selftests/powerpc/nx-gzip/Makefile 
b/tools/testing/selftests/powerpc/nx-gzip/Makefile
index ab903f63bbbd..82abc19a49a0 100644
--- a/tools/testing/selftests/powerpc/nx-gzip/Makefile
+++ b/tools/testing/selftests/powerpc/nx-gzip/Makefile
@@ -1,9 +1,9 @@
 CC = gcc
 CFLAGS = -O3
 INC = ./inc
-SRC = gzfht_test.c
+SRC = gzfht_test.c gunz_test.c
 OBJ = $(SRC:.c=.o)
-TESTS = gzfht_test
+TESTS = gzfht_test gunz_test
 EXTRA_SOURCES = gzip_vas.c
 
 all:   $(TESTS)
@@ -16,6 +16,7 @@ $(TESTS): $(OBJ)
 
 run_tests: $(TESTS)
./gzfht_test gzip_vas.c
+   ./gunz_test gzip_vas.c.nx.gz
 
 clean:
-   rm -f $(TESTS) *.o *~ *.gz
+   rm -f $(TESTS) *.o *~ *.gz *.gunzip
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c 
b/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c
new file mode 100644
index ..94cb79616225
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c
@@ -0,0 +1,1026 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* P9 gunzip sample code for demonstrating the P9 NX hardware
+ * interface.  Not intended for productive uses or for performance or
+ * compression ratio measurements.  Note also that /dev/crypto/gzip,
+ * VAS and skiboot support are required
+ *
+ * Copyright 2020 IBM Corp.
+ *
+ * Author: Bulent Abali 
+ *
+ * https://github.com/libnxz/power-gzip for zlib api and other utils
+ * Definitions of acronyms used here.  See
+ * P9 NX Gzip Accelerator User's Manual for details:
+ * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
+ *
+ * adler/crc: 32 bit checksums appended to stream tail
+ * ce:   completion extension
+ * cpb:  coprocessor parameter block (metadata)
+ * crb:  coprocessor request block (command)
+ * csb:  coprocessor status block (status)
+ * dht:  dynamic huffman table
+ * dde:  data descriptor element (address, length)
+ * ddl:  list of ddes
+ * dh/fh:dynamic and fixed huffman types
+ * fc:   coprocessor function code
+ * histlen:  history/dictionary length
+ * history:  sliding window of up to 32KB of data
+ * lzcount:  Deflate LZ symbol counts
+ * rembytecnt: remaining byte count
+ * sfbt: source final block type; last block's type during decomp
+ * spbc: source processed byte count
+ * subc: source unprocessed bit count
+ * tebc: target ending bit count; valid bits in the last byte
+ * tpbc: target processed byte count
+ * vas:  virtual accelerator switch; the user mode interface
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "nxu.h"
+#include "nx.h"
+#include "crb.h"
+
+int nx_dbg;
+FILE *nx_gzip_log;
+
+#define NX_MIN(X, Y) (((X) < (Y))?(X):(Y))
+#define NX_MAX(X, Y) (((X) > (Y))?(X):(Y))
+
+#define GETINPC(X) fgetc(X)
+#define FNAME_MAX 1024
+
+/* fifo queue management */
+#define fifo_used_bytes(used) (used)
+#define fifo_free_bytes(used, len) ((len)-(used))
+/* amount of free bytes in the first and last parts */
+#define fifo_free_first_bytes(cur, used, len)  cur)+(used)) <= (len)) \
+ ? (len)-((cur)+(used)) : 0)
+#define fifo_free_last_bytes(cur, used, len)   cur)+(used)) <= (len)) \
+ ? (cur) : (len)-(used))
+/* amount of used bytes in the first and last parts */
+#define fifo_used_first_bytes(cur, used, len)  cur)+(used)) <= (len)) \
+ ? (used) : (len)-(cur))
+#define fifo_used_last_bytes(cur, used, len)   cur)+(used)) <= (len)) \
+ ? 0 : ((used)+(cur))-(len))
+/* first and last free parts start here */
+#define fifo_free_first_offset(cur, used)  ((cur)+(used))
+#define fifo_free_last_offset(cur, used, len)  \
+  fifo_used_last_bytes(cur, used, len)
+/* first and last used parts start here */
+#define fifo_used_first_offset(cur)(cur)
+#define fifo_used_last_offset(cur) (0)
+
+const int fifo_in_len = 1<<24;
+const int fifo_out_len = 1<<24;
+const int page_sz = 1<<16;
+const int line_sz = 1<<7;
+const int window_max = 1<<15;
+
+/*
+ * Adds an (address, len) pair to the list of ddes (ddl) and updates
+ * the base dde.  ddl[0] is the only dde in a direct dde which
+ * contains a single (addr,len) pair.  For more pairs, ddl[0] becomes
+ * the indirect (base) dde that points to a list of direct ddes.
+ * 

[PATCH V3 3/5] selftests/powerpc: Add NX-GZIP engine compress testcase

2020-04-13 Thread Raphael Moreira Zinsly
Add a compression testcase for the powerpc NX-GZIP engine.

Signed-off-by: Bulent Abali 
Signed-off-by: Raphael Moreira Zinsly 
---
 .../selftests/powerpc/nx-gzip/Makefile|  21 +
 .../selftests/powerpc/nx-gzip/gzfht_test.c| 432 ++
 .../selftests/powerpc/nx-gzip/gzip_vas.c  | 316 +
 3 files changed, 769 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/Makefile
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gzip_vas.c

diff --git a/tools/testing/selftests/powerpc/nx-gzip/Makefile 
b/tools/testing/selftests/powerpc/nx-gzip/Makefile
new file mode 100644
index ..ab903f63bbbd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/Makefile
@@ -0,0 +1,21 @@
+CC = gcc
+CFLAGS = -O3
+INC = ./inc
+SRC = gzfht_test.c
+OBJ = $(SRC:.c=.o)
+TESTS = gzfht_test
+EXTRA_SOURCES = gzip_vas.c
+
+all:   $(TESTS)
+
+$(OBJ): %.o: %.c
+   $(CC) $(CFLAGS) -I$(INC) -c $<
+
+$(TESTS): $(OBJ)
+   $(CC) $(CFLAGS) -I$(INC) -o $@ $@.o $(EXTRA_SOURCES)
+
+run_tests: $(TESTS)
+   ./gzfht_test gzip_vas.c
+
+clean:
+   rm -f $(TESTS) *.o *~ *.gz
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c 
b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
new file mode 100644
index ..e60f743e2c6b
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
@@ -0,0 +1,432 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* P9 gzip sample code for demonstrating the P9 NX hardware interface.
+ * Not intended for productive uses or for performance or compression
+ * ratio measurements.  For simplicity of demonstration, this sample
+ * code compresses in to fixed Huffman blocks only (Deflate btype=1)
+ * and has very simple memory management.  Dynamic Huffman blocks
+ * (Deflate btype=2) are more involved as detailed in the user guide.
+ * Note also that /dev/crypto/gzip, VAS and skiboot support are
+ * required.
+ *
+ * Copyright 2020 IBM Corp.
+ *
+ * https://github.com/libnxz/power-gzip for zlib api and other utils
+ *
+ * Author: Bulent Abali 
+ *
+ * Definitions of acronyms used here. See
+ * P9 NX Gzip Accelerator User's Manual for details:
+ * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
+ *
+ * adler/crc: 32 bit checksums appended to stream tail
+ * ce:   completion extension
+ * cpb:  coprocessor parameter block (metadata)
+ * crb:  coprocessor request block (command)
+ * csb:  coprocessor status block (status)
+ * dht:  dynamic huffman table
+ * dde:  data descriptor element (address, length)
+ * ddl:  list of ddes
+ * dh/fh:dynamic and fixed huffman types
+ * fc:   coprocessor function code
+ * histlen:  history/dictionary length
+ * history:  sliding window of up to 32KB of data
+ * lzcount:  Deflate LZ symbol counts
+ * rembytecnt: remaining byte count
+ * sfbt: source final block type; last block's type during decomp
+ * spbc: source processed byte count
+ * subc: source unprocessed bit count
+ * tebc: target ending bit count; valid bits in the last byte
+ * tpbc: target processed byte count
+ * vas:  virtual accelerator switch; the user mode interface
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "nxu.h"
+#include "nx.h"
+
+int nx_dbg;
+FILE *nx_gzip_log;
+
+#define NX_MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define FNAME_MAX 1024
+#define FEXT ".nx.gz"
+
+/*
+ * LZ counts returned in the user supplied nx_gzip_crb_cpb_t structure.
+ */
+static int compress_fht_sample(char *src, uint32_t srclen, char *dst,
+   uint32_t dstlen, int with_count,
+   struct nx_gzip_crb_cpb_t *cmdp, void *handle)
+{
+   int cc;
+   uint32_t fc;
+
+   assert(!!cmdp);
+
+   put32(cmdp->crb, gzip_fc, 0);  /* clear */
+   fc = (with_count) ? GZIP_FC_COMPRESS_RESUME_FHT_COUNT :
+   GZIP_FC_COMPRESS_RESUME_FHT;
+   putnn(cmdp->crb, gzip_fc, fc);
+   putnn(cmdp->cpb, in_histlen, 0); /* resuming with no history */
+   memset((void *) >crb.csb, 0, sizeof(cmdp->crb.csb));
+
+   /* Section 6.6 programming notes; spbc may be in two different
+* places depending on FC.
+*/
+   if (!with_count)
+   put32(cmdp->cpb, out_spbc_comp, 0);
+   else
+   put32(cmdp->cpb, out_spbc_comp_with_count, 0);
+
+   /* Figure 6-3 6-4; CSB location */
+   put64(cmdp->crb, csb_address, 0);
+   put64(cmdp->crb, csb_address,
+ (uint64_t) >crb.csb & csb_address_mask);
+
+   /* Source direct dde (scatter-gather list) */
+   clear_dde(cmdp->crb.source_dde);
+   putnn(cmdp->crb.source_dde, dde_count, 0);
+   put32(cmdp->crb.source_dde, 

[PATCH V3 2/5] selftests/powerpc: Add header files for NX compresion/decompression

2020-04-13 Thread Raphael Moreira Zinsly
Add files to be able to compress and decompress files using the
powerpc NX-GZIP engine.

Signed-off-by: Bulent Abali 
Signed-off-by: Raphael Moreira Zinsly 
---
 .../powerpc/nx-gzip/inc/copy-paste.h  |  54 ++
 .../selftests/powerpc/nx-gzip/inc/nx_dbg.h|  95 +++
 .../selftests/powerpc/nx-gzip/inc/nxu.h   | 650 ++
 3 files changed, 799 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/copy-paste.h
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/nx_dbg.h
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/nxu.h

diff --git a/tools/testing/selftests/powerpc/nx-gzip/inc/copy-paste.h 
b/tools/testing/selftests/powerpc/nx-gzip/inc/copy-paste.h
new file mode 100644
index ..107139b6c7df
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/inc/copy-paste.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "nx-helpers.h"
+
+/*
+ * Macros taken from arch/powerpc/include/asm/ppc-opcode.h and other
+ * header files.
+ */
+#define ___PPC_RA(a)(((a) & 0x1f) << 16)
+#define ___PPC_RB(b)(((b) & 0x1f) << 11)
+
+#define PPC_INST_COPY   0x7c20060c
+#define PPC_INST_PASTE  0x7c20070d
+
+#define PPC_COPY(a, b)  stringify_in_c(.long PPC_INST_COPY | \
+   ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \
+   ___PPC_RA(a) | ___PPC_RB(b))
+#define CR0_SHIFT  28
+#define CR0_MASK   0xF
+/*
+ * Copy/paste instructions:
+ *
+ * copy RA,RB
+ * Copy contents of address (RA) + effective_address(RB)
+ * to internal copy-buffer.
+ *
+ * paste RA,RB
+ * Paste contents of internal copy-buffer to the address
+ * (RA) + effective_address(RB)
+ */
+static inline int vas_copy(void *crb, int offset)
+{
+   asm volatile(PPC_COPY(%0, %1)";"
+   :
+   : "b" (offset), "b" (crb)
+   : "memory");
+
+   return 0;
+}
+
+static inline int vas_paste(void *paste_address, int offset)
+{
+   u32 cr;
+
+   cr = 0;
+   asm volatile(PPC_PASTE(%1, %2)";"
+   "mfocrf %0, 0x80;"
+   : "=r" (cr)
+   : "b" (offset), "b" (paste_address)
+   : "memory", "cr0");
+
+   return (cr >> CR0_SHIFT) & CR0_MASK;
+}
diff --git a/tools/testing/selftests/powerpc/nx-gzip/inc/nx_dbg.h 
b/tools/testing/selftests/powerpc/nx-gzip/inc/nx_dbg.h
new file mode 100644
index ..f2c0eee2317e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/inc/nx_dbg.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright 2020 IBM Corporation
+ *
+ */
+
+#ifndef _NXU_DBG_H_
+#define _NXU_DBG_H_
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+extern FILE * nx_gzip_log;
+extern int nx_gzip_trace;
+extern unsigned int nx_gzip_inflate_impl;
+extern unsigned int nx_gzip_deflate_impl;
+extern unsigned int nx_gzip_inflate_flags;
+extern unsigned int nx_gzip_deflate_flags;
+
+extern int nx_dbg;
+pthread_mutex_t mutex_log;
+
+#define nx_gzip_trace_enabled()   (nx_gzip_trace & 0x1)
+#define nx_gzip_hw_trace_enabled()(nx_gzip_trace & 0x2)
+#define nx_gzip_sw_trace_enabled()(nx_gzip_trace & 0x4)
+#define nx_gzip_gather_statistics()   (nx_gzip_trace & 0x8)
+#define nx_gzip_per_stream_stat() (nx_gzip_trace & 0x10)
+
+#define prt(fmt, ...) do { \
+   pthread_mutex_lock(_log); \
+   flock(nx_gzip_log->_fileno, LOCK_EX);   \
+   time_t t; struct tm *m; time(); m = localtime();\
+   fprintf(nx_gzip_log, "[%04d/%02d/%02d %02d:%02d:%02d] " \
+   "pid %d: " fmt, \
+   (int)m->tm_year + 1900, (int)m->tm_mon+1, (int)m->tm_mday, \
+   (int)m->tm_hour, (int)m->tm_min, (int)m->tm_sec,\
+   (int)getpid(), ## __VA_ARGS__); \
+   fflush(nx_gzip_log);\
+   flock(nx_gzip_log->_fileno, LOCK_UN);   \
+   pthread_mutex_unlock(_log);   \
+} while (0)
+
+/* Use in case of an error */
+#define prt_err(fmt, ...) do { if (nx_dbg >= 0) {  \
+   prt("%s:%u: Error: "fmt,\
+   __FILE__, __LINE__, ## __VA_ARGS__);\
+}} while (0)
+
+/* Use in case of an warning */
+#define prt_warn(fmt, ...) do {if (nx_dbg >= 1) {  
\
+   prt("%s:%u: Warning: "fmt,  \
+   __FILE__, __LINE__, ## __VA_ARGS__);\
+}} while (0)
+
+/* Informational printouts */
+#define prt_info(fmt, ...) do {if (nx_dbg >= 2) {  
\
+ 

[PATCH V3 1/5] selftests/powerpc: Add header files for GZIP engine test

2020-04-13 Thread Raphael Moreira Zinsly
Add files to access the powerpc NX-GZIP engine in user space.

Signed-off-by: Bulent Abali 
Signed-off-by: Raphael Moreira Zinsly 
---
 .../selftests/powerpc/nx-gzip/inc/crb.h   | 159 ++
 .../selftests/powerpc/nx-gzip/inc/nx-gzip.h   |  27 +++
 .../powerpc/nx-gzip/inc/nx-helpers.h  |  54 ++
 .../selftests/powerpc/nx-gzip/inc/nx.h|  38 +
 4 files changed, 278 insertions(+)
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/crb.h
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/nx-gzip.h
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/nx-helpers.h
 create mode 100644 tools/testing/selftests/powerpc/nx-gzip/inc/nx.h

diff --git a/tools/testing/selftests/powerpc/nx-gzip/inc/crb.h 
b/tools/testing/selftests/powerpc/nx-gzip/inc/crb.h
new file mode 100644
index ..9056e3dc1831
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/inc/crb.h
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __CRB_H
+#define __CRB_H
+#include 
+#include "nx.h"
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+/* CCW 842 CI/FC masks
+ * NX P8 workbook, section 4.3.1, figure 4-6
+ * "CI/FC Boundary by NX CT type"
+ */
+#define CCW_CI_842  (0x3ff8)
+#define CCW_FC_842  (0x0007)
+
+/* Chapter 6.5.8 Coprocessor-Completion Block (CCB) */
+
+#define CCB_VALUE  (0x3fff)
+#define CCB_ADDRESS(0xfff8)
+#define CCB_CM (0x0007)
+#define CCB_CM0(0x0004)
+#define CCB_CM12   (0x0003)
+
+#define CCB_CM0_ALL_COMPLETIONS(0x0)
+#define CCB_CM0_LAST_IN_CHAIN  (0x4)
+#define CCB_CM12_STORE (0x0)
+#define CCB_CM12_INTERRUPT (0x1)
+
+#define CCB_SIZE   (0x10)
+#define CCB_ALIGN  CCB_SIZE
+
+struct coprocessor_completion_block {
+   __be64 value;
+   __be64 address;
+} __aligned(CCB_ALIGN);
+
+
+/* Chapter 6.5.7 Coprocessor-Status Block (CSB) */
+
+#define CSB_V  (0x80)
+#define CSB_F  (0x04)
+#define CSB_CH (0x03)
+#define CSB_CE_INCOMPLETE  (0x80)
+#define CSB_CE_TERMINATION (0x40)
+#define CSB_CE_TPBC(0x20)
+
+#define CSB_CC_SUCCESS (0)
+#define CSB_CC_INVALID_ALIGN   (1)
+#define CSB_CC_OPERAND_OVERLAP (2)
+#define CSB_CC_DATA_LENGTH (3)
+#define CSB_CC_TRANSLATION (5)
+#define CSB_CC_PROTECTION  (6)
+#define CSB_CC_RD_EXTERNAL (7)
+#define CSB_CC_INVALID_OPERAND (8)
+#define CSB_CC_PRIVILEGE   (9)
+#define CSB_CC_INTERNAL(10)
+#define CSB_CC_WR_EXTERNAL (12)
+#define CSB_CC_NOSPC   (13)
+#define CSB_CC_EXCESSIVE_DDE   (14)
+#define CSB_CC_WR_TRANSLATION  (15)
+#define CSB_CC_WR_PROTECTION   (16)
+#define CSB_CC_UNKNOWN_CODE(17)
+#define CSB_CC_ABORT   (18)
+#define CSB_CC_TRANSPORT   (20)
+#define CSB_CC_SEGMENTED_DDL   (31)
+#define CSB_CC_PROGRESS_POINT  (32)
+#define CSB_CC_DDE_OVERFLOW(33)
+#define CSB_CC_SESSION (34)
+#define CSB_CC_PROVISION   (36)
+#define CSB_CC_CHAIN   (37)
+#define CSB_CC_SEQUENCE(38)
+#define CSB_CC_HW  (39)
+
+#define CSB_SIZE   (0x10)
+#define CSB_ALIGN  CSB_SIZE
+
+struct coprocessor_status_block {
+   u8 flags;
+   u8 cs;
+   u8 cc;
+   u8 ce;
+   __be32 count;
+   __be64 address;
+} __aligned(CSB_ALIGN);
+
+
+/* Chapter 6.5.10 Data-Descriptor List (DDL)
+ * each list contains one or more Data-Descriptor Entries (DDE)
+ */
+
+#define DDE_P  (0x8000)
+
+#define DDE_SIZE   (0x10)
+#define DDE_ALIGN  DDE_SIZE
+
+struct data_descriptor_entry {
+   __be16 flags;
+   u8 count;
+   u8 index;
+   __be32 length;
+   __be64 address;
+} __aligned(DDE_ALIGN);
+
+
+/* Chapter 6.5.2 Coprocessor-Request Block (CRB) */
+
+#define CRB_SIZE   (0x80)
+#define CRB_ALIGN  (0x100) /* Errata: requires 256 alignment */
+
+
+/* Coprocessor Status Block field
+ *   ADDRESS   address of CSB
+ *   C CCB is valid
+ *   AT0 = addrs are virtual, 1 = addrs are phys
+ *   M enable perf monitor
+ */
+#define CRB_CSB_ADDRESS(0xfff0)
+#define CRB_CSB_C  (0x0008)
+#define CRB_CSB_AT (0x0002)
+#define CRB_CSB_M  (0x0001)
+
+struct coprocessor_request_block {
+   __be32 ccw;
+   __be32 flags;
+   __be64 csb_addr;
+
+   struct data_descriptor_entry source;
+   struct data_descriptor_entry target;
+
+   struct coprocessor_completion_block ccb;
+
+   u8 reserved[48];
+
+   struct coprocessor_status_block csb;
+} __aligned(CRB_ALIGN);
+
+#define crb_csb_addr(c) __be64_to_cpu(c->csb_addr)

[PATCH V3 0/5] selftests/powerpc: Add NX-GZIP engine testcase

2020-04-13 Thread Raphael Moreira Zinsly


This patch series are intended to test the POWER9 Nest
Accelerator (NX) GZIP engine that is being introduced by
https://lists.ozlabs.org/pipermail/linuxppc-dev/2020-March/205659.html
More information about how to access the NX can be found in that patch, also a
complete userspace library and more documentation can be found at:
https://github.com/libnxz/power-gzip

Changes in V3:
- Defined a macro and increased the number of retries for page faults
  to work in system with less memory, mentioning the issue on README.
- Returned to use volatile on the touch pages routine and a few structs
  on inc/nxu.h as they are handled by hardware and some compilers could
  optmize it wrongly.
- Moved common functions to gzip_vas.c.



Re: [PATCH] papr/scm: Add bad memory ranges to nvdimm bad ranges

2020-04-13 Thread Santosh Sivaraj
Mahesh J Salgaonkar  writes:

> On 2020-04-01 13:17:41 Wed, Santosh Sivaraj wrote:
>> Subscribe to the MCE notification and add the physical address which
>> generated a memory error to nvdimm bad range.
>> 
>> Signed-off-by: Santosh Sivaraj 
>> ---
>> 
>> This patch depends on "powerpc/mce: Add MCE notification chain" [1].
>> 
>> Unlike the previous series[2], the patch adds badblock registration only for
>> pseries scm driver. Handling badblocks for baremetal (powernv) PMEM will be 
>> done
>> later and if possible get the badblock handling as a common code.
>> 
>> [1] 
>> https://lore.kernel.org/linuxppc-dev/20200330071219.12284-1-ganes...@linux.ibm.com/
>> [2] 
>> https://lore.kernel.org/linuxppc-dev/20190820023030.18232-1-sant...@fossix.org/
>> 
>> arch/powerpc/platforms/pseries/papr_scm.c | 96 ++-
>>  1 file changed, 95 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/powerpc/platforms/pseries/papr_scm.c 
>> b/arch/powerpc/platforms/pseries/papr_scm.c
>> index 0b4467e378e5..5012cbf4606e 100644
>> --- a/arch/powerpc/platforms/pseries/papr_scm.c
>> +++ b/arch/powerpc/platforms/pseries/papr_scm.c
> [...]
>> +static int handle_mce_ue(struct notifier_block *nb, unsigned long val,
>> + void *data)
>> +{
>> +struct machine_check_event *evt = data;
>> +struct papr_scm_priv *p;
>> +u64 phys_addr;
>> +bool found = false;
>> +
>> +if (evt->error_type != MCE_ERROR_TYPE_UE)
>> +return NOTIFY_DONE;
>> +
>> +if (list_empty(_nd_regions))
>> +return NOTIFY_DONE;
>
> Do you really need this check ?

Quite harmless I guess, atleast it saves a branch and mutex_lock/unlock.

>
>> +
>> +phys_addr = evt->u.ue_error.physical_address +
>> +(evt->u.ue_error.effective_address & ~PAGE_MASK);
>> +
>> +if (!evt->u.ue_error.physical_address_provided ||
>> +!is_zone_device_page(pfn_to_page(phys_addr >> PAGE_SHIFT)))
>> +return NOTIFY_DONE;
>> +
>> +/* mce notifier is called from a process context, so mutex is safe */
>> +mutex_lock(_ndr_lock);
>> +list_for_each_entry(p, _nd_regions, region_list) {
>> +struct resource res = p->res;
>> +
>> +if (phys_addr >= res.start && phys_addr <= res.end) {
>> +found = true;
>> +break;
>> +}
>> +}
>> +
>> +mutex_unlock(_ndr_lock);
>> +
>> +if (!found)
>> +return NOTIFY_DONE;
>> +
>> +papr_scm_add_badblock(p->region, p->bus, phys_addr);
>> +
>> +return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block mce_ue_nb = {
>> +.notifier_call = handle_mce_ue
>> +};
>> +
> [...]
>> -module_platform_driver(papr_scm_driver);
>> +static int __init papr_scm_init(void)
>> +{
>> +int ret;
>> +
>> +ret = platform_driver_register(_scm_driver);
>> +if (!ret)
>> +mce_register_notifier(_ue_nb);
>> +
>> +return ret;
>> +}
>> +module_init(papr_scm_init);
>> +
>> +static void __exit papr_scm_exit(void)
>> +{
>> +mce_unregister_notifier(_ue_nb);
>> +platform_driver_unregister(_scm_driver);
>> +}
>> +module_exit(papr_scm_exit);
>
> Rest Looks good to me.
>
> Reviewed-by: Mahesh Salgaonkar 

Thanks for the review.

Santosh
>
> Thanks,
> -Mahesh.
>
>> +
>>  MODULE_DEVICE_TABLE(of, papr_scm_match);
>>  MODULE_LICENSE("GPL");
>>  MODULE_AUTHOR("IBM Corporation");
>> -- 
>> 2.25.1
>> 
>
> -- 
> Mahesh J Salgaonkar


Re: [PATCH] papr/scm: Add bad memory ranges to nvdimm bad ranges

2020-04-13 Thread Mahesh J Salgaonkar
On 2020-04-01 13:17:41 Wed, Santosh Sivaraj wrote:
> Subscribe to the MCE notification and add the physical address which
> generated a memory error to nvdimm bad range.
> 
> Signed-off-by: Santosh Sivaraj 
> ---
> 
> This patch depends on "powerpc/mce: Add MCE notification chain" [1].
> 
> Unlike the previous series[2], the patch adds badblock registration only for
> pseries scm driver. Handling badblocks for baremetal (powernv) PMEM will be 
> done
> later and if possible get the badblock handling as a common code.
> 
> [1] 
> https://lore.kernel.org/linuxppc-dev/20200330071219.12284-1-ganes...@linux.ibm.com/
> [2] 
> https://lore.kernel.org/linuxppc-dev/20190820023030.18232-1-sant...@fossix.org/
> 
> arch/powerpc/platforms/pseries/papr_scm.c | 96 ++-
>  1 file changed, 95 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/papr_scm.c 
> b/arch/powerpc/platforms/pseries/papr_scm.c
> index 0b4467e378e5..5012cbf4606e 100644
> --- a/arch/powerpc/platforms/pseries/papr_scm.c
> +++ b/arch/powerpc/platforms/pseries/papr_scm.c
[...]
> +static int handle_mce_ue(struct notifier_block *nb, unsigned long val,
> +  void *data)
> +{
> + struct machine_check_event *evt = data;
> + struct papr_scm_priv *p;
> + u64 phys_addr;
> + bool found = false;
> +
> + if (evt->error_type != MCE_ERROR_TYPE_UE)
> + return NOTIFY_DONE;
> +
> + if (list_empty(_nd_regions))
> + return NOTIFY_DONE;

Do you really need this check ?

> +
> + phys_addr = evt->u.ue_error.physical_address +
> + (evt->u.ue_error.effective_address & ~PAGE_MASK);
> +
> + if (!evt->u.ue_error.physical_address_provided ||
> + !is_zone_device_page(pfn_to_page(phys_addr >> PAGE_SHIFT)))
> + return NOTIFY_DONE;
> +
> + /* mce notifier is called from a process context, so mutex is safe */
> + mutex_lock(_ndr_lock);
> + list_for_each_entry(p, _nd_regions, region_list) {
> + struct resource res = p->res;
> +
> + if (phys_addr >= res.start && phys_addr <= res.end) {
> + found = true;
> + break;
> + }
> + }
> +
> + mutex_unlock(_ndr_lock);
> +
> + if (!found)
> + return NOTIFY_DONE;
> +
> + papr_scm_add_badblock(p->region, p->bus, phys_addr);
> +
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block mce_ue_nb = {
> + .notifier_call = handle_mce_ue
> +};
> +
[...]
> -module_platform_driver(papr_scm_driver);
> +static int __init papr_scm_init(void)
> +{
> + int ret;
> +
> + ret = platform_driver_register(_scm_driver);
> + if (!ret)
> + mce_register_notifier(_ue_nb);
> +
> + return ret;
> +}
> +module_init(papr_scm_init);
> +
> +static void __exit papr_scm_exit(void)
> +{
> + mce_unregister_notifier(_ue_nb);
> + platform_driver_unregister(_scm_driver);
> +}
> +module_exit(papr_scm_exit);

Rest Looks good to me.

Reviewed-by: Mahesh Salgaonkar 

Thanks,
-Mahesh.

> +
>  MODULE_DEVICE_TABLE(of, papr_scm_match);
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("IBM Corporation");
> -- 
> 2.25.1
> 

-- 
Mahesh J Salgaonkar



[Bug 205099] KASAN hit at raid6_pq: BUG: Unable to handle kernel data access at 0x00f0fd0d

2020-04-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205099

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Attachment #287623|0   |1
is obsolete||

--- Comment #29 from Erhard F. (erhar...@mailbox.org) ---
Created attachment 288413
  --> https://bugzilla.kernel.org/attachment.cgi?id=288413=edit
kernel .config (5.7-rc1, OUTLINE KASAN, PowerMac G4 DP)

-- 
You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 205099] KASAN hit at raid6_pq: BUG: Unable to handle kernel data access at 0x00f0fd0d

2020-04-13 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=205099

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Attachment #287621|0   |1
is obsolete||

--- Comment #28 from Erhard F. (erhar...@mailbox.org) ---
Created attachment 288411
  --> https://bugzilla.kernel.org/attachment.cgi?id=288411=edit
dmesg (5.7-rc1, OUTLINE KASAN, PowerMac G4 DP)

Re-tested with v5.7-rc1 out of curiosity. Not much change here, the bug shows
up with OUTLINE KASAN but not with INLINE KASAN, everything else being equal.

[...]
Apr 13 16:01:11 T600 kernel: BUG: Unable to handle kernel data access on read
at 0x0050a0f0
Apr 13 16:01:11 T600 kernel: Faulting instruction address: 0xf1aa1564
Apr 13 16:01:11 T600 kernel: Oops: Kernel access of bad area, sig: 11 [#1]
Apr 13 16:01:11 T600 kernel: BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=2 PowerMac
Apr 13 16:01:11 T600 kernel: Modules linked in: raid6_pq(+) zlib_inflate
firewire_ohci firewire_core ehci_pci(+) ohci_hcd crc_itu_t sr_mod cdrom
ehci_hcd snd_aoa_i2sbus snd_aoa_soundbus snd_pcm snd_timer snd ss>
Apr 13 16:01:11 T600 kernel: CPU: 0 PID: 149 Comm: modprobe Tainted: GW
5.7.0-rc1-PowerMacG4+ #1
Apr 13 16:01:11 T600 kernel: NIP:  f1aa1564 LR: f1aa14e8 CTR: c0255b78
Apr 13 16:01:11 T600 kernel: REGS: f1963780 TRAP: 0300   Tainted: GW   
  (5.7.0-rc1-PowerMacG4+)
Apr 13 16:01:11 T600 kernel: MSR:  02009032   CR: 28228828 
XER: 
Apr 13 16:01:11 T600 kernel: DAR: 0050a0f0 DSISR: 4000 
 GPR00: f19639d8 f1963838 ebd1de60 eb1dc070
1000 0003 f1aa14e8  
 GPR08:  0050a0f0 5d0dfdad fff0
c0255b78 00a48ff4 0060 0050 
 GPR16: eb1dc000 eb1df000 eb1de000 0070
0060 0050 0040 0030 
 GPR24: 0020 0010 0008 f1963a8c
f1963a78 eb1df010 eb1de010  
Apr 13 16:01:11 T600 kernel: NIP [f1aa1564]
raid6_altivec8_gen_syndrome_real+0x3c4/0x480 [raid6_pq]
Apr 13 16:01:11 T600 kernel: LR [f1aa14e8]
raid6_altivec8_gen_syndrome_real+0x348/0x480 [raid6_pq]
Apr 13 16:01:11 T600 kernel: Call Trace:
Apr 13 16:01:11 T600 kernel: [f1963838] [000a] 0xa (unreliable)
Apr 13 16:01:11 T600 kernel: [f1963a28] [f1aa1654]
raid6_altivec8_gen_syndrome+0x34/0x58 [raid6_pq]
Apr 13 16:01:11 T600 kernel: [f1963a48] [f12603cc] init_module+0x3cc/0x530
[raid6_pq]
Apr 13 16:01:11 T600 kernel: [f1963b18] [c00058e4] do_one_initcall+0xb8/0x36c
Apr 13 16:01:11 T600 kernel: [f1963be8] [c0117f64] do_init_module+0xa8/0x2c4
Apr 13 16:01:11 T600 kernel: [f1963c18] [c011ae38] load_module+0x2bd8/0x2d5c
Apr 13 16:01:11 T600 kernel: [f1963e18] [c011b230] sys_finit_module+0x100/0x138
Apr 13 16:01:11 T600 kernel: [f1963f38] [c001a224] ret_from_syscall+0x0/0x34
Apr 13 16:01:11 T600 kernel: --- interrupt: c01 at 0x892988
 LR = 0xa20a14
Apr 13 16:01:11 T600 kernel: Instruction dump:
Apr 13 16:01:11 T600 kernel: 1304c4c4 7d2048ce 39210090 1325ccc4 7d6048ce
1346d4c4 81210088 1367dcc4 
Apr 13 16:01:11 T600 kernel: 8141008c 11284cc4 115f5b06 116b5800 <7c0048ce>
392100a0 7d8048ce 392100b0 
Apr 13 16:01:11 T600 kernel: ---[ end trace ebe3b589d509d4f6 ]---
[...]

-- 
You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH v2 4/4] mm/vmalloc: Hugepage vmalloc mappings

2020-04-13 Thread Matthew Wilcox
On Mon, Apr 13, 2020 at 10:53:03PM +1000, Nicholas Piggin wrote:
> +static int vmap_pages_range_noflush(unsigned long start, unsigned long end,
> + pgprot_t prot, struct page **pages,
> + unsigned int page_shift)
> +{
> + if (page_shift == PAGE_SIZE) {

... I think you meant 'page_shift == PAGE_SHIFT'

Overall I like this series, although it's a bit biased towards CPUs
which have page sizes which match PMD/PUD sizes.  It doesn't offer the
possibility of using 64kB page sizes on ARM, for example.  But it's a
step in the right direction.


Re: [PATCH v2 1/4] mm/vmalloc: fix vmalloc_to_page for huge vmap mappings

2020-04-13 Thread Matthew Wilcox
On Mon, Apr 13, 2020 at 10:53:00PM +1000, Nicholas Piggin wrote:
> vmalloc_to_page returns NULL for addresses mapped by larger pages[*].
> Whether or not a vmap is huge depends on the architecture details,
> alignments, boot options, etc., which the caller can not be expected
> to know. Therefore HUGE_VMAP is a regression for vmalloc_to_page.
> 
> This change teaches vmalloc_to_page about larger pages, and returns
> the struct page that corresponds to the offset within the large page.
> This makes the API agnostic to mapping implementation details.

I'm trying to get us away from returning tail pages from various
functions.  How much of a pain would it be to return the head page
instead of the tail page?  Obviously the implementation gets simpler,
but can the callers cope?  I've been focusing on the page cache, so I
haven't been looking at the vmalloc side of things at all.


[PATCH v2 4/4] mm/vmalloc: Hugepage vmalloc mappings

2020-04-13 Thread Nicholas Piggin
For platforms that define HAVE_ARCH_HUGE_VMAP and support PMD vmap mappings,
have vmalloc attempt to allocate PMD-sized pages first, before falling back
to small pages. Allocations which use something other than PAGE_KERNEL
protections are not permitted to use huge pages yet, not all callers expect
this (e.g., module allocations vs strict module rwx).

This gives a 6x reduction in dTLB misses for a `git diff` (of linux), from
45600 to 6500 and a 2.2% reduction in cycles on a 2-node POWER9.

This can result in more internal fragmentation and memory overhead for a
given allocation. It can also cause greater NUMA unbalance on hashdist
allocations.

There may be other callers that expect small pages under vmalloc but use
PAGE_KERNEL, I'm not sure if it's feasible to catch them all. An
alternative would be a new function or flag which enables large mappings,
and use that in callers.

Signed-off-by: Nicholas Piggin 
---
 include/linux/vmalloc.h |   2 +
 mm/vmalloc.c| 135 +---
 2 files changed, 102 insertions(+), 35 deletions(-)

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 291313a7e663..853b82eac192 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -24,6 +24,7 @@ struct notifier_block;/* in notifier.h */
 #define VM_UNINITIALIZED   0x0020  /* vm_struct is not fully 
initialized */
 #define VM_NO_GUARD0x0040  /* don't add guard page */
 #define VM_KASAN   0x0080  /* has allocated kasan shadow 
memory */
+#define VM_HUGE_PAGES  0x0100  /* may use huge pages */
 
 /*
  * VM_KASAN is used slighly differently depending on CONFIG_KASAN_VMALLOC.
@@ -58,6 +59,7 @@ struct vm_struct {
unsigned long   size;
unsigned long   flags;
struct page **pages;
+   unsigned intpage_order;
unsigned intnr_pages;
phys_addr_t phys_addr;
const void  *caller;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index c898d16ddd25..7b7e992c5ff1 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -436,7 +436,7 @@ static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long 
addr,
  *
  * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N]
  */
-static int vmap_pages_range_noflush(unsigned long start, unsigned long end,
+static int vmap_small_pages_range_noflush(unsigned long start, unsigned long 
end,
   pgprot_t prot, struct page **pages)
 {
pgd_t *pgd;
@@ -457,13 +457,44 @@ static int vmap_pages_range_noflush(unsigned long start, 
unsigned long end,
return nr;
 }
 
+static int vmap_pages_range_noflush(unsigned long start, unsigned long end,
+   pgprot_t prot, struct page **pages,
+   unsigned int page_shift)
+{
+   if (page_shift == PAGE_SIZE) {
+   return vmap_small_pages_range_noflush(start, end, prot, pages);
+   } else {
+   unsigned long addr = start;
+   unsigned int i, nr = (end - start) >> page_shift;
+
+   for (i = 0; i < nr; i++) {
+   int err;
+
+   err = vmap_range_noflush(addr,
+   addr + (1UL << page_shift),
+   __pa(page_address(pages[i])), prot,
+   page_shift);
+   if (err)
+   return err;
+
+   addr += 1UL << page_shift;
+   }
+
+   return 0;
+   }
+}
+
 static int vmap_pages_range(unsigned long start, unsigned long end,
-  pgprot_t prot, struct page **pages)
+   pgprot_t prot, struct page **pages,
+   unsigned int page_shift)
 {
int ret;
 
-   ret = vmap_pages_range_noflush(start, end, prot, pages);
+   BUG_ON(page_shift < PAGE_SHIFT);
+
+   ret = vmap_pages_range_noflush(start, end, prot, pages, page_shift);
flush_cache_vmap(start, end);
+
return ret;
 }
 
@@ -2064,7 +2095,7 @@ void *vm_map_ram(struct page **pages, unsigned int count, 
int node, pgprot_t pro
 
kasan_unpoison_vmalloc(mem, size);
 
-   if (vmap_pages_range(addr, addr + size, prot, pages) < 0) {
+   if (vmap_pages_range(addr, addr + size, prot, pages, PAGE_SHIFT) < 0) {
vm_unmap_ram(mem, count);
return NULL;
}
@@ -2230,7 +2261,7 @@ void __init vmalloc_init(void)
 int map_kernel_range_noflush(unsigned long addr, unsigned long size,
 pgprot_t prot, struct page **pages)
 {
-   return vmap_pages_range_noflush(addr, addr + size, prot, pages);
+   return vmap_pages_range_noflush(addr, addr + size, prot, pages, 
PAGE_SHIFT);
 }
 
 /**
@@ -2277,7 +2308,7 @@ int 

[PATCH v2 3/4] mm: HUGE_VMAP arch query functions cleanup

2020-04-13 Thread Nicholas Piggin
This changes the awkward approach where architectures provide init
functions to determine which levels they can provide large mappings for,
to one where the arch is queried for each call.

This allows odd configurations to be allowed (PUD but not PMD), and will
make it easier to constant-fold dead code away if the arch inlines
unsupported levels.

This also adds a prot argument to the arch query. This is unused
currently but could help with some architectures (some powerpc
implementations can't map uncacheable memory with large pages for
example).

The name is changed from ioremap to vmap, as it will be used more
generally in the next patch.

Signed-off-by: Nicholas Piggin 
---
 arch/arm64/mm/mmu.c  |  8 ++--
 arch/powerpc/mm/book3s64/radix_pgtable.c |  6 +--
 arch/x86/mm/ioremap.c|  6 +--
 include/linux/io.h   |  3 --
 include/linux/vmalloc.h  | 10 +
 lib/ioremap.c| 51 ++--
 mm/vmalloc.c |  9 +
 7 files changed, 33 insertions(+), 60 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a374e4f51a62..b8e381c46fa1 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1244,12 +1244,12 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int 
*size, pgprot_t prot)
return dt_virt;
 }
 
-int __init arch_ioremap_p4d_supported(void)
+bool arch_vmap_p4d_supported(pgprot_t prot)
 {
return 0;
 }
 
-int __init arch_ioremap_pud_supported(void)
+bool arch_vmap_pud_supported(pgprot_t prot)
 {
/*
 * Only 4k granule supports level 1 block mappings.
@@ -1259,9 +1259,9 @@ int __init arch_ioremap_pud_supported(void)
   !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS);
 }
 
-int __init arch_ioremap_pmd_supported(void)
+bool arch_vmap_pmd_supported(pgprot_t prot)
 {
-   /* See arch_ioremap_pud_supported() */
+   /* See arch_vmap_pud_supported() */
return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS);
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 8f9edf07063a..5130e7912dd4 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -1091,13 +1091,13 @@ void radix__ptep_modify_prot_commit(struct 
vm_area_struct *vma,
set_pte_at(mm, addr, ptep, pte);
 }
 
-int __init arch_ioremap_pud_supported(void)
+bool arch_vmap_pud_supported(pgprot_t prot)
 {
/* HPT does not cope with large pages in the vmalloc area */
return radix_enabled();
 }
 
-int __init arch_ioremap_pmd_supported(void)
+bool arch_vmap_pmd_supported(pgprot_t prot)
 {
return radix_enabled();
 }
@@ -1191,7 +1191,7 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
return 1;
 }
 
-int __init arch_ioremap_p4d_supported(void)
+bool arch_vmap_p4d_supported(pgprot_t prot)
 {
return 0;
 }
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 18c637c0dc6f..bb4b75c344e4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -481,12 +481,12 @@ void iounmap(volatile void __iomem *addr)
 }
 EXPORT_SYMBOL(iounmap);
 
-int __init arch_ioremap_p4d_supported(void)
+bool arch_vmap_p4d_supported(pgprot_t prot)
 {
return 0;
 }
 
-int __init arch_ioremap_pud_supported(void)
+bool arch_vmap_pud_supported(pgprot_t prot)
 {
 #ifdef CONFIG_X86_64
return boot_cpu_has(X86_FEATURE_GBPAGES);
@@ -495,7 +495,7 @@ int __init arch_ioremap_pud_supported(void)
 #endif
 }
 
-int __init arch_ioremap_pmd_supported(void)
+bool arch_vmap_pmd_supported(pgprot_t prot)
 {
return boot_cpu_has(X86_FEATURE_PSE);
 }
diff --git a/include/linux/io.h b/include/linux/io.h
index 8394c56babc2..2832e051bc2e 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -33,9 +33,6 @@ static inline int ioremap_page_range(unsigned long addr, 
unsigned long end,
 
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
 void __init ioremap_huge_init(void);
-int arch_ioremap_p4d_supported(void);
-int arch_ioremap_pud_supported(void);
-int arch_ioremap_pmd_supported(void);
 #else
 static inline void ioremap_huge_init(void) { }
 #endif
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index eb8a5080e472..291313a7e663 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -84,6 +84,16 @@ struct vmap_area {
};
 };
 
+#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
+bool arch_vmap_p4d_supported(pgprot_t prot);
+bool arch_vmap_pud_supported(pgprot_t prot);
+bool arch_vmap_pmd_supported(pgprot_t prot);
+#else
+static inline bool arch_vmap_p4d_supported(pgprot_t prot) { return false; }
+static inline bool arch_vmap_pud_supported(pgprot_t prot) { return false; }
+static inline bool arch_vmap_pmd_supported(prprot_t prot) { return false; }
+#endif
+
 /*
  * Highlevel APIs for driver use
  */
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 7e383bdc51ad..0a1ddf1a1286 100644
--- a/lib/ioremap.c
+++ 

[PATCH v2 2/4] mm: Move ioremap page table mapping function to mm/

2020-04-13 Thread Nicholas Piggin
ioremap_page_range is a generic function to create a kernel virtual
mapping, move it to mm/vmalloc.c and rename it vmap_range.

For clarity with this move, also:
- Rename vunmap_page_range (vmap_range's inverse) to vunmap_range.
- Rename vmap_pages_range (which takes a page array) to vmap_pages.

Signed-off-by: Nicholas Piggin 
---
 include/linux/vmalloc.h |   3 +
 lib/ioremap.c   | 182 +++---
 mm/vmalloc.c| 239 
 3 files changed, 239 insertions(+), 185 deletions(-)

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 0507a162ccd0..eb8a5080e472 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -173,6 +173,9 @@ extern struct vm_struct *find_vm_area(const void *addr);
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
struct page **pages);
 #ifdef CONFIG_MMU
+int vmap_range(unsigned long addr,
+  unsigned long end, phys_addr_t phys_addr, pgprot_t prot,
+  unsigned int max_page_shift);
 extern int map_kernel_range_noflush(unsigned long start, unsigned long size,
pgprot_t prot, struct page **pages);
 extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size);
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 3f0e18543de8..7e383bdc51ad 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -60,176 +60,26 @@ static inline int ioremap_pud_enabled(void) { return 0; }
 static inline int ioremap_pmd_enabled(void) { return 0; }
 #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
 
-static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
-{
-   pte_t *pte;
-   u64 pfn;
-
-   pfn = phys_addr >> PAGE_SHIFT;
-   pte = pte_alloc_kernel(pmd, addr);
-   if (!pte)
-   return -ENOMEM;
-   do {
-   BUG_ON(!pte_none(*pte));
-   set_pte_at(_mm, addr, pte, pfn_pte(pfn, prot));
-   pfn++;
-   } while (pte++, addr += PAGE_SIZE, addr != end);
-   return 0;
-}
-
-static int ioremap_try_huge_pmd(pmd_t *pmd, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr,
-   pgprot_t prot)
-{
-   if (!ioremap_pmd_enabled())
-   return 0;
-
-   if ((end - addr) != PMD_SIZE)
-   return 0;
-
-   if (!IS_ALIGNED(addr, PMD_SIZE))
-   return 0;
-
-   if (!IS_ALIGNED(phys_addr, PMD_SIZE))
-   return 0;
-
-   if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr))
-   return 0;
-
-   return pmd_set_huge(pmd, phys_addr, prot);
-}
-
-static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
-{
-   pmd_t *pmd;
-   unsigned long next;
-
-   pmd = pmd_alloc(_mm, pud, addr);
-   if (!pmd)
-   return -ENOMEM;
-   do {
-   next = pmd_addr_end(addr, end);
-
-   if (ioremap_try_huge_pmd(pmd, addr, next, phys_addr, prot))
-   continue;
-
-   if (ioremap_pte_range(pmd, addr, next, phys_addr, prot))
-   return -ENOMEM;
-   } while (pmd++, phys_addr += (next - addr), addr = next, addr != end);
-   return 0;
-}
-
-static int ioremap_try_huge_pud(pud_t *pud, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr,
-   pgprot_t prot)
-{
-   if (!ioremap_pud_enabled())
-   return 0;
-
-   if ((end - addr) != PUD_SIZE)
-   return 0;
-
-   if (!IS_ALIGNED(addr, PUD_SIZE))
-   return 0;
-
-   if (!IS_ALIGNED(phys_addr, PUD_SIZE))
-   return 0;
-
-   if (pud_present(*pud) && !pud_free_pmd_page(pud, addr))
-   return 0;
-
-   return pud_set_huge(pud, phys_addr, prot);
-}
-
-static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
-{
-   pud_t *pud;
-   unsigned long next;
-
-   pud = pud_alloc(_mm, p4d, addr);
-   if (!pud)
-   return -ENOMEM;
-   do {
-   next = pud_addr_end(addr, end);
-
-   if (ioremap_try_huge_pud(pud, addr, next, phys_addr, prot))
-   continue;
-
-   if (ioremap_pmd_range(pud, addr, next, phys_addr, prot))
-   return -ENOMEM;
-   } while (pud++, phys_addr += (next - addr), addr = next, addr != end);
-   return 0;
-}
-
-static int ioremap_try_huge_p4d(p4d_t *p4d, unsigned long addr,
-   unsigned long end, phys_addr_t phys_addr,
-   pgprot_t prot)
-{
-   if (!ioremap_p4d_enabled())
-   return 0;
-
-   if 

[PATCH v2 1/4] mm/vmalloc: fix vmalloc_to_page for huge vmap mappings

2020-04-13 Thread Nicholas Piggin
vmalloc_to_page returns NULL for addresses mapped by larger pages[*].
Whether or not a vmap is huge depends on the architecture details,
alignments, boot options, etc., which the caller can not be expected
to know. Therefore HUGE_VMAP is a regression for vmalloc_to_page.

This change teaches vmalloc_to_page about larger pages, and returns
the struct page that corresponds to the offset within the large page.
This makes the API agnostic to mapping implementation details.

[*] As explained by commit 029c54b095995 ("mm/vmalloc.c: huge-vmap:
fail gracefully on unexpected huge vmap mappings")

Signed-off-by: Nicholas Piggin 
---
 mm/vmalloc.c | 40 ++--
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 399f219544f7..1afec7def23f 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -36,6 +36,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 
@@ -272,7 +273,9 @@ int is_vmalloc_or_module_addr(const void *x)
 }
 
 /*
- * Walk a vmap address to the struct page it maps.
+ * Walk a vmap address to the struct page it maps. Huge vmap mappings will
+ * return the tail page that corresponds to the base page address, which
+ * matches small vmap mappings.
  */
 struct page *vmalloc_to_page(const void *vmalloc_addr)
 {
@@ -292,25 +295,33 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
 
if (pgd_none(*pgd))
return NULL;
+   if (WARN_ON_ONCE(pgd_leaf(*pgd)))
+   return NULL; /* XXX: no allowance for huge pgd */
+   if (WARN_ON_ONCE(pgd_bad(*pgd)))
+   return NULL;
+
p4d = p4d_offset(pgd, addr);
if (p4d_none(*p4d))
return NULL;
-   pud = pud_offset(p4d, addr);
+   if (p4d_leaf(*p4d))
+   return p4d_page(*p4d) + ((addr & ~P4D_MASK) >> PAGE_SHIFT);
+   if (WARN_ON_ONCE(p4d_bad(*p4d)))
+   return NULL;
 
-   /*
-* Don't dereference bad PUD or PMD (below) entries. This will also
-* identify huge mappings, which we may encounter on architectures
-* that define CONFIG_HAVE_ARCH_HUGE_VMAP=y. Such regions will be
-* identified as vmalloc addresses by is_vmalloc_addr(), but are
-* not [unambiguously] associated with a struct page, so there is
-* no correct value to return for them.
-*/
-   WARN_ON_ONCE(pud_bad(*pud));
-   if (pud_none(*pud) || pud_bad(*pud))
+   pud = pud_offset(p4d, addr);
+   if (pud_none(*pud))
+   return NULL;
+   if (pud_leaf(*pud))
+   return pud_page(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
+   if (WARN_ON_ONCE(pud_bad(*pud)))
return NULL;
+
pmd = pmd_offset(pud, addr);
-   WARN_ON_ONCE(pmd_bad(*pmd));
-   if (pmd_none(*pmd) || pmd_bad(*pmd))
+   if (pmd_none(*pmd))
+   return NULL;
+   if (pmd_leaf(*pmd))
+   return pmd_page(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+   if (WARN_ON_ONCE(pmd_bad(*pmd)))
return NULL;
 
ptep = pte_offset_map(pmd, addr);
@@ -318,6 +329,7 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
if (pte_present(pte))
page = pte_page(pte);
pte_unmap(ptep);
+
return page;
 }
 EXPORT_SYMBOL(vmalloc_to_page);
-- 
2.23.0



[PATCH v2 0/4] huge vmalloc mappings

2020-04-13 Thread Nicholas Piggin
We can get a significant win with larger mappings for some of the big
global hashes.

Since RFC, relevant architectures have added p?d_leaf accessors so no
real arch changes required, and I changed it not to allocate huge
mappings for modules and a bunch of other fixes.

Nicholas Piggin (4):
  mm/vmalloc: fix vmalloc_to_page for huge vmap mappings
  mm: Move ioremap page table mapping function to mm/
  mm: HUGE_VMAP arch query functions cleanup
  mm/vmalloc: Hugepage vmalloc mappings

 arch/arm64/mm/mmu.c  |   8 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c |   6 +-
 arch/x86/mm/ioremap.c|   6 +-
 include/linux/io.h   |   3 -
 include/linux/vmalloc.h  |  15 +
 lib/ioremap.c| 203 +--
 mm/vmalloc.c | 413 +++
 7 files changed, 380 insertions(+), 274 deletions(-)

-- 
2.23.0



Re: [PATCH v5 18/21] powerpc64: Add prefixed instructions to instruction data type

2020-04-13 Thread Balamuruhan S
On Mon, 2020-04-06 at 18:09 +1000, Jordan Niethe wrote:
> For powerpc64, redefine the ppc_inst type so both word and prefixed
> instructions can be represented. On powerpc32 the type will remain the
> same.  Update places which had assumed instructions to be 4 bytes long.
> 
> Signed-off-by: Jordan Niethe 
> ---
> v4: New to series
> v5:  - Distinguish normal instructions from prefixed instructions with a
>0xff marker for the suffix.
>  - __patch_instruction() using std for prefixed instructions
> ---
>  arch/powerpc/include/asm/inst.h  | 71 ++--
>  arch/powerpc/include/asm/kprobes.h   |  2 +-
>  arch/powerpc/include/asm/uaccess.h   | 31 ++--
>  arch/powerpc/include/asm/uprobes.h   |  2 +-
>  arch/powerpc/kernel/optprobes.c  | 42 
>  arch/powerpc/kernel/optprobes_head.S |  3 ++
>  arch/powerpc/kernel/trace/ftrace.c   | 26 +-
>  arch/powerpc/lib/code-patching.c | 19 +---
>  arch/powerpc/lib/feature-fixups.c|  5 +-
>  arch/powerpc/lib/sstep.c |  4 +-
>  arch/powerpc/xmon/xmon.c |  6 +--
>  arch/powerpc/xmon/xmon_bpts.S|  4 +-
>  12 files changed, 171 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/inst.h
> b/arch/powerpc/include/asm/inst.h
> index 70b37a35a91a..7e23e7146c66 100644
> --- a/arch/powerpc/include/asm/inst.h
> +++ b/arch/powerpc/include/asm/inst.h
> @@ -8,23 +8,67 @@
>  
>  struct ppc_inst {
>  u32 val;
> +#ifdef __powerpc64__
> +u32 suffix;
> +#endif /* __powerpc64__ */
>  } __packed;
>  
> -#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +static inline int ppc_inst_opcode(struct ppc_inst x)
> +{
> + return x.val >> 26;


why don't we wrap here and in `ppc_inst_opcode()` in patch 9 using
`ppc_inst_val()` ?


> +}
>  
>  static inline u32 ppc_inst_val(struct ppc_inst x)


There is another same definition below for the same function in
#else part of __powerpc64__ ifdef.


>  {
>   return x.val;
>  }
>  
> -static inline bool ppc_inst_len(struct ppc_inst x)
> +#ifdef __powerpc64__
> +#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff })
> +
> +#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y)
> })
> +
> +static inline u32 ppc_inst_suffix(struct ppc_inst x)
>  {
> - return sizeof(struct ppc_inst);
> + return x.suffix;
>  }
>  
> -static inline int ppc_inst_opcode(struct ppc_inst x)
> +static inline bool ppc_inst_prefixed(struct ppc_inst x) {
> + return ((ppc_inst_val(x) >> 26) == 1) && ppc_inst_suffix(x) != 0xff;
> +}
> +
> +static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
>  {
> - return x.val >> 26;
> + return ppc_inst_prefix(swab32(ppc_inst_val(x)),
> +swab32(ppc_inst_suffix(x)));
> +}
> +
> +static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
> +{
> + u32 val, suffix = 0xff;
> + val = *(u32 *)ptr;
> + if ((val >> 26) == 1)
> + suffix = *((u32 *)ptr + 1);
> + return ppc_inst_prefix(val, suffix);
> +}
> +
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> + if (ppc_inst_prefixed(x)) {
> + *(u32 *)ptr = x.val;
> + *((u32 *)ptr + 1) = x.suffix;
> + } else {
> + *(u32 *)ptr = x.val;


can we wrap here as well with `ppc_inst_val()` and `ppc_inst_suffix()` ?


> + }
> +}
> +
> +#else
> +
> +#define ppc_inst(x) ((struct ppc_inst){ .val = x })
> +
> +static inline bool ppc_inst_prefixed(ppc_inst x)
> +{
> + return 0;


Is it return !!0 or return false ?


>  }
>  
>  static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
> @@ -32,14 +76,31 @@ static inline struct ppc_inst ppc_inst_swab(struct
> ppc_inst x)
>   return ppc_inst(swab32(ppc_inst_val(x)));
>  }
>  
> +static inline u32 ppc_inst_val(struct ppc_inst x)


[...] duplicate definition that is defined outside __powerpc64__ above.


> +{
> + return x.val;
> +}
> +
>  static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
>  {
>   return *ptr;
>  }
>  
> +static inline void ppc_inst_write(struct ppc_inst *ptr, struct ppc_inst x)
> +{
> + *ptr = x;
> +}
> +
> +#endif /* __powerpc64__ */
> +
>  static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
>  {
>   return !memcmp(, , sizeof(struct ppc_inst));
>  }
>  
> +static inline int ppc_inst_len(struct ppc_inst x)
> +{
> + return (ppc_inst_prefixed(x)) ? 8  : 4;
> +}
> +
>  #endif /* _ASM_INST_H */
> diff --git a/arch/powerpc/include/asm/kprobes.h
> b/arch/powerpc/include/asm/kprobes.h
> index 66b3f2983b22..4fc0e15e23a5 100644
> --- a/arch/powerpc/include/asm/kprobes.h
> +++ b/arch/powerpc/include/asm/kprobes.h
> @@ -43,7 +43,7 @@ extern kprobe_opcode_t optprobe_template_ret[];
>  extern kprobe_opcode_t optprobe_template_end[];
>  
>  /* Fixed instruction size for powerpc */
> -#define MAX_INSN_SIZE1
> +#define 

Re: [PATCH] papr/scm: Add bad memory ranges to nvdimm bad ranges

2020-04-13 Thread Santosh Sivaraj
kbuild test robot  writes:

> Hi Santosh,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on powerpc/next]
> [also build test ERROR on v5.7-rc1 next-20200412]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system. BTW, we also suggest to use '--base' option to specify the
> base tree in git format-patch, please see
> https://stackoverflow.com/a/37406982]

This patch depends on "powerpc/mce: Add MCE notification chain" [1].

[1]: 
https://lore.kernel.org/linuxppc-dev/20200330071219.12284-1-ganes...@linux.ibm.com/

Thanks,
Santosh

>
> url:
> https://github.com/0day-ci/linux/commits/Santosh-Sivaraj/papr-scm-Add-bad-memory-ranges-to-nvdimm-bad-ranges/20200401-171233
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: powerpc-allyesconfig (attached as .config)
> compiler: powerpc64-linux-gcc (GCC) 9.3.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=9.3.0 make.cross ARCH=powerpc 
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kbuild test robot 
>
> All errors (new ones prefixed by >>):
>
>arch/powerpc/platforms/pseries/papr_scm.c: In function 'papr_scm_init':
>>> arch/powerpc/platforms/pseries/papr_scm.c:584:3: error: implicit 
>>> declaration of function 'mce_register_notifier'; did you mean 
>>> 'bus_register_notifier'? [-Werror=implicit-function-declaration]
>  584 |   mce_register_notifier(_ue_nb);
>  |   ^
>  |   bus_register_notifier
>arch/powerpc/platforms/pseries/papr_scm.c: In function 'papr_scm_exit':
>>> arch/powerpc/platforms/pseries/papr_scm.c:592:2: error: implicit 
>>> declaration of function 'mce_unregister_notifier'; did you mean 
>>> 'bus_unregister_notifier'? [-Werror=implicit-function-declaration]
>  592 |  mce_unregister_notifier(_ue_nb);
>  |  ^~~
>  |  bus_unregister_notifier
>cc1: some warnings being treated as errors
>
> vim +584 arch/powerpc/platforms/pseries/papr_scm.c
>
>577
>578static int __init papr_scm_init(void)
>579{
>580int ret;
>581
>582ret = platform_driver_register(_scm_driver);
>583if (!ret)
>  > 584mce_register_notifier(_ue_nb);
>585
>586return ret;
>587}
>588module_init(papr_scm_init);
>589
>590static void __exit papr_scm_exit(void)
>591{
>  > 592mce_unregister_notifier(_ue_nb);
>593platform_driver_unregister(_scm_driver);
>594}
>595module_exit(papr_scm_exit);
>596
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


Re: Build regressions/improvements in v5.7-rc1

2020-04-13 Thread Geert Uytterhoeven

On Mon, 13 Apr 2020, Geert Uytterhoeven wrote:

Below is the list of build error/warning regressions/improvements in
v5.7-rc1[1] compared to v5.6[2].

Summarized:
 - build errors: +132/-3
 - build warnings: +257/-79

Happy fixing! ;-)

Thanks to the linux-next team for providing the build service.

[1] 
http://kisskb.ellerman.id.au/kisskb/branch/linus/head/8f3d9f354286745c751374f5f1fcafee6b3f3136/
 (all 239 configs)
[2] 
http://kisskb.ellerman.id.au/kisskb/branch/linus/head/7111951b8d4973bda27ff663f2cf18b663d15b48/
 (all 239 configs)


*** ERRORS ***

132 error regressions:
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/hash.h: error: implicit 
declaration of function 'pte_raw' [-Werror=implicit-function-declaration]:  => 
192:2
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/hash.h: error: implicit 
declaration of function 'pte_raw'; did you mean 'pte_read'? 
[-Werror=implicit-function-declaration]:  => 192:8
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 
'SLICE_NUM_HIGH' undeclared here (not in a function):  => 698:2, 698:30
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 'struct 
mmu_psize_def' has no member named 'ap':  => 207:28
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 'struct 
mmu_psize_def' has no member named 'avpnm':  => 337:57
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 'struct 
mmu_psize_def' has no member named 'penc':  => 411:49
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 'struct 
mmu_psize_def' has no member named 'penc'; did you mean 'enc'?:  => 411:50
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: 'struct 
mmu_psize_def' has no member named 'sllp':  => 218:32, 219:26
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: redefinition 
of 'mmu_psize_to_shift':  => 195:28
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/mmu-hash.h: error: redefinition 
of 'shift_to_mmu_psize':  => 185:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: implicit 
declaration of function 'pgd_raw' [-Werror=implicit-function-declaration]:  => 
35:3
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: implicit 
declaration of function 'pgd_raw'; did you mean 'pgd_val'? 
[-Werror=implicit-function-declaration]:  => 35:13
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: implicit 
declaration of function 'pud_raw' [-Werror=implicit-function-declaration]:  => 
25:3
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: implicit 
declaration of function 'pud_raw'; did you mean 'pud_val'? 
[-Werror=implicit-function-declaration]:  => 25:13
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: 
redefinition of 'hugepd_ok':  => 44:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: 
redefinition of 'pgd_huge':  => 29:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: 
redefinition of 'pmd_huge':  => 9:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable-4k.h: error: 
redefinition of 'pud_huge':  => 19:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected ')' 
before '!=' token:  => 964:19, 921:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected ')' 
before '==' token:  => 979:19, 801:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected ')' 
before '^' token:  => 801:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected ')' 
before '__vmalloc_end':  => 291:21, 274:21
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected 
identifier or '(' before '!' token:  => 916:19, 904:19, 939:19, 959:19, 868:19, 
873:19
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: expected 
identifier or '(' before 'struct':  => 291:21
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: implicit 
declaration of function '__pgd_raw' [-Werror=implicit-function-declaration]:  
=> 976:2
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: implicit 
declaration of function '__pgd_raw'; did you mean '__fdget_raw'? 
[-Werror=implicit-function-declaration]:  => 976:9
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: implicit 
declaration of function '__pmd_raw' [-Werror=implicit-function-declaration]:  
=> 1075:9, 1075:2
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: implicit 
declaration of function '__pte_raw' [-Werror=implicit-function-declaration]:  
=> 552:2, 552:9
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: implicit 
declaration of function '__pud_raw' [-Werror=implicit-function-declaration]:  
=> 935:9, 935:2
 + /kisskb/src/arch/powerpc/include/asm/book3s/64/pgtable.h: error: incompatible 
types when returning type 'int' but 'pgd_t' was expected:  => 976:2
 + 

Re: [RFC/PATCH 2/3] pseries/kvm: Clear PSSCR[ESL|EC] bits before guest entry

2020-04-13 Thread Gautham R Shenoy
Hello David,

On Wed, Apr 08, 2020 at 12:29:57PM +1000, David Gibson wrote:
> On Tue, Apr 07, 2020 at 06:55:26PM +0530, Gautham R Shenoy wrote:
> > Hello David,
> > 
> > On Mon, Apr 06, 2020 at 07:58:19PM +1000, David Gibson wrote:
> > > On Fri, Apr 03, 2020 at 03:01:03PM +0530, Gautham R Shenoy wrote:
> > > > On Fri, Apr 03, 2020 at 12:20:26PM +1000, Nicholas Piggin wrote:
> > > > > Gautham R. Shenoy's on March 31, 2020 10:10 pm:
> > > > > > From: "Gautham R. Shenoy" 
> > > > > > 
> > > > > > ISA v3.0 allows the guest to execute a stop instruction. For this, 
> > > > > > the
> > > > > > PSSCR[ESL|EC] bits need to be cleared by the hypervisor before
> > > > > > scheduling in the guest vCPU.
> > > > > > 
> > > > > > Currently we always schedule in a vCPU with PSSCR[ESL|EC] bits
> > > > > > set. This patch changes the behaviour to enter the guest with
> > > > > > PSSCR[ESL|EC] bits cleared. This is a RFC patch where we
> > > > > > unconditionally clear these bits. Ideally this should be done
> > > > > > conditionally on platforms where the guest stop instruction has no
> > > > > > Bugs (starting POWER9 DD2.3).
> > > > > 
> > > > > How will guests know that they can use this facility safely after your
> > > > > series? You need both DD2.3 and a patched KVM.
> > > > 
> > > > 
> > > > Yes, this is something that isn't addressed in this series (mentioned
> > > > in the cover letter), which is a POC demonstrating that the stop0lite
> > > > state in guest works.
> > > > 
> > > > However, to answer your question, this is the scheme that I had in
> > > > mind :
> > > > 
> > > > OPAL:
> > > >On Procs >= DD2.3 : we publish a dt-cpu-feature "idle-stop-guest"
> > > > 
> > > > Hypervisor Kernel:
> > > > 1. If "idle-stop-guest" dt-cpu-feature is discovered, then
> > > >we set bool enable_guest_stop = true;
> > > > 
> > > > 2. During KVM guest entry, clear PSSCR[ESL|EC] iff
> > > >enable_guest_stop == true.
> > > > 
> > > > 3. In kvm_vm_ioctl_check_extension(), for a new capability
> > > >KVM_CAP_STOP, return true iff enable_guest_top == true.
> > > > 
> > > > QEMU:
> > > >Check with the hypervisor if KVM_CAP_STOP is present. If so,
> > > >indicate the presence to the guest via device tree.
> > > 
> > > Nack.  Presenting different capabilities to the guest depending on
> > > host capabilities (rather than explicit options) is never ok.  It
> > > means that depending on the system you start on you may or may not be
> > > able to migrate to other systems that you're supposed to be able to,
> > 
> > I agree that blocking migration for the unavailability of this feature
> > is not desirable. Could you point me to some other capabilities in KVM
> > which have been implemented via explicit options?
> 
> TBH, most of the options for the 'pseries' machine type are in this
> category: cap-vsx, cap-dfp, cap-htm, a bunch related to various
> Spectre mitigations, cap-hpt-max-page-size (maximum page size for hash
> guests), cap-nested-hv, cap-large-decr, cap-fwnmi, resize-hpt (HPT
> resizing extension), ic-mode (which irq controllers are available to
> the guest).


Thanks. I will follow this suit.

> 
> > The ISA 3.0 allows the guest to execute the "stop" instruction.
> 
> So, this was a bug in DD2.2's implementation of the architecture?

Yes, the previous versions could miss wakeup events when stop was
executed in HV=0,PR=0 mode. So, the hypervisor had to block that.


> 
> > If the
> > Hypervisor hasn't cleared the PSSCR[ESL|EC] then, guest executing the
> > "stop" instruction in the causes a Hypervisor Facility Unavailable
> > Exception, thus giving the hypervisor a chance to emulate the
> > instruction. However, in the current code, when the hypervisor
> > receives this exception, it sends a PROGKILL to the guest which
> > results in crashing the guest.
> > 
> > Patch 1 of this series emulates wakeup from the "stop"
> > instruction. Would the following scheme be ok?
> > 
> > OPAL:
> > On Procs >= DD2.3 : we publish a dt-cpu-feature "idle-stop-guest"
> > 
> > Hypervisor Kernel:
> > 
> >If "idle-stop-guest" dt feature is available, then, before
> >entering the guest, the hypervisor clears the PSSCR[EC|ESL]
> >bits allowing the guest to safely execute stop instruction.
> > 
> >If "idle-stop-guest" dt feature is not available, then, the
> >Hypervisor sets the PSSCR[ESL|EC] bits, thereby causing a
> >guest "stop" instruction execution to trap back into the
> >hypervisor. We then emulate a wakeup from the stop
> >instruction (Patch 1 of this series).
> > 
> > Guest Kernel:
> >   If (cpu_has_feature(CPU_FTR_ARCH_300)) only then use the
> >   stop0lite cpuidle state.
> > 
> > This allows us to migrate the KVM guest across any POWER9
> > Hypervisor. The minimal addition that the Hypervisor would need is
> > Patch 1 of this series.
> 
> That could be workable.  Some caveats, though:
> 
>  * How does the latency of the 

Re: [PATCH v6 5/7] ASoC: fsl_asrc: Move common definition to fsl_asrc_common

2020-04-13 Thread Shengjiu Wang
On Mon, Apr 13, 2020 at 12:31 PM Nicolin Chen  wrote:
>
> On Mon, Apr 13, 2020 at 11:16:31AM +0800, Shengjiu Wang wrote:
> > On Sun, Apr 12, 2020 at 10:08 AM Nicolin Chen  
> > wrote:
> > >
> > > On Sat, Apr 11, 2020 at 01:49:43PM +0800, Shengjiu Wang wrote:
> > >
> > > > > > diff --git a/sound/soc/fsl/fsl_asrc_dma.c 
> > > > > > b/sound/soc/fsl/fsl_asrc_dma.c
> > > > > > index b15946e03380..5cf0468ce6e3 100644
> > > > > > --- a/sound/soc/fsl/fsl_asrc_dma.c
> > > > > > +++ b/sound/soc/fsl/fsl_asrc_dma.c
> > > > >
> > > > > > @@ -311,11 +311,12 @@ static int fsl_asrc_dma_startup(struct 
> > > > > > snd_soc_component *component,
> > > > > >   return ret;
> > > > > >   }
> > > > > >
> > > > > > - pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL);
> > > > > > + pair = kzalloc(sizeof(struct fsl_asrc_pair) + 
> > > > > > PAIR_PRIVAT_SIZE, GFP_KERNEL);
> > > > >
> > > > > If we only use the PAIR_PRIVATE_SIZE here, maybe we can put the
> > > > > define in this file too, rather than in the header file.
> > > > >
> > > > > And could fit 80 characters:
> > > > >
> > > > > +   pair = kzalloc(sizeof(*pair) + PAIR_PRIVAT_SIZE, GFP_KERNEL);
> > >
> > > > I will use a function pointer
> > > > int (*get_pair_priv_size)(void)
> > >
> > > Since it's the size of pair or cts structure, could be just a
> > > size_t variable?
> >
> > Yes, should be "size_t (*get_pair_priv_size)(void)"
>
> Does it have to be a function? -- how about this:
>
> struct pair {
> ...
> size_t private_size;
> void *private;
> };
>
> probe/or-somewhere() {
> ...
> pair->private = pair_priv;

we need to know the size of pair_priv before allocate memory.

> pair->private_size = sizeof(*pair_priv);
> ...
> }

In fsl_asrc_dma_startup, we need to allocate memory for pair and
pair->private,but we don't know the object, so we don't know the
size of private, so function pointer is better.

best regards
wang shengjiu