Re: [PATCH 4/8] riscv: Prepare ptdump for vm layout dynamic addresses

2020-05-24 Thread Anup Patel
On Sun, May 24, 2020 at 2:44 PM Alexandre Ghiti  wrote:
>
> This is a preparatory patch for sv48 support that will introduce
> dynamic PAGE_OFFSET.
>
> Dynamic PAGE_OFFSET implies that all zones (vmalloc, vmemmap, fixaddr...)
> whose addresses depend on PAGE_OFFSET become dynamic and can't be used
> to statically initialize the array used by ptdump to identify the
> different zones of the vm layout.
>
> Signed-off-by: Alexandre Ghiti 
> ---
>  arch/riscv/mm/ptdump.c | 49 ++
>  1 file changed, 40 insertions(+), 9 deletions(-)
>
> diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
> index 7eab76a93106..7d9386a7f5c2 100644
> --- a/arch/riscv/mm/ptdump.c
> +++ b/arch/riscv/mm/ptdump.c
> @@ -49,22 +49,41 @@ struct addr_marker {
> const char *name;
>  };
>
> +enum address_markers_idx {
> +#ifdef CONFIG_KASAN
> +   KASAN_SHADOW_START_NR,
> +   KASAN_SHADOW_END_NR,
> +#endif
> +   FIXMAP_START_NR,
> +   FIXMAP_END_NR,
> +   PCI_IO_START_NR,
> +   PCI_IO_END_NR,
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +   VMEMMAP_START_NR,
> +   VMEMMAP_END_NR,
> +#endif
> +   VMALLOC_START_NR,
> +   VMALLOC_END_NR,
> +   PAGE_OFFSET_NR,
> +   END_OF_SPACE_NR
> +};
> +
>  static struct addr_marker address_markers[] = {
>  #ifdef CONFIG_KASAN
> {KASAN_SHADOW_START,"Kasan shadow start"},
> {KASAN_SHADOW_END,  "Kasan shadow end"},
>  #endif
> -   {FIXADDR_START, "Fixmap start"},
> -   {FIXADDR_TOP,   "Fixmap end"},
> -   {PCI_IO_START,  "PCI I/O start"},
> -   {PCI_IO_END,"PCI I/O end"},
> +   {0, "Fixmap start"},
> +   {0, "Fixmap end"},
> +   {0, "PCI I/O start"},
> +   {0, "PCI I/O end"},
>  #ifdef CONFIG_SPARSEMEM_VMEMMAP
> -   {VMEMMAP_START, "vmemmap start"},
> -   {VMEMMAP_END,   "vmemmap end"},
> +   {0, "vmemmap start"},
> +   {0, "vmemmap end"},
>  #endif
> -   {VMALLOC_START, "vmalloc() area"},
> -   {VMALLOC_END,   "vmalloc() end"},
> -   {PAGE_OFFSET,   "Linear mapping"},
> +   {0, "vmalloc() area"},
> +   {0, "vmalloc() end"},
> +   {0, "Linear mapping"},
> {-1, NULL},
>  };
>
> @@ -304,6 +323,18 @@ static int ptdump_init(void)
>  {
> unsigned int i, j;
>
> +   address_markers[FIXMAP_START_NR].start_address = FIXADDR_START;
> +   address_markers[FIXMAP_END_NR].start_address = FIXADDR_TOP;
> +   address_markers[PCI_IO_START_NR].start_address = PCI_IO_START;
> +   address_markers[PCI_IO_END_NR].start_address = PCI_IO_END;
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +   address_markers[VMEMMAP_START_NR].start_address = VMEMMAP_START;
> +   address_markers[VMEMMAP_END_NR].start_address = VMEMMAP_END;
> +#endif
> +   address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
> +   address_markers[VMALLOC_END_NR].start_address = VMALLOC_END;
> +   address_markers[PAGE_OFFSET_NR].start_address = PAGE_OFFSET;
> +
> for (i = 0; i < ARRAY_SIZE(pg_level); i++)
> for (j = 0; j < ARRAY_SIZE(pte_bits); j++)
> pg_level[i].mask |= pte_bits[j].mask;
> --
> 2.20.1
>

Looks good to me.

Reviewed-by: Anup Patel 

Regards,
Anup


[PATCH] treewide: fix incomplete error-handling in img_i2s_in_probe.

2020-05-24 Thread wu000273
From: Qiushi Wu 

Function "pm_runtime_get_sync()" is not handled by "pm_runtime_put()"
if "PTR_ERR(rst) == -EPROBE_DEFER". Fix this issue by adding
"pm_runtime_put()" into this error path.

Fixes: f65bb92ca12e ("ASoC: img-i2s-in: Add runtime PM")
Signed-off-by: Qiushi Wu 
---
 sound/soc/img/img-i2s-in.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
index a495d1050d49..e30b66b94bf6 100644
--- a/sound/soc/img/img-i2s-in.c
+++ b/sound/soc/img/img-i2s-in.c
@@ -482,6 +482,7 @@ static int img_i2s_in_probe(struct platform_device *pdev)
if (IS_ERR(rst)) {
if (PTR_ERR(rst) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
+   pm_runtime_put(>dev);
goto err_suspend;
}
 
-- 
2.17.1



[PATCH 0/4] kernfs: proposed locking and concurrency improvement

2020-05-24 Thread Ian Kent
For very large systems with hundreds of CPUs and TBs of RAM booting can
take a very long time.

Initial reports showed that booting a configuration of several hundred
CPUs and 64TB of RAM would take more than 30 minutes and require kernel
parameters of udev.children-max=1024 systemd.default_timeout_start_sec=3600
to prevent dropping into emergency mode.

Gathering information about what's happening during the boot is a bit
challenging. But two main issues appeared to be, a large number of path
lookups for non-existent files, and high lock contention in the VFS during
path walks particularly in the dentry allocation code path.

The underlying cause of this was believed to be the sheer number of sysfs
memory objects, 100,000+ for a 64TB memory configuration.

This patch series tries to reduce the locking needed during path walks
based on the assumption that there are many path walks with a fairly
large portion of those for non-existent paths.

This was done by adding kernfs negative dentry caching (non-existent
paths) to avoid continual alloc/free cycle of dentries and a read/write
semaphore introduced to increase kernfs concurrency during path walks.

With these changes the kernel parameters of udev.children-max=2048 and
systemd.default_timeout_start_sec=300 for are still needed to get the
fastest boot times and result in boot time of under 5 minutes.

There may be opportunities for further improvements but the series here
has seen a fair amount of testing. And thinking about what else could be
done, and discussing it with Rick Lindsay, I suspect improvements will
get more difficult to implement for somewhat less improvement so I think
what we have here is a good start for now.

I think what's needed now is patch review, and if we can get through
that, send them via linux-next for broader exposure and hopefully have
them merged into mainline.
---

Ian Kent (4):
  kernfs: switch kernfs to use an rwsem
  kernfs: move revalidate to be near lookup
  kernfs: improve kernfs path resolution
  kernfs: use revision to identify directory node changes


 fs/kernfs/dir.c |  283 ---
 fs/kernfs/file.c|4 -
 fs/kernfs/inode.c   |   16 +-
 fs/kernfs/kernfs-internal.h |   29 
 fs/kernfs/mount.c   |   12 +-
 fs/kernfs/symlink.c |4 -
 include/linux/kernfs.h  |5 +
 7 files changed, 232 insertions(+), 121 deletions(-)

--
Ian



[PATCH 2/2] modpost: refactor sech_name()

2020-05-24 Thread Masahiro Yamada
Use sym_get_data_offset() helper to get access to the .shstrtab
section data. No functional change is intended because
elf->sechdrs[elf->secindex_strings].sh_addr is 0 for both ET_REL
and ET_EXEC object types.

Signed-off-by: Masahiro Yamada 
---

 scripts/mod/modpost.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index a8306adb3554..a5f3908bc9e4 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -333,18 +333,6 @@ static enum export export_no(const char *s)
return export_unknown;
 }
 
-static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
-{
-   return (void *)elf->hdr +
-   elf->sechdrs[elf->secindex_strings].sh_offset +
-   sechdr->sh_name;
-}
-
-static const char *sec_name(struct elf_info *elf, int secindex)
-{
-   return sech_name(elf, >sechdrs[secindex]);
-}
-
 static void *sym_get_data_offset(const struct elf_info *info,
 unsigned int secindex, unsigned long offset)
 {
@@ -362,6 +350,16 @@ static void *sym_get_data(const struct elf_info *info, 
const Elf_Sym *sym)
   sym->st_value);
 }
 
+static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
+{
+   return sym_get_data_offset(elf, elf->secindex_strings, sechdr->sh_name);
+}
+
+static const char *sec_name(struct elf_info *elf, int secindex)
+{
+   return sech_name(elf, >sechdrs[secindex]);
+}
+
 #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
 
 static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
-- 
2.25.1



[PATCH 1/4] kernfs: switch kernfs to use an rwsem

2020-05-24 Thread Ian Kent
The kernfs global lock restricts the ability to perform kernfs node
lookup operations in parallel.

Change the kernfs mutex to an rwsem so that, when oppertunity arises,
node searches can be done in parallel.

Signed-off-by: Ian Kent 
---
 fs/kernfs/dir.c |  119 +++
 fs/kernfs/file.c|4 +
 fs/kernfs/inode.c   |   16 +++---
 fs/kernfs/kernfs-internal.h |5 +-
 fs/kernfs/mount.c   |   12 ++--
 fs/kernfs/symlink.c |4 +
 6 files changed, 86 insertions(+), 74 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 9aec80b9d7c6..d8213fc65eba 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -17,7 +17,7 @@
 
 #include "kernfs-internal.h"
 
-DEFINE_MUTEX(kernfs_mutex);
+DECLARE_RWSEM(kernfs_rwsem);
 static DEFINE_SPINLOCK(kernfs_rename_lock);/* kn->parent and ->name */
 static char kernfs_pr_cont_buf[PATH_MAX];  /* protected by rename_lock */
 static DEFINE_SPINLOCK(kernfs_idr_lock);   /* root->ino_idr */
@@ -26,10 +26,21 @@ static DEFINE_SPINLOCK(kernfs_idr_lock);/* 
root->ino_idr */
 
 static bool kernfs_active(struct kernfs_node *kn)
 {
-   lockdep_assert_held(_mutex);
return atomic_read(>active) >= 0;
 }
 
+static bool kernfs_active_write(struct kernfs_node *kn)
+{
+   lockdep_assert_held_write(_rwsem);
+   return kernfs_active(kn);
+}
+
+static bool kernfs_active_read(struct kernfs_node *kn)
+{
+   lockdep_assert_held_read(_rwsem);
+   return kernfs_active(kn);
+}
+
 static bool kernfs_lockdep(struct kernfs_node *kn)
 {
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -340,7 +351,7 @@ static int kernfs_sd_compare(const struct kernfs_node *left,
  * @kn->parent->dir.children.
  *
  * Locking:
- * mutex_lock(kernfs_mutex)
+ * kernfs_rwsem write lock
  *
  * RETURNS:
  * 0 on susccess -EEXIST on failure.
@@ -385,7 +396,7 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
  * removed, %false if @kn wasn't on the rbtree.
  *
  * Locking:
- * mutex_lock(kernfs_mutex)
+ * kernfs_rwsem write lock
  */
 static bool kernfs_unlink_sibling(struct kernfs_node *kn)
 {
@@ -455,14 +466,14 @@ void kernfs_put_active(struct kernfs_node *kn)
  * return after draining is complete.
  */
 static void kernfs_drain(struct kernfs_node *kn)
-   __releases(_mutex) __acquires(_mutex)
+   __releases(_rwsem) __acquires(_rwsem)
 {
struct kernfs_root *root = kernfs_root(kn);
 
-   lockdep_assert_held(_mutex);
+   lockdep_assert_held_write(_rwsem);
WARN_ON_ONCE(kernfs_active(kn));
 
-   mutex_unlock(_mutex);
+   up_write(_rwsem);
 
if (kernfs_lockdep(kn)) {
rwsem_acquire(>dep_map, 0, 0, _RET_IP_);
@@ -481,7 +492,7 @@ static void kernfs_drain(struct kernfs_node *kn)
 
kernfs_drain_open_files(kn);
 
-   mutex_lock(_mutex);
+   down_write(_rwsem);
 }
 
 /**
@@ -560,10 +571,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
goto out_bad_unlocked;
 
kn = kernfs_dentry_node(dentry);
-   mutex_lock(_mutex);
+   down_read(_rwsem);
 
/* The kernfs node has been deactivated */
-   if (!kernfs_active(kn))
+   if (!kernfs_active_read(kn))
goto out_bad;
 
/* The kernfs node has been moved? */
@@ -579,10 +590,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
kernfs_info(dentry->d_sb)->ns != kn->ns)
goto out_bad;
 
-   mutex_unlock(_mutex);
+   up_read(_rwsem);
return 1;
 out_bad:
-   mutex_unlock(_mutex);
+   up_read(_rwsem);
 out_bad_unlocked:
return 0;
 }
@@ -764,7 +775,7 @@ int kernfs_add_one(struct kernfs_node *kn)
bool has_ns;
int ret;
 
-   mutex_lock(_mutex);
+   down_write(_rwsem);
 
ret = -EINVAL;
has_ns = kernfs_ns_enabled(parent);
@@ -779,7 +790,7 @@ int kernfs_add_one(struct kernfs_node *kn)
if (parent->flags & KERNFS_EMPTY_DIR)
goto out_unlock;
 
-   if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent))
+   if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active_write(parent))
goto out_unlock;
 
kn->hash = kernfs_name_hash(kn->name, kn->ns);
@@ -795,7 +806,7 @@ int kernfs_add_one(struct kernfs_node *kn)
ps_iattr->ia_mtime = ps_iattr->ia_ctime;
}
 
-   mutex_unlock(_mutex);
+   up_write(_rwsem);
 
/*
 * Activate the new node unless CREATE_DEACTIVATED is requested.
@@ -809,7 +820,7 @@ int kernfs_add_one(struct kernfs_node *kn)
return 0;
 
 out_unlock:
-   mutex_unlock(_mutex);
+   up_write(_rwsem);
return ret;
 }
 
@@ -830,7 +841,7 @@ static struct kernfs_node *kernfs_find_ns(struct 
kernfs_node *parent,
bool has_ns = kernfs_ns_enabled(parent);
unsigned int hash;
 
-   

[PATCH 1/2] modpost: fix potential segmentation fault for addend_i386_rel()

2020-05-24 Thread Masahiro Yamada
This may not be a practical problem, but the second pass of ARCH=i386
modpost causes segmentation fault if the -s option is not passed.

MODPOST 12 modules
  Segmentation fault (core dumped)
  make[2]: *** [scripts/Makefile.modpost:94: __modpost] Error 139
  make[1]: *** [Makefile:1339: modules] Error 2
  make[1]: *** Waiting for unfinished jobs

The segmentation fault occurs when section_rel() is called for vmlinux,
which is untested in regular builds. The cause of the problem is
reloc_location() returns a wrong pointer for ET_EXEC object type.
In this case, you need to subtract sechdr->sh_addr, otherwise it would
get access beyond the mmap'ed memory.

Add sym_get_data_offset() helper to avoid code duplication.

Signed-off-by: Masahiro Yamada 
---

 scripts/mod/modpost.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 34f2aa3a021f..a8306adb3554 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -345,19 +345,23 @@ static const char *sec_name(struct elf_info *elf, int 
secindex)
return sech_name(elf, >sechdrs[secindex]);
 }
 
-static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
+static void *sym_get_data_offset(const struct elf_info *info,
+unsigned int secindex, unsigned long offset)
 {
-   unsigned int secindex = get_secindex(info, sym);
Elf_Shdr *sechdr = >sechdrs[secindex];
-   unsigned long offset;
 
-   offset = sym->st_value;
if (info->hdr->e_type != ET_REL)
offset -= sechdr->sh_addr;
 
return (void *)info->hdr + sechdr->sh_offset + offset;
 }
 
+static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
+{
+   return sym_get_data_offset(info, get_secindex(info, sym),
+  sym->st_value);
+}
+
 #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
 
 static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
@@ -1761,11 +1765,7 @@ static void check_section_mismatch(const char *modname, 
struct elf_info *elf,
 static unsigned int *reloc_location(struct elf_info *elf,
Elf_Shdr *sechdr, Elf_Rela *r)
 {
-   Elf_Shdr *sechdrs = elf->sechdrs;
-   int section = sechdr->sh_info;
-
-   return (void *)elf->hdr + sechdrs[section].sh_offset +
-   r->r_offset;
+   return sym_get_data_offset(elf, sechdr->sh_info, r->r_offset);
 }
 
 static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
-- 
2.25.1



[PATCH 4/4] kernfs: use revision to identify directory node changes

2020-05-24 Thread Ian Kent
If a kernfs directory node hasn't changed there's no need to search for
an added (or removed) child dentry.

Add a revision counter to kernfs directory nodes so it can be used
to detect if a directory node has changed.

Signed-off-by: Ian Kent 
---
 fs/kernfs/dir.c |   17 +++--
 fs/kernfs/kernfs-internal.h |   24 
 include/linux/kernfs.h  |5 +
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index f4943329e578..03f4f179bbc4 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -383,6 +383,7 @@ static int kernfs_link_sibling(struct kernfs_node *kn)
/* successfully added, account subdir number */
if (kernfs_type(kn) == KERNFS_DIR)
kn->parent->dir.subdirs++;
+   kernfs_inc_rev(kn->parent);
 
return 0;
 }
@@ -405,6 +406,7 @@ static bool kernfs_unlink_sibling(struct kernfs_node *kn)
 
if (kernfs_type(kn) == KERNFS_DIR)
kn->parent->dir.subdirs--;
+   kernfs_inc_rev(kn->parent);
 
rb_erase(>rb, >parent->dir.children);
RB_CLEAR_NODE(>rb);
@@ -1044,9 +1046,16 @@ struct kernfs_node *kernfs_create_empty_dir(struct 
kernfs_node *parent,
 
 static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
 {
+   struct kernfs_node *parent;
struct kernfs_node *kn;
 
if (flags & LOOKUP_RCU) {
+   /* Directory node changed? */
+   parent = kernfs_dentry_node(dentry->d_parent);
+
+   if (!kernfs_dir_changed(parent, dentry))
+   return 1;
+
kn = kernfs_dentry_node(dentry);
if (!kn) {
/* Negative hashed dentry, tell the VFS to switch to
@@ -1093,8 +1102,6 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
 
kn = kernfs_dentry_node(dentry);
if (!kn) {
-   struct kernfs_node *parent;
-
/* If the kernfs node can be found this is a stale negative
 * hashed dentry so it must be discarded and the lookup redone.
 */
@@ -1102,6 +1109,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
if (parent) {
const void *ns = NULL;
 
+   /* Directory node changed? */
+   if (kernfs_dir_changed(parent, dentry))
+   goto out_bad;
+
if (kernfs_ns_enabled(parent))
ns = kernfs_info(dentry->d_parent->d_sb)->ns;
kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
@@ -1156,6 +1167,8 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
 
down_read(_rwsem);
 
+   kernfs_set_rev(dentry, parent);
+
if (kernfs_ns_enabled(parent))
ns = kernfs_info(dir->i_sb)->ns;
 
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index 097c1a989aa4..a7b0e2074260 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -82,6 +82,30 @@ static inline struct kernfs_node *kernfs_dentry_node(struct 
dentry *dentry)
return d_inode(dentry)->i_private;
 }
 
+static inline void kernfs_set_rev(struct dentry *dentry,
+ struct kernfs_node *kn)
+{
+   dentry->d_time = kn->dir.rev;
+}
+
+static inline void kernfs_inc_rev(struct kernfs_node *kn)
+{
+   if (kernfs_type(kn) == KERNFS_DIR) {
+   if (!++kn->dir.rev)
+   kn->dir.rev++;
+   }
+}
+
+static inline bool kernfs_dir_changed(struct kernfs_node *kn,
+ struct dentry *dentry)
+{
+   if (kernfs_type(kn) == KERNFS_DIR) {
+   if (kn->dir.rev != dentry->d_time)
+   return true;
+   }
+   return false;
+}
+
 extern const struct super_operations kernfs_sops;
 extern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache;
 
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 89f6a4214a70..74727d98e380 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -98,6 +98,11 @@ struct kernfs_elem_dir {
 * better directly in kernfs_node but is here to save space.
 */
struct kernfs_root  *root;
+   /*
+* Monotonic revision counter, used to identify if a directory
+* node has changed during revalidation.
+*/
+   unsigned long rev;
 };
 
 struct kernfs_elem_symlink {




[PATCH 3/4] kernfs: improve kernfs path resolution

2020-05-24 Thread Ian Kent
Now that an rwsem is used by kernfs, take advantage of it to reduce
lookup overhead.

If there are many lookups (possibly many negative ones) there can
be a lot of overhead during path walks.

To reduce lookup overhead avoid allocating a new dentry where possible.

To do this stay in rcu-walk mode where possible and use the dentry cache
handling of negative hashed dentries to avoid allocating (and freeing
shortly after) new dentries on every negative lookup.

Signed-off-by: Ian Kent 
---
 fs/kernfs/dir.c |   87 ++-
 1 file changed, 72 insertions(+), 15 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 9b315f3b20ee..f4943329e578 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1046,15 +1046,75 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
 {
struct kernfs_node *kn;
 
-   if (flags & LOOKUP_RCU)
+   if (flags & LOOKUP_RCU) {
+   kn = kernfs_dentry_node(dentry);
+   if (!kn) {
+   /* Negative hashed dentry, tell the VFS to switch to
+* ref-walk mode and call us again so that node
+* existence can be checked.
+*/
+   if (!d_unhashed(dentry))
+   return -ECHILD;
+
+   /* Negative unhashed dentry, this shouldn't happen
+* because this case occurs in rcu-walk mode after
+* dentry allocation which is followed by a call
+* to ->loopup(). But if it does happen the dentry
+* is surely invalid.
+*/
+   return 0;
+   }
+
+   /* Since the dentry is positive (we got the kernfs node) a
+* kernfs node reference was held at the time. Now if the
+* dentry reference count is still greater than 0 it's still
+* positive so take a reference to the node to perform an
+* active check.
+*/
+   if (d_count(dentry) <= 0 || !atomic_inc_not_zero(>count))
+   return -ECHILD;
+
+   /* The kernfs node reference count was greater than 0, if
+* it's active continue in rcu-walk mode.
+*/
+   if (kernfs_active_read(kn)) {
+   kernfs_put(kn);
+   return 1;
+   }
+
+   /* Otherwise, just tell the VFS to switch to ref-walk mode
+* and call us again so the kernfs node can be validated.
+*/
+   kernfs_put(kn);
return -ECHILD;
+   }
 
-   /* Always perform fresh lookup for negatives */
-   if (d_really_is_negative(dentry))
-   goto out_bad_unlocked;
+   down_read(_rwsem);
 
kn = kernfs_dentry_node(dentry);
-   down_read(_rwsem);
+   if (!kn) {
+   struct kernfs_node *parent;
+
+   /* If the kernfs node can be found this is a stale negative
+* hashed dentry so it must be discarded and the lookup redone.
+*/
+   parent = kernfs_dentry_node(dentry->d_parent);
+   if (parent) {
+   const void *ns = NULL;
+
+   if (kernfs_ns_enabled(parent))
+   ns = kernfs_info(dentry->d_parent->d_sb)->ns;
+   kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
+   if (kn)
+   goto out_bad;
+   }
+
+   /* The kernfs node doesn't exist, leave the dentry negative
+* and return success.
+*/
+   goto out;
+   }
+
 
/* The kernfs node has been deactivated */
if (!kernfs_active_read(kn))
@@ -1072,12 +1132,11 @@ static int kernfs_dop_revalidate(struct dentry *dentry, 
unsigned int flags)
if (kn->parent && kernfs_ns_enabled(kn->parent) &&
kernfs_info(dentry->d_sb)->ns != kn->ns)
goto out_bad;
-
+out:
up_read(_rwsem);
return 1;
 out_bad:
up_read(_rwsem);
-out_bad_unlocked:
return 0;
 }
 
@@ -1092,7 +1151,7 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
struct dentry *ret;
struct kernfs_node *parent = dir->i_private;
struct kernfs_node *kn;
-   struct inode *inode;
+   struct inode *inode = NULL;
const void *ns = NULL;
 
down_read(_rwsem);
@@ -1102,11 +1161,9 @@ static struct dentry *kernfs_iop_lookup(struct inode 
*dir,
 
kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
 
-   /* no such entry */
-   if (!kn || !kernfs_active(kn)) {
-   ret = NULL;
-   goto out_unlock;
-   }
+   /* no such entry, retain 

[PATCH 2/4] kernfs: move revalidate to be near lookup

2020-05-24 Thread Ian Kent
While the dentry operation kernfs_dop_revalidate() is grouped with
dentry'ish functions it also has a strong afinity to the inode
operation ->lookup(). And when path walk improvements are applied
it will need to call kernfs_find_ns() so move it to be near
kernfs_iop_lookup() to avoid the need for a forward declaration.

There's no functional change from this patch.

Signed-off-by: Ian Kent 
---
 fs/kernfs/dir.c |   86 ---
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index d8213fc65eba..9b315f3b20ee 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -559,49 +559,6 @@ void kernfs_put(struct kernfs_node *kn)
 }
 EXPORT_SYMBOL_GPL(kernfs_put);
 
-static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
-{
-   struct kernfs_node *kn;
-
-   if (flags & LOOKUP_RCU)
-   return -ECHILD;
-
-   /* Always perform fresh lookup for negatives */
-   if (d_really_is_negative(dentry))
-   goto out_bad_unlocked;
-
-   kn = kernfs_dentry_node(dentry);
-   down_read(_rwsem);
-
-   /* The kernfs node has been deactivated */
-   if (!kernfs_active_read(kn))
-   goto out_bad;
-
-   /* The kernfs node has been moved? */
-   if (kernfs_dentry_node(dentry->d_parent) != kn->parent)
-   goto out_bad;
-
-   /* The kernfs node has been renamed */
-   if (strcmp(dentry->d_name.name, kn->name) != 0)
-   goto out_bad;
-
-   /* The kernfs node has been moved to a different namespace */
-   if (kn->parent && kernfs_ns_enabled(kn->parent) &&
-   kernfs_info(dentry->d_sb)->ns != kn->ns)
-   goto out_bad;
-
-   up_read(_rwsem);
-   return 1;
-out_bad:
-   up_read(_rwsem);
-out_bad_unlocked:
-   return 0;
-}
-
-const struct dentry_operations kernfs_dops = {
-   .d_revalidate   = kernfs_dop_revalidate,
-};
-
 /**
  * kernfs_node_from_dentry - determine kernfs_node associated with a dentry
  * @dentry: the dentry in question
@@ -1085,6 +1042,49 @@ struct kernfs_node *kernfs_create_empty_dir(struct 
kernfs_node *parent,
return ERR_PTR(rc);
 }
 
+static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
+{
+   struct kernfs_node *kn;
+
+   if (flags & LOOKUP_RCU)
+   return -ECHILD;
+
+   /* Always perform fresh lookup for negatives */
+   if (d_really_is_negative(dentry))
+   goto out_bad_unlocked;
+
+   kn = kernfs_dentry_node(dentry);
+   down_read(_rwsem);
+
+   /* The kernfs node has been deactivated */
+   if (!kernfs_active_read(kn))
+   goto out_bad;
+
+   /* The kernfs node has been moved? */
+   if (kernfs_dentry_node(dentry->d_parent) != kn->parent)
+   goto out_bad;
+
+   /* The kernfs node has been renamed */
+   if (strcmp(dentry->d_name.name, kn->name) != 0)
+   goto out_bad;
+
+   /* The kernfs node has been moved to a different namespace */
+   if (kn->parent && kernfs_ns_enabled(kn->parent) &&
+   kernfs_info(dentry->d_sb)->ns != kn->ns)
+   goto out_bad;
+
+   up_read(_rwsem);
+   return 1;
+out_bad:
+   up_read(_rwsem);
+out_bad_unlocked:
+   return 0;
+}
+
+const struct dentry_operations kernfs_dops = {
+   .d_revalidate   = kernfs_dop_revalidate,
+};
+
 static struct dentry *kernfs_iop_lookup(struct inode *dir,
struct dentry *dentry,
unsigned int flags)




RE: [PATCH v2 0/2] enable spi flash and update is25wp256d page write capabilities

2020-05-24 Thread Sagar Kadam
Hi,

A gentle reminder.
Any suggestions here?

BR,
Sagar Kadam

> -Original Message-
> From: Sagar Kadam 
> Sent: Tuesday, May 19, 2020 4:16 PM
> To: linux-ri...@lists.infradead.org; linux-kernel@vger.kernel.org; linux-
> m...@lists.infradead.org
> Cc: Paul Walmsley ; pal...@dabbelt.com;
> a...@eecs.berkeley.edu; tudor.amba...@microchip.com;
> miquel.ray...@bootlin.com; rich...@nod.at; vigne...@ti.com;
> anup.pa...@wdc.com; Sagar Kadam 
> Subject: [PATCH v2 0/2] enable spi flash and update is25wp256d page write
> capabilities
> 
> HiFive Unleashed A00 board has is25wp256d snor chip. It is observed that it
> gets configured with Serial Input Page program by the end of spi_nor_scan.
> Using the post bfpt fixup hook we prioritize the page program settings to
> use quad input page program (opcode:0x34) over serial input page program
> (opcode: 0x12).
> 
> The patchset is tested on Linux 5.7.0-rc5.
> 
> Changelog:
> ===
> V2:
> -Split common code between is25lp256 and is25wp256 devices as suggested
> Added a generic post bfpt fixup handler that identifies the flash parts
> based on their device id and uses the corresponding fixup. Other device's
> that need a post bfpt fixup can just add the device id check and either
> reuse the available fixups or write the necessary fixup code if one is not
> available.
> 
> V1:
> -Moved SPI_SIFIVE from defconfig to Kconfig.socs for SOC_SIFIVE.
>  Retained it's configurability using "imply" instead of "select"
> 
> V0: Base version patch (Tested on 5.7.0-rc3).
> 
> 
> Sagar Shrikant Kadam (2):
>   riscv: defconfig: enable spi nor on Hifive Unleashed A00
>   spi: nor: update page program settings for is25wp256 using post bfpt
> fixup
> 
>  arch/riscv/Kconfig.socs  |  1 +
>  arch/riscv/configs/defconfig |  3 +-
>  drivers/mtd/spi-nor/issi.c   | 72
> 
>  3 files changed, 63 insertions(+), 13 deletions(-)
> 
> --
> 2.7.4



Re: [PATCH V2 3/3] mmc: sdhci: Allow platform controlled voltage switching

2020-05-24 Thread Adrian Hunter
On 21/05/20 6:23 pm, Veerabhadrarao Badiganti wrote:
> From: Vijay Viswanath 
> 
> If vendor platform drivers are controlling whole logic of voltage
> switching, then sdhci driver no need control vqmmc regulator.
> So skip enabling/disable vqmmc from SDHC driver.
> 
> Signed-off-by: Vijay Viswanath 
> Signed-off-by: Veerabhadrarao Badiganti 

Acked-by: Adrian Hunter 

> ---
>  drivers/mmc/host/sdhci.c | 32 +++-
>  drivers/mmc/host/sdhci.h |  1 +
>  2 files changed, 20 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 1bb6b67..88e5312 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -4098,6 +4098,7 @@ int sdhci_setup_host(struct sdhci_host *host)
>   unsigned int override_timeout_clk;
>   u32 max_clk;
>   int ret;
> + bool enable_vqmmc = false;
>  
>   WARN_ON(host == NULL);
>   if (host == NULL)
> @@ -4111,9 +4112,12 @@ int sdhci_setup_host(struct sdhci_host *host)
>* the host can take the appropriate action if regulators are not
>* available.
>*/
> - ret = mmc_regulator_get_supply(mmc);
> - if (ret)
> - return ret;
> + if (!mmc->supply.vqmmc) {
> + ret = mmc_regulator_get_supply(mmc);
> + if (ret)
> + return ret;
> + enable_vqmmc  = true;
> + }
>  
>   DBG("Version:   0x%08x | Present:  0x%08x\n",
>   sdhci_readw(host, SDHCI_HOST_VERSION),
> @@ -4373,7 +4377,15 @@ int sdhci_setup_host(struct sdhci_host *host)
>   mmc->caps |= MMC_CAP_NEEDS_POLL;
>  
>   if (!IS_ERR(mmc->supply.vqmmc)) {
> - ret = regulator_enable(mmc->supply.vqmmc);
> + if (enable_vqmmc) {
> + ret = regulator_enable(mmc->supply.vqmmc);
> + if (ret) {
> + pr_warn("%s: Failed to enable vqmmc regulator: 
> %d\n",
> + mmc_hostname(mmc), ret);
> + mmc->supply.vqmmc = ERR_PTR(-EINVAL);
> + }
> + host->sdhci_core_to_disable_vqmmc = !ret;
> + }
>  
>   /* If vqmmc provides no 1.8V signalling, then there's no UHS */
>   if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 170,
> @@ -4386,12 +4398,6 @@ int sdhci_setup_host(struct sdhci_host *host)
>   if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 270,
>   360))
>   host->flags &= ~SDHCI_SIGNALING_330;
> -
> - if (ret) {
> - pr_warn("%s: Failed to enable vqmmc regulator: %d\n",
> - mmc_hostname(mmc), ret);
> - mmc->supply.vqmmc = ERR_PTR(-EINVAL);
> - }
>   }
>  
>   if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) {
> @@ -4625,7 +4631,7 @@ int sdhci_setup_host(struct sdhci_host *host)
>   return 0;
>  
>  unreg:
> - if (!IS_ERR(mmc->supply.vqmmc))
> + if (host->sdhci_core_to_disable_vqmmc)
>   regulator_disable(mmc->supply.vqmmc);
>  undma:
>   if (host->align_buffer)
> @@ -4643,7 +4649,7 @@ void sdhci_cleanup_host(struct sdhci_host *host)
>  {
>   struct mmc_host *mmc = host->mmc;
>  
> - if (!IS_ERR(mmc->supply.vqmmc))
> + if (host->sdhci_core_to_disable_vqmmc)
>   regulator_disable(mmc->supply.vqmmc);
>  
>   if (host->align_buffer)
> @@ -4780,7 +4786,7 @@ void sdhci_remove_host(struct sdhci_host *host, int 
> dead)
>  
>   destroy_workqueue(host->complete_wq);
>  
> - if (!IS_ERR(mmc->supply.vqmmc))
> + if (host->sdhci_core_to_disable_vqmmc)
>   regulator_disable(mmc->supply.vqmmc);
>  
>   if (host->align_buffer)
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 8d2a096..c7dbc68 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -570,6 +570,7 @@ struct sdhci_host {
>   u32 caps1;  /* CAPABILITY_1 */
>   bool read_caps; /* Capability flags have been read */
>  
> + bool sdhci_core_to_disable_vqmmc;  /* sdhci core can disable vqmmc */
>   unsigned intocr_avail_sdio; /* OCR bit masks */
>   unsigned intocr_avail_sd;
>   unsigned intocr_avail_mmc;
> 



Re: Another approach of UFSHPB

2020-05-24 Thread Daejun Park
I am Daejun Park who is working to patch HPB driver.
Thank you for your comment, and the following is our answer.

> Splitting the UFS driver into multiple modules would be great if the
> interface between these modules can be kept small and elegant. However,
> I'm not sure that this approach should be based on Linux device driver
> bus concept. Devices can be unbound at any time from their driver by
> writing into the "unbind" sysfs attribute. I don't think we want the UFS
> core functionality ever to be unbound while any other UFS functionality
> is still active. Has it been considered to implement each feature as a
> loadable module without relying on the bus model? The existing kernel
> module infrastructure already prevents to unload modules (e.g. the UFS
> core) that are in use by a kernel module that depends on it (e.g. UFS HPB).

The HPB driver is close to the UFS core function, but it is not essential
for operating UFS device. With reference to this article
(https://lwn.net/Articles/645810/), we implemented extended UFS-feature
as bus model. Because the HPB driver consumes the user's main memory, it should
support bind / unbind functionality as needed. We implemented the HPB driver 
can be unbind / unload on runtime.

> What will happen if a feature module is unloaded (e.g. HPB) while I/O is
> ongoing that relies on HPB?

In the HPB driver, it checks whether the HPB can be unload / unbind through
the reference counter. Therefore, there is no problem that the driver is 
unloaded / unbind when there is I/O related to HPB.

> Should these parameters be per module or per UFS device?

I think it is necessary to take parameters for each module. 
This is because each extended UFS-feature module has different functions
and may require different parameters.

Thanks,

Daejun Park.


Re: [PATCH v4 14/45] powerpc/32s: Don't warn when mapping RO data ROX.

2020-05-24 Thread Michael Ellerman
Christophe Leroy  writes:
> Mapping RO data as ROX is not an issue since that data
> cannot be modified to introduce an exploit.

Being pedantic: it is still an issue, in that it means there's more
targets for a code-reuse attack.

But given the entire kernel text is also available for code-reuse
attacks, the RO data is unlikely to contain any useful sequences that
aren't also in the kernel text.

> PPC64 accepts to have RO data mapped ROX, as a trade off
> between kernel size and strictness of protection.
>
> On PPC32, kernel size is even more critical as amount of
> memory is usually small.

Yep, I think it's a reasonable trade off to make.

cheers

> Depending on the number of available IBATs, the last IBATs
> might overflow the end of text. Only warn if it crosses
> the end of RO data.
>
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/mm/book3s32/mmu.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
> index 39ba53ca5bb5..a9b2cbc74797 100644
> --- a/arch/powerpc/mm/book3s32/mmu.c
> +++ b/arch/powerpc/mm/book3s32/mmu.c
> @@ -187,6 +187,7 @@ void mmu_mark_initmem_nx(void)
>   int i;
>   unsigned long base = (unsigned long)_stext - PAGE_OFFSET;
>   unsigned long top = (unsigned long)_etext - PAGE_OFFSET;
> + unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET;
>   unsigned long size;
>  
>   if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
> @@ -201,9 +202,10 @@ void mmu_mark_initmem_nx(void)
>   size = block_size(base, top);
>   size = max(size, 128UL << 10);
>   if ((top - base) > size) {
> - if (strict_kernel_rwx_enabled())
> - pr_warn("Kernel _etext not properly aligned\n");
>   size <<= 1;
> + if (strict_kernel_rwx_enabled() && base + size > border)
> + pr_warn("Some RW data is getting mapped X. "
> + "Adjust CONFIG_DATA_SHIFT to avoid 
> that.\n");
>   }
>   setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT);
>   base += size;
> -- 
> 2.25.0


[git pull] habanalabs second pull request for kernel 5.8

2020-05-24 Thread Oded Gabbay
Hello Greg,

This is the second pull request for habanalabs driver for kernel 5.8.

It contains important improvements to our MMU code and our ASIC reset code.

Please see the tag message for more details on what this pull request
contains.

Thanks,
Oded

The following changes since commit 709b41b56a16a5901a89dcaeb75d2233f80d9e55:

  misc: rtsx: Remove unnecessary rts5249_set_aspm(), rts5260_set_aspm() 
(2020-05-22 09:38:14 +0200)

are available in the Git repository at:

  git://people.freedesktop.org/~gabbayo/linux 
tags/misc-habanalabs-next-2020-05-25

for you to fetch changes up to 8ff5f4fd40df9525675ea0e512da4cec65d646eb:

  habanalabs: handle MMU cache invalidation timeout (2020-05-25 08:17:57 +0300)


This tag contains the following changes for kernel 5.8:

- Improve MMU cache invalidation code and handle case where the
  invalidation doesn't finish in a reasonable time.

- Remove the option to perform soft-reset to GAUDI. Soft-reset is where the
  driver only resets the compute and DMA engines of the ASIC. This is not
  relevant to GAUDI as we must also reset the NIC ports. And when we reset
  the NIC ports, we must also reset other stuff so we prefer to just do
  hard-reset (where we reset the entire ASIC except for PCIe).

- Fail the hard-reset procedure in case we still have user processes which
  have active file-descriptors on a device. Doing hard-reset in that case
  can result in a kernel panic because of gen_pool checks

- Don't initialize the default wait callback of dma_buf with the default
  wait function as that's the default...


Daniel Vetter (1):
  habanalabs: don't set default fence_ops->wait

Oded Gabbay (1):
  habanalabs: GAUDI does not support soft-reset

Omer Shpigelman (4):
  habanalabs: improve MMU cache invalidation code
  habanalabs: add print for soft reset due to event
  habanalabs: don't allow hard reset with open processes
  habanalabs: handle MMU cache invalidation timeout

 drivers/misc/habanalabs/command_submission.c |  1 -
 drivers/misc/habanalabs/device.c | 23 ++---
 drivers/misc/habanalabs/gaudi/gaudi.c| 74 ++--
 drivers/misc/habanalabs/goya/goya.c  | 35 -
 drivers/misc/habanalabs/habanalabs.h | 10 ++--
 drivers/misc/habanalabs/memory.c | 35 ++---
 drivers/misc/habanalabs/sysfs.c  |  5 ++
 7 files changed, 126 insertions(+), 57 deletions(-)


Re: [PATCH 0/2] Optimise try_to_wake_up() when wakee is descheduling

2020-05-24 Thread Ingo Molnar


* Mel Gorman  wrote:

> The following two patches optimise try_to_wake_up() when the wakee is
> descheduling. In a vanilla kernel, there can be excessive time spent
> spinning on p->on_rq. This is fine if it's a strictly synchronous wakeup
> and the waker is going to sleep but in other cases, the waker spins until
> it can do work that can be deferred to the wakee.
> 
> The first patch frontloads work that can be done before p->on_rq is
> checked.  If it's a wakeup on a CPU that does not share cache then the
> wakelist is used instead of spinning. The second patch goes a little
> further and uses the wakelist if the wakee is descheduling and is the
> only task running on the target CPU.
> 
> The performance impact is documented in the changelog of the second patch.
> 
>  kernel/sched/core.c  | 81 
>  kernel/sched/sched.h |  3 +-
>  2 files changed, 61 insertions(+), 23 deletions(-)

Thanks, these are really nice improvements, those latency spikes in netperf
runs were always annoying, and they've been there forever I think.

I've applied these two patches to tip:sched/core:

  c6e7bd7afaeb: ("sched/core: Optimize ttwu() spinning on p->on_cpu")
  2ebb17717550: ("sched/core: Offload wakee task activation if it the wakee is 
descheduling")

In 2ebb17717550 I resolved the conflict with a recent cleanup by PeterZ:

  90b5363acd47: ("sched: Clean up scheduler_ipi()")

... which had a drive-by cleanup of ttwu_queue_remote() as well.

Thanks,

Ingo


[tip: sched/core] sched/core: Offload wakee task activation if it the wakee is descheduling

2020-05-24 Thread tip-bot2 for Mel Gorman
The following commit has been merged into the sched/core branch of tip:

Commit-ID: 2ebb17717550607bcd85fb8cf7d24ac870e9d762
Gitweb:
https://git.kernel.org/tip/2ebb17717550607bcd85fb8cf7d24ac870e9d762
Author:Mel Gorman 
AuthorDate:Sun, 24 May 2020 21:29:56 +01:00
Committer: Ingo Molnar 
CommitterDate: Mon, 25 May 2020 07:04:10 +02:00

sched/core: Offload wakee task activation if it the wakee is descheduling

The previous commit:

  c6e7bd7afaeb: ("sched/core: Optimize ttwu() spinning on p->on_cpu")

avoids spinning on p->on_rq when the task is descheduling, but only if the
wakee is on a CPU that does not share cache with the waker.

This patch offloads the activation of the wakee to the CPU that is about to
go idle if the task is the only one on the runqueue. This potentially allows
the waker task to continue making progress when the wakeup is not strictly
synchronous.

This is very obvious with netperf UDP_STREAM running on localhost. The
waker is sending packets as quickly as possible without waiting for any
reply. It frequently wakes the server for the processing of packets and
when netserver is using local memory, it quickly completes the processing
and goes back to idle. The waker often observes that netserver is on_rq
and spins excessively leading to a drop in throughput.

This is a comparison of 5.7-rc6 against "sched: Optimize ttwu() spinning
on p->on_cpu" and against this patch labeled vanilla, optttwu-v1r1 and
localwakelist-v1r2 respectively.

  5.7.0-rc6  5.7.0-rc6  
5.7.0-rc6
vanilla   optttwu-v1r1 
localwakelist-v1r2
Hmean send-64 251.49 (   0.00%)  258.05 *   2.61%*  305.59 
*  21.51%*
Hmean send-128497.86 (   0.00%)  519.89 *   4.43%*  600.25 
*  20.57%*
Hmean send-256944.90 (   0.00%)  997.45 *   5.56%* 1140.19 
*  20.67%*
Hmean send-1024  3779.03 (   0.00%) 3859.18 *   2.12%* 4518.19 
*  19.56%*
Hmean send-2048  7030.81 (   0.00%) 7315.99 *   4.06%* 8683.01 
*  23.50%*
Hmean send-3312 10847.44 (   0.00%)11149.43 *   2.78%*12896.71 
*  18.89%*
Hmean send-4096 13436.19 (   0.00%)13614.09 (   1.32%)15041.09 
*  11.94%*
Hmean send-8192 22624.49 (   0.00%)23265.32 *   2.83%*24534.96 
*   8.44%*
Hmean send-1638434441.87 (   0.00%)36457.15 *   5.85%*35986.21 
*   4.48%*

Note that this benefit is not universal to all wakeups, it only applies
to the case where the waker often spins on p->on_rq.

The impact can be seen from a "perf sched latency" report generated from
a single iteration of one packet size:

   
-
Task  |   Runtime ms  | Switches | Average delay ms | 
Maximum delay ms | Maximum delay at   |
   
-

  vanilla
netperf:4337  |  21709.193 ms | 2932 | avg:0.002 ms | max:  
  0.041 ms | max at:112.154512 s
netserver:4338|  14629.459 ms |  5146990 | avg:0.001 ms | max: 
1615.864 ms | max at:140.134496 s

  localwakelist-v1r2
netperf:4339  |  29789.717 ms | 2460 | avg:0.002 ms | max:  
  0.059 ms | max at:138.205389 s
netserver:4340|  18858.767 ms |  7279005 | avg:0.001 ms | max:  
  0.362 ms | max at:135.709683 s
   
-

Note that the average wakeup delay is quite small on both the vanilla
kernel and with the two patches applied. However, there are significant
outliers with the vanilla kernel with the maximum one measured as 1615
milliseconds with a vanilla kernel but never worse than 0.362 ms with
both patches applied and a much higher rate of context switching.

Similarly a separate profile of cycles showed that 2.83% of all cycles
were spent in try_to_wake_up() with almost half of the cycles spent
on spinning on p->on_rq. With the two patches, the percentage of cycles
spent in try_to_wake_up() drops to 1.13%

Signed-off-by: Mel Gorman 
Signed-off-by: Ingo Molnar 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Jirka Hladky 
Cc: Vincent Guittot 
Cc: valentin.schnei...@arm.com
Cc: Hillf Danton 
Cc: Rik van Riel 
Link: 
https://lore.kernel.org/r/20200524202956.27665-3-mgor...@techsingularity.net
---
 kernel/sched/core.c  | 39 +--
 kernel/sched/sched.h |  3 ++-
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 903c9ee..6130ab1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2312,7 +2312,13 @@ static void wake_csd_func(void *info)
sched_ttwu_pending();
 }

Re: [RFC 00/16] KVM protected memory extension

2020-05-24 Thread Kirill A. Shutemov
On Fri, May 22, 2020 at 03:51:58PM +0300, Kirill A. Shutemov wrote:
> == Background / Problem ==
> 
> There are a number of hardware features (MKTME, SEV) which protect guest
> memory from some unauthorized host access. The patchset proposes a purely
> software feature that mitigates some of the same host-side read-only
> attacks.

CC people who worked on the related patchsets.
 
> == What does this set mitigate? ==
> 
>  - Host kernel ”accidental” access to guest data (think speculation)
> 
>  - Host kernel induced access to guest data (write(fd, _data_ptr, len))
> 
>  - Host userspace access to guest data (compromised qemu)
> 
> == What does this set NOT mitigate? ==
> 
>  - Full host kernel compromise.  Kernel will just map the pages again.
> 
>  - Hardware attacks
> 
> 
> The patchset is RFC-quality: it works but has known issues that must be
> addressed before it can be considered for applying.
> 
> We are looking for high-level feedback on the concept.  Some open
> questions:
> 
>  - This protects from some kernel and host userspace read-only attacks,
>but does not place the host kernel outside the trust boundary. Is it
>still valuable?
> 
>  - Can this approach be used to avoid cache-coherency problems with
>hardware encryption schemes that repurpose physical bits?
> 
>  - The guest kernel must be modified for this to work.  Is that a deal
>breaker, especially for public clouds?
> 
>  - Are the costs of removing pages from the direct map too high to be
>feasible?
> 
> == Series Overview ==
> 
> The hardware features protect guest data by encrypting it and then
> ensuring that only the right guest can decrypt it.  This has the
> side-effect of making the kernel direct map and userspace mapping
> (QEMU et al) useless.  But, this teaches us something very useful:
> neither the kernel or userspace mappings are really necessary for normal
> guest operations.
> 
> Instead of using encryption, this series simply unmaps the memory. One
> advantage compared to allowing access to ciphertext is that it allows bad
> accesses to be caught instead of simply reading garbage.
> 
> Protection from physical attacks needs to be provided by some other means.
> On Intel platforms, (single-key) Total Memory Encryption (TME) provides
> mitigation against physical attacks, such as DIMM interposers sniffing
> memory bus traffic.
> 
> The patchset modifies both host and guest kernel. The guest OS must enable
> the feature via hypercall and mark any memory range that has to be shared
> with the host: DMA regions, bounce buffers, etc. SEV does this marking via a
> bit in the guest’s page table while this approach uses a hypercall.
> 
> For removing the userspace mapping, use a trick similar to what NUMA
> balancing does: convert memory that belongs to KVM memory slots to
> PROT_NONE: all existing entries converted to PROT_NONE with mprotect() and
> the newly faulted in pages get PROT_NONE from the updated vm_page_prot.
> The new VMA flag -- VM_KVM_PROTECTED -- indicates that the pages in the
> VMA must be treated in a special way in the GUP and fault paths. The flag
> allows GUP to return the page even though it is mapped with PROT_NONE, but
> only if the new GUP flag -- FOLL_KVM -- is specified. Any userspace access
> to the memory would result in SIGBUS. Any GUP access without FOLL_KVM
> would result in -EFAULT.
> 
> Any anonymous page faulted into the VM_KVM_PROTECTED VMA gets removed from
> the direct mapping with kernel_map_pages(). Note that kernel_map_pages() only
> flushes local TLB. I think it's a reasonable compromise between security and
> perfromance.
> 
> Zapping the PTE would bring the page back to the direct mapping after 
> clearing.
> At least for now, we don't remove file-backed pages from the direct mapping.
> File-backed pages could be accessed via read/write syscalls. It adds
> complexity.
> 
> Occasionally, host kernel has to access guest memory that was not made
> shared by the guest. For instance, it happens for instruction emulation.
> Normally, it's done via copy_to/from_user() which would fail with -EFAULT
> now. We introduced a new pair of helpers: copy_to/from_guest(). The new
> helpers acquire the page via GUP, map it into kernel address space with
> kmap_atomic()-style mechanism and only then copy the data.
> 
> For some instruction emulation copying is not good enough: cmpxchg
> emulation has to have direct access to the guest memory. __kvm_map_gfn()
> is modified to accommodate the case.
> 
> The patchset is on top of v5.7-rc6 plus this patch:
> 
> https://lkml.kernel.org/r/20200402172507.2786-1-jimmyassars...@gmail.com
> 
> == Open Issues ==
> 
> Unmapping the pages from direct mapping bring a few of issues that have
> not rectified yet:
> 
>  - Touching direct mapping leads to fragmentation. We need to be able to
>recover from it. I have a buggy patch that aims at recovering 2M/1G page.
>It has to be fixed and tested properly
> 
>  - Page migration and KSM is not 

[tip: sched/core] sched/core: Optimize ttwu() spinning on p->on_cpu

2020-05-24 Thread tip-bot2 for Peter Zijlstra
The following commit has been merged into the sched/core branch of tip:

Commit-ID: c6e7bd7afaeb3af55ffac122828035f1c01d1d7b
Gitweb:
https://git.kernel.org/tip/c6e7bd7afaeb3af55ffac122828035f1c01d1d7b
Author:Peter Zijlstra 
AuthorDate:Sun, 24 May 2020 21:29:55 +01:00
Committer: Ingo Molnar 
CommitterDate: Mon, 25 May 2020 07:01:44 +02:00

sched/core: Optimize ttwu() spinning on p->on_cpu

Both Rik and Mel reported seeing ttwu() spend significant time on:

  smp_cond_load_acquire(>on_cpu, !VAL);

Attempt to avoid this by queueing the wakeup on the CPU that owns the
p->on_cpu value. This will then allow the ttwu() to complete without
further waiting.

Since we run schedule() with interrupts disabled, the IPI is
guaranteed to happen after p->on_cpu is cleared, this is what makes it
safe to queue early.

Signed-off-by: Peter Zijlstra (Intel) 
Signed-off-by: Mel Gorman 
Signed-off-by: Ingo Molnar 
Cc: Jirka Hladky 
Cc: Vincent Guittot 
Cc: valentin.schnei...@arm.com
Cc: Hillf Danton 
Cc: Rik van Riel 
Link: 
https://lore.kernel.org/r/20200524202956.27665-2-mgor...@techsingularity.net
---
 kernel/sched/core.c | 52 ++--
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index fa905b6..903c9ee 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2312,7 +2312,7 @@ static void wake_csd_func(void *info)
sched_ttwu_pending();
 }
 
-static void ttwu_queue_remote(struct task_struct *p, int cpu, int wake_flags)
+static void __ttwu_queue_remote(struct task_struct *p, int cpu, int wake_flags)
 {
struct rq *rq = cpu_rq(cpu);
 
@@ -2354,6 +2354,17 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
 {
return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
 }
+
+static bool ttwu_queue_remote(struct task_struct *p, int cpu, int wake_flags)
+{
+   if (sched_feat(TTWU_QUEUE) && !cpus_share_cache(smp_processor_id(), 
cpu)) {
+   sched_clock_cpu(cpu); /* Sync clocks across CPUs */
+   __ttwu_queue_remote(p, cpu, wake_flags);
+   return true;
+   }
+
+   return false;
+}
 #endif /* CONFIG_SMP */
 
 static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
@@ -2362,11 +2373,8 @@ static void ttwu_queue(struct task_struct *p, int cpu, 
int wake_flags)
struct rq_flags rf;
 
 #if defined(CONFIG_SMP)
-   if (sched_feat(TTWU_QUEUE) && !cpus_share_cache(smp_processor_id(), 
cpu)) {
-   sched_clock_cpu(cpu); /* Sync clocks across CPUs */
-   ttwu_queue_remote(p, cpu, wake_flags);
+   if (ttwu_queue_remote(p, cpu, wake_flags))
return;
-   }
 #endif
 
rq_lock(rq, );
@@ -2548,7 +2556,15 @@ try_to_wake_up(struct task_struct *p, unsigned int 
state, int wake_flags)
if (p->on_rq && ttwu_remote(p, wake_flags))
goto unlock;
 
+   if (p->in_iowait) {
+   delayacct_blkio_end(p);
+   atomic_dec(_rq(p)->nr_iowait);
+   }
+
 #ifdef CONFIG_SMP
+   p->sched_contributes_to_load = !!task_contributes_to_load(p);
+   p->state = TASK_WAKING;
+
/*
 * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
 * possible to, falsely, observe p->on_cpu == 0.
@@ -2572,6 +2588,16 @@ try_to_wake_up(struct task_struct *p, unsigned int 
state, int wake_flags)
 
/*
 * If the owning (remote) CPU is still in the middle of schedule() with
+* this task as prev, considering queueing p on the remote CPUs 
wake_list
+* which potentially sends an IPI instead of spinning on p->on_cpu to
+* let the waker make forward progress. This is safe because IRQs are
+* disabled and the IPI will deliver after on_cpu is cleared.
+*/
+   if (READ_ONCE(p->on_cpu) && ttwu_queue_remote(p, cpu, wake_flags))
+   goto unlock;
+
+   /*
+* If the owning (remote) CPU is still in the middle of schedule() with
 * this task as prev, wait until its done referencing the task.
 *
 * Pairs with the smp_store_release() in finish_task().
@@ -2581,28 +2607,12 @@ try_to_wake_up(struct task_struct *p, unsigned int 
state, int wake_flags)
 */
smp_cond_load_acquire(>on_cpu, !VAL);
 
-   p->sched_contributes_to_load = !!task_contributes_to_load(p);
-   p->state = TASK_WAKING;
-
-   if (p->in_iowait) {
-   delayacct_blkio_end(p);
-   atomic_dec(_rq(p)->nr_iowait);
-   }
-
cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags);
if (task_cpu(p) != cpu) {
wake_flags |= WF_MIGRATED;
psi_ttwu_dequeue(p);
set_task_cpu(p, cpu);
}
-
-#else /* CONFIG_SMP */
-
-   if (p->in_iowait) {
-   delayacct_blkio_end(p);
-   atomic_dec(_rq(p)->nr_iowait);
-   }
-
 #endif 

[PATCH] kexec: Do not verify the signature without the lockdown or mandatory signature

2020-05-24 Thread Lianbo Jiang
Signature verification is an important security feature, to protect
system from being attacked with a kernel of unknown origin. Kexec
rebooting is a way to replace the running kernel, hence need be
secured carefully.

In the current code of handling signature verification of kexec kernel,
the logic is very twisted. It mixes signature verification, IMA signature
appraising and kexec lockdown.

If there is no KEXEC_SIG_FORCE, kexec kernel image doesn't have one of
signature, the supported crypto, and key, we don't think this is wrong,
Unless kexec lockdown is executed. IMA is considered as another kind of
signature appraising method.

If kexec kernel image has signature/crypto/key, it has to go through the
signature verification and pass. Otherwise it's seen as verification
failure, and won't be loaded.

Seems kexec kernel image with an unqualified signature is even worse than
those w/o signature at all, this sounds very unreasonable. E.g. If people
get a unsigned kernel to load, or a kernel signed with expired key, which
one is more dangerous?

So, here, let's simplify the logic to improve code readability. If the
KEXEC_SIG_FORCE enabled or kexec lockdown enabled, signature verification
is mandated. Otherwise, we lift the bar for any kernel image.

Signed-off-by: Lianbo Jiang 
---
 kernel/kexec_file.c | 37 ++---
 1 file changed, 6 insertions(+), 31 deletions(-)

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index faa74d5f6941..e4bdf0c42f35 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -181,52 +181,27 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 static int
 kimage_validate_signature(struct kimage *image)
 {
-   const char *reason;
int ret;
 
ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,
   image->kernel_buf_len);
-   switch (ret) {
-   case 0:
-   break;
+   if (ret) {
+   pr_debug("kernel signature verification failed (%d).\n", ret);
 
-   /* Certain verification errors are non-fatal if we're not
-* checking errors, provided we aren't mandating that there
-* must be a valid signature.
-*/
-   case -ENODATA:
-   reason = "kexec of unsigned image";
-   goto decide;
-   case -ENOPKG:
-   reason = "kexec of image with unsupported crypto";
-   goto decide;
-   case -ENOKEY:
-   reason = "kexec of image with unavailable key";
-   decide:
-   if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) {
-   pr_notice("%s rejected\n", reason);
+   if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE))
return ret;
-   }
 
-   /* If IMA is guaranteed to appraise a signature on the kexec
+   /*
+* If IMA is guaranteed to appraise a signature on the kexec
 * image, permit it even if the kernel is otherwise locked
 * down.
 */
if (!ima_appraise_signature(READING_KEXEC_IMAGE) &&
security_locked_down(LOCKDOWN_KEXEC))
return -EPERM;
-
-   return 0;
-
-   /* All other errors are fatal, including nomem, unparseable
-* signatures and signature check failures - even if signatures
-* aren't required.
-*/
-   default:
-   pr_notice("kernel signature verification failed (%d).\n", ret);
}
 
-   return ret;
+   return 0;
 }
 #endif
 
-- 
2.17.1



Re: [PATCH] habanalabs: handle MMU cache invalidation timeout

2020-05-24 Thread Oded Gabbay
On Sun, May 24, 2020 at 11:07 PM Omer Shpigelman  wrote:
>
> MMU cache invalidation timeout indicates that the device is unstable and
> therefore unusable.
> Hence in such case do hard reset and return an error to the user if was
> called from ioctl.
> In addition, change the print to error level and rephrase its text.
>
> Signed-off-by: Omer Shpigelman 
> ---
>  drivers/misc/habanalabs/gaudi/gaudi.c | 36 ---
>  drivers/misc/habanalabs/goya/goya.c   | 34 +++--
>  drivers/misc/habanalabs/habanalabs.h  |  8 +++---
>  drivers/misc/habanalabs/memory.c  | 35 --
>  4 files changed, 75 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c 
> b/drivers/misc/habanalabs/gaudi/gaudi.c
> index 92a5130f06fb..61f88e9884ce 100644
> --- a/drivers/misc/habanalabs/gaudi/gaudi.c
> +++ b/drivers/misc/habanalabs/gaudi/gaudi.c
> @@ -5975,7 +5975,7 @@ static void *gaudi_get_events_stat(struct hl_device 
> *hdev, bool aggregate,
> return gaudi->events_stat;
>  }
>
> -static void gaudi_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
> +static int gaudi_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
> u32 flags)
>  {
> struct gaudi_device *gaudi = hdev->asic_specific;
> @@ -5984,15 +5984,15 @@ static void gaudi_mmu_invalidate_cache(struct 
> hl_device *hdev, bool is_hard,
>
> if (!(gaudi->hw_cap_initialized & HW_CAP_MMU) ||
> hdev->hard_reset_pending)
> -   return;
> -
> -   mutex_lock(>mmu_cache_lock);
> +   return 0;
>
> if (hdev->pldm)
> timeout_usec = GAUDI_PLDM_MMU_TIMEOUT_USEC;
> else
> timeout_usec = MMU_CONFIG_TIMEOUT_USEC;
>
> +   mutex_lock(>mmu_cache_lock);
> +
> /* L0 & L1 invalidation */
> WREG32(mmSTLB_INV_PS, 2);
>
> @@ -6006,14 +6006,18 @@ static void gaudi_mmu_invalidate_cache(struct 
> hl_device *hdev, bool is_hard,
>
> WREG32(mmSTLB_INV_SET, 0);
>
> -   if (rc)
> -   dev_notice_ratelimited(hdev->dev,
> -   "Timeout when waiting for MMU cache invalidation\n");
> -
> mutex_unlock(>mmu_cache_lock);
> +
> +   if (rc) {
> +   dev_err_ratelimited(hdev->dev,
> +   "MMU cache invalidation timeout\n");
> +   hl_device_reset(hdev, true, false);
> +   }
> +
> +   return rc;
>  }
>
> -static void gaudi_mmu_invalidate_cache_range(struct hl_device *hdev,
> +static int gaudi_mmu_invalidate_cache_range(struct hl_device *hdev,
> bool is_hard, u32 asid, u64 va, u64 size)
>  {
> struct gaudi_device *gaudi = hdev->asic_specific;
> @@ -6024,7 +6028,7 @@ static void gaudi_mmu_invalidate_cache_range(struct 
> hl_device *hdev,
>
> if (!(gaudi->hw_cap_initialized & HW_CAP_MMU) ||
> hdev->hard_reset_pending)
> -   return;
> +   return 0;
>
> mutex_lock(>mmu_cache_lock);
>
> @@ -6055,11 +6059,15 @@ static void gaudi_mmu_invalidate_cache_range(struct 
> hl_device *hdev,
> 1000,
> timeout_usec);
>
> -   if (rc)
> -   dev_notice_ratelimited(hdev->dev,
> -   "Timeout when waiting for MMU cache invalidation\n");
> -
> mutex_unlock(>mmu_cache_lock);
> +
> +   if (rc) {
> +   dev_err_ratelimited(hdev->dev,
> +   "MMU cache invalidation timeout\n");
> +   hl_device_reset(hdev, true, false);
> +   }
> +
> +   return rc;
>  }
>
>  static int gaudi_mmu_update_asid_hop0_addr(struct hl_device *hdev,
> diff --git a/drivers/misc/habanalabs/goya/goya.c 
> b/drivers/misc/habanalabs/goya/goya.c
> index 152418dfe20c..0d2952bb58df 100644
> --- a/drivers/misc/habanalabs/goya/goya.c
> +++ b/drivers/misc/habanalabs/goya/goya.c
> @@ -4884,7 +4884,7 @@ static void goya_mmu_prepare(struct hl_device *hdev, 
> u32 asid)
> goya_mmu_prepare_reg(hdev, goya_mmu_regs[i], asid);
>  }
>
> -static void goya_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
> +static int goya_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
> u32 flags)
>  {
> struct goya_device *goya = hdev->asic_specific;
> @@ -4893,11 +4893,11 @@ static void goya_mmu_invalidate_cache(struct 
> hl_device *hdev, bool is_hard,
>
> if (!(goya->hw_cap_initialized & HW_CAP_MMU) ||
> hdev->hard_reset_pending)
> -   return;
> +   return 0;
>
> /* no need in L1 only invalidation in Goya */
> if (!is_hard)
> -   return;
> +   return 0;
>
> if (hdev->pldm)
> timeout_usec = GOYA_PLDM_MMU_TIMEOUT_USEC;
> @@ -4919,13 +4919,17 @@ static void 

Re: [PATCH v4 07/45] powerpc/ptdump: Limit size of flags text to 1/2 chars on PPC32

2020-05-24 Thread Michael Ellerman
Christophe Leroy  writes:
> In order to have all flags fit on a 80 chars wide screen,
> reduce the flags to 1 char (2 where ambiguous).

I don't love this, the output is less readable. Is fitting on an 80 char
screen a real issue for you? I just make my terminal window bigger.

cheers


> No cache is 'i'
> User is 'ur' (Supervisor would be sr)
> Shared (for 8xx) becomes 'sh' (it was 'user' when not shared but
> that was ambiguous because that's not entirely right)
>
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/mm/ptdump/8xx.c| 33 ---
>  arch/powerpc/mm/ptdump/shared.c | 35 +
>  2 files changed, 35 insertions(+), 33 deletions(-)


mmotm 2020-05-24-22-09 uploaded

2020-05-24 Thread Andrew Morton
The mm-of-the-moment snapshot 2020-05-24-22-09 has been uploaded to

   http://www.ozlabs.org/~akpm/mmotm/

mmotm-readme.txt says

README for mm-of-the-moment:

http://www.ozlabs.org/~akpm/mmotm/

This is a snapshot of my -mm patch queue.  Uploaded at random hopefully
more than once a week.

You will need quilt to apply these patches to the latest Linus release (5.x
or 5.x-rcY).  The series file is in broken-out.tar.gz and is duplicated in
http://ozlabs.org/~akpm/mmotm/series

The file broken-out.tar.gz contains two datestamp files: .DATE and
.DATE--mm-dd-hh-mm-ss.  Both contain the string -mm-dd-hh-mm-ss,
followed by the base kernel version against which this patch series is to
be applied.

This tree is partially included in linux-next.  To see which patches are
included in linux-next, consult the `series' file.  Only the patches
within the #NEXT_PATCHES_START/#NEXT_PATCHES_END markers are included in
linux-next.


A full copy of the full kernel tree with the linux-next and mmotm patches
already applied is available through git within an hour of the mmotm
release.  Individual mmotm releases are tagged.  The master branch always
points to the latest release, so it's constantly rebasing.

https://github.com/hnaz/linux-mm

The directory http://www.ozlabs.org/~akpm/mmots/ (mm-of-the-second)
contains daily snapshots of the -mm tree.  It is updated more frequently
than mmotm, and is untested.

A git copy of this tree is also available at

https://github.com/hnaz/linux-mm



This mmotm tree contains the following patches against 5.7-rc7:
(patches marked "*" will be included in linux-next)

* checkpatch-test-git_dir-changes.patch
* proc-kpageflags-prevent-an-integer-overflow-in-stable_page_flags.patch
* proc-kpageflags-do-not-use-uninitialized-struct-pages.patch
* kcov-cleanup-debug-messages.patch
* kcov-fix-potential-use-after-free-in-kcov_remote_start.patch
* kcov-move-t-kcov-assignments-into-kcov_start-stop.patch
* kcov-move-t-kcov_sequence-assignment.patch
* kcov-use-t-kcov_mode-as-enabled-indicator.patch
* kcov-collect-coverage-from-interrupts.patch
* usb-core-kcov-collect-coverage-from-usb-complete-callback.patch
* memcg-optimize-memorynuma_stat-like-memorystat.patch
* lib-lzo-fix-ambiguous-encoding-bug-in-lzo-rle.patch
* mm-compaction-avoid-vm_bug_onpageslab-in-page_mapcount.patch
* x86-mm-ptdump-calculate-effective-permissions-correctly.patch
* mm-ptdump-expand-type-of-val-in-note_page.patch
* mm-z3fold-silence-kmemleak-false-positives-of-slots.patch
* mmthp-stop-leaking-unreleased-file-pages.patch
* mm-remove-vm_bug_onpageslab-from-page_mapcount.patch
* squashfs-migrate-from-ll_rw_block-usage-to-bio.patch
* squashfs-migrate-from-ll_rw_block-usage-to-bio-fix.patch
* ocfs2-add-missing-annotation-for-dlm_empty_lockres.patch
* ocfs2-mount-shared-volume-without-ha-stack.patch
* arch-parisc-include-asm-pgtableh-remove-unused-old_pte.patch
* drivers-tty-serial-sh-scic-suppress-uninitialized-var-warning.patch
* ramfs-support-o_tmpfile.patch
* vfs-track-per-sb-writeback-errors-and-report-them-to-syncfs.patch
* buffer-record-blockdev-write-errors-in-super_block-that-it-backs.patch
* kernel-watchdog-flush-all-printk-nmi-buffers-when-hardlockup-detected.patch
  mm.patch
* usercopy-mark-dma-kmalloc-caches-as-usercopy-caches.patch
* mm-slub-fix-corrupted-freechain-in-deactivate_slab.patch
* mm-slub-fix-corrupted-freechain-in-deactivate_slab-fix.patch
* slub-remove-userspace-notifier-for-cache-add-remove.patch
* slub-remove-kmalloc-under-list_lock-from-list_slab_objects.patch
* mm-slub-fix-stack-overruns-with-slub_stats.patch
* mm-slub-add-panic_on_error-to-the-debug-facilities-fix.patch
* mm-dump_page-do-not-crash-with-invalid-mapping-pointer.patch
* mm-move-readahead-prototypes-from-mmh.patch
* mm-return-void-from-various-readahead-functions.patch
* mm-ignore-return-value-of-readpages.patch
* mm-move-readahead-nr_pages-check-into-read_pages.patch
* mm-add-new-readahead_control-api.patch
* mm-use-readahead_control-to-pass-arguments.patch
* mm-rename-various-offset-parameters-to-index.patch
* mm-rename-readahead-loop-variable-to-i.patch
* mm-remove-page_offset-from-readahead-loop.patch
* mm-put-readahead-pages-in-cache-earlier.patch
* mm-add-readahead-address-space-operation.patch
* mm-move-end_index-check-out-of-readahead-loop.patch
* mm-add-page_cache_readahead_unbounded.patch
* mm-document-why-we-dont-set-pagereadahead.patch
* mm-use-memalloc_nofs_save-in-readahead-path.patch
* fs-convert-mpage_readpages-to-mpage_readahead.patch
* btrfs-convert-from-readpages-to-readahead.patch
* erofs-convert-uncompressed-files-from-readpages-to-readahead.patch
* erofs-convert-compressed-files-from-readpages-to-readahead.patch
* ext4-convert-from-readpages-to-readahead.patch
* ext4-pass-the-inode-to-ext4_mpage_readpages.patch
* f2fs-convert-from-readpages-to-readahead.patch
* f2fs-pass-the-inode-to-f2fs_mpage_readpages.patch
* fuse-convert-from-readpages-to-readahead.patch
* 

Re: [PATCH] ASoC: fsl_asrc: Merge suspend/resume function to runtime_suspend/resume

2020-05-24 Thread Nicolin Chen
On Fri, May 22, 2020 at 05:57:24PM +0800, Shengjiu Wang wrote:
> With dedicated power domain for asrc, power can be disabled after
> probe and pm runtime suspend, then the value of all registers need to
> be restored in pm runtime resume. So we can merge suspend/resume function
> to runtime_suspend/resume function and enable regcache only in end of
> probe.
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  sound/soc/fsl/fsl_asrc.c | 70 
>  1 file changed, 27 insertions(+), 43 deletions(-)
> 
> diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> index 432936039de4..3ebbe15ac378 100644
> --- a/sound/soc/fsl/fsl_asrc.c
> +++ b/sound/soc/fsl/fsl_asrc.c
> @@ -1100,6 +1100,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
>   platform_set_drvdata(pdev, asrc);
>   pm_runtime_enable(>dev);
>   spin_lock_init(>lock);
> + regcache_cache_only(asrc->regmap, true);
>  
>   ret = devm_snd_soc_register_component(>dev, _asrc_component,
> _asrc_dai, 1);
> @@ -1117,6 +1118,7 @@ static int fsl_asrc_runtime_resume(struct device *dev)
>   struct fsl_asrc *asrc = dev_get_drvdata(dev);
>   struct fsl_asrc_priv *asrc_priv = asrc->private;
>   int i, ret;
> + u32 asrctr;
>  
>   ret = clk_prepare_enable(asrc->mem_clk);
>   if (ret)
> @@ -1135,6 +1137,24 @@ static int fsl_asrc_runtime_resume(struct device *dev)
>   goto disable_asrck_clk;
>   }
>  
> + /* Stop all pairs provisionally */
> + regmap_read(asrc->regmap, REG_ASRCTR, );
> + regmap_update_bits(asrc->regmap, REG_ASRCTR,
> +ASRCTR_ASRCEi_ALL_MASK, 0);
> +
> + /* Restore all registers */
> + regcache_cache_only(asrc->regmap, false);
> + regcache_mark_dirty(asrc->regmap);


I see you doing regcache_mark_dirty() in the resume() now,
being different from previously doing in suspend()?

Thanks
Nic


> + regcache_sync(asrc->regmap);
> +
> + regmap_update_bits(asrc->regmap, REG_ASRCFG,
> +ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
> +ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
> +
> + /* Restart enabled pairs */
> + regmap_update_bits(asrc->regmap, REG_ASRCTR,
> +ASRCTR_ASRCEi_ALL_MASK, asrctr);
> +
>   return 0;
>  
>  disable_asrck_clk:
> @@ -1155,6 +1175,11 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
>   struct fsl_asrc_priv *asrc_priv = asrc->private;
>   int i;
>  
> + regmap_read(asrc->regmap, REG_ASRCFG,
> + _priv->regcache_cfg);
> +
> + regcache_cache_only(asrc->regmap, true);
> +
>   for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
>   clk_disable_unprepare(asrc_priv->asrck_clk[i]);
>   if (!IS_ERR(asrc->spba_clk))
> @@ -1166,51 +1191,10 @@ static int fsl_asrc_runtime_suspend(struct device 
> *dev)
>  }
>  #endif /* CONFIG_PM */
>  
> -#ifdef CONFIG_PM_SLEEP
> -static int fsl_asrc_suspend(struct device *dev)
> -{
> - struct fsl_asrc *asrc = dev_get_drvdata(dev);
> - struct fsl_asrc_priv *asrc_priv = asrc->private;
> -
> - regmap_read(asrc->regmap, REG_ASRCFG,
> - _priv->regcache_cfg);
> -
> - regcache_cache_only(asrc->regmap, true);
> - regcache_mark_dirty(asrc->regmap);
> -
> - return 0;
> -}
> -
> -static int fsl_asrc_resume(struct device *dev)
> -{
> - struct fsl_asrc *asrc = dev_get_drvdata(dev);
> - struct fsl_asrc_priv *asrc_priv = asrc->private;
> - u32 asrctr;
> -
> - /* Stop all pairs provisionally */
> - regmap_read(asrc->regmap, REG_ASRCTR, );
> - regmap_update_bits(asrc->regmap, REG_ASRCTR,
> -ASRCTR_ASRCEi_ALL_MASK, 0);
> -
> - /* Restore all registers */
> - regcache_cache_only(asrc->regmap, false);
> - regcache_sync(asrc->regmap);
> -
> - regmap_update_bits(asrc->regmap, REG_ASRCFG,
> -ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
> -ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
> -
> - /* Restart enabled pairs */
> - regmap_update_bits(asrc->regmap, REG_ASRCTR,
> -ASRCTR_ASRCEi_ALL_MASK, asrctr);
> -
> - return 0;
> -}
> -#endif /* CONFIG_PM_SLEEP */
> -
>  static const struct dev_pm_ops fsl_asrc_pm = {
>   SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, 
> NULL)
> - SET_SYSTEM_SLEEP_PM_OPS(fsl_asrc_suspend, fsl_asrc_resume)
> + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> + pm_runtime_force_resume)
>  };
>  
>  static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
> -- 
> 2.21.0
> 


linux-next: build failure after merge of the block tree

2020-05-24 Thread Stephen Rothwell
Hi all,

After merging the block tree, today's linux-next build (arm
multi_v7_defconfig) failed like this:

mm/filemap.c: In function 'generic_file_buffered_read':
mm/filemap.c:2075:9: error: 'written' undeclared (first use in this function); 
did you mean 'writeb'?
 2075 | if (written) {
  | ^~~
  | writeb

Caused by commit

  23d513106fd8 ("mm: support async buffered reads in 
generic_file_buffered_read()")

from the block tree interacting with commit

  6e66f10f2cac ("fs: export generic_file_buffered_read()")

from the btrfs tree.

[Aside: that btrfs tree commit talks about "correct the comments and variable
names", but changes "written" to "copied" in the function definition
but to "already_read" in the header file declaration ...]

I ave applied the following merge fix patch:

From: Stephen Rothwell 
Date: Mon, 25 May 2020 15:00:44 +1000
Subject: [PATCH] mm: fix up for "fs: export generic_file_buffered_read()" merge

Signed-off-by: Stephen Rothwell 
---
 mm/filemap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index 742998883d9c..208095551a17 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2072,7 +2072,7 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
 * serialisations and why it's safe.
 */
if (iocb->ki_flags & IOCB_WAITQ) {
-   if (written) {
+   if (copied) {
put_page(page);
goto out;
}
-- 
2.26.2

-- 
Cheers,
Stephen Rothwell


pgpfsVKVjWRMO.pgp
Description: OpenPGP digital signature


Re: [PATCH] twist: allow converting pr_devel()/pr_debug() into printk(KERN_DEBUG)

2020-05-24 Thread Tetsuo Handa
On 2020/05/25 4:18, Ondrej Mosnacek wrote:
> I'm also not sure if this is really worth it... It would help localize
> the bug in this specific case, but there is nothing systematic about
> it. Are there that many debug print statements that dereference
> pointers that are later passed to functions, but not dereferenced
> otherwise? Maybe yes, but it seems to be quite an optimistic
> assumption... I don't consider it such a big problem that a bug in
> function X only manifests itself deeper in the callchain. There will
> always be such bugs, no matter how many moles you whack.

There are about 1400 pr_debug() callers. About 1000 pr_debug() callers seem
to pass plain '%p' (which is now likely useless for debugging purpose due to
default ptr_to_id() conversion inside pointer()), and about 400 pr_debug()
callers seem to pass '%p[a-zA-Z]' (which does some kind of dereference inside
pointer()). Thus, we might find some bugs by evaluating '%p[a-zA-Z]'.



On Sun, May 24, 2020 at 7:38 PM Joe Perches  wrote:
> While I think this is rather unnecessary,
> what about dev_dbg/netdev_dbg/netif_dbg et al ?

Maybe a good idea, for there are about 24000 *dev_dbg() callers, and
479 callers pass '%p[a-zA-Z]'. But we can defer to another patch, in
case this patch finds crashes before fuzz testing process starts.



Re: lockdep trace with xfs + mm in it from 5.7.0-rc5

2020-05-24 Thread Dave Airlie
On Sat, 23 May 2020 at 06:51, Darrick J. Wong  wrote:
>
> OTOH, it didn't take that long to whip up a patch.
>
> Dave, does this fix your problem?

I reproduced with 5.7.0-rc7, and tried this patch on top in the same
VM doing the same thing.

with this patch I no longer see the lockdep trace.

Tested-by: Dave Airlie 

Thanks,
Dave.


Re: [PATCH v4 24/36] mm: Remove page fault assumption of compound page size

2020-05-24 Thread Kirill A. Shutemov
On Fri, May 15, 2020 at 06:16:44AM -0700, Matthew Wilcox wrote:
> From: "Matthew Wilcox (Oracle)" 
> 
> A compound page in the page cache will not necessarily be of PMD size,
> so check explicitly.
> 
> Signed-off-by: Matthew Wilcox (Oracle) 
> ---
>  mm/memory.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index f703fe8c8346..d68ce428ddd2 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -3549,13 +3549,14 @@ static vm_fault_t do_set_pmd(struct vm_fault *vmf, 
> struct page *page)
>   unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
>   pmd_t entry;
>   int i;
> - vm_fault_t ret;
> + vm_fault_t ret = VM_FAULT_FALLBACK;
>  
>   if (!transhuge_vma_suitable(vma, haddr))
> - return VM_FAULT_FALLBACK;
> + return ret;
>  
> - ret = VM_FAULT_FALLBACK;
>   page = compound_head(page);
> + if (page_order(page) != HPAGE_PMD_ORDER)
> + return ret;

Maybe WARN() for page_order(page) > HPAGE_PMD_ORDER. It would be fun to
handle :P
>  
>   /*
>* Archs like ppc64 need additonal space to store information
> -- 
> 2.26.2
> 

-- 
 Kirill A. Shutemov


Re: [PATCH v4 11/36] fs: Support THPs in zero_user_segments

2020-05-24 Thread Kirill A. Shutemov
On Fri, May 15, 2020 at 06:16:31AM -0700, Matthew Wilcox wrote:
> From: "Matthew Wilcox (Oracle)" 
> 
> We can only kmap() one subpage of a THP at a time, so loop over all
> relevant subpages, skipping ones which don't need to be zeroed.  This is
> too large to inline when THPs are enabled and we actually need highmem,
> so put it in highmem.c.
> 
> Signed-off-by: Matthew Wilcox (Oracle) 
> ---
>  include/linux/highmem.h | 15 +++---
>  mm/highmem.c| 62 +++--
>  2 files changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/highmem.h b/include/linux/highmem.h
> index ea5cdbd8c2c3..74614903619d 100644
> --- a/include/linux/highmem.h
> +++ b/include/linux/highmem.h
> @@ -215,13 +215,18 @@ static inline void clear_highpage(struct page *page)
>   kunmap_atomic(kaddr);
>  }
>  
> +#if defined(CONFIG_HIGHMEM) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
> +void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
> + unsigned start2, unsigned end2);
> +#else /* !HIGHMEM || !TRANSPARENT_HUGEPAGE */
>  static inline void zero_user_segments(struct page *page,
> - unsigned start1, unsigned end1,
> - unsigned start2, unsigned end2)
> + unsigned start1, unsigned end1,
> + unsigned start2, unsigned end2)
>  {
> + unsigned long i;
>   void *kaddr = kmap_atomic(page);
>  
> - BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE);
> + BUG_ON(end1 > thp_size(page) || end2 > thp_size(page));
>  
>   if (end1 > start1)
>   memset(kaddr + start1, 0, end1 - start1);
> @@ -230,8 +235,10 @@ static inline void zero_user_segments(struct page *page,
>   memset(kaddr + start2, 0, end2 - start2);
>  
>   kunmap_atomic(kaddr);
> - flush_dcache_page(page);
> + for (i = 0; i < hpage_nr_pages(page); i++)
> + flush_dcache_page(page + i);

Well, we need to settle on whether flush_dcache_page() has to be aware
about compound pages. There are already architectures that know how to
flush compound page, see ARM.

-- 
 Kirill A. Shutemov


RE: [RFC PATCH v12 10/11] arm64: add mechanism to let user choose which counter to return

2020-05-24 Thread Jianyong Wu
Hi Richard,

> -Original Message-
> From: Richard Cochran 
> Sent: Sunday, May 24, 2020 10:11 AM
> To: Jianyong Wu 
> Cc: net...@vger.kernel.org; yangbo...@nxp.com; john.stu...@linaro.org;
> t...@linutronix.de; pbonz...@redhat.com; sean.j.christopher...@intel.com;
> m...@kernel.org; Mark Rutland ; w...@kernel.org;
> Suzuki Poulose ; Steven Price
> ; linux-kernel@vger.kernel.org; linux-arm-
> ker...@lists.infradead.org; kvm...@lists.cs.columbia.edu;
> k...@vger.kernel.org; Steve Capper ; Kaly Xin
> ; Justin He ; Wei Chen
> ; nd 
> Subject: Re: [RFC PATCH v12 10/11] arm64: add mechanism to let user choose
> which counter to return
> 
> On Fri, May 22, 2020 at 04:37:23PM +0800, Jianyong Wu wrote:
> > In general, vm inside will use virtual counter compered with host use
> > phyical counter. But in some special scenarios, like nested
> > virtualization, phyical counter maybe used by vm. A interface added in
> > ptp_kvm driver to offer a mechanism to let user choose which counter
> > should be return from host.
> 
> Sounds like you have two time sources, one for normal guest, and one for
> nested.  Why not simply offer the correct one to user space automatically?  If
> that cannot be done, then just offer two PHC devices with descriptive names.
> 

It's a good idea, but in most case physical counter will not be used, so it's  
better not keep 2 ptp devices all the time.
How about adding an extra argument in struct ptp_clock_info to serve as a flag, 
then we can control this flag using IOCTL to determine the counter type.
In this way, no extra arguments needed in .getcrosststamp. But we also need 
specific code in ptp_ioctl to implement it like in this patch.

The second way, maybe we can use the flag as a module parameter, this is easier 
to implement.
  @m...@kernel.org WDYT?
 
> > diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
> > index fef72f29f3c8..8b0a7b328bcd 100644
> > --- a/drivers/ptp/ptp_chardev.c
> > +++ b/drivers/ptp/ptp_chardev.c
> > @@ -123,6 +123,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int
> cmd, unsigned long arg)
> > struct timespec64 ts;
> > int enable, err = 0;
> >
> > +#ifdef CONFIG_ARM64
> > +   static long flag;
> 
> static?  This is not going to fly.

Need remove here.

> 
> > +* In most cases, we just need virtual counter from host and
> > +* there is limited scenario using this to get physical counter
> > +* in guest.
> > +* Be careful to use this as there is no way to set it back
> > +* unless you reinstall the module.
> 
> How on earth is the user supposed to know this?
> 
Yeah, It's odd , should be removed.

> From your description, this "flag" really should be a module parameter.
Maybe use flag as a module parameter is a better way.

Thanks
Jianyong 
> 
> Thanks,
> Richard


Re: [PATCH] x86/mm: Fix boot with some memory above MAXMEM

2020-05-24 Thread Kirill A. Shutemov
On Mon, May 11, 2020 at 10:17:21PM +0300, Kirill A. Shutemov wrote:
> A 5-level paging capable machine can have memory above 46-bit in the
> physical address space. This memory is only addressable in the 5-level
> paging mode: we don't have enough virtual address space to create direct
> mapping for such memory in the 4-level paging mode.
> 
> Currently, we fail boot completely: NULL pointer dereference in
> subsection_map_init().
> 
> Skip creating a memblock for such memory instead and notify user that
> some memory is not addressable.
> 
> Signed-off-by: Kirill A. Shutemov 
> Reviewed-by: Dave Hansen 
> Cc: sta...@vger.kernel.org # v4.14
> ---

Gentle ping.

It's not urgent, but it's a bug fix. Please consider applying.

> Tested with a hacked QEMU: 
> https://gist.github.com/kiryl/d45eb54110944ff95e544972d8bdac1d
> 
> ---
>  arch/x86/kernel/e820.c | 19 +--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index c5399e80c59c..d320d37d0f95 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -1280,8 +1280,8 @@ void __init e820__memory_setup(void)
>  
>  void __init e820__memblock_setup(void)
>  {
> + u64 size, end, not_addressable = 0;
>   int i;
> - u64 end;
>  
>   /*
>* The bootstrap memblock region count maximum is 128 entries
> @@ -1307,7 +1307,22 @@ void __init e820__memblock_setup(void)
>   if (entry->type != E820_TYPE_RAM && entry->type != 
> E820_TYPE_RESERVED_KERN)
>   continue;
>  
> - memblock_add(entry->addr, entry->size);
> + if (entry->addr >= MAXMEM) {
> + not_addressable += entry->size;
> + continue;
> + }
> +
> + end = min_t(u64, end, MAXMEM - 1);
> + size = end - entry->addr;
> + not_addressable += entry->size - size;
> + memblock_add(entry->addr, size);
> + }
> +
> + if (not_addressable) {
> + pr_err("%lldGB of physical memory is not addressable in the 
> paging mode\n",
> +not_addressable >> 30);
> + if (!pgtable_l5_enabled())
> + pr_err("Consider enabling 5-level paging\n");
>   }
>  
>   /* Throw away partial pages: */
> -- 
> 2.26.2
> 
> 

-- 
 Kirill A. Shutemov


Re: [PATCH v2] mm: remove VM_BUG_ON(PageSlab()) from page_mapcount()

2020-05-24 Thread Kirill A. Shutemov
On Sun, May 24, 2020 at 04:43:18PM +0300, Konstantin Khlebnikov wrote:
> Replace superfluous VM_BUG_ON() with comment about correct usage.
> 
> Technically reverts commit 1d148e218a0d0566b1c06f2f45f1436d53b049b2
> ("mm: add VM_BUG_ON_PAGE() to page_mapcount()"), but context have changed.
> 
> Function isolate_migratepages_block() runs some checks out of lru_lock
> when choose pages for migration. After checking PageLRU() it checks extra
> page references by comparing page_count() and page_mapcount(). Between
> these two checks page could be removed from lru, freed and taken by slab.
> 
> As a result this race triggers VM_BUG_ON(PageSlab()) in page_mapcount().
> Race window is tiny. For certain workload this happens around once a year.
> 
> 
>  page:ea0105ca9380 count:1 mapcount:0 mapping:88ff7712c180 index:0x0 
> compound_mapcount: 0
>  flags: 0x5008100(slab|head)
>  raw: 05008100 dead0100 dead0200 88ff7712c180
>  raw:  80200020 0001 
>  page dumped because: VM_BUG_ON_PAGE(PageSlab(page))
>  [ cut here ]
>  kernel BUG at ./include/linux/mm.h:628!
>  invalid opcode:  [#1] SMP NOPTI
>  CPU: 77 PID: 504 Comm: kcompactd1 Tainted: GW 4.19.109-27 #1
>  Hardware name: Yandex T175-N41-Y3N/MY81-EX0-Y3N, BIOS R05 06/20/2019
>  RIP: 0010:isolate_migratepages_block+0x986/0x9b0
> 
> 
> Code in isolate_migratepages_block() was added in commit 119d6d59dcc0
> ("mm, compaction: avoid isolating pinned pages") before adding VM_BUG_ON
> into page_mapcount().
> 
> This race has been predicted in 2015 by Vlastimil Babka (see link below).
> 
> Signed-off-by: Konstantin Khlebnikov 
> Fixes: 1d148e218a0d ("mm: add VM_BUG_ON_PAGE() to page_mapcount()")
> Link: https://lore.kernel.org/lkml/557710e1.6060...@suse.cz/
> Link: 
> https://lore.kernel.org/linux-mm/158937872515.474360.5066096871639561424.stgit@buzz/T/
>  (v1)

Acked-by: Kirill A. Shutemov 

-- 
 Kirill A. Shutemov


Re: [PATCH V4 7/8] fs/ext4: Introduce DAX inode flag

2020-05-24 Thread Ira Weiny
On Fri, May 22, 2020 at 01:48:48PM +0200, Jan Kara wrote:
> On Thu 21-05-20 12:13:12, ira.we...@intel.com wrote:
> > From: Ira Weiny 
> > 
> > Add a flag to preserve FS_XFLAG_DAX in the ext4 inode.
> > 
> > Set the flag to be user visible and changeable.  Set the flag to be
> > inherited.  Allow applications to change the flag at any time with the
> > exception of if VERITY or ENCRYPT is set.
> > 
> > Disallow setting VERITY or ENCRYPT if DAX is set.
> > 
> > Finally, on regular files, flag the inode to not be cached to facilitate
> > changing S_DAX on the next creation of the inode.
> > 
> > Signed-off-by: Ira Weiny 
> 
> ...
> 
> > @@ -303,6 +318,16 @@ static int ext4_ioctl_setflags(struct inode *inode,
> > unsigned int jflag;
> > struct super_block *sb = inode->i_sb;
> >  
> > +   if (ext4_test_inode_flag(inode, EXT4_INODE_DAX)) {
> > +   if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY) ||
> > +   ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT) ||
> > +   ext4_test_inode_state(inode,
> > + EXT4_STATE_VERITY_IN_PROGRESS)) {
> > +   err = -EOPNOTSUPP;
> > +   goto flags_out;
> > +   }
> > +   }
> 
> The way this check is implemented wouldn't IMO do what we need... It
> doesn't check the flags that are being set but just the current inode
> state. I think it should rather be:

Sorry, I got confused by the flags when I wrote this.

> 
>   if ((flags ^ oldflags) & EXT4_INODE_DAX_FL) {
>   ...
>   }
> 
> And perhaps move this to a place in ext4_ioctl_setflags() where we check
> other similar conflicts.

Sure.  It seems like a ext4_setflags_prepare() helper would be in order.  I'll
see what I can do.

> 
> And then we should check conflicts with the journal flag as well, as I
> mentioned in reply to the first patch. There it is more complicated by the
> fact that we should disallow setting of both EXT4_INODE_DAX_FL and
> EXT4_JOURNAL_DATA_FL at the same time so the checks will be somewhat more
> complicated.

I'm confused by jflag.  Why is EXT4_JOURNAL_DATA_FL stored in jflag?

Ira

> 
>   Honza
> 
> > +
> > /* Is it quota file? Do not allow user to mess with it */
> > if (ext4_is_quota_file(inode))
> > goto flags_out;
> -- 
> Jan Kara 
> SUSE Labs, CR


[PATCH 2/2] refperf: Add a test to measure performance of read-side synchronization

2020-05-24 Thread Joel Fernandes (Google)
Add a test for comparing the performance of RCU with various read-side
synchronization mechanisms. The test has proved useful for collecting
data and performing these comparisons.

Currently RCU, SRCU, reader-writer lock, reader-writer semaphore and
reference counting can be measured using refperf.perf_type parameter.
Each invocation of the test runs measures performance of a specific
mechanism.

The maximum number of CPUs to concurrently run readers on is chosen by
the test itself and is 75% of the total number of CPUs. So if you had 24
CPUs, the test runs with a maximum of 18 parallel readers.

A number of experiments are conducted, and in each experiment, the
number of readers is increased by 1, upto the 75% of CPUs mark. During
each experiment, all readers execute an empty loop with refperf.loops
iterations and time the total loop duration. This is then averaged.

Example output:
Parameters "refperf.perf_type=srcu refperf.loops=200" looks like:

[3.347133] srcu-ref-perf:
[3.347133] Threads  Time(ns)
[3.347133] 136
[3.347133] 234
[3.347133] 334
[3.347133] 434
[3.347133] 533
[3.347133] 633
[3.347133] 733
[3.347133] 833
[3.347133] 933
[3.347133] 10   33
[3.347133] 11   33
[3.347133] 12   33
[3.347133] 13   33
[3.347133] 14   33
[3.347133] 15   32
[3.347133] 16   33
[3.347133] 17   33
[3.347133] 18   34

Signed-off-by: Joel Fernandes (Google) 

---
 kernel/rcu/Kconfig.debug |  19 ++
 kernel/rcu/Makefile  |   1 +
 kernel/rcu/refperf.c | 558 +++
 3 files changed, 578 insertions(+)
 create mode 100644 kernel/rcu/refperf.c

diff --git a/kernel/rcu/Kconfig.debug b/kernel/rcu/Kconfig.debug
index a4db41d9a401e..04c35e1e3c3fa 100644
--- a/kernel/rcu/Kconfig.debug
+++ b/kernel/rcu/Kconfig.debug
@@ -56,6 +56,25 @@ config RCU_TORTURE_TEST
  Say M if you want the RCU torture tests to build as a module.
  Say N if you are unsure.
 
+config RCU_REF_PERF_TEST
+   tristate "Performance tests for read-side synchronization (RCU and 
others)"
+   depends on DEBUG_KERNEL
+   select TORTURE_TEST
+   select SRCU
+   select TASKS_RCU
+   select TASKS_RUDE_RCU
+   select TASKS_TRACE_RCU
+   default n
+   help
+ This option provides a kernel module that runs performance tests
+ useful comparing RCU with various read-side synchronization 
mechanisms.
+ The kernel module may be built after the fact on the running kernel 
to be
+ tested, if desired.
+
+ Say Y here if you want these performance tests built into the kernel.
+ Say M if you want to build it as a module instead.
+ Say N if you are unsure.
+
 config RCU_CPU_STALL_TIMEOUT
int "RCU CPU stall timeout in seconds"
depends on RCU_STALL_COMMON
diff --git a/kernel/rcu/Makefile b/kernel/rcu/Makefile
index f91f2c2cf1382..ba7d82609cbe1 100644
--- a/kernel/rcu/Makefile
+++ b/kernel/rcu/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_TREE_SRCU) += srcutree.o
 obj-$(CONFIG_TINY_SRCU) += srcutiny.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 obj-$(CONFIG_RCU_PERF_TEST) += rcuperf.o
+obj-$(CONFIG_RCU_REF_PERF_TEST) += refperf.o
 obj-$(CONFIG_TREE_RCU) += tree.o
 obj-$(CONFIG_TINY_RCU) += tiny.o
 obj-$(CONFIG_RCU_NEED_SEGCBLIST) += rcu_segcblist.o
diff --git a/kernel/rcu/refperf.c b/kernel/rcu/refperf.c
new file mode 100644
index 0..20a40eb134ad1
--- /dev/null
+++ b/kernel/rcu/refperf.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Performance test comparing RCU vs other mechanisms
+// for acquiring references on objects.
+//
+// Copyright (C) Google, 2020.
+//
+// Author: Joel Fernandes 
+
+#define pr_fmt(fmt) fmt
+
+#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 "rcu.h"
+
+#define PERF_FLAG "-ref-perf: "
+
+#define PERFOUT(s, x...) \
+   pr_alert("%s" PERF_FLAG s, perf_type, ## x)
+
+#define VERBOSE_PERFOUT(s, x...) \
+   do { if (verbose) pr_alert("%s" PERF_FLAG s, perf_type, ## x); } while 
(0)
+
+#define VERBOSE_PERFOUT_ERRSTRING(s, x...) \
+   do { if (verbose) pr_alert("%s" PERF_FLAG "!!! " s, perf_type, ## x); } 
while (0)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joel Fernandes (Google) ");
+
+static char *perf_type = "rcu";
+module_param(perf_type, charp, 0444);
+MODULE_PARM_DESC(perf_type, "Type of test (rcu, srcu, refcnt, rwsem, rwlock.");
+
+torture_param(int, verbose, 0, "Enable verbose debugging printk()s");
+
+// Number of loops per experiment, all readers execute an operation 
concurrently
+torture_param(long, loops, 1000, "Number of loops 

[PATCH 1/2] rcuperf: Remove useless while loops around wait_event

2020-05-24 Thread Joel Fernandes (Google)
wait_event() already retries if the condition for the wake up is not
satisifed after wake up. Remove them from the rcuperf test.

Signed-off-by: Joel Fernandes (Google) 

---
 kernel/rcu/rcuperf.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c
index 16dd1e6b7c09f..246da8fe199e8 100644
--- a/kernel/rcu/rcuperf.c
+++ b/kernel/rcu/rcuperf.c
@@ -576,11 +576,8 @@ static int compute_real(int n)
 static int
 rcu_perf_shutdown(void *arg)
 {
-   do {
-   wait_event(shutdown_wq,
-  atomic_read(_rcu_perf_writer_finished) >=
-  nrealwriters);
-   } while (atomic_read(_rcu_perf_writer_finished) < nrealwriters);
+   wait_event(shutdown_wq,
+  atomic_read(_rcu_perf_writer_finished) >= nrealwriters);
smp_mb(); /* Wake before output. */
rcu_perf_cleanup();
kernel_power_off();
@@ -693,11 +690,8 @@ kfree_perf_cleanup(void)
 static int
 kfree_perf_shutdown(void *arg)
 {
-   do {
-   wait_event(shutdown_wq,
-  atomic_read(_kfree_perf_thread_ended) >=
-  kfree_nrealthreads);
-   } while (atomic_read(_kfree_perf_thread_ended) < kfree_nrealthreads);
+   wait_event(shutdown_wq,
+  atomic_read(_kfree_perf_thread_ended) >= 
kfree_nrealthreads);
 
smp_mb(); /* Wake before output. */
 
-- 
2.27.0.rc0.183.gde8f92d652-goog



Re: [PATCH] mm,thp: stop leaking unreleased file pages

2020-05-24 Thread Kirill A. Shutemov
On Sat, May 23, 2020 at 06:50:15PM -0700, Hugh Dickins wrote:
> When collapse_file() calls try_to_release_page(), it has already
> isolated the page: so if releasing buffers happens to fail (as it
> sometimes does), remember to putback_lru_page(): otherwise that page is
> left unreclaimable and unfreeable, and the file extent uncollapsible.
> 
> Signed-off-by: Hugh Dickins 
> Fixes: 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS")
> Cc: sta...@vger.kernel.org # v5.4+

Acked-by: Kirill A. Shutemov 

-- 
 Kirill A. Shutemov


Re: [RFC 08/11] net: phy: Allow mdio buses to auto-probe c45 devices

2020-05-24 Thread Jeremy Linton

Hi,

On 5/24/20 9:44 AM, Andrew Lunn wrote:

+++ b/include/linux/phy.h
@@ -275,6 +275,11 @@ struct mii_bus {
int reset_delay_us;
/* RESET GPIO descriptor pointer */
struct gpio_desc *reset_gpiod;
+   /* bus capabilities, used for probing */
+   enum {
+   MDIOBUS_C22_ONLY = 0,
+   MDIOBUS_C45_FIRST,
+   } probe_capabilities;
  };



I'm not so keen on _FIRST. It suggest _LAST would also be valid.  But
that then suggests this is not a bus property, but a PHY property, and
some PHYs might need _FIRST and other phys need _LAST, and then you
have a bus which has both sorts of PHY on it, and you have a problem.

So i think it would be better to have

enum {
MDIOBUS_UNKNOWN = 0,
MDIOBUS_C22,
MDIOBUS_C45,
MDIOBUS_C45_C22,
} bus_capabilities;

Describe just what the bus master can support.


Yes, the naming is reasonable and I will update it in the next patch. I 
went around a bit myself with this naming early on, and the problem I 
saw was that a C45 capable master, can have C45 electrical phy's that 
only respond to c22 requests (AFAIK). So the MDIOBUS_C45 (I think I was 
calling it C45_ONLY) is an invalid selection. Not, that it wouldn't be 
helpful to have a C45_ONLY case, but that the assumption is that you 
wouldn't try and probe c22 registers, which I thought was a mistake.



Thanks,



Re: [PATCH v5 0/7] Add interrupt support to FPGA DFL drivers

2020-05-24 Thread Xu Yilun
Hi Moritz:

Thanks for your comments for first 3 patches. And do you have more comments
on last 4 patches?

I have done the changes for those fixes. I'm not sure if I should send
the v6 patchset now?

Thanks,
Yilun.

On Wed, May 06, 2020 at 06:17:27PM -0700, Moritz Fischer wrote:
> Hi Xu,
> 
> On Tue, May 5, 2020 at 10:13 PM Xu Yilun  wrote:
> >
> > Hi Moritz:
> >
> > Hao and I did several rounds of review and fix in the mailing list. Now
> > the patches are all acked by Hao.
> >
> > Could you please help review it when you have time?
> 
> I'll get to it this weekend. Sorry for the delay,
> 
> Moritz
> >
> > Thanks! :)
> >
> > On Mon, Apr 20, 2020 at 04:11:36PM +0800, Xu Yilun wrote:
> > > This patchset add interrupt support to FPGA DFL drivers.
> > >
> > > With these patches, DFL driver will parse and assign interrupt resources
> > > for enumerated feature devices and their sub features.
> > >
> > > This patchset also introduces a set of APIs for user to monitor DFL
> > > interrupts. Three sub features (DFL FME error, DFL AFU error and user
> > > interrupt) drivers now support these APIs.
> > >
> > > Patch #1: DFL framework change. Accept interrupt info input from DFL bus
> > >   driver, and add interrupt parsing and assignment for feature
> > >   sub devices.
> > > Patch #2: DFL pci driver change, add interrupt info on DFL enumeration.
> > > Patch #3: DFL framework change. Add helper functions for feature sub
> > >   device drivers to handle interrupt and notify users.
> > > Patch #4: Add interrupt support for AFU error reporting sub feature.
> > > Patch #5: Add interrupt support for FME global error reporting sub
> > >   feature.
> > > Patch #6: Add interrupt support for a new sub feature, to handle user
> > >   interrupts implemented in AFU.
> > > Patch #7: Documentation for DFL interrupt handling.
> > >
> > > Main changes from v1:
> > >  - Early validating irq table for each feature in parse_feature_irq()
> > >in Patch #1.
> > >  - Changes IOCTL interfaces. use DFL_FPGA_FME/PORT_XXX_GET_IRQ_NUM
> > >instead of DFL_FPGA_FME/PORT_XXX_GET_INFO, delete flag field for
> > >DFL_FPGA_FME/PORT_XXX_SET_IRQ param
> > >
> > > Main changes from v2:
> > >  - put parse_feature_irqs() inside create_feature_instance().
> > >  - refines code for dfl_fpga_set_irq_triggers, delete local variable j.
> > >  - put_user() instead of copy_to_user() for DFL_FPGA_XXX_GET_IRQ_NUM IOCTL
> > >
> > > Main changes from v3:
> > >  - rebased to 5.7-rc1.
> > >  - fail the dfl enumeration when irq parsing error happens.
> > >  - Add 2 helper functions in dfl.c to handle generic irq ioctls in feature
> > >drivers.
> > >
> > > Main changes from v4:
> > >  - Minor fixes for Hao's comments.
> > >
> > > Xu Yilun (7):
> > >   fpga: dfl: parse interrupt info for feature devices on enumeration
> > >   fpga: dfl: pci: add irq info for feature devices enumeration
> > >   fpga: dfl: introduce interrupt trigger setting API
> > >   fpga: dfl: afu: add interrupt support for port error reporting
> > >   fpga: dfl: fme: add interrupt support for global error reporting
> > >   fpga: dfl: afu: add AFU interrupt support
> > >   Documentation: fpga: dfl: add descriptions for interrupt related
> > > interfaces.
> > >
> > >  Documentation/fpga/dfl.rst|  19 +++
> > >  drivers/fpga/dfl-afu-error.c  |  17 +++
> > >  drivers/fpga/dfl-afu-main.c   |  32 +
> > >  drivers/fpga/dfl-fme-error.c  |  18 +++
> > >  drivers/fpga/dfl-fme-main.c   |   6 +
> > >  drivers/fpga/dfl-pci.c|  80 +--
> > >  drivers/fpga/dfl.c| 310 
> > > ++
> > >  drivers/fpga/dfl.h|  57 
> > >  include/uapi/linux/fpga-dfl.h |  82 +++
> > >  9 files changed, 612 insertions(+), 9 deletions(-)
> > >
> > > --
> > > 2.7.4


Re: [RFC 07/11] net: phy: reset invalid phy reads of 0 back to 0xffffffff

2020-05-24 Thread Jeremy Linton

Hi,

On 5/23/20 1:44 PM, Russell King - ARM Linux admin wrote:

On Fri, May 22, 2020 at 04:30:55PM -0500, Jeremy Linton wrote:

MMD's in the device list sometimes return 0 for their id.
When that happens lets reset the id back to 0xfff so
that we don't get a stub device created for it.

This is a questionable commit, but i'm tossing it out
there along with the comment that reading the spec
seems to indicate that maybe there are further registers
that could be probed in an attempt to resolve some futher
"bad" phys. It sort of comes down to do we want unused phy
devices floating around (potentially unmatched in dt) or
do we want to cut them off early and let DT create them
directly.


I'm not sure what you mean "stub device" or "unused phy devices
floating around" - the individual MMDs are not treated as separate
"phy devices", but as one PHY device as a whole.



Well, I guess its clearer to say phy/mmd devices with a phy_id=0. Which 
is a problem if we don't have DT overriding the phy_id for a given 
address. Although AFAIK given a couple of the /sys/bus/mdio_bus/devices 
lists I've seen, and after studying this code for a while now, I think 
"bogus" phy's might be getting created*. I was far to easy, to upset the 
cart when I was hacking on this set, and end up with a directory chuck 
full of phys.


So this gets close to one of the questions I asked in the cover letter. 
This patch and 09/11 serve to cut off possibly valid phy's which are 
failing to identify themselves using the standard registers. Which per 
the 802.3 spec there is a blurb about 0 in the id registers for some 
cases. Its not really a critical problem for ACPI machines to have these 
phys around (OTOH, there might be issues with c22 phys on c45 electrical 
buses that respond to c45 reg requests but don't set the c22 regs flag, 
I haven't seen that yet.). I considered dropping this patch, and 9/11 
was a last minute addition. I kept it because I was worried all those 
extra "reserved" MMDs would end up with id = 0's in there and break 
something.


* In places where there isn't actually a phy, likely a large part of the 
problem was clearing the c22 bit, which allowed 0x returns to 
slip through the devices list.


[PATCH v2 2/9] irqchip/sun6i-r: Add wakeup support

2020-05-24 Thread Samuel Holland
Maintain a mask of wake-enabled IRQs, and enable them in hardware
during the syscore phase of suspend. The restore the original mask
of enabled IRQs (just the NMI) during resume.

This serves two purposes. First, it lets power management firmware
running on the ARISC coprocessor know which wakeup sources Linux wants
to have enabled. That way, it can avoid turning them off when it shuts
down the remainder of the clock tree. Second, it preconfigures the
coprocessor's interrupt controller, so the firmware's wakeup logic
is as simple as waiting for an interrupt to arrive.

Signed-off-by: Samuel Holland 
---
 drivers/irqchip/irq-sun6i-r.c | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/drivers/irqchip/irq-sun6i-r.c b/drivers/irqchip/irq-sun6i-r.c
index f8bfa5515f20..a5deea92057f 100644
--- a/drivers/irqchip/irq-sun6i-r.c
+++ b/drivers/irqchip/irq-sun6i-r.c
@@ -3,12 +3,14 @@
 // Allwinner A31 and newer SoCs R_INTC driver
 //
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -24,6 +26,9 @@
 static void __iomem *base;
 static irq_hw_number_t parent_offset;
 static u32 parent_type;
+#ifdef CONFIG_PM_SLEEP
+static atomic_t wake_mask;
+#endif
 
 static struct irq_chip sun6i_r_intc_edge;
 static struct irq_chip sun6i_r_intc_level;
@@ -106,6 +111,20 @@ static int sun6i_r_intc_irq_set_type(struct irq_data 
*data, unsigned int type)
return irq_chip_set_type_parent(data, type);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int sun6i_r_intc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+   if (on)
+   atomic_or(BIT(data->hwirq), _mask);
+   else
+   atomic_andnot(BIT(data->hwirq), _mask);
+
+   return 0;
+}
+#else
+#define sun6i_r_intc_irq_set_wake NULL
+#endif
+
 static struct irq_chip sun6i_r_intc_edge = {
.name   = "sun6i-r-intc",
.irq_ack= sun6i_r_intc_irq_ack,
@@ -116,6 +135,7 @@ static struct irq_chip sun6i_r_intc_edge = {
.irq_set_type   = sun6i_r_intc_irq_set_type,
.irq_get_irqchip_state  = irq_chip_get_parent_state,
.irq_set_irqchip_state  = irq_chip_set_parent_state,
+   .irq_set_wake   = sun6i_r_intc_irq_set_wake,
.irq_set_vcpu_affinity  = irq_chip_set_vcpu_affinity_parent,
.flags  = IRQCHIP_SET_TYPE_MASKED,
 };
@@ -129,6 +149,7 @@ static struct irq_chip sun6i_r_intc_level = {
.irq_set_type   = sun6i_r_intc_irq_set_type,
.irq_get_irqchip_state  = irq_chip_get_parent_state,
.irq_set_irqchip_state  = irq_chip_set_parent_state,
+   .irq_set_wake   = sun6i_r_intc_irq_set_wake,
.irq_set_vcpu_affinity  = irq_chip_set_vcpu_affinity_parent,
.flags  = IRQCHIP_SET_TYPE_MASKED |
  IRQCHIP_EOI_THREADED,
@@ -170,6 +191,34 @@ static const struct irq_domain_ops sun6i_r_intc_domain_ops 
= {
.free   = irq_domain_free_irqs_common,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int sun6i_r_intc_suspend(void)
+{
+   /* All wake IRQs are enabled during system sleep. */
+   writel_relaxed(atomic_read(_mask), base + SUN6I_R_INTC_ENABLE);
+
+   return 0;
+}
+
+static void sun6i_r_intc_resume(void)
+{
+   /* Only the NMI is relevant during normal operation. */
+   writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_ENABLE);
+}
+
+static struct syscore_ops sun6i_r_intc_syscore_ops = {
+   .suspend= sun6i_r_intc_suspend,
+   .resume = sun6i_r_intc_resume,
+};
+
+static void sun6i_r_intc_syscore_init(void)
+{
+   register_syscore_ops(_r_intc_syscore_ops);
+}
+#else
+static inline void sun6i_r_intc_syscore_init(void) {}
+#endif
+
 static int __init sun6i_r_intc_init(struct device_node *node,
struct device_node *parent)
 {
@@ -211,6 +260,8 @@ static int __init sun6i_r_intc_init(struct device_node 
*node,
writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_PENDING);
writel_relaxed(NMI_HWIRQ_BIT, base + SUN6I_R_INTC_ENABLE);
 
+   sun6i_r_intc_syscore_init();
+
return 0;
 }
 IRQCHIP_DECLARE(sun6i_r_intc, "allwinner,sun6i-a31-r-intc", sun6i_r_intc_init);
-- 
2.24.1



[PATCH v2 5/9] ARM: dts: sunxi: h3/h5: Move wakeup-capable IRQs to r_intc

2020-05-24 Thread Samuel Holland
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.

For the H3/H5, r_intc IRQ numbers are offset by 32 from the GIC IRQ
numbers.

Signed-off-by: Samuel Holland 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 94f648ad1c9e..93e7ce60a64b 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -829,8 +829,9 @@ hdmi_phy: hdmi-phy@1ef {
rtc: rtc@1f0 {
/* compatible is in per SoC .dtsi file */
reg = <0x01f0 0x400>;
-   interrupts = ,
-;
+   interrupt-parent = <_intc>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>,
+<9 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
clocks = <>;
#clock-cells = <1>;
@@ -865,7 +866,8 @@ ir: ir@1f02000 {
clocks = <_ccu CLK_APB0_IR>, <_ccu CLK_IR>;
clock-names = "apb", "ir";
resets = <_ccu RST_APB0_IR>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x400>;
status = "disabled";
};
@@ -886,7 +888,8 @@ r_i2c: i2c@1f02400 {
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-h3-r-pinctrl";
reg = <0x01f02c00 0x400>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_ccu CLK_APB0_PIO>, <>, < 0>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
-- 
2.24.1



[PATCH v2 9/9] arm64: dts: allwinner: h6: Move wakeup-capable IRQs to r_intc

2020-05-24 Thread Samuel Holland
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.

For the H6, r_intc IRQ numbers are offset by 96 from the GIC IRQ
numbers.

Signed-off-by: Samuel Holland 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d912188dc6ea..188699f47dea 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -844,8 +844,9 @@ tcon_tv_out_tcon_top: endpoint@1 {
rtc: rtc@700 {
compatible = "allwinner,sun50i-h6-rtc";
reg = <0x0700 0x400>;
-   interrupts = ,
-;
+   interrupt-parent = <_intc>;
+   interrupts = <5 IRQ_TYPE_LEVEL_HIGH>,
+<6 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
#clock-cells = <1>;
};
@@ -880,8 +881,9 @@ r_intc: interrupt-controller@7021000 {
r_pio: pinctrl@7022000 {
compatible = "allwinner,sun50i-h6-r-pinctrl";
reg = <0x07022000 0x400>;
-   interrupts = ,
-;
+   interrupt-parent = <_intc>;
+   interrupts = < 9 IRQ_TYPE_LEVEL_HIGH>,
+<15 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_ccu CLK_R_APB1>, <>, < 0>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
@@ -904,7 +906,8 @@ r_ir: ir@704 {
compatible = "allwinner,sun50i-h6-ir",
 "allwinner,sun6i-a31-ir";
reg = <0x0704 0x400>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_ccu CLK_R_APB1_IR>,
 <_ccu CLK_IR>;
clock-names = "apb", "ir";
-- 
2.24.1



[PATCH v2 4/9] ARM: dts: sunxi: h3/h5: Add r_intc node

2020-05-24 Thread Samuel Holland
The H3 and H5 SoCs have an additional interrupt controller in the RTC
power domain that can be used to enable wakeup for certain IRQs.

Add a node for it.

Signed-off-by: Samuel Holland 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 01a5df9aa71b..94f648ad1c9e 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -836,6 +836,15 @@ rtc: rtc@1f0 {
#clock-cells = <1>;
};
 
+   r_intc: interrupt-controller@1f00c00 {
+   compatible = "allwinner,sun8i-h3-r-intc",
+"allwinner,sun6i-a31-r-intc";
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   reg = <0x01f00c00 0x400>;
+   interrupts = ;
+   };
+
r_ccu: clock@1f01400 {
compatible = "allwinner,sun8i-h3-r-ccu";
reg = <0x01f01400 0x100>;
-- 
2.24.1



[PATCH v2 7/9] arm64: dts: allwinner: a64: Move wakeup-capable IRQs to r_intc

2020-05-24 Thread Samuel Holland
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.

For the A64, r_intc IRQ numbers are offset by 32 from the GIC IRQ
numbers.

Signed-off-by: Samuel Holland 
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index c26cc1fcaffd..33f2ce0d93aa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -1176,8 +1176,9 @@ rtc: rtc@1f0 {
compatible = "allwinner,sun50i-a64-rtc",
 "allwinner,sun8i-h3-rtc";
reg = <0x01f0 0x400>;
-   interrupts = ,
-;
+   interrupt-parent = <_intc>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>,
+<9 IRQ_TYPE_LEVEL_HIGH>;
clock-output-names = "osc32k", "osc32k-out", "iosc";
clocks = <>;
#clock-cells = <1>;
@@ -1227,7 +1228,8 @@ r_ir: ir@1f02000 {
clocks = <_ccu CLK_APB0_IR>, <_ccu CLK_IR>;
clock-names = "apb", "ir";
resets = <_ccu RST_APB0_IR>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <_ir_rx_pin>;
status = "disabled";
@@ -1247,7 +1249,8 @@ r_pwm: pwm@1f03800 {
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun50i-a64-r-pinctrl";
reg = <0x01f02c00 0x400>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_ccu CLK_APB0_PIO>, <>, <>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
-- 
2.24.1



[PATCH v2 1/9] irqchip/sun6i-r: Use a stacked irqchip driver

2020-05-24 Thread Samuel Holland
The R_INTC in the A31 and newer sun8i/sun50i SoCs is more similar to the
original sun4i interrupt controller than the sun7i/sun9i NMI controller.
It is used for two distinct purposes:
 1) To control the trigger, latch, and mask for the NMI input pin
 2) To provide the interrupt input for the ARISC coprocessor

As this interrupt controller is not documented, information about it
comes from vendor-provided ARISC firmware and from experimentation.

Like the original sun4i interrupt controller, it has:
 - A VECTOR_REG at 0x00 (configurable via the BASE_ADDR_REG at 0x04)
 - A NMI_CTRL_REG, PENDING_REG, and ENABLE_REG as used by both the
   sun4i and sunxi-nmi drivers
 - A MASK_REG at 0x50
 - A RESP_REG at 0x60

Differences from the sun4i interrupt controller appear to be:
 - It is only known to have one register of each kind (max 32 inputs)
 - There is no FIQ-related logic
 - There is no interrupt priority logic

In order to fulfill its two purposes, this hardware block combines two
types of IRQs. First, the NMI pin is routed to the "IRQ 0" input on this
chip, with a trigger type controlled by the NMI_CTRL_REG. The "IRQ 0
pending" output from this chip, if enabled, is then routed to a SPI IRQ
input on the GIC, as IRQ_TYPE_LEVEL_HIGH. In other words, bit 0 of
ENABLE_REG *does* affect the NMI IRQ seen at the GIC.

The NMI is then followed by a contiguous block of (at least) 15 IRQ
inputs that are connected in parallel to both R_INTC and the GIC. Or
in other words, the other bits of ENABLE_REG *do not* affect the IRQs
seen at the GIC.

Finally, the global "IRQ pending" output from R_INTC, after being masked
by MASK_REG and RESP_REG, is connected to the "external interrupt" input
of the ARISC CPU (an OR1200). This path is not relevant to Linux.

Because of the 1:1 correspondence between R_INTC and GIC inputs, this is
a perfect scenario for using a stacked irqchip driver. We want to hook
into enabling/disabling IRQs to add more features to the GIC
(specifically to allow masking the NMI and setting its trigger type),
but we don't need to actually handle the IRQ in this driver.

And since R_INTC is in the always-on power domain, and its output is
connected directly in to the power management coprocessor, a stacked
irqchip driver provides a simple way to add wakeup support to this set
of IRQs. That is a future patch; for now, just the NMI is moved over.

This driver keeps the same DT binding as the existing driver. The
"interrupt" property of the R_INTC node is used to determine 1) the
offset between GIC and R_INTC hwirq numbers and 2) the type of trigger
between the R_INTC "IRQ 0 pending" output and the GIC NMI input.

This commit mostly reverts commit 173bda53b340 ("irqchip/sunxi-nmi:
Support sun6i-a31-r-intc compatible").

Signed-off-by: Samuel Holland 
---
 arch/arm/mach-sunxi/Kconfig |   4 +
 arch/arm64/Kconfig.platforms|   2 +
 drivers/irqchip/Makefile|   1 +
 drivers/irqchip/irq-sun6i-r.c   | 216 
 drivers/irqchip/irq-sunxi-nmi.c |  26 +---
 5 files changed, 226 insertions(+), 23 deletions(-)
 create mode 100644 drivers/irqchip/irq-sun6i-r.c

diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index eeadb1a4dcfe..216b5954d6a9 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -30,6 +30,8 @@ config MACH_SUN6I
bool "Allwinner A31 (sun6i) SoCs support"
default ARCH_SUNXI
select ARM_GIC
+   select IRQ_DOMAIN_HIERARCHY
+   select IRQ_FASTEOI_HIERARCHY_HANDLERS
select MFD_SUN6I_PRCM
select SUN5I_HSTIMER
 
@@ -46,6 +48,8 @@ config MACH_SUN8I
bool "Allwinner sun8i Family SoCs support"
default ARCH_SUNXI
select ARM_GIC
+   select IRQ_DOMAIN_HIERARCHY
+   select IRQ_FASTEOI_HIERARCHY_HANDLERS
select MFD_SUN6I_PRCM
 
 config MACH_SUN9I
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 55d70cfe0f9e..b9c3a7118a2c 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -17,6 +17,8 @@ config ARCH_SUNXI
bool "Allwinner sunxi 64-bit SoC Family"
select ARCH_HAS_RESET_CONTROLLER
select GENERIC_IRQ_CHIP
+   select IRQ_DOMAIN_HIERARCHY
+   select IRQ_FASTEOI_HIERARCHY_HANDLERS
select PINCTRL
select RESET_CONTROLLER
help
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 37bbe39bf909..c9692bdaabfa 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_OR1K_PIC)+= 
irq-or1k-pic.o
 obj-$(CONFIG_ORION_IRQCHIP)+= irq-orion.o
 obj-$(CONFIG_OMAP_IRQCHIP) += irq-omap-intc.o
 obj-$(CONFIG_ARCH_SUNXI)   += irq-sun4i.o
+obj-$(CONFIG_ARCH_SUNXI)   += irq-sun6i-r.o
 obj-$(CONFIG_ARCH_SUNXI)   += irq-sunxi-nmi.o
 obj-$(CONFIG_ARCH_SPEAR3XX)+= spear-shirq.o
 obj-$(CONFIG_ARM_GIC)  += 

[PATCH v2 8/9] arm64: dts: allwinner: h6: Fix indentation of IR node

2020-05-24 Thread Samuel Holland
This node was indented by two tabs when added instead of one.
Remove the extra tab.

Signed-off-by: Samuel Holland 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 ++--
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index b9ab7d8fa8af..d912188dc6ea 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -901,17 +901,17 @@ r_ir_rx_pin: r-ir-rx-pin {
};
 
r_ir: ir@704 {
-   compatible = "allwinner,sun50i-h6-ir",
-"allwinner,sun6i-a31-ir";
-   reg = <0x0704 0x400>;
-   interrupts = ;
-   clocks = <_ccu CLK_R_APB1_IR>,
-<_ccu CLK_IR>;
-   clock-names = "apb", "ir";
-   resets = <_ccu RST_R_APB1_IR>;
-   pinctrl-names = "default";
-   pinctrl-0 = <_ir_rx_pin>;
-   status = "disabled";
+   compatible = "allwinner,sun50i-h6-ir",
+"allwinner,sun6i-a31-ir";
+   reg = <0x0704 0x400>;
+   interrupts = ;
+   clocks = <_ccu CLK_R_APB1_IR>,
+<_ccu CLK_IR>;
+   clock-names = "apb", "ir";
+   resets = <_ccu RST_R_APB1_IR>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_ir_rx_pin>;
+   status = "disabled";
};
 
r_i2c: i2c@7081400 {
-- 
2.24.1



[PATCH v2 6/9] ARM: dts: sunxi: a83t: Move wakeup-capable IRQs to r_intc

2020-05-24 Thread Samuel Holland
All IRQs that can be used to wake up the system must be routed through
r_intc, so they are visible to firmware while the system is suspended.

For the A83T, r_intc IRQ numbers are offset by 32 from the GIC IRQ
numbers.

Signed-off-by: Samuel Holland 
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 655404d6d3a3..fcfc573eb96d 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -1130,7 +1130,8 @@ r_cir: ir@1f02000 {
clocks = <_ccu CLK_APB0_IR>, <_ccu CLK_IR>;
clock-names = "apb", "ir";
resets = <_ccu RST_APB0_IR>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01f02000 0x400>;
pinctrl-names = "default";
pinctrl-0 = <_cir_pin>;
@@ -1140,14 +1141,16 @@ r_cir: ir@1f02000 {
r_lradc: lradc@1f03c00 {
compatible = "allwinner,sun8i-a83t-r-lradc";
reg = <0x01f03c00 0x100>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
 
r_pio: pinctrl@1f02c00 {
compatible = "allwinner,sun8i-a83t-r-pinctrl";
reg = <0x01f02c00 0x400>;
-   interrupts = ;
+   interrupt-parent = <_intc>;
+   interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_ccu CLK_APB0_PIO>, <>,
 <>;
clock-names = "apb", "hosc", "losc";
-- 
2.24.1



[PATCH v2 3/9] dt-bindings: irq: Add a compatible for the H3 R_INTC

2020-05-24 Thread Samuel Holland
The Allwinner H3 SoC contains an R_INTC that is, as far as we know,
compatible with the R_INTC present in other sun8i/sun50i SoCs starting
with the A31. Since the R_INTC hardware is undocumented, introduce a new
compatible for the R_INTC variant in this SoC, in case there turns out
to be some difference.

Signed-off-by: Samuel Holland 
---
 .../allwinner,sun7i-a20-sc-nmi.yaml  | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
 
b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
index cf09055da78b..973fe5d17af0 100644
--- 
a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
+++ 
b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun7i-a20-sc-nmi.yaml
@@ -26,15 +26,13 @@ properties:
   - const: allwinner,sun6i-a31-sc-nmi
 deprecated: true
   - const: allwinner,sun7i-a20-sc-nmi
-  - items:
-- const: allwinner,sun8i-a83t-r-intc
-- const: allwinner,sun6i-a31-r-intc
   - const: allwinner,sun9i-a80-sc-nmi
   - items:
-- const: allwinner,sun50i-a64-r-intc
-- const: allwinner,sun6i-a31-r-intc
-  - items:
-- const: allwinner,sun50i-h6-r-intc
+- enum:
+  - allwinner,sun8i-a83t-r-intc
+  - allwinner,sun8i-h3-r-intc
+  - allwinner,sun50i-a64-r-intc
+  - allwinner,sun50i-h6-r-intc
 - const: allwinner,sun6i-a31-r-intc
 
   reg:
-- 
2.24.1



[PATCH v2 0/9] sunxi: Support IRQ wakeup from deep sleep

2020-05-24 Thread Samuel Holland
Allwinner sun8i/sun50i SoCs (A31 and newer) have two interrupt
controllers: GIC and R_INTC. GIC does not support wakeup. R_INTC handles
the external NMI pin, and provides 16-32 IRQs to the ARISC. At least the
first 16 of these correspond 1:1 to a block of GIC IRQs starting with
the NMI.

This series replaces the existing chained irqchip driver used only to
control the NMI, with a stacked irqchip driver that also provides wakeup
capability for those 16 IRQs. The idea is that we preconfigure the
ARISC's IRQ controller, and then the ARISC firmware knows to wake up as
soon as it receives an IRQ.

I went back and forth about updating the existing driver versus writing
a new one. Since the hardware really is different from the NMI-only
controller on the A20, ultimately I went with a new driver. It may be
useful to separately do the chained->stacked conversion on the sunxi-nmi
driver as well.

Patch 1 adds the new driver.
Patch 2 adds wakeup capability.
The other patches update the DT+bindings to use R_INTC where beneficial.

With appropriate firmware, this series allows waking from RTC, NMI/PMIC,
(power button, plugging in USB, etc.), and Port L GPIO (lid switch, BT,
WiFi, modem, etc.).

Changes from v1:
 - Use writel_relaxed() instead if writel().
 - Remove use of the MASK register, as it doesn't affect the NMI as seen
   by the GIC. It only affects the IRQs seen by the coprocessor.
 - Leave NMI_HWIRQ enabled at all times, since it can be masked at the
   GIC level (removed .irq_enable and .irq_disable).
 - Use .irq_ack vs .irq_eoi depending on the trigger type, to avoid
   missing interrupts or double interrupts.
   - Because of this change, the driver needs two "irq_chip"s, one
 with .irq_eoi set to our function and one without.
   - Also because of this, we need IRQ_FASTEOI_HIERARCHY_HANDLERS for
 handle_fasteoi_ack_irq(), so our .irq_ack function gets called
 while the GIC driver works as if handle_fasteoi_irq() was used.
 - Inline the SUNXI_SRC_TYPE_* enum into sun6i_r_intc_irq_set_type().
 - Add a comment explaining how the trigger type is used.
 - Don't call irqd_set_trigger_type().
 - Set IRQCHIP_SET_TYPE_MASKED to match the GIC (since flags from this
   driver mask flags from that one).
 - Set IRQCHIP_EOI_THREADED to avoid doubled level interrupts, since the
   latch will be set again as long as the trigger is met.
 - Replace sun6i_r_intc_domain_translate() with
   irq_domain_translate_twocell().
 - Use an enum for the device tree binding.
 - Update commit messages for accuracy and typos.


Samuel Holland (9):
  irqchip/sun6i-r: Use a stacked irqchip driver
  irqchip/sun6i-r: Add wakeup support
  dt-bindings: irq: Add a compatible for the H3 R_INTC
  ARM: dts: sunxi: h3/h5: Add r_intc node
  ARM: dts: sunxi: h3/h5: Move wakeup-capable IRQs to r_intc
  ARM: dts: sunxi: a83t: Move wakeup-capable IRQs to r_intc
  arm64: dts: allwinner: a64: Move wakeup-capable IRQs to r_intc
  arm64: dts: allwinner: h6: Fix indentation of IR node
  arm64: dts: allwinner: h6: Move wakeup-capable IRQs to r_intc

 .../allwinner,sun7i-a20-sc-nmi.yaml   |  12 +-
 arch/arm/boot/dts/sun8i-a83t.dtsi |   9 +-
 arch/arm/boot/dts/sunxi-h3-h5.dtsi|  20 +-
 arch/arm/mach-sunxi/Kconfig   |   4 +
 arch/arm64/Kconfig.platforms  |   2 +
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi |  11 +-
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  |  33 ++-
 drivers/irqchip/Makefile  |   1 +
 drivers/irqchip/irq-sun6i-r.c | 267 ++
 drivers/irqchip/irq-sunxi-nmi.c   |  26 +-
 10 files changed, 329 insertions(+), 56 deletions(-)
 create mode 100644 drivers/irqchip/irq-sun6i-r.c

-- 
2.24.1



Re: [PATCH 1/9] irqchip/sun6i-r: Switch to a stacked irqchip driver

2020-05-24 Thread Samuel Holland
Hello, and thanks for the feedback!

I know this is quite the delay in responding; I wanted to make sure my
understanding of the hardware was as clear as possible before sending a v2.

After experimentation, I came up with a diagram describing the hardware
architecture, available here:
https://linux-sunxi.org/images/5/5c/R_INTC.png (PNG)
https://sholland.org/files/R_INTC_v2.svg (SVG)

Based on that, your feedback, and similar examples like the great explanation of
the robustness requirements in 6dd859508336 ("gpio: zynq: Fix IRQ handlers"), I
think v2 will work properly for both edge and level interrupts. I tested both
triggers, albeit with the same source of (level) interrupts connected to the NMI
pin.

On 1/20/20 4:52 AM, Marc Zyngier wrote:
> Hi Samuel,
> 
> On 2020-01-13 05:49, Samuel Holland wrote:
>> The R_INTC in the A31 and newer sun8i/sun50i SoCs is more similar to the
>> original sun4i interrupt controller than the sun7i/sun9i NMI controller.
>> It is used for two distinct purposes:
>>  1) To control the trigger and mask for the NMI input pin
>>  2) To provide the interrupt input for the ARISC coprocessor
>>
>> As this interrupt controller is not documented, information about it
>> comes from reverse-engineering the BSP-provided ARISC firmware.
>>
>> Like the original sun4i interrupt controller, it has:
>>  - A VECTOR_REG at 0x00 (configurable via the BASE_ADDR_REG at 0x04)
>>  - A NMI_CTRL_REG, PENDING_REG, and ENABLE_REG as used by both the
>>    sun4i and sunxi-nmi drivers
>>  - A MASK_REG at 0x50
>>
>> Differences from the sun4i interrupt controller appear to be:
>>  - It is only known to have one register of each kind (max 32 inputs)
>>  - There is no FIQ-related logic
>>  - There is no interrupt priority logic
>>
>> In order to fulfill its two purposes, this hardware block combines two
>> types of IRQs. First, the NMI pin is routed to the "IRQ 0" input on this
>> chip, with a trigger type controlled by the NMI_CTRL_REG. The (masked)
>> "IRQ 0 pending" output from this chip is then routed to a non-maskable
>> SPI IRQ input on the GIC, as IRQ_TYPE_LEVEL_HIGH. In other words, bit 0
> 
> I object to the "non-maskable" wording here. It may be non-maskable
> at this irqchip level (and yet you seem to have code to that effect),
> but the GIC definitely should be able to mask things.

You're 100% correct here. I had thought IRQ 0 was non-maskable because the MASK
register didn't affect the IRQ being sent to the GIC. Disabling the IRQ via
GICD_ICENABLER does indeed work.

>> of ENABLE_REG and MASK_REG *do* affect the IRQs seen at the GIC.
>>
>> The NMI is then followed by a contiguous block of (at least) 15 IRQ
>> inputs that are connected *in parallel* to both R_INTC and the GIC. Or
>> in other words, the other bits of ENABLE_REG and MASK_REG *do not*
>> affect the IRQs seen at the GIC.
>>
>> Finally, the global "IRQ pending" output from R_INTC is connected to the
>> "external interrupt" input of the ARISC CPU (an OR1200).
>>
>> Because of the 1:1 correspondence between R_INTC and GIC inputs, this is
>> a perfect scenario for using a stacked irqchip driver. We want to hook
>> into enabling/disabling/masking IRQs to add more features to the GIC
>> (specifically to allow masking the NMI and setting its trigger type),
>> but we don't need to actually *handle* the IRQ.
>>
>> And since R_INTC is in the always-on power domain, and its output is
>> connected directly in to the power management coprocessor, a stacked
>> irqchip driver provides a simple way to add wakeup support to this set
>> of IRQs. That is a future patch; for now, just the NMI is moved over.
>>
>> This driver keeps the same DT binding as the existing driver. The
>> "interrupt" property of the R_INTC node is used to determine 1) the
>> offset between GIC and R_INTC hwirq numbers and 2) the type of trigger
>> between the R_INTC "IRQ 0 pending" output and the GIC NMI input.
>>
>> This commit mostly reverts commit 173bda53b340 ("irqchip/sunxi-nmi:
>> Support sun6i-a31-r-intc compatible").
>>
>> Signed-off-by: Samuel Holland 
>> ---
>>  arch/arm/mach-sunxi/Kconfig |   1 +
>>  arch/arm64/Kconfig.platforms    |   1 +
>>  drivers/irqchip/Makefile    |   1 +
>>  drivers/irqchip/irq-sun6i-r.c   | 220 
>>  drivers/irqchip/irq-sunxi-nmi.c |  26 +---
>>  5 files changed, 226 insertions(+), 23 deletions(-)
>>  create mode 100644 drivers/irqchip/irq-sun6i-r.c
>>
>> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
>> index eeadb1a4dcfe..ef1cc25902b5 100644
>> --- a/arch/arm/mach-sunxi/Kconfig
>> +++ b/arch/arm/mach-sunxi/Kconfig
>> @@ -6,6 +6,7 @@ menuconfig ARCH_SUNXI
>>  select CLKSRC_MMIO
>>  select GENERIC_IRQ_CHIP
>>  select GPIOLIB
>> +    select IRQ_DOMAIN_HIERARCHY
>>  select PINCTRL
>>  select PM_OPP
>>  select SUN4I_TIMER
>> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
>> index 16d761475a86..d282d0a1d17d 100644
>> --- 

[PATCH 2/2] phy: Remove CONFIG_ARCH_ROCKCHIP check for subdir rockchip

2020-05-24 Thread Tiezhu Yang
If CONFIG_ARCH_ROCKCHIP is not set but COMPILE_TEST is set, the file in
the subdir rockchip can not be built due to CONFIG_ARCH_ROCKCHIP check
in drivers/phy/Makefile.

Since the related configs in drivers/phy/rockchip/Kconfig depend on
ARCH_ROCKCHIP, so remove CONFIG_ARCH_ROCKCHIP check for subdir rockchip
in drivers/phy/Makefile.

Signed-off-by: Tiezhu Yang 
---
 drivers/phy/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 310c149..e5b4f58 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_ARCH_SUNXI)  += allwinner/
 obj-$(CONFIG_ARCH_MESON)   += amlogic/
 obj-$(CONFIG_ARCH_MEDIATEK)+= mediatek/
 obj-$(CONFIG_ARCH_RENESAS) += renesas/
-obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
+obj-y  += rockchip/
 obj-$(CONFIG_ARCH_TEGRA)   += tegra/
 obj-y  += broadcom/\
   cadence/ \
-- 
2.1.0



[PATCH 1/2] phy: rockchip: Fix return value of inno_dsidphy_probe()

2020-05-24 Thread Tiezhu Yang
When call function devm_platform_ioremap_resource(), we should use IS_ERR()
to check the return value and return PTR_ERR() if failed.

Fixes: b7535a3bc0ba ("phy/rockchip: Add support for Innosilicon MIPI/LVDS/TTL 
PHY")
Signed-off-by: Tiezhu Yang 
---
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c 
b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index a7c6c94..8af8c6c 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -607,8 +607,8 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, inno);
 
inno->phy_base = devm_platform_ioremap_resource(pdev, 0);
-   if (!inno->phy_base)
-   return -ENOMEM;
+   if (IS_ERR(inno->phy_base))
+   return PTR_ERR(inno->phy_base);
 
inno->ref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(inno->ref_clk)) {
-- 
2.1.0



Re: [PATCH] ACPI/IORT: Remove the unused __get_pci_rid()

2020-05-24 Thread Zenghui Yu

On 2020/5/9 17:56, Hanjun Guo wrote:

On 2020/5/9 17:34, Zenghui Yu wrote:

Since commit bc8648d49a95 ("ACPI/IORT: Handle PCI aliases properly for
IOMMUs"), __get_pci_rid() has become actually unused and can be removed.

Signed-off-by: Zenghui Yu 


Looks good to me,

Acked-by: Hanjun Guo 


Hi Will,

Could you please take this patch [*] into v5.8 (if it's not too late)?
I've tried and it can be applied to for-next/acpi cleanly.

[*] 
https://lore.kernel.org/linux-acpi/20200509093430.1983-1-yuzeng...@huawei.com/



Thanks,
Zenghui


Re: [PATCH v3] f2fs: avoid inifinite loop to wait for flushing node pages at cp_error

2020-05-24 Thread Jaegeuk Kim
Shutdown test is somtimes hung, since it keeps trying to flush dirty node pages
in an inifinite loop. Let's drop dirty pages at umount in that case.

Signed-off-by: Jaegeuk Kim 
---
v3:
 - fix wrong unlock

v2:
 - fix typos

 fs/f2fs/node.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index e632de10aedab..e0bb0f7e0506e 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1520,8 +1520,15 @@ static int __write_node_page(struct page *page, bool 
atomic, bool *submitted,
 
trace_f2fs_writepage(page, NODE);
 
-   if (unlikely(f2fs_cp_error(sbi)))
+   if (unlikely(f2fs_cp_error(sbi))) {
+   if (is_sbi_flag_set(sbi, SBI_IS_CLOSE)) {
+   ClearPageUptodate(page);
+   dec_page_count(sbi, F2FS_DIRTY_NODES);
+   unlock_page(page);
+   return 0;
+   }
goto redirty_out;
+   }
 
if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
goto redirty_out;
-- 
2.27.0.rc0.183.gde8f92d652-goog



linux-next: manual merge of the drm tree with Linus' tree

2020-05-24 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm tree got conflicts in:

  drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
  drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c

between commit:

  31ecebee9c36 ("drm/amd/display: Defer cursor lock until after VUPDATE")

from Linus' tree and commits:

  b3a941df690f ("drm/amd/display: Power down hw blocks on boot")
  4b0e95d1838f ("drm/amd/display: Add set backlight to hw sequencer.")
  ddea4ed01058 ("drm/amd/display: remove duplicate assignment of dcn21_funcs 
members")
  3ba01817365c ("drm/amd/display: Move panel_cntl specific register from abm to 
panel_cntl.")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
index 9e8e32629e47,897a3d25685a..
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c
@@@ -72,7 -72,8 +72,9 @@@ static const struct hw_sequencer_funcs 
.set_clock = dcn10_set_clock,
.get_clock = dcn10_get_clock,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
+   .set_backlight_level = dce110_set_backlight_level,
+   .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
 +  .calc_vupdate_position = dcn10_calc_vupdate_position,
  };
  
  static const struct hwseq_private_funcs dcn10_private_funcs = {
diff --cc drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
index 8334bbd6eabb,a8bcd747d7ba..
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
@@@ -83,7 -83,8 +83,9 @@@ static const struct hw_sequencer_funcs 
.init_vm_ctx = dcn20_init_vm_ctx,
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
+   .set_backlight_level = dce110_set_backlight_level,
+   .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
 +  .calc_vupdate_position = dcn10_calc_vupdate_position,
  };
  
  static const struct hwseq_private_funcs dcn20_private_funcs = {
diff --cc drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
index 4dd634118df2,e97dfaa656e9..
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
@@@ -86,12 -86,9 +86,10 @@@ static const struct hw_sequencer_funcs 
.optimize_pwr_state = dcn21_optimize_pwr_state,
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
 +  .calc_vupdate_position = dcn10_calc_vupdate_position,
-   .set_cursor_position = dcn10_set_cursor_position,
-   .set_cursor_attribute = dcn10_set_cursor_attribute,
-   .set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
-   .optimize_pwr_state = dcn21_optimize_pwr_state,
-   .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
+   .power_down = dce110_power_down,
+   .set_backlight_level = dce110_set_backlight_level,
+   .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
  };
  
  static const struct hwseq_private_funcs dcn21_private_funcs = {


pgpS1zhuj2DyT.pgp
Description: OpenPGP digital signature


[PATCH] MIPS: Fix IRQ tracing when call handle_fpe()

2020-05-24 Thread YuanJunQing
 Register "a1" is unsaved in this function,
 when CONFIG_TRACE_IRQFLAGS is enabled,
 the TRACE_IRQS_OFF macro will call trace_hardirqs_off(),
 and this may change register "a1".
 The variment of register "a1" may send SIGFPE signal
 to task when call do_fpe(),and this may kill the task.

Signed-off-by: YuanJunQing 
---
 arch/mips/kernel/genex.S | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 8236fb291e3f..956a76429773 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -480,16 +480,18 @@ NESTED(nmi_handler, PT_SIZE, sp)
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
.setmips1
SET_HARDFLOAT
-   cfc1a1, fcr31
+   cfc1s0, fcr31
.setpop
CLI
TRACE_IRQS_OFF
+   movea1,s0
.endm
 
.macro  __build_clear_msa_fpe
-   _cfcmsa a1, MSA_CSR
+   _cfcmsa s0, MSA_CSR
CLI
TRACE_IRQS_OFF
+   movea1,s0
.endm
 
.macro  __build_clear_ade
-- 
2.17.1



[PATCH v5 8/8] spi: flags 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX' can't be coexit with 'SPI_3WIRE' mode

2020-05-24 Thread dillon . minfei
From: dillon min 

since chip spi driver need get the transfer direction by 'tx_buf' and
'rx_buf' of 'struct spi_transfer' in 'SPI_3WIRE' mode.

so, we need bypass 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX'
feature in 'SPI_3WIRE' mode

Signed-off-by: dillon min 
---
 drivers/spi/spi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c92c894..f884411 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1023,7 +1023,8 @@ static int spi_map_msg(struct spi_controller *ctlr, 
struct spi_message *msg)
void *tmp;
unsigned int max_tx, max_rx;
 
-   if (ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX)) {
+   if ((ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX))
+   && !(msg->spi->mode & SPI_3WIRE)) {
max_tx = 0;
max_rx = 0;
 
-- 
2.7.4



[PATCH v5 3/8] ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on stm32429-disco board

2020-05-24 Thread dillon . minfei
From: dillon min 

Enable the ltdc & ili9341, gyro l3gd20 on stm32429-disco board.

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f429-disco.dts | 48 +++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429-disco.dts 
b/arch/arm/boot/dts/stm32f429-disco.dts
index 30c0f67..365d16f 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -49,6 +49,8 @@
 #include "stm32f429.dtsi"
 #include "stm32f429-pinctrl.dtsi"
 #include 
+#include 
+#include 
 
 / {
model = "STMicroelectronics STM32F429i-DISCO board";
@@ -127,3 +129,49 @@
pinctrl-names = "default";
status = "okay";
 };
+
+ {
+   status = "okay";
+   pinctrl-0 = <_pins_f429_disco>;
+   pinctrl-names = "default";
+
+   port {
+   ltdc_out_rgb: endpoint {
+   remote-endpoint = <_in_rgb>;
+   };
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-0 = <_pins>;
+   pinctrl-names = "default";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   cs-gpios = < 1 GPIO_ACTIVE_LOW>, < 2 GPIO_ACTIVE_LOW>;
+
+   l3gd20: l3gd20@0 {
+   compatible = "st,l3gd20-gyro";
+   spi-max-frequency = <1000>;
+   st,drdy-int-pin = <2>;
+   interrupt-parent = <>;
+   interrupts = <1 IRQ_TYPE_EDGE_RISING>,
+   <2 IRQ_TYPE_EDGE_RISING>;
+   reg = <0>;
+   status = "okay";
+   };
+
+   display: display@1{
+   /* Connect panel-ilitek-9341 to ltdc */
+   compatible = "st,sf-tc240t-9370-t";
+   reg = <1>;
+   spi-3wire;
+   spi-max-frequency = <1000>;
+   dc-gpios = < 13 0>;
+   port {
+   panel_in_rgb: endpoint {
+   remote-endpoint = <_out_rgb>;
+   };
+   };
+   };
+};
-- 
2.7.4



[PATCH v5 1/8] ARM: dts: stm32: Add dma config for spi5

2020-05-24 Thread dillon . minfei
From: dillon min 

Enable spi5's dma configuration. for graphics data output to
ilitek ili9341 panel via mipi dbi interface

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f429.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index d777069..5820b11 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -660,6 +660,9 @@
reg = <0x40015000 0x400>;
interrupts = <85>;
clocks = < 0 STM32F4_APB2_CLOCK(SPI5)>;
+   dmas = < 3 2 0x400 0x0>,
+   < 4 2 0x400 0x0>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.7.4



[PATCH v5 0/8] Enable ili9341 and l3gd20 on stm32f429-disco

2020-05-24 Thread dillon . minfei
From: dillon min 

V5's update based on Mark Brown's suggestion, use 'SPI_MASTER_MUST_RX'
for SPI_SIMPLEX_RX mode on stm32 spi controller.

V5:
1 instead of add send dummy data out under SIMPLEX_RX mode,
   add flags 'SPI_CONTROLLER_MUST_TX' for stm32 spi driver
2 bypass 'SPI_CONTROLLER_MUST_TX' and 'SPI_CONTROLLER_MUST_RX' under
'SPI_3WIRE' mode

V4:
According to alexandre torgue's suggestion, combine ili9341 and
l3gd20's modification on stm32f429-disco board to one patchset.

Changes:

ili9341:

1 update ili9341 panel driver according to Linus's suggestion
2 drop V1's No.5 patch, sumbit new changes for clk-stm32f4
3 merge l3gd20's change to this patchset

V3:
1 merge original tiny/ili9341.c driver to panel/panel-ilitek-ili9341.c
  to support serial spi & parallel rgb interface in one driver.
2 update ilitek,ili9341.yaml dts binding documentation.
3 update stm32f429-disco dts binding

V2:
1 verify ilitek,ili9341.yaml with make O=../linux-stm32
  dt_binding_check
  DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/panel/
  ilitek,ili9341.yaml

V1:
1 add ili9341 drm panel driver
2 add ltdc, spi5 controller for stm32f429-disco
3 add ltdc, spi5 pin map for stm32f429-disco
4 add docs about ili9341
5 fix ltdc driver loading hang in clk set rate bug


L3gd20:
V3:
1 merge stm32f429-disco dtbs binding with ili9341 part

V2:
1 insert blank line at stm32f420-disco.dts line 143
2 add more description for l3gd20 in commit message

V1:
1 enable spi5 controller on stm32f429-disco (dts)
2 add spi5 pinmap for stm32f429-disco  (dts)
3 add SPI_SIMPLEX_RX, SPI_3WIRE_RX support for stm32f4


dillon min (8):
  ARM: dts: stm32: Add dma config for spi5
  ARM: dts: stm32: Add pin map for ltdc & spi5 on stm32f429-disco board
  ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on
stm32429-disco board
  dt-bindings: display: panel: Add ilitek ili9341 panel bindings
  clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate,
fix duplicated ltdc clock register to 'clk_core' case ltdc's clock  
  turn off by clk_disable_unused()
  drm/panel: Add ilitek ili9341 panel driver
  spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4
  spi: flags 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX' can't
be coexit with 'SPI_3WIRE' mode

 .../bindings/display/panel/ilitek,ili9341.yaml |   69 ++
 arch/arm/boot/dts/stm32f4-pinctrl.dtsi |   67 +
 arch/arm/boot/dts/stm32f429-disco.dts  |   48 +
 arch/arm/boot/dts/stm32f429.dtsi   |3 +
 drivers/clk/clk-stm32f4.c  |7 +-
 drivers/gpu/drm/panel/Kconfig  |   12 +
 drivers/gpu/drm/panel/Makefile |1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c   | 1301 
 drivers/spi/spi-stm32.c|   19 +-
 drivers/spi/spi.c  |3 +-
 10 files changed, 1521 insertions(+), 9 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

-- 
2.7.4



[PATCH v5 6/8] drm/panel: Add ilitek ili9341 panel driver

2020-05-24 Thread dillon . minfei
From: dillon min 

This driver combine tiny/ili9341.c mipi_dbi_interface driver
with mipi_dpi_interface driver, can support ili9341 with serial
mode or parallel rgb interface mode by register configuration.

Changes since V3:

accoding to Linus Walleij's suggestion.
1 add more comments to driver.
2 reduce magic number usage in the driver.
3 move panel configuration from common place to system configuration.
4 reuse MIPI_DCS_* as more as possible.

Signed-off-by: dillon min 
---
 drivers/gpu/drm/panel/Kconfig|   12 +
 drivers/gpu/drm/panel/Makefile   |1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1301 ++
 3 files changed, 1314 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a1723c1..c938bee 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -95,6 +95,18 @@ config DRM_PANEL_ILITEK_IL9322
  Say Y here if you want to enable support for Ilitek IL9322
  QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
 
+config DRM_PANEL_ILITEK_ILI9341
+   tristate "Ilitek ILI9341 240x320 QVGA panels"
+   depends on OF && SPI
+   depends on DRM_KMS_HELPER
+   depends on DRM_KMS_CMA_HELPER
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DBI
+   help
+ Say Y here if you want to enable support for Ilitek IL9341
+ QVGA (240x320) RGB panels. support serial & parallel rgb
+ interface.
+
 config DRM_PANEL_ILITEK_ILI9881C
tristate "Ilitek ILI9881C-based panels"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 96a883c..16947d7 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
 obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
panel-feiyang-fy07024di26a30d.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
new file mode 100644
index 000..dd6f860
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -0,0 +1,1301 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Ilitek ILI9341 TFT LCD drm_panel driver.
+ *
+ * This panel can be configured to support:
+ * - 16-bit parallel RGB interface
+ * - 18-bit parallel RGB interface
+ * - 4-line serial spi interface
+ *
+ * Copyright (C) 2020 Dillon Min 
+ * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
+#define ILI9341_FRC0xb1   /* Frame Rate Control register */
+#define ILI9341_DFC0xb6   /* Display Function Control register */
+#define ILI9341_POWER1 0xc0   /* Power Control 1 register */
+#define ILI9341_POWER2 0xc1   /* Power Control 2 register */
+#define ILI9341_VCOM1  0xc5   /* VCOM Control 1 register */
+#define ILI9341_VCOM2  0xc7   /* VCOM Control 2 register */
+#define ILI9341_POWERA 0xcb   /* Power control A register */
+#define ILI9341_POWERB 0xcf   /* Power control B register */
+#define ILI9341_PGAMMA 0xe0   /* Positive Gamma Correction register */
+#define ILI9341_NGAMMA 0xe1   /* Negative Gamma Correction register */
+#define ILI9341_DTCA   0xe8   /* Driver timing control A */
+#define ILI9341_DTCB   0xea   /* Driver timing control B */
+#define ILI9341_POWER_SEQ  0xed   /* Power on sequence register */
+#define ILI9341_3GAMMA_EN  0xf2   /* 3 Gamma enable register */
+#define ILI9341_INTERFACE  0xf6   /* Interface control register */
+#define ILI9341_PRC0xf7   /* Pump ratio control register */
+#define ILI9341_ETMOD 0xb7   /* Entry mode set */
+
+#define ILI9341_MADCTL_BGR BIT(3)
+#define ILI9341_MADCTL_MV  BIT(5)
+#define ILI9341_MADCTL_MX  BIT(6)
+#define ILI9341_MADCTL_MY  BIT(7)
+
+
+#define ILI9341_POWER_B_LEN3
+#define ILI9341_POWER_SEQ_LEN  4
+#define ILI9341_DTCA_LEN   3
+#define ILI9341_DTCB_LEN   2
+#define ILI9341_POWER_A_LEN5
+#define ILI9341_DFC_1_LEN  2
+#define ILI9341_FRC_LEN2
+#define ILI9341_VCOM_1_LEN 2
+#define ILI9341_DFC_2_LEN  

[PATCH v5 2/8] ARM: dts: stm32: Add pin map for ltdc & spi5 on stm32f429-disco board

2020-05-24 Thread dillon . minfei
From: dillon min 

This patch adds the pin configuration for ltdc and spi5 controller
on stm32f429-disco board.

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 ++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi 
b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
index 392fa14..0eb107f 100644
--- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
@@ -316,6 +316,73 @@
};
};
 
+   ltdc_pins_f429_disco: ltdc-1 {
+   pins {
+   pinmux = ,
+   /* LCD_HSYNC */
+,
+/* LCD_VSYNC */
+,
+/* LCD_CLK */
+,
+/* LCD_R2 */
+,
+/* LCD_R3 */
+,
+/* LCD_R4 */
+,
+/* LCD_R5 */
+,
+/* LCD_R6*/
+,
+/* LCD_R7 */
+,
+/* LCD_G2 */
+,
+/* LCD_G3 */
+,
+/* LCD_G4 */
+,
+/* LCD_B2 */
+,
+/* LCD_B3*/
+,
+/* LCD_G5 */
+,
+/* LCD_G6 */
+,
+/* LCD_G7 */
+,
+/* LCD_B4 */
+,
+/* LCD_B5 */
+,
+/* LCD_B6 */
+,
+/* LCD_B7 */
+;
+/* LCD_DE */
+   slew-rate = <2>;
+   };
+   };
+
+   spi5_pins: spi5-0 {
+   pins1 {
+   pinmux = ,
+   /* SPI5_CLK */
+;
+   /* SPI5_MOSI */
+   bias-disable;
+   drive-push-pull;
+   slew-rate = <0>;
+   };
+   pins2 {
+   pinmux = ;
+   /* SPI5_MISO */
+   bias-disable;
+   };
+   };
+
dcmi_pins: dcmi-0 {
pins {
pinmux = , 
/* DCMI_HSYNC */
-- 
2.7.4



[PATCH v5 7/8] spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4

2020-05-24 Thread dillon . minfei
From: dillon min 

in l3gd20 driver startup, there is a setup failed error return from
stm32 spi driver

 "
 [2.687630] st-gyro-spi spi0.0: supply vdd not found, using dummy
 regulator
 [2.696869] st-gyro-spi spi0.0: supply vddio not found, using dummy
 regulator
 [2.706707] spi_stm32 40015000.spi: SPI transfer setup failed
 [2.713741] st-gyro-spi spi0.0: SPI transfer failed: -22
 [2.721096] spi_master spi0: failed to transfer one message from queue
 [2.729268] iio iio:device0: failed to read Who-Am-I register.
 [2.737504] st-gyro-spi: probe of spi0.0 failed with error -22
 "

after debug into spi-stm32 driver, st-gyro-spi split two steps to read
l3gd20 id

first: send command to l3gd20 with read id command in tx_buf, rx_buf
is null.
second: read id with tx_buf is null, rx_buf not null.

so, for second step, stm32 driver recongise this process as 'SPI_SIMPLE_RX'
from stm32_spi_communication_type(), but there is no related process for this
type in stm32f4_spi_set_mode(), then we get error from
stm32_spi_transfer_one_setup().

we can use two method to fix this bug.
1, use stm32 spi's "In unidirectional receive-only mode (BIDIMODE=0 and
RXONLY=1)". but as our code running in sdram, the read latency is too large
to get so many receive overrun error in interrupts handler.

2, use stm32 spi's "In full-duplex (BIDIMODE=0 and RXONLY=0)", as tx_buf is
null, so add flag 'SPI_MASTER_MUST_TX' to spi master.

Change since V4:
1 remove dummy data sent out by stm32 spi driver
2 add flag 'SPI_MASTER_MUST_TX' to spi master

Signed-off-by: dillon min 
---

Hi Mark,

This changes add 'SPI_MASTER_MUST_TX' for stm32 spi controller

thanks.


 drivers/spi/spi-stm32.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index 44ac6eb3..4c643df 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -811,7 +811,9 @@ static irqreturn_t stm32f4_spi_irq_event(int irq, void 
*dev_id)
mask |= STM32F4_SPI_SR_TXE;
}
 
-   if (!spi->cur_usedma && spi->cur_comm == SPI_FULL_DUPLEX) {
+   if (!spi->cur_usedma && (spi->cur_comm == SPI_FULL_DUPLEX ||
+   spi->cur_comm == SPI_SIMPLEX_RX ||
+   spi->cur_comm == SPI_3WIRE_RX)) {
/* TXE flag is set and is handled when RXNE flag occurs */
sr &= ~STM32F4_SPI_SR_TXE;
mask |= STM32F4_SPI_SR_RXNE | STM32F4_SPI_SR_OVR;
@@ -850,7 +852,7 @@ static irqreturn_t stm32f4_spi_irq_event(int irq, void 
*dev_id)
stm32f4_spi_read_rx(spi);
if (spi->rx_len == 0)
end = true;
-   else /* Load data for discontinuous mode */
+   else if (spi->tx_buf)/* Load data for discontinuous mode */
stm32f4_spi_write_tx(spi);
}
 
@@ -1151,7 +1153,9 @@ static int stm32f4_spi_transfer_one_irq(struct stm32_spi 
*spi)
/* Enable the interrupts relative to the current communication mode */
if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) {
cr2 |= STM32F4_SPI_CR2_TXEIE;
-   } else if (spi->cur_comm == SPI_FULL_DUPLEX) {
+   } else if (spi->cur_comm == SPI_FULL_DUPLEX ||
+   spi->cur_comm == SPI_SIMPLEX_RX ||
+   spi->cur_comm == SPI_3WIRE_RX) {
/* In transmit-only mode, the OVR flag is set in the SR register
 * since the received data are never read. Therefore set OVR
 * interrupt only when rx buffer is available.
@@ -1462,10 +1466,16 @@ static int stm32f4_spi_set_mode(struct stm32_spi *spi, 
unsigned int comm_type)
stm32_spi_set_bits(spi, STM32F4_SPI_CR1,
STM32F4_SPI_CR1_BIDIMODE |
STM32F4_SPI_CR1_BIDIOE);
-   } else if (comm_type == SPI_FULL_DUPLEX) {
+   } else if (comm_type == SPI_FULL_DUPLEX ||
+   comm_type == SPI_SIMPLEX_RX) {
stm32_spi_clr_bits(spi, STM32F4_SPI_CR1,
STM32F4_SPI_CR1_BIDIMODE |
STM32F4_SPI_CR1_BIDIOE);
+   } else if (comm_type == SPI_3WIRE_RX) {
+   stm32_spi_set_bits(spi, STM32F4_SPI_CR1,
+   STM32F4_SPI_CR1_BIDIMODE);
+   stm32_spi_clr_bits(spi, STM32F4_SPI_CR1,
+   STM32F4_SPI_CR1_BIDIOE);
} else {
return -EINVAL;
}
@@ -1906,6 +1916,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
master->prepare_message = stm32_spi_prepare_msg;
master->transfer_one = stm32_spi_transfer_one;
master->unprepare_message = stm32_spi_unprepare_msg;
+   master->flags 

[PATCH v5 4/8] dt-bindings: display: panel: Add ilitek ili9341 panel bindings

2020-05-24 Thread dillon . minfei
From: dillon min 

Add documentation for "ilitek,ili9341" panel.

Signed-off-by: dillon min 
---
 .../bindings/display/panel/ilitek,ili9341.yaml | 69 ++
 1 file changed, 69 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml 
b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
new file mode 100644
index 000..2172f88
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/ilitek,ili9341.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ilitek-9341 Display Panel
+
+maintainers:
+  - Dillon Min 
+
+description: |
+  Ilitek ILI9341 TFT panel driver with SPI control bus
+  This is a driver for 320x240 TFT panels, accepting a rgb input
+  streams with 16 bits or 18 bits.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+  # ili9341 240*320 Color on stm32f429-disco board
+- st,sf-tc240t-9370-t
+  - const: ilitek,ili9341
+
+  reg: true
+
+  dc-gpios:
+maxItems: 1
+description: Display data/command selection (D/CX)
+
+  spi-3wire: true
+
+  spi-max-frequency:
+const: 1000
+
+  port: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - dc-gpios
+  - port
+
+examples:
+  - |+
+spi {
+#address-cells = <1>;
+#size-cells = <0>;
+panel: display@0 {
+ compatible = "st,sf-tc240t-9370-t",
+  "ilitek,ili9341";
+ reg = <0>;
+ spi-3wire;
+ spi-max-frequency = <1000>;
+ dc-gpios = < 13 0>;
+ port {
+ panel_in: endpoint {
+   remote-endpoint = <_out>;
+  };
+ };
+ };
+};
+...
+
-- 
2.7.4



[PATCH v5 5/8] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate, fix duplicated ltdc clock register to 'clk_core' case ltdc's clock turn off by clk_disable_unused()

2020-05-24 Thread dillon . minfei
From: dillon min 

ltdc set clock rate crashed
   'post_div_data[]''s pll_num is PLL_I2S, PLL_SAI (number is 1,2). but,
as pll_num is offset of 'clks[]' input to clk_register_pll_div(), which
is FCLK, CLK_LSI, defined in 'include/dt-bindings/clock/stm32fx-clock.h'
so, this is a null object at the register time.
then, in ltdc's clock is_enabled(), enable(), will call to_clk_gate().
will return a null object, cause kernel crashed.
need change pll_num to PLL_VCO_I2S, PLL_VCO_SAI for 'post_div_data[]'

 duplicated ltdc clock
   'stm32f429_gates[]' has a member 'ltdc' register to 'clk_core', but no
upper driver use it, ltdc driver use the lcd-tft defined in
   'stm32f429_aux_clk[]'. after system startup, as stm32f429_gates[]'s ltdc
enable_count is zero, so turn off by clk_disable_unused()

Changes since V3:
1 drop last wrong changes about 'CLK_IGNORE_UNUSED' patch
2 fix PLL_SAI mismatch with PLL_VCO_SAI

Signed-off-by: dillon min 
---
 drivers/clk/clk-stm32f4.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 18117ce..fa62e99 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] 
__initconst = {
{ STM32F4_RCC_APB2ENR, 20,  "spi5", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 21,  "spi6", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 22,  "sai1", "apb2_div" },
-   { STM32F4_RCC_APB2ENR, 26,  "ltdc", "apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
@@ -557,13 +556,13 @@ static const struct clk_div_table post_divr_table[] = {
 
 #define MAX_POST_DIV 3
 static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
-   { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
+   { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
 
-   { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
+   { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
 
-   { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
+   { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
 };
 
-- 
2.7.4



Re: [PATCH 1/2] crypto: virtio: fix src/dst scatterlist calculation

2020-05-24 Thread Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
Hi Jason,

On 2020/5/25 11:12, Jason Wang wrote:
> 
> On 2020/5/25 上午8:56, Longpeng(Mike) wrote:
>> The system will crash when we insmod crypto/tcrypt.ko whit mode=38.
>>
>> Usually the next entry of one sg will be @sg@ + 1, but if this sg element
>> is part of a chained scatterlist, it could jump to the start of a new
>> scatterlist array. Let's fix it by sg_next() on calculation of src/dst
>> scatterlist.
>>
>> BTW I add a check for sg_nents_for_len() its return value since
>> sg_nents_for_len() function could fail.
>>
>> Cc: Gonglei 
>> Cc: Herbert Xu 
>> Cc: "Michael S. Tsirkin" 
>> Cc: Jason Wang 
>> Cc: "David S. Miller" 
>> Cc: virtualizat...@lists.linux-foundation.org
>> Cc: linux-kernel@vger.kernel.org
>>
>> Reported-by: LABBE Corentin 
>> Signed-off-by: Gonglei 
>> Signed-off-by: Longpeng(Mike) 
>> ---
>>   drivers/crypto/virtio/virtio_crypto_algs.c | 14 ++
>>   1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c
>> b/drivers/crypto/virtio/virtio_crypto_algs.c
>> index 372babb44112..2fa1129f96d6 100644
>> --- a/drivers/crypto/virtio/virtio_crypto_algs.c
>> +++ b/drivers/crypto/virtio/virtio_crypto_algs.c
>> @@ -359,8 +359,14 @@ __virtio_crypto_skcipher_do_req(struct
>> virtio_crypto_sym_request *vc_sym_req,
>>   unsigned int num_out = 0, num_in = 0;
>>   int sg_total;
>>   uint8_t *iv;
>> +    struct scatterlist *sg;
>>     src_nents = sg_nents_for_len(req->src, req->cryptlen);
>> +    if (src_nents < 0) {
>> +    pr_err("Invalid number of src SG.\n");
>> +    return src_nents;
>> +    }
>> +
>>   dst_nents = sg_nents(req->dst);
>>     pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: 
>> %d)\n",
>> @@ -446,12 +452,12 @@ __virtio_crypto_skcipher_do_req(struct
>> virtio_crypto_sym_request *vc_sym_req,
>>   vc_sym_req->iv = iv;
>>     /* Source data */
>> -    for (i = 0; i < src_nents; i++)
>> -    sgs[num_out++] = >src[i];
>> +    for (sg = req->src, i = 0; sg && i < src_nents; sg = sg_next(sg), i++)
> 
> 
> Any reason sg is checked here?
> 
> I believe it should be checked in sg_nents_for_len().
> 
Do you means:
for (sg = req->src, i = 0; i < src_nents; sg = sg_next(sg), i++) ?

> 
>> +    sgs[num_out++] = sg;
>>     /* Destination data */
>> -    for (i = 0; i < dst_nents; i++)
>> -    sgs[num_out + num_in++] = >dst[i];
>> +    for (sg = req->dst, i = 0; sg && i < dst_nents; sg = sg_next(sg), i++)
>> +    sgs[num_out + num_in++] = sg;
> 
> 
> I believe sg should be checked in sg_nents().
>
How about
for (sg = req->dst; sg; sg = sg_next(sg)) ?

> Thanks
> 
> 
>>     /* Status */
>>   sg_init_one(_sg, _req->status, sizeof(vc_req->status));
> 
> .
> 

-- 
---
Regards,
Longpeng(Mike)


[PATCH v5 4/8] dt-bindings: display: panel: Add ilitek ili9341 panel bindings

2020-05-24 Thread dillon . minfei
From: dillon min 

Add documentation for "ilitek,ili9341" panel.

Signed-off-by: dillon min 
---
 .../bindings/display/panel/ilitek,ili9341.yaml | 69 ++
 1 file changed, 69 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml 
b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
new file mode 100644
index 000..2172f88
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/ilitek,ili9341.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ilitek-9341 Display Panel
+
+maintainers:
+  - Dillon Min 
+
+description: |
+  Ilitek ILI9341 TFT panel driver with SPI control bus
+  This is a driver for 320x240 TFT panels, accepting a rgb input
+  streams with 16 bits or 18 bits.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+  # ili9341 240*320 Color on stm32f429-disco board
+- st,sf-tc240t-9370-t
+  - const: ilitek,ili9341
+
+  reg: true
+
+  dc-gpios:
+maxItems: 1
+description: Display data/command selection (D/CX)
+
+  spi-3wire: true
+
+  spi-max-frequency:
+const: 1000
+
+  port: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - dc-gpios
+  - port
+
+examples:
+  - |+
+spi {
+#address-cells = <1>;
+#size-cells = <0>;
+panel: display@0 {
+ compatible = "st,sf-tc240t-9370-t",
+  "ilitek,ili9341";
+ reg = <0>;
+ spi-3wire;
+ spi-max-frequency = <1000>;
+ dc-gpios = < 13 0>;
+ port {
+ panel_in: endpoint {
+   remote-endpoint = <_out>;
+  };
+ };
+ };
+};
+...
+
-- 
2.7.4



[PATCH v5 8/8] spi: flags 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX' can't be coexit with 'SPI_3WIRE' mode

2020-05-24 Thread dillon . minfei
From: dillon min 

since chip spi driver need get the transfer direction by 'tx_buf' and
'rx_buf' of 'struct spi_transfer' in 'SPI_3WIRE' mode.

so, we need bypass 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX'
feature in 'SPI_3WIRE' mode

Signed-off-by: dillon min 
---
 drivers/spi/spi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c92c894..f884411 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1023,7 +1023,8 @@ static int spi_map_msg(struct spi_controller *ctlr, 
struct spi_message *msg)
void *tmp;
unsigned int max_tx, max_rx;
 
-   if (ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX)) {
+   if ((ctlr->flags & (SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX))
+   && !(msg->spi->mode & SPI_3WIRE)) {
max_tx = 0;
max_rx = 0;
 
-- 
2.7.4



[PATCH v5 7/8] spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4

2020-05-24 Thread dillon . minfei
From: dillon min 

in l3gd20 driver startup, there is a setup failed error return from
stm32 spi driver

 "
 [2.687630] st-gyro-spi spi0.0: supply vdd not found, using dummy
 regulator
 [2.696869] st-gyro-spi spi0.0: supply vddio not found, using dummy
 regulator
 [2.706707] spi_stm32 40015000.spi: SPI transfer setup failed
 [2.713741] st-gyro-spi spi0.0: SPI transfer failed: -22
 [2.721096] spi_master spi0: failed to transfer one message from queue
 [2.729268] iio iio:device0: failed to read Who-Am-I register.
 [2.737504] st-gyro-spi: probe of spi0.0 failed with error -22
 "

after debug into spi-stm32 driver, st-gyro-spi split two steps to read
l3gd20 id

first: send command to l3gd20 with read id command in tx_buf, rx_buf
is null.
second: read id with tx_buf is null, rx_buf not null.

so, for second step, stm32 driver recongise this process as 'SPI_SIMPLE_RX'
from stm32_spi_communication_type(), but there is no related process for this
type in stm32f4_spi_set_mode(), then we get error from
stm32_spi_transfer_one_setup().

we can use two method to fix this bug.
1, use stm32 spi's "In unidirectional receive-only mode (BIDIMODE=0 and
RXONLY=1)". but as our code running in sdram, the read latency is too large
to get so many receive overrun error in interrupts handler.

2, use stm32 spi's "In full-duplex (BIDIMODE=0 and RXONLY=0)", as tx_buf is
null, so add flag 'SPI_MASTER_MUST_TX' to spi master.

Change since V4:
1 remove dummy data sent out by stm32 spi driver
2 add flag 'SPI_MASTER_MUST_TX' to spi master

Signed-off-by: dillon min 
---

Hi Mark,

This changes add 'SPI_MASTER_MUST_TX' for stm32 spi controller

thanks.


 drivers/spi/spi-stm32.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index 44ac6eb3..4c643df 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -811,7 +811,9 @@ static irqreturn_t stm32f4_spi_irq_event(int irq, void 
*dev_id)
mask |= STM32F4_SPI_SR_TXE;
}
 
-   if (!spi->cur_usedma && spi->cur_comm == SPI_FULL_DUPLEX) {
+   if (!spi->cur_usedma && (spi->cur_comm == SPI_FULL_DUPLEX ||
+   spi->cur_comm == SPI_SIMPLEX_RX ||
+   spi->cur_comm == SPI_3WIRE_RX)) {
/* TXE flag is set and is handled when RXNE flag occurs */
sr &= ~STM32F4_SPI_SR_TXE;
mask |= STM32F4_SPI_SR_RXNE | STM32F4_SPI_SR_OVR;
@@ -850,7 +852,7 @@ static irqreturn_t stm32f4_spi_irq_event(int irq, void 
*dev_id)
stm32f4_spi_read_rx(spi);
if (spi->rx_len == 0)
end = true;
-   else /* Load data for discontinuous mode */
+   else if (spi->tx_buf)/* Load data for discontinuous mode */
stm32f4_spi_write_tx(spi);
}
 
@@ -1151,7 +1153,9 @@ static int stm32f4_spi_transfer_one_irq(struct stm32_spi 
*spi)
/* Enable the interrupts relative to the current communication mode */
if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) {
cr2 |= STM32F4_SPI_CR2_TXEIE;
-   } else if (spi->cur_comm == SPI_FULL_DUPLEX) {
+   } else if (spi->cur_comm == SPI_FULL_DUPLEX ||
+   spi->cur_comm == SPI_SIMPLEX_RX ||
+   spi->cur_comm == SPI_3WIRE_RX) {
/* In transmit-only mode, the OVR flag is set in the SR register
 * since the received data are never read. Therefore set OVR
 * interrupt only when rx buffer is available.
@@ -1462,10 +1466,16 @@ static int stm32f4_spi_set_mode(struct stm32_spi *spi, 
unsigned int comm_type)
stm32_spi_set_bits(spi, STM32F4_SPI_CR1,
STM32F4_SPI_CR1_BIDIMODE |
STM32F4_SPI_CR1_BIDIOE);
-   } else if (comm_type == SPI_FULL_DUPLEX) {
+   } else if (comm_type == SPI_FULL_DUPLEX ||
+   comm_type == SPI_SIMPLEX_RX) {
stm32_spi_clr_bits(spi, STM32F4_SPI_CR1,
STM32F4_SPI_CR1_BIDIMODE |
STM32F4_SPI_CR1_BIDIOE);
+   } else if (comm_type == SPI_3WIRE_RX) {
+   stm32_spi_set_bits(spi, STM32F4_SPI_CR1,
+   STM32F4_SPI_CR1_BIDIMODE);
+   stm32_spi_clr_bits(spi, STM32F4_SPI_CR1,
+   STM32F4_SPI_CR1_BIDIOE);
} else {
return -EINVAL;
}
@@ -1906,6 +1916,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
master->prepare_message = stm32_spi_prepare_msg;
master->transfer_one = stm32_spi_transfer_one;
master->unprepare_message = stm32_spi_unprepare_msg;
+   master->flags 

[PATCH v5 6/8] drm/panel: Add ilitek ili9341 panel driver

2020-05-24 Thread dillon . minfei
From: dillon min 

This driver combine tiny/ili9341.c mipi_dbi_interface driver
with mipi_dpi_interface driver, can support ili9341 with serial
mode or parallel rgb interface mode by register configuration.

Changes since V3:

accoding to Linus Walleij's suggestion.
1 add more comments to driver.
2 reduce magic number usage in the driver.
3 move panel configuration from common place to system configuration.
4 reuse MIPI_DCS_* as more as possible.

Signed-off-by: dillon min 
---
 drivers/gpu/drm/panel/Kconfig|   12 +
 drivers/gpu/drm/panel/Makefile   |1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1301 ++
 3 files changed, 1314 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a1723c1..c938bee 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -95,6 +95,18 @@ config DRM_PANEL_ILITEK_IL9322
  Say Y here if you want to enable support for Ilitek IL9322
  QVGA (320x240) RGB, YUV and ITU-T BT.656 panels.
 
+config DRM_PANEL_ILITEK_ILI9341
+   tristate "Ilitek ILI9341 240x320 QVGA panels"
+   depends on OF && SPI
+   depends on DRM_KMS_HELPER
+   depends on DRM_KMS_CMA_HELPER
+   depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_MIPI_DBI
+   help
+ Say Y here if you want to enable support for Ilitek IL9341
+ QVGA (240x320) RGB panels. support serial & parallel rgb
+ interface.
+
 config DRM_PANEL_ILITEK_ILI9881C
tristate "Ilitek ILI9881C-based panels"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 96a883c..16947d7 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
 obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
panel-feiyang-fy07024di26a30d.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
 obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
new file mode 100644
index 000..dd6f860
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -0,0 +1,1301 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Ilitek ILI9341 TFT LCD drm_panel driver.
+ *
+ * This panel can be configured to support:
+ * - 16-bit parallel RGB interface
+ * - 18-bit parallel RGB interface
+ * - 4-line serial spi interface
+ *
+ * Copyright (C) 2020 Dillon Min 
+ * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
+#define ILI9341_FRC0xb1   /* Frame Rate Control register */
+#define ILI9341_DFC0xb6   /* Display Function Control register */
+#define ILI9341_POWER1 0xc0   /* Power Control 1 register */
+#define ILI9341_POWER2 0xc1   /* Power Control 2 register */
+#define ILI9341_VCOM1  0xc5   /* VCOM Control 1 register */
+#define ILI9341_VCOM2  0xc7   /* VCOM Control 2 register */
+#define ILI9341_POWERA 0xcb   /* Power control A register */
+#define ILI9341_POWERB 0xcf   /* Power control B register */
+#define ILI9341_PGAMMA 0xe0   /* Positive Gamma Correction register */
+#define ILI9341_NGAMMA 0xe1   /* Negative Gamma Correction register */
+#define ILI9341_DTCA   0xe8   /* Driver timing control A */
+#define ILI9341_DTCB   0xea   /* Driver timing control B */
+#define ILI9341_POWER_SEQ  0xed   /* Power on sequence register */
+#define ILI9341_3GAMMA_EN  0xf2   /* 3 Gamma enable register */
+#define ILI9341_INTERFACE  0xf6   /* Interface control register */
+#define ILI9341_PRC0xf7   /* Pump ratio control register */
+#define ILI9341_ETMOD 0xb7   /* Entry mode set */
+
+#define ILI9341_MADCTL_BGR BIT(3)
+#define ILI9341_MADCTL_MV  BIT(5)
+#define ILI9341_MADCTL_MX  BIT(6)
+#define ILI9341_MADCTL_MY  BIT(7)
+
+
+#define ILI9341_POWER_B_LEN3
+#define ILI9341_POWER_SEQ_LEN  4
+#define ILI9341_DTCA_LEN   3
+#define ILI9341_DTCB_LEN   2
+#define ILI9341_POWER_A_LEN5
+#define ILI9341_DFC_1_LEN  2
+#define ILI9341_FRC_LEN2
+#define ILI9341_VCOM_1_LEN 2
+#define ILI9341_DFC_2_LEN  

[PATCH v5 0/8] Enable ili9341 and l3gd20 on stm32f429-disco

2020-05-24 Thread dillon . minfei
From: dillon min 

V5's update based on Mark Brown's suggestion, use 'SPI_MASTER_MUST_RX'
for SPI_SIMPLEX_RX mode on stm32 spi controller.

V5:
1 instead of add send dummy data out under SIMPLEX_RX mode,
   add flags 'SPI_CONTROLLER_MUST_TX' for stm32 spi driver
2 bypass 'SPI_CONTROLLER_MUST_TX' and 'SPI_CONTROLLER_MUST_RX' under
'SPI_3WIRE' mode

V4:
According to alexandre torgue's suggestion, combine ili9341 and
l3gd20's modification on stm32f429-disco board to one patchset.

Changes:

ili9341:

1 update ili9341 panel driver according to Linus's suggestion
2 drop V1's No.5 patch, sumbit new changes for clk-stm32f4
3 merge l3gd20's change to this patchset

V3:
1 merge original tiny/ili9341.c driver to panel/panel-ilitek-ili9341.c
  to support serial spi & parallel rgb interface in one driver.
2 update ilitek,ili9341.yaml dts binding documentation.
3 update stm32f429-disco dts binding

V2:
1 verify ilitek,ili9341.yaml with make O=../linux-stm32
  dt_binding_check
  DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/panel/
  ilitek,ili9341.yaml

V1:
1 add ili9341 drm panel driver
2 add ltdc, spi5 controller for stm32f429-disco
3 add ltdc, spi5 pin map for stm32f429-disco
4 add docs about ili9341
5 fix ltdc driver loading hang in clk set rate bug


L3gd20:
V3:
1 merge stm32f429-disco dtbs binding with ili9341 part

V2:
1 insert blank line at stm32f420-disco.dts line 143
2 add more description for l3gd20 in commit message

V1:
1 enable spi5 controller on stm32f429-disco (dts)
2 add spi5 pinmap for stm32f429-disco  (dts)
3 add SPI_SIMPLEX_RX, SPI_3WIRE_RX support for stm32f4


dillon min (8):
  ARM: dts: stm32: Add dma config for spi5
  ARM: dts: stm32: Add pin map for ltdc & spi5 on stm32f429-disco board
  ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on
stm32429-disco board
  dt-bindings: display: panel: Add ilitek ili9341 panel bindings
  clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate,
fix duplicated ltdc clock register to 'clk_core' case ltdc's clock  
  turn off by clk_disable_unused()
  drm/panel: Add ilitek ili9341 panel driver
  spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4
  spi: flags 'SPI_CONTROLLER_MUST_RX' and 'SPI_CONTROLLER_MUST_TX' can't
be coexit with 'SPI_3WIRE' mode

 .../bindings/display/panel/ilitek,ili9341.yaml |   69 ++
 arch/arm/boot/dts/stm32f4-pinctrl.dtsi |   67 +
 arch/arm/boot/dts/stm32f429-disco.dts  |   48 +
 arch/arm/boot/dts/stm32f429.dtsi   |3 +
 drivers/clk/clk-stm32f4.c  |7 +-
 drivers/gpu/drm/panel/Kconfig  |   12 +
 drivers/gpu/drm/panel/Makefile |1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c   | 1301 
 drivers/spi/spi-stm32.c|   19 +-
 drivers/spi/spi.c  |3 +-
 10 files changed, 1521 insertions(+), 9 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c

-- 
2.7.4



[PATCH v5 5/8] clk: stm32: Fix stm32f429's ltdc driver hang in set clock rate, fix duplicated ltdc clock register to 'clk_core' case ltdc's clock turn off by clk_disable_unused()

2020-05-24 Thread dillon . minfei
From: dillon min 

ltdc set clock rate crashed
   'post_div_data[]''s pll_num is PLL_I2S, PLL_SAI (number is 1,2). but,
as pll_num is offset of 'clks[]' input to clk_register_pll_div(), which
is FCLK, CLK_LSI, defined in 'include/dt-bindings/clock/stm32fx-clock.h'
so, this is a null object at the register time.
then, in ltdc's clock is_enabled(), enable(), will call to_clk_gate().
will return a null object, cause kernel crashed.
need change pll_num to PLL_VCO_I2S, PLL_VCO_SAI for 'post_div_data[]'

 duplicated ltdc clock
   'stm32f429_gates[]' has a member 'ltdc' register to 'clk_core', but no
upper driver use it, ltdc driver use the lcd-tft defined in
   'stm32f429_aux_clk[]'. after system startup, as stm32f429_gates[]'s ltdc
enable_count is zero, so turn off by clk_disable_unused()

Changes since V3:
1 drop last wrong changes about 'CLK_IGNORE_UNUSED' patch
2 fix PLL_SAI mismatch with PLL_VCO_SAI

Signed-off-by: dillon min 
---
 drivers/clk/clk-stm32f4.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 18117ce..fa62e99 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] 
__initconst = {
{ STM32F4_RCC_APB2ENR, 20,  "spi5", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 21,  "spi6", "apb2_div" },
{ STM32F4_RCC_APB2ENR, 22,  "sai1", "apb2_div" },
-   { STM32F4_RCC_APB2ENR, 26,  "ltdc", "apb2_div" },
 };
 
 static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
@@ -557,13 +556,13 @@ static const struct clk_div_table post_divr_table[] = {
 
 #define MAX_POST_DIV 3
 static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
-   { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
+   { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
 
-   { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
+   { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
 
-   { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
+   { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
 };
 
-- 
2.7.4



[PATCH v5 1/8] ARM: dts: stm32: Add dma config for spi5

2020-05-24 Thread dillon . minfei
From: dillon min 

Enable spi5's dma configuration. for graphics data output to
ilitek ili9341 panel via mipi dbi interface

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f429.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index d777069..5820b11 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -660,6 +660,9 @@
reg = <0x40015000 0x400>;
interrupts = <85>;
clocks = < 0 STM32F4_APB2_CLOCK(SPI5)>;
+   dmas = < 3 2 0x400 0x0>,
+   < 4 2 0x400 0x0>;
+   dma-names = "rx", "tx";
status = "disabled";
};
 
-- 
2.7.4



[PATCH v5 2/8] ARM: dts: stm32: Add pin map for ltdc & spi5 on stm32f429-disco board

2020-05-24 Thread dillon . minfei
From: dillon min 

This patch adds the pin configuration for ltdc and spi5 controller
on stm32f429-disco board.

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 ++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi 
b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
index 392fa14..0eb107f 100644
--- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi
@@ -316,6 +316,73 @@
};
};
 
+   ltdc_pins_f429_disco: ltdc-1 {
+   pins {
+   pinmux = ,
+   /* LCD_HSYNC */
+,
+/* LCD_VSYNC */
+,
+/* LCD_CLK */
+,
+/* LCD_R2 */
+,
+/* LCD_R3 */
+,
+/* LCD_R4 */
+,
+/* LCD_R5 */
+,
+/* LCD_R6*/
+,
+/* LCD_R7 */
+,
+/* LCD_G2 */
+,
+/* LCD_G3 */
+,
+/* LCD_G4 */
+,
+/* LCD_B2 */
+,
+/* LCD_B3*/
+,
+/* LCD_G5 */
+,
+/* LCD_G6 */
+,
+/* LCD_G7 */
+,
+/* LCD_B4 */
+,
+/* LCD_B5 */
+,
+/* LCD_B6 */
+,
+/* LCD_B7 */
+;
+/* LCD_DE */
+   slew-rate = <2>;
+   };
+   };
+
+   spi5_pins: spi5-0 {
+   pins1 {
+   pinmux = ,
+   /* SPI5_CLK */
+;
+   /* SPI5_MOSI */
+   bias-disable;
+   drive-push-pull;
+   slew-rate = <0>;
+   };
+   pins2 {
+   pinmux = ;
+   /* SPI5_MISO */
+   bias-disable;
+   };
+   };
+
dcmi_pins: dcmi-0 {
pins {
pinmux = , 
/* DCMI_HSYNC */
-- 
2.7.4



[PATCH v5 3/8] ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on stm32429-disco board

2020-05-24 Thread dillon . minfei
From: dillon min 

Enable the ltdc & ili9341, gyro l3gd20 on stm32429-disco board.

Signed-off-by: dillon min 
---
 arch/arm/boot/dts/stm32f429-disco.dts | 48 +++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429-disco.dts 
b/arch/arm/boot/dts/stm32f429-disco.dts
index 30c0f67..365d16f 100644
--- a/arch/arm/boot/dts/stm32f429-disco.dts
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -49,6 +49,8 @@
 #include "stm32f429.dtsi"
 #include "stm32f429-pinctrl.dtsi"
 #include 
+#include 
+#include 
 
 / {
model = "STMicroelectronics STM32F429i-DISCO board";
@@ -127,3 +129,49 @@
pinctrl-names = "default";
status = "okay";
 };
+
+ {
+   status = "okay";
+   pinctrl-0 = <_pins_f429_disco>;
+   pinctrl-names = "default";
+
+   port {
+   ltdc_out_rgb: endpoint {
+   remote-endpoint = <_in_rgb>;
+   };
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-0 = <_pins>;
+   pinctrl-names = "default";
+   #address-cells = <1>;
+   #size-cells = <0>;
+   cs-gpios = < 1 GPIO_ACTIVE_LOW>, < 2 GPIO_ACTIVE_LOW>;
+
+   l3gd20: l3gd20@0 {
+   compatible = "st,l3gd20-gyro";
+   spi-max-frequency = <1000>;
+   st,drdy-int-pin = <2>;
+   interrupt-parent = <>;
+   interrupts = <1 IRQ_TYPE_EDGE_RISING>,
+   <2 IRQ_TYPE_EDGE_RISING>;
+   reg = <0>;
+   status = "okay";
+   };
+
+   display: display@1{
+   /* Connect panel-ilitek-9341 to ltdc */
+   compatible = "st,sf-tc240t-9370-t";
+   reg = <1>;
+   spi-3wire;
+   spi-max-frequency = <1000>;
+   dc-gpios = < 13 0>;
+   port {
+   panel_in_rgb: endpoint {
+   remote-endpoint = <_out_rgb>;
+   };
+   };
+   };
+};
-- 
2.7.4



Re: [RFC 04/11] net: phy: Handle c22 regs presence better

2020-05-24 Thread Jeremy Linton

Hi,

On 5/23/20 1:37 PM, Russell King - ARM Linux admin wrote:

On Fri, May 22, 2020 at 04:30:52PM -0500, Jeremy Linton wrote:

Until this point, we have been sanitizing the c22
regs presence bit out of all the MMD device lists.
This is incorrect as it causes the 0x checks
to incorrectly fail. Further, it turns out that we
want to utilize this flag to make a determination that
there is actually a phy at this location and we should
be accessing it using c22.

Signed-off-by: Jeremy Linton 
---
  drivers/net/phy/phy_device.c | 16 +---
  1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f0761fa5e40b..2d677490ecab 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -689,9 +689,6 @@ static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int 
addr, int dev_addr,
return -EIO;
*devices_in_package |= phy_reg;
  
-	/* Bit 0 doesn't represent a device, it indicates c22 regs presence */

-   *devices_in_package &= ~BIT(0);
-
return 0;
  }
  
@@ -742,6 +739,8 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,

int i;
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
u32 *devs = _ids->devices_in_package;
+   bool c22_present = false;
+   bool valid_id = false;
  
  	/* Find first non-zero Devices In package. Device zero is reserved

 * for 802.3 c45 complied PHYs, so don't probe it at first.
@@ -770,6 +769,10 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, 
u32 *phy_id,
return 0;
}
  
+	/* Bit 0 doesn't represent a device, it indicates c22 regs presence */

+   c22_present = *devs & BIT(0);
+   *devs &= ~BIT(0);
+
/* Now probe Device Identifiers for each device present. */
for (i = 1; i < num_ids; i++) {
if (!(c45_ids->devices_in_package & (1 << i)))
@@ -778,6 +781,13 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, 
u32 *phy_id,
ret = _get_phy_id(bus, addr, i, _ids->device_ids[i], true);
if (ret < 0)
return ret;
+   if (valid_phy_id(c45_ids->device_ids[i]))
+   valid_id = true;


Here you are using your "devices in package" validator to validate the
PHY ID value.  One of the things it does is mask this value with
0x1fff.  That means you lose some of the vendor OUI.  To me, this
looks completely wrong.


I think in this case I was just using it like the comment in 
get_phy_device() "if the phy_id is mostly F's, there is no device here".


My understanding is that the code is trying to avoid the 0x 
returns that seem to indicate "bus ok, phy didn't respond".


I just checked the OUI registration, and while there are a couple OUI's 
registered that have a number of FFF's in them, none of those cases 
seems to overlap sufficiently to cause this to throw them out. Plus a 
phy would also have to have model+revision set to 'F's. So while might 
be possible, if unlikely, at the moment I think the OUI registration 
keeps this from being a problem. Particularly, if i'm reading the 
mapping correctly, the OUI mapping guarantees that the field cannot be 
all '1's due to the OUI having X & M bits cleared. It sort of looks like 
the mapping is trying to lose those bits, by tossing bit 1 & 2, but the 
X & M are in the wrong octet (AFAIK, I just read it three times cause it 
didn't make any sense).





[PATCH 2/2] clk: Remove CONFIG_ARCH_HISI check for subdir hisilicon

2020-05-24 Thread Tiezhu Yang
If CONFIG_ARCH_HISI is not set but COMPILE_TEST is set, the file
in the subdir hisilicon can not be built due to CONFIG_ARCH_HISI
check in drivers/clk/Makefile.

Since the related configs in drivers/clk/hisilicon/Kconfig depend
on ARCH_HISI, so remove CONFIG_ARCH_HISI check for subdir hisilicon
in drivers/clk/Makefile.

Signed-off-by: Tiezhu Yang 
---
 drivers/clk/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f4169cc..81045ec 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -79,7 +79,7 @@ obj-y += bcm/
 obj-$(CONFIG_ARCH_BERLIN)  += berlin/
 obj-$(CONFIG_ARCH_DAVINCI) += davinci/
 obj-$(CONFIG_H8300)+= h8300/
-obj-$(CONFIG_ARCH_HISI)+= hisilicon/
+obj-y  += hisilicon/
 obj-y  += imgtec/
 obj-y  += imx/
 obj-y  += ingenic/
-- 
2.1.0



[PATCH 1/2] clk: hisilicon: Use correct return value about hisi_reset_init()

2020-05-24 Thread Tiezhu Yang
The return value about hisi_reset_init() is not correct, fix it.

Signed-off-by: Tiezhu Yang 
---
 drivers/clk/hisilicon/clk-hi3519.c  | 4 ++--
 drivers/clk/hisilicon/crg-hi3516cv300.c | 4 ++--
 drivers/clk/hisilicon/crg-hi3798cv200.c | 4 ++--
 drivers/clk/hisilicon/reset.c   | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3519.c 
b/drivers/clk/hisilicon/clk-hi3519.c
index ad0c7f3..803fa66 100644
--- a/drivers/clk/hisilicon/clk-hi3519.c
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -149,8 +149,8 @@ static int hi3519_clk_probe(struct platform_device *pdev)
return -ENOMEM;
 
crg->rstc = hisi_reset_init(pdev);
-   if (!crg->rstc)
-   return -ENOMEM;
+   if (IS_ERR(crg->rstc))
+   return PTR_ERR(crg->rstc);
 
crg->clk_data = hi3519_clk_register(pdev);
if (IS_ERR(crg->clk_data)) {
diff --git a/drivers/clk/hisilicon/crg-hi3516cv300.c 
b/drivers/clk/hisilicon/crg-hi3516cv300.c
index 5d4e61c..c2af03d 100644
--- a/drivers/clk/hisilicon/crg-hi3516cv300.c
+++ b/drivers/clk/hisilicon/crg-hi3516cv300.c
@@ -271,8 +271,8 @@ static int hi3516cv300_crg_probe(struct platform_device 
*pdev)
return -ENOENT;
 
crg->rstc = hisi_reset_init(pdev);
-   if (!crg->rstc)
-   return -ENOMEM;
+   if (IS_ERR(crg->rstc))
+   return PTR_ERR(crg->rstc);
 
crg->clk_data = crg->funcs->register_clks(pdev);
if (IS_ERR(crg->clk_data)) {
diff --git a/drivers/clk/hisilicon/crg-hi3798cv200.c 
b/drivers/clk/hisilicon/crg-hi3798cv200.c
index 08a19ba..66fd6a9 100644
--- a/drivers/clk/hisilicon/crg-hi3798cv200.c
+++ b/drivers/clk/hisilicon/crg-hi3798cv200.c
@@ -354,8 +354,8 @@ static int hi3798cv200_crg_probe(struct platform_device 
*pdev)
return -ENOENT;
 
crg->rstc = hisi_reset_init(pdev);
-   if (!crg->rstc)
-   return -ENOMEM;
+   if (IS_ERR(crg->rstc))
+   return PTR_ERR(crg->rstc);
 
crg->clk_data = crg->funcs->register_clks(pdev);
if (IS_ERR(crg->clk_data)) {
diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c
index 93cee17..f17d15f 100644
--- a/drivers/clk/hisilicon/reset.c
+++ b/drivers/clk/hisilicon/reset.c
@@ -93,11 +93,11 @@ struct hisi_reset_controller *hisi_reset_init(struct 
platform_device *pdev)
 
rstc = devm_kmalloc(>dev, sizeof(*rstc), GFP_KERNEL);
if (!rstc)
-   return NULL;
+   return ERR_PTR(-ENOMEM);
 
rstc->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rstc->membase))
-   return NULL;
+   return rstc->membase;
 
spin_lock_init(>lock);
rstc->rcdev.owner = THIS_MODULE;
-- 
2.1.0



Re: [PATCH v5 03/14] PCI: cadence: Convert all r/w accessors to perform only 32-bit accesses

2020-05-24 Thread Kishon Vijay Abraham I
Hi Rob,

On 5/22/2020 9:24 PM, Rob Herring wrote:
> On Thu, May 21, 2020 at 9:37 PM Kishon Vijay Abraham I  wrote:
>>
>> Certain platforms like TI's J721E using Cadence PCIe IP can perform only
>> 32-bit accesses for reading or writing to Cadence registers. Convert all
>> read and write accesses to 32-bit in Cadence PCIe driver in preparation
>> for adding PCIe support in TI's J721E SoC.
> 
> Looking more closely I don't think cdns_pcie_ep_assert_intx is okay
> with this and never can be given the PCI_COMMAND and PCI_STATUS
> registers are in the same word (IIRC, that's the main reason 32-bit
> config space accesses are broken). So this isn't going to work at

right, PCI_STATUS has write '1' to clear bits and there's a chance that it
could be reset while raising legacy interrupt. While this cannot be avoided for
TI's J721E, other platforms doesn't have to have this limitation.
> least for EP accesses. And maybe you need a custom .raise_irq() hook
> to minimize any problems (such as making the RMW atomic at least from
> the endpoint's perspective).

This is to make sure EP doesn't update in-consistent state when RC is updating
the PCI_STATUS register? Since this involves two different systems, how do we
make this atomic?

Thanks
Kishon


Re: [PATCH 3/8] srcu: Use local_lock() for per-CPU struct srcu_data access

2020-05-24 Thread Paul E. McKenney
On Sun, May 24, 2020 at 09:03:56PM +0200, Sebastian Andrzej Siewior wrote:
> On 2020-05-23 17:08:32 [+0200], To Paul E. McKenney wrote:
> > On 2020-05-22 10:39:53 [-0700], Paul E. McKenney wrote:
> > > It looks good to me, but I have not yet tested it.  (Happy to let you
> > > take the first crack at rcutorture in any case, scenarios SRCU-P and
> > > SRCU-N.)
> > 
> > on it.
> 
> |tools/testing/selftests/rcutorture/bin/kvm.sh --cpus 32 --duration 240 
> --configs 8*SRCU-N
> |SRCU-N --- 2127126 GPs (147.717/s) [srcu: g26566592 f0x0 ]
> |SRCU-N.2 --- 2123520 GPs (147.467/s) [srcu: g26563696 f0x0 ]
> |SRCU-N.3 --- 2122181 GPs (147.374/s) [srcu: g26549140 f0x0 ]
> |SRCU-N.4 --- 2126099 GPs (147.646/s) [srcu: g26564232 f0x0 ]
> |SRCU-N.5 --- 2127107 GPs (147.716/s) [srcu: g26590168 f0x0 ]
> |SRCU-N.6 --- 2125489 GPs (147.603/s) [srcu: g26545616 f0x0 ]
> |SRCU-N.7 --- 2128308 GPs (147.799/s) [srcu: g26591524 f0x0 ]
> |SRCU-N.8 --- 2126432 GPs (147.669/s) [srcu: g26586816 f0x0 ]
> |
> |tools/testing/selftests/rcutorture/bin/kvm.sh --cpus 32 --duration 240 
> --configs 8*SRCU-P
> |SRCU-P --- 565751 GPs (39.2883/s) [srcud: g5034676 f0x0 ]
> |SRCU-P.2 --- 569508 GPs (39.5492/s) [srcud: g5062872 f0x0 ]
> |SRCU-P.3 --- 574240 GPs (39.8778/s) [srcud: g5098488 f0x0 ]
> |SRCU-P.4 --- 564376 GPs (39.1928/s) [srcud: g5031244 f0x0 ]
> |SRCU-P.5 --- 563705 GPs (39.1462/s) [srcud: g5024720 f0x0 ]
> |SRCU-P.6 --- 565043 GPs (39.2391/s) [srcud: g5030272 f0x0 ]
> |SRCU-P.7 --- 567450 GPs (39.4062/s) [srcud: g5046392 f0x0 ]
> |SRCU-P.8 --- 566496 GPs (39.34/s) [srcud: g5039396 f0x0 ]
> 
> Results at
>https://breakpoint.cc/res.tar.xz

Looks good, thank you!

Thanx, Paul


Re: [PATCH] [v2] extcon: arizona: Fix runtime PM imbalance on error

2020-05-24 Thread Chanwoo Choi
Hi Dinghao Liu,

On 5/23/20 3:17 PM, Dinghao Liu wrote:
> When arizona_request_irq() returns an error code, a
> pairing runtime PM usage counter decrement is needed
> to keep the counter balanced. For error paths after
> this function, things are the same.
> 
> Also, remove calls to pm_runtime_disable() when
> pm_runtime_enable() has not been executed.
> 
> Signed-off-by: Dinghao Liu 
> ---
> 
> Changelog:
> 
> v2: - Add a new label "err_pm" to balance refcount.
>   Remove 3 calls to pm_runtime_disable().
>   Move pm_runtime_put() from the front of
>   input_register_device() to the back.
> ---
>  drivers/extcon/extcon-arizona.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
> index 7401733db08b..aae82db542a5 100644
> --- a/drivers/extcon/extcon-arizona.c
> +++ b/drivers/extcon/extcon-arizona.c
> @@ -1460,7 +1460,7 @@ static int arizona_extcon_probe(struct platform_device 
> *pdev)
>   if (!info->input) {
>   dev_err(arizona->dev, "Can't allocate input dev\n");
>   ret = -ENOMEM;
> - goto err_register;
> + return ret;
>   }
>  
>   info->input->name = "Headset";
> @@ -1492,7 +1492,7 @@ static int arizona_extcon_probe(struct platform_device 
> *pdev)
>   if (ret != 0) {
>   dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
>   pdata->micd_pol_gpio, ret);
> - goto err_register;
> + return ret;
>   }
>  
>   info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);
> @@ -1515,7 +1515,7 @@ static int arizona_extcon_probe(struct platform_device 
> *pdev)
>   dev_err(arizona->dev,
>   "Failed to get microphone polarity GPIO: %d\n",
>   ret);
> - goto err_register;
> + return ret;
>   }
>   }
>  
> @@ -1672,7 +1672,7 @@ static int arizona_extcon_probe(struct platform_device 
> *pdev)
>   if (ret != 0) {
>   dev_err(>dev, "Failed to get JACKDET rise IRQ: %d\n",
>   ret);
> - goto err_gpio;
> + goto err_pm;
>   }
>  
>   ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
> @@ -1721,14 +1721,14 @@ static int arizona_extcon_probe(struct 
> platform_device *pdev)
>   dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
>ret);
>  
> - pm_runtime_put(>dev);
> -
>   ret = input_register_device(info->input);
>   if (ret) {
>   dev_err(>dev, "Can't register input device: %d\n", ret);
>   goto err_hpdet;
>   }
>  
> + pm_runtime_put(>dev);
> +
>   return 0;
>  
>  err_hpdet:
> @@ -1743,10 +1743,11 @@ static int arizona_extcon_probe(struct 
> platform_device *pdev)
>   arizona_set_irq_wake(arizona, jack_irq_rise, 0);
>  err_rise:
>   arizona_free_irq(arizona, jack_irq_rise, info);
> +err_pm:
> + pm_runtime_put(>dev);
> + pm_runtime_disable(>dev);
>  err_gpio:
>   gpiod_put(info->micd_pol_gpio);
> -err_register:
> - pm_runtime_disable(>dev);
>   return ret;
>  }
>  
> 

Applied it. Thanks. 

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics


Re: [PATCH v3 2/3] extcon: max14577: Add proper dt-compatible strings

2020-05-24 Thread Chanwoo Choi
Hi Marek,

On 5/22/20 7:24 PM, Marek Szyprowski wrote:
> Add device tree compatible strings and create proper modalias structures
> to let this driver load automatically if compiled as module, because
> max14577 MFD driver creates MFD cells with such compatible strings.
> 
> Signed-off-by: Marek Szyprowski 
> ---
> v3:
> - sorted of_max14577_muic_dt_match
> v2:
> - added .of_match_table pointer
> ---
>  drivers/extcon/extcon-max14577.c | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/extcon/extcon-max14577.c 
> b/drivers/extcon/extcon-max14577.c
> index 32f663436e6e..03af678ddeba 100644
> --- a/drivers/extcon/extcon-max14577.c
> +++ b/drivers/extcon/extcon-max14577.c
> @@ -782,9 +782,19 @@ static const struct platform_device_id 
> max14577_muic_id[] = {
>  };
>  MODULE_DEVICE_TABLE(platform, max14577_muic_id);
>  
> +static const struct of_device_id of_max14577_muic_dt_match[] = {
> + { .compatible = "maxim,max14577-muic",
> +   .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, },
> + { .compatible = "maxim,max77836-muic",
> +   .data = (void *)MAXIM_DEVICE_TYPE_MAX77836, },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, of_max14577_muic_dt_match);
> +
>  static struct platform_driver max14577_muic_driver = {
>   .driver = {
>   .name   = "max14577-muic",
> + .of_match_table = of_max14577_muic_dt_match,
>   },
>   .probe  = max14577_muic_probe,
>   .remove = max14577_muic_remove,
> 

Applied it. Thanks.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics


general protection fault in sock_recvmsg

2020-05-24 Thread syzbot
Hello,

syzbot found the following crash on:

HEAD commit:caffb99b Merge git://git.kernel.org/pub/scm/linux/kernel/g..
git tree:   upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=15a7444110
kernel config:  https://syzkaller.appspot.com/x/.config?x=c33c7f7c5471fd39
dashboard link: https://syzkaller.appspot.com/bug?extid=d7cface3f90b13edf5b0
compiler:   clang version 10.0.0 (https://github.com/llvm/llvm-project/ 
c2443155a0fb245c8f17f2c1c72b6ea391e86e81)
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=141034ba10
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=119cd01610

The bug was bisected to:

commit 263e1201a2c324b60b15ecda5de9ebf1e7293e31
Author: Paolo Abeni 
Date:   Thu Apr 30 13:01:51 2020 +

mptcp: consolidate synack processing.

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=119d862610
final crash:https://syzkaller.appspot.com/x/report.txt?x=139d862610
console output: https://syzkaller.appspot.com/x/log.txt?x=159d862610

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+d7cface3f90b13edf...@syzkaller.appspotmail.com
Fixes: 263e1201a2c3 ("mptcp: consolidate synack processing.")

general protection fault, probably for non-canonical address 
0xdc04:  [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0020-0x0027]
CPU: 1 PID: 7226 Comm: syz-executor523 Not tainted 5.7.0-rc6-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
01/01/2011
RIP: 0010:sock_recvmsg_nosec net/socket.c:886 [inline]
RIP: 0010:sock_recvmsg+0x92/0x110 net/socket.c:904
Code: 5b 41 5c 41 5d 41 5e 41 5f 5d c3 44 89 6c 24 04 e8 53 18 1d fb 4d 8d 6f 
20 4c 89 e8 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 
ef e8 20 12 5b fb bd a0 00 00 00 49 03 6d
RSP: 0018:c90001077b98 EFLAGS: 00010202
RAX: 0004 RBX: c90001077dc0 RCX: dc00
RDX:  RSI:  RDI: 
RBP:  R08: 86565e59 R09: ed10115afeaa
R10: ed10115afeaa R11:  R12: 19200020efbc
R13: 0020 R14: c90001077de0 R15: 
FS:  7fc6a3abe700() GS:8880ae90() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 004d0050 CR3: 969f CR4: 001406e0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400
Call Trace:
 mptcp_recvmsg+0x18d5/0x19b0 net/mptcp/protocol.c:891
 inet_recvmsg+0xf6/0x1d0 net/ipv4/af_inet.c:838
 sock_recvmsg_nosec net/socket.c:886 [inline]
 sock_recvmsg net/socket.c:904 [inline]
 __sys_recvfrom+0x2f3/0x470 net/socket.c:2057
 __do_sys_recvfrom net/socket.c:2075 [inline]
 __se_sys_recvfrom net/socket.c:2071 [inline]
 __x64_sys_recvfrom+0xda/0xf0 net/socket.c:2071
 do_syscall_64+0xf3/0x1b0 arch/x86/entry/common.c:295
 entry_SYSCALL_64_after_hwframe+0x49/0xb3
RIP: 0033:0x448ef9
Code: e8 cc 14 03 00 48 83 c4 18 c3 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 48 
89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 
9b 0c fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:7fc6a3abdda8 EFLAGS: 0246 ORIG_RAX: 002d
RAX: ffda RBX: 006dec28 RCX: 00448ef9
RDX: 1000 RSI: 24c0 RDI: 0003
RBP: 006dec20 R08:  R09: 
R10: 4000 R11: 0246 R12: 006dec2c
R13: 7ffe4730174f R14: 7fc6a3abe9c0 R15: 006dec2c
Modules linked in:
---[ end trace 097bdf143c3a60db ]---
RIP: 0010:sock_recvmsg_nosec net/socket.c:886 [inline]
RIP: 0010:sock_recvmsg+0x92/0x110 net/socket.c:904
Code: 5b 41 5c 41 5d 41 5e 41 5f 5d c3 44 89 6c 24 04 e8 53 18 1d fb 4d 8d 6f 
20 4c 89 e8 48 c1 e8 03 48 b9 00 00 00 00 00 fc ff df <80> 3c 08 00 74 08 4c 89 
ef e8 20 12 5b fb bd a0 00 00 00 49 03 6d
RSP: 0018:c90001077b98 EFLAGS: 00010202
RAX: 0004 RBX: c90001077dc0 RCX: dc00
RDX:  RSI:  RDI: 
RBP:  R08: 86565e59 R09: ed10115afeaa
R10: ed10115afeaa R11:  R12: 19200020efbc
R13: 0020 R14: c90001077de0 R15: 
FS:  7fc6a3abe700() GS:8880ae90() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 004d0050 CR3: 969f CR4: 001406e0
DR0:  DR1:  DR2: 
DR3:  DR6: fffe0ff0 DR7: 0400


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkal...@googlegroups.com.

syzbot will keep track of this bug report. 

Re: [PATCH 1/2] crypto: virtio: fix src/dst scatterlist calculation

2020-05-24 Thread Jason Wang



On 2020/5/25 上午8:56, Longpeng(Mike) wrote:

The system will crash when we insmod crypto/tcrypt.ko whit mode=38.

Usually the next entry of one sg will be @sg@ + 1, but if this sg element
is part of a chained scatterlist, it could jump to the start of a new
scatterlist array. Let's fix it by sg_next() on calculation of src/dst
scatterlist.

BTW I add a check for sg_nents_for_len() its return value since
sg_nents_for_len() function could fail.

Cc: Gonglei 
Cc: Herbert Xu 
Cc: "Michael S. Tsirkin" 
Cc: Jason Wang 
Cc: "David S. Miller" 
Cc: virtualizat...@lists.linux-foundation.org
Cc: linux-kernel@vger.kernel.org

Reported-by: LABBE Corentin 
Signed-off-by: Gonglei 
Signed-off-by: Longpeng(Mike) 
---
  drivers/crypto/virtio/virtio_crypto_algs.c | 14 ++
  1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c 
b/drivers/crypto/virtio/virtio_crypto_algs.c
index 372babb44112..2fa1129f96d6 100644
--- a/drivers/crypto/virtio/virtio_crypto_algs.c
+++ b/drivers/crypto/virtio/virtio_crypto_algs.c
@@ -359,8 +359,14 @@ __virtio_crypto_skcipher_do_req(struct 
virtio_crypto_sym_request *vc_sym_req,
unsigned int num_out = 0, num_in = 0;
int sg_total;
uint8_t *iv;
+   struct scatterlist *sg;
  
  	src_nents = sg_nents_for_len(req->src, req->cryptlen);

+   if (src_nents < 0) {
+   pr_err("Invalid number of src SG.\n");
+   return src_nents;
+   }
+
dst_nents = sg_nents(req->dst);
  
  	pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n",

@@ -446,12 +452,12 @@ __virtio_crypto_skcipher_do_req(struct 
virtio_crypto_sym_request *vc_sym_req,
vc_sym_req->iv = iv;
  
  	/* Source data */

-   for (i = 0; i < src_nents; i++)
-   sgs[num_out++] = >src[i];
+   for (sg = req->src, i = 0; sg && i < src_nents; sg = sg_next(sg), i++)



Any reason sg is checked here?

I believe it should be checked in sg_nents_for_len().



+   sgs[num_out++] = sg;
  
  	/* Destination data */

-   for (i = 0; i < dst_nents; i++)
-   sgs[num_out + num_in++] = >dst[i];
+   for (sg = req->dst, i = 0; sg && i < dst_nents; sg = sg_next(sg), i++)
+   sgs[num_out + num_in++] = sg;



I believe sg should be checked in sg_nents().

Thanks


  
  	/* Status */

sg_init_one(_sg, _req->status, sizeof(vc_req->status));




Re: [PATCH v9 05/14] KVM: X86: Implement ring-based dirty memory tracking

2020-05-24 Thread kbuild test robot
Hi Peter,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on vhost/linux-next]
[also build test WARNING on linus/master v5.7-rc7]
[cannot apply to kvm/linux-next tip/auto-latest linux/master next-20200522]
[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]

url:
https://github.com/0day-ci/linux/commits/Peter-Xu/KVM-Dirty-ring-interface/20200524-070926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
config: s390-randconfig-s002-20200524 (attached as .config)
compiler: s390-linux-gcc (GCC) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-240-gf0fe1cd9-dirty
# save the attached .config to linux build tree
make W=1 C=1 ARCH=s390 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot 

All warnings (new ones prefixed by >>, old ones prefixed by <<):

arch/s390/kvm/../../../virt/kvm/kvm_main.c: In function 
'kvm_page_in_dirty_ring':
>> arch/s390/kvm/../../../virt/kvm/kvm_main.c:2932:16: warning: comparison of 
>> unsigned expression >= 0 is always true [-Wtype-limits]
2932 |  return (pgoff >= KVM_DIRTY_LOG_PAGE_OFFSET) &&
|^~

vim +2932 arch/s390/kvm/../../../virt/kvm/kvm_main.c

  2926  
  2927  static bool kvm_page_in_dirty_ring(struct kvm *kvm, unsigned long pgoff)
  2928  {
  2929  if (!KVM_DIRTY_LOG_PAGE_OFFSET)
  2930  return false;
  2931  
> 2932  return (pgoff >= KVM_DIRTY_LOG_PAGE_OFFSET) &&
  2933  (pgoff < KVM_DIRTY_LOG_PAGE_OFFSET +
  2934   kvm->dirty_ring_size / PAGE_SIZE);
  2935  }
  2936  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH v2] xfrm: policy: Fix xfrm policy match

2020-05-24 Thread Yuehaibing
On 2020/5/23 17:02, Xin Long wrote:
> On Fri, May 22, 2020 at 8:39 PM Yuehaibing  wrote:
>>
>> On 2020/5/22 13:49, Xin Long wrote:
>>> On Fri, May 22, 2020 at 9:45 AM Yuehaibing  wrote:

 On 2020/5/21 14:49, Xin Long wrote:
> On Tue, May 19, 2020 at 4:53 PM Steffen Klassert
>  wrote:
>>
>> On Fri, May 15, 2020 at 04:39:57PM +0800, Yuehaibing wrote:
>>>
>>> Friendly ping...
>>>
>>> Any plan for this issue?
>>
>> There was still no consensus between you and Xin on how
>> to fix this issue. Once this happens, I consider applying
>> a fix.
>>
> Sorry, Yuehaibing, I can't really accept to do: (A->mark.m & A->mark.v)
> I'm thinking to change to:
>
>  static bool xfrm_policy_mark_match(struct xfrm_policy *policy,
>struct xfrm_policy *pol)
>  {
> -   u32 mark = policy->mark.v & policy->mark.m;
> -
> -   if (policy->mark.v == pol->mark.v && policy->mark.m == 
> pol->mark.m)
> -   return true;
> -
> -   if ((mark & pol->mark.m) == pol->mark.v &&
> -   policy->priority == pol->priority)
> +   if (policy->mark.v == pol->mark.v &&
> +   (policy->mark.m == pol->mark.m ||
> +policy->priority == pol->priority))
> return true;
>
> return false;
>
> which means we consider (the same value and mask) or
> (the same value and priority) as the same one. This will
> cover both problems.

   policy A (mark.v = 0x1011, mark.m = 0x1011, priority = 1)
   policy B (mark.v = 0x1001, mark.m = 0x1001, priority = 1)
>>> I'd think these are 2 different policies.
>>>

   when fl->flowi_mark == 0x12341011, in xfrm_policy_match() do check like 
 this:

 (fl->flowi_mark & pol->mark.m) != pol->mark.v

 0x12341011 & 0x1011 == 0x1011
 0x12341011 & 0x1001 == 0x1001

  This also match different policy depends on the order of policy inserting.
>>> Yes, this may happen when a user adds 2  policies like that.
>>> But I think this's a problem that the user doesn't configure it well,
>>> 'priority' should be set.
>>> and this can not be avoided, also such as:
>>>
>>>policy A (mark.v = 0xff00, mark.m = 0x1000, priority = 1)
>>>policy B (mark.v = 0x00ff, mark.m = 0x0011, priority = 1)
>>>
>>>try with 0x12341011
>>>
>>> So just be it, let users decide.
>>
>> Ok, this make sense.
> Thanks Yuehaibing, it's good we're on the same page now.
> 
> Just realized the patch I created above won't work for the case:
> 
>   policy A (mark.v = 0x10, mark.m = 0, priority = 1)
>   policy B (mark.v = 0x1,  mark.m = 0, priority = 2)
>   policy C (mark.v = 0x10, mark.m = 0, priority = 2)
> 
> when policy C is being added, the warning still occurs.

Do you means this:

   policy A (mark.v = 0x10, mark.m = 0, priority = 1)
   policy B (mark.v = 0x10, mark.m = 1, priority = 2)
   policy C (mark.v = 0x10, mark.m = 0, priority = 2)

> 
> So I will just check value and priority:
> -   u32 mark = policy->mark.v & policy->mark.m;
> -
> -   if (policy->mark.v == pol->mark.v && policy->mark.m == pol->mark.m)
> -   return true;
> -
> -   if ((mark & pol->mark.m) == pol->mark.v &&
> +   if (policy->mark.v == pol->mark.v &&
> policy->priority == pol->priority)
> return true;
> 
> This allows two policies like this exist:
> 
>   policy A (mark.v = 0x10, mark.m = 0, priority = 1)
>   policy C (mark.v = 0x10, mark.m = 0, priority = 2)
> 
> But I don't think it's a problem.

Agreed.
>
> .
> 



[PATCH v6 3/4] mm/memory.c: Add memory read privilege on page fault handling

2020-05-24 Thread Bibo Mao
Here add pte_sw_mkyoung function to make page readable on MIPS
platform during page fault handling. This patch improves page
fault latency about 10% on my MIPS machine with lmbench
lat_pagefault case.

It is noop function on other arches, there is no negative
influence on those architectures.

Signed-off-by: Bibo Mao 
---
 arch/mips/include/asm/pgtable.h |  2 ++
 include/asm-generic/pgtable.h   | 16 
 mm/memory.c |  3 +++
 3 files changed, 21 insertions(+)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index d2004b5..0743087 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -414,6 +414,8 @@ static inline pte_t pte_mkyoung(pte_t pte)
return pte;
 }
 
+#define pte_sw_mkyoung pte_mkyoung
+
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 static inline int pte_huge(pte_t pte)  { return pte_val(pte) & _PAGE_HUGE; }
 
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index fa5c73f..b5278ec 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -244,6 +244,22 @@ static inline void ptep_set_wrprotect(struct mm_struct 
*mm, unsigned long addres
 }
 #endif
 
+/*
+ * On some architectures hardware does not set page access bit when accessing
+ * memory page, it is responsibilty of software setting this bit. It brings
+ * out extra page fault penalty to track page access bit. For optimization page
+ * access bit can be set during all page fault flow on these arches.
+ * To be differentiate with macro pte_mkyoung, this macro is used on platforms
+ * where software maintains page access bit.
+ */
+#ifndef pte_sw_mkyoung
+static inline pte_t pte_sw_mkyoung(pte_t pte)
+{
+   return pte;
+}
+#define pte_sw_mkyoung pte_sw_mkyoung
+#endif
+
 #ifndef pte_savedwrite
 #define pte_savedwrite pte_write
 #endif
diff --git a/mm/memory.c b/mm/memory.c
index 8bb31c4..c7c8960 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2704,6 +2704,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
}
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
entry = mk_pte(new_page, vma->vm_page_prot);
+   entry = pte_sw_mkyoung(entry);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
/*
 * Clear the pte entry and flush it first, before updating the
@@ -3378,6 +3379,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
__SetPageUptodate(page);
 
entry = mk_pte(page, vma->vm_page_prot);
+   entry = pte_sw_mkyoung(entry);
if (vma->vm_flags & VM_WRITE)
entry = pte_mkwrite(pte_mkdirty(entry));
 
@@ -3660,6 +3662,7 @@ vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct 
mem_cgroup *memcg,
 
flush_icache_page(vma, page);
entry = mk_pte(page, vma->vm_page_prot);
+   entry = pte_sw_mkyoung(entry);
if (write)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
/* copy-on-write page */
-- 
1.8.3.1



[PATCH v6 4/4] MIPS: mm: add page valid judgement in function pte_modify

2020-05-24 Thread Bibo Mao
If original PTE has _PAGE_ACCESSED bit set, and new pte has no
_PAGE_NO_READ bit set, we can add _PAGE_SILENT_READ bit to enable
page valid bit.

Signed-off-by: Bibo Mao 
---
 arch/mips/include/asm/pgtable.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 0743087..dfe79f4 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -529,8 +529,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #else
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-   return __pte((pte_val(pte) & _PAGE_CHG_MASK) |
-(pgprot_val(newprot) & ~_PAGE_CHG_MASK));
+   pte_val(pte) &= _PAGE_CHG_MASK;
+   pte_val(pte) |= pgprot_val(newprot) & ~_PAGE_CHG_MASK;
+   if ((pte_val(pte) & _PAGE_ACCESSED) && !(pte_val(pte) & _PAGE_NO_READ))
+   pte_val(pte) |= _PAGE_SILENT_READ;
+   return pte;
 }
 #endif
 
-- 
1.8.3.1



[PATCH v6 1/4] MIPS: Do not flush tlb page when updating PTE entry

2020-05-24 Thread Bibo Mao
It is not necessary to flush tlb page on all CPUs if suitable PTE
entry exists already during page fault handling, just updating
TLB is fine.

Here redefine flush_tlb_fix_spurious_fault as empty on MIPS system.
V6:
- Add update_mmu_tlb function as empty on all platform except mips
  system, we use this function to update local tlb for page fault
  smp-race handling
V5:
- define update_mmu_cache function specified on MIPS platform, and
  add page fault smp-race stats info
V4:
- add pte_sw_mkyoung function to implement readable privilege, and
  this function is  only in effect on MIPS system.
- add page valid bit judgement in function pte_modify
V3:
- add detailed changelog, modify typo issue in patch V2
v2:
- split flush_tlb_fix_spurious_fault and tlb update into two patches
- comments typo modification
- separate tlb update and add pte readable privilege into two patches

Signed-off-by: Bibo Mao 
---
 arch/mips/include/asm/pgtable.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 9b01d2d..0d625c2 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -478,6 +478,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
return __pgprot(prot);
 }
 
+#define flush_tlb_fix_spurious_fault(vma, address) do { } while (0)
+
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
-- 
1.8.3.1



[PATCH v6 2/4] mm/memory.c: Update local TLB if PTE entry exists

2020-05-24 Thread Bibo Mao
If two threads concurrently fault at the same page, the thread that
won the race updates the PTE and its local TLB. For now, the other
thread gives up, simply does nothing, and continues.

It could happen that this second thread triggers another fault, whereby
it only updates its local TLB while handling the fault. Instead of
triggering another fault, let's directly update the local TLB of the
second thread. Function update_mmu_tlb is used here to update local
TLB on the second thread, and it is defined as empty on other arches.

Signed-off-by: Bibo Mao 
---
 arch/mips/include/asm/pgtable.h | 23 +++
 include/asm-generic/pgtable.h   | 17 +
 mm/memory.c | 27 +++
 3 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 0d625c2..d2004b5 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -480,6 +480,26 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
 
 #define flush_tlb_fix_spurious_fault(vma, address) do { } while (0)
 
+#define __HAVE_ARCH_PTE_SAME
+static inline int pte_same(pte_t pte_a, pte_t pte_b)
+{
+   return pte_val(pte_a) == pte_val(pte_b);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
+   unsigned long address, pte_t *ptep,
+   pte_t entry, int dirty)
+{
+   if (!pte_same(*ptep, entry))
+   set_pte_at(vma->vm_mm, address, ptep, entry);
+   /*
+* update_mmu_cache will unconditionally execute, handling both
+* the case that the PTE changed and the spurious fault case.
+*/
+   return true;
+}
+
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
@@ -523,6 +543,9 @@ static inline void update_mmu_cache(struct vm_area_struct 
*vma,
__update_tlb(vma, address, pte);
 }
 
+#define__HAVE_ARCH_UPDATE_MMU_TLB
+#define update_mmu_tlb update_mmu_cache
+
 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp)
 {
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 329b8c8..fa5c73f 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -188,6 +188,23 @@ static inline pte_t ptep_get_and_clear_full(struct 
mm_struct *mm,
 }
 #endif
 
+
+/*
+ * If two threads concurrently fault at the same page, the thread that
+ * won the race updates the PTE and its local TLB/Cache. The other thread
+ * gives up, simply does nothing, and continues; on architectures where
+ * software can update TLB,  local TLB can be updated here to avoid next page
+ * fault. This function updates TLB only, do nothing with cache or others.
+ * It is the difference with function update_mmu_cache.
+ */
+#ifndef __HAVE_ARCH_UPDATE_MMU_TLB
+static inline void update_mmu_tlb(struct vm_area_struct *vma,
+   unsigned long address, pte_t *ptep)
+{
+}
+#define __HAVE_ARCH_UPDATE_MMU_TLB
+#endif
+
 /*
  * Some architectures may be able to avoid expensive synchronization
  * primitives when modifications are made to PTE's which are already
diff --git a/mm/memory.c b/mm/memory.c
index f703fe8..8bb31c4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2436,10 +2436,9 @@ static inline bool cow_user_page(struct page *dst, 
struct page *src,
if (!likely(pte_same(*vmf->pte, vmf->orig_pte))) {
/*
 * Other thread has already handled the fault
-* and we don't need to do anything. If it's
-* not the case, the fault will be triggered
-* again on the same address.
+* and update local tlb only
 */
+   update_mmu_tlb(vma, addr, vmf->pte);
ret = false;
goto pte_unlock;
}
@@ -2463,7 +2462,8 @@ static inline bool cow_user_page(struct page *dst, struct 
page *src,
vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, >ptl);
locked = true;
if (!likely(pte_same(*vmf->pte, vmf->orig_pte))) {
-   /* The PTE changed under us. Retry page fault. */
+   /* The PTE changed under us, update local tlb */
+   update_mmu_tlb(vma, addr, vmf->pte);
ret = false;
goto pte_unlock;
}
@@ -2752,6 +2752,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
new_page = old_page;
page_copied = 1;
} else {
+   update_mmu_tlb(vma, vmf->address, vmf->pte);

[v2] ceph: show max caps in debugfs caps file

2020-05-24 Thread Yanhu Cao
before
--
total   1286
avail   1005
used281
reserved0
min 1024

after
-
total   1286
avail   1005
used281
limit   261
reserved0
min 1024

Signed-off-by: Yanhu Cao 
Signed-off-by: Yanhu Cao 
Reported-by: kbuild test robot 
---
 fs/ceph/caps.c   | 6 --
 fs/ceph/debugfs.c| 8 +---
 fs/ceph/mds_client.c | 1 +
 fs/ceph/mds_client.h | 4 +++-
 fs/ceph/super.h  | 2 +-
 5 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 5f3aa4d607de..17191d6cd3b5 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -404,8 +404,8 @@ void ceph_put_cap(struct ceph_mds_client *mdsc, struct 
ceph_cap *cap)
 }
 
 void ceph_reservation_status(struct ceph_fs_client *fsc,
-int *total, int *avail, int *used, int *reserved,
-int *min)
+int *total, int *avail, int *used, int *limit,
+int *reserved, int *min)
 {
struct ceph_mds_client *mdsc = fsc->mdsc;
 
@@ -417,6 +417,8 @@ void ceph_reservation_status(struct ceph_fs_client *fsc,
*avail = mdsc->caps_avail_count;
if (used)
*used = mdsc->caps_use_count;
+   if (limit)
+   *limit = mdsc->caps_limit;
if (reserved)
*reserved = mdsc->caps_reserve_count;
if (min)
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
index 481ac97b4d25..617020261902 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -138,16 +138,18 @@ static int caps_show(struct seq_file *s, void *p)
 {
struct ceph_fs_client *fsc = s->private;
struct ceph_mds_client *mdsc = fsc->mdsc;
-   int total, avail, used, reserved, min, i;
+   int total, avail, used, limit, reserved, min, i;
struct cap_wait *cw;
 
-   ceph_reservation_status(fsc, , , , , );
+   ceph_reservation_status(fsc, , , ,
+   , , );
seq_printf(s, "total\t\t%d\n"
   "avail\t\t%d\n"
   "used\t\t%d\n"
+  "limit\t\t%d\n"
   "reserved\t%d\n"
   "min\t\t%d\n\n",
-  total, avail, used, reserved, min);
+  total, avail, used, limit, reserved, min);
seq_printf(s, "inoissued   implemented\n");
seq_printf(s, "---\n");
 
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 7c63abf5bea9..d26bc065f5f5 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1920,6 +1920,7 @@ int ceph_trim_caps(struct ceph_mds_client *mdsc,
   int max_caps)
 {
int trim_caps = session->s_nr_caps - max_caps;
+   mdsc->caps_limit = max_caps;
 
dout("trim_caps mds%d start: %d / %d, trim %d\n",
 session->s_mds, session->s_nr_caps, max_caps, trim_caps);
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 903d9edfd4bf..840d47976dbb 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -445,7 +445,9 @@ struct ceph_mds_client {
struct  list_head cap_wait_list;
int caps_total_count;/* total caps allocated */
int caps_use_count;  /* in use */
-   int caps_use_max;/* max used caps */
+   int caps_use_max;/* max used caps,
+   limited by client */
+   int caps_limit;  /* limited by mds */
int caps_reserve_count;  /* unused, reserved */
int caps_avail_count;/* unused, unreserved */
int caps_min_count;  /* keep at least this many
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 60aac3aee055..052d7725761d 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -700,7 +700,7 @@ extern void ceph_unreserve_caps(struct ceph_mds_client 
*mdsc,
   struct ceph_cap_reservation *ctx);
 extern void ceph_reservation_status(struct ceph_fs_client *client,
int *total, int *avail, int *used,
-   int *reserved, int *min);
+   int *limit, int *reserved, int *min);
 
 
 
-- 
2.24.3 (Apple Git-128)



Re: [RFC 02/11] net: phy: Simplify MMD device list termination

2020-05-24 Thread Jeremy Linton

Hi,

On 5/23/20 1:36 PM, Russell King - ARM Linux admin wrote:

On Fri, May 22, 2020 at 04:30:50PM -0500, Jeremy Linton wrote:

Since we are already checking for *devs == 0 after
the loop terminates, we can add a mostly F's check
as well. With that change we can simplify the return/break
sequence inside the loop.

Add a valid_phy_id() macro for this, since we will be using it
in a couple other places.


I'm not sure you have the name of this correct, and your usage layer
in your patch series is correct.


Or the name is poor..





Signed-off-by: Jeremy Linton 
---
  drivers/net/phy/phy_device.c | 15 +++
  1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 245899b58a7d..7746c07b97fe 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -695,6 +695,11 @@ static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, 
int addr, int dev_addr,
return 0;
  }
  
+static bool valid_phy_id(int val)

+{
+   return (val > 0 && ((val & 0x1fff) != 0x1fff));
+}
+
  /**
   * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
   * @bus: the target MII bus
@@ -732,18 +737,12 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, 
u32 *phy_id,
phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs);
if (phy_reg < 0)
return -EIO;
-   /* no device there, let's get out of here */
-   if ((*devs & 0x1fff) == 0x1fff) {
-   *phy_id = 0x;
-   return 0;
-   } else {
-   break;
-   }
+   break;
}
}
  
  	/* no reported devices */

-   if (*devs == 0) {
+   if (!valid_phy_id(*devs)) {


You are using this to validate the "devices in package" value, not the
PHY ID value.  So, IMHO this should be called "valid_devs_in_package()"
or similar.


Hmmm, its more "valid_phy_reg()" since it ends up being used to validate 
both the devs in package as well as phy id.







*phy_id = 0x;
return 0;
}
--
2.26.2








RE: [PATCH] soc: fsl: qe: Replace one-element array and use struct_size() helper

2020-05-24 Thread Qiang Zhao
On Wed, May 23, 2020 at 5:22 PM Li Yang 
> -Original Message-
> From: Li Yang 
> Sent: 2020年5月23日 5:22
> To: Kees Cook 
> Cc: Gustavo A. R. Silva ; Qiang Zhao
> ; linuxppc-dev ;
> moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
> ; lkml ;
> Gustavo A. R. Silva 
> Subject: Re: [PATCH] soc: fsl: qe: Replace one-element array and use
> struct_size() helper
> 
> On Wed, May 20, 2020 at 10:24 PM Kees Cook 
> wrote:
> >
> > On Wed, May 20, 2020 at 06:52:21PM -0500, Li Yang wrote:
> > > On Mon, May 18, 2020 at 5:57 PM Kees Cook 
> wrote:
> > > > Hm, looking at this code, I see a few other things that need to be
> > > > fixed:
> > > >
> > > > 1) drivers/tty/serial/ucc_uart.c does not do a be32_to_cpu() conversion
> > > >on the length test (understandably, a little-endian system has never
> run
> > > >this code since it's ppc specific), but it's still wrong:
> > > >
> > > > if (firmware->header.length != fw->size) {
> > > >
> > > >compare to the firmware loader:
> > > >
> > > > length = be32_to_cpu(hdr->length);
> > > >
> > > > 2) drivers/soc/fsl/qe/qe.c does not perform bounds checking on the
> > > >per-microcode offsets, so the uploader might send data outside the
> > > >firmware buffer. Perhaps:
> > >
> > > We do validate the CRC for each microcode, it is unlikely the CRC
> > > check can pass if the offset or length is not correct.  But you are
> > > probably right that it will be safer to check the boundary and fail
> >
> > Right, but a malicious firmware file could still match CRC but trick
> > the kernel code.
> >
> > > quicker before we actually start the CRC check.  Will you come up
> > > with a formal patch or you want us to deal with it?
> >
> > It sounds like Gustavo will be sending one, though I don't think
> > either of us have the hardware to test it with, so if you could do
> > that part, that would be great! :)
> 
> That will be great.  I think Zhao Qiang can help with the testing part.
> 

Now the firmware are loaded in uboot, and kernel will do nothing for it.
So testing on it maybe need some extra codes both in driver and dts.
In the meanwhile, I am so busy on some high priority work that maybe test work 
could not be done in time.
Once I am free, I will do it.

Best Regards
Qiang Zhao


Re: [RFC 01/11] net: phy: Don't report success if devices weren't found

2020-05-24 Thread Jeremy Linton

Hi,

Thanks for taking a look at this.

On 5/23/20 1:20 PM, Russell King - ARM Linux admin wrote:

On Fri, May 22, 2020 at 04:30:49PM -0500, Jeremy Linton wrote:

C45 devices are to return 0 for registers they haven't
implemented. This means in theory we can terminate the
device search loop without finding any MMDs. In that
case we want to immediately return indicating that
nothing was found rather than continuing to probe
and falling into the success state at the bottom.


This is a little confusing when you read this comment:

 /*  If mostly Fs, there is no device there,
  *  then let's continue to probe more, as some
  *  10G PHYs have zero Devices In package,
  *  e.g. Cortina CS4315/CS4340 PHY.
  */

Since it appears to be talking about the case of a PHY where *devs will
be zero.  However, tracking down the original submission, it seems this
is not the case at all, and the comment is grossly misleading.

It seems these PHYs only report a valid data in the Devices In Package
registers for devad=0 - it has nothing to do with a zero Devices In
Package.


Yes, this ended up being my understanding of this commit, and is part of 
my justification for starting the devices search at the reserved address 
0 rather than 1.




Can I suggest that this comment is fixed while we're changing the code
to explicitly reject this "zero Devices In package" so that it's not
confusing?


Its probably better to kill it in 5/11 with a mention that we are 
starting at a reserved address?


OTOH, I'm a bit concerned that reading at 0 as the first address will 
cause problems because the original code was only triggering it after a 
read returning 0x at a valid MMD address. It does 
simplify/clarify the loop though. If it weren't for this 0 read, I would 
have tried to avoid some of the additional MMD reserved addresses.




RE: [PATCH] thermal: imx8mm: Add get_trend ops

2020-05-24 Thread Anson Huang
Hi, Daniel


> Subject: RE: [PATCH] thermal: imx8mm: Add get_trend ops
> 
> Hi, Daniel
> 
> > Subject: Re: [PATCH] thermal: imx8mm: Add get_trend ops
> >
> > On 23/05/2020 02:35, Anson Huang wrote:
> > > Hi, Daniel
> > >
> > >
> > >> Subject: Re: [PATCH] thermal: imx8mm: Add get_trend ops
> > >>
> > >> On 13/05/2020 04:58, Anson Huang wrote:
> > >>> Add get_trend ops for i.MX8MM thermal to apply fast cooling
> > >>> mechanism, when temperature exceeds passive trip point, the
> > >>> highest cooling action will be applied, and when temperature drops
> > >>> to lower than the margin below passive trip point, the lowest
> > >>> cooling action will be applied.
> > >>
> > >> You are not describing what is the goal of this change.
> > >
> > > The goal of this change is to make sure whenever temperature exceeds
> > > passive trip point, the highest cooling action will be applied
> > > immediately, e.g., if there are many cpufreq OPP, the default
> > > cooling will be step by step, it will take some more rounds to make
> > > cpufreq drop to
> > lowest OPP, while on i.MX, we expect the cpufreq drop to lowest OPP
> > immediately.
> >
> > Whatever the slope of the temperature increase?
> 
> Yes.
> 
> >
> > >> IIUC, the resulting change will be an on/off action. The thermal
> > >> zone is mitigated with the highest cooling effect, so the lowest
> > >> OPP, then the temperature trend is stable until it goes below the
> > >> trip - margin where the mitigation is stopped.
> > >
> > > Yes, your understanding is correctly, once the temperature exceeds
> > > passive trip point, the highest cooling action will be applied
> > > immediately and then it will be stable there until temperature drop
> > > to trip - margin, then the cooling action will be cancelled, the
> > > margin is to avoid
> > the back and forth near the passive trip point.
> > >
> > >>
> > >> Except, I'm missing something, setting a trip point with a 1
> > >> hysteresis and a cooling map min/max set to the highest opp will
> > >> result on
> > the same.
> > >
> > > Yes setting cooling map min/max cooling state to highest OPP will
> > > make the highest cooling action applied immediately, and to have the
> > > function of cooling action being cancelled when temperature drops to
> > > trip - margin, I have to define another trip point, say passive trip
> > > point is 85000, and cooling map min/max set to highest OPP in
> > > passive trip point then add another trip point named "active" with
> > > 75000, and
> > without any cooling map in it, right?
> >
> > May be I misunderstood but only the change as below is needed. No need
> > to add a trip point, especially an 'active' trip which is a for an
> > active cooling device like a fan.
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > index cc7152ecedd9..bea263bd06b4 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > @@ -231,10 +231,10 @@ cooling-maps {
> > map0 {
> > trip = <_alert0>;
> > cooling-device =
> > -   <_0 THERMAL_NO_LIMIT
> > THERMAL_NO_LIMIT>,
> > -   <_1 THERMAL_NO_LIMIT
> > THERMAL_NO_LIMIT>,
> > -   <_2 THERMAL_NO_LIMIT
> > THERMAL_NO_LIMIT>,
> > -   <_3 THERMAL_NO_LIMIT
> > THERMAL_NO_LIMIT>;
> > +   <_0 2 2>,
> > +   <_1 2 2>,
> > +   <_2 2 2>,
> > +   <_3 2 2>
> > };
> > };
> > };
> >
> >
> 
> Thanks, I will have a try to see if it meets our expectation.

I tried modifying the min/max to '2' in cooling map, it works that whenever 
cooling
action is needed, the max cooling action will be applied. But I also noticed 
some behaviors
which NOT as expected:

1. to easy the test, I enable the " CONFIG_THERMAL_WRITABLE_TRIPS", and just 
modify the
passive trip threshold to trigger the cooling action, this is much more easy 
then putting the board
into an oven to increase the SoC temperature or running many high loading test 
to increase the temperature,
but when I modify the passive trip threshold to be lower than current 
temperature, the cooling action is NOT
triggered immediately, it is because the default step_wise governor will NOT 
trigger the cooling action when
the trend is THERMAL_TREND_STABLE.
But what expected is, when the temperature is exceed the passive trip 
threshold, the cooling action can be
triggered immediately no matter the trend is stable or raising. That means we 
have to implement our own
.get_trend callback?

2. No margin for releasing the cooling action, for example, if 

Re: [PATCH 1/2] software node: implement software_node_unregister()

2020-05-24 Thread Randy Dunlap
On 5/24/20 9:43 AM, Guenter Roeck wrote:
> On 5/24/20 8:30 AM, Greg Kroah-Hartman wrote:
>> Sometimes it is better to unregister individual nodes instead of trying
>> to do them all at once with software_node_unregister_nodes(), so create
>> software_node_unregister() so that you can unregister them one at a
>> time.
>>
>> This is especially important when creating nodes in a hierarchy, with
>> parent -> children representations.  Children always need to be removed
>> before a parent is, as the swnode logic assumes this is going to be the
>> case.
>>
>> Fix up the lib/test_printf.c fwnode_pointer() test which to use this new
>> function as it had the problem of tearing things down in the backwards
>> order.
>>
>> Fixes: f1ce39df508d ("lib/test_printf: Add tests for %pfw printk modifier")
>> Reported-by: Naresh Kamboju 
>> Reported-by: kernel test robot 
>> Cc: stable 
>> Cc: Andy Shevchenko 
>> Cc: Brendan Higgins 
>> Cc: Dmitry Torokhov 
>> Cc: Heikki Krogerus 
>> Cc: Petr Mladek 
>> Cc: Rafael J. Wysocki 
>> Cc: Randy Dunlap 
>> Cc: Rasmus Villemoes 
>> Cc: Sakari Ailus 
>> Cc: Sergey Senozhatsky 
>> Cc: Steven Rostedt 
>> Signed-off-by: Greg Kroah-Hartman 
> 
> Both patches pass my boot tests on arm64 and arm64be (I didn't test any 
> others).
> So, FWIW,
> 
> Tested-by: Guenter Roeck 
> 
> I wasn't sure it the two patches replace or fix commit 4ef12f719802 ("kobject:
> Make sure the parent does not get released before its children"), so I tried
> to re-apply 4ef12f719802 on top of the two patches. Unfortunately that still
> results in crashes and UAF messages.

Yes, that kobject patch has been reverted:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e6764aa0e5530066dd969eccea2a1a7d177859a8

and these 2 patches are to be used instead.

thanks.
-- 
~Randy



Re: [RFC 03/11] net: phy: refactor c45 phy identification sequence

2020-05-24 Thread Jeremy Linton

Hi,

On 5/23/20 3:01 PM, Russell King - ARM Linux admin wrote:

On Sat, May 23, 2020 at 09:51:31PM +0200, Andrew Lunn wrote:

  static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
   struct phy_c45_device_ids *c45_ids) {
-   int phy_reg;
-   int i, reg_addr;
+   int ret;
+   int i;
const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
u32 *devs = _ids->devices_in_package;


I feel a "reverse christmas tree" complaint brewing... yes, the original
code didn't follow it.  Maybe a tidy up while touching this code?


At minimum, a patch should not make it worse. ret and i should clearly
be after devs.


  static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
  bool is_c45, struct phy_c45_device_ids *c45_ids)
  {
-   int phy_reg;
+   int ret;
  
  	if (is_c45)

return get_phy_c45_ids(bus, addr, phy_id, c45_ids);
  
-	/* Grab the bits from PHYIR1, and put them in the upper half */

-   phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
-   if (phy_reg < 0) {
+   ret = _get_phy_id(bus, addr, 0, phy_id, false);
+   if (ret < 0) {
/* returning -ENODEV doesn't stop bus scanning */
-   return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO;
+   return (ret == -EIO || ret == -ENODEV) ? -ENODEV : -EIO;


Since ret will only ever be -EIO here, this can only ever return
-ENODEV, which is a functional change in the code (probably unintended.)
Nevertheless, it's likely introducing a bug if the intention is for
some other return from mdiobus_read() to be handled differently.


}
  
-	*phy_id = phy_reg << 16;

-
-   /* Grab the bits from PHYIR2, and put them in the lower half */
-   phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
-   if (phy_reg < 0)
-   return -EIO;


... whereas this one always returns -EIO on any error.

So, I think you have the potential in this patch to introduce a subtle
change of behaviour, which may lead to problems - have you closely
analysed why the code was the way it was, and whether your change of
behaviour is actually valid?


I could be remembering this wrongly, but i think this is to do with
orion_mdio_xsmi_read() returning -ENODEV, not 0xff, if there
is no device on the bus at the given address. -EIO is fatal to the
scan, everything stops with the assumption the bus is broken. -ENODEV
should not be fatal to the scan.


Maybe orion_mdio_xsmi_read() should be fixed then?  Also, maybe
adding return code documentation for mdiobus_read() / mdiobus_write()
would help MDIO driver authors have some consistency in what
errors they are expected to return (does anyone know for certain?)



My understanding at this point (which is mostly based on the xgmac 
here), is that 0x is equivalent to "bus responding correctly, 
phy failed to respond at this register location" while any -Eerror is 
understood as "something wrong with bus", and the mdio core then makes a 
choice about terminating just the current phy search (ENODEV), or 
terminating the entire mdio bus (basically everything else) registration.


I will see about clarifying the docs. I need to see if that will end up 
being a bit of a rabbit hole before committing to including that in this 
set.


Which brings up the problem that at least xgmac_mdio doesn't appear to 
handle being told "your bus registration failed" without OOPSing the 
probe routine. I think Calvin is aware of this, and I believe he has 
some additional xgmac/etc patches on top of this set. Although he pinged 
me offline the other day to say that apparently all my hunk shuffling 
broke some of the c45 phy detection I had working earlier in the week.




Re: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

2020-05-24 Thread John Hubbard

On 2020-05-24 19:25, Wu, Hao wrote:

Hi Moritz and FPGA developers,

Is this OK? And if so, is it going into your git tree? Or should I
send it up through a different tree? (I'm new to the FPGA development
model).


I can take it, sorry for sluggish response.



That's great news, thanks Moritz! Sorry to be pushy, just didn't want it
to get lost. :)


Thanks John for this patch, and thanks Moritz for taking care of this.
Sorry for late response, one thing here we may need to be careful is
a recent bug fixing patch, that fixing patch has been merged by Greg
in char-misc-next tree, and may have some conflict with this one.

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/commit/?h=char-misc-next=c9d7e3da1f3c4cf5dddfc5d7ce4d76d013aba1cc
fpga: dfl: afu: Corrected error handling levels

I guess we need to rebase this patch on top of it?
Moritz, do you have any suggestion?



I'll send you a v2, rebased on top of the latest char-misc.git, no problem.

thanks,
--
John Hubbard
NVIDIA


Re: [PATCH v5 09/13] soc: mediatek: cmdq: add write_s value function

2020-05-24 Thread Dennis-YC Hsieh

On Sun, 2020-05-24 at 20:13 +0200, Matthias Brugger wrote:
> 
> On 24/05/2020 19:31, Dennis-YC Hsieh wrote:
> > Hi Matthias,
> > 
> > Thanks for your comment.
> > 
> > On Sat, 2020-05-16 at 20:20 +0200, Matthias Brugger wrote:
> >>
> >> On 08/03/2020 11:52, Dennis YC Hsieh wrote:
> >>> add write_s function in cmdq helper functions which
> >>> writes a constant value to address with large dma
> >>> access support.
> >>>
> >>> Signed-off-by: Dennis YC Hsieh 
> >>> Reviewed-by: CK Hu 
> >>> ---
> >>>  drivers/soc/mediatek/mtk-cmdq-helper.c | 26 ++
> >>>  include/linux/soc/mediatek/mtk-cmdq.h  | 14 ++
> >>>  2 files changed, 40 insertions(+)
> >>>
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> index 03c129230cd7..a9ebbabb7439 100644
> >>> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> >>> @@ -269,6 +269,32 @@ int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 
> >>> high_addr_reg_idx,
> >>>  }
> >>>  EXPORT_SYMBOL(cmdq_pkt_write_s);
> >>>  
> >>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +u16 addr_low, u32 value, u32 mask)
> >>> +{
> >>> + struct cmdq_instruction inst = { {0} };
> >>> + int err;
> >>> +
> >>> + if (mask != U32_MAX) {
> >>> + inst.op = CMDQ_CODE_MASK;
> >>> + inst.mask = ~mask;
> >>> + err = cmdq_pkt_append_command(pkt, inst);
> >>> + if (err < 0)
> >>> + return err;
> >>> +
> >>> + inst.op = CMDQ_CODE_WRITE_S_MASK;
> >>> + } else {
> >>> + inst.op = CMDQ_CODE_WRITE_S;
> >>> + }
> >>> +
> >>> + inst.sop = high_addr_reg_idx;
> >>
> >> Writing u16 value in a 5 bit wide variable?
> > 
> > We need only 5 bits in this case. I'll change high_addr_reg_idx
> > parameter to u8.
> > 
> 
> Ok, please make sure to mask the value, so that it's explicit in the code that
> we only use the lowest 5 bits of high_addr_reg_idx.

Is it necessary to mask the value?
Since sop already defined as "u8 sop:5;", I thought it is explicit that
only use 5 bits and compiler should do the rest jobs.


Regards,
Dennis

> 
> Regards,
> Matthias
> 
> >>
> >>> + inst.offset = addr_low;
> >>> + inst.value = value;
> >>> +
> >>> + return cmdq_pkt_append_command(pkt, inst);
> >>> +}
> >>> +EXPORT_SYMBOL(cmdq_pkt_write_s_value);
> >>> +
> >>>  int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
> >>>  {
> >>>   struct cmdq_instruction inst = { {0} };
> >>> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h 
> >>> b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> index 01b4184af310..fec292aac83c 100644
> >>> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> >>> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> >>> @@ -135,6 +135,20 @@ int cmdq_pkt_read_s(struct cmdq_pkt *pkt, u16 
> >>> high_addr_reg_idx, u16 addr_low,
> >>>  int cmdq_pkt_write_s(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>>u16 addr_low, u16 src_reg_idx, u32 mask);
> >>>  
> >>> +/**
> >>> + * cmdq_pkt_write_s_value() - append write_s command with mask to the 
> >>> CMDQ
> >>> + * packet which write value to a physical 
> >>> address
> >>> + * @pkt: the CMDQ packet
> >>> + * @high_addr_reg_idx:   internal regisger ID which contains high 
> >>> address of pa
> >>
> >> register
> > 
> > will fix
> > 
> > 
> > Regards,
> > Dennis
> > 
> >>
> >>> + * @addr_low:low address of pa
> >>> + * @value:   the specified target value
> >>> + * @mask:the specified target mask
> >>> + *
> >>> + * Return: 0 for success; else the error code is returned
> >>> + */
> >>> +int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u16 high_addr_reg_idx,
> >>> +u16 addr_low, u32 value, u32 mask);
> >>> +
> >>>  /**
> >>>   * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
> >>>   * @pkt: the CMDQ packet
> >>>
> > 



mm: Behavior of process_vm_* with short local buffers

2020-05-24 Thread Keno Fischer
Hi everyone,

I'm in the process of trying to port a debugging tool (http://rr-project.org/)
from x86 to various other architectures. This tool relies on noting every
change that was made to the memory of the process being debugged.
As such, it has a battery of tests for corner cases of copyin/out and it
is one of these that I saw behaving strangely when ported to non-x86
architectures. This particular test was testing the behavior of
process_vm_readv (and writev, but for simplicity, let's assume readv here)
with short local buffers.

On x86 if the buffer is short and the following page is unmapped,
the syscall will fill the remainder of the page, and
then return however many bytes it actually wrote. However, on other
architectures (I mostly looked at arm64, though the same applies
elsewhere), the behavior can be quite different.
In general, the behavior depends strongly on factors like how close to
the start of the copy region the page break occurs, how many bytes
were supposed to be left after the page break and the total size of
the region to be copied. In various situations, I'm seeing:

- Writes that end many bytes before the page break
- Bytes being modified beyond what the syscall result would indicate
happened.
- Combinations thereof

I can work around this in my port, but I thought it might be valuable
to ask where the line is between "architecture-defined behavior" and
a bug that should be reported to the appropriate architecture
maintainers and eventually fixed. For example, I think it would be
nice if the syscall result actually did match the actual number of
bytes written in all cases.

I've written a small program [1] that sets up this situation for various
parameter values and prints the results. I have access to arm64,
powerpc and x86, so I included results for those architectures,
but I suspect other architectures have similar issues. The
program should be easy to run to get your own results for
a different architecture.

[1] https://gist.github.com/Keno/b247bca85219c4e3bdde9f7d7ff36c77

Thanks, Keno


RE: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

2020-05-24 Thread Wu, Hao
> >> Hi Moritz and FPGA developers,
> >>
> >> Is this OK? And if so, is it going into your git tree? Or should I
> >> send it up through a different tree? (I'm new to the FPGA development
> >> model).
> >
> > I can take it, sorry for sluggish response.
> >
> 
> That's great news, thanks Moritz! Sorry to be pushy, just didn't want it
> to get lost. :)

Thanks John for this patch, and thanks Moritz for taking care of this.
Sorry for late response, one thing here we may need to be careful is
a recent bug fixing patch, that fixing patch has been merged by Greg
in char-misc-next tree, and may have some conflict with this one.

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/commit/?h=char-misc-next=c9d7e3da1f3c4cf5dddfc5d7ce4d76d013aba1cc
fpga: dfl: afu: Corrected error handling levels

I guess we need to rebase this patch on top of it?
Moritz, do you have any suggestion?

Thanks
Hao

> 
> thanks,
> --
> John Hubbard
> NVIDIA


  1   2   3   4   5   6   >